annet 3.2.0__tar.gz → 3.4.0__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 (225) hide show
  1. {annet-3.2.0/annet.egg-info → annet-3.4.0}/PKG-INFO +2 -2
  2. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v42/models.py +6 -0
  3. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v42/storage.py +27 -1
  4. {annet-3.2.0 → annet-3.4.0}/annet/api/__init__.py +68 -45
  5. {annet-3.2.0 → annet-3.4.0}/annet/generators/__init__.py +45 -39
  6. {annet-3.2.0 → annet-3.4.0}/annet/generators/entire.py +5 -15
  7. {annet-3.2.0 → annet-3.4.0}/annet/generators/perf.py +9 -18
  8. {annet-3.2.0 → annet-3.4.0/annet.egg-info}/PKG-INFO +2 -2
  9. {annet-3.2.0 → annet-3.4.0}/annet.egg-info/requires.txt +1 -1
  10. {annet-3.2.0 → annet-3.4.0}/setup.py +1 -1
  11. {annet-3.2.0 → annet-3.4.0}/AUTHORS +0 -0
  12. {annet-3.2.0 → annet-3.4.0}/LICENSE +0 -0
  13. {annet-3.2.0 → annet-3.4.0}/MANIFEST.in +0 -0
  14. {annet-3.2.0 → annet-3.4.0}/README.md +0 -0
  15. {annet-3.2.0 → annet-3.4.0}/annet/__init__.py +0 -0
  16. {annet-3.2.0 → annet-3.4.0}/annet/adapters/__init__.py +0 -0
  17. {annet-3.2.0 → annet-3.4.0}/annet/adapters/fetchers/__init__.py +0 -0
  18. {annet-3.2.0 → annet-3.4.0}/annet/adapters/fetchers/stub/__init__.py +0 -0
  19. {annet-3.2.0 → annet-3.4.0}/annet/adapters/fetchers/stub/fetcher.py +0 -0
  20. {annet-3.2.0 → annet-3.4.0}/annet/adapters/file/__init__.py +0 -0
  21. {annet-3.2.0 → annet-3.4.0}/annet/adapters/file/provider.py +0 -0
  22. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/__init__.py +0 -0
  23. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/__init__.py +0 -0
  24. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/adapter.py +0 -0
  25. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/client.py +0 -0
  26. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/manufacturer.py +0 -0
  27. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/models.py +0 -0
  28. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/query.py +0 -0
  29. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/status_client.py +0 -0
  30. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/storage_base.py +0 -0
  31. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/common/storage_opts.py +0 -0
  32. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/provider.py +0 -0
  33. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v24/__init__.py +0 -0
  34. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v24/models.py +0 -0
  35. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v24/storage.py +0 -0
  36. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v37/__init__.py +0 -0
  37. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v37/models.py +0 -0
  38. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v37/storage.py +0 -0
  39. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v41/__init__.py +0 -0
  40. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v41/models.py +0 -0
  41. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v41/storage.py +0 -0
  42. {annet-3.2.0 → annet-3.4.0}/annet/adapters/netbox/v42/__init__.py +0 -0
  43. {annet-3.2.0 → annet-3.4.0}/annet/annet.py +0 -0
  44. {annet-3.2.0 → annet-3.4.0}/annet/annlib/__init__.py +0 -0
  45. {annet-3.2.0 → annet-3.4.0}/annet/annlib/command.py +0 -0
  46. {annet-3.2.0 → annet-3.4.0}/annet/annlib/diff.py +0 -0
  47. {annet-3.2.0 → annet-3.4.0}/annet/annlib/errors.py +0 -0
  48. {annet-3.2.0 → annet-3.4.0}/annet/annlib/filter_acl.py +0 -0
  49. {annet-3.2.0 → annet-3.4.0}/annet/annlib/jsontools.py +0 -0
  50. {annet-3.2.0 → annet-3.4.0}/annet/annlib/lib.py +0 -0
  51. {annet-3.2.0 → annet-3.4.0}/annet/annlib/netdev/__init__.py +0 -0
  52. {annet-3.2.0 → annet-3.4.0}/annet/annlib/netdev/db.py +0 -0
  53. {annet-3.2.0 → annet-3.4.0}/annet/annlib/netdev/devdb/__init__.py +0 -0
  54. {annet-3.2.0 → annet-3.4.0}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
  55. {annet-3.2.0 → annet-3.4.0}/annet/annlib/netdev/views/__init__.py +0 -0
  56. {annet-3.2.0 → annet-3.4.0}/annet/annlib/netdev/views/dump.py +0 -0
  57. {annet-3.2.0 → annet-3.4.0}/annet/annlib/netdev/views/hardware.py +0 -0
  58. {annet-3.2.0 → annet-3.4.0}/annet/annlib/output.py +0 -0
  59. {annet-3.2.0 → annet-3.4.0}/annet/annlib/patching.py +0 -0
  60. {annet-3.2.0 → annet-3.4.0}/annet/annlib/rbparser/__init__.py +0 -0
  61. {annet-3.2.0 → annet-3.4.0}/annet/annlib/rbparser/acl.py +0 -0
  62. {annet-3.2.0 → annet-3.4.0}/annet/annlib/rbparser/deploying.py +0 -0
  63. {annet-3.2.0 → annet-3.4.0}/annet/annlib/rbparser/ordering.py +0 -0
  64. {annet-3.2.0 → annet-3.4.0}/annet/annlib/rbparser/platform.py +0 -0
  65. {annet-3.2.0 → annet-3.4.0}/annet/annlib/rbparser/syntax.py +0 -0
  66. {annet-3.2.0 → annet-3.4.0}/annet/annlib/rulebook/__init__.py +0 -0
  67. {annet-3.2.0 → annet-3.4.0}/annet/annlib/rulebook/common.py +0 -0
  68. {annet-3.2.0 → annet-3.4.0}/annet/annlib/tabparser.py +0 -0
  69. {annet-3.2.0 → annet-3.4.0}/annet/annlib/types.py +0 -0
  70. {annet-3.2.0 → annet-3.4.0}/annet/argparse.py +0 -0
  71. {annet-3.2.0 → annet-3.4.0}/annet/bgp_models.py +0 -0
  72. {annet-3.2.0 → annet-3.4.0}/annet/cli.py +0 -0
  73. {annet-3.2.0 → annet-3.4.0}/annet/cli_args.py +0 -0
  74. {annet-3.2.0 → annet-3.4.0}/annet/configs/context.yml +0 -0
  75. {annet-3.2.0 → annet-3.4.0}/annet/configs/logging.yaml +0 -0
  76. {annet-3.2.0 → annet-3.4.0}/annet/connectors.py +0 -0
  77. {annet-3.2.0 → annet-3.4.0}/annet/deploy.py +0 -0
  78. {annet-3.2.0 → annet-3.4.0}/annet/deploy_ui.py +0 -0
  79. {annet-3.2.0 → annet-3.4.0}/annet/diff.py +0 -0
  80. {annet-3.2.0 → annet-3.4.0}/annet/executor.py +0 -0
  81. {annet-3.2.0 → annet-3.4.0}/annet/filtering.py +0 -0
  82. {annet-3.2.0 → annet-3.4.0}/annet/gen.py +0 -0
  83. {annet-3.2.0 → annet-3.4.0}/annet/generators/base.py +0 -0
  84. {annet-3.2.0 → annet-3.4.0}/annet/generators/common/__init__.py +0 -0
  85. {annet-3.2.0 → annet-3.4.0}/annet/generators/common/initial.py +0 -0
  86. {annet-3.2.0 → annet-3.4.0}/annet/generators/exceptions.py +0 -0
  87. {annet-3.2.0 → annet-3.4.0}/annet/generators/jsonfragment.py +0 -0
  88. {annet-3.2.0 → annet-3.4.0}/annet/generators/partial.py +0 -0
  89. {annet-3.2.0 → annet-3.4.0}/annet/generators/ref.py +0 -0
  90. {annet-3.2.0 → annet-3.4.0}/annet/generators/result.py +0 -0
  91. {annet-3.2.0 → annet-3.4.0}/annet/hardware.py +0 -0
  92. {annet-3.2.0 → annet-3.4.0}/annet/implicit.py +0 -0
  93. {annet-3.2.0 → annet-3.4.0}/annet/lib.py +0 -0
  94. {annet-3.2.0 → annet-3.4.0}/annet/mesh/__init__.py +0 -0
  95. {annet-3.2.0 → annet-3.4.0}/annet/mesh/basemodel.py +0 -0
  96. {annet-3.2.0 → annet-3.4.0}/annet/mesh/device_models.py +0 -0
  97. {annet-3.2.0 → annet-3.4.0}/annet/mesh/executor.py +0 -0
  98. {annet-3.2.0 → annet-3.4.0}/annet/mesh/match_args.py +0 -0
  99. {annet-3.2.0 → annet-3.4.0}/annet/mesh/models_converter.py +0 -0
  100. {annet-3.2.0 → annet-3.4.0}/annet/mesh/peer_models.py +0 -0
  101. {annet-3.2.0 → annet-3.4.0}/annet/mesh/port_processor.py +0 -0
  102. {annet-3.2.0 → annet-3.4.0}/annet/mesh/registry.py +0 -0
  103. {annet-3.2.0 → annet-3.4.0}/annet/output.py +0 -0
  104. {annet-3.2.0 → annet-3.4.0}/annet/parallel.py +0 -0
  105. {annet-3.2.0 → annet-3.4.0}/annet/patching.py +0 -0
  106. {annet-3.2.0 → annet-3.4.0}/annet/reference.py +0 -0
  107. {annet-3.2.0 → annet-3.4.0}/annet/rpl/__init__.py +0 -0
  108. {annet-3.2.0 → annet-3.4.0}/annet/rpl/action.py +0 -0
  109. {annet-3.2.0 → annet-3.4.0}/annet/rpl/condition.py +0 -0
  110. {annet-3.2.0 → annet-3.4.0}/annet/rpl/match_builder.py +0 -0
  111. {annet-3.2.0 → annet-3.4.0}/annet/rpl/policy.py +0 -0
  112. {annet-3.2.0 → annet-3.4.0}/annet/rpl/result.py +0 -0
  113. {annet-3.2.0 → annet-3.4.0}/annet/rpl/routemap.py +0 -0
  114. {annet-3.2.0 → annet-3.4.0}/annet/rpl/statement_builder.py +0 -0
  115. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/__init__.py +0 -0
  116. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/aspath.py +0 -0
  117. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/community.py +0 -0
  118. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/cumulus_frr.py +0 -0
  119. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/entities.py +0 -0
  120. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/execute.py +0 -0
  121. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/policy.py +0 -0
  122. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/prefix_lists.py +0 -0
  123. {annet-3.2.0 → annet-3.4.0}/annet/rpl_generators/rd.py +0 -0
  124. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/__init__.py +0 -0
  125. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/arista/__init__.py +0 -0
  126. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/arista/aaa.py +0 -0
  127. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/arista/iface.py +0 -0
  128. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/aruba/__init__.py +0 -0
  129. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/aruba/ap_env.py +0 -0
  130. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/aruba/misc.py +0 -0
  131. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/b4com/__init__.py +0 -0
  132. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/b4com/file.py +0 -0
  133. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/b4com/iface.py +0 -0
  134. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/cisco/__init__.py +0 -0
  135. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/cisco/iface.py +0 -0
  136. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/cisco/misc.py +0 -0
  137. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/cisco/vlandb.py +0 -0
  138. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/common.py +0 -0
  139. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/deploying.py +0 -0
  140. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/huawei/__init__.py +0 -0
  141. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/huawei/aaa.py +0 -0
  142. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/huawei/bgp.py +0 -0
  143. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/huawei/iface.py +0 -0
  144. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/huawei/misc.py +0 -0
  145. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/huawei/vlandb.py +0 -0
  146. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/juniper/__init__.py +0 -0
  147. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/nexus/__init__.py +0 -0
  148. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/nexus/iface.py +0 -0
  149. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/patching.py +0 -0
  150. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/routeros/__init__.py +0 -0
  151. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/routeros/file.py +0 -0
  152. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/arista.deploy +0 -0
  153. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/arista.order +0 -0
  154. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/arista.rul +0 -0
  155. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/aruba.deploy +0 -0
  156. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/aruba.order +0 -0
  157. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/aruba.rul +0 -0
  158. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/b4com.deploy +0 -0
  159. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/b4com.order +0 -0
  160. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/b4com.rul +0 -0
  161. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/cisco.deploy +0 -0
  162. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/cisco.order +0 -0
  163. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/cisco.rul +0 -0
  164. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/huawei.deploy +0 -0
  165. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/huawei.order +0 -0
  166. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/huawei.rul +0 -0
  167. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/iosxr.deploy +0 -0
  168. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/iosxr.order +0 -0
  169. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/iosxr.rul +0 -0
  170. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/juniper.order +0 -0
  171. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/juniper.rul +0 -0
  172. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/nexus.deploy +0 -0
  173. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/nexus.order +0 -0
  174. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/nexus.rul +0 -0
  175. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/nokia.rul +0 -0
  176. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/optixtrans.deploy +0 -0
  177. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/optixtrans.order +0 -0
  178. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/optixtrans.rul +0 -0
  179. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/pc.deploy +0 -0
  180. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/pc.order +0 -0
  181. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/pc.rul +0 -0
  182. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/ribbon.deploy +0 -0
  183. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/ribbon.rul +0 -0
  184. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/routeros.order +0 -0
  185. {annet-3.2.0 → annet-3.4.0}/annet/rulebook/texts/routeros.rul +0 -0
  186. {annet-3.2.0 → annet-3.4.0}/annet/storage.py +0 -0
  187. {annet-3.2.0 → annet-3.4.0}/annet/text_term_format.py +0 -0
  188. {annet-3.2.0 → annet-3.4.0}/annet/tracing.py +0 -0
  189. {annet-3.2.0 → annet-3.4.0}/annet/types.py +0 -0
  190. {annet-3.2.0 → annet-3.4.0}/annet/vendors/__init__.py +0 -0
  191. {annet-3.2.0 → annet-3.4.0}/annet/vendors/base.py +0 -0
  192. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/__init__.py +0 -0
  193. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/arista.py +0 -0
  194. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/aruba.py +0 -0
  195. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/b4com.py +0 -0
  196. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/cisco.py +0 -0
  197. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/h3c.py +0 -0
  198. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/huawei.py +0 -0
  199. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/iosxr.py +0 -0
  200. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/juniper.py +0 -0
  201. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/nexus.py +0 -0
  202. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/nokia.py +0 -0
  203. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/optixtrans.py +0 -0
  204. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/pc.py +0 -0
  205. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/ribbon.py +0 -0
  206. {annet-3.2.0 → annet-3.4.0}/annet/vendors/library/routeros.py +0 -0
  207. {annet-3.2.0 → annet-3.4.0}/annet/vendors/registry.py +0 -0
  208. {annet-3.2.0 → annet-3.4.0}/annet.egg-info/SOURCES.txt +0 -0
  209. {annet-3.2.0 → annet-3.4.0}/annet.egg-info/dependency_links.txt +0 -0
  210. {annet-3.2.0 → annet-3.4.0}/annet.egg-info/entry_points.txt +0 -0
  211. {annet-3.2.0 → annet-3.4.0}/annet.egg-info/top_level.txt +0 -0
  212. {annet-3.2.0 → annet-3.4.0}/annet_generators/__init__.py +0 -0
  213. {annet-3.2.0 → annet-3.4.0}/annet_generators/example/__init__.py +0 -0
  214. {annet-3.2.0 → annet-3.4.0}/annet_generators/example/hostname.py +0 -0
  215. {annet-3.2.0 → annet-3.4.0}/annet_generators/example/lldp.py +0 -0
  216. {annet-3.2.0 → annet-3.4.0}/annet_generators/mesh_example/__init__.py +0 -0
  217. {annet-3.2.0 → annet-3.4.0}/annet_generators/mesh_example/bgp.py +0 -0
  218. {annet-3.2.0 → annet-3.4.0}/annet_generators/mesh_example/mesh_logic.py +0 -0
  219. {annet-3.2.0 → annet-3.4.0}/annet_generators/rpl_example/__init__.py +0 -0
  220. {annet-3.2.0 → annet-3.4.0}/annet_generators/rpl_example/generator.py +0 -0
  221. {annet-3.2.0 → annet-3.4.0}/annet_generators/rpl_example/items.py +0 -0
  222. {annet-3.2.0 → annet-3.4.0}/annet_generators/rpl_example/mesh.py +0 -0
  223. {annet-3.2.0 → annet-3.4.0}/annet_generators/rpl_example/route_policy.py +0 -0
  224. {annet-3.2.0 → annet-3.4.0}/requirements.txt +0 -0
  225. {annet-3.2.0 → annet-3.4.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annet
3
- Version: 3.2.0
3
+ Version: 3.4.0
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -21,7 +21,7 @@ Requires-Dist: yarl>=1.8.2
21
21
  Requires-Dist: adaptix==3.0.0b7
22
22
  Requires-Dist: dataclass-rest==0.4
23
23
  Provides-Extra: netbox
24
- Requires-Dist: annetbox[sync]>=0.3.0; extra == "netbox"
24
+ Requires-Dist: annetbox[sync]>=0.4.0; extra == "netbox"
25
25
  Dynamic: home-page
26
26
  Dynamic: license
27
27
  Dynamic: license-file
@@ -3,6 +3,7 @@ from datetime import datetime, timezone
3
3
  from typing import Optional
4
4
  from annet.adapters.netbox.common.models import InterfaceType, IpFamily, Label, Prefix, Entity
5
5
  from annet.adapters.netbox.v41.models import InterfaceV41, IpAddressV41, NetboxDeviceV41
6
+ import annetbox.v42.models
6
7
 
7
8
 
8
9
  @dataclass
@@ -61,3 +62,8 @@ class NetboxDeviceV42(NetboxDeviceV41):
61
62
  connected_endpoints=[],
62
63
  mode=None,
63
64
  )
