annet 1.1.0__tar.gz → 1.1.2__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 (195) hide show
  1. {annet-1.1.0/annet.egg-info → annet-1.1.2}/PKG-INFO +2 -3
  2. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/query.py +3 -1
  3. {annet-1.1.0 → annet-1.1.2}/annet/annlib/lib.py +0 -14
  4. {annet-1.1.0 → annet-1.1.2}/annet/annlib/patching.py +9 -3
  5. {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/ordering.py +6 -1
  6. {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/platform.py +2 -2
  7. {annet-1.1.0 → annet-1.1.2}/annet/annlib/tabparser.py +54 -22
  8. {annet-1.1.0 → annet-1.1.2}/annet/api/__init__.py +1 -1
  9. {annet-1.1.0 → annet-1.1.2}/annet/executor.py +1 -23
  10. {annet-1.1.0 → annet-1.1.2}/annet/generators/entire.py +0 -4
  11. {annet-1.1.0 → annet-1.1.2}/annet/lib.py +6 -2
  12. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/juniper/__init__.py +1 -1
  13. annet-1.1.2/annet/rulebook/texts/juniper.order +4 -0
  14. {annet-1.1.0 → annet-1.1.2/annet.egg-info}/PKG-INFO +2 -3
  15. {annet-1.1.0 → annet-1.1.2}/annet.egg-info/requires.txt +1 -2
  16. {annet-1.1.0 → annet-1.1.2}/requirements.txt +0 -1
  17. {annet-1.1.0 → annet-1.1.2}/setup.py +1 -1
  18. annet-1.1.0/annet/rulebook/texts/juniper.order +0 -4
  19. {annet-1.1.0 → annet-1.1.2}/AUTHORS +0 -0
  20. {annet-1.1.0 → annet-1.1.2}/LICENSE +0 -0
  21. {annet-1.1.0 → annet-1.1.2}/MANIFEST.in +0 -0
  22. {annet-1.1.0 → annet-1.1.2}/README.md +0 -0
  23. {annet-1.1.0 → annet-1.1.2}/annet/__init__.py +0 -0
  24. {annet-1.1.0 → annet-1.1.2}/annet/adapters/__init__.py +0 -0
  25. {annet-1.1.0 → annet-1.1.2}/annet/adapters/fetchers/__init__.py +0 -0
  26. {annet-1.1.0 → annet-1.1.2}/annet/adapters/fetchers/stub/__init__.py +0 -0
  27. {annet-1.1.0 → annet-1.1.2}/annet/adapters/fetchers/stub/fetcher.py +0 -0
  28. {annet-1.1.0 → annet-1.1.2}/annet/adapters/file/__init__.py +0 -0
  29. {annet-1.1.0 → annet-1.1.2}/annet/adapters/file/provider.py +0 -0
  30. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/__init__.py +0 -0
  31. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/__init__.py +0 -0
  32. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/client.py +0 -0
  33. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/manufacturer.py +0 -0
  34. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/models.py +0 -0
  35. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/status_client.py +0 -0
  36. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/storage_opts.py +0 -0
  37. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/provider.py +0 -0
  38. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/v24/__init__.py +0 -0
  39. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/v24/storage.py +0 -0
  40. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/v37/__init__.py +0 -0
  41. {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/v37/storage.py +0 -0
  42. {annet-1.1.0 → annet-1.1.2}/annet/annet.py +0 -0
  43. {annet-1.1.0 → annet-1.1.2}/annet/annlib/__init__.py +0 -0
  44. {annet-1.1.0 → annet-1.1.2}/annet/annlib/command.py +0 -0
  45. {annet-1.1.0 → annet-1.1.2}/annet/annlib/diff.py +0 -0
  46. {annet-1.1.0 → annet-1.1.2}/annet/annlib/errors.py +0 -0
  47. {annet-1.1.0 → annet-1.1.2}/annet/annlib/filter_acl.py +0 -0
  48. {annet-1.1.0 → annet-1.1.2}/annet/annlib/jsontools.py +0 -0
  49. {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/__init__.py +0 -0
  50. {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/db.py +0 -0
  51. {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/devdb/__init__.py +0 -0
  52. {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
  53. {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/views/__init__.py +0 -0
  54. {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/views/dump.py +0 -0
  55. {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/views/hardware.py +0 -0
  56. {annet-1.1.0 → annet-1.1.2}/annet/annlib/output.py +0 -0
  57. {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/__init__.py +0 -0
  58. {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/acl.py +0 -0
  59. {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/deploying.py +0 -0
  60. {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/syntax.py +0 -0
  61. {annet-1.1.0 → annet-1.1.2}/annet/annlib/rulebook/__init__.py +0 -0
  62. {annet-1.1.0 → annet-1.1.2}/annet/annlib/rulebook/common.py +0 -0
  63. {annet-1.1.0 → annet-1.1.2}/annet/annlib/types.py +0 -0
  64. {annet-1.1.0 → annet-1.1.2}/annet/argparse.py +0 -0
  65. {annet-1.1.0 → annet-1.1.2}/annet/bgp_models.py +0 -0
  66. {annet-1.1.0 → annet-1.1.2}/annet/cli.py +0 -0
  67. {annet-1.1.0 → annet-1.1.2}/annet/cli_args.py +0 -0
  68. {annet-1.1.0 → annet-1.1.2}/annet/configs/context.yml +0 -0
  69. {annet-1.1.0 → annet-1.1.2}/annet/configs/logging.yaml +0 -0
  70. {annet-1.1.0 → annet-1.1.2}/annet/connectors.py +0 -0
  71. {annet-1.1.0 → annet-1.1.2}/annet/deploy.py +0 -0
  72. {annet-1.1.0 → annet-1.1.2}/annet/deploy_ui.py +0 -0
  73. {annet-1.1.0 → annet-1.1.2}/annet/diff.py +0 -0
  74. {annet-1.1.0 → annet-1.1.2}/annet/filtering.py +0 -0
  75. {annet-1.1.0 → annet-1.1.2}/annet/gen.py +0 -0
  76. {annet-1.1.0 → annet-1.1.2}/annet/generators/__init__.py +0 -0
  77. {annet-1.1.0 → annet-1.1.2}/annet/generators/base.py +0 -0
  78. {annet-1.1.0 → annet-1.1.2}/annet/generators/common/__init__.py +0 -0
  79. {annet-1.1.0 → annet-1.1.2}/annet/generators/common/initial.py +0 -0
  80. {annet-1.1.0 → annet-1.1.2}/annet/generators/exceptions.py +0 -0
  81. {annet-1.1.0 → annet-1.1.2}/annet/generators/jsonfragment.py +0 -0
  82. {annet-1.1.0 → annet-1.1.2}/annet/generators/partial.py +0 -0
  83. {annet-1.1.0 → annet-1.1.2}/annet/generators/perf.py +0 -0
  84. {annet-1.1.0 → annet-1.1.2}/annet/generators/ref.py +0 -0
  85. {annet-1.1.0 → annet-1.1.2}/annet/generators/result.py +0 -0
  86. {annet-1.1.0 → annet-1.1.2}/annet/hardware.py +0 -0
  87. {annet-1.1.0 → annet-1.1.2}/annet/implicit.py +0 -0
  88. {annet-1.1.0 → annet-1.1.2}/annet/mesh/__init__.py +0 -0
  89. {annet-1.1.0 → annet-1.1.2}/annet/mesh/basemodel.py +0 -0
  90. {annet-1.1.0 → annet-1.1.2}/annet/mesh/device_models.py +0 -0
  91. {annet-1.1.0 → annet-1.1.2}/annet/mesh/executor.py +0 -0
  92. {annet-1.1.0 → annet-1.1.2}/annet/mesh/match_args.py +0 -0
  93. {annet-1.1.0 → annet-1.1.2}/annet/mesh/models_converter.py +0 -0
  94. {annet-1.1.0 → annet-1.1.2}/annet/mesh/peer_models.py +0 -0
  95. {annet-1.1.0 → annet-1.1.2}/annet/mesh/port_processor.py +0 -0
  96. {annet-1.1.0 → annet-1.1.2}/annet/mesh/registry.py +0 -0
  97. {annet-1.1.0 → annet-1.1.2}/annet/output.py +0 -0
  98. {annet-1.1.0 → annet-1.1.2}/annet/parallel.py +0 -0
  99. {annet-1.1.0 → annet-1.1.2}/annet/patching.py +0 -0
  100. {annet-1.1.0 → annet-1.1.2}/annet/reference.py +0 -0
  101. {annet-1.1.0 → annet-1.1.2}/annet/rpl/__init__.py +0 -0
  102. {annet-1.1.0 → annet-1.1.2}/annet/rpl/action.py +0 -0
  103. {annet-1.1.0 → annet-1.1.2}/annet/rpl/condition.py +0 -0
  104. {annet-1.1.0 → annet-1.1.2}/annet/rpl/match_builder.py +0 -0
  105. {annet-1.1.0 → annet-1.1.2}/annet/rpl/policy.py +0 -0
  106. {annet-1.1.0 → annet-1.1.2}/annet/rpl/result.py +0 -0
  107. {annet-1.1.0 → annet-1.1.2}/annet/rpl/routemap.py +0 -0
  108. {annet-1.1.0 → annet-1.1.2}/annet/rpl/statement_builder.py +0 -0
  109. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/__init__.py +0 -0
  110. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/aspath.py +0 -0
  111. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/community.py +0 -0
  112. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/cumulus_frr.py +0 -0
  113. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/entities.py +0 -0
  114. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/execute.py +0 -0
  115. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/policy.py +0 -0
  116. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/prefix_lists.py +0 -0
  117. {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/rd.py +0 -0
  118. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/__init__.py +0 -0
  119. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/arista/__init__.py +0 -0
  120. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/arista/aaa.py +0 -0
  121. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/arista/iface.py +0 -0
  122. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/aruba/__init__.py +0 -0
  123. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/aruba/ap_env.py +0 -0
  124. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/aruba/misc.py +0 -0
  125. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/b4com/__init__.py +0 -0
  126. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/b4com/file.py +0 -0
  127. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/b4com/iface.py +0 -0
  128. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/cisco/__init__.py +0 -0
  129. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/cisco/iface.py +0 -0
  130. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/cisco/misc.py +0 -0
  131. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/cisco/vlandb.py +0 -0
  132. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/common.py +0 -0
  133. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/deploying.py +0 -0
  134. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/__init__.py +0 -0
  135. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/aaa.py +0 -0
  136. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/bgp.py +0 -0
  137. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/iface.py +0 -0
  138. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/misc.py +0 -0
  139. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/vlandb.py +0 -0
  140. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/nexus/__init__.py +0 -0
  141. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/nexus/iface.py +0 -0
  142. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/patching.py +0 -0
  143. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/routeros/__init__.py +0 -0
  144. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/routeros/file.py +0 -0
  145. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/arista.deploy +0 -0
  146. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/arista.order +0 -0
  147. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/arista.rul +0 -0
  148. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/aruba.deploy +0 -0
  149. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/aruba.order +0 -0
  150. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/aruba.rul +0 -0
  151. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/b4com.deploy +0 -0
  152. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/b4com.order +0 -0
  153. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/b4com.rul +0 -0
  154. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/cisco.deploy +0 -0
  155. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/cisco.order +0 -0
  156. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/cisco.rul +0 -0
  157. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/huawei.deploy +0 -0
  158. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/huawei.order +0 -0
  159. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/huawei.rul +0 -0
  160. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/juniper.rul +0 -0
  161. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/nexus.deploy +0 -0
  162. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/nexus.order +0 -0
  163. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/nexus.rul +0 -0
  164. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/nokia.rul +0 -0
  165. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/optixtrans.deploy +0 -0
  166. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/optixtrans.order +0 -0
  167. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/optixtrans.rul +0 -0
  168. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/pc.deploy +0 -0
  169. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/pc.order +0 -0
  170. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/pc.rul +0 -0
  171. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/ribbon.deploy +0 -0
  172. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/ribbon.rul +0 -0
  173. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/routeros.order +0 -0
  174. {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/routeros.rul +0 -0
  175. {annet-1.1.0 → annet-1.1.2}/annet/storage.py +0 -0
  176. {annet-1.1.0 → annet-1.1.2}/annet/tabparser.py +0 -0
  177. {annet-1.1.0 → annet-1.1.2}/annet/text_term_format.py +0 -0
  178. {annet-1.1.0 → annet-1.1.2}/annet/tracing.py +0 -0
  179. {annet-1.1.0 → annet-1.1.2}/annet/types.py +0 -0
  180. {annet-1.1.0 → annet-1.1.2}/annet.egg-info/SOURCES.txt +0 -0
  181. {annet-1.1.0 → annet-1.1.2}/annet.egg-info/dependency_links.txt +0 -0
  182. {annet-1.1.0 → annet-1.1.2}/annet.egg-info/entry_points.txt +0 -0
  183. {annet-1.1.0 → annet-1.1.2}/annet.egg-info/top_level.txt +0 -0
  184. {annet-1.1.0 → annet-1.1.2}/annet_generators/__init__.py +0 -0
  185. {annet-1.1.0 → annet-1.1.2}/annet_generators/example/__init__.py +0 -0
  186. {annet-1.1.0 → annet-1.1.2}/annet_generators/example/lldp.py +0 -0
  187. {annet-1.1.0 → annet-1.1.2}/annet_generators/mesh_example/__init__.py +0 -0
  188. {annet-1.1.0 → annet-1.1.2}/annet_generators/mesh_example/bgp.py +0 -0
  189. {annet-1.1.0 → annet-1.1.2}/annet_generators/mesh_example/mesh_logic.py +0 -0
  190. {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/__init__.py +0 -0
  191. {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/generator.py +0 -0
  192. {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/items.py +0 -0
  193. {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/mesh.py +0 -0
  194. {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/route_policy.py +0 -0
  195. {annet-1.1.0 → annet-1.1.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: annet
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -14,7 +14,6 @@ Requires-Dist: jsonpointer>=2.4
14
14
  Requires-Dist: PyYAML>=6.0.1
15
15
  Requires-Dist: Pygments>=2.14.0
16
16
  Requires-Dist: Mako>=1.2.4
17
- Requires-Dist: Jinja2>=3.1.2
18
17
  Requires-Dist: packaging>=23.2
19
18
  Requires-Dist: contextlog>=1.1
20
19
  Requires-Dist: valkit>=0.1.4
@@ -22,7 +21,7 @@ Requires-Dist: yarl>=1.8.2
22
21
  Requires-Dist: adaptix==3.0.0b7
23
22
  Requires-Dist: dataclass-rest==0.4
24
23
  Provides-Extra: netbox
25
- Requires-Dist: annetbox[sync]>=0.2.0; extra == "netbox"
24
+ Requires-Dist: annetbox[sync]>=0.2.1; extra == "netbox"
26
25
  Dynamic: home-page
27
26
  Dynamic: license
28
27
  Dynamic: provides-extra
@@ -5,7 +5,7 @@ from typing import cast, List, Union, Iterable, Optional, TypedDict
5
5
  from annet.storage import Query
6
6
 
7
7
  FIELD_VALUE_SEPARATOR = ":"
8
- ALLOWED_GLOB_GROUPS = ["site", "tag", "role", "device_type"]
8
+ ALLOWED_GLOB_GROUPS = ["site", "tag", "role", "device_type", "status", "tenant"]
9
9
 
10
10
 
11
11
  class Filter(TypedDict, total=False):
@@ -14,6 +14,8 @@ class Filter(TypedDict, total=False):
14
14
  role: list[str]
15
15
  name: list[str]
16
16
  device_type: list[str]
17
+ status: list[str]
18
+ tenant: list[str]
17
19
 
18
20
 
19
21
  @dataclass
@@ -18,7 +18,6 @@ from functools import lru_cache
18
18
  from typing import List, NamedTuple, Optional, Tuple, Union
19
19
 
20
20
  import contextlog
21
- import jinja2
22
21
  import mako.template
23
22
 
24
23
  _logger = contextlog.get_logger()
@@ -292,19 +291,6 @@ def mako_render(template, dedent=False, **kwargs):
292
291
  return ret
293
292
 
294
293
 
295
- def jinja_render(template, dedent=False, **kwargs):
296
- @lru_cache(None)
297
- def _compile_jinja(template, dedent):
298
- if dedent:
299
- template = textwrap.dedent(template).strip()
300
- return jinja2.Template(template)
301
-
302
- ret = _compile_jinja(template, dedent).render(**kwargs)
303
- if dedent:
304
- ret = ret.strip()
305
- return ret
306
-
307
-
308
294
  # =====
309
295
  def find_exc_in_stack(
310
296
  container_exc: Exception,
@@ -2,7 +2,7 @@ import copy
2
2
  import operator
3
3
  import textwrap
4
4
  from collections import OrderedDict as odict
5
- from typing import ( # pylint: disable=unused-import
5
+ from typing import (
6
6
  Any,
7
7
  Dict,
8
8
  Iterator,
@@ -177,7 +177,7 @@ class Orderer:
177
177
  def rule_weight(self, row, rule, regexp_key):
178
178
  return len(set(row).intersection(set(rule["attrs"][regexp_key].pattern))) / len(row)
179
179
 
180
- def get_order(self, row, cmd_direct):
180
+ def get_order(self, row, cmd_direct, scope: str | None = None):
181
181
  f_order = None
182
182
  f_weight = 0
183
183
  f_rule = ""
@@ -186,6 +186,12 @@ class Orderer:
186
186
  block_exit = platform.VENDOR_EXIT[self.vendor]
187
187
 
188
188
  for (order, (raw_rule, rule)) in enumerate(ordering.items()):
189
+ if (
190
+ (rule_scope := rule["attrs"]["scope"]) is not None
191
+ and scope not in rule_scope
192
+ ):
193
+ continue
194
+
189
195
  if rule["attrs"]["global"]:
190
196
  children.append((raw_rule, rule))
191
197
 
@@ -419,7 +425,7 @@ def make_patch(pre, rb, hw, add_comments, orderer=None, _root_pre=None, do_commi
419
425
  patch_row = "%s %s" % (row, comments)
420
426
 
421
427
  # pylint: disable=unused-variable
422
- (order, order_direct, ordering, order_rule) = orderer.get_order(row, direct)
428
+ (order, order_direct, ordering, order_rule) = orderer.get_order(row, direct, scope="patch")
423
429
  fmt_row = patch_row
424
430
  # fmt_row += " # %s" % str(order_rule) # uncomment to debug ordering
425
431
 
@@ -2,7 +2,7 @@ import functools
2
2
  import re
3
3
  from collections import OrderedDict as odict
4
4
 
5
- from valkit.common import valid_bool
5
+ from valkit.common import valid_bool, valid_string_list
6
6
 
7
7
  from . import platform, syntax
8
8
 
@@ -19,6 +19,10 @@ def compile_ordering_text(text, vendor):
19
19
  "global": {
20
20
  "validator": valid_bool,
21
21
  "default": False,
22
+ },
23
+ "scope": {
24
+ "validator": valid_string_list,
25
+ "default": None,
22
26
  }
23
27
  }),
24
28
  reverse_prefix=platform.VENDOR_REVERSES[vendor],
@@ -49,6 +53,7 @@ def _compile_ordering(tree, reverse_prefix):
49
53
  ),
50
54
  "order_reverse": attrs["params"]["order_reverse"],
51
55
  "global": attrs["params"]["global"],
56
+ "scope": attrs["params"]["scope"],
52
57
  "raw_rule": attrs["raw_rule"],
53
58
  "context": attrs["context"],
54
59
  },
@@ -25,7 +25,7 @@ VENDOR_DIFF = {
25
25
  "routeros": "common.default_diff",
26
26
  "aruba": "aruba.default_diff",
27
27
  "pc": "common.default_diff",
28
- "ribbon": "common.default_diff",
28
+ "ribbon": "juniper.default_diff",
29
29
  "b4com": "common.default_diff",
30
30
  }
31
31
 
@@ -40,7 +40,7 @@ VENDOR_DIFF_ORDERED = {
40
40
  "routeros": "common.ordered_diff",
41
41
  "aruba": "common.ordered_diff",
42
42
  "pc": "common.ordered_diff",
43
- "ribbon": "common.ordered_diff",
43
+ "ribbon": "juniper.ordered_diff",
44
44
  "b4com": "common.ordered_diff",
45
45
  }
46
46
 
@@ -387,6 +387,24 @@ class AsrFormatter(BlockExitFormatter):
387
387
  yield from super().block_exit(context)
388
388
 
389
389
 
390
+ class JuniperPatch:
391
+ def __init__(self):
392
+ """In the case of comments, odict is not suitable: there may be several identical edit and exit"""
393
+ self._items = []
394
+
395
+ def __setitem__(self, key, value):
396
+ self._items.append((key, value))
397
+
398
+ def keys(self):
399
+ return list(self)
400
+
401
+ def items(self):
402
+ return self._items
403
+
404
+ def __iter__(self):
405
+ return iter(item[0] for item in self._items)
406
+
407
+
390
408
  class JuniperFormatter(CommonFormatter):
391
409
  patch_set_prefix = "set"
392
410
 
@@ -399,7 +417,7 @@ class JuniperFormatter(CommonFormatter):
399
417
  comment: str
400
418
 
401
419
  def __post_init__(self):
402
- self.row = self.row.strip()
420
+ self.row = " ".join(map(lambda x: x.strip("\"'"), self.row.strip().split(" ")))
403
421
  self.comment = self.comment.strip()
404
422
 
405
423
  @classmethod
@@ -458,6 +476,13 @@ class JuniperFormatter(CommonFormatter):
458
476
  def patch_plain(self, patch):
459
477
  return list(self.cmd_paths(patch).keys())
460
478
 
479
+ def _blocks(self, tree: "PatchTree", is_patch: bool):
480
+ for row in super()._blocks(tree, is_patch):
481
+ if isinstance(row, str) and row.startswith(self.Comment.begin):
482
+ yield f"{self.Comment.begin} {self.Comment.loads(row).comment} {self.Comment.end}"
483
+ else:
484
+ yield row
485
+
461
486
  def _formatted_blocks(self, blocks):
462
487
  level = 0
463
488
  line = None
@@ -469,7 +494,7 @@ class JuniperFormatter(CommonFormatter):
469
494
  elif new_line is BlockEnd:
470
495
  level -= 1
471
496
  if isinstance(line, str):
472
- yield line + self._statement_end
497
+ yield line + ("" if line.endswith(self.Comment.end) else self._statement_end)
473
498
  yield self._indent * level + self._block_end
474
499
  elif isinstance(line, str):
475
500
  yield line + ("" if line.endswith(self.Comment.end) else self._statement_end)
@@ -478,7 +503,8 @@ class JuniperFormatter(CommonFormatter):
478
503
  yield line + self._statement_end
479
504
 
480
505
  def cmd_paths(self, patch, _prev=tuple()):
481
- commands = odict()
506
+ commands = JuniperPatch()
507
+
482
508
  for item in patch.itms:
483
509
  key, childs, context = item.row, item.child, item.context
484
510
 
@@ -490,33 +516,39 @@ class JuniperFormatter(CommonFormatter):
490
516
  value = (
491
517
  ""
492
518
  if key.startswith("delete")
493
- else context["comment"]
519
+ else key.removeprefix(self.Comment.begin).removesuffix(self.Comment.end).strip()
494
520
  )
495
-
496
- cmd = "\n".join(
497
- (
498
- "edit " + " ".join(_prev),
499
- " ".join(("annotate", context["row"].split(" ")[0], f'"{value}"')),
500
- "exit"
501
- )
521
+ cmds = (
522
+ f"edit {' '.join(_prev)}",
523
+ " ".join(("annotate", context["row"].split(" ")[0], f'"{value}"')),
524
+ "exit"
502
525
  )
503
526
  elif key.startswith("delete"):
504
- cmd = " ".join(("delete", *_prev, key.replace("delete", "", 1).strip()))
527
+ cmds = (
528
+ " ".join(("delete", *_prev, key.replace("delete", "", 1).strip())),
529
+ )
505
530
  elif key.startswith("activate"):
506
- cmd = " ".join(("activate", *_prev, key.replace("activate", "", 1).strip()))
531
+ cmds = (
532
+ " ".join(("activate", *_prev, key.replace("activate", "", 1).strip())),
533
+ )
507
534
  elif key.startswith("deactivate"):
508
- cmd = " ".join(("deactivate", *_prev, key.replace("deactivate", "", 1).strip()))
535
+ cmds = (
536
+ " ".join(("deactivate", *_prev, key.replace("deactivate", "", 1).strip())),
537
+ )
509
538
  else:
510
- cmd = " ".join((self.patch_set_prefix, *_prev, key.strip()))
539
+ cmds = (
540
+ " ".join((self.patch_set_prefix, *_prev, key.strip())),
541
+ )
511
542
 
512
543
  # Expanding [ a b c ] junipers list of arguments
513
- if matches := re.search(r"^(.*)\s+\[(.+)\]$", cmd):
514
- for c in matches.group(2).split(" "):
515
- if c.strip():
516
- cmd = " ".join([matches.group(1), c])
517
- commands[(cmd,)] = context
518
- else:
519
- commands[(cmd,)] = context
544
+ for cmd in cmds:
545
+ if matches := re.search(r"^(.*)\s+\[(.+)\]$", cmd):
546
+ for c in matches.group(2).split(" "):
547
+ if c.strip():
548
+ items = " ".join([matches.group(1), c])
549
+ commands[(items,)] = context
550
+ else:
551
+ commands[(cmd,)] = context
520
552
 
521
553
  return commands
522
554
 
@@ -700,7 +700,7 @@ async def adeploy(
700
700
  ans = deployer.ask_deploy()
701
701
  if ans != "y":
702
702
  return 2 ** 2
703
- progress_bar = None
703
+
704
704
  if sys.stdout.isatty() and not args.no_progress:
705
705
  progress_bar = annet.deploy_ui.ProgressBars(odict([(device.fqdn, {}) for device in deploy_cmds]))
706
706
  progress_bar.init()
@@ -4,7 +4,7 @@ import statistics
4
4
  from abc import ABC, abstractmethod
5
5
  from functools import partial
6
6
  from operator import itemgetter
7
- from typing import Any, Dict, List, Optional, Union
7
+ from typing import Any, List, Optional
8
8
 
9
9
  import colorama
10
10
  from annet.annlib.command import Command, CommandList, Question # noqa: F401
@@ -16,28 +16,6 @@ class CommandResult(ABC):
16
16
  pass
17
17
 
18
18
 
19
- class Connector(ABC):
20
- @abstractmethod
21
- async def cmd(self, cmd: Union[Command, str]) -> CommandResult:
22
- pass
23
-
24
- @abstractmethod
25
- async def download(self, files: List[str]) -> Dict[str, str]:
26
- pass
27
-
28
- @abstractmethod
29
- async def upload(self, files: Dict[str, str]):
30
- pass
31
-
32
- @abstractmethod
33
- def get_conn_trace(self) -> str:
34
- pass
35
-
36
- @abstractmethod
37
- async def aclose(self) -> str:
38
- pass
39
-
40
-
41
19
  class ExecutorException(Exception):
42
20
  def __init__(self, *args: List[Any], auxiliary: Optional[Any] = None, **kwargs: object):
43
21
  self.auxiliary = auxiliary
@@ -14,7 +14,6 @@ from typing import (
14
14
 
15
15
  from annet.lib import (
16
16
  flatten,
17
- jinja_render,
18
17
  mako_render,
19
18
  )
20
19
  from .base import BaseGenerator, _filter_str
@@ -70,9 +69,6 @@ class Entire(BaseGenerator):
70
69
  def mako(self, text, **kwargs) -> str:
71
70
  return mako_render(text, dedent=True, device=self.__device, **kwargs)
72
71
 
73
- def jinja(self, text, **kwargs) -> str:
74
- return jinja_render(text, dedent=True, device=self.__device, **kwargs)
75
-
76
72
  # =====
77
73
 
78
74
  @classmethod
@@ -24,7 +24,6 @@ from annet.annlib.lib import ( # pylint: disable=unused-import
24
24
  huawei_expand_vlandb,
25
25
  huawei_iface_ranges,
26
26
  is_relative,
27
- jinja_render,
28
27
  jun_activate,
29
28
  jun_is_inactive,
30
29
  juniper_fmt_prefix_lists_acl,
@@ -151,10 +150,15 @@ def do_async(coro: Awaitable[ReturnType], new_thread=False) -> ReturnType:
151
150
 
152
151
  def wrapper(main):
153
152
  nonlocal res
154
- res = asyncio.run(main)
153
+ try:
154
+ res = asyncio.run(main)
155
+ except BaseException as e:
156
+ res = e
155
157
  thread = threading.Thread(target=wrapper, args=(coro,))
156
158
  thread.start()
157
159
  thread.join()
160
+ if isinstance(res, BaseException):
161
+ raise res
158
162
  return res
159
163
  else:
160
164
  return asyncio.run(coro)
@@ -12,8 +12,8 @@ def comment_processor(item: common.DiffItem):
12
12
  if item.op in (Op.REMOVED, Op.ADDED) and item.row.startswith(JuniperFormatter.Comment.begin):
13
13
  comment = JuniperFormatter.Comment.loads(item.row)
14
14
 
15
+ item.diff_pre["attrs"]["context"]["comment"] = True
15
16
  item.diff_pre["attrs"]["context"]["row"] = comment.row
16
- item.diff_pre["attrs"]["context"]["comment"] = comment.comment
17
17
  item.diff_pre["key"] = item.diff_pre["raw_rule"] = (
18
18
  f"{JuniperFormatter.Comment.begin} {comment.row} {JuniperFormatter.Comment.end}"
19
19
  )
@@ -0,0 +1,4 @@
1
+ # Правило на все команды
2
+ * %global
3
+ # Добавляем веса комментам, чтобы они катились всегда после команд, но только в патче
4
+ */\/\*(?:(?!\*\/).)*\*\// %global %scope=patch
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: annet
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -14,7 +14,6 @@ Requires-Dist: jsonpointer>=2.4
14
14
  Requires-Dist: PyYAML>=6.0.1
15
15
  Requires-Dist: Pygments>=2.14.0
16
16
  Requires-Dist: Mako>=1.2.4
17
- Requires-Dist: Jinja2>=3.1.2
18
17
  Requires-Dist: packaging>=23.2
19
18
  Requires-Dist: contextlog>=1.1
20
19
  Requires-Dist: valkit>=0.1.4
@@ -22,7 +21,7 @@ Requires-Dist: yarl>=1.8.2
22
21
  Requires-Dist: adaptix==3.0.0b7
23
22
  Requires-Dist: dataclass-rest==0.4
24
23
  Provides-Extra: netbox
25
- Requires-Dist: annetbox[sync]>=0.2.0; extra == "netbox"
24
+ Requires-Dist: annetbox[sync]>=0.2.1; extra == "netbox"
26
25
  Dynamic: home-page
27
26
  Dynamic: license
28
27
  Dynamic: provides-extra
@@ -5,7 +5,6 @@ jsonpointer>=2.4
5
5
  PyYAML>=6.0.1
6
6
  Pygments>=2.14.0
7
7
  Mako>=1.2.4
8
- Jinja2>=3.1.2
9
8
  packaging>=23.2
10
9
  contextlog>=1.1
11
10
  valkit>=0.1.4
@@ -14,4 +13,4 @@ adaptix==3.0.0b7
14
13
  dataclass-rest==0.4
15
14
 
16
15
  [netbox]
17
- annetbox[sync]>=0.2.0
16
+ annetbox[sync]>=0.2.1
@@ -5,7 +5,6 @@ jsonpointer>=2.4
5
5
  PyYAML>=6.0.1
6
6
  Pygments>=2.14.0
7
7
  Mako>=1.2.4
8
- Jinja2>=3.1.2
9
8
  packaging>=23.2
10
9
  contextlog>=1.1
11
10
  valkit>=0.1.4
@@ -44,7 +44,7 @@ if __name__ == "__main__":
44
44
  ],
45
45
  },
46
46
  extras_require={
47
- "netbox": ["annetbox[sync]>=0.2.0"],
47
+ "netbox": ["annetbox[sync]>=0.2.1"],
48
48
  },
49
49
  python_requires=">=3.10",
50
50
  install_requires=requirements(),
@@ -1,4 +0,0 @@
1
- # Правило на все команды
2
- * %global
3
- # Добавляем веса комментам, чтобы они катились всегда после команд
4
- */\/\*(?:(?!\*\/).)*\*\// %global
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
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