annet 3.8.0__tar.gz → 3.9.1__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 (228) hide show
  1. {annet-3.8.0/annet.egg-info → annet-3.9.1}/PKG-INFO +1 -1
  2. {annet-3.8.0 → annet-3.9.1}/annet/annlib/jsontools.py +76 -36
  3. {annet-3.8.0 → annet-3.9.1}/annet/annlib/netdev/devdb/data/devdb.json +10 -1
  4. {annet-3.8.0 → annet-3.9.1}/annet/gen.py +8 -34
  5. {annet-3.8.0 → annet-3.9.1}/annet/generators/result.py +7 -4
  6. {annet-3.8.0 → annet-3.9.1}/annet/implicit.py +17 -0
  7. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/huawei.rul +6 -0
  8. {annet-3.8.0 → annet-3.9.1/annet.egg-info}/PKG-INFO +1 -1
  9. {annet-3.8.0 → annet-3.9.1}/AUTHORS +0 -0
  10. {annet-3.8.0 → annet-3.9.1}/LICENSE +0 -0
  11. {annet-3.8.0 → annet-3.9.1}/MANIFEST.in +0 -0
  12. {annet-3.8.0 → annet-3.9.1}/README.md +0 -0
  13. {annet-3.8.0 → annet-3.9.1}/annet/__init__.py +0 -0
  14. {annet-3.8.0 → annet-3.9.1}/annet/adapters/__init__.py +0 -0
  15. {annet-3.8.0 → annet-3.9.1}/annet/adapters/fetchers/__init__.py +0 -0
  16. {annet-3.8.0 → annet-3.9.1}/annet/adapters/fetchers/stub/__init__.py +0 -0
  17. {annet-3.8.0 → annet-3.9.1}/annet/adapters/fetchers/stub/fetcher.py +0 -0
  18. {annet-3.8.0 → annet-3.9.1}/annet/adapters/file/__init__.py +0 -0
  19. {annet-3.8.0 → annet-3.9.1}/annet/adapters/file/provider.py +0 -0
  20. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/__init__.py +0 -0
  21. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/__init__.py +0 -0
  22. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/adapter.py +0 -0
  23. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/client.py +0 -0
  24. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/manufacturer.py +0 -0
  25. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/models.py +0 -0
  26. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/query.py +0 -0
  27. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/status_client.py +0 -0
  28. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/storage_base.py +0 -0
  29. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/common/storage_opts.py +0 -0
  30. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/provider.py +0 -0
  31. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v24/__init__.py +0 -0
  32. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v24/models.py +0 -0
  33. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v24/storage.py +0 -0
  34. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v37/__init__.py +0 -0
  35. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v37/models.py +0 -0
  36. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v37/storage.py +0 -0
  37. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v41/__init__.py +0 -0
  38. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v41/models.py +0 -0
  39. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v41/storage.py +0 -0
  40. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v42/__init__.py +0 -0
  41. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v42/models.py +0 -0
  42. {annet-3.8.0 → annet-3.9.1}/annet/adapters/netbox/v42/storage.py +0 -0
  43. {annet-3.8.0 → annet-3.9.1}/annet/annet.py +0 -0
  44. {annet-3.8.0 → annet-3.9.1}/annet/annlib/__init__.py +0 -0
  45. {annet-3.8.0 → annet-3.9.1}/annet/annlib/command.py +0 -0
  46. {annet-3.8.0 → annet-3.9.1}/annet/annlib/diff.py +0 -0
  47. {annet-3.8.0 → annet-3.9.1}/annet/annlib/errors.py +0 -0
  48. {annet-3.8.0 → annet-3.9.1}/annet/annlib/filter_acl.py +0 -0
  49. {annet-3.8.0 → annet-3.9.1}/annet/annlib/lib.py +0 -0
  50. {annet-3.8.0 → annet-3.9.1}/annet/annlib/netdev/__init__.py +0 -0
  51. {annet-3.8.0 → annet-3.9.1}/annet/annlib/netdev/db.py +0 -0
  52. {annet-3.8.0 → annet-3.9.1}/annet/annlib/netdev/devdb/__init__.py +0 -0
  53. {annet-3.8.0 → annet-3.9.1}/annet/annlib/netdev/views/__init__.py +0 -0
  54. {annet-3.8.0 → annet-3.9.1}/annet/annlib/netdev/views/dump.py +0 -0
  55. {annet-3.8.0 → annet-3.9.1}/annet/annlib/netdev/views/hardware.py +0 -0
  56. {annet-3.8.0 → annet-3.9.1}/annet/annlib/output.py +0 -0
  57. {annet-3.8.0 → annet-3.9.1}/annet/annlib/patching.py +0 -0
  58. {annet-3.8.0 → annet-3.9.1}/annet/annlib/rbparser/__init__.py +0 -0
  59. {annet-3.8.0 → annet-3.9.1}/annet/annlib/rbparser/acl.py +0 -0
  60. {annet-3.8.0 → annet-3.9.1}/annet/annlib/rbparser/deploying.py +0 -0
  61. {annet-3.8.0 → annet-3.9.1}/annet/annlib/rbparser/ordering.py +0 -0
  62. {annet-3.8.0 → annet-3.9.1}/annet/annlib/rbparser/platform.py +0 -0
  63. {annet-3.8.0 → annet-3.9.1}/annet/annlib/rbparser/syntax.py +0 -0
  64. {annet-3.8.0 → annet-3.9.1}/annet/annlib/rulebook/__init__.py +0 -0
  65. {annet-3.8.0 → annet-3.9.1}/annet/annlib/rulebook/common.py +0 -0
  66. {annet-3.8.0 → annet-3.9.1}/annet/annlib/types.py +0 -0
  67. {annet-3.8.0 → annet-3.9.1}/annet/api/__init__.py +0 -0
  68. {annet-3.8.0 → annet-3.9.1}/annet/argparse.py +0 -0
  69. {annet-3.8.0 → annet-3.9.1}/annet/bgp_models.py +0 -0
  70. {annet-3.8.0 → annet-3.9.1}/annet/cli.py +0 -0
  71. {annet-3.8.0 → annet-3.9.1}/annet/cli_args.py +0 -0
  72. {annet-3.8.0 → annet-3.9.1}/annet/configs/context.yml +0 -0
  73. {annet-3.8.0 → annet-3.9.1}/annet/configs/logging.yaml +0 -0
  74. {annet-3.8.0 → annet-3.9.1}/annet/connectors.py +0 -0
  75. {annet-3.8.0 → annet-3.9.1}/annet/deploy.py +0 -0
  76. {annet-3.8.0 → annet-3.9.1}/annet/deploy_ui.py +0 -0
  77. {annet-3.8.0 → annet-3.9.1}/annet/diff.py +0 -0
  78. {annet-3.8.0 → annet-3.9.1}/annet/executor.py +0 -0
  79. {annet-3.8.0 → annet-3.9.1}/annet/filtering.py +0 -0
  80. {annet-3.8.0 → annet-3.9.1}/annet/generators/__init__.py +0 -0
  81. {annet-3.8.0 → annet-3.9.1}/annet/generators/base.py +0 -0
  82. {annet-3.8.0 → annet-3.9.1}/annet/generators/common/__init__.py +0 -0
  83. {annet-3.8.0 → annet-3.9.1}/annet/generators/common/initial.py +0 -0
  84. {annet-3.8.0 → annet-3.9.1}/annet/generators/entire.py +0 -0
  85. {annet-3.8.0 → annet-3.9.1}/annet/generators/exceptions.py +0 -0
  86. {annet-3.8.0 → annet-3.9.1}/annet/generators/jsonfragment.py +0 -0
  87. {annet-3.8.0 → annet-3.9.1}/annet/generators/partial.py +0 -0
  88. {annet-3.8.0 → annet-3.9.1}/annet/generators/perf.py +0 -0
  89. {annet-3.8.0 → annet-3.9.1}/annet/generators/ref.py +0 -0
  90. {annet-3.8.0 → annet-3.9.1}/annet/hardware.py +0 -0
  91. {annet-3.8.0 → annet-3.9.1}/annet/lib.py +0 -0
  92. {annet-3.8.0 → annet-3.9.1}/annet/mesh/__init__.py +0 -0
  93. {annet-3.8.0 → annet-3.9.1}/annet/mesh/basemodel.py +0 -0
  94. {annet-3.8.0 → annet-3.9.1}/annet/mesh/device_models.py +0 -0
  95. {annet-3.8.0 → annet-3.9.1}/annet/mesh/executor.py +0 -0
  96. {annet-3.8.0 → annet-3.9.1}/annet/mesh/match_args.py +0 -0
  97. {annet-3.8.0 → annet-3.9.1}/annet/mesh/models_converter.py +0 -0
  98. {annet-3.8.0 → annet-3.9.1}/annet/mesh/peer_models.py +0 -0
  99. {annet-3.8.0 → annet-3.9.1}/annet/mesh/port_processor.py +0 -0
  100. {annet-3.8.0 → annet-3.9.1}/annet/mesh/registry.py +0 -0
  101. {annet-3.8.0 → annet-3.9.1}/annet/output.py +0 -0
  102. {annet-3.8.0 → annet-3.9.1}/annet/parallel.py +0 -0
  103. {annet-3.8.0 → annet-3.9.1}/annet/patching.py +0 -0
  104. {annet-3.8.0 → annet-3.9.1}/annet/reference.py +0 -0
  105. {annet-3.8.0 → annet-3.9.1}/annet/rpl/__init__.py +0 -0
  106. {annet-3.8.0 → annet-3.9.1}/annet/rpl/action.py +0 -0
  107. {annet-3.8.0 → annet-3.9.1}/annet/rpl/condition.py +0 -0
  108. {annet-3.8.0 → annet-3.9.1}/annet/rpl/match_builder.py +0 -0
  109. {annet-3.8.0 → annet-3.9.1}/annet/rpl/policy.py +0 -0
  110. {annet-3.8.0 → annet-3.9.1}/annet/rpl/result.py +0 -0
  111. {annet-3.8.0 → annet-3.9.1}/annet/rpl/routemap.py +0 -0
  112. {annet-3.8.0 → annet-3.9.1}/annet/rpl/statement_builder.py +0 -0
  113. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/__init__.py +0 -0
  114. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/aspath.py +0 -0
  115. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/community.py +0 -0
  116. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/cumulus_frr.py +0 -0
  117. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/entities.py +0 -0
  118. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/execute.py +0 -0
  119. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/policy.py +0 -0
  120. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/prefix_lists.py +0 -0
  121. {annet-3.8.0 → annet-3.9.1}/annet/rpl_generators/rd.py +0 -0
  122. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/__init__.py +0 -0
  123. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/arista/__init__.py +0 -0
  124. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/arista/aaa.py +0 -0
  125. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/arista/iface.py +0 -0
  126. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/aruba/__init__.py +0 -0
  127. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/aruba/ap_env.py +0 -0
  128. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/aruba/misc.py +0 -0
  129. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/b4com/__init__.py +0 -0
  130. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/b4com/file.py +0 -0
  131. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/b4com/iface.py +0 -0
  132. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/cisco/__init__.py +0 -0
  133. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/cisco/iface.py +0 -0
  134. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/cisco/misc.py +0 -0
  135. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/cisco/vlandb.py +0 -0
  136. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/common.py +0 -0
  137. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/deploying.py +0 -0
  138. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/generic/__init__.py +0 -0
  139. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/generic/misc.py +0 -0
  140. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/huawei/__init__.py +0 -0
  141. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/huawei/aaa.py +0 -0
  142. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/huawei/bgp.py +0 -0
  143. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/huawei/iface.py +0 -0
  144. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/huawei/misc.py +0 -0
  145. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/huawei/vlandb.py +0 -0
  146. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/juniper/__init__.py +0 -0
  147. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/juniper/iface.py +0 -0
  148. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/nexus/__init__.py +0 -0
  149. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/nexus/iface.py +0 -0
  150. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/patching.py +0 -0
  151. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/routeros/__init__.py +0 -0
  152. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/routeros/file.py +0 -0
  153. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/arista.deploy +0 -0
  154. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/arista.order +0 -0
  155. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/arista.rul +0 -0
  156. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/aruba.deploy +0 -0
  157. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/aruba.order +0 -0
  158. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/aruba.rul +0 -0
  159. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/b4com.deploy +0 -0
  160. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/b4com.order +0 -0
  161. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/b4com.rul +0 -0
  162. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/cisco.deploy +0 -0
  163. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/cisco.order +0 -0
  164. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/cisco.rul +0 -0
  165. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/huawei.deploy +0 -0
  166. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/huawei.order +0 -0
  167. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/iosxr.deploy +0 -0
  168. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/iosxr.order +0 -0
  169. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/iosxr.rul +0 -0
  170. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/juniper.order +0 -0
  171. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/juniper.rul +0 -0
  172. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/nexus.deploy +0 -0
  173. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/nexus.order +0 -0
  174. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/nexus.rul +0 -0
  175. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/nokia.rul +0 -0
  176. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/optixtrans.deploy +0 -0
  177. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/optixtrans.order +0 -0
  178. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/optixtrans.rul +0 -0
  179. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/pc.deploy +0 -0
  180. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/pc.order +0 -0
  181. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/pc.rul +0 -0
  182. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/ribbon.deploy +0 -0
  183. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/ribbon.rul +0 -0
  184. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/routeros.order +0 -0
  185. {annet-3.8.0 → annet-3.9.1}/annet/rulebook/texts/routeros.rul +0 -0
  186. {annet-3.8.0 → annet-3.9.1}/annet/storage.py +0 -0
  187. {annet-3.8.0 → annet-3.9.1}/annet/text_term_format.py +0 -0
  188. {annet-3.8.0 → annet-3.9.1}/annet/tracing.py +0 -0
  189. {annet-3.8.0 → annet-3.9.1}/annet/types.py +0 -0
  190. {annet-3.8.0 → annet-3.9.1}/annet/vendors/__init__.py +0 -0
  191. {annet-3.8.0 → annet-3.9.1}/annet/vendors/base.py +0 -0
  192. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/__init__.py +0 -0
  193. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/arista.py +0 -0
  194. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/aruba.py +0 -0
  195. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/b4com.py +0 -0
  196. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/cisco.py +0 -0
  197. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/h3c.py +0 -0
  198. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/huawei.py +0 -0
  199. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/iosxr.py +0 -0
  200. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/juniper.py +0 -0
  201. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/nexus.py +0 -0
  202. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/nokia.py +0 -0
  203. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/optixtrans.py +0 -0
  204. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/pc.py +0 -0
  205. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/ribbon.py +0 -0
  206. {annet-3.8.0 → annet-3.9.1}/annet/vendors/library/routeros.py +0 -0
  207. {annet-3.8.0 → annet-3.9.1}/annet/vendors/registry.py +0 -0
  208. {annet-3.8.0 → annet-3.9.1}/annet/vendors/tabparser.py +0 -0
  209. {annet-3.8.0 → annet-3.9.1}/annet.egg-info/SOURCES.txt +0 -0
  210. {annet-3.8.0 → annet-3.9.1}/annet.egg-info/dependency_links.txt +0 -0
  211. {annet-3.8.0 → annet-3.9.1}/annet.egg-info/entry_points.txt +0 -0
  212. {annet-3.8.0 → annet-3.9.1}/annet.egg-info/requires.txt +0 -0
  213. {annet-3.8.0 → annet-3.9.1}/annet.egg-info/top_level.txt +0 -0
  214. {annet-3.8.0 → annet-3.9.1}/annet_generators/__init__.py +0 -0
  215. {annet-3.8.0 → annet-3.9.1}/annet_generators/example/__init__.py +0 -0
  216. {annet-3.8.0 → annet-3.9.1}/annet_generators/example/hostname.py +0 -0
  217. {annet-3.8.0 → annet-3.9.1}/annet_generators/example/lldp.py +0 -0
  218. {annet-3.8.0 → annet-3.9.1}/annet_generators/mesh_example/__init__.py +0 -0
  219. {annet-3.8.0 → annet-3.9.1}/annet_generators/mesh_example/bgp.py +0 -0
  220. {annet-3.8.0 → annet-3.9.1}/annet_generators/mesh_example/mesh_logic.py +0 -0
  221. {annet-3.8.0 → annet-3.9.1}/annet_generators/rpl_example/__init__.py +0 -0
  222. {annet-3.8.0 → annet-3.9.1}/annet_generators/rpl_example/generator.py +0 -0
  223. {annet-3.8.0 → annet-3.9.1}/annet_generators/rpl_example/items.py +0 -0
  224. {annet-3.8.0 → annet-3.9.1}/annet_generators/rpl_example/mesh.py +0 -0
  225. {annet-3.8.0 → annet-3.9.1}/annet_generators/rpl_example/route_policy.py +0 -0
  226. {annet-3.8.0 → annet-3.9.1}/requirements.txt +0 -0
  227. {annet-3.8.0 → annet-3.9.1}/setup.cfg +0 -0
  228. {annet-3.8.0 → annet-3.9.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annet
3
- Version: 3.8.0
3
+ Version: 3.9.1
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -4,8 +4,9 @@ import copy
4
4
  import fnmatch
5
5
  import json
6
6
  from collections.abc import Mapping, Sequence
7
+ from itertools import starmap
7
8
  from operator import itemgetter
8
- from typing import Any, Dict, List, Optional
9
+ from typing import Any, Dict, Iterable, List, Optional
9
10
 
10
11
  import jsonpatch
11
12
  import jsonpointer
@@ -16,23 +17,28 @@ def format_json(data: Any, stable: bool = False) -> str:
16
17
  return json.dumps(data, indent=4, ensure_ascii=False, sort_keys=not stable) + "\n"
17
18
 
18
19
 
19
- def _sanitize_json_pointer(pattern: str) -> str:
20
- """Replace special characters on the JsonPointer valid ones"""
21
- return pattern.replace("~", "~0").replace("/", "~1")
22
-
23
-
24
20
  def apply_json_fragment(
25
21
  old: Dict[str, Any],
26
- new_fragment: Dict[str, Any],
27
- acl: List[str],
22
+ new_fragment: Dict[str, Any], *,
23
+ acl: Sequence[str],
24
+ filters: Sequence[str] | None = None,
28
25
  ) -> Dict[str, Any]:
29
26
  """
30
27
  Replace parts of the old document with 'new_fragment' using ACL restrictions.
28
+ If `filter` is not `None`, only those parts which also matches at least one filter
29
+ from the list will be modified (updated or deleted).
31
30
  """
32
31
  full_new_config = copy.deepcopy(old)
33
32
  for acl_item in acl:
34
33
  new_pointers = _resolve_json_pointers(acl_item, new_fragment)
35
34
  old_pointers = _resolve_json_pointers(acl_item, full_new_config)
35
+ if filters is not None:
36
+ new_pointers = _apply_filters_to_json_pointers(
37
+ new_pointers, filters, content=new_fragment
38
+ )
39
+ old_pointers = _apply_filters_to_json_pointers(
40
+ old_pointers, filters, content=full_new_config
41
+ )
36
42
 
37
43
  for pointer in new_pointers:
38
44
  new_value = pointer.get(new_fragment)
@@ -102,30 +108,7 @@ def apply_patch(content: Optional[bytes], patch_bytes: bytes) -> bytes:
102
108
  return new_contents
103
109
 
104
110
 
105
- def apply_acl_filters(content: Dict[str, Any], filters: List[str]) -> Dict[str, Any]:
106
- result = {}
107
- for f in filters:
108
- filter_text = f.strip()
109
- if not filter_text:
110
- continue
111
-
112
- pointers = _resolve_json_pointers(filter_text, content)
113
- for pointer in pointers:
114
- part = pointer.get(copy.deepcopy(content))
115
-
116
- sub_tree = result
117
- for i in pointer.get_parts():
118
- if i not in sub_tree:
119
- sub_tree[i] = {}
120
- sub_tree = sub_tree[i]
121
-
122
- patch = jsonpatch.JsonPatch([{"op": "add", "path": pointer.path, "value": part}])
123
- result = patch.apply(result)
124
-
125
- return result
126
-
127
-
128
- def _resolve_json_pointers(pattern: str, content: Dict[str, Any]) -> List[jsonpointer.JsonPointer]:
111
+ def _resolve_json_pointers(pattern: str, content: dict[str, Any]) -> list[jsonpointer.JsonPointer]:
129
112
  """
130
113
  Resolve globbed json pointer pattern to a list of actual pointers, existing in the document.
131
114
 
@@ -163,7 +146,7 @@ def _resolve_json_pointers(pattern: str, content: Dict[str, Any]) -> List[jsonpo
163
146
  ]
164
147
  """
165
148
  parts = jsonpointer.JsonPointer(pattern).parts
166
- matched = [([], content)]
149
+ matched = [((), content)]
167
150
  for part in parts:
168
151
  new_matched = []
169
152
  for matched_parts, doc in matched:
@@ -179,10 +162,67 @@ def _resolve_json_pointers(pattern: str, content: Dict[str, Any]) -> List[jsonpo
179
162
  if fnmatch.fnmatchcase(str(i), part)
180
163
  ]
181
164
  for key, sub_doc in keys_and_docs:
182
- new_matched.append((matched_parts + [key], sub_doc))
165
+ new_matched.append((matched_parts + (key,), sub_doc))
183
166
  matched = new_matched
184
167
 
185
- ret: List[jsonpointer.JsonPointer] = []
168
+ ret: list[jsonpointer.JsonPointer] = []
186
169
  for matched_parts, _ in matched:
187
- ret.append(jsonpointer.JsonPointer("/" + "/".join([_sanitize_json_pointer(v) for v in matched_parts])))
170
+ ret.append(jsonpointer.JsonPointer.from_parts(matched_parts))
188
171
  return ret
172
+
173
+
174
+ def _apply_filters_to_json_pointers(
175
+ pointers: Iterable[jsonpointer.JsonPointer],
176
+ filters: Sequence[str], *,
177
+ content: Any,
178
+ ) -> list[jsonpointer.JsonPointer]:
179
+
180
+ """
181
+ Takes a list of pointers, a list of filters and a document
182
+ and returns a list of pointers that match at least one of the filters
183
+ (if necessary, pointers may be deeper than from the input).
184
+
185
+ For example, given:
186
+ pointers=["/foo", "/lorem/ipsum", "/lorem/dolor"],
187
+ filters=["/foo/b*/q*", "/lorem"],
188
+ content={
189
+ "foo": {
190
+ "bar": {
191
+ "baz": [1, 2],
192
+ "qux": [3, 4]
193
+ },
194
+ "qux": {
195
+ "baz": [5, 6]
196
+ }
197
+ },
198
+ "lorem": {
199
+ "ipsum": [7, 8],
200
+ "dolor": "sit",
201
+ "amet": "consectetur"
202
+ }
203
+ }
204
+ The function will return:
205
+ ["/foo/bar/qux", "/lorem/ipsum", "/lorem/dolor"]
206
+ """
207
+
208
+ ret: set[jsonpointer.JsonPointer] = set()
209
+ for filter_item in filters:
210
+ filter_parts = jsonpointer.JsonPointer(filter_item).parts
211
+ for pointer in pointers:
212
+ pointer_parts = pointer.parts
213
+ if not all(starmap(fnmatch.fnmatchcase, zip(pointer_parts, filter_parts))):
214
+ continue # common part not matched
215
+ if len(filter_parts) > len(pointer_parts):
216
+ # filter is deeper than data pointer
217
+ deeper_doc = pointer.resolve(content)
218
+ deeper_pattern = "".join((
219
+ f"/{jsonpointer.escape(part)}"
220
+ for part in filter_parts[len(pointer_parts):]
221
+ ))
222
+ ret.update(map(pointer.join, _resolve_json_pointers(deeper_pattern, deeper_doc)))
223
+ else:
224
+ ret.add(pointer)
225
+ # sort return value by some stable key, to decrease the chance
226
+ # that some bug may lead to unstable output being produced
227
+ # (since `type(ret) is set`)
228
+ return sorted(ret, key=str)
@@ -63,7 +63,12 @@
63
63
  "Huawei.Quidway.S2x.S2300": "23\\d\\d",
64
64
  "Huawei.Quidway.S2x.S2700": "27\\d\\d",
65
65
  "Huawei.Quidway.S5300": "53\\d\\d",
66
+ "Huawei.Quidway.S5300.S5328": "5328",
67
+ "Huawei.Quidway.S5300.S5352": "5352",
66
68
  "Huawei.Quidway.S5700": "57\\d\\d",
69
+ "Huawei.Quidway.S5700.S5731": "5731",
70
+ "Huawei.Quidway.S5700.S5735": "5735",
71
+ "Huawei.Quidway.S5700.S5735I": "5735I",
67
72
  "Huawei.Quidway.S6700": "67\\d\\d",
68
73
  "Huawei.NE": " NE\\d+",
69
74
  "Huawei.NE.NE40E": " NE40E",
@@ -152,8 +157,12 @@
152
157
  "Aruba.AP.AP300.AP367": " AP-367",
153
158
  "Aruba.AP.AP300.AP377": " AP-377",
154
159
  "Aruba.AP.AP500": " AP-5\\d\\d",
160
+ "Aruba.AP.AP500.AP505": " AP-505",
155
161
  "Aruba.AP.AP500.AP514": " AP-514",
156
162
  "Aruba.AP.AP500.AP515": " AP-515",
163
+ "Aruba.AP.AP500.AP535": " AP-535",
164
+ "Aruba.AP.AP500.AP565": " AP-565",
165
+ "Aruba.AP.AP500.AP567": " AP-567",
157
166
  "Aruba.AP.AP600": " AP-6\\d\\d",
158
167
  "Aruba.AP.AP600.AP615": " AP-615",
159
168
  "Aruba.AP.AP600.AP635": " AP-635",
@@ -178,4 +187,4 @@
178
187
  "B4com.CS4132U": "^[Bb]4com B4T-CS4132U.*",
179
188
  "B4com.CS4148Q": "^[Bb]4com B4T-CS4148Q.*",
180
189
  "B4com.CS4164U": "^[Bb]4com B4T-CS4164U.*"
181
- }
190
+ }
@@ -259,38 +259,19 @@ def _old_new_per_device(ctx: OldNewDeviceContext, device: Device, filterer: Filt
259
259
 
260
260
  entire_results = res.entire_results
261
261
  json_fragment_results = res.json_fragment_results
262
- old_json_fragment_files = old_files.json_fragment_files
263
262
 
264
263
  new_files = res.new_files()
265
- new_json_fragment_files = res.new_json_fragment_files(old_json_fragment_files)
266
-
267
- filters: List[str] = []
268
- filters_text = build_filter_text(filterer, device, ctx.stdin, ctx.args, ctx.config)
269
- if filters_text:
270
- filters = filters_text.split("\n")
271
-
272
- for file_name in new_json_fragment_files:
273
- if new_json_fragment_files.get(file_name) is not None:
274
- new_json_fragment_files = _update_json_config(
275
- new_json_fragment_files,
276
- file_name,
277
- jsontools.apply_acl_filters(new_json_fragment_files[file_name][0], filters)
278
- )
279
- for file_name in old_json_fragment_files:
280
- if old_json_fragment_files.get(file_name) is not None:
281
- old_json_fragment_files[file_name] = jsontools.apply_acl_filters(old_json_fragment_files[file_name], filters)
264
+
265
+ filters = None
266
+ if filters_text := build_filter_text(filterer, device, ctx.stdin, ctx.args, ctx.config):
267
+ filters = filters_text.removesuffix("\n").split("\n")
268
+
269
+ old_json_fragment_files = old_files.json_fragment_files.copy()
270
+ new_json_fragment_files = res.new_json_fragment_files(old_json_fragment_files, filters=filters)
282
271
 
283
272
  if ctx.args.acl_safe:
284
273
  safe_new_files = res.new_files(safe=True)
285
- safe_new_json_fragment_files = res.new_json_fragment_files(old_json_fragment_files, safe=True)
286
- if filters:
287
- for file_name in safe_new_json_fragment_files:
288
- if safe_new_json_fragment_files.get(file_name):
289
- safe_new_json_fragment_files = _update_json_config(
290
- safe_new_json_fragment_files,
291
- file_name,
292
- jsontools.apply_acl_filters(safe_new_json_fragment_files[file_name][0], filters)
293
- )
274
+ safe_new_json_fragment_files = res.new_json_fragment_files(old_json_fragment_files, safe=True, filters=filters)
294
275
 
295
276
  if ctx.args.profile:
296
277
  perf = res.perf_mesures()
@@ -322,13 +303,6 @@ def _old_new_per_device(ctx: OldNewDeviceContext, device: Device, filterer: Filt
322
303
  )
323
304
 
324
305
 
325
- def _update_json_config(json_files, file_name, new_config):
326
- file = list(json_files[file_name])
327
- file[0] = new_config
328
- json_files[file_name] = tuple(file)
329
- return json_files
330
-
331
-
332
306
  @dataclasses.dataclass
333
307
  class DeviceDownloadedFiles:
334
308
  # map file path to file content for entire generators
@@ -4,9 +4,11 @@ import textwrap
4
4
  from collections import OrderedDict as odict
5
5
  from typing import (
6
6
  Any,
7
+ Callable,
7
8
  Dict,
8
9
  Optional,
9
- Tuple, Callable,
10
+ Sequence,
11
+ Tuple,
10
12
  )
11
13
 
12
14
  from annet.annlib import jsontools
@@ -84,6 +86,7 @@ class RunGeneratorResult:
84
86
  self,
85
87
  old_files: Dict[str, Optional[str]],
86
88
  safe: bool = False,
89
+ filters: Sequence[str] | None = None,
87
90
  ) -> Dict[str, Tuple[Any, Optional[str]]]:
