57 |
57 |
from ganeti import query
|
58 |
58 |
from ganeti import qlang
|
59 |
59 |
from ganeti import opcodes
|
|
60 |
from ganeti import network
|
60 |
61 |
|
61 |
62 |
import ganeti.masterd.instance # pylint: disable-msg=W0611
|
62 |
63 |
|
... | ... | |
11873 |
11874 |
return result
|
11874 |
11875 |
|
11875 |
11876 |
|
|
11877 |
# Network LUs
|
|
11878 |
class LUNetworkAdd(LogicalUnit):
|
|
11879 |
"""Logical unit for creating node groups.
|
|
11880 |
|
|
11881 |
"""
|
|
11882 |
HPATH = "network-add"
|
|
11883 |
HTYPE = constants.HTYPE_NETWORK
|
|
11884 |
REQ_BGL = False
|
|
11885 |
|
|
11886 |
def ExpandNames(self):
|
|
11887 |
self.needed_locks = {
|
|
11888 |
locking.LEVEL_NODE: locking.ALL_SET,
|
|
11889 |
}
|
|
11890 |
self.share_locks[locking.LEVEL_NODE] = 1
|
|
11891 |
|
|
11892 |
def CheckPrereq(self):
|
|
11893 |
"""Check prerequisites.
|
|
11894 |
|
|
11895 |
This checks that the given group name is not an existing node group
|
|
11896 |
already.
|
|
11897 |
|
|
11898 |
"""
|
|
11899 |
try:
|
|
11900 |
uuid = self.cfg.LookupNetwork(self.op.network_name)
|
|
11901 |
except errors.OpPrereqError:
|
|
11902 |
uuid = None
|
|
11903 |
|
|
11904 |
if uuid is not None:
|
|
11905 |
raise errors.OpPrereqError("Network '%s' already defined" %
|
|
11906 |
self.op.network, errors.ECODE_EXISTS)
|
|
11907 |
|
|
11908 |
def BuildHooksEnv(self):
|
|
11909 |
"""Build hooks env.
|
|
11910 |
|
|
11911 |
"""
|
|
11912 |
env = {
|
|
11913 |
"NETWORK_NAME": self.op.network_name,
|
|
11914 |
"NETWORK_SUBNET": self.op.network,
|
|
11915 |
"NETWORK_GATEWAY": self.op.gateway,
|
|
11916 |
}
|
|
11917 |
mn = self.cfg.GetMasterNode()
|
|
11918 |
return env, [mn], [mn]
|
|
11919 |
|
|
11920 |
def Exec(self, feedback_fn):
|
|
11921 |
"""Add the ip pool to the cluster.
|
|
11922 |
|
|
11923 |
"""
|
|
11924 |
#FIXME: error handling
|
|
11925 |
nobj = objects.Network(name=self.op.network_name,
|
|
11926 |
network=self.op.network,
|
|
11927 |
gateway=self.op.gateway,
|
|
11928 |
family=4)
|
|
11929 |
|
|
11930 |
# Initialize the associated address pool
|
|
11931 |
pool = network.AddressPool.InitializeNetwork(nobj)
|
|
11932 |
|
|
11933 |
# Check if we need to reserve the nodes and the cluster master IP
|
|
11934 |
# These may not be allocated to any instances in routed mode, as
|
|
11935 |
# they wouldn't function anyway.
|
|
11936 |
for node in self.cfg.GetAllNodesInfo().values():
|
|
11937 |
for ip in [node.primary_ip, node.secondary_ip]:
|
|
11938 |
try:
|
|
11939 |
pool.Reserve(ip)
|
|
11940 |
self.LogInfo("Reserved node %s's IP (%s)", node.name, ip)
|
|
11941 |
|
|
11942 |
except errors.AddressPoolError:
|
|
11943 |
pass
|
|
11944 |
|
|
11945 |
master_ip = self.cfg.GetClusterInfo().master_ip
|
|
11946 |
try:
|
|
11947 |
pool.Reserve(master_ip)
|
|
11948 |
self.LogInfo("Reserved cluster master IP (%s)", master_ip)
|
|
11949 |
except errors.AddressPoolError:
|
|
11950 |
pass
|
|
11951 |
|
|
11952 |
if self.op.reserved_ips:
|
|
11953 |
for ip in self.op.reserved_ips:
|
|
11954 |
pool.Reserve(ip, external=True)
|
|
11955 |
|
|
11956 |
self.cfg.AddNetwork(nobj, self.proc.GetECId())
|
|
11957 |
|
|
11958 |
|
|
11959 |
class _NetworkQuery(_QueryBase):
|
|
11960 |
FIELDS = query.NETWORK_FIELDS
|
|
11961 |
|
|
11962 |
def ExpandNames(self, lu):
|
|
11963 |
lu.needed_locks = {}
|
|
11964 |
|
|
11965 |
self._all_networks = lu.cfg.GetAllNetworksInfo()
|
|
11966 |
name_to_uuid = dict((n.name, n.uuid) for n in self._all_networks.values())
|
|
11967 |
|
|
11968 |
if not self.names:
|
|
11969 |
self.wanted = [name_to_uuid[name]
|
|
11970 |
for name in utils.NiceSort(name_to_uuid.keys())]
|
|
11971 |
else:
|
|
11972 |
# Accept names to be either names or UUIDs.
|
|
11973 |
missing = []
|
|
11974 |
self.wanted = []
|
|
11975 |
all_uuid = frozenset(self._all_networks.keys())
|
|
11976 |
|
|
11977 |
for name in self.names:
|
|
11978 |
if name in all_uuid:
|
|
11979 |
self.wanted.append(name)
|
|
11980 |
elif name in name_to_uuid:
|
|
11981 |
self.wanted.append(name_to_uuid[name])
|
|
11982 |
else:
|
|
11983 |
missing.append(name)
|
|
11984 |
|
|
11985 |
if missing:
|
|
11986 |
raise errors.OpPrereqError("Some networks do not exist: %s" % missing,
|
|
11987 |
errors.ECODE_NOENT)
|
|
11988 |
|
|
11989 |
def DeclareLocks(self, lu, level):
|
|
11990 |
pass
|
|
11991 |
|
|
11992 |
def _GetQueryData(self, lu):
|
|
11993 |
"""Computes the list of networks and their attributes.
|
|
11994 |
|
|
11995 |
"""
|
|
11996 |
do_instances = query.NETQ_INST in self.requested_data
|
|
11997 |
do_groups = do_instances or (query.NETQ_GROUP in self.requested_data)
|
|
11998 |
do_stats = query.NETQ_STATS in self.requested_data
|
|
11999 |
|
|
12000 |
network_to_groups = None
|
|
12001 |
network_to_instances = None
|
|
12002 |
stats = None
|
|
12003 |
|
|
12004 |
# For NETQ_GROUP, we need to map network->[groups]
|
|
12005 |
if do_groups:
|
|
12006 |
all_groups = lu.cfg.GetAllNodeGroupsInfo()
|
|
12007 |
network_to_groups = dict((uuid, []) for uuid in self.wanted)
|
|
12008 |
|
|
12009 |
if do_instances:
|
|
12010 |
all_instances = lu.cfg.GetAllInstancesInfo()
|
|
12011 |
all_nodes = lu.cfg.GetAllNodesInfo()
|
|
12012 |
network_to_instances = dict((uuid, []) for uuid in self.wanted)
|
|
12013 |
|
|
12014 |
for group in all_groups.values():
|
|
12015 |
if do_instances:
|
|
12016 |
group_nodes = [node.name for node in all_nodes.values() if
|
|
12017 |
node.group == group.uuid]
|
|
12018 |
group_instances = [instance for instance in all_instances.values()
|
|
12019 |
if instance.primary_node in group_nodes]
|
|
12020 |
|
|
12021 |
for uuid, link in group.networks.items():
|
|
12022 |
if uuid in network_to_groups:
|
|
12023 |
network_to_groups[uuid].append(":".join((group.name, link)))
|
|
12024 |
|
|
12025 |
if do_instances:
|
|
12026 |
for instance in group_instances:
|
|
12027 |
for nic in instance.nics:
|
|
12028 |
if nic.nicparams.get(constants.NIC_LINK, None) == link:
|
|
12029 |
network_to_instances[uuid].append(instance.name)
|
|
12030 |
break
|
|
12031 |
|
|
12032 |
if do_stats:
|
|
12033 |
stats = {}
|
|
12034 |
for uuid, net in self._all_networks.items():
|
|
12035 |
if uuid in self.wanted:
|
|
12036 |
pool = network.AddressPool(net)
|
|
12037 |
stats[uuid] = {
|
|
12038 |
"free_count": pool.GetFreeCount(),
|
|
12039 |
"reserved_count": pool.GetReservedCount(),
|
|
12040 |
"map": pool.GetMap(),
|
|
12041 |
}
|
|
12042 |
|
|
12043 |
return query.NetworkQueryData([self._all_networks[uuid]
|
|
12044 |
for uuid in self.wanted],
|
|
12045 |
network_to_groups,
|
|
12046 |
network_to_instances,
|
|
12047 |
stats)
|
|
12048 |
|
|
12049 |
|
|
12050 |
class LUNetworkQuery(NoHooksLU):
|
|
12051 |
"""Logical unit for querying node groups.
|
|
12052 |
|
|
12053 |
"""
|
|
12054 |
REQ_BGL = False
|
|
12055 |
|
|
12056 |
def CheckArguments(self):
|
|
12057 |
self.nq = _NetworkQuery(self.op.names, self.op.output_fields, False)
|
|
12058 |
|
|
12059 |
def ExpandNames(self):
|
|
12060 |
self.nq.ExpandNames(self)
|
|
12061 |
|
|
12062 |
def Exec(self, feedback_fn):
|
|
12063 |
return self.nq.OldStyleQuery(self)
|
|
12064 |
|
|
12065 |
|
11876 |
12066 |
#: Query type implementations
|
11877 |
12067 |
_QUERY_IMPL = {
|
11878 |
12068 |
constants.QR_INSTANCE: _InstanceQuery,
|
11879 |
12069 |
constants.QR_NODE: _NodeQuery,
|
11880 |
12070 |
constants.QR_GROUP: _GroupQuery,
|
|
12071 |
constants.QR_NETWORK: _NetworkQuery,
|
11881 |
12072 |
}
|
11882 |
12073 |
|
11883 |
12074 |
|