Commit 0fbd466b authored by Dimitris Aragiorgis's avatar Dimitris Aragiorgis Committed by Iustin Pop
Browse files

Implement network/nodegroup mappings



LUNetworkConnect() connects a network to a nodegroup and defines
its netparams (mode and link). Specifically:
 * Check if network already exists
 * Check if netparams are valid
 * Check if already connected to the same nodegroup
 * Produce errors if any conflicting IPs found
 * Update the 'networks' slot in NodeGroup config object
   with the network UUID and netparams requested. E.g.
   nodegroup_uuid {
     networks {
       network_uuid: {mode: 'bridged', link: 'br100'}
     }
   }

LUNetworkDisconnect() unmaps a network from a nodegroup:
 * Produce errors if an instance has a NIC with IP inside the network
 * Remove corresponding entry in 'networks' slot of NodeGroup object

Check for conflicting ips can be avoided with corresponding option.
Signed-off-by: default avatarDimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 1e0d3321
......@@ -15741,19 +15741,181 @@ class LUNetworkQuery(NoHooksLU):
 
 
class LUNetworkConnect(LogicalUnit):
def BuildHooksNodes(self):
pass
"""Connect a network to a nodegroup
"""
HPATH = "network-connect"
HTYPE = constants.HTYPE_NETWORK
REQ_BGL = False
def ExpandNames(self):
self.network_name = self.op.network_name
self.group_name = self.op.group_name
self.network_mode = self.op.network_mode
self.network_link = self.op.network_link
self.network_uuid = self.cfg.LookupNetwork(self.network_name)
self.network = self.cfg.GetNetwork(self.network_uuid)
self.group_uuid = self.cfg.LookupNodeGroup(self.group_name)
self.group = self.cfg.GetNodeGroup(self.group_uuid)
self.needed_locks = {
locking.LEVEL_INSTANCE: [],
locking.LEVEL_NODEGROUP: [self.group_uuid],
}
self.share_locks[locking.LEVEL_INSTANCE] = 1
def DeclareLocks(self, level):
if level == locking.LEVEL_INSTANCE:
assert not self.needed_locks[locking.LEVEL_INSTANCE]
# Lock instances optimistically, needs verification once group lock has
# been acquired
self.needed_locks[locking.LEVEL_INSTANCE] = \
self.cfg.GetNodeGroupInstances(self.group_uuid)
 
def BuildHooksEnv(self):
pass
ret = dict()
ret["GROUP_NAME"] = self.group_name
ret["GROUP_NETWORK_NAME"] = self.network_name
ret["GROUP_NETWORK_MODE"] = self.network_mode
ret["GROUP_NETWORK_LINK"] = self.network_link
return ret
def BuildHooksNodes(self):
nodes = self.cfg.GetNodeGroup(self.group_uuid).members
return (nodes, nodes)
def CheckPrereq(self):
l = lambda value: ", ".join("%s: %s/%s" % (i[0], i[1], i[2])
for i in value)
if self.network is None:
raise errors.OpPrereqError("Network %s does not exist" %
self.network_name, errors.ECODE_INVAL)
self.netparams = dict()
self.netparams[constants.NIC_MODE] = self.network_mode
self.netparams[constants.NIC_LINK] = self.network_link
objects.NIC.CheckParameterSyntax(self.netparams)
#if self.network_mode == constants.NIC_MODE_BRIDGED:
# _CheckNodeGroupBridgesExist(self, self.network_link, self.group_uuid)
self.connected = False
if self.network_uuid in self.group.networks:
self.LogWarning("Network '%s' is already mapped to group '%s'" %
(self.network_name, self.group.name))
self.connected = True
return
pool = network.AddressPool(self.network)
if self.op.conflicts_check:
groupinstances = []
for n in self.cfg.GetNodeGroupInstances(self.group_uuid):
groupinstances.append(self.cfg.GetInstanceInfo(n))
instances = [(instance.name, idx, nic.ip)
for instance in groupinstances
for idx, nic in enumerate(instance.nics)
if (not nic.network and pool._Contains(nic.ip))]
if instances:
self.LogWarning("Following occurences use IPs from network %s"
" that is about to connect to nodegroup %s: %s" %
(self.network_name, self.group.name,
l(instances)))
raise errors.OpPrereqError("Conflicting IPs found."
" Please remove/modify"
" corresponding NICs",
errors.ECODE_INVAL)
def Exec(self, feedback_fn):
if self.connected:
return
self.group.networks[self.network_uuid] = self.netparams
self.cfg.Update(self.group, feedback_fn)
 
 
class LUNetworkDisconnect(LogicalUnit):
def BuildHooksNodes(self):
pass
"""Disconnect a network to a nodegroup
"""
HPATH = "network-disconnect"
HTYPE = constants.HTYPE_NETWORK
REQ_BGL = False
def ExpandNames(self):
self.network_name = self.op.network_name
self.group_name = self.op.group_name
self.network_uuid = self.cfg.LookupNetwork(self.network_name)
self.network = self.cfg.GetNetwork(self.network_uuid)
self.group_uuid = self.cfg.LookupNodeGroup(self.group_name)
self.group = self.cfg.GetNodeGroup(self.group_uuid)
self.needed_locks = {
locking.LEVEL_INSTANCE: [],
locking.LEVEL_NODEGROUP: [self.group_uuid],
}
self.share_locks[locking.LEVEL_INSTANCE] = 1
def DeclareLocks(self, level):
if level == locking.LEVEL_INSTANCE:
assert not self.needed_locks[locking.LEVEL_INSTANCE]
# Lock instances optimistically, needs verification once group lock has
# been acquired
self.needed_locks[locking.LEVEL_INSTANCE] = \
self.cfg.GetNodeGroupInstances(self.group_uuid)
 
def BuildHooksEnv(self):
pass
ret = dict()
ret["GROUP_NAME"] = self.group_name
ret["GROUP_NETWORK_NAME"] = self.network_name
return ret
def BuildHooksNodes(self):
nodes = self.cfg.GetNodeGroup(self.group_uuid).members
return (nodes, nodes)
def CheckPrereq(self):
l = lambda value: ", ".join("%s: %s/%s" % (i[0], i[1], i[2])
for i in value)
self.connected = True
if self.network_uuid not in self.group.networks:
self.LogWarning("Network '%s' is"
" not mapped to group '%s'" %
(self.network_name, self.group.name))
self.connected = False
return
if self.op.conflicts_check:
groupinstances = []
for n in self.cfg.GetNodeGroupInstances(self.group_uuid):
groupinstances.append(self.cfg.GetInstanceInfo(n))
instances = [(instance.name, idx, nic.ip)
for instance in groupinstances
for idx, nic in enumerate(instance.nics)
if nic.network == self.network_name]
if instances:
self.LogWarning("Following occurences use IPs from network %s"
" that is about to disconnected from the nodegroup"
" %s: %s" %
(self.network_name, self.group.name,
l(instances)))
raise errors.OpPrereqError("Conflicting IPs."
" Please remove/modify"
" corresponding NICS",
errors.ECODE_INVAL)
def Exec(self, feedback_fn):
if not self.connected:
return
del self.group.networks[self.network_uuid]
self.cfg.Update(self.group, feedback_fn)
 
 
#: Query type implementations
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment