Package ganeti :: Package client :: Module gnt_network
[hide private]
[frames] | no frames]

Source Code for Module ganeti.client.gnt_network

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2011, 2012, 2013 Google Inc. 
  5  # All rights reserved. 
  6  # 
  7  # Redistribution and use in source and binary forms, with or without 
  8  # modification, are permitted provided that the following conditions are 
  9  # met: 
 10  # 
 11  # 1. Redistributions of source code must retain the above copyright notice, 
 12  # this list of conditions and the following disclaimer. 
 13  # 
 14  # 2. Redistributions in binary form must reproduce the above copyright 
 15  # notice, this list of conditions and the following disclaimer in the 
 16  # documentation and/or other materials provided with the distribution. 
 17  # 
 18  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
 19  # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
 20  # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 21  # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 22  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 23  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 24  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 25  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 26  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 27  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 28  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 29   
 30  """IP pool related commands""" 
 31   
 32  # pylint: disable=W0401,W0614 
 33  # W0401: Wildcard import ganeti.cli 
 34  # W0614: Unused import %s from wildcard import (since we need cli) 
 35   
 36  import textwrap 
 37  import itertools 
 38   
 39  from ganeti.cli import * 
 40  from ganeti import constants 
 41  from ganeti import opcodes 
 42  from ganeti import utils 
 43  from ganeti import errors 
 44  from ganeti import objects 
 45   
 46   
 47  #: default list of fields for L{ListNetworks} 
 48  _LIST_DEF_FIELDS = ["name", "network", "gateway", 
 49                      "mac_prefix", "group_list", "tags"] 
 50   
 51   