65
+
66
+
67
+ # should be unified in case of netbox update
68
+ Vrf = annetbox.v42.models.Vrf
69
+ Vlan = annetbox.v42.models.Vlan
@@ -1,4 +1,6 @@
1
1
  import ssl
2
+ from typing import Optional
3
+
2
4
  from adaptix import P
3
5
  from adaptix.conversion import get_converter, link, link_constant, link_function
4
6
  from annetbox.v42 import client_sync
@@ -6,7 +8,8 @@ from annetbox.v42 import models as api_models
6
8
 
7
9
  from annet.adapters.netbox.common.adapter import NetboxAdapter, get_device_breed, get_device_hw
8
10
  from annet.adapters.netbox.common.storage_base import BaseNetboxStorage
9
- from annet.adapters.netbox.v42.models import InterfaceV42, NetboxDeviceV42, PrefixV42, IpAddressV42
11
+ from annet.adapters.netbox.common.storage_opts import NetboxStorageOpts
12
+ from annet.adapters.netbox.v42.models import InterfaceV42, NetboxDeviceV42, PrefixV42, IpAddressV42, Vlan, Vrf
10
13
  from annet.storage import Storage
11
14
 
12
15
 
@@ -79,8 +82,21 @@ class NetboxV42Adapter(NetboxAdapter[NetboxDeviceV42, InterfaceV42, IpAddressV42
79
82
  def list_ipprefixes(self, prefixes: list[str]) -> list[PrefixV42]:
80
83
  return self.convert_ip_prefixes(self.netbox.ipam_all_prefixes(prefix=prefixes).results)
81
84
 
85
+ def list_all_vrfs(self) -> list[Vrf]:
86
+ return self.netbox.ipam_all_vrfs().results
87
+
88
+ def list_all_vlans(self) -> list[Vlan]:
89
+ return self.netbox.ipam_all_vlans().results
90
+
82
91
 
83
92
  class NetboxStorageV42(BaseNetboxStorage[NetboxDeviceV42, InterfaceV42, IpAddressV42, PrefixV42]):
93
+ netbox: NetboxV42Adapter
94
+
95
+ def __init__(self, opts: Optional[NetboxStorageOpts] = None):
96
+ super().__init__(opts)
97
+ self._all_vlans: list[Vlan] | None = None
98
+ self._all_vrfs: list[Vrf] | None = None
99
+
84
100
  def _init_adapter(
85
101
  self,
86
102
  url: str,
@@ -89,3 +105,13 @@ class NetboxStorageV42(BaseNetboxStorage[NetboxDeviceV42, InterfaceV42, IpAddres
89
105
  threads: int,
90
106
  ) -> NetboxAdapter[NetboxDeviceV42, InterfaceV42, IpAddressV42, PrefixV42]:
91
107
  return NetboxV42Adapter(self, url, token, ssl_context, threads)
108
+
109
+ def resolve_all_vlans(self) -> list[Vlan]:
110
+ if self._all_vlans is None:
111
+ self._all_vlans = self.netbox.list_all_vlans()
112
+ return self._all_vlans
113
+
114
+ def resolve_all_vrfs(self) -> list[Vrf]:
115
+ if self._all_vrfs is None:
116
+ self._all_vrfs = self.netbox.list_all_vrfs()
117
+ return self._all_vrfs
@@ -6,9 +6,10 @@ import sys
6
6
  import time
7
7
  import warnings
8
8
  from collections import OrderedDict as odict
9
- from itertools import groupby, chain
9
+ from itertools import chain, groupby
10
10
  from operator import itemgetter
11
11
  from typing import (
12
+ Any,
12
13
  Dict,
13
14
  Generator,
14
15
  Iterable,
@@ -16,39 +17,37 @@ from typing import (
16
17
  Mapping,
17
18
  Set,
18
19
  Tuple,
19
- Union, cast, Any,
20
+ Union,
21
+ cast,
20
22
  )
21
23
 
22
24
  import colorama
25
+ from contextlog import get_logger
26
+
23
27
  import annet.deploy
24
28
  import annet.deploy_ui
25
29
  import annet.lib
26
- from annet.annlib import jsontools
27
- from annet.annlib.netdev.views.hardware import HardwareView
28
- from annet.annlib.types import GeneratorType
29
- from contextlog import get_logger
30
-
31
- from annet.deploy import Fetcher, DeployDriver
32
30
  from annet import cli_args
33
31
  from annet import diff as ann_diff
34
32
  from annet import filtering
35
33
  from annet import gen as ann_gen
36
34
  from annet import patching, rulebook, tabparser, tracing
35
+ from annet.annlib import jsontools
36
+ from annet.annlib.netdev.views.hardware import HardwareView
37
+ from annet.annlib.types import GeneratorType
38
+ from annet.deploy import DeployDriver, Fetcher
37
39
  from annet.diff import file_differ_connector
38
- from annet.rulebook import deploying
39
40
  from annet.filtering import Filterer
40
41
  from annet.hardware import hardware_connector
41
- from annet.output import (
42
- format_file_diff,
43
- output_driver_connector,
44
- print_err_label,
45
- )
42
+ from annet.output import format_file_diff, output_driver_connector, print_err_label
46
43
  from annet.parallel import Parallel, TaskResult
47
44
  from annet.reference import RefTracker
45
+ from annet.rulebook import deploying
48
46
  from annet.storage import Device, get_storage
49
- from annet.types import Diff, ExitCode, OldNewResult, Op, PCDiff, PCDiffFile
47
+ from annet.types import Diff, ExitCode, OldNewResult, Op, PCDiff
50
48
  from annet.vendors import registry_connector
51
49
 
50
+
52
51
  DEFAULT_INDENT = " "
53
52
 
54
53
 
@@ -96,21 +95,45 @@ def _read_old_new_diff_patch(old: Dict[str, Dict], new: Dict[str, Dict], hw: Har
96
95
  return rb, diff_obj, pre, patchtree
97
96
 
98
97
 
99
- def _read_old_new_hw(old_path: str, new_path: str, args: cli_args.FileInputOptions):
98
+ def _read_old_new_configs(old_path, new_path):
99
+ _logger = get_logger()
100
+ with open(old_path) as f:
101
+ _logger.debug("Reading %r ...", old_path)
102
+ old_config = f.read()
103
+
104
+ with open(new_path) as f:
105
+ _logger.debug("Reading %r ...", new_path)
106
+ new_config = f.read()
107
+
108
+ return old_config, new_config
109
+
110
+
111
+ def _read_old_new_hw(old_path: str, old_config: str, new_path: str, new_config: str, args: cli_args.FileInputOptions):
100
112
  _logger = get_logger()
113
+
101
114
  hw = args.hw
102
115
  if isinstance(args.hw, str):
103
116
  hw = HardwareView(args.hw, "")
104
117
 
105
- old, old_hw, old_score = _read_device_config(old_path, hw)
106
- new, new_hw, new_score = _read_device_config(new_path, hw)
118
+ try:
119
+ old, old_hw, old_score = _parse_device_config(old_config, hw)
120
+ except tabparser.ParserError:
121
+ _logger.exception("Parser error: %r", old_path)
122
+ raise
123
+
124
+ try:
125
+ new, new_hw, new_score = _parse_device_config(new_config, hw)
126
+ except tabparser.ParserError:
127
+ _logger.exception("Parser error: %r", new_path)
128
+ raise
129
+
107
130
  hw = new_hw
108
131
  if old_score > new_score:
109
132
  hw = old_hw
110
133
  if old_hw != new_hw:
111
- _logger.debug("Old and new detected hw differs, assume %r", hw)
112
- dest_name = os.path.basename(new_path)
113
- return dest_name, old, new, hw
134
+ _logger.warning("Old and new detected hw differs, assume %r", hw)
135
+
136
+ return old, new, hw
114
137
 
115
138
 
116
139
  @tracing.function
@@ -134,27 +157,19 @@ def _read_old_new_cfgdumps(args: cli_args.FileInputOptions):
134
157
  yield (old_path_name, new_path_name)
135
158
 
136
159
 
137
- def _read_device_config(path, hw):
138
- _logger = get_logger()
139
- _logger.debug("Reading %r ...", path)
160
+ def _parse_device_config(text, hw):
140
161
  score = 1
141
162
  vendor_registry = registry_connector.get()
142
163
 
143
- with open(path) as cfgdump_file:
144
- text = cfgdump_file.read()
145
- try:
146
- if not hw:
147
- hw, score = guess_hw(text)
164
+ if not hw:
165
+ hw, score = guess_hw(text)
148
166
 
149
- config = tabparser.parse_to_tree(
150
- text=text,
151
- splitter=vendor_registry.match(hw).make_formatter().split,
152
- )
167
+ config = tabparser.parse_to_tree(
168
+ text=text,
169
+ splitter=vendor_registry.match(hw).make_formatter().split,
170
+ )
153
171
 
154
- return config, hw, score
155
- except tabparser.ParserError:
156
- _logger.exception("Parser error: %r", path)
157
- raise
172
+ return config, hw, score
158
173
 
159
174
 
160
175
  # =====
@@ -756,12 +771,15 @@ def file_diff_worker(
756
771
  if diff_text:
757
772
  yield diff_file.label, diff_text, False
758
773
  else:
759
- dest_name, old, new, hw = _read_old_new_hw(old_path, new_path, args)
774
+ old_config, new_config = _read_old_new_configs(old_path, new_path)
775
+ if old_config == new_config:
776
+ return
777
+
778
+ old, new, hw = _read_old_new_hw(old_path, old_config, new_path, new_config, args)
760
779
  _, __, pre, ___ = _read_old_new_diff_patch(old, new, hw, add_comments=False)
761
- diff_lines = ann_diff.gen_pre_as_diff(pre, args.show_rules, args.indent, args.no_color)
762
- diff_text = "".join(diff_lines)
763
- if diff_text:
764
- yield dest_name, diff_text, False
780
+
781
+ if diff_lines := ann_diff.gen_pre_as_diff(pre, args.show_rules, args.indent, args.no_color):
782
+ yield os.path.basename(new_path), "".join(diff_lines), False
765
783
 
766
784
 
767
785
  @tracing.function
@@ -773,18 +791,23 @@ def file_patch(args: cli_args.FilePatchOptions):
773
791
 
774
792
 
775
793
  def file_patch_worker(old_new: Tuple[str, str], args: cli_args.FileDiffOptions) -> Generator[
776
- Tuple[str, str, bool], None, None]:
794
+ Tuple[str, str, bool], None, None
795
+ ]:
777
796
  old_path, new_path = old_new
778
797
  if os.path.isdir(old_path) and os.path.isdir(new_path):
779
798
  for relative_cfg_path, cfg_text in ann_gen.load_pc_config(new_path).items():
780
799
  label = os.path.join(os.path.basename(new_path), relative_cfg_path)
781
800
  yield label, cfg_text, False
782
801
  else:
783
- dest_name, old, new, hw = _read_old_new_hw(old_path, new_path, args)
802
+ old_config, new_config = _read_old_new_configs(old_path, new_path)
803
+ if old_config == new_config:
804
+ return
805
+
806
+ old, new, hw = _read_old_new_hw(old_path, old_config, new_path, new_config, args)
784
807
  _, __, ___, patch_tree = _read_old_new_diff_patch(old, new, hw, args.add_comments)
785
808
  patch_text = _format_patch_blocks(patch_tree, hw, args.indent)
786
809
  if patch_text:
787
- yield dest_name, patch_text, False
810
+ yield os.path.basename(new_path), patch_text, False
788
811
 
789
812
 
790
813
  def guess_hw(config_text: str):
@@ -157,7 +157,7 @@ def run_partial_generators(
157
157
 
158
158
 
159
159
  @tracing.function(name="run_partial_generator")
160
- def _run_partial_generator(gen: "PartialGenerator", run_args: GeneratorPartialRunArgs) -> Optional[GeneratorPartialResult]:
160
+ def _run_partial_generator(gen: "PartialGenerator", run_args: GeneratorPartialRunArgs) -> GeneratorPartialResult | None:
161
161
  logger = get_logger(generator=_make_generator_ctx(gen))
162
162
  device = run_args.device
163
163
  output = ""
@@ -207,7 +207,9 @@ def _run_partial_generator(gen: "PartialGenerator", run_args: GeneratorPartialRu
207
207
 
208
208
  if run_args.use_acl:
209
209
  try:
210
- with tracing_connector.get().start_as_current_span("apply_acl", tracer_name=__name__, min_duration="0.01") as acl_span:
210
+ with tracing_connector.get().start_as_current_span(
211
+ "apply_acl", tracer_name=__name__, min_duration="0.01"
212
+ ) as acl_span:
211
213
  tracing_connector.get().set_device_attributes(acl_span, run_args.device)
212
214
  config = patching.apply_acl(
213
215
  config=config,
@@ -265,8 +267,8 @@ def check_entire_generators_required_packages(gens, device_packages: FrozenSet[s
265
267
 
266
268
  @tracing.function
267
269
  def run_file_generators(
268
- gens: Iterable[Union["JSONFragment", "Entire"]],
269
- device: "Device",
270
+ gens: Iterable[Union["JSONFragment", "Entire"]],
271
+ device: "Device",
270
272
  ) -> RunGeneratorResult:
271
273
  """Run generators that generate files or file parts."""
272
274
  ret = RunGeneratorResult()
@@ -295,21 +297,22 @@ def run_file_generators(
295
297
  @tracing.function(min_duration="0.5")
296
298
  def _run_entire_generator(gen: "Entire", device: "Device") -> Optional[GeneratorResult]:
297
299
  logger = get_logger(generator=_make_generator_ctx(gen))
298
- if not gen.supports_device(device):
299
- logger.info("generator %s is not supported for device %s", gen, device.hostname)
300
- return
301
-
302
300
  span = tracing_connector.get().get_current_span()
303
301
  if span:
304
302
  tracing_connector.get().set_device_attributes(span, device)
305
303
  tracing_connector.get().set_dimensions_attributes(span, gen, device)
306
304
 
307
- path = gen.path(device)
308
- if not path:
309
- raise RuntimeError("entire generator should return non-empty path")
310
-
311
- logger.info("Generating ENTIRE ...")
312
305
  with GeneratorPerfMesurer(gen, trace_min_duration="0.5") as pm:
306
+ if not gen.supports_device(device):
307
+ logger.debug("generator %s is not supported for device %s", gen, device.hostname)
308
+ return
309
+
310
+ path = gen.path(device)
311
+ if not path:
312
+ raise RuntimeError("entire generator should return non-empty path")
313
+
314
+ logger.info("Generating ENTIRE ...")
315
+
313
316
  output = gen(device)
314
317
 
315
318
  return GeneratorEntireResult(
@@ -329,35 +332,37 @@ def _make_generator_ctx(gen):
329
332
 
330
333
 
331
334
  def _run_json_fragment_generator(
332
- gen: "JSONFragment",
333
- device: "Device",
335
+ gen: "JSONFragment",
336
+ device: "Device",
334
337
  ) -> Optional[GeneratorResult]:
335
338
  logger = get_logger(generator=_make_generator_ctx(gen))
336
- if not gen.supports_device(device):
337
- logger.info("generator %s is not supported for device %s", gen, device.hostname)
338
- return
339
-
340
- path = gen.path(device)
341
- if not path:
342
- raise RuntimeError("json fragment generator should return non-empty path")
343
-
344
- acl_item_or_list_of_items = gen.acl(device)
345
- safe_acl_item_or_list_of_items = gen.acl_safe(device)
346
- if not acl_item_or_list_of_items:
347
- raise RuntimeError("json fragment generator should return non-empty acl")
348
- if isinstance(acl_item_or_list_of_items, list):
349
- acl = acl_item_or_list_of_items
350
- else:
351
- acl = [acl_item_or_list_of_items]
352
- if isinstance(safe_acl_item_or_list_of_items, list):
353
- acl_safe = safe_acl_item_or_list_of_items
354
- else:
355
- acl_safe = [safe_acl_item_or_list_of_items]
356
-
357
- logger.info("Generating JSON_FRAGMENT ...")
339
+
358
340
  with GeneratorPerfMesurer(gen) as pm:
341
+ if not gen.supports_device(device):
342
+ logger.info("generator %s is not supported for device %s", gen, device.hostname)
343
+ return
344
+
345
+ path = gen.path(device)
346
+ if not path:
347
+ raise RuntimeError("json fragment generator should return non-empty path")
348
+
349
+ acl_item_or_list_of_items = gen.acl(device)
350
+ safe_acl_item_or_list_of_items = gen.acl_safe(device)
351
+ if not acl_item_or_list_of_items:
352
+ raise RuntimeError("json fragment generator should return non-empty acl")
353
+ if isinstance(acl_item_or_list_of_items, list):
354
+ acl = acl_item_or_list_of_items
355
+ else:
356
+ acl = [acl_item_or_list_of_items]
357
+ if isinstance(safe_acl_item_or_list_of_items, list):
358
+ acl_safe = safe_acl_item_or_list_of_items
359
+ else:
360
+ acl_safe = [safe_acl_item_or_list_of_items]
361
+
362
+ logger.info("Generating JSON_FRAGMENT ...")
363
+
359
364
  config = gen(device)
360
- reload_cmds = gen.get_reload_cmds(device)
365
+ reload_cmds = gen.get_reload_cmds(device)
361
366
  return GeneratorJSONFragmentResult(
362
367
  name=gen.__class__.__name__,
363
368
  tags=gen.TAGS,
@@ -407,7 +412,8 @@ def _load_gen_module(module_path: str):
407
412
  except ModuleNotFoundError as e:
408
413
  try: # maybe it's a path to module
409
414
  module_abs_path = os.path.abspath(module_path)
410
- module = importlib.machinery.SourceFileLoader(re.sub(r"[./]", "_", module_abs_path).strip("_"), module_abs_path).load_module()
415
+ module = importlib.machinery.SourceFileLoader(re.sub(r"[./]", "_", module_abs_path).strip("_"),
416
+ module_abs_path).load_module()
411
417
  except ModuleNotFoundError:
412
418
  raise e
413
419
  return module
@@ -3,19 +3,10 @@ from __future__ import annotations
3
3
  import pkgutil
4
4
  import re
5
5
  import types
6
- from typing import (
7
- FrozenSet,
8
- Iterable,
9
- List,
10
- Optional,
11
- Set,
12
- Union,
13
- )
14
-
15
- from annet.lib import (
16
- flatten,
17
- mako_render,
18
- )
6
+ from typing import FrozenSet, Iterable, List, Optional, Set, Union
7
+
8
+ from annet.lib import flatten, mako_render
9
+
19
10
  from .base import BaseGenerator, _filter_str
20
11
  from .exceptions import NotSupportedDevice
21
12
 
@@ -39,8 +30,7 @@ class Entire(BaseGenerator):
39
30
  def run(self, device) -> Union[None, str, Iterable[Union[str, tuple]]]:
40
31
  raise NotImplementedError
41
32
 
42
- def reload(self, device) -> Optional[
43
- str]: # pylint: disable=unused-argument
33
+ def reload(self, device) -> Optional[str]: # pylint: disable=unused-argument
44
34
  return
45
35
 
46
36
  def get_reload_cmds(self, device) -> str:
@@ -1,27 +1,19 @@
1
- from __future__ import annotations
2
-
3
1
  import time
4
- from typing import (
5
- Optional,
6
- Union,
7
- )
2
+ from typing import Optional, Union
8
3
 
9
4
  from annet import tracing
10
5
  from annet.tracing import tracing_connector
11
- from annet.types import (
12
- GeneratorPartialRunArgs,
13
- GeneratorPerf,
14
- )
15
- from .entire import Entire
16
- from .partial import PartialGenerator
6
+ from annet.types import GeneratorPartialRunArgs, GeneratorPerf
7
+
8
+ from .base import BaseGenerator
17
9
 
18
10
 
19
11
  class GeneratorPerfMesurer:
20
12
  def __init__(
21
- self,
22
- gen: Union[PartialGenerator, Entire],
23
- run_args: Optional[GeneratorPartialRunArgs] = None,
24
- trace_min_duration: tracing.MinDurationT = None
13
+ self,
14
+ gen: BaseGenerator,
15
+ run_args: Optional[GeneratorPartialRunArgs] = None,
16
+ trace_min_duration: tracing.MinDurationT = None
25
17
  ):
26
18
  self._gen = gen
27
19
  self._run_args = run_args
@@ -44,8 +36,7 @@ class GeneratorPerfMesurer:
44
36
  self._span = self._span_ctx.__enter__() # pylint: disable=unnecessary-dunder-call
45
37
 
46
38
  if self._span:
47
- self._span.set_attributes(
48
- {"generator.class": self._gen.__class__.__name__})
39
+ self._span.set_attributes({"generator.class": self._gen.__class__.__name__})
49
40
  if self._run_args:
50
41
  tracing_connector.get().set_device_attributes(
51
42
  self._span, self._run_args.device,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annet
3
- Version: 3.2.0
3
+ Version: 3.4.0
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -21,7 +21,7 @@ Requires-Dist: yarl>=1.8.2
21
21
  Requires-Dist: adaptix==3.0.0b7
22
22
  Requires-Dist: dataclass-rest==0.4
23
23
  Provides-Extra: netbox
24
- Requires-Dist: annetbox[sync]>=0.3.0; extra == "netbox"
24
+ Requires-Dist: annetbox[sync]>=0.4.0; extra == "netbox"
25
25
  Dynamic: home-page
26
26
  Dynamic: license
27
27
  Dynamic: license-file
@@ -13,4 +13,4 @@ adaptix==3.0.0b7
13
13
  dataclass-rest==0.4
14
14
 
15
15
  [netbox]
16
- annetbox[sync]>=0.3.0
16
+ annetbox[sync]>=0.4.0
@@ -44,7 +44,7 @@ if __name__ == "__main__":
44
44
  ],
45
45
  },
46
46
  extras_require={
47
- "netbox": ["annetbox[sync]>=0.3.0"],
47
+ "netbox": ["annetbox[sync]>=0.4.0"],
48
48
  },
49
49
  python_requires=">=3.10",
50
50
  install_requires=requirements(),
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