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 153 (network, ) = args[:1] 154 groups = _GetDefaultGroups(cl, args[1:]) 155 156 # TODO: Change logic to support "--submit" 157 for group in groups: 158 op = opcodes.OpNetworkDisconnect(group_name=group, 159 network_name=network) 160 SubmitOpCode(op, opts=opts, cl=cl)
161 162
163 -def ListNetworks(opts, args):
164 """List Ip pools and their properties. 165 166 @param opts: the command line options selected by the user 167 @type args: list 168 @param args: networks to list, or empty for all 169 @rtype: int 170 @return: the desired exit code 171 172 """ 173 desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS) 174 fmtoverride = { 175 "group_list": 176 (lambda data: 177 utils.CommaJoin("%s (%s, %s, %s)" % (name, mode, link, vlan) 178 for (name, mode, link, vlan) in data), 179 False), 180 "inst_list": (",".join, False), 181 "tags": (",".join, False), 182 } 183 184 cl = GetClient() 185 return GenericList(constants.QR_NETWORK, desired_fields, args, None, 186 opts.separator, not opts.no_headers, 187 verbose=opts.verbose, format_override=fmtoverride, 188 cl=cl)
189 190
191 -def ListNetworkFields(opts, args):
192 """List network fields. 193 194 @param opts: the command line options selected by the user 195 @type args: list 196 @param args: fields to list, or empty for all 197 @rtype: int 198 @return: the desired exit code 199 200 """ 201 cl = GetClient() 202 203 return GenericListFields(constants.QR_NETWORK, args, opts.separator, 204 not opts.no_headers, cl=cl)
205 206
207 -def ShowNetworkConfig(_, args):
208 """Show network information. 209 210 @type args: list 211 @param args: should either be an empty list, in which case 212 we show information about all nodes, or should contain 213 a list of networks (names or UUIDs) to be queried for information 214 @rtype: int 215 @return: the desired exit code 216 217 """ 218 cl = GetClient() 219 result = cl.QueryNetworks(fields=["name", "network", "gateway", 220 "network6", "gateway6", 221 "mac_prefix", 222 "free_count", "reserved_count", 223 "map", "group_list", "inst_list", 224 "external_reservations", 225 "serial_no", "uuid"], 226 names=args, use_locking=False) 227 228 for (name, network, gateway, network6, gateway6, 229 mac_prefix, free_count, reserved_count, 230 mapping, group_list, instances, ext_res, serial, uuid) in result: 231 size = free_count + reserved_count 232 ToStdout("Network name: %s", name) 233 ToStdout("UUID: %s", uuid) 234 ToStdout("Serial number: %d", serial) 235 ToStdout(" Subnet: %s", network) 236 ToStdout(" Gateway: %s", gateway) 237 ToStdout(" IPv6 Subnet: %s", network6) 238 ToStdout(" IPv6 Gateway: %s", gateway6) 239 ToStdout(" Mac Prefix: %s", mac_prefix) 240 ToStdout(" Size: %d", size) 241 ToStdout(" Free: %d (%.2f%%)", free_count, 242 100 * float(free_count) / float(size)) 243 ToStdout(" Usage map:") 244 lenmapping = len(mapping) 245 idx = 0 246 while idx < lenmapping: 247 line = mapping[idx: idx + 64] 248 ToStdout(" %s %s %d", str(idx).rjust(4), line.ljust(64), idx + 63) 249 idx += 64 250 ToStdout(" (X) used (.) free") 251 252 if ext_res: 253 ToStdout(" externally reserved IPs:") 254 for line in textwrap.wrap(ext_res, width=64): 255 ToStdout(" %s" % line) 256 257 if group_list: 258 ToStdout(" connected to node groups:") 259 for group, nic_mode, nic_link, nic_vlan in group_list: 260 ToStdout(" %s (mode:%s link:%s vlan:%s)", 261 group, nic_mode, nic_link, nic_vlan) 262 else: 263 ToStdout(" not connected to any node group") 264 265 if instances: 266 ToStdout(" used by %d instances:", len(instances)) 267 for name in instances: 268 ((ips, networks), ) = cl.QueryInstances([name], 269 ["nic.ips", "nic.networks"], 270 use_locking=False) 271 272 l = lambda value: ", ".join(str(idx) + ":" + str(ip) 273 for idx, (ip, net) in enumerate(value) 274 if net == uuid) 275 276 ToStdout(" %s: %s", name, l(zip(ips, networks))) 277 else: 278 ToStdout(" not used by any instances")
279 280
281 -def SetNetworkParams(opts, args):
282 """Modifies an IP address pool's parameters. 283 284 @param opts: the command line options selected by the user 285 @type args: list 286 @param args: should contain only one element, the node group name 287 288 @rtype: int 289 @return: the desired exit code 290 291 """ 292 # TODO: add "network": opts.network, 293 all_changes = { 294 "gateway": opts.gateway, 295 "add_reserved_ips": _HandleReservedIPs(opts.add_reserved_ips), 296 "remove_reserved_ips": _HandleReservedIPs(opts.remove_reserved_ips), 297 "mac_prefix": opts.mac_prefix, 298 "gateway6": opts.gateway6, 299 "network6": opts.network6, 300 } 301 302 if all_changes.values().count(None) == len(all_changes): 303 ToStderr("Please give at least one of the parameters.") 304 return 1 305 306 # pylint: disable=W0142 307 op = opcodes.OpNetworkSetParams(network_name=args[0], **all_changes) 308 309 # TODO: add feedback to user, e.g. list the modifications 310 SubmitOrSend(op, opts)
311 312
313 -def RemoveNetwork(opts, args):
314 """Remove an IP address pool from the cluster. 315 316 @param opts: the command line options selected by the user 317 @type args: list 318 @param args: a list of length 1 with the id of the IP address pool to remove 319 @rtype: int 320 @return: the desired exit code 321 322 """ 323 (network_name,) = args 324 op = opcodes.OpNetworkRemove(network_name=network_name, force=opts.force) 325 SubmitOrSend(op, opts)
326 327 328 commands = { 329 "add": ( 330 AddNetwork, ARGS_ONE_NETWORK, 331 [DRY_RUN_OPT, NETWORK_OPT, GATEWAY_OPT, ADD_RESERVED_IPS_OPT, 332 MAC_PREFIX_OPT, NETWORK6_OPT, GATEWAY6_OPT, 333 NOCONFLICTSCHECK_OPT, TAG_ADD_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 334 "<network_name>", "Add a new IP network to the cluster"), 335 "list": ( 336 ListNetworks, ARGS_MANY_NETWORKS, 337 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT], 338 "[<network_id>...]", 339 "Lists the IP networks in the cluster. The available fields can be shown" 340 " using the \"list-fields\" command (see the man page for details)." 341 " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)), 342 "list-fields": ( 343 ListNetworkFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]", 344 "Lists all available fields for networks"), 345 "info": ( 346 ShowNetworkConfig, ARGS_MANY_NETWORKS, [], 347 "[<network_name>...]", "Show information about the network(s)"), 348 "modify": ( 349 SetNetworkParams, ARGS_ONE_NETWORK, 350 [DRY_RUN_OPT] + SUBMIT_OPTS + 351 [ADD_RESERVED_IPS_OPT, 352 REMOVE_RESERVED_IPS_OPT, GATEWAY_OPT, MAC_PREFIX_OPT, NETWORK6_OPT, 353 GATEWAY6_OPT, PRIORITY_OPT], 354 "<network_name>", "Alters the parameters of a network"), 355 "connect": ( 356 ConnectNetwork, 357 [ArgNetwork(min=1, max=1), 358 ArgGroup()], 359 [NOCONFLICTSCHECK_OPT, PRIORITY_OPT, NIC_PARAMS_OPT], 360 "<network_name> [<node_group>...]", 361 "Map a given network to the specified node group" 362 " with given mode and link (netparams)"), 363 "disconnect": ( 364 DisconnectNetwork, 365 [ArgNetwork(min=1, max=1), ArgGroup()], 366 [PRIORITY_OPT], 367 "<network_name> [<node_group>...]", 368 "Unmap a given network from a specified node group"), 369 "remove": ( 370 RemoveNetwork, ARGS_ONE_NETWORK, 371 [FORCE_OPT, DRY_RUN_OPT] + SUBMIT_OPTS + [PRIORITY_OPT], 372 "[--dry-run] <network_id>", 373 "Remove an (empty) network from the cluster"), 374 "list-tags": ( 375 ListTags, ARGS_ONE_NETWORK, [], 376 "<network_name>", "List the tags of the given network"), 377 "add-tags": ( 378 AddTags, [ArgNetwork(min=1, max=1), ArgUnknown()], 379 [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 380 "<network_name> tag...", "Add tags to the given network"), 381 "remove-tags": ( 382 RemoveTags, [ArgNetwork(min=1, max=1), ArgUnknown()], 383 [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 384 "<network_name> tag...", "Remove tags from given network"), 385 } 386 387
388 -def Main():
389 return GenericMain(commands, override={"tag_type": constants.TAG_NETWORK})
390