52 -def _HandleReservedIPs(ips):
53 if ips is None: 54 return None 55 elif not ips: 56 return [] 57 else: 58 return utils.UnescapeAndSplit(ips, sep=",")
59 60
61 -def AddNetwork(opts, args):
62 """Add a network to the cluster. 63 64 @param opts: the command line options selected by the user 65 @type args: list 66 @param args: a list of length 1 with the network name to create 67 @rtype: int 68 @return: the desired exit code 69 70 """ 71 (network_name, ) = args 72 73 if opts.network is None: 74 raise errors.OpPrereqError("The --network option must be given", 75 errors.ECODE_INVAL) 76 77 if opts.tags is not None: 78 tags = opts.tags.split(",") 79 else: 80 tags = [] 81 82 reserved_ips = _HandleReservedIPs(opts.add_reserved_ips) 83 84 op = opcodes.OpNetworkAdd(network_name=network_name, 85 gateway=opts.gateway, 86 network=opts.network, 87 gateway6=opts.gateway6, 88 network6=opts.network6, 89 mac_prefix=opts.mac_prefix, 90 add_reserved_ips=reserved_ips, 91 conflicts_check=opts.conflicts_check, 92 tags=tags) 93 SubmitOrSend(op, opts)
94 95
96 -def _GetDefaultGroups(cl, groups):
97 """Gets list of groups to operate on. 98 99 If C{groups} doesn't contain groups, a list of all groups in the cluster is 100 returned. 101 102 @type cl: L{luxi.Client} 103 @type groups: list 104 @rtype: list 105 106 """ 107 if groups: 108 return groups 109 110 return list(itertools.chain(*cl.QueryGroups([], ["uuid"], False)))
111 112
113 -def ConnectNetwork(opts, args):
114 """Map a network to a node group. 115 116 @param opts: the command line options selected by the user 117 @type args: list 118 @param args: Network, mode, physlink and node groups 119 @rtype: int 120 @return: the desired exit code 121 122 """ 123 cl = GetClient() 124 125 network = args[0] 126 nicparams = objects.FillDict(constants.NICC_DEFAULTS, opts.nicparams) 127 128 groups = _GetDefaultGroups(cl, args[1:]) 129 130 # TODO: Change logic to support "--submit" 131 for group in groups: 132 op = opcodes.OpNetworkConnect(group_name=group, 133 network_name=network, 134 network_mode=nicparams[constants.NIC_MODE], 135 network_link=nicparams[constants.NIC_LINK], 136 network_vlan=nicparams[constants.NIC_VLAN], 137 conflicts_check=opts.conflicts_check) 138 SubmitOpCode(op, opts=opts, cl=cl)
139 140
141 -def DisconnectNetwork(opts, args):
142 """Unmap a network from a node group. 143 144 @param opts: the command line options selected by the user 145 @type args: list 146 @param args: Network and node groups 147 @rtype: int 148 @return: the desired exit code 149 150 """ 151 cl = GetClient() 152 qcl = GetClient(query=True) 153 154 (network, ) = args[:1] 155 groups = _GetDefaultGroups(qcl, args[1:]) 156 157 # TODO: Change logic to support "--submit" 158 for group in groups: 159 op = opcodes.OpNetworkDisconnect(group_name=group, 160 network_name=network) 161 SubmitOpCode(op, opts=opts, cl=cl)
162 163
164 -def ListNetworks(opts, args):
165 """List Ip pools and their properties. 166 167 @param opts: the command line options selected by the user 168 @type args: list 169 @param args: networks to list, or empty for all 170 @rtype: int 171 @return: the desired exit code 172 173 """ 174 desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS) 175 fmtoverride = { 176 "group_list": 177 (lambda data: 178 utils.CommaJoin("%s (%s, %s, %s)" % (name, mode, link, vlan) 179 for (name, mode, link, vlan) in data), 180 False), 181 "inst_list": (",".join, False), 182 "tags": (",".join, False), 183 } 184 185 cl = GetClient(query=True) 186 return GenericList(constants.QR_NETWORK, desired_fields, args, None, 187 opts.separator, not opts.no_headers, 188 verbose=opts.verbose, format_override=fmtoverride, 189 cl=cl)
190 191
192 -def ListNetworkFields(opts, args):
193 """List network fields. 194 195 @param opts: the command line options selected by the user 196 @type args: list 197 @param args: fields to list, or empty for all 198 @rtype: int 199 @return: the desired exit code 200 201 """ 202 cl = GetClient(query=True) 203 204 return GenericListFields(constants.QR_NETWORK, args, opts.separator, 205 not opts.no_headers, cl=cl)
206 207
208 -def ShowNetworkConfig(_, args):
209 """Show network information. 210 211 @type args: list 212 @param args: should either be an empty list, in which case 213 we show information about all nodes, or should contain 214 a list of networks (names or UUIDs) to be queried for information 215 @rtype: int 216 @return: the desired exit code 217 218 """ 219 cl = GetClient(query=True) 220 result = cl.QueryNetworks(fields=["name", "network", "gateway", 221 "network6", "gateway6", 222 "mac_prefix", 223 "free_count", "reserved_count", 224 "map", "group_list", "inst_list", 225 "external_reservations", 226 "serial_no", "uuid"], 227 names=args, use_locking=False) 228 229 for (name, network, gateway, network6, gateway6, 230 mac_prefix, free_count, reserved_count, 231 mapping, group_list, instances, ext_res, serial, uuid) in result: 232 size = free_count + reserved_count 233 ToStdout("Network name: %s", name) 234 ToStdout("UUID: %s", uuid) 235 ToStdout("Serial number: %d", serial) 236 ToStdout(" Subnet: %s", network) 237 ToStdout(" Gateway: %s", gateway) 238 ToStdout(" IPv6 Subnet: %s", network6) 239 ToStdout(" IPv6 Gateway: %s", gateway6) 240 ToStdout(" Mac Prefix: %s", mac_prefix) 241 ToStdout(" Size: %d", size) 242 ToStdout(" Free: %d (%.2f%%)", free_count, 243 100 * float(free_count) / float(size)) 244 ToStdout(" Usage map:") 245 lenmapping = len(mapping) 246 idx = 0 247 while idx < lenmapping: 248 line = mapping[idx: idx + 64] 249 ToStdout(" %s %s %d", str(idx).rjust(4), line.ljust(64), idx + 63) 250 idx += 64 251 ToStdout(" (X) used (.) free") 252 253 if ext_res: 254 ToStdout(" externally reserved IPs:") 255 for line in textwrap.wrap(ext_res, width=64): 256 ToStdout(" %s" % line) 257 258 if group_list: 259 ToStdout(" connected to node groups:") 260 for group, nic_mode, nic_link, nic_vlan in group_list: 261 ToStdout(" %s (mode:%s link:%s vlan:%s)", 262 group, nic_mode, nic_link, nic_vlan) 263 else: 264 ToStdout(" not connected to any node group") 265 266 if instances: 267 ToStdout(" used by %d instances:", len(instances)) 268 for name in instances: 269 ((ips, networks), ) = cl.QueryInstances([name], 270 ["nic.ips", "nic.networks"], 271 use_locking=False) 272 273 l = lambda value: ", ".join(str(idx) + ":" + str(ip) 274 for idx, (ip, net) in enumerate(value) 275 if net == uuid) 276 277 ToStdout(" %s: %s", name, l(zip(ips, networks))) 278 else: 279 ToStdout(" not used by any instances")
280 281
282 -def SetNetworkParams(opts, args):
283 """Modifies an IP address pool's parameters. 284 285 @param opts: the command line options selected by the user 286 @type args: list 287 @param args: should contain only one element, the node group name 288 289 @rtype: int 290 @return: the desired exit code 291 292 """ 293 # TODO: add "network": opts.network, 294 all_changes = { 295 "gateway": opts.gateway, 296 "add_reserved_ips": _HandleReservedIPs(opts.add_reserved_ips), 297 "remove_reserved_ips": _HandleReservedIPs(opts.remove_reserved_ips), 298 "mac_prefix": opts.mac_prefix, 299 "gateway6": opts.gateway6, 300 "network6": opts.network6, 301 } 302 303 if all_changes.values().count(None) == len(all_changes): 304 ToStderr("Please give at least one of the parameters.") 305 return 1 306 307 # pylint: disable=W0142 308 op = opcodes.OpNetworkSetParams(network_name=args[0], **all_changes) 309 310 # TODO: add feedback to user, e.g. list the modifications 311 SubmitOrSend(op, opts)
312 313
314 -def RemoveNetwork(opts, args):
315 """Remove an IP address pool from the cluster. 316 317 @param opts: the command line options selected by the user 318 @type args: list 319 @param args: a list of length 1 with the id of the IP address pool to remove 320 @rtype: int 321 @return: the desired exit code 322 323 """ 324 (network_name,) = args 325 op = opcodes.OpNetworkRemove(network_name=network_name, force=opts.force) 326 SubmitOrSend(op, opts)
327 328 329 commands = { 330 "add": ( 331 AddNetwork, ARGS_ONE_NETWORK, 332 [DRY_RUN_OPT, NETWORK_OPT, GATEWAY_OPT, ADD_RESERVED_IPS_OPT, 333 MAC_PREFIX_OPT, NETWORK6_OPT, GATEWAY6_OPT, 334 NOCONFLICTSCHECK_OPT, TAG_ADD_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 335 "<network_name>", "Add a new IP network to the cluster"), 336 "list": ( 337 ListNetworks, ARGS_MANY_NETWORKS, 338 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT], 339 "[<network_id>...]", 340 "Lists the IP networks in the cluster. The available fields can be shown" 341 " using the \"list-fields\" command (see the man page for details)." 342 " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)), 343 "list-fields": ( 344 ListNetworkFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]", 345 "Lists all available fields for networks"), 346 "info": ( 347 ShowNetworkConfig, ARGS_MANY_NETWORKS, [], 348 "[<network_name>...]", "Show information about the network(s)"), 349 "modify": ( 350 SetNetworkParams, ARGS_ONE_NETWORK, 351 [DRY_RUN_OPT] + SUBMIT_OPTS + 352 [ADD_RESERVED_IPS_OPT, 353 REMOVE_RESERVED_IPS_OPT, GATEWAY_OPT, MAC_PREFIX_OPT, NETWORK6_OPT, 354 GATEWAY6_OPT, PRIORITY_OPT], 355 "<network_name>", "Alters the parameters of a network"), 356 "connect": ( 357 ConnectNetwork, 358 [ArgNetwork(min=1, max=1), 359 ArgGroup()], 360 [NOCONFLICTSCHECK_OPT, PRIORITY_OPT, NIC_PARAMS_OPT], 361 "<network_name> [<node_group>...]", 362 "Map a given network to the specified node group" 363 " with given mode and link (netparams)"), 364 "disconnect": ( 365 DisconnectNetwork, 366 [ArgNetwork(min=1, max=1), ArgGroup()], 367 [PRIORITY_OPT], 368 "<network_name> [<node_group>...]", 369 "Unmap a given network from a specified node group"), 370 "remove": ( 371 RemoveNetwork, ARGS_ONE_NETWORK, 372 [FORCE_OPT, DRY_RUN_OPT] + SUBMIT_OPTS + [PRIORITY_OPT], 373 "[--dry-run] <network_id>", 374 "Remove an (empty) network from the cluster"), 375 "list-tags": ( 376 ListTags, ARGS_ONE_NETWORK, [], 377 "<network_name>", "List the tags of the given network"), 378 "add-tags": ( 379 AddTags, [ArgNetwork(min=1, max=1), ArgUnknown()], 380 [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 381 "<network_name> tag...", "Add tags to the given network"), 382 "remove-tags": ( 383 RemoveTags, [ArgNetwork(min=1, max=1), ArgUnknown()], 384 [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 385 "<network_name> tag...", "Remove tags from given network"), 386 } 387 388
389 -def Main():
390 return GenericMain(commands, override={"tag_type": constants.TAG_NETWORK})
391