annet 0.16.9__tar.gz → 0.16.10__tar.gz

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.

Potentially problematic release.


This version of annet might be problematic. Click here for more details.

Files changed (169) hide show
  1. {annet-0.16.9/annet.egg-info → annet-0.16.10}/PKG-INFO +3 -3
  2. annet-0.16.10/README.md +62 -0
  3. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/common/manufacturer.py +2 -0
  4. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/common/models.py +1 -1
  5. {annet-0.16.9 → annet-0.16.10}/annet/configs/context.yml +0 -9
  6. {annet-0.16.9 → annet-0.16.10}/annet/generators/jsonfragment.py +13 -12
  7. {annet-0.16.9 → annet-0.16.10/annet.egg-info}/PKG-INFO +3 -3
  8. {annet-0.16.9 → annet-0.16.10}/annet.egg-info/requires.txt +2 -3
  9. {annet-0.16.9 → annet-0.16.10}/requirements.txt +0 -2
  10. {annet-0.16.9 → annet-0.16.10}/setup.py +3 -0
  11. annet-0.16.9/README.md +0 -236
  12. {annet-0.16.9 → annet-0.16.10}/AUTHORS +0 -0
  13. {annet-0.16.9 → annet-0.16.10}/LICENSE +0 -0
  14. {annet-0.16.9 → annet-0.16.10}/MANIFEST.in +0 -0
  15. {annet-0.16.9 → annet-0.16.10}/annet/__init__.py +0 -0
  16. {annet-0.16.9 → annet-0.16.10}/annet/adapters/__init__.py +0 -0
  17. {annet-0.16.9 → annet-0.16.10}/annet/adapters/fetchers/__init__.py +0 -0
  18. {annet-0.16.9 → annet-0.16.10}/annet/adapters/fetchers/stub/__init__.py +0 -0
  19. {annet-0.16.9 → annet-0.16.10}/annet/adapters/fetchers/stub/fetcher.py +0 -0
  20. {annet-0.16.9 → annet-0.16.10}/annet/adapters/file/__init__.py +0 -0
  21. {annet-0.16.9 → annet-0.16.10}/annet/adapters/file/provider.py +0 -0
  22. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/__init__.py +0 -0
  23. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/common/__init__.py +0 -0
  24. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/common/client.py +0 -0
  25. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/common/query.py +0 -0
  26. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/common/status_client.py +0 -0
  27. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/common/storage_opts.py +0 -0
  28. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/provider.py +0 -0
  29. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/v24/__init__.py +0 -0
  30. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/v24/storage.py +0 -0
  31. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/v37/__init__.py +0 -0
  32. {annet-0.16.9 → annet-0.16.10}/annet/adapters/netbox/v37/storage.py +0 -0
  33. {annet-0.16.9 → annet-0.16.10}/annet/annet.py +0 -0
  34. {annet-0.16.9 → annet-0.16.10}/annet/annlib/__init__.py +0 -0
  35. {annet-0.16.9 → annet-0.16.10}/annet/annlib/command.py +0 -0
  36. {annet-0.16.9 → annet-0.16.10}/annet/annlib/diff.py +0 -0
  37. {annet-0.16.9 → annet-0.16.10}/annet/annlib/errors.py +0 -0
  38. {annet-0.16.9 → annet-0.16.10}/annet/annlib/filter_acl.py +0 -0
  39. {annet-0.16.9 → annet-0.16.10}/annet/annlib/jsontools.py +0 -0
  40. {annet-0.16.9 → annet-0.16.10}/annet/annlib/lib.py +0 -0
  41. {annet-0.16.9 → annet-0.16.10}/annet/annlib/netdev/__init__.py +0 -0
  42. {annet-0.16.9 → annet-0.16.10}/annet/annlib/netdev/db.py +0 -0
  43. {annet-0.16.9 → annet-0.16.10}/annet/annlib/netdev/devdb/__init__.py +0 -0
  44. {annet-0.16.9 → annet-0.16.10}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
  45. {annet-0.16.9 → annet-0.16.10}/annet/annlib/netdev/views/__init__.py +0 -0
  46. {annet-0.16.9 → annet-0.16.10}/annet/annlib/netdev/views/dump.py +0 -0
  47. {annet-0.16.9 → annet-0.16.10}/annet/annlib/netdev/views/hardware.py +0 -0
  48. {annet-0.16.9 → annet-0.16.10}/annet/annlib/output.py +0 -0
  49. {annet-0.16.9 → annet-0.16.10}/annet/annlib/patching.py +0 -0
  50. {annet-0.16.9 → annet-0.16.10}/annet/annlib/rbparser/__init__.py +0 -0
  51. {annet-0.16.9 → annet-0.16.10}/annet/annlib/rbparser/acl.py +0 -0
  52. {annet-0.16.9 → annet-0.16.10}/annet/annlib/rbparser/deploying.py +0 -0
  53. {annet-0.16.9 → annet-0.16.10}/annet/annlib/rbparser/ordering.py +0 -0
  54. {annet-0.16.9 → annet-0.16.10}/annet/annlib/rbparser/platform.py +0 -0
  55. {annet-0.16.9 → annet-0.16.10}/annet/annlib/rbparser/syntax.py +0 -0
  56. {annet-0.16.9 → annet-0.16.10}/annet/annlib/rulebook/__init__.py +0 -0
  57. {annet-0.16.9 → annet-0.16.10}/annet/annlib/rulebook/common.py +0 -0
  58. {annet-0.16.9 → annet-0.16.10}/annet/annlib/tabparser.py +0 -0
  59. {annet-0.16.9 → annet-0.16.10}/annet/annlib/types.py +0 -0
  60. {annet-0.16.9 → annet-0.16.10}/annet/api/__init__.py +0 -0
  61. {annet-0.16.9 → annet-0.16.10}/annet/argparse.py +0 -0
  62. {annet-0.16.9 → annet-0.16.10}/annet/bgp_models.py +0 -0
  63. {annet-0.16.9 → annet-0.16.10}/annet/cli.py +0 -0
  64. {annet-0.16.9 → annet-0.16.10}/annet/cli_args.py +0 -0
  65. {annet-0.16.9 → annet-0.16.10}/annet/configs/logging.yaml +0 -0
  66. {annet-0.16.9 → annet-0.16.10}/annet/connectors.py +0 -0
  67. {annet-0.16.9 → annet-0.16.10}/annet/deploy.py +0 -0
  68. {annet-0.16.9 → annet-0.16.10}/annet/diff.py +0 -0
  69. {annet-0.16.9 → annet-0.16.10}/annet/executor.py +0 -0
  70. {annet-0.16.9 → annet-0.16.10}/annet/filtering.py +0 -0
  71. {annet-0.16.9 → annet-0.16.10}/annet/gen.py +0 -0
  72. {annet-0.16.9 → annet-0.16.10}/annet/generators/__init__.py +0 -0
  73. {annet-0.16.9 → annet-0.16.10}/annet/generators/base.py +0 -0
  74. {annet-0.16.9 → annet-0.16.10}/annet/generators/common/__init__.py +0 -0
  75. {annet-0.16.9 → annet-0.16.10}/annet/generators/common/initial.py +0 -0
  76. {annet-0.16.9 → annet-0.16.10}/annet/generators/entire.py +0 -0
  77. {annet-0.16.9 → annet-0.16.10}/annet/generators/exceptions.py +0 -0
  78. {annet-0.16.9 → annet-0.16.10}/annet/generators/partial.py +0 -0
  79. {annet-0.16.9 → annet-0.16.10}/annet/generators/perf.py +0 -0
  80. {annet-0.16.9 → annet-0.16.10}/annet/generators/ref.py +0 -0
  81. {annet-0.16.9 → annet-0.16.10}/annet/generators/result.py +0 -0
  82. {annet-0.16.9 → annet-0.16.10}/annet/hardware.py +0 -0
  83. {annet-0.16.9 → annet-0.16.10}/annet/implicit.py +0 -0
  84. {annet-0.16.9 → annet-0.16.10}/annet/lib.py +0 -0
  85. {annet-0.16.9 → annet-0.16.10}/annet/mesh/__init__.py +0 -0
  86. {annet-0.16.9 → annet-0.16.10}/annet/mesh/basemodel.py +0 -0
  87. {annet-0.16.9 → annet-0.16.10}/annet/mesh/device_models.py +0 -0
  88. {annet-0.16.9 → annet-0.16.10}/annet/mesh/executor.py +0 -0
  89. {annet-0.16.9 → annet-0.16.10}/annet/mesh/match_args.py +0 -0
  90. {annet-0.16.9 → annet-0.16.10}/annet/mesh/models_converter.py +0 -0
  91. {annet-0.16.9 → annet-0.16.10}/annet/mesh/peer_models.py +0 -0
  92. {annet-0.16.9 → annet-0.16.10}/annet/mesh/registry.py +0 -0
  93. {annet-0.16.9 → annet-0.16.10}/annet/output.py +0 -0
  94. {annet-0.16.9 → annet-0.16.10}/annet/parallel.py +0 -0
  95. {annet-0.16.9 → annet-0.16.10}/annet/patching.py +0 -0
  96. {annet-0.16.9 → annet-0.16.10}/annet/reference.py +0 -0
  97. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/__init__.py +0 -0
  98. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/arista/__init__.py +0 -0
  99. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/arista/iface.py +0 -0
  100. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/aruba/__init__.py +0 -0
  101. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/aruba/ap_env.py +0 -0
  102. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/aruba/misc.py +0 -0
  103. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/b4com/__init__.py +0 -0
  104. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/b4com/file.py +0 -0
  105. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/cisco/__init__.py +0 -0
  106. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/cisco/iface.py +0 -0
  107. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/cisco/misc.py +0 -0
  108. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/cisco/vlandb.py +0 -0
  109. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/common.py +0 -0
  110. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/deploying.py +0 -0
  111. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/huawei/__init__.py +0 -0
  112. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/huawei/aaa.py +0 -0
  113. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/huawei/bgp.py +0 -0
  114. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/huawei/iface.py +0 -0
  115. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/huawei/misc.py +0 -0
  116. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/huawei/vlandb.py +0 -0
  117. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/juniper/__init__.py +0 -0
  118. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/nexus/__init__.py +0 -0
  119. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/nexus/iface.py +0 -0
  120. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/patching.py +0 -0
  121. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/ribbon/__init__.py +0 -0
  122. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/routeros/__init__.py +0 -0
  123. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/routeros/file.py +0 -0
  124. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/arista.deploy +0 -0
  125. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/arista.order +0 -0
  126. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/arista.rul +0 -0
  127. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/aruba.deploy +0 -0
  128. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/aruba.order +0 -0
  129. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/aruba.rul +0 -0
  130. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/b4com.deploy +0 -0
  131. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/b4com.order +0 -0
  132. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/b4com.rul +0 -0
  133. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/cisco.deploy +0 -0
  134. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/cisco.order +0 -0
  135. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/cisco.rul +0 -0
  136. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/huawei.deploy +0 -0
  137. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/huawei.order +0 -0
  138. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/huawei.rul +0 -0
  139. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/juniper.rul +0 -0
  140. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/nexus.deploy +0 -0
  141. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/nexus.order +0 -0
  142. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/nexus.rul +0 -0
  143. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/nokia.rul +0 -0
  144. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/optixtrans.deploy +0 -0
  145. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/optixtrans.order +0 -0
  146. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/optixtrans.rul +0 -0
  147. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/pc.deploy +0 -0
  148. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/pc.order +0 -0
  149. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/pc.rul +0 -0
  150. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/ribbon.deploy +0 -0
  151. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/ribbon.rul +0 -0
  152. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/routeros.order +0 -0
  153. {annet-0.16.9 → annet-0.16.10}/annet/rulebook/texts/routeros.rul +0 -0
  154. {annet-0.16.9 → annet-0.16.10}/annet/storage.py +0 -0
  155. {annet-0.16.9 → annet-0.16.10}/annet/tabparser.py +0 -0
  156. {annet-0.16.9 → annet-0.16.10}/annet/text_term_format.py +0 -0
  157. {annet-0.16.9 → annet-0.16.10}/annet/tracing.py +0 -0
  158. {annet-0.16.9 → annet-0.16.10}/annet/types.py +0 -0
  159. {annet-0.16.9 → annet-0.16.10}/annet.egg-info/SOURCES.txt +0 -0
  160. {annet-0.16.9 → annet-0.16.10}/annet.egg-info/dependency_links.txt +0 -0
  161. {annet-0.16.9 → annet-0.16.10}/annet.egg-info/entry_points.txt +0 -0
  162. {annet-0.16.9 → annet-0.16.10}/annet.egg-info/top_level.txt +0 -0
  163. {annet-0.16.9 → annet-0.16.10}/annet_generators/__init__.py +0 -0
  164. {annet-0.16.9 → annet-0.16.10}/annet_generators/example/__init__.py +0 -0
  165. {annet-0.16.9 → annet-0.16.10}/annet_generators/example/lldp.py +0 -0
  166. {annet-0.16.9 → annet-0.16.10}/annet_generators/mesh_example/__init__.py +0 -0
  167. {annet-0.16.9 → annet-0.16.10}/annet_generators/mesh_example/bgp.py +0 -0
  168. {annet-0.16.9 → annet-0.16.10}/annet_generators/mesh_example/mesh_logic.py +0 -0
  169. {annet-0.16.9 → annet-0.16.10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: annet
3
- Version: 0.16.9
3
+ Version: 0.16.10
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -23,5 +23,5 @@ Requires-Dist: aiohttp>=3.8.4
23
23
  Requires-Dist: yarl>=1.8.2
24
24
  Requires-Dist: adaptix==3.0.0b7
25
25
  Requires-Dist: dataclass-rest==0.4
26
- Requires-Dist: requests>=2.32.3
27
- Requires-Dist: annetbox>=0.1.8; python_version > "3.9"
26
+ Provides-Extra: netbox
27
+ Requires-Dist: annetbox[sync]>=0.1.8; extra == "netbox"
@@ -0,0 +1,62 @@
1
+ # Annet - configuration generation and deploying utility for network equipment
2
+
3
+ Annet is a configuration generator that can translate differences between old and new configurations into sequnce of commands. This feature is vital for CLI-based devices, such as Huawei, Cisco IOS, Cisco NX-OS, Juniper. Devices configured via separate config files, Linux, FreeBSD and Cumulus are also supported.
4
+
5
+ It works this way. Annet `gen`erates configuration for a device by running Python code, which usually goes to the Network Source of Truth, like NetBox. Annet then gets the `diff`erence by getting the configuration from the device and comparing it. Finally, Annet translates the difference into a sequence of commands, called a `patch`. After `deploy`ing these commands, the diff will be empty.
6
+
7
+ Annet has a number of modes (subcommands):
8
+
9
+ - ```annet gen``` - generates the entire config for the specified devices or specified parts of it
10
+ - ```annet diff``` - first does gen and then builds diff with current config version
11
+ - ```annet patch``` - first does diff and then generates a list of commands to apply diff on the device
12
+ - ```annet deploy``` - first does patch and then deploys it to the device
13
+
14
+ Usage help can be obtained by calling ```annet -h``` or for a specific command, such as ```annet gen -h```.
15
+
16
+ <img src="https://github.com/annetutil/annet/blob/main/docs/_static/annet_demo.gif?raw=true" width="800" />
17
+
18
+ ## Configuration
19
+
20
+ The path to the configuration file is searched in following order:
21
+ - `ANN_CONTEXT_CONFIG_PATH` env.
22
+ - `~/.annet/context.yml`.
23
+ - `annet/configs/context.yml`.
24
+
25
+ Config example:
26
+
27
+ ```yaml
28
+ generators:
29
+ default:
30
+ - my_annet_generators.example
31
+
32
+ storage:
33
+ default:
34
+ adapter: annet.adapters.file.provider
35
+ params:
36
+ path: /path/to/file
37
+
38
+ context:
39
+ default:
40
+ generators: default
41
+ storage: default
42
+
43
+ selected_context: default
44
+ ```
45
+
46
+ Environment variable `ANN_SELECTED_CONTEXT` can be used to override `selected_context` parameter.
47
+
48
+ ## Building doc
49
+
50
+ 1. Install dependencies:
51
+
52
+ ```shell
53
+ pip install -r requirements-doc.txt
54
+ ```
55
+
56
+ 2. Build
57
+
58
+ ```shell
59
+ sphinx-build -M html docs docs-build
60
+ ```
61
+
62
+ 3. Open rendered html in browser [docs-build/html/index.html](docs-build/html/index.html)
@@ -51,4 +51,6 @@ def get_breed(manufacturer: str, model: str):
51
51
  return "bcom-os"
52
52
  elif manufacturer == "MikroTik":
53
53
  return "routeros"
54
+ elif manufacturer == "PC":
55
+ return "pc"
54
56
  return ""
@@ -207,7 +207,7 @@ class NetboxDevice(Entity):
207
207
  return type(self) is type(other) and self.url == other.url
208
208
 
209
209
  def is_pc(self) -> bool:
210
- return self.device_type.manufacturer.name == "Mellanox"
210
+ return self.device_type.manufacturer.name == "Mellanox" or self.breed == "pc"
211
211
 
212
212
  def _make_interface(self, name: str, type: InterfaceType) -> Interface:
213
213
  return Interface(
@@ -1,11 +1,3 @@
1
- connection:
2
- default:
3
- login: ~
4
- passwords: ~
5
- enable_ssh_conf: false
6
- no_nocauth: false
7
- ssh_forward_agent: ~
8
- tunnel: ~
9
1
  generators:
10
2
  default:
11
3
  - annet_generators.example
@@ -17,7 +9,6 @@ storage:
17
9
 
18
10
  context:
19
11
  default:
20
- connection: default
21
12
  generators: default
22
13
  storage: default
23
14
 
@@ -86,9 +86,12 @@ class JSONFragment(TreeGenerator):
86
86
  self._config_pointer.pop()
87
87
 
88
88
  def __call__(self, device: Device, annotate: bool = False):
89
- for cfg_fragment in self.run(device):
90
- self._set_or_replace_dict(self._config_pointer, cfg_fragment)
91
- return self._json_config
89
+ try:
90
+ for cfg_fragment in self.run(device):
91
+ self._set_or_replace_dict(self._config_pointer, cfg_fragment)
92
+ return self._json_config
93
+ finally:
94
+ self._json_config = {}
92
95
 
93
96
  def _set_or_replace_dict(self, pointer, value):
94
97
  if not pointer:
@@ -99,27 +102,25 @@ class JSONFragment(TreeGenerator):
99
102
  else:
100
103
  self._set_dict(self._json_config, pointer, value)
101
104
 
102
- @classmethod
103
- def _to_str(cls, value: Any) -> str:
105
+ def process_value(self, value: Any) -> Any:
104
106
  if isinstance(value, str):
105
107
  return value
106
108
  elif isinstance(value, list):
107
- return [cls._to_str(x) for x in value]
109
+ return [self.process_value(x) for x in value]
108
110
  elif isinstance(value, dict):
109
111
  for k, v in value.items():
110
- value[k] = cls._to_str(v)
112
+ value[k] = self.process_value(v)
111
113
  return value
112
114
  return str(value)
113
115
 
114
- @classmethod
115
- def _set_dict(cls, cfg, pointer, value):
116
+ def _set_dict(self, cfg, pointer, value):
116
117
  # pointer has at least one key
117
118
  if len(pointer) == 1:
118
119
  if pointer[0] in cfg:
119
- cfg[pointer[0]] = [cfg[pointer[0]], cls._to_str(value)]
120
+ cfg[pointer[0]] = [cfg[pointer[0]], self.process_value(value)]
120
121
  else:
121
- cfg[pointer[0]] = cls._to_str(value)
122
+ cfg[pointer[0]] = self.process_value(value)
122
123
  else:
123
124
  if pointer[0] not in cfg:
124
125
  cfg[pointer[0]] = {}
125
- cls._set_dict(cfg[pointer[0]], pointer[1:], cls._to_str(value))
126
+ self._set_dict(cfg[pointer[0]], pointer[1:], self.process_value(value))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: annet
3
- Version: 0.16.9
3
+ Version: 0.16.10
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -23,5 +23,5 @@ Requires-Dist: aiohttp>=3.8.4
23
23
  Requires-Dist: yarl>=1.8.2
24
24
  Requires-Dist: adaptix==3.0.0b7
25
25
  Requires-Dist: dataclass-rest==0.4
26
- Requires-Dist: requests>=2.32.3
27
- Requires-Dist: annetbox>=0.1.8; python_version > "3.9"
26
+ Provides-Extra: netbox
27
+ Requires-Dist: annetbox[sync]>=0.1.8; extra == "netbox"
@@ -14,7 +14,6 @@ aiohttp>=3.8.4
14
14
  yarl>=1.8.2
15
15
  adaptix==3.0.0b7
16
16
  dataclass-rest==0.4
17
- requests>=2.32.3
18
17
 
19
- [:python_version > "3.9"]
20
- annetbox>=0.1.8
18
+ [netbox]
19
+ annetbox[sync]>=0.1.8
@@ -14,5 +14,3 @@ aiohttp>=3.8.4
14
14
  yarl>=1.8.2
15
15
  adaptix==3.0.0b7
16
16
  dataclass-rest==0.4
17
- requests>=2.32.3
18
- annetbox>=0.1.8;python_version > "3.9"
@@ -43,6 +43,9 @@ if __name__ == "__main__":
43
43
  "file = annet.adapters.file.provider:Provider",
44
44
  ],
45
45
  },
46
+ extras_require={
47
+ "netbox": ["annetbox[sync]>=0.1.8"],
48
+ },
46
49
  python_requires=">=3.9",
47
50
  install_requires=requirements(),
48
51
  include_package_data=True,
annet-0.16.9/README.md DELETED
@@ -1,236 +0,0 @@
1
- # Annet - configuration generation and deploying utility for network equipment
2
-
3
- Annet is a configuration generator that can translate differences between old and new configurations into sequnce of commands. This feature is vital for CLI-based devices, such as Huawei, Cisco IOS, Cisco NX-OS, Juniper. Devices configured via separate config files, Linux, FreeBSD and Cumulus are also supported.
4
-
5
- It works this way. Annet `gen`erates configuration for a device by running Python code, which usually goes to the Network Source of Truth, like NetBox. Annet then gets the `diff`erence by getting the configuration from the device and comparing it. Finally, Annet translates the difference into a sequence of commands, called a `patch`. After `deploy`ing these commands, the diff will be empty.
6
-
7
- Annet has a number of modes (subcommands):
8
-
9
- - ```annet gen``` - generates the entire config for the specified devices or specified parts of it
10
- - ```annet diff``` - first does gen and then builds diff with current config version
11
- - ```annet patch``` - first does diff and then generates a list of commands to apply diff on the device
12
- - ```annet deploy``` - first does patch and then deploys it to the device
13
-
14
- Usage help can be obtained by calling ```annet -h``` or for a specific command, such as ```annet gen -h```.
15
-
16
- ## Overview
17
-
18
- ### annet gen
19
-
20
- The annet_generators directory contains many files called generators.
21
- A generator takes information about the switch as input and returns the configuration.
22
- The part of the config that the generator is responsible for is specified in the generator's acl function. If a generator returns a configuration that does not fall under acl, an exception will be thrown.
23
-
24
- Example generator:
25
-
26
- ```python
27
- from annet.generators import PartialGenerator
28
-
29
- class Mtu(PartialGenerator):
30
- TAGS = ["mtu"]
31
- def acl_cisco(self, _):
32
- return "system mtu jumbo"
33
-
34
- def run_cisco(self, device):
35
- yield "system mtu jumbo %d" % 9000
36
- ```
37
-
38
-
39
- And an example of calling annet:
40
- ```bash
41
- annet gen -g mtu sw6-i1
42
- # -------------------- sw6-i1.cfg --------------------
43
- system mtu jumbo 9000
44
- ```
45
-
46
- Method `acl_cisco` defines scope of the generator, which commands and block it controls.
47
- The option `-g mtu` means that only generators with the mtu element in the TAGS variable should be called. If no tag is specified, all generators will be executed.
48
-
49
-
50
- ### annet diff
51
-
52
- If we were configuring the switch from scratch, these options would be enough, but in our reality we need to be able not only to generate the desired configuration, but also to be able to bring the current configuration to the desired one.
53
- To do this, you need to be able to delete an outdated configuration and correctly add a new one. The **diff** module, which implements some tricky logic, is responsible for this work.
54
- This logic is defined in the rulebook/texts/VENDOR folder.
55
-
56
- Example diff:
57
- ```diff
58
- # -------------------- sw1-i38.cfg --------------------
59
- acl number 2610
60
- - rule 40 permit source 10.11.170.150 0
61
- + rule 12 permit source 10.11.133.81 0
62
- ```
63
-
64
- ### annet patch
65
-
66
- Next, you need to create a list of commands from the resulting diff. The **patch** module is responsible for this. It receives the diff, runs the logic specified in rulebook/texts/VENDOR and returns the list of commands.
67
- Let's take the above diff. It says to remove the command ``rule 40 permit source 10.11.170.150 0`` and add ``rule 12 permit source 10.11.133.81 0``.
68
- Basic command delete logic for huawei is adding undo to the command. So the undo command will look like this: ``undo rule 40 permit source 10.11.170.150 0```, but this is an invalid command. In case of canceling acl rules, you need to execute ``undo rule N```.
69
- So you need to write the undo logic for the ```rule ```` command in the ``acl ``` block.
70
- Here is the part of rulebook/texts/huawei.rul responsible for this:
71
- ```
72
- acl name *
73
- rule * %logic=huawei.misc.undo_redo
74
- ```
75
- The asterisk here means that the key argument of the undo_redo function will contain the first word after rule, namely the rule number.
76
-
77
- Here, the undo_redo function from the file in rulebook/huawei/misc.py is used to generate the command to remove rules in acl.
78
- ```python
79
- def undo_redo(rule, key, diff, **_):
80
- ...
81
- ```
82
- Now calling `annet patch -g snmp sw1-i38` returns the correct set of commands.
83
- ```
84
- acl number 2610
85
- undo rule 40
86
- rule 12 permit source 10.11.133.81 0
87
- quit
88
- ```
89
-
90
- ### annet deploy
91
-
92
- To apply these commands on a switch there is a **deploy** module.
93
- Annet can apply changes (roll out) to multiple devices at the same time.
94
-
95
- By default, the edits that annet proposes to roll out will be shown before the rollout.
96
- The user must confirm that they agree to roll out the proposed diff to a given list of devices.
97
- During the rollout, annet will display the overall progress of the task and the log of one of the devices.
98
-
99
- Normal layout. The screen with patches will be shown and the process of laying out will be displayed.
100
-
101
- ```bash
102
- annet deploy -g snmp $HOST
103
- ```
104
-
105
- Credentials will be used from the current user (username, ssh key, ssh agent).
106
-
107
- ## Installation
108
-
109
- ```shell
110
- mkdir myproject
111
- cd myproject
112
- python3 -m venv venv
113
- source venv/bin/activate
114
- pip install annet gnetcli_adapter
115
-
116
- cat > ~/.annet/context.yml_tmp<<EOF
117
- fetcher:
118
- default:
119
- adapter: gnetcli
120
- deployer:
121
- default:
122
- adapter: gnetcli
123
- generators:
124
- default:
125
- - my_generators
126
- storage:
127
- netbox:
128
- adapter: netbox
129
- params:
130
- url: http://127.0.0.1:8000
131
- token: 1234567890abcdef01234567890abcdef0123456
132
- context:
133
- default:
134
- fetcher: default
135
- deployer: default
136
- connection: default
137
- generators: default
138
- storage: default
139
- selected_context: default
140
- EOF
141
-
142
- cp -r my_generators
143
-
144
- annet deploy mydevice
145
- ```
146
-
147
- ## Configuration
148
-
149
- The path to the configuration file is searched in following order:
150
- - `ANN_CONTEXT_CONFIG_PATH` env.
151
- - `~/.annet/context.yml`.
152
- - `annet/configs/context.yml`.
153
-
154
- Config example:
155
-
156
- ```yaml
157
- connection:
158
- default:
159
- login: ~
160
- passwords: ~
161
-
162
- generators:
163
- default:
164
- - my_annet_generators.example
165
-
166
- storage:
167
- default:
168
- adapter: annet.adapters.file.provider
169
- params:
170
- path: /path/to/file
171
-
172
- context:
173
- default:
174
- connection: default
175
- generators: default
176
- storage: default
177
-
178
- selected_context: default
179
- ```
180
-
181
- Environment variable `ANN_SELECTED_CONTEXT` can be used to override `selected_context` parameter.
182
-
183
- ### Storages
184
-
185
- Storages provide information about devices like FQDN, interface and so on.
186
-
187
- #### Netbox storage
188
-
189
- Provide `NETBOX_URL` and `NETBOX_TOKEN` environment variable to setup data source.
190
-
191
- ```shell
192
- export NETBOX_URL="https://demo.netbox.dev"
193
- export NETBOX_TOKEN="1234567890abcdef01234567890abcdef0123456"
194
- ```
195
-
196
- #### File storage
197
- ```yaml
198
- storage:
199
- default:
200
- adapter: annet.adapters.file.provider
201
- params:
202
- path: /path/to/file
203
- ```
204
-
205
- cat /path/to/file:
206
-
207
- ```yaml
208
- devices:
209
- - fqdn: myhost.yndx.net
210
- vendor: mikrotik
211
- interfaces:
212
- - name: eth0
213
- description: test
214
- ```
215
-
216
- ## Extending
217
-
218
- Annet uses [Entry Points](https://setuptools.pypa.io/en/latest/userguide/entry_point.html) mechanism for customization.
219
- For example, you can implement the Storage interface on top of your favorite inventory system.
220
-
221
-
222
- ## Building doc
223
-
224
- 1. Install dependencies:
225
-
226
- ```shell
227
- pip install -r requirements-doc.txt
228
- ```
229
-
230
- 2. Build
231
-
232
- ```shell
233
- sphinx-build -M html docs docs-build
234
- ```
235
-
236
- 3. Open rendered html in browser [docs-build/html/index.html](docs-build/html/index.html)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes