nsxctl 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 (63) hide show
  1. nsx_toolkit/__init__.py +0 -0
  2. nsx_toolkit/__main__.py +9 -0
  3. nsx_toolkit/actions/__init__.py +0 -0
  4. nsx_toolkit/actions/audit_view.py +150 -0
  5. nsx_toolkit/actions/author.py +874 -0
  6. nsx_toolkit/actions/bulk.py +206 -0
  7. nsx_toolkit/actions/change_ticket.py +138 -0
  8. nsx_toolkit/actions/dashboard.py +108 -0
  9. nsx_toolkit/actions/doctor.py +260 -0
  10. nsx_toolkit/actions/drift.py +69 -0
  11. nsx_toolkit/actions/groups.py +81 -0
  12. nsx_toolkit/actions/hygiene.py +502 -0
  13. nsx_toolkit/actions/inspect.py +377 -0
  14. nsx_toolkit/actions/parity.py +151 -0
  15. nsx_toolkit/actions/recommend.py +145 -0
  16. nsx_toolkit/actions/reverse.py +161 -0
  17. nsx_toolkit/actions/tags.py +288 -0
  18. nsx_toolkit/actions/trace.py +371 -0
  19. nsx_toolkit/actions/verify.py +57 -0
  20. nsx_toolkit/api.py +317 -0
  21. nsx_toolkit/audit.py +214 -0
  22. nsx_toolkit/authoring.py +503 -0
  23. nsx_toolkit/baseline.py +171 -0
  24. nsx_toolkit/cli.py +372 -0
  25. nsx_toolkit/commands/__init__.py +216 -0
  26. nsx_toolkit/commands/analysis.py +100 -0
  27. nsx_toolkit/commands/apply.py +58 -0
  28. nsx_toolkit/commands/group.py +139 -0
  29. nsx_toolkit/commands/inspect.py +75 -0
  30. nsx_toolkit/commands/recommend.py +70 -0
  31. nsx_toolkit/commands/rule.py +436 -0
  32. nsx_toolkit/commands/setup.py +298 -0
  33. nsx_toolkit/commands/shell.py +427 -0
  34. nsx_toolkit/commands/snapshot.py +322 -0
  35. nsx_toolkit/commands/tag.py +134 -0
  36. nsx_toolkit/commands/trace.py +76 -0
  37. nsx_toolkit/config.py +210 -0
  38. nsx_toolkit/creds.py +240 -0
  39. nsx_toolkit/diff.py +254 -0
  40. nsx_toolkit/errors.py +28 -0
  41. nsx_toolkit/export.py +154 -0
  42. nsx_toolkit/flows.py +339 -0
  43. nsx_toolkit/http.py +515 -0
  44. nsx_toolkit/legacy.py +167 -0
  45. nsx_toolkit/menu.py +323 -0
  46. nsx_toolkit/namecache.py +196 -0
  47. nsx_toolkit/output.py +340 -0
  48. nsx_toolkit/paths.py +58 -0
  49. nsx_toolkit/policy.py +200 -0
  50. nsx_toolkit/render.py +89 -0
  51. nsx_toolkit/report.py +144 -0
  52. nsx_toolkit/sinks.py +316 -0
  53. nsx_toolkit/snapshot.py +326 -0
  54. nsx_toolkit/taxonomy.py +143 -0
  55. nsx_toolkit/trace.py +779 -0
  56. nsx_toolkit/version.py +6 -0
  57. nsx_toolkit/wizard.py +231 -0
  58. nsxctl-1.0.0.dist-info/METADATA +834 -0
  59. nsxctl-1.0.0.dist-info/RECORD +63 -0
  60. nsxctl-1.0.0.dist-info/WHEEL +5 -0
  61. nsxctl-1.0.0.dist-info/entry_points.txt +3 -0
  62. nsxctl-1.0.0.dist-info/licenses/LICENSE +201 -0
  63. nsxctl-1.0.0.dist-info/top_level.txt +1 -0
File without changes
@@ -0,0 +1,9 @@
1
+ """Support `python -m nsx_toolkit`, for environments where a console script
2
+ is awkward to put on PATH."""
3
+
4
+ import sys
5
+
6
+ from .cli import main
7
+
8
+ if __name__ == "__main__":
9
+ sys.exit(main())
File without changes
@@ -0,0 +1,150 @@
1
+ """Audit log viewing and single-entry undo.
2
+
3
+ Two eras of entry live in the log -- VM tag changes, and the group and rule
4
+ changes authoring writes -- so everything here reads the normalised shape
5
+ `audit.normalise_entry` produces and dispatches undo on `object_type`. A log
6
+ written before authoring existed lists and undoes exactly as it always did.
7
+
8
+ **Undo is asymmetric, and the messages say which case they are in.** Undoing
9
+ a create is a delete and undoing a modify is a write of the before-body: both
10
+ exact. Undoing a delete recreates an object whose references may have been
11
+ cleaned up underneath it, and that cannot be guaranteed -- a snapshot restore
12
+ is the reliable way back from a delete.
13
+ """
14
+
15
+ from ..api import F_EXTERNAL_ID
16
+ from ..audit import OBJ_GROUP, OBJ_RULE, OBJ_VM_TAGS, summarise_entry
17
+ from ..errors import NsxError
18
+ from ..output import (
19
+ ask,
20
+ cB,
21
+ cBY,
22
+ cC,
23
+ cD,
24
+ cG,
25
+ confirm,
26
+ cR,
27
+ err,
28
+ hr,
29
+ is_interactive,
30
+ ok_msg,
31
+ say,
32
+ )
33
+ from ..render import fmt_tags_plain, tags_of
34
+ from .author import undo_object_entry
35
+
36
+ AUDIT_HEADERS = ["timestamp", "user", "manager", "action", "object_type",
37
+ "object", "added", "removed", "status"]
38
+
39
+ UNDOABLE_OBJECTS = (OBJ_GROUP, OBJ_RULE)
40
+
41
+
42
+ def _entry_row(entry, added, removed):
43
+ return [entry["timestamp"], entry["user"], entry["manager"],
44
+ entry["action"], entry["object_type"], entry["object_name"],
45
+ fmt_tags_plain(added) if added else "",
46
+ fmt_tags_plain(removed) if removed else "",
47
+ entry["status"]]
48
+
49
+
50
+ def _print_entry(index, entry):
51
+ say(" {:5s} {} {:28s} {} [{}]".format(
52
+ cD(str(index) + "."), cD(str(entry["timestamp"])[:19]),
53
+ str(entry["object_name"])[:28], cD(entry["object_type"]),
54
+ cC(entry["manager"])))
55
+ if entry["object_type"] == OBJ_VM_TAGS:
56
+ added, removed = summarise_entry(entry)
57
+ if added:
58
+ say(" {}".format(cG("+ " + fmt_tags_plain(added))))
59
+ if removed:
60
+ say(" {}".format(cR("- " + fmt_tags_plain(removed))))
61
+ return
62
+ if entry["before"] is None:
63
+ say(" {}".format(cG("created")))
64
+ elif entry["after"] is None:
65
+ say(" {}".format(cR("deleted")))
66
+ else:
67
+ say(" {}".format(cBY("modified")))
68
+ if entry["status"] and entry["status"] != "success":
69
+ say(" {} {}".format(cR(entry["status"]), cD(entry["detail"])))
70
+
71
+
72
+ def act_audit_log(audit, sessions, write_enabled, exporter=None, limit=20,
73
+ domain="default"):
74
+ entries = audit.last_n_normalised(limit)
75
+ if not entries:
76
+ say(" Audit log empty.")
77
+ if exporter is not None:
78
+ exporter.stage("audit_log", AUDIT_HEADERS, [])
79
+ return
80
+ say("\n Last {} entries:".format(cC(str(len(entries)))))
81
+ hr()
82
+ rows = []
83
+ for index, entry in enumerate(entries, 1):
84
+ _print_entry(index, entry)
85
+ added, removed = summarise_entry(entry)
86
+ rows.append(_entry_row(entry, added, removed))
87
+ if exporter is not None:
88
+ exporter.stage("audit_log", AUDIT_HEADERS, rows)
89
+
90
+ if not write_enabled:
91
+ say("\n {}.".format(cBY("Undo needs write mode")))
92
+ return
93
+ if not is_interactive():
94
+ return
95
+ hr()
96
+ choice = ask(" Undo entry # (or b): ")
97
+ if not choice.isdigit() or not (1 <= int(choice) <= len(entries)):
98
+ say(" Cancelled.")
99
+ return
100
+ target = entries[int(choice) - 1]
101
+ try:
102
+ if target["object_type"] == OBJ_VM_TAGS:
103
+ _undo_vm_tags(target, sessions, audit)
104
+ elif target["object_type"] in UNDOABLE_OBJECTS:
105
+ undo_object_entry(target, sessions, domain, audit)
106
+ else:
107
+ err("Entries of type '{}' cannot be undone.".format(
108
+ target["object_type"]))
109
+ except NsxError as e:
110
+ err(str(e))
111
+
112
+
113
+ def _undo_vm_tags(target, sessions, audit):
114
+ """The original tag undo, unchanged in behaviour.
115
+
116
+ Reads `before`/`after` off the normalised entry, which for a tag entry
117
+ comes from `tags_before`/`tags_after` whether it was written this release
118
+ or three releases ago.
119
+ """
120
+ restore_to = target["before"] or []
121
+ raw = target["raw"]
122
+ vm_name = raw.get("vm_display_name", target["object_name"])
123
+ mgr_name = target["manager"]
124
+ ext = raw.get("vm_external_id", "?")
125
+
126
+ nsx = next((s for s in sessions if s.name == mgr_name), None)
127
+ if not nsx:
128
+ err("Manager '{}' is not in this session.".format(mgr_name))
129
+ return
130
+ vm = nsx.get_vm_by_external_id(ext)
131
+ if not vm:
132
+ err("VM '{}' (external_id {}) not found on {}.".format(
133
+ vm_name, ext, mgr_name))
134
+ return
135
+ current = sorted(tags_of(vm))
136
+ say("\n Restore '{}' on [{}]".format(cB(vm_name), cC(mgr_name)))
137
+ say(" current : {}".format(fmt_tags_plain(current)))
138
+ say(" restore : {}".format(fmt_tags_plain(sorted(restore_to))))
139
+ if current == sorted(restore_to):
140
+ say(" Already in that state -- nothing to undo.")
141
+ return
142
+ if not confirm(" Apply undo? [y/N]: "):
143
+ say(" Cancelled.")
144
+ return
145
+ fresh = nsx.refresh_vm(vm) or vm
146
+ nsx.update_vm_tags(fresh, restore_to)
147
+ audit.log("undo", nsx.name, vm_name, fresh.get(F_EXTERNAL_ID),
148
+ current, restore_to, detail="undo of {}".format(
149
+ target.get("timestamp", "?")))
150
+ ok_msg("Undo applied.")