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