88
91
  # TODO: safe
89
92
  files: Dict[str, Tuple[Any, Optional[str]]] = {}
@@ -101,9 +104,9 @@ class RunGeneratorResult:
101
104
  previous_config: Dict[str, Any] = files[filepath][0]
102
105
  new_fragment = generator_result.config
103
106
  new_config = jsontools.apply_json_fragment(
104
- previous_config,
105
- new_fragment,
106
- result_acl,
107
+ previous_config, new_fragment,
108
+ acl=result_acl,
109
+ filters=filters,
107
110
  )
108
111
  if jsontools.format_json(new_config) == jsontools.format_json(previous_config):
109
112
  # config is not changed, deprioritize reload_cmd
@@ -63,6 +63,19 @@ def _implicit_tree(device):
63
63
  undo user-password complexity-check
64
64
  netconf
65
65
  """
66
+ elif device.hw.Huawei.Quidway.S5700.S5735I:
67
+ text = """
68
+ !interface *
69
+ port link-type access
70
+ interface NULL0
71
+ """
72
+ elif device.hw.Huawei.Quidway.S2x:
73
+ text = """
74
+ !interface *
75
+ port link-type hybrid
76
+ dot1x enable
77
+ interface NULL0
78
+ """
66
79
  else:
67
80
  text = """
68
81
  stp mode mstp
@@ -158,10 +171,14 @@ def _implicit_tree(device):
158
171
  """
159
172
  if device.hw.Cisco.Catalyst:
160
173
  # this configuration is not visible in running-config when enabled
174
+ # no vstack and system mtu are default values
161
175
  text += r"""
162
176
  # line console aaa config
163
177
  !line con 0
164
178
  authorization exec default
179
+ no vstack
180
+ system mtu routing 1500
181
+ system mtu jumbo 9000
165
182
  """
166
183
  return parse_text(text)
167
184
 
@@ -428,6 +428,12 @@ isis *
428
428
 
429
429
  error-down auto-recovery cause link-flap
430
430
 
431
+ configuration file auto-save backup-to-server server
432
+ configuration file auto-save
433
+
434
+
435
+ set save-configuration backup-to-server *
436
+ set save-configuration *
431
437
 
432
438
  ip route-static default-bfd
433
439
  ipv6 route-static default-bfd
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annet
3
- Version: 3.8.0
3
+ Version: 3.9.1
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
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