1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 """IP pool related commands"""
31
32
33
34
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
48 _LIST_DEF_FIELDS = ["name", "network", "gateway",
49 "mac_prefix", "group_list", "tags"]
50
51
53 if ips is None:
54 return None
55 elif not ips:
56 return []
57 else:
58 return utils.UnescapeAndSplit(ips, sep=",")
59
60
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
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
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
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
162
163
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
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
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
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
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
308 op = opcodes.OpNetworkSetParams(network_name=args[0], **all_changes)
309
310
311 SubmitOrSend(op, opts)
312
313
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
390 return GenericMain(commands, override={"tag_type": constants.TAG_NETWORK})
391