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
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
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
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
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
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
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
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
305 op = opcodes.OpNetworkSetParams(network_name=args[0], **all_changes)
306
307
308 SubmitOrSend(op, opts)
309
310
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
387 return GenericMain(commands, override={"tag_type": constants.TAG_NETWORK})
388