("nics", ht.TListOf(ht.TDict)),
("vcpus", ht.TInt),
("hypervisor", ht.TString),
+ ("node_whitelist", ht.TMaybeListOf(ht.TNonEmptyString)),
]
REQ_RESULT = ht.TList
if isinstance(self.req, IAReqInstanceAlloc):
hypervisor_name = self.req.hypervisor
+ node_whitelist = self.req.node_whitelist
elif isinstance(self.req, IAReqRelocate):
hypervisor_name = cfg.GetInstanceInfo(self.req.name).hypervisor
+ node_whitelist = None
else:
hypervisor_name = cluster_info.primary_hypervisor
+ node_whitelist = None
node_data = self.rpc.call_node_info(node_list, [cfg.GetVGName()],
[hypervisor_name])
data["nodegroups"] = self._ComputeNodeGroupData(cfg)
- config_ndata = self._ComputeBasicNodeData(cfg, ninfo)
+ config_ndata = self._ComputeBasicNodeData(cfg, ninfo, node_whitelist)
data["nodes"] = self._ComputeDynamicNodeData(ninfo, node_data, node_iinfo,
i_list, config_ndata)
assert len(data["nodes"]) == len(ninfo), \
return ng
@staticmethod
- def _ComputeBasicNodeData(cfg, node_cfg):
+ def _ComputeBasicNodeData(cfg, node_cfg, node_whitelist):
"""Compute global node data.
@rtype: dict
"tags": list(ninfo.GetTags()),
"primary_ip": ninfo.primary_ip,
"secondary_ip": ninfo.secondary_ip,
- "offline": ninfo.offline,
+ "offline": (ninfo.offline or
+ not (node_whitelist is None or
+ ninfo.name in node_whitelist)),
"drained": ninfo.drained,
"master_candidate": ninfo.master_candidate,
"group": ninfo.group,
from ganeti import compat
from ganeti import constants
from ganeti import errors
+from ganeti import objects
from ganeti import ht
from ganeti.masterd import iallocator
stub.ValidateResult(_StubIAllocator(False), "foo")
+class _FakeConfigWithNdParams:
+ def GetNdParams(self, _):
+ return None
+
+
+class TestComputeBasicNodeData(unittest.TestCase):
+ def setUp(self):
+ self.fn = compat.partial(iallocator.IAllocator._ComputeBasicNodeData,
+ _FakeConfigWithNdParams())
+
+ def testEmpty(self):
+ self.assertEqual(self.fn({}, None), {})
+
+ def testSimple(self):
+ node1 = objects.Node(name="node1",
+ primary_ip="192.0.2.1",
+ secondary_ip="192.0.2.2",
+ offline=False,
+ drained=False,
+ master_candidate=True,
+ master_capable=True,
+ group="11112222",
+ vm_capable=False)
+
+ node2 = objects.Node(name="node2",
+ primary_ip="192.0.2.3",
+ secondary_ip="192.0.2.4",
+ offline=True,
+ drained=False,
+ master_candidate=False,
+ master_capable=False,
+ group="11112222",
+ vm_capable=True)
+
+ assert node1 != node2
+
+ ninfo = {
+ "#unused-1#": node1,
+ "#unused-2#": node2,
+ }
+
+ self.assertEqual(self.fn(ninfo, None), {
+ "node1": {
+ "tags": [],
+ "primary_ip": "192.0.2.1",
+ "secondary_ip": "192.0.2.2",
+ "offline": False,
+ "drained": False,
+ "master_candidate": True,
+ "group": "11112222",
+ "master_capable": True,
+ "vm_capable": False,
+ "ndparams": None,
+ },
+ "node2": {
+ "tags": [],
+ "primary_ip": "192.0.2.3",
+ "secondary_ip": "192.0.2.4",
+ "offline": True,
+ "drained": False,
+ "master_candidate": False,
+ "group": "11112222",
+ "master_capable": False,
+ "vm_capable": True,
+ "ndparams": None,
+ },
+ })
+
+ def testOfflineNode(self):
+ for whitelist in [None, [], set(), ["node1"], ["node2"]]:
+ result = self.fn({
+ "node1": objects.Node(name="node1", offline=True)
+ }, whitelist)
+ self.assertEqual(len(result), 1)
+ self.assertTrue(result["node1"]["offline"])
+
+ def testWhitelist(self):
+ for whitelist in [None, [], set(), ["node1"], ["node2"]]:
+ result = self.fn({
+ "node1": objects.Node(name="node1", offline=False)
+ }, whitelist)
+ self.assertEqual(len(result), 1)
+
+ if whitelist is None or "node1" in whitelist:
+ self.assertFalse(result["node1"]["offline"])
+ else:
+ self.assertTrue(result["node1"]["offline"])
+
+
if __name__ == "__main__":
testutils.GanetiTestProgram()