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.
- mreg_cli/__about__.py +7 -0
- mreg_cli/__init__.py +5 -0
- mreg_cli/__main__.py +8 -0
- mreg_cli/_version.py +16 -0
- mreg_cli/api/__init__.py +7 -0
- mreg_cli/api/abstracts.py +486 -0
- mreg_cli/api/endpoints.py +130 -0
- mreg_cli/api/fields.py +104 -0
- mreg_cli/api/history.py +152 -0
- mreg_cli/api/models.py +3416 -0
- mreg_cli/cli.py +382 -0
- mreg_cli/commands/__init__.py +1 -0
- mreg_cli/commands/base.py +62 -0
- mreg_cli/commands/dhcp.py +136 -0
- mreg_cli/commands/group.py +326 -0
- mreg_cli/commands/help.py +77 -0
- mreg_cli/commands/host.py +54 -0
- mreg_cli/commands/host_submodules/__init__.py +28 -0
- mreg_cli/commands/host_submodules/a_aaaa.py +452 -0
- mreg_cli/commands/host_submodules/bacnet.py +126 -0
- mreg_cli/commands/host_submodules/cname.py +166 -0
- mreg_cli/commands/host_submodules/core.py +507 -0
- mreg_cli/commands/host_submodules/rr.py +973 -0
- mreg_cli/commands/label.py +146 -0
- mreg_cli/commands/logging.py +112 -0
- mreg_cli/commands/network.py +516 -0
- mreg_cli/commands/permission.py +202 -0
- mreg_cli/commands/policy.py +519 -0
- mreg_cli/commands/recording.py +59 -0
- mreg_cli/commands/registry.py +56 -0
- mreg_cli/commands/root.py +58 -0
- mreg_cli/commands/zone.py +288 -0
- mreg_cli/config.py +253 -0
- mreg_cli/errorbuilder.py +193 -0
- mreg_cli/exceptions.py +237 -0
- mreg_cli/help_formatter.py +38 -0
- mreg_cli/main.py +238 -0
- mreg_cli/outputmanager.py +466 -0
- mreg_cli/py.typed +0 -0
- mreg_cli/tags.txt +55 -0
- mreg_cli/tokenfile.py +89 -0
- mreg_cli/types.py +160 -0
- mreg_cli/utilities/__init__.py +5 -0
- mreg_cli/utilities/api.py +595 -0
- mreg_cli/utilities/shared.py +65 -0
- mreg_cli/utilities/validators.py +19 -0
- mreg_cli-1.0.0.dist-info/AUTHORS +12 -0
- mreg_cli-1.0.0.dist-info/LICENSE +674 -0
- mreg_cli-1.0.0.dist-info/METADATA +1079 -0
- mreg_cli-1.0.0.dist-info/RECORD +53 -0
- mreg_cli-1.0.0.dist-info/WHEEL +5 -0
- mreg_cli-1.0.0.dist-info/entry_points.txt +2 -0
- mreg_cli-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
"""Policy 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.models import Atom, Host, HostPolicy, Role
|
|
9
|
+
from mreg_cli.commands.base import BaseCommand
|
|
10
|
+
from mreg_cli.commands.registry import CommandRegistry
|
|
11
|
+
from mreg_cli.exceptions import CreateError, DeleteError, EntityAlreadyExists
|
|
12
|
+
from mreg_cli.outputmanager import OutputManager
|
|
13
|
+
from mreg_cli.types import Flag
|
|
14
|
+
|
|
15
|
+
command_registry = CommandRegistry()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class PolicyCommands(BaseCommand):
|
|
19
|
+
"""Policy commands for the CLI."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, cli: Any) -> None:
|
|
22
|
+
"""Initialize the policy commands."""
|
|
23
|
+
super().__init__(
|
|
24
|
+
cli, command_registry, "policy", "Manage policies for hosts.", "Manage policies"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@command_registry.register_command(
|
|
29
|
+
prog="atom_create",
|
|
30
|
+
description="Create a new atom",
|
|
31
|
+
short_desc="Create a new atom",
|
|
32
|
+
flags=[
|
|
33
|
+
Flag("name", description="Atom name", metavar="NAME"),
|
|
34
|
+
Flag("description", description="Description", metavar="DESCRIPTION"),
|
|
35
|
+
Flag("-created", description="Created date", metavar="CREATED"),
|
|
36
|
+
],
|
|
37
|
+
)
|
|
38
|
+
def atom_create(args: argparse.Namespace) -> None:
|
|
39
|
+
"""Create a new atom.
|
|
40
|
+
|
|
41
|
+
:param args: argparse.Namespace (name, description, created)
|
|
42
|
+
"""
|
|
43
|
+
name: str = args.name
|
|
44
|
+
description: str = args.description
|
|
45
|
+
created: str = args.created
|
|
46
|
+
|
|
47
|
+
# Check if atom with that name already exists
|
|
48
|
+
Atom.get_by_name_and_raise(name)
|
|
49
|
+
|
|
50
|
+
params = {"name": name, "description": description}
|
|
51
|
+
if created:
|
|
52
|
+
params["create_date"] = created
|
|
53
|
+
|
|
54
|
+
Atom.create(params)
|
|
55
|
+
OutputManager().add_ok(f"Created new atom {name}")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@command_registry.register_command(
|
|
59
|
+
prog="atom_delete",
|
|
60
|
+
description="Delete an atom",
|
|
61
|
+
short_desc="Delete an atom",
|
|
62
|
+
flags=[
|
|
63
|
+
Flag("name", description="Atom name", metavar="NAME"),
|
|
64
|
+
],
|
|
65
|
+
)
|
|
66
|
+
def atom_delete(args: argparse.Namespace) -> None:
|
|
67
|
+
"""Delete an atom.
|
|
68
|
+
|
|
69
|
+
:param args: argparse.Namespace (name)
|
|
70
|
+
"""
|
|
71
|
+
name: str = args.name
|
|
72
|
+
|
|
73
|
+
atom = Atom.get_by_name_or_raise(name)
|
|
74
|
+
if atom.delete():
|
|
75
|
+
OutputManager().add_ok(f"Deleted atom {name}")
|
|
76
|
+
else:
|
|
77
|
+
raise DeleteError(f"Failed to delete atom {name}")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@command_registry.register_command(
|
|
81
|
+
prog="role_create",
|
|
82
|
+
description="Create a new role",
|
|
83
|
+
short_desc="Create a new role",
|
|
84
|
+
flags=[
|
|
85
|
+
Flag("name", description="Role name", metavar="NAME"),
|
|
86
|
+
Flag("description", description="Description", metavar="DESCRIPTION"),
|
|
87
|
+
Flag("-created", description="Created date", metavar="CREATED"),
|
|
88
|
+
],
|
|
89
|
+
)
|
|
90
|
+
def role_create(args: argparse.Namespace) -> None:
|
|
91
|
+
"""Create a new role.
|
|
92
|
+
|
|
93
|
+
:param args: argparse.Namespace (name, description, created)
|
|
94
|
+
"""
|
|
95
|
+
name: str = args.name
|
|
96
|
+
description: str = args.description
|
|
97
|
+
created: str = args.created
|
|
98
|
+
|
|
99
|
+
# Check if role with that name already exists
|
|
100
|
+
Role.get_by_name_and_raise(name)
|
|
101
|
+
|
|
102
|
+
params = {"name": name, "description": description}
|
|
103
|
+
if created:
|
|
104
|
+
params["create_date"] = created
|
|
105
|
+
|
|
106
|
+
Role.create(params)
|
|
107
|
+
OutputManager().add_ok(f"Created new role {name!r}")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@command_registry.register_command(
|
|
111
|
+
prog="role_delete",
|
|
112
|
+
description="Delete a role",
|
|
113
|
+
short_desc="Delete a role",
|
|
114
|
+
flags=[
|
|
115
|
+
Flag("name", description="Role name", metavar="NAME"),
|
|
116
|
+
],
|
|
117
|
+
)
|
|
118
|
+
def role_delete(args: argparse.Namespace) -> None:
|
|
119
|
+
"""Delete a role.
|
|
120
|
+
|
|
121
|
+
:param args: argparse.Namespace (name)
|
|
122
|
+
"""
|
|
123
|
+
name: str = args.name
|
|
124
|
+
|
|
125
|
+
role = Role.get_by_name_or_raise(name)
|
|
126
|
+
if role.delete():
|
|
127
|
+
OutputManager().add_ok(f"Deleted role {name!r}")
|
|
128
|
+
else:
|
|
129
|
+
raise DeleteError(f"Failed to delete role {name!r}")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@command_registry.register_command(
|
|
133
|
+
prog="add_atom",
|
|
134
|
+
description="Make an atom member of a role",
|
|
135
|
+
short_desc="Make an atom member of a role",
|
|
136
|
+
flags=[
|
|
137
|
+
Flag("role", description="Role name", metavar="ROLE"),
|
|
138
|
+
Flag("atom", description="Atom name", metavar="ATOM"),
|
|
139
|
+
],
|
|
140
|
+
)
|
|
141
|
+
def add_atom(args: argparse.Namespace) -> None:
|
|
142
|
+
"""Make an atom member of a role.
|
|
143
|
+
|
|
144
|
+
:param args: argparse.Namespace (role, atom)
|
|
145
|
+
"""
|
|
146
|
+
role_name: str = args.role
|
|
147
|
+
atom_name: str = args.atom
|
|
148
|
+
|
|
149
|
+
role = Role.get_by_name_or_raise(role_name)
|
|
150
|
+
if role.add_atom(atom_name):
|
|
151
|
+
OutputManager().add_ok(f"Added atom {atom_name!r} to role {role_name!r}")
|
|
152
|
+
else:
|
|
153
|
+
raise CreateError(f"Failed to add atom {atom_name!r} to role {role_name!r}")
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@command_registry.register_command(
|
|
157
|
+
prog="remove_atom",
|
|
158
|
+
description="Remove an atom member from a role",
|
|
159
|
+
short_desc="Remove an atom member from a role",
|
|
160
|
+
flags=[
|
|
161
|
+
Flag("role", description="Role name", metavar="ROLE"),
|
|
162
|
+
Flag("atom", description="Atom name", metavar="ATOM"),
|
|
163
|
+
],
|
|
164
|
+
)
|
|
165
|
+
def remove_atom(args: argparse.Namespace) -> None:
|
|
166
|
+
"""Remove an atom member from a role.
|
|
167
|
+
|
|
168
|
+
:param args: argparse.Namespace (role, atom)
|
|
169
|
+
"""
|
|
170
|
+
role_name: str = args.role
|
|
171
|
+
atom_name: str = args.atom
|
|
172
|
+
|
|
173
|
+
role = Role.get_by_name_or_raise(role_name)
|
|
174
|
+
if role.remove_atom(atom_name):
|
|
175
|
+
OutputManager().add_ok(f"Removed atom {atom_name!r} from role {role_name!r}")
|
|
176
|
+
else:
|
|
177
|
+
raise DeleteError(f"Failed to remove atom {atom_name!r} from role {role_name!r}")
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@command_registry.register_command(
|
|
181
|
+
prog="info",
|
|
182
|
+
description="Show info about an atom or role",
|
|
183
|
+
short_desc="atom/role info",
|
|
184
|
+
flags=[
|
|
185
|
+
Flag("name", description="atom/role name", nargs="+", metavar="NAME"),
|
|
186
|
+
],
|
|
187
|
+
)
|
|
188
|
+
def info(args: argparse.Namespace) -> None:
|
|
189
|
+
"""Show info about an atom or role.
|
|
190
|
+
|
|
191
|
+
:param args: argparse.Namespace (name)
|
|
192
|
+
"""
|
|
193
|
+
names: list[str] = args.name
|
|
194
|
+
for name in names:
|
|
195
|
+
role_or_atom = HostPolicy.get_role_or_atom_or_raise(name)
|
|
196
|
+
role_or_atom.output()
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@command_registry.register_command(
|
|
200
|
+
prog="list_atoms",
|
|
201
|
+
description="List all atoms by given filters",
|
|
202
|
+
short_desc="List all atoms by given filters",
|
|
203
|
+
flags=[
|
|
204
|
+
Flag(
|
|
205
|
+
"name",
|
|
206
|
+
description="Atom name, or part of name. You can use * as a wildcard.",
|
|
207
|
+
metavar="FILTER",
|
|
208
|
+
),
|
|
209
|
+
],
|
|
210
|
+
)
|
|
211
|
+
def list_atoms(args: argparse.Namespace) -> None:
|
|
212
|
+
"""List all atoms by given filters.
|
|
213
|
+
|
|
214
|
+
:param args: argparse.Namespace (name)
|
|
215
|
+
"""
|
|
216
|
+
name: str = args.name
|
|
217
|
+
|
|
218
|
+
atoms = Atom.get_list_by_name_regex(name)
|
|
219
|
+
if atoms:
|
|
220
|
+
Atom.output_multiple_lines(atoms)
|
|
221
|
+
else:
|
|
222
|
+
OutputManager().add_line("No match")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@command_registry.register_command(
|
|
226
|
+
prog="list_roles",
|
|
227
|
+
description="List all roles by given filters",
|
|
228
|
+
short_desc="List all roles by given filters",
|
|
229
|
+
flags=[
|
|
230
|
+
Flag(
|
|
231
|
+
"name",
|
|
232
|
+
description="Role name, or part of name. You can use * as a wildcard.",
|
|
233
|
+
metavar="FILTER",
|
|
234
|
+
),
|
|
235
|
+
],
|
|
236
|
+
)
|
|
237
|
+
def list_roles(args: argparse.Namespace) -> None:
|
|
238
|
+
"""List all roles by given filters.
|
|
239
|
+
|
|
240
|
+
:param args: argparse.Namespace (name)
|
|
241
|
+
"""
|
|
242
|
+
name: str = args.name
|
|
243
|
+
|
|
244
|
+
roles = Role.get_list_by_name_regex(name)
|
|
245
|
+
if not roles:
|
|
246
|
+
OutputManager().add_line("No match")
|
|
247
|
+
return
|
|
248
|
+
Role.output_multiple_table(roles)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@command_registry.register_command(
|
|
252
|
+
prog="list_hosts",
|
|
253
|
+
description="List hosts which use the given role",
|
|
254
|
+
short_desc="List hosts which use the given role",
|
|
255
|
+
flags=[
|
|
256
|
+
Flag("name", description="Role name", metavar="ROLE"),
|
|
257
|
+
],
|
|
258
|
+
)
|
|
259
|
+
def list_hosts(args: argparse.Namespace) -> None:
|
|
260
|
+
"""List hosts which use the given role.
|
|
261
|
+
|
|
262
|
+
:param args: argparse.Namespace (name)
|
|
263
|
+
"""
|
|
264
|
+
name: str = args.name
|
|
265
|
+
|
|
266
|
+
role = Role.get_by_name_or_raise(name)
|
|
267
|
+
role.output_hosts()
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
@command_registry.register_command(
|
|
271
|
+
prog="list_members",
|
|
272
|
+
description="List all members of a role",
|
|
273
|
+
short_desc="List role members",
|
|
274
|
+
flags=[
|
|
275
|
+
Flag("name", description="Role name", metavar="ROLE"),
|
|
276
|
+
],
|
|
277
|
+
)
|
|
278
|
+
def list_members(args: argparse.Namespace) -> None:
|
|
279
|
+
"""List atom members for a role.
|
|
280
|
+
|
|
281
|
+
:param args: argparse.Namespace (name)
|
|
282
|
+
"""
|
|
283
|
+
name: str = args.name
|
|
284
|
+
|
|
285
|
+
role = Role.get_by_name_or_raise(name)
|
|
286
|
+
role.output_atoms()
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
@command_registry.register_command(
|
|
290
|
+
prog="host_add",
|
|
291
|
+
description="Add host(s) to role",
|
|
292
|
+
short_desc="Add host(s) to role",
|
|
293
|
+
flags=[
|
|
294
|
+
Flag("role", description="role", metavar="ROLE"),
|
|
295
|
+
Flag("hosts", description="hosts", nargs="+", metavar="HOST"),
|
|
296
|
+
],
|
|
297
|
+
)
|
|
298
|
+
def host_add(args: argparse.Namespace) -> None:
|
|
299
|
+
"""Add host(s) to role.
|
|
300
|
+
|
|
301
|
+
:param args: argparse.Namespace (role, hosts)
|
|
302
|
+
"""
|
|
303
|
+
role_name: str = args.role
|
|
304
|
+
host_names: list[str] = args.hosts
|
|
305
|
+
|
|
306
|
+
role = Role.get_by_name_or_raise(role_name)
|
|
307
|
+
hosts = [Host.get_by_any_means_or_raise(host) for host in host_names]
|
|
308
|
+
|
|
309
|
+
for host in hosts:
|
|
310
|
+
role.add_host(host.name.hostname)
|
|
311
|
+
OutputManager().add_ok(f"Added host {host.name!r} to role {role_name!r}")
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@command_registry.register_command(
|
|
315
|
+
prog="host_copy",
|
|
316
|
+
description="Copy roles from one host to another",
|
|
317
|
+
short_desc="Copy roles between hosts",
|
|
318
|
+
flags=[
|
|
319
|
+
Flag("source", description="Source host", metavar="SOURCE"),
|
|
320
|
+
Flag("destination", description="Destination host", nargs="+", metavar="DESTINATION"),
|
|
321
|
+
],
|
|
322
|
+
)
|
|
323
|
+
def host_copy(args: argparse.Namespace) -> None:
|
|
324
|
+
"""Copy roles from one host to another.
|
|
325
|
+
|
|
326
|
+
:param args: argparse.Namespace (source, destination)
|
|
327
|
+
"""
|
|
328
|
+
source_name: str = args.source
|
|
329
|
+
source = Host.get_by_any_means_or_raise(source_name)
|
|
330
|
+
source_roles = set(source.roles())
|
|
331
|
+
|
|
332
|
+
for destination_name in args.destination:
|
|
333
|
+
destination = Host.get_by_any_means_or_raise(destination_name)
|
|
334
|
+
destination_roles = set(destination.roles())
|
|
335
|
+
OutputManager().add_line(f"Copying roles from from {source_name} to {destination_name}")
|
|
336
|
+
|
|
337
|
+
# Check if role already exists in destination
|
|
338
|
+
for role in source_roles & destination_roles:
|
|
339
|
+
OutputManager().add_line(f" + {role.name} (existing membership)")
|
|
340
|
+
|
|
341
|
+
# Check what roles need to be added
|
|
342
|
+
for role in source_roles - destination_roles:
|
|
343
|
+
role.add_host(destination.name.hostname)
|
|
344
|
+
OutputManager().add_line(f" + {role.name}")
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
@command_registry.register_command(
|
|
348
|
+
prog="host_list",
|
|
349
|
+
description="List roles for host(s)",
|
|
350
|
+
short_desc="List roles for host(s)",
|
|
351
|
+
flags=[
|
|
352
|
+
Flag("hosts", description="hosts", nargs="+", metavar="HOST"),
|
|
353
|
+
],
|
|
354
|
+
)
|
|
355
|
+
def host_list(args: argparse.Namespace) -> None:
|
|
356
|
+
"""List host roles.
|
|
357
|
+
|
|
358
|
+
:param args: argparse.Namespace (hosts)
|
|
359
|
+
"""
|
|
360
|
+
hosts: list[str] = args.hosts
|
|
361
|
+
|
|
362
|
+
for name in hosts:
|
|
363
|
+
host = Host.get_by_any_means_or_raise(name)
|
|
364
|
+
host.output_roles()
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
@command_registry.register_command(
|
|
368
|
+
prog="host_remove",
|
|
369
|
+
description="Remove host(s) from role",
|
|
370
|
+
short_desc="Remove host(s) from role",
|
|
371
|
+
flags=[
|
|
372
|
+
Flag("role", description="role", metavar="ROLE"),
|
|
373
|
+
Flag("hosts", description="host", nargs="+", metavar="HOST"),
|
|
374
|
+
],
|
|
375
|
+
)
|
|
376
|
+
def host_remove(args: argparse.Namespace) -> None:
|
|
377
|
+
"""Remove host(s) from role.
|
|
378
|
+
|
|
379
|
+
:param args: argparse.Namespace (role, hosts)
|
|
380
|
+
"""
|
|
381
|
+
role_name: str = args.role
|
|
382
|
+
host_names: list[str] = args.hosts
|
|
383
|
+
|
|
384
|
+
role = Role.get_by_name_or_raise(role_name)
|
|
385
|
+
hosts = [Host.get_by_any_means_or_raise(host) for host in host_names]
|
|
386
|
+
|
|
387
|
+
for host in hosts:
|
|
388
|
+
role.remove_host(host.name.hostname)
|
|
389
|
+
OutputManager().add_ok(f"Removed host {host.name!r} from role {role_name!r}")
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
@command_registry.register_command(
|
|
393
|
+
prog="rename",
|
|
394
|
+
description="Rename an atom or role",
|
|
395
|
+
short_desc="Rename an atom or role",
|
|
396
|
+
flags=[
|
|
397
|
+
Flag("oldname", description="Existing name", metavar="OLDNAME"),
|
|
398
|
+
Flag("newname", description="New name", metavar="NEWNAME"),
|
|
399
|
+
],
|
|
400
|
+
)
|
|
401
|
+
def rename(args: argparse.Namespace) -> None:
|
|
402
|
+
"""Rename an atom/role.
|
|
403
|
+
|
|
404
|
+
:param args: argparse.Namespace (oldname, newname)
|
|
405
|
+
"""
|
|
406
|
+
oldname: str = args.oldname
|
|
407
|
+
newname: str = args.newname
|
|
408
|
+
|
|
409
|
+
if oldname == newname:
|
|
410
|
+
raise EntityAlreadyExists("Old and new names are the same")
|
|
411
|
+
|
|
412
|
+
# Check if role or atom with the new name already exists
|
|
413
|
+
HostPolicy.get_role_or_atom_and_raise(newname)
|
|
414
|
+
|
|
415
|
+
role_or_atom = HostPolicy.get_role_or_atom_or_raise(oldname)
|
|
416
|
+
role_or_atom.rename(newname)
|
|
417
|
+
OutputManager().add_ok(f"Renamed {oldname!r} to {newname!r}")
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
@command_registry.register_command(
|
|
421
|
+
prog="set_description",
|
|
422
|
+
description="Set description for an atom or role",
|
|
423
|
+
short_desc="Set description for an atom or role",
|
|
424
|
+
flags=[
|
|
425
|
+
Flag("name", description="Name", metavar="NAME"),
|
|
426
|
+
Flag("description", description="Description.", metavar="DESC"),
|
|
427
|
+
],
|
|
428
|
+
)
|
|
429
|
+
def set_description(args: argparse.Namespace) -> None:
|
|
430
|
+
"""Set description for atom/role.
|
|
431
|
+
|
|
432
|
+
:param args: argparse.Namespace (name, description)
|
|
433
|
+
"""
|
|
434
|
+
name: str = args.name
|
|
435
|
+
description: str = args.description
|
|
436
|
+
|
|
437
|
+
role_or_atom = HostPolicy.get_role_or_atom_or_raise(name)
|
|
438
|
+
role_or_atom.set_description(description)
|
|
439
|
+
OutputManager().add_ok(f"updated description to {description!r} for {name!r}")
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
@command_registry.register_command(
|
|
443
|
+
prog="label_add",
|
|
444
|
+
description="Add a label to a role",
|
|
445
|
+
short_desc="Add label",
|
|
446
|
+
flags=[
|
|
447
|
+
Flag("label", description="Label name", metavar="LABEL"),
|
|
448
|
+
Flag("role", description="Role name", metavar="ROLE"),
|
|
449
|
+
],
|
|
450
|
+
)
|
|
451
|
+
def add_label_to_role(args: argparse.Namespace) -> None:
|
|
452
|
+
"""Add a label to a role.
|
|
453
|
+
|
|
454
|
+
:param args: argparse.Namespace (role, label)
|
|
455
|
+
"""
|
|
456
|
+
role_name: str = args.role
|
|
457
|
+
label_name: str = args.label
|
|
458
|
+
|
|
459
|
+
role = Role.get_by_name_or_raise(role_name)
|
|
460
|
+
role.add_label(label_name)
|
|
461
|
+
OutputManager().add_ok(f"Added the label {label_name!r} to the role {role_name!r}.")
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
@command_registry.register_command(
|
|
465
|
+
prog="label_remove",
|
|
466
|
+
description="Remove a label from a role",
|
|
467
|
+
short_desc="Remove label",
|
|
468
|
+
flags=[
|
|
469
|
+
Flag("label", description="Label name", metavar="LABEL"),
|
|
470
|
+
Flag("role", description="Role name", metavar="ROLE"),
|
|
471
|
+
],
|
|
472
|
+
)
|
|
473
|
+
def remove_label_from_role(args: argparse.Namespace) -> None:
|
|
474
|
+
"""Remove a label from a role.
|
|
475
|
+
|
|
476
|
+
:param args: argparse.Namespace (role, label)
|
|
477
|
+
"""
|
|
478
|
+
role_name: str = args.role
|
|
479
|
+
label_name: str = args.label
|
|
480
|
+
|
|
481
|
+
role = Role.get_by_name_or_raise(role_name)
|
|
482
|
+
role.remove_label(label_name)
|
|
483
|
+
OutputManager().add_ok(f"Removed the label {label_name!r} from the role {role_name!r}.")
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
@command_registry.register_command(
|
|
487
|
+
prog="atom_history",
|
|
488
|
+
description="Show history for atom name",
|
|
489
|
+
short_desc="Show history for atom name",
|
|
490
|
+
flags=[
|
|
491
|
+
Flag("name", description="Atom name", metavar="NAME"),
|
|
492
|
+
],
|
|
493
|
+
)
|
|
494
|
+
def atom_history(args: argparse.Namespace) -> None:
|
|
495
|
+
"""Show history for name.
|
|
496
|
+
|
|
497
|
+
:param args: argparse.Namespace (name)
|
|
498
|
+
"""
|
|
499
|
+
name: str = args.name
|
|
500
|
+
|
|
501
|
+
Atom.output_history(name)
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
@command_registry.register_command(
|
|
505
|
+
prog="role_history",
|
|
506
|
+
description="Show history for role name",
|
|
507
|
+
short_desc="Show history for role name",
|
|
508
|
+
flags=[
|
|
509
|
+
Flag("name", description="Role name", metavar="NAME"),
|
|
510
|
+
],
|
|
511
|
+
)
|
|
512
|
+
def role_history(args: argparse.Namespace) -> None:
|
|
513
|
+
"""Show history for name.
|
|
514
|
+
|
|
515
|
+
:param args: argparse.Namespace (name)
|
|
516
|
+
"""
|
|
517
|
+
name: str = args.name
|
|
518
|
+
|
|
519
|
+
Role.output_history(name)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Recording commands for the CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from mreg_cli.commands.base import BaseCommand
|
|
9
|
+
from mreg_cli.commands.registry import CommandRegistry
|
|
10
|
+
from mreg_cli.exceptions import InputFailure
|
|
11
|
+
from mreg_cli.outputmanager import OutputManager
|
|
12
|
+
from mreg_cli.types import Flag
|
|
13
|
+
|
|
14
|
+
command_registry = CommandRegistry()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RecordingCommmands(BaseCommand):
|
|
18
|
+
"""Recording commands for the CLI."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, cli: Any) -> None:
|
|
21
|
+
"""Initialize the recording commands."""
|
|
22
|
+
super().__init__(
|
|
23
|
+
cli,
|
|
24
|
+
command_registry,
|
|
25
|
+
"recording",
|
|
26
|
+
"Recording commands for the CLI.",
|
|
27
|
+
"Manage recording.",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@command_registry.register_command(
|
|
32
|
+
prog="start",
|
|
33
|
+
description="Start recording commands to a file.",
|
|
34
|
+
short_desc="Start recording",
|
|
35
|
+
flags=[
|
|
36
|
+
Flag(
|
|
37
|
+
"filename",
|
|
38
|
+
description="The filename to record to.",
|
|
39
|
+
short_desc="Filename",
|
|
40
|
+
metavar="filename",
|
|
41
|
+
)
|
|
42
|
+
],
|
|
43
|
+
)
|
|
44
|
+
def start_recording(args: argparse.Namespace) -> None:
|
|
45
|
+
"""Start recording commands and output to the given file."""
|
|
46
|
+
if not args.filename:
|
|
47
|
+
raise InputFailure("No filename given.")
|
|
48
|
+
|
|
49
|
+
OutputManager().recording_start(args.filename)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@command_registry.register_command(
|
|
53
|
+
prog="stop",
|
|
54
|
+
description="Stop recording commands and output to the given file.",
|
|
55
|
+
short_desc="Stop recording",
|
|
56
|
+
)
|
|
57
|
+
def stop_recording(_: argparse.Namespace):
|
|
58
|
+
"""Stop recording commands and output to the given file."""
|
|
59
|
+
OutputManager().recording_stop()
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Main command wrapper interface for mreg-cli.
|
|
2
|
+
|
|
3
|
+
This module provides the :py:class:`CommandWrapper` class, which is used to wrap
|
|
4
|
+
a command and its attributes, so it may be used as a subcommand of mreg-cli.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
|
|
11
|
+
from mreg_cli.types import Command, CommandFunc, Flag
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CommandRegistry:
|
|
15
|
+
"""A registry of commands that can be registered with the CLI.
|
|
16
|
+
|
|
17
|
+
This class is used to register commands with the CLI. It provides a
|
|
18
|
+
decorator, :py:meth:`register_command`, which can be used to register a
|
|
19
|
+
command with the CLI.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, root: bool = False) -> None:
|
|
23
|
+
"""Initialize the command registry.
|
|
24
|
+
|
|
25
|
+
:param root: Whether the command is a root command.
|
|
26
|
+
"""
|
|
27
|
+
self._commands: list[Command] = []
|
|
28
|
+
self.root = root
|
|
29
|
+
|
|
30
|
+
def register_command(
|
|
31
|
+
self,
|
|
32
|
+
prog: str,
|
|
33
|
+
description: str,
|
|
34
|
+
short_desc: str,
|
|
35
|
+
flags: list[Flag] | None = None,
|
|
36
|
+
) -> Callable[[CommandFunc], CommandFunc]:
|
|
37
|
+
"""Register a command with the CLI.
|
|
38
|
+
|
|
39
|
+
:param prog: The name of the command.
|
|
40
|
+
:param description: A description of the command.
|
|
41
|
+
:param short_desc: A short description of the command.
|
|
42
|
+
:param flags: A list of flags for the command.
|
|
43
|
+
|
|
44
|
+
Returns a decorator that registers a command with the CLI within the
|
|
45
|
+
current scope.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def decorator(func: CommandFunc) -> CommandFunc:
|
|
49
|
+
self._commands.append(Command(prog, description, short_desc, func, flags))
|
|
50
|
+
return func
|
|
51
|
+
|
|
52
|
+
return decorator
|
|
53
|
+
|
|
54
|
+
def get_commands(self) -> list[Command]:
|
|
55
|
+
"""Get the list of registered commands."""
|
|
56
|
+
return self._commands
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Root / base commands for the CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
from typing import Any, NoReturn
|
|
7
|
+
|
|
8
|
+
from mreg_cli.commands.base import BaseCommand
|
|
9
|
+
from mreg_cli.commands.registry import CommandRegistry
|
|
10
|
+
from mreg_cli.exceptions import CliExit
|
|
11
|
+
from mreg_cli.utilities.api import logout as _force_logout
|
|
12
|
+
|
|
13
|
+
command_registry = CommandRegistry(root=True)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RootCommmands(BaseCommand):
|
|
17
|
+
"""Root commands for the CLI."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, cli: Any) -> None:
|
|
20
|
+
"""Initialize the root commands."""
|
|
21
|
+
super().__init__(
|
|
22
|
+
cli,
|
|
23
|
+
command_registry,
|
|
24
|
+
"root",
|
|
25
|
+
"Root commands for the CLI.",
|
|
26
|
+
"Root commands.",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@command_registry.register_command(
|
|
31
|
+
prog="quit",
|
|
32
|
+
description="Exit application.",
|
|
33
|
+
short_desc="Quit",
|
|
34
|
+
)
|
|
35
|
+
def quit_mreg_cli(_: argparse.Namespace) -> NoReturn:
|
|
36
|
+
"""Exit application."""
|
|
37
|
+
raise CliExit
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@command_registry.register_command(
|
|
41
|
+
prog="exit",
|
|
42
|
+
description="Exit application.",
|
|
43
|
+
short_desc="Quit",
|
|
44
|
+
)
|
|
45
|
+
def exit_mreg_cli(_: argparse.Namespace) -> NoReturn:
|
|
46
|
+
"""Exit application."""
|
|
47
|
+
raise CliExit
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@command_registry.register_command(
|
|
51
|
+
prog="logout",
|
|
52
|
+
description="Log out from mreg and exit. Will delete the token.",
|
|
53
|
+
short_desc="Log out from mreg",
|
|
54
|
+
)
|
|
55
|
+
def logout(_: argparse.Namespace):
|
|
56
|
+
"""Log out from mreg and exit. Will delete token."""
|
|
57
|
+
_force_logout()
|
|
58
|
+
raise CliExit
|