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(query=True) 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(query=True) 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 idx = 0 245 for line in textwrap.wrap(mapping, width=64): 246 ToStdout(" %s %s %d", str(idx).rjust(3), line.ljust(64), idx + 63) 247 idx += 64 248 ToStdout(" (X) used (.) free") 249 250 if ext_res: 251 ToStdout(" externally reserved IPs:") 252 for line in textwrap.wrap(ext_res, width=64): 253 ToStdout(" %s" % line) 254 255 if group_list: 256 ToStdout(" connected to node groups:") 257 for group, nic_mode, nic_link, nic_vlan in group_list: 258 ToStdout(" %s (mode:%s link:%s vlan:%s)", 259 group, nic_mode, nic_link, nic_vlan) 260 else: 261 ToStdout(" not connected to any node group") 262 263 if instances: 264 ToStdout(" used by %d instances:", len(instances)) 265 for name in instances: 266 ((ips, networks), ) = cl.QueryInstances([name], 267 ["nic.ips", "nic.networks"], 268 use_locking=False) 269 270 l = lambda value: ", ".join(str(idx) + ":" + str(ip) 271 for idx, (ip, net) in enumerate(value) 272 if net == uuid) 273 274 ToStdout(" %s: %s", name, l(zip(ips, networks))) 275 else: 276 ToStdout(" not used by any instances")
277 278
279 -def SetNetworkParams(opts, args):
280 """Modifies an IP address pool's parameters. 281 282 @param opts: the command line options selected by the user 283 @type args: list 284 @param args: should contain only one element, the node group name 285 286 @rtype: int 287 @return: the desired exit code 288 289 """ 290 # TODO: add "network": opts.network, 291 all_changes = { 292 "gateway": opts.gateway, 293 "add_reserved_ips": _HandleReservedIPs(opts.add_reserved_ips), 294 "remove_reserved_ips": _HandleReservedIPs(opts.remove_reserved_ips), 295 "mac_prefix": opts.mac_prefix, 296 "gateway6": opts.gateway6, 297 "network6": opts.network6, 298 } 299 300 if all_changes.values().count(None) == len(all_changes): 301 ToStderr("Please give at least one of the parameters.") 302 return 1 303 304 # pylint: disable=W0142 305 op = opcodes.OpNetworkSetParams(network_name=args[0], **all_changes) 306 307 # TODO: add feedback to user, e.g. list the modifications 308 SubmitOrSend(op, opts)
309 310
311 -def RemoveNetwork(opts, args):
312 """Remove an IP address pool from the cluster. 313 314 @param opts: the command line options selected by the user 315 @type args: list 316 @param args: a list of length 1 with the id of the IP address pool to remove 317 @rtype: int 318 @return: the desired exit code 319 320 """ 321 (network_name,) = args 322 op = opcodes.OpNetworkRemove(network_name=network_name, force=opts.force) 323 SubmitOrSend(op, opts)
324 325 326 commands = { 327 "add": ( 328 AddNetwork, ARGS_ONE_NETWORK, 329 [DRY_RUN_OPT, NETWORK_OPT, GATEWAY_OPT, ADD_RESERVED_IPS_OPT, 330 MAC_PREFIX_OPT, NETWORK6_OPT, GATEWAY6_OPT, 331 NOCONFLICTSCHECK_OPT, TAG_ADD_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 332 "<network_name>", "Add a new IP network to the cluster"), 333 "list": ( 334 ListNetworks, ARGS_MANY_NETWORKS, 335 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT], 336 "[<network_id>...]", 337 "Lists the IP networks in the cluster. The available fields can be shown" 338 " using the \"list-fields\" command (see the man page for details)." 339 " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)), 340 "list-fields": ( 341 ListNetworkFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]", 342 "Lists all available fields for networks"), 343 "info": ( 344 ShowNetworkConfig, ARGS_MANY_NETWORKS, [], 345 "[<network_name>...]", "Show information about the network(s)"), 346 "modify": ( 347 SetNetworkParams, ARGS_ONE_NETWORK, 348 [DRY_RUN_OPT] + SUBMIT_OPTS + 349 [ADD_RESERVED_IPS_OPT, 350 REMOVE_RESERVED_IPS_OPT, GATEWAY_OPT, MAC_PREFIX_OPT, NETWORK6_OPT, 351 GATEWAY6_OPT, PRIORITY_OPT], 352 "<network_name>", "Alters the parameters of a network"), 353 "connect": ( 354 ConnectNetwork, 355 [ArgNetwork(min=1, max=1), 356 ArgGroup()], 357 [NOCONFLICTSCHECK_OPT, PRIORITY_OPT, NIC_PARAMS_OPT], 358 "<network_name> [<node_group>...]", 359 "Map a given network to the specified node group" 360 " with given mode and link (netparams)"), 361 "disconnect": ( 362 DisconnectNetwork, 363 [ArgNetwork(min=1, max=1), ArgGroup()], 364 [PRIORITY_OPT], 365 "<network_name> [<node_group>...]", 366 "Unmap a given network from a specified node group"), 367 "remove": ( 368 RemoveNetwork, ARGS_ONE_NETWORK, 369 [FORCE_OPT, DRY_RUN_OPT] + SUBMIT_OPTS + [PRIORITY_OPT], 370 "[--dry-run] <network_id>", 371 "Remove an (empty) network from the cluster"), 372 "list-tags": ( 373 ListTags, ARGS_ONE_NETWORK, [], 374 "<network_name>", "List the tags of the given network"), 375 "add-tags": ( 376 AddTags, [ArgNetwork(min=1, max=1), ArgUnknown()], 377 [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 378 "<network_name> tag...", "Add tags to the given network"), 379 "remove-tags": ( 380 RemoveTags, [ArgNetwork(min=1, max=1), ArgUnknown()], 381 [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 382 "<network_name> tag...", "Remove tags from given network"), 383 } 384 385
386 -def Main():
387 return GenericMain(commands, override={"tag_type": constants.TAG_NETWORK})
388