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  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, but 
 12  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 14  # General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
 19  # 02110-1301, USA. 
 20   
 21  """IP pool related commands""" 
 22   
 23  # pylint: disable=W0401,W0614 
 24  # W0401: Wildcard import ganeti.cli 
 25  # W0614: Unused import %s from wildcard import (since we need cli) 
 26   
 27  import textwrap 
 28  import itertools 
 29   
 30  from ganeti.cli import * 
 31  from ganeti import constants 
 32  from ganeti import opcodes 
 33  from ganeti import utils 
 34  from ganeti import errors 
 35   
 36   
 37  #: default list of fields for L{ListNetworks} 
 38  _LIST_DEF_FIELDS = ["name", "network", "gateway", 
 39                      "mac_prefix", "group_list", "tags"] 
 40   
 41   
42 -def _HandleReservedIPs(ips):
43 if ips is None: 44 return None 45 elif not ips: 46 return [] 47 else: 48 return utils.UnescapeAndSplit(ips, sep=",")
49 50
51 -def AddNetwork(opts, args):
52 """Add a network to the cluster. 53 54 @param opts: the command line options selected by the user 55 @type args: list 56 @param args: a list of length 1 with the network name to create 57 @rtype: int 58 @return: the desired exit code 59 60 """ 61 (network_name, ) = args 62 63 if opts.network is None: 64 raise errors.OpPrereqError("The --network option must be given", 65 errors.ECODE_INVAL) 66 67 if opts.tags is not None: 68 tags = opts.tags.split(",") 69 else: 70 tags = [] 71 72 reserved_ips = _HandleReservedIPs(opts.add_reserved_ips) 73 74 op = opcodes.OpNetworkAdd(network_name=network_name, 75 gateway=opts.gateway, 76 network=opts.network, 77 gateway6=opts.gateway6, 78 network6=opts.network6, 79 mac_prefix=opts.mac_prefix, 80 add_reserved_ips=reserved_ips, 81 conflicts_check=opts.conflicts_check, 82 tags=tags) 83 SubmitOrSend(op, opts)
84 85
86 -def _GetDefaultGroups(cl, groups):
87 """Gets list of groups to operate on. 88 89 If C{groups} doesn't contain groups, a list of all groups in the cluster is 90 returned. 91 92 @type cl: L{luxi.Client} 93 @type groups: list 94 @rtype: list 95 96 """ 97 if groups: 98 return groups 99 100 return list(itertools.chain(*cl.QueryGroups([], ["uuid"], False)))
101 102
103 -def ConnectNetwork(opts, args):
104 """Map a network to a node group. 105 106 @param opts: the command line options selected by the user 107 @type args: list 108 @param args: Network, mode, physlink and node groups 109 @rtype: int 110 @return: the desired exit code 111 112 """ 113 cl = GetClient() 114 115 (network, mode, link) = args[:3] 116 groups = _GetDefaultGroups(cl, args[3:]) 117 118 # TODO: Change logic to support "--submit" 119 for group in groups: 120 op = opcodes.OpNetworkConnect(group_name=group, 121 network_name=network, 122 network_mode=mode, 123 network_link=link, 124 conflicts_check=opts.conflicts_check) 125 SubmitOpCode(op, opts=opts, cl=cl)
126 127
128 -def DisconnectNetwork(opts, args):
129 """Unmap a network from a node group. 130 131 @param opts: the command line options selected by the user 132 @type args: list 133 @param args: Network and node groups 134 @rtype: int 135 @return: the desired exit code 136 137 """ 138 cl = GetClient() 139 140 (network, ) = args[:1] 141 groups = _GetDefaultGroups(cl, args[1:]) 142 143 # TODO: Change logic to support "--submit" 144 for group in groups: 145 op = opcodes.OpNetworkDisconnect(group_name=group, 146 network_name=network) 147 SubmitOpCode(op, opts=opts, cl=cl)
148 149
150 -def ListNetworks(opts, args):
151 """List Ip pools and their properties. 152 153 @param opts: the command line options selected by the user 154 @type args: list 155 @param args: networks to list, or empty for all 156 @rtype: int 157 @return: the desired exit code 158 159 """ 160 desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS) 161 fmtoverride = { 162 "group_list": 163 (lambda data: utils.CommaJoin("%s (%s, %s)" % (name, mode, link) 164 for (name, mode, link) in data), 165 False), 166 "inst_list": (",".join, False), 167 "tags": (",".join, False), 168 } 169 170 cl = GetClient(query=True) 171 return GenericList(constants.QR_NETWORK, desired_fields, args, None, 172 opts.separator, not opts.no_headers, 173 verbose=opts.verbose, format_override=fmtoverride, 174 cl=cl)
175 176
177 -def ListNetworkFields(opts, args):
178 """List network fields. 179 180 @param opts: the command line options selected by the user 181 @type args: list 182 @param args: fields to list, or empty for all 183 @rtype: int 184 @return: the desired exit code 185 186 """ 187 cl = GetClient(query=True) 188 189 return GenericListFields(constants.QR_NETWORK, args, opts.separator, 190 not opts.no_headers, cl=cl)
191 192
193 -def ShowNetworkConfig(_, args):
194 """Show network information. 195 196 @type args: list 197 @param args: should either be an empty list, in which case 198 we show information about all nodes, or should contain 199 a list of networks (names or UUIDs) to be queried for information 200 @rtype: int 201 @return: the desired exit code 202 203 """ 204 cl = GetClient() 205 result = cl.QueryNetworks(fields=["name", "network", "gateway", 206 "network6", "gateway6", 207 "mac_prefix", 208 "free_count", "reserved_count", 209 "map", "group_list", "inst_list", 210 "external_reservations", 211 "serial_no", "uuid"], 212 names=args, use_locking=False) 213 214 for (name, network, gateway, network6, gateway6, 215 mac_prefix, free_count, reserved_count, 216 mapping, group_list, instances, ext_res, serial, uuid) in result: 217 size = free_count + reserved_count 218 ToStdout("Network name: %s", name) 219 ToStdout("UUID: %s", uuid) 220 ToStdout("Serial number: %d", serial) 221 ToStdout(" Subnet: %s", network) 222 ToStdout(" Gateway: %s", gateway) 223 ToStdout(" IPv6 Subnet: %s", network6) 224 ToStdout(" IPv6 Gateway: %s", gateway6) 225 ToStdout(" Mac Prefix: %s", mac_prefix) 226 ToStdout(" Size: %d", size) 227 ToStdout(" Free: %d (%.2f%%)", free_count, 228 100 * float(free_count) / float(size)) 229 ToStdout(" Usage map:") 230 idx = 0 231 for line in textwrap.wrap(mapping, width=64): 232 ToStdout(" %s %s %d", str(idx).rjust(3), line.ljust(64), idx + 63) 233 idx += 64 234 ToStdout(" (X) used (.) free") 235 236 if ext_res: 237 ToStdout(" externally reserved IPs:") 238 for line in textwrap.wrap(ext_res, width=64): 239 ToStdout(" %s" % line) 240 241 if group_list: 242 ToStdout(" connected to node groups:") 243 for group, nic_mode, nic_link in group_list: 244 ToStdout(" %s (%s on %s)", group, nic_mode, nic_link) 245 else: 246 ToStdout(" not connected to any node group") 247 248 if instances: 249 ToStdout(" used by %d instances:", len(instances)) 250 for inst in instances: 251 ((ips, networks), ) = cl.QueryInstances([inst], 252 ["nic.ips", "nic.networks"], 253 use_locking=False) 254 255 l = lambda value: ", ".join(str(idx) + ":" + str(ip) 256 for idx, (ip, net) in enumerate(value) 257 if net == uuid) 258 259 ToStdout(" %s : %s", inst, l(zip(ips, networks))) 260 else: 261 ToStdout(" not used by any instances")
262 263
264 -def SetNetworkParams(opts, args):
265 """Modifies an IP address pool's parameters. 266 267 @param opts: the command line options selected by the user 268 @type args: list 269 @param args: should contain only one element, the node group name 270 271 @rtype: int 272 @return: the desired exit code 273 274 """ 275 # TODO: add "network": opts.network, 276 all_changes = { 277 "gateway": opts.gateway, 278 "add_reserved_ips": _HandleReservedIPs(opts.add_reserved_ips), 279 "remove_reserved_ips": _HandleReservedIPs(opts.remove_reserved_ips), 280 "mac_prefix": opts.mac_prefix, 281 "gateway6": opts.gateway6, 282 "network6": opts.network6, 283 } 284 285 if all_changes.values().count(None) == len(all_changes): 286 ToStderr("Please give at least one of the parameters.") 287 return 1 288 289 # pylint: disable=W0142 290 op = opcodes.OpNetworkSetParams(network_name=args[0], **all_changes) 291 292 # TODO: add feedback to user, e.g. list the modifications 293 SubmitOrSend(op, opts)
294 295
296 -def RemoveNetwork(opts, args):
297 """Remove an IP address pool from the cluster. 298 299 @param opts: the command line options selected by the user 300 @type args: list 301 @param args: a list of length 1 with the id of the IP address pool to remove 302 @rtype: int 303 @return: the desired exit code 304 305 """ 306 (network_name,) = args 307 op = opcodes.OpNetworkRemove(network_name=network_name, force=opts.force) 308 SubmitOrSend(op, opts)
309 310 311 commands = { 312 "add": ( 313 AddNetwork, ARGS_ONE_NETWORK, 314 [DRY_RUN_OPT, NETWORK_OPT, GATEWAY_OPT, ADD_RESERVED_IPS_OPT, 315 MAC_PREFIX_OPT, NETWORK6_OPT, GATEWAY6_OPT, 316 NOCONFLICTSCHECK_OPT, TAG_ADD_OPT, PRIORITY_OPT, SUBMIT_OPT], 317 "<network_name>", "Add a new IP network to the cluster"), 318 "list": ( 319 ListNetworks, ARGS_MANY_NETWORKS, 320 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT], 321 "[<network_id>...]", 322 "Lists the IP networks in the cluster. The available fields can be shown" 323 " using the \"list-fields\" command (see the man page for details)." 324 " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)), 325 "list-fields": ( 326 ListNetworkFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]", 327 "Lists all available fields for networks"), 328 "info": ( 329 ShowNetworkConfig, ARGS_MANY_NETWORKS, [], 330 "[<network_name>...]", "Show information about the network(s)"), 331 "modify": ( 332 SetNetworkParams, ARGS_ONE_NETWORK, 333 [DRY_RUN_OPT, SUBMIT_OPT, ADD_RESERVED_IPS_OPT, REMOVE_RESERVED_IPS_OPT, 334 GATEWAY_OPT, MAC_PREFIX_OPT, NETWORK6_OPT, GATEWAY6_OPT, 335 PRIORITY_OPT], 336 "<network_name>", "Alters the parameters of a network"), 337 "connect": ( 338 ConnectNetwork, 339 [ArgNetwork(min=1, max=1), 340 ArgChoice(min=1, max=1, choices=constants.NIC_VALID_MODES), 341 ArgUnknown(min=1, max=1), 342 ArgGroup()], 343 [NOCONFLICTSCHECK_OPT, PRIORITY_OPT], 344 "<network_name> <mode> <link> [<node_group>...]", 345 "Map a given network to the specified node group" 346 " with given mode and link (netparams)"), 347 "disconnect": ( 348 DisconnectNetwork, 349 [ArgNetwork(min=1, max=1), ArgGroup()], 350 [PRIORITY_OPT], 351 "<network_name> [<node_group>...]", 352 "Unmap a given network from a specified node group"), 353 "remove": ( 354 RemoveNetwork, ARGS_ONE_NETWORK, 355 [FORCE_OPT, DRY_RUN_OPT, SUBMIT_OPT, PRIORITY_OPT], 356 "[--dry-run] <network_id>", 357 "Remove an (empty) network from the cluster"), 358 "list-tags": ( 359 ListTags, ARGS_ONE_NETWORK, [], 360 "<network_name>", "List the tags of the given network"), 361 "add-tags": ( 362 AddTags, [ArgNetwork(min=1, max=1), ArgUnknown()], 363 [TAG_SRC_OPT, PRIORITY_OPT, SUBMIT_OPT], 364 "<network_name> tag...", "Add tags to the given network"), 365 "remove-tags": ( 366 RemoveTags, [ArgNetwork(min=1, max=1), ArgUnknown()], 367 [TAG_SRC_OPT, PRIORITY_OPT, SUBMIT_OPT], 368 "<network_name> tag...", "Remove tags from given network"), 369 } 370 371
372 -def Main():
373 return GenericMain(commands, override={"tag_type": constants.TAG_NETWORK})
374