mreg-cli 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. mreg_cli/__about__.py +7 -0
  2. mreg_cli/__init__.py +5 -0
  3. mreg_cli/__main__.py +8 -0
  4. mreg_cli/_version.py +16 -0
  5. mreg_cli/api/__init__.py +7 -0
  6. mreg_cli/api/abstracts.py +486 -0
  7. mreg_cli/api/endpoints.py +130 -0
  8. mreg_cli/api/fields.py +104 -0
  9. mreg_cli/api/history.py +152 -0
  10. mreg_cli/api/models.py +3416 -0
  11. mreg_cli/cli.py +382 -0
  12. mreg_cli/commands/__init__.py +1 -0
  13. mreg_cli/commands/base.py +62 -0
  14. mreg_cli/commands/dhcp.py +136 -0
  15. mreg_cli/commands/group.py +326 -0
  16. mreg_cli/commands/help.py +77 -0
  17. mreg_cli/commands/host.py +54 -0
  18. mreg_cli/commands/host_submodules/__init__.py +28 -0
  19. mreg_cli/commands/host_submodules/a_aaaa.py +452 -0
  20. mreg_cli/commands/host_submodules/bacnet.py +126 -0
  21. mreg_cli/commands/host_submodules/cname.py +166 -0
  22. mreg_cli/commands/host_submodules/core.py +507 -0
  23. mreg_cli/commands/host_submodules/rr.py +973 -0
  24. mreg_cli/commands/label.py +146 -0
  25. mreg_cli/commands/logging.py +112 -0
  26. mreg_cli/commands/network.py +516 -0
  27. mreg_cli/commands/permission.py +202 -0
  28. mreg_cli/commands/policy.py +519 -0
  29. mreg_cli/commands/recording.py +59 -0
  30. mreg_cli/commands/registry.py +56 -0
  31. mreg_cli/commands/root.py +58 -0
  32. mreg_cli/commands/zone.py +288 -0
  33. mreg_cli/config.py +253 -0
  34. mreg_cli/errorbuilder.py +193 -0
  35. mreg_cli/exceptions.py +237 -0
  36. mreg_cli/help_formatter.py +38 -0
  37. mreg_cli/main.py +238 -0
  38. mreg_cli/outputmanager.py +466 -0
  39. mreg_cli/py.typed +0 -0
  40. mreg_cli/tags.txt +55 -0
  41. mreg_cli/tokenfile.py +89 -0
  42. mreg_cli/types.py +160 -0
  43. mreg_cli/utilities/__init__.py +5 -0
  44. mreg_cli/utilities/api.py +595 -0
  45. mreg_cli/utilities/shared.py +65 -0
  46. mreg_cli/utilities/validators.py +19 -0
  47. mreg_cli-1.0.0.dist-info/AUTHORS +12 -0
  48. mreg_cli-1.0.0.dist-info/LICENSE +674 -0
  49. mreg_cli-1.0.0.dist-info/METADATA +1079 -0
  50. mreg_cli-1.0.0.dist-info/RECORD +53 -0
  51. mreg_cli-1.0.0.dist-info/WHEEL +5 -0
  52. mreg_cli-1.0.0.dist-info/entry_points.txt +2 -0
  53. mreg_cli-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,516 @@
1
+ """Network commands for mreg_cli."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ from typing import Any
7
+
8
+ from mreg_cli.api.fields import IPAddressField
9
+ from mreg_cli.api.models import Network
10
+ from mreg_cli.commands.base import BaseCommand
11
+ from mreg_cli.commands.registry import CommandRegistry
12
+ from mreg_cli.exceptions import (
13
+ DeleteError,
14
+ EntityNotFound,
15
+ ForceMissing,
16
+ InputFailure,
17
+ NetworkOverlap,
18
+ )
19
+ from mreg_cli.outputmanager import OutputManager
20
+ from mreg_cli.types import Flag, QueryParams
21
+ from mreg_cli.utilities.shared import convert_wildcard_to_regex, string_to_int
22
+ from mreg_cli.utilities.validators import is_valid_category_tag, is_valid_location_tag
23
+
24
+ command_registry = CommandRegistry()
25
+
26
+
27
+ class NetworkCommands(BaseCommand):
28
+ """Network commands for the CLI."""
29
+
30
+ def __init__(self, cli: Any) -> None:
31
+ """Initialize the network commands."""
32
+ super().__init__(cli, command_registry, "network", "Manage networks.", "Manage networks")
33
+
34
+
35
+ ##########################################
36
+ # Implementation of sub command 'create' #
37
+ ##########################################
38
+
39
+
40
+ @command_registry.register_command(
41
+ prog="create",
42
+ description="Create a new network",
43
+ short_desc="Create a new network",
44
+ flags=[
45
+ Flag("-network", description="Network.", required=True, metavar="NETWORK"),
46
+ Flag(
47
+ "-desc",
48
+ description="Network description.",
49
+ required=True,
50
+ metavar="DESCRIPTION",
51
+ ),
52
+ Flag("-vlan", description="VLAN.", default=None, metavar="VLAN"),
53
+ Flag("-category", description="Category.", default=None, metavar="Category"),
54
+ Flag("-location", description="Location.", default=None, metavar="LOCATION"),
55
+ Flag("-frozen", description="Set frozen network.", action="store_true"),
56
+ ],
57
+ )
58
+ def create(args: argparse.Namespace) -> None:
59
+ """Create a new network.
60
+
61
+ :param args: argparse.Namespace (network, desc, vlan, category, location, frozen)
62
+ """
63
+ if args.vlan:
64
+ string_to_int(args.vlan, "VLAN")
65
+ if args.category and not is_valid_category_tag(args.category):
66
+ raise InputFailure("Not a valid category tag")
67
+ if args.location and not is_valid_location_tag(args.location):
68
+ raise InputFailure("Not a valid location tag")
69
+
70
+ arg_network = Network.str_to_network(args.network)
71
+ networks = Network.get_list()
72
+ for network in networks:
73
+ if network.overlaps(arg_network):
74
+ raise NetworkOverlap(
75
+ f"New network {arg_network} overlaps existing network {network.network}"
76
+ )
77
+
78
+ Network.create(
79
+ {
80
+ "network": args.network,
81
+ "description": args.desc,
82
+ "vlan": args.vlan,
83
+ "category": args.category,
84
+ "location": args.location,
85
+ "frozen": args.frozen,
86
+ }
87
+ )
88
+
89
+ OutputManager().add_ok(f"created network {args.network}")
90
+
91
+
92
+ @command_registry.register_command(
93
+ prog="info",
94
+ description="Display network info for one or more networks.",
95
+ short_desc="Display network info.",
96
+ flags=[
97
+ Flag(
98
+ "networks",
99
+ description="One or more networks.",
100
+ nargs="+",
101
+ metavar="NETWORK",
102
+ ),
103
+ ],
104
+ )
105
+ def info(args: argparse.Namespace) -> None:
106
+ """Display network info.
107
+
108
+ :param args: argparse.Namespace (networks)
109
+ """
110
+ networks = [Network.get_by_any_means_or_raise(net) for net in args.networks]
111
+ Network.output_multiple(networks)
112
+
113
+
114
+ @command_registry.register_command(
115
+ prog="find",
116
+ description="Search for networks based on a range of search parameters",
117
+ short_desc="Search for networks",
118
+ flags=[
119
+ Flag(
120
+ "-ip",
121
+ description="Exact IP address",
122
+ metavar="IP",
123
+ ),
124
+ Flag(
125
+ "-network",
126
+ description="Network address",
127
+ metavar="NETWORK",
128
+ ),
129
+ Flag(
130
+ "-description",
131
+ description="Description. Supports * as a wildcard",
132
+ metavar="DESCRIPTION",
133
+ ),
134
+ Flag(
135
+ "-vlan",
136
+ description="VLAN",
137
+ metavar="VLAN",
138
+ ),
139
+ Flag(
140
+ "-dns_delegated",
141
+ description="DNS delegation status (0 or 1)",
142
+ metavar="DNS-DELEGATED",
143
+ ),
144
+ Flag(
145
+ "-category",
146
+ description="Category",
147
+ metavar="CATEGORY",
148
+ ),
149
+ Flag(
150
+ "-location",
151
+ description="Location",
152
+ metavar="LOCATION",
153
+ ),
154
+ Flag(
155
+ "-frozen",
156
+ description="Frozen status (0 or 1)",
157
+ metavar="FROZEN",
158
+ ),
159
+ Flag(
160
+ "-reserved",
161
+ description="Exact number of reserved network addresses",
162
+ metavar="RESERVED",
163
+ ),
164
+ Flag(
165
+ "-addr-only",
166
+ description="Only print network address of matching networks",
167
+ action="store_true",
168
+ ),
169
+ Flag(
170
+ "-limit",
171
+ description="Maximum number of networks to print",
172
+ metavar="LIMIT",
173
+ flag_type=int,
174
+ ),
175
+ Flag(
176
+ "-silent",
177
+ description="Do not print meta info (number of networks found, limit reached, etc.)",
178
+ action="store_true",
179
+ ),
180
+ ],
181
+ )
182
+ def find(args: argparse.Namespace) -> None:
183
+ """List networks matching search criteria.
184
+
185
+ :param args: argparse.Namespace (limit, silent, addr_only, ip, network, description, vlan,
186
+ dns_delegated, category, location, frozen, reserved)
187
+ """
188
+ args_dict = vars(args)
189
+
190
+ if ip_arg := args_dict.get("ip"):
191
+ addr = IPAddressField(address=ip_arg)
192
+ networks = [Network.get_by_ip_or_raise(addr.address)]
193
+ else:
194
+ params: QueryParams = {}
195
+ param_names = [
196
+ "network",
197
+ "description",
198
+ "vlan",
199
+ "dns_delegated",
200
+ "category",
201
+ "location",
202
+ "frozen",
203
+ "reserved",
204
+ ]
205
+ for name in param_names:
206
+ value = args_dict.get(name)
207
+ if value is None:
208
+ continue
209
+ param, val = convert_wildcard_to_regex(name, value)
210
+ params[param] = val
211
+
212
+ if not params:
213
+ raise InputFailure("Need at least one search criteria")
214
+
215
+ networks = Network.get_by_query(params)
216
+
217
+ if not networks:
218
+ raise EntityNotFound("No networks matching the query were found.")
219
+
220
+ Network.output_multiple(networks)
221
+ if not args.silent:
222
+ s = "s" if len(networks) > 1 else ""
223
+ OutputManager().add_line(
224
+ f"\nFound {len(networks)} network{s} matching the search criteria."
225
+ )
226
+
227
+
228
+ @command_registry.register_command(
229
+ prog="list_unused_addresses",
230
+ description="Lists all the unused addresses for a network",
231
+ short_desc="Lists unused addresses",
232
+ flags=[
233
+ Flag("network", description="Network.", metavar="NETWORK"),
234
+ ],
235
+ )
236
+ def list_unused_addresses(args: argparse.Namespace) -> None:
237
+ """List all the unused addresses for a network.
238
+
239
+ :param args: argparse.Namespace (network)
240
+ """
241
+ net = Network.get_by_network_or_raise(args.network)
242
+ net.output_unused_addresses()
243
+
244
+
245
+ @command_registry.register_command(
246
+ prog="list_used_addresses",
247
+ description="Lists all the used addresses for a network",
248
+ short_desc="Lists all the used addresses for a network",
249
+ flags=[
250
+ Flag("network", description="Network.", metavar="NETWORK"),
251
+ ],
252
+ )
253
+ def list_used_addresses(args: argparse.Namespace) -> None:
254
+ """List all the used addresses for a network.
255
+
256
+ :param args: argparse.Namespace (network)
257
+ """
258
+ net = Network.get_by_network_or_raise(args.network)
259
+ net.output_used_addresses()
260
+
261
+
262
+ @command_registry.register_command(
263
+ prog="remove",
264
+ description="Remove network",
265
+ short_desc="Remove network",
266
+ flags=[
267
+ Flag("network", description="Network.", metavar="NETWORK"),
268
+ Flag("-force", action="store_true", description="Enable force."),
269
+ ],
270
+ )
271
+ def remove(args: argparse.Namespace) -> None:
272
+ """Remove network.
273
+
274
+ :param args: argparse.Namespace (network, force)
275
+ """
276
+ net = Network.get_by_any_means_or_raise(args.network)
277
+ if net.get_used_count():
278
+ raise DeleteError(
279
+ "Network contains addresses that are in use. Remove hosts before deletion"
280
+ )
281
+
282
+ if not args.force:
283
+ raise ForceMissing("Must force.")
284
+ if net.delete():
285
+ OutputManager().add_ok(f"Removed network {args.network}")
286
+ else:
287
+ raise DeleteError(f"Unable to delete network {args.network}")
288
+
289
+
290
+ @command_registry.register_command(
291
+ prog="add_excluded_range",
292
+ description="Add an excluded range to a network",
293
+ short_desc="Add an excluded range to a network",
294
+ flags=[
295
+ Flag("network", description="Network.", metavar="NETWORK"),
296
+ Flag("start_ip", description="Start ipaddress", metavar="STARTIP"),
297
+ Flag("end_ip", description="End ipaddress", metavar="ENDIP"),
298
+ ],
299
+ )
300
+ def add_excluded_range(args: argparse.Namespace) -> None:
301
+ """Add an excluded range to a network.
302
+
303
+ :param args: argparse.Namespace (network, start_ip, end_ip)
304
+ """
305
+ net = Network.get_by_network_or_raise(args.network)
306
+ net.add_excluded_range(args.start_ip, args.end_ip)
307
+ OutputManager().add_ok(f"Added exclude range to {net.network}")
308
+
309
+
310
+ @command_registry.register_command(
311
+ prog="remove_excluded_range",
312
+ description="Remove an excluded range to a network",
313
+ short_desc="Remove an excluded range to a network",
314
+ flags=[
315
+ Flag("network", description="Network.", metavar="NETWORK"),
316
+ Flag("start_ip", description="Start ipaddress", metavar="STARTIP"),
317
+ Flag("end_ip", description="End ipaddress", metavar="ENDIP"),
318
+ ],
319
+ )
320
+ def remove_excluded_range(args: argparse.Namespace) -> None:
321
+ """Remove an excluded range to a network.
322
+
323
+ :param args: argparse.Namespace (network, start_ip, end_ip)
324
+ """
325
+ net = Network.get_by_network_or_raise(args.network)
326
+ net.remove_excluded_range(args.start_ip, args.end_ip)
327
+ OutputManager().add_ok(f"Removed exclude range from {net.network}")
328
+
329
+
330
+ @command_registry.register_command(
331
+ prog="list_excluded_ranges",
332
+ description="List excluded ranges for a network",
333
+ short_desc="List excluded ranges for a network",
334
+ flags=[
335
+ Flag("network", description="Network.", metavar="NETWORK"),
336
+ ],
337
+ )
338
+ def list_excluded_ranges(args: argparse.Namespace) -> None:
339
+ """List excluded ranges for a network.
340
+
341
+ :param args: argparse.Namespace (network, start_ip, end_ip)
342
+ """
343
+ net = Network.get_by_network_or_raise(args.network)
344
+ net.output_excluded_ranges()
345
+
346
+
347
+ @command_registry.register_command(
348
+ prog="set_category",
349
+ description="Set category tag for network",
350
+ short_desc="Set category tag for network",
351
+ flags=[
352
+ Flag("network", description="Network.", metavar="NETWORK"),
353
+ Flag("category", description="Category tag.", metavar="CATEGORY-TAG"),
354
+ ],
355
+ )
356
+ def set_category(args: argparse.Namespace) -> None:
357
+ """Set category tag for network.
358
+
359
+ :param args: argparse.Namespace (network, category)
360
+ """
361
+ net = Network.get_by_network_or_raise(args.network)
362
+ net.set_category(args.category)
363
+ OutputManager().add_ok(f"Updated category tag to {args.category!r} for {net.network}")
364
+
365
+
366
+ @command_registry.register_command(
367
+ prog="set_description",
368
+ description="Set description for network",
369
+ short_desc="Set description for network",
370
+ flags=[
371
+ Flag("network", description="Network.", metavar="NETWORK"),
372
+ Flag("description", description="Network description.", metavar="DESC"),
373
+ ],
374
+ )
375
+ def set_description(args: argparse.Namespace) -> None:
376
+ """Set description for network.
377
+
378
+ :param args: argparse.Namespace (network, description)
379
+ """
380
+ net = Network.get_by_network_or_raise(args.network)
381
+ net.set_description(args.description)
382
+ OutputManager().add_ok(f"Updated description to {args.description!r} for {net.network}")
383
+
384
+
385
+ @command_registry.register_command(
386
+ prog="set_dns_delegated",
387
+ description="Set that DNS-administration is being handled elsewhere.",
388
+ short_desc="Set that DNS-administration is being handled elsewhere.",
389
+ flags=[
390
+ Flag("network", description="Network.", metavar="NETWORK"),
391
+ ],
392
+ )
393
+ def set_dns_delegated(args: argparse.Namespace) -> None:
394
+ """Set that DNS-administration is being handled elsewhere.
395
+
396
+ :param args: argparse.Namespace (network)
397
+ """
398
+ net = Network.get_by_network_or_raise(args.network)
399
+ net.set_dns_delegation(True)
400
+ OutputManager().add_ok(f"Set DNS delegation to 'True' for {net.network!r}")
401
+
402
+
403
+ @command_registry.register_command(
404
+ prog="set_frozen",
405
+ description="Freeze a network.",
406
+ short_desc="Freeze a network.",
407
+ flags=[
408
+ Flag("network", description="Network.", metavar="NETWORK"),
409
+ ],
410
+ )
411
+ def set_frozen(args: argparse.Namespace) -> None:
412
+ """Freeze a network.
413
+
414
+ :param args: argparse.Namespace (network)
415
+ """
416
+ net = Network.get_by_network_or_raise(args.network)
417
+ net.set_frozen(True)
418
+ OutputManager().add_ok(f"Updated frozen to 'True' for {net.network}")
419
+
420
+
421
+ @command_registry.register_command(
422
+ prog="set_location",
423
+ description="Set location tag for network",
424
+ short_desc="Set location tag for network",
425
+ flags=[
426
+ Flag("network", description="Network.", metavar="NETWORK"),
427
+ Flag("location", description="Location tag.", metavar="LOCATION-TAG"),
428
+ ],
429
+ )
430
+ def set_location(args: argparse.Namespace) -> None:
431
+ """Set location tag for network.
432
+
433
+ :param args: argparse.Namespace (network, location)
434
+ """
435
+ net = Network.get_by_network_or_raise(args.network)
436
+ net.set_location(args.location)
437
+ OutputManager().add_ok(f"Updated location tag to '{args.location}' for {args.network}")
438
+
439
+
440
+ @command_registry.register_command(
441
+ prog="set_reserved",
442
+ description="Set number of reserved hosts.",
443
+ short_desc="Set number of reserved hosts.",
444
+ flags=[
445
+ Flag("network", description="Network.", metavar="NETWORK"),
446
+ Flag(
447
+ "number",
448
+ description="Number of reserved hosts.",
449
+ flag_type=int,
450
+ metavar="NUM",
451
+ ),
452
+ ],
453
+ )
454
+ def set_reserved(args: argparse.Namespace) -> None:
455
+ """Set number of reserved hosts for a network.
456
+
457
+ :param args: argparse.Namespace (network, number)
458
+ """
459
+ net = Network.get_by_network_or_raise(args.network)
460
+ net.set_reserved(args.number)
461
+ OutputManager().add_ok(f"Updated reserved to '{args.number}' for {net.network}")
462
+
463
+
464
+ @command_registry.register_command(
465
+ prog="set_vlan", # <network> <vlan>
466
+ description="Set VLAN for network",
467
+ short_desc="Set VLAN for network",
468
+ flags=[
469
+ Flag("network", description="Network.", metavar="NETWORK"),
470
+ Flag("vlan", description="VLAN.", flag_type=int, metavar="VLAN"),
471
+ ],
472
+ )
473
+ def set_vlan(args: argparse.Namespace) -> None:
474
+ """Set VLAN for network.
475
+
476
+ :param args: argparse.Namespace (network, vlan)
477
+ """
478
+ net = Network.get_by_network_or_raise(args.network)
479
+ net.set_vlan(args.vlan)
480
+ OutputManager().add_ok(f"Updated vlan to {args.vlan} for {net.network}")
481
+
482
+
483
+ @command_registry.register_command(
484
+ prog="unset_dns_delegated",
485
+ description="Set that DNS-administration is not being handled elsewhere.",
486
+ short_desc="Set that DNS-administration is not being handled elsewhere.",
487
+ flags=[
488
+ Flag("network", description="Network.", metavar="NETWORK"),
489
+ ],
490
+ )
491
+ def unset_dns_delegated(args: argparse.Namespace) -> None:
492
+ """Set that DNS-administration is not being handled elsewhere.
493
+
494
+ :param args: argparse.Namespace (network)
495
+ """
496
+ net = Network.get_by_network_or_raise(args.network)
497
+ net.set_dns_delegation(False)
498
+ OutputManager().add_ok(f"Set DNS delegation to 'False' for {net.network!r}")
499
+
500
+
501
+ @command_registry.register_command(
502
+ prog="unset_frozen",
503
+ description="Unfreeze a network.",
504
+ short_desc="Unfreeze a network.",
505
+ flags=[
506
+ Flag("network", description="Network.", metavar="NETWORK"),
507
+ ],
508
+ )
509
+ def unset_frozen(args: argparse.Namespace) -> None:
510
+ """Unfreeze a network.
511
+
512
+ :param args: argparse.Namespace (network)
513
+ """
514
+ net = Network.get_by_network_or_raise(args.network)
515
+ net.set_frozen(False)
516
+ OutputManager().add_ok(f"Updated frozen to 'False' for {net.network}")