annet 3.0.0__tar.gz → 3.1.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 (227) hide show
  1. {annet-3.0.0/annet.egg-info → annet-3.1.1}/PKG-INFO +1 -1
  2. {annet-3.0.0 → annet-3.1.1}/annet/__init__.py +5 -4
  3. {annet-3.0.0 → annet-3.1.1}/annet/annlib/patching.py +2 -1
  4. annet-3.1.1/annet/annlib/rbparser/platform.py +3 -0
  5. {annet-3.0.0 → annet-3.1.1}/annet/annlib/rulebook/common.py +21 -14
  6. {annet-3.0.0 → annet-3.1.1}/annet/annlib/tabparser.py +0 -18
  7. {annet-3.0.0 → annet-3.1.1}/annet/api/__init__.py +15 -7
  8. {annet-3.0.0 → annet-3.1.1}/annet/diff.py +3 -3
  9. {annet-3.0.0 → annet-3.1.1}/annet/gen.py +6 -6
  10. {annet-3.0.0 → annet-3.1.1}/annet/generators/__init__.py +15 -22
  11. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/__init__.py +1 -1
  12. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/juniper/__init__.py +2 -2
  13. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/patching.py +3 -3
  14. {annet-3.0.0 → annet-3.1.1}/annet/vendors/base.py +13 -0
  15. annet-3.1.1/annet/vendors/library/arista.py +30 -0
  16. annet-3.1.1/annet/vendors/library/aruba.py +30 -0
  17. annet-3.1.1/annet/vendors/library/b4com.py +27 -0
  18. annet-3.1.1/annet/vendors/library/cisco.py +30 -0
  19. annet-3.1.1/annet/vendors/library/h3c.py +27 -0
  20. annet-3.1.1/annet/vendors/library/huawei.py +30 -0
  21. annet-3.1.1/annet/vendors/library/iosxr.py +30 -0
  22. annet-3.1.1/annet/vendors/library/juniper.py +33 -0
  23. annet-3.1.1/annet/vendors/library/nexus.py +27 -0
  24. annet-3.1.1/annet/vendors/library/nokia.py +30 -0
  25. annet-3.1.1/annet/vendors/library/optixtrans.py +27 -0
  26. annet-3.1.1/annet/vendors/library/pc.py +27 -0
  27. annet-3.1.1/annet/vendors/library/ribbon.py +30 -0
  28. annet-3.1.1/annet/vendors/library/routeros.py +27 -0
  29. {annet-3.0.0 → annet-3.1.1}/annet/vendors/registry.py +9 -0
  30. {annet-3.0.0 → annet-3.1.1/annet.egg-info}/PKG-INFO +1 -1
  31. {annet-3.0.0 → annet-3.1.1}/annet.egg-info/SOURCES.txt +15 -1
  32. annet-3.1.1/annet_generators/__init__.py +0 -0
  33. annet-3.0.0/annet/annlib/rbparser/platform.py +0 -69
  34. annet-3.0.0/annet/tabparser.py +0 -53
  35. {annet-3.0.0 → annet-3.1.1}/AUTHORS +0 -0
  36. {annet-3.0.0 → annet-3.1.1}/LICENSE +0 -0
  37. {annet-3.0.0 → annet-3.1.1}/MANIFEST.in +0 -0
  38. {annet-3.0.0 → annet-3.1.1}/README.md +0 -0
  39. {annet-3.0.0 → annet-3.1.1}/annet/adapters/__init__.py +0 -0
  40. {annet-3.0.0 → annet-3.1.1}/annet/adapters/fetchers/__init__.py +0 -0
  41. {annet-3.0.0 → annet-3.1.1}/annet/adapters/fetchers/stub/__init__.py +0 -0
  42. {annet-3.0.0 → annet-3.1.1}/annet/adapters/fetchers/stub/fetcher.py +0 -0
  43. {annet-3.0.0 → annet-3.1.1}/annet/adapters/file/__init__.py +0 -0
  44. {annet-3.0.0 → annet-3.1.1}/annet/adapters/file/provider.py +0 -0
  45. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/__init__.py +0 -0
  46. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/__init__.py +0 -0
  47. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/adapter.py +0 -0
  48. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/client.py +0 -0
  49. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/manufacturer.py +0 -0
  50. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/models.py +0 -0
  51. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/query.py +0 -0
  52. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/status_client.py +0 -0
  53. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/storage_base.py +0 -0
  54. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/common/storage_opts.py +0 -0
  55. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/provider.py +0 -0
  56. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v24/__init__.py +0 -0
  57. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v24/models.py +0 -0
  58. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v24/storage.py +0 -0
  59. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v37/__init__.py +0 -0
  60. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v37/models.py +0 -0
  61. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v37/storage.py +0 -0
  62. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v41/__init__.py +0 -0
  63. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v41/models.py +0 -0
  64. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v41/storage.py +0 -0
  65. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v42/__init__.py +0 -0
  66. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v42/models.py +0 -0
  67. {annet-3.0.0 → annet-3.1.1}/annet/adapters/netbox/v42/storage.py +0 -0
  68. {annet-3.0.0 → annet-3.1.1}/annet/annet.py +0 -0
  69. {annet-3.0.0 → annet-3.1.1}/annet/annlib/__init__.py +0 -0
  70. {annet-3.0.0 → annet-3.1.1}/annet/annlib/command.py +0 -0
  71. {annet-3.0.0 → annet-3.1.1}/annet/annlib/diff.py +0 -0
  72. {annet-3.0.0 → annet-3.1.1}/annet/annlib/errors.py +0 -0
  73. {annet-3.0.0 → annet-3.1.1}/annet/annlib/filter_acl.py +0 -0
  74. {annet-3.0.0 → annet-3.1.1}/annet/annlib/jsontools.py +0 -0
  75. {annet-3.0.0 → annet-3.1.1}/annet/annlib/lib.py +0 -0
  76. {annet-3.0.0 → annet-3.1.1}/annet/annlib/netdev/__init__.py +0 -0
  77. {annet-3.0.0 → annet-3.1.1}/annet/annlib/netdev/db.py +0 -0
  78. {annet-3.0.0 → annet-3.1.1}/annet/annlib/netdev/devdb/__init__.py +0 -0
  79. {annet-3.0.0 → annet-3.1.1}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
  80. {annet-3.0.0 → annet-3.1.1}/annet/annlib/netdev/views/__init__.py +0 -0
  81. {annet-3.0.0 → annet-3.1.1}/annet/annlib/netdev/views/dump.py +0 -0
  82. {annet-3.0.0 → annet-3.1.1}/annet/annlib/netdev/views/hardware.py +0 -0
  83. {annet-3.0.0 → annet-3.1.1}/annet/annlib/output.py +0 -0
  84. {annet-3.0.0 → annet-3.1.1}/annet/annlib/rbparser/__init__.py +0 -0
  85. {annet-3.0.0 → annet-3.1.1}/annet/annlib/rbparser/acl.py +0 -0
  86. {annet-3.0.0 → annet-3.1.1}/annet/annlib/rbparser/deploying.py +0 -0
  87. {annet-3.0.0 → annet-3.1.1}/annet/annlib/rbparser/ordering.py +0 -0
  88. {annet-3.0.0 → annet-3.1.1}/annet/annlib/rbparser/syntax.py +0 -0
  89. {annet-3.0.0 → annet-3.1.1}/annet/annlib/rulebook/__init__.py +0 -0
  90. {annet-3.0.0 → annet-3.1.1}/annet/annlib/types.py +0 -0
  91. {annet-3.0.0 → annet-3.1.1}/annet/argparse.py +0 -0
  92. {annet-3.0.0 → annet-3.1.1}/annet/bgp_models.py +0 -0
  93. {annet-3.0.0 → annet-3.1.1}/annet/cli.py +0 -0
  94. {annet-3.0.0 → annet-3.1.1}/annet/cli_args.py +0 -0
  95. {annet-3.0.0 → annet-3.1.1}/annet/configs/context.yml +0 -0
  96. {annet-3.0.0 → annet-3.1.1}/annet/configs/logging.yaml +0 -0
  97. {annet-3.0.0 → annet-3.1.1}/annet/connectors.py +0 -0
  98. {annet-3.0.0 → annet-3.1.1}/annet/deploy.py +0 -0
  99. {annet-3.0.0 → annet-3.1.1}/annet/deploy_ui.py +0 -0
  100. {annet-3.0.0 → annet-3.1.1}/annet/executor.py +0 -0
  101. {annet-3.0.0 → annet-3.1.1}/annet/filtering.py +0 -0
  102. {annet-3.0.0 → annet-3.1.1}/annet/generators/base.py +0 -0
  103. {annet-3.0.0 → annet-3.1.1}/annet/generators/common/__init__.py +0 -0
  104. {annet-3.0.0 → annet-3.1.1}/annet/generators/common/initial.py +0 -0
  105. {annet-3.0.0 → annet-3.1.1}/annet/generators/entire.py +0 -0
  106. {annet-3.0.0 → annet-3.1.1}/annet/generators/exceptions.py +0 -0
  107. {annet-3.0.0 → annet-3.1.1}/annet/generators/jsonfragment.py +0 -0
  108. {annet-3.0.0 → annet-3.1.1}/annet/generators/partial.py +0 -0
  109. {annet-3.0.0 → annet-3.1.1}/annet/generators/perf.py +0 -0
  110. {annet-3.0.0 → annet-3.1.1}/annet/generators/ref.py +0 -0
  111. {annet-3.0.0 → annet-3.1.1}/annet/generators/result.py +0 -0
  112. {annet-3.0.0 → annet-3.1.1}/annet/hardware.py +0 -0
  113. {annet-3.0.0 → annet-3.1.1}/annet/implicit.py +0 -0
  114. {annet-3.0.0 → annet-3.1.1}/annet/lib.py +0 -0
  115. {annet-3.0.0 → annet-3.1.1}/annet/mesh/__init__.py +0 -0
  116. {annet-3.0.0 → annet-3.1.1}/annet/mesh/basemodel.py +0 -0
  117. {annet-3.0.0 → annet-3.1.1}/annet/mesh/device_models.py +0 -0
  118. {annet-3.0.0 → annet-3.1.1}/annet/mesh/executor.py +0 -0
  119. {annet-3.0.0 → annet-3.1.1}/annet/mesh/match_args.py +0 -0
  120. {annet-3.0.0 → annet-3.1.1}/annet/mesh/models_converter.py +0 -0
  121. {annet-3.0.0 → annet-3.1.1}/annet/mesh/peer_models.py +0 -0
  122. {annet-3.0.0 → annet-3.1.1}/annet/mesh/port_processor.py +0 -0
  123. {annet-3.0.0 → annet-3.1.1}/annet/mesh/registry.py +0 -0
  124. {annet-3.0.0 → annet-3.1.1}/annet/output.py +0 -0
  125. {annet-3.0.0 → annet-3.1.1}/annet/parallel.py +0 -0
  126. {annet-3.0.0 → annet-3.1.1}/annet/patching.py +0 -0
  127. {annet-3.0.0 → annet-3.1.1}/annet/reference.py +0 -0
  128. {annet-3.0.0 → annet-3.1.1}/annet/rpl/__init__.py +0 -0
  129. {annet-3.0.0 → annet-3.1.1}/annet/rpl/action.py +0 -0
  130. {annet-3.0.0 → annet-3.1.1}/annet/rpl/condition.py +0 -0
  131. {annet-3.0.0 → annet-3.1.1}/annet/rpl/match_builder.py +0 -0
  132. {annet-3.0.0 → annet-3.1.1}/annet/rpl/policy.py +0 -0
  133. {annet-3.0.0 → annet-3.1.1}/annet/rpl/result.py +0 -0
  134. {annet-3.0.0 → annet-3.1.1}/annet/rpl/routemap.py +0 -0
  135. {annet-3.0.0 → annet-3.1.1}/annet/rpl/statement_builder.py +0 -0
  136. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/__init__.py +0 -0
  137. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/aspath.py +0 -0
  138. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/community.py +0 -0
  139. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/cumulus_frr.py +0 -0
  140. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/entities.py +0 -0
  141. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/execute.py +0 -0
  142. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/policy.py +0 -0
  143. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/prefix_lists.py +0 -0
  144. {annet-3.0.0 → annet-3.1.1}/annet/rpl_generators/rd.py +0 -0
  145. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/arista/__init__.py +0 -0
  146. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/arista/aaa.py +0 -0
  147. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/arista/iface.py +0 -0
  148. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/aruba/__init__.py +0 -0
  149. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/aruba/ap_env.py +0 -0
  150. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/aruba/misc.py +0 -0
  151. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/b4com/__init__.py +0 -0
  152. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/b4com/file.py +0 -0
  153. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/b4com/iface.py +0 -0
  154. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/cisco/__init__.py +0 -0
  155. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/cisco/iface.py +0 -0
  156. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/cisco/misc.py +0 -0
  157. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/cisco/vlandb.py +0 -0
  158. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/common.py +0 -0
  159. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/deploying.py +0 -0
  160. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/huawei/__init__.py +0 -0
  161. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/huawei/aaa.py +0 -0
  162. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/huawei/bgp.py +0 -0
  163. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/huawei/iface.py +0 -0
  164. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/huawei/misc.py +0 -0
  165. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/huawei/vlandb.py +0 -0
  166. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/nexus/__init__.py +0 -0
  167. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/nexus/iface.py +0 -0
  168. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/routeros/__init__.py +0 -0
  169. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/routeros/file.py +0 -0
  170. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/arista.deploy +0 -0
  171. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/arista.order +0 -0
  172. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/arista.rul +0 -0
  173. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/aruba.deploy +0 -0
  174. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/aruba.order +0 -0
  175. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/aruba.rul +0 -0
  176. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/b4com.deploy +0 -0
  177. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/b4com.order +0 -0
  178. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/b4com.rul +0 -0
  179. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/cisco.deploy +0 -0
  180. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/cisco.order +0 -0
  181. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/cisco.rul +0 -0
  182. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/huawei.deploy +0 -0
  183. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/huawei.order +0 -0
  184. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/huawei.rul +0 -0
  185. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/iosxr.deploy +0 -0
  186. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/iosxr.order +0 -0
  187. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/iosxr.rul +0 -0
  188. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/juniper.order +0 -0
  189. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/juniper.rul +0 -0
  190. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/nexus.deploy +0 -0
  191. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/nexus.order +0 -0
  192. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/nexus.rul +0 -0
  193. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/nokia.rul +0 -0
  194. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/optixtrans.deploy +0 -0
  195. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/optixtrans.order +0 -0
  196. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/optixtrans.rul +0 -0
  197. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/pc.deploy +0 -0
  198. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/pc.order +0 -0
  199. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/pc.rul +0 -0
  200. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/ribbon.deploy +0 -0
  201. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/ribbon.rul +0 -0
  202. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/routeros.order +0 -0
  203. {annet-3.0.0 → annet-3.1.1}/annet/rulebook/texts/routeros.rul +0 -0
  204. {annet-3.0.0 → annet-3.1.1}/annet/storage.py +0 -0
  205. {annet-3.0.0 → annet-3.1.1}/annet/text_term_format.py +0 -0
  206. {annet-3.0.0 → annet-3.1.1}/annet/tracing.py +0 -0
  207. {annet-3.0.0 → annet-3.1.1}/annet/types.py +0 -0
  208. {annet-3.0.0 → annet-3.1.1}/annet/vendors/__init__.py +0 -0
  209. {annet-3.0.0/annet_generators → annet-3.1.1/annet/vendors/library}/__init__.py +0 -0
  210. {annet-3.0.0 → annet-3.1.1}/annet.egg-info/dependency_links.txt +0 -0
  211. {annet-3.0.0 → annet-3.1.1}/annet.egg-info/entry_points.txt +0 -0
  212. {annet-3.0.0 → annet-3.1.1}/annet.egg-info/requires.txt +0 -0
  213. {annet-3.0.0 → annet-3.1.1}/annet.egg-info/top_level.txt +0 -0
  214. {annet-3.0.0 → annet-3.1.1}/annet_generators/example/__init__.py +0 -0
  215. {annet-3.0.0 → annet-3.1.1}/annet_generators/example/hostname.py +0 -0
  216. {annet-3.0.0 → annet-3.1.1}/annet_generators/example/lldp.py +0 -0
  217. {annet-3.0.0 → annet-3.1.1}/annet_generators/mesh_example/__init__.py +0 -0
  218. {annet-3.0.0 → annet-3.1.1}/annet_generators/mesh_example/bgp.py +0 -0
  219. {annet-3.0.0 → annet-3.1.1}/annet_generators/mesh_example/mesh_logic.py +0 -0
  220. {annet-3.0.0 → annet-3.1.1}/annet_generators/rpl_example/__init__.py +0 -0
  221. {annet-3.0.0 → annet-3.1.1}/annet_generators/rpl_example/generator.py +0 -0
  222. {annet-3.0.0 → annet-3.1.1}/annet_generators/rpl_example/items.py +0 -0
  223. {annet-3.0.0 → annet-3.1.1}/annet_generators/rpl_example/mesh.py +0 -0
  224. {annet-3.0.0 → annet-3.1.1}/annet_generators/rpl_example/route_policy.py +0 -0
  225. {annet-3.0.0 → annet-3.1.1}/requirements.txt +0 -0
  226. {annet-3.0.0 → annet-3.1.1}/setup.cfg +0 -0
  227. {annet-3.0.0 → annet-3.1.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annet
3
- Version: 3.0.0
3
+ Version: 3.1.1
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -7,14 +7,15 @@ from argparse import SUPPRESS, Namespace
7
7
 
8
8
  import colorama
9
9
  import yaml
10
- from annet.annlib.errors import ( # pylint: disable=wrong-import-position
11
- DeployCancelled,
12
- ExecError,
13
- )
14
10
  from contextlog import patch_logging, patch_threading
15
11
  from valkit.python import valid_logging_level
16
12
 
17
13
  import annet.argparse
14
+ from annet.annlib import tabparser # pylint: disable=unused-import
15
+ from annet.annlib.errors import ( # pylint: disable=wrong-import-position
16
+ DeployCancelled,
17
+ ExecError,
18
+ )
18
19
 
19
20
 
20
21
  __all__ = ("DeployCancelled", "ExecError")
@@ -184,7 +184,8 @@ class Orderer:
184
184
  f_rule = ""
185
185
  children = []
186
186
  ordering = self.rb
187
- block_exit = platform.VENDOR_EXIT[self.vendor]
187
+
188
+ block_exit = registry_connector.get()[self.vendor].exit
188
189
 
189
190
  for (order, (raw_rule, rule)) in enumerate(ordering.items()):
190
191
  if (
@@ -0,0 +1,3 @@
1
+ VENDOR_ALIASES = {
2
+ "h3c": "huawei",
3
+ }
@@ -135,20 +135,21 @@ class DiffItem(typing.NamedTuple):
135
135
  diff_pre: typing.Dict[str, typing.Any]
136
136
 
137
137
 
138
- def default_diff(old, new, diff_pre, _pops=(Op.AFFECTED,)):
138
+ Differ = typing.Callable[[odict, odict, odict, tuple[Op, ...]], list[DiffItem]]
139
+
140
+
141
+ def default_diff(old: odict, new: odict, diff_pre: odict, _pops: tuple[Op, ...] = (Op.AFFECTED,)) -> list[DiffItem]:
139
142
  diff = base_diff(old, new, diff_pre, _pops, moved_to_affected=True)
140
143
  return diff
141
144
 
142
145
 
143
- def ordered_diff(old, new, diff_pre, _pops=(Op.AFFECTED,)):
146
+ def ordered_diff(old: odict, new: odict, diff_pre: odict, _pops: tuple[Op, ...] = (Op.AFFECTED,)) -> list[DiffItem]:
144
147
  diff = base_diff(old, new, diff_pre, _pops, moved_to_affected=False)
145
148
  return diff
146
149
 
147
150
 
148
- def rewrite_diff(old, new, diff_pre, _pops=(Op.AFFECTED,)):
149
- def iter_diff(
150
- diff: typing.List[DiffItem],
151
- ) -> typing.Iterable[typing.Tuple[int, typing.List[DiffItem]]]:
151
+ def rewrite_diff(old: odict, new: odict, diff_pre: odict, _pops: tuple[Op, ...] = (Op.AFFECTED,)) -> list[DiffItem]:
152
+ def iter_diff(diff: list[DiffItem]) -> typing.Iterable[tuple[int, list[DiffItem]]]:
152
153
  queue = [diff]
153
154
  while queue:
154
155
  items, queue = queue[0], queue[1:]
@@ -173,16 +174,18 @@ def rewrite_diff(old, new, diff_pre, _pops=(Op.AFFECTED,)):
173
174
  return diff
174
175
 
175
176
 
176
- def multiline_diff(old, new, diff_pre, _pops=(Op.AFFECTED,)):
177
+ def multiline_diff(old: odict, new: odict, diff_pre: odict, _pops: tuple[Op, ...] = (Op.AFFECTED,)) -> list[DiffItem]:
177
178
  """
178
179
  Особая логика diff'a для хуавейных мультилайнов.
179
180
  Она трактует все дочерние элементы %multiline-команды как
180
181
  одну общую команду, покидывая внутрь тот Op который был
181
182
  определен на вернем уровне
182
183
  """
184
+
183
185
  def process_multiline(op, tree):
184
- for (row, children) in tree.items():
185
- yield (op, row, list(process_multiline(op, children)), None)
186
+ for row, children in tree.items():
187
+ yield op, row, list(process_multiline(op, children)), None
188
+
186
189
  ret = []
187
190
  for item in default_diff(old, new, diff_pre, _pops):
188
191
  if old.get(item.row, {}) == new.get(item.row, {}):
@@ -192,23 +195,27 @@ def multiline_diff(old, new, diff_pre, _pops=(Op.AFFECTED,)):
192
195
  op, tree = Op.REMOVED, old
193
196
  children = list(process_multiline(op, tree[item.row]))
194
197
  ret.append(DiffItem(item.op, item.row, children, item.diff_pre))
198
+
195
199
  return ret
196
200
 
197
201
 
198
- def base_diff(old, new, diff_pre, pops, moved_to_affected=False) -> typing.List[DiffItem]:
202
+ def base_diff(
203
+ old: odict, new: odict, diff_pre: odict, pops: tuple[Op, ...], moved_to_affected: bool = False
204
+ ) -> list[DiffItem]:
199
205
  diff_indexed: typing.List[typing.Tuple[int, DiffItem]] = []
200
206
  old = _ignore_case(diff_pre, old)
201
207
  new = _ignore_case(diff_pre, new)
202
208
 
203
- for (index, row) in enumerate(old):
209
+ for index, row in enumerate(old):
204
210
  if row not in new:
205
- children = call_diff_logic(diff_pre[row]["subtree"], old[row], {}, pops + (Op.REMOVED,))
211
+ children = call_diff_logic(diff_pre[row]["subtree"], old[row], odict(), pops + (Op.REMOVED,))
206
212
  diff_indexed.append((index, DiffItem(
207
213
  op=Op.REMOVED,
208
214
  row=row,
209
215
  children=children,
210
216
  diff_pre=diff_pre[row]["match"],
211
217
  )))
218
+
212
219
  old_indexes = {row: index for (index, row) in enumerate(old)}
213
220
  block_in_disorder = False
214
221
  parent_op = pops[-1]
@@ -232,13 +239,13 @@ def base_diff(old, new, diff_pre, pops, moved_to_affected=False) -> typing.List[
232
239
  return [x[1] for x in diff_indexed]
233
240
 
234
241
 
235
- def call_diff_logic(diff_pre, old, new, pops=(Op.AFFECTED,)):
242
+ def call_diff_logic(diff_pre: odict, old: odict, new: odict, pops: tuple[Op, ...] = (Op.AFFECTED,)):
236
243
  """
237
244
  Группируем команды в старом и новом конфиге согласно выставленным
238
245
  в рулбуке атрибутам %diff_logic и вызывает их поочереди согласно
239
246
  порядку команд в old и new, предпочитая old (т.е. сначала удаления)
240
247
  """
241
- diff_logics = odict()
248
+ diff_logics: odict = odict()
242
249
  for row in old:
243
250
  logic = diff_pre[row]["match"]["attrs"]["diff_logic"]
244
251
  if logic not in diff_logics:
@@ -819,24 +819,6 @@ class RosFormatter(CommonFormatter):
819
819
  return commands
820
820
 
821
821
 
822
- def make_formatter(vendor, **kwargs):
823
- formatters = {
824
- "juniper": JuniperFormatter,
825
- "cisco": CiscoFormatter,
826
- "nexus": NexusFormatter,
827
- "huawei": HuaweiFormatter,
828
- "optixtrans": OptixtransFormatter,
829
- "arista": AristaFormatter,
830
- "nokia": NokiaFormatter,
831
- "routeros": RosFormatter,
832
- "aruba": ArubaFormatter,
833
- "pc": CommonFormatter,
834
- "ribbon": RibbonFormatter,
835
- "b4com": B4comFormatter,
836
- }
837
- return formatters[vendor](**kwargs)
838
-
839
-
840
822
  # ====
841
823
  def parse_to_tree(text, splitter, comments=("!", "#")):
842
824
  tree = odict()
@@ -25,7 +25,6 @@ import annet.deploy_ui
25
25
  import annet.lib
26
26
  from annet.annlib import jsontools
27
27
  from annet.annlib.netdev.views.hardware import HardwareView
28
- from annet.annlib.rbparser.platform import VENDOR_REVERSES
29
28
  from annet.annlib.types import GeneratorType
30
29
  from contextlog import get_logger
31
30
 
@@ -139,16 +138,19 @@ def _read_device_config(path, hw):
139
138
  _logger = get_logger()
140
139
  _logger.debug("Reading %r ...", path)
141
140
  score = 1
141
+ vendor_registry = registry_connector.get()
142
142
 
143
143
  with open(path) as cfgdump_file:
144
144
  text = cfgdump_file.read()
145
145
  try:
146
146
  if not hw:
147
147
  hw, score = guess_hw(text)
148
+
148
149
  config = tabparser.parse_to_tree(
149
150
  text=text,
150
- splitter=tabparser.make_formatter(hw).split,
151
+ splitter=vendor_registry.match(hw).make_formatter().split,
151
152
  )
153
+
152
154
  return config, hw, score
153
155
  except tabparser.ParserError:
154
156
  _logger.exception("Parser error: %r", path)
@@ -157,7 +159,7 @@ def _read_device_config(path, hw):
157
159
 
158
160
  # =====
159
161
  def _format_patch_blocks(patch_tree, hw, indent):
160
- formatter = tabparser.make_formatter(hw, indent=indent)
162
+ formatter = registry_connector.get().match(hw).make_formatter(indent=indent)
161
163
  return formatter.patch(patch_tree)
162
164
 
163
165
 
@@ -396,9 +398,12 @@ class CliDeployerJob(DeployerJob):
396
398
  (diff_obj, patch_tree) = _diff_and_patch(device, old, new, acl_rules,
397
399
  res.filter_acl_rules, self.add_comments,
398
400
  do_commit=not self.args.dont_commit)
399
- cmds = tabparser.make_formatter(device.hw, indent="").cmd_paths(patch_tree)
401
+
402
+ formatter = registry_connector.get().match(device.hw).make_formatter(indent="")
403
+ cmds = formatter.cmd_paths(patch_tree)
400
404
  if not cmds:
401
405
  return
406
+
402
407
  self._has_diff = True
403
408
  self.diffs[device] = diff_obj
404
409
  self.cmd_lines.extend(["= %s " % device.hostname, ""])
@@ -551,7 +556,7 @@ class Deployer:
551
556
  dest_name = "= %s" % ", ".join([dev.hostname for dev in devices])
552
557
  diff_lines.extend([dest_name, ""])
553
558
 
554
- for line in tabparser.make_formatter(devices[0].hw).diff(diff_obj):
559
+ for line in registry_connector.get().match(devices[0].hw).make_formatter().diff(diff_obj):
555
560
  diff_lines.append(line)
556
561
  diff_lines.append("")
557
562
  return diff_lines
@@ -787,14 +792,17 @@ def guess_hw(config_text: str):
787
792
  текста конфига и annet/rulebook/texts/*.rul"""
788
793
  scores = {}
789
794
  hw_provider = hardware_connector.get()
790
- for vendor in registry_connector.get():
795
+ vendor_registry = registry_connector.get()
796
+ for vendor in vendor_registry:
791
797
  hw = hw_provider.vendor_to_hw(vendor)
792
- fmtr = tabparser.make_formatter(hw)
793
798
  rb = rulebook.get_rulebook(hw)
799
+ fmtr = vendor_registry[vendor].make_formatter()
800
+
794
801
  try:
795
802
  config = tabparser.parse_to_tree(config_text, fmtr.split)
796
803
  except Exception:
797
804
  continue
805
+
798
806
  pre = patching.make_pre(patching.make_diff({}, config, rb, []))
799
807
  metric = _count_pre_score(pre)
800
808
  scores[metric] = hw
@@ -21,8 +21,8 @@ from annet.cli_args import ShowDiffOptions
21
21
  from annet.connectors import CachedConnector
22
22
  from annet.output import output_driver_connector
23
23
  from annet.storage import Device
24
- from annet.tabparser import make_formatter
25
24
  from annet.types import Diff, PCDiff, PCDiffFile
25
+ from annet.vendors import registry_connector
26
26
 
27
27
  from .gen import Loader, old_new
28
28
 
@@ -159,7 +159,7 @@ def _transform_text_diff_for_collapsing(text_diff) -> List[str]:
159
159
 
160
160
 
161
161
  def _make_text_diff(device: Device, diff: Diff) -> List[str]:
162
- formatter = make_formatter(device.hw)
162
+ formatter = registry_connector.get().match(device.hw).make_formatter()
163
163
  res = formatter.diff(diff)
164
164
  return res
165
165
 
@@ -226,7 +226,7 @@ class FrrFileDiffer(UnifiedFileDiffer):
226
226
  indent = " "
227
227
  rb = rulebook.rulebook_provider_connector.get()
228
228
  rulebook_data = rb.get_rulebook(hw)
229
- formatter = tabparser.make_formatter(hw, indent=indent)
229
+ formatter = registry_connector.get().match(hw).make_formatter(indent=indent)
230
230
 
231
231
  old_tree = tabparser.parse_to_tree(old_text or "", splitter=formatter.split)
232
232
  new_tree = tabparser.parse_to_tree(new_text or "", splitter=formatter.split)
@@ -29,7 +29,7 @@ from annet import generators, implicit, patching, tabparser, tracing
29
29
  from annet.annlib import jsontools
30
30
  from annet.annlib.rbparser.acl import compile_acl_text
31
31
  from annet.cli_args import DeployOptions, GenOptions, ShowGenOptions
32
- from annet.deploy import scrub_config, get_fetcher
32
+ from annet.deploy import get_fetcher, scrub_config
33
33
  from annet.filtering import Filterer
34
34
  from annet.generators import (
35
35
  BaseGenerator,
@@ -40,12 +40,12 @@ from annet.generators import (
40
40
  PartialGenerator,
41
41
  RefGenerator,
42
42
  )
43
- from annet.lib import merge_dicts, percentile, do_async
43
+ from annet.lib import do_async, merge_dicts, percentile
44
44
  from annet.output import output_driver_connector
45
- from annet.parallel import Parallel
46
- from annet.storage import Device, Storage, storage_connector
45
+ from annet.storage import Device, Storage
47
46
  from annet.tracing import tracing_connector
48
47
  from annet.types import OldNewResult
48
+ from annet.vendors import registry_connector
49
49
 
50
50
 
51
51
  # Вывод всех генераторов вместе.
@@ -162,7 +162,7 @@ def _old_new_per_device(ctx: OldNewDeviceContext, device: Device, filterer: Filt
162
162
  if ctx.config != "empty":
163
163
  old = tabparser.parse_to_tree(
164
164
  text=text,
165
- splitter=tabparser.make_formatter(device.hw).split,
165
+ splitter=registry_connector.get().match(device.hw).make_formatter().split,
166
166
  )
167
167
  if not old:
168
168
  res = generators.run_partial_initial(device)
@@ -638,7 +638,7 @@ def _existing_cfg_file_name(config_dir: str, device) -> Optional[str]:
638
638
 
639
639
 
640
640
  def format_config_blocks(config, hw, indent, _level=0):
641
- formatter = tabparser.make_formatter(hw, indent=indent)
641
+ formatter = registry_connector.get().match(hw).make_formatter(indent=indent)
642
642
  return formatter.join(config)
643
643
 
644
644
 
@@ -7,24 +7,15 @@ import os
7
7
  import re
8
8
  import textwrap
9
9
  from collections import OrderedDict as odict
10
- from typing import (
11
- FrozenSet,
12
- Iterable,
13
- List,
14
- Optional,
15
- Union,
16
- )
10
+ from typing import FrozenSet, Iterable, List, Optional, Union
17
11
 
18
- from annet.annlib.rbparser.acl import compile_acl_text
19
12
  from contextlog import get_logger
20
13
 
21
- from annet.storage import Device
22
-
23
14
  from annet import patching, tabparser, tracing
15
+ from annet.annlib.rbparser.acl import compile_acl_text
24
16
  from annet.cli_args import GenSelectOptions, ShowGeneratorsOptions
25
- from annet.lib import (
26
- get_context,
27
- )
17
+ from annet.lib import get_context
18
+ from annet.storage import Device
28
19
  from annet.tracing import tracing_connector
29
20
  from annet.types import (
30
21
  GeneratorEntireResult,
@@ -33,19 +24,20 @@ from annet.types import (
33
24
  GeneratorPartialRunArgs,
34
25
  GeneratorResult,
35
26
  )
36
- from .base import (
37
- BaseGenerator,
38
- TextGenerator as TextGenerator,
39
- ParamsList as ParamsList,
40
- )
41
- from .exceptions import NotSupportedDevice, GeneratorError
27
+ from annet.vendors import registry_connector
28
+
29
+ from .base import BaseGenerator
30
+ from .base import ParamsList as ParamsList
31
+ from .base import TextGenerator as TextGenerator
32
+ from .entire import Entire
33
+ from .exceptions import GeneratorError, NotSupportedDevice
42
34
  from .jsonfragment import JSONFragment
43
35
  from .partial import PartialGenerator
44
- from .entire import Entire
45
- from .ref import RefGenerator
46
36
  from .perf import GeneratorPerfMesurer
37
+ from .ref import RefGenerator
47
38
  from .result import RunGeneratorResult
48
39
 
40
+
49
41
  # =====
50
42
  DISABLED_TAG = "disable"
51
43
 
@@ -200,7 +192,8 @@ def _run_partial_generator(gen: "PartialGenerator", run_args: GeneratorPartialRu
200
192
  logger.error("Generator error in file '%s:%i'", filename, lineno)
201
193
  raise GeneratorError(f"{gen} on {device}") from err
202
194
 
203
- fmtr = tabparser.make_formatter(device.hw)
195
+ fmtr = registry_connector.get().match(device.hw).make_formatter()
196
+
204
197
  try:
205
198
  config = tabparser.parse_to_tree(text=output, splitter=fmtr.split)
206
199
  except tabparser.ParserError as err:
@@ -5,7 +5,7 @@ from typing import Iterable, Union
5
5
 
6
6
  from annet.annlib.lib import mako_render
7
7
  from annet.annlib.rbparser.ordering import compile_ordering_text
8
- from annet.annlib.rbparser.platform import VENDOR_REVERSES, VENDOR_ALIASES
8
+ from annet.annlib.rbparser.platform import VENDOR_ALIASES
9
9
 
10
10
  from annet.connectors import CachedConnector
11
11
  from annet.rulebook.deploying import compile_deploying_text
@@ -1,10 +1,10 @@
1
+ import functools
1
2
  import re
2
3
  from collections import OrderedDict as odict
3
- import functools
4
4
 
5
5
  from annet.annlib.lib import jun_activate, jun_is_inactive, merge_dicts
6
+ from annet.annlib.tabparser import JuniperFormatter
6
7
  from annet.annlib.types import Op
7
- from annet.tabparser import JuniperFormatter
8
8
  from annet.rulebook import common
9
9
 
10
10
 
@@ -1,7 +1,6 @@
1
1
  import functools
2
2
  import re
3
3
  from collections import OrderedDict as odict
4
-
5
4
  from annet.annlib.rbparser import platform, syntax
6
5
  from annet.vendors import registry_connector
7
6
  from valkit.common import valid_bool, valid_string_list
@@ -19,6 +18,7 @@ MULTILINE_DIFF_LOGIC = "common.multiline_diff"
19
18
  # =====
20
19
  @functools.lru_cache()
21
20
  def compile_patching_text(text, vendor):
21
+
22
22
  return _compile_patching(
23
23
  tree=syntax.parse_text(text, params_scheme={
24
24
  "global": {
@@ -31,7 +31,7 @@ def compile_patching_text(text, vendor):
31
31
  },
32
32
  "diff_logic": {
33
33
  "validator": valid_object_path,
34
- "default": platform.VENDOR_DIFF[vendor],
34
+ "default": registry_connector.get()[vendor].diff(False),
35
35
  },
36
36
  "comment": {
37
37
  "validator": valid_string_list,
@@ -86,7 +86,7 @@ def _compile_patching(tree, reverse_prefix, vendor):
86
86
  }
87
87
  else:
88
88
  if attrs["params"]["ordered"]:
89
- attrs["params"]["diff_logic"] = platform.VENDOR_DIFF_ORDERED[vendor]
89
+ attrs["params"]["diff_logic"] = registry_connector.get()[vendor].diff(True)
90
90
  attrs["params"]["logic"] = ORDERED_PATCH_LOGIC
91
91
  elif attrs["params"]["rewrite"]:
92
92
  attrs["params"]["diff_logic"] = REWRITE_DIFF_LOGIC
@@ -2,6 +2,7 @@ import abc
2
2
  from typing import ClassVar
3
3
 
4
4
  from annet.annlib.netdev.views.hardware import HardwareView
5
+ from annet.annlib.tabparser import CommonFormatter
5
6
 
6
7
 
7
8
  class AbstractVendor(abc.ABC):
@@ -16,6 +17,14 @@ class AbstractVendor(abc.ABC):
16
17
  def reverse(self) -> str:
17
18
  raise NotImplementedError
18
19
 
20
+ def diff(self, order: bool) -> str:
21
+ return "common.ordered_diff" if order else "common.default_diff"
22
+
23
+ @property
24
+ @abc.abstractmethod
25
+ def exit(self) -> str:
26
+ raise NotImplementedError
27
+
19
28
  @property
20
29
  @abc.abstractmethod
21
30
  def hardware(self) -> HardwareView:
@@ -23,3 +32,7 @@ class AbstractVendor(abc.ABC):
23
32
 
24
33
  def svi_name(self, num: int) -> str:
25
34
  return f"vlan{num}"
35
+
36
+ @abc.abstractmethod
37
+ def make_formatter(self, **kwargs) -> CommonFormatter:
38
+ raise NotImplementedError
@@ -0,0 +1,30 @@
1
+ from annet.annlib.netdev.views.hardware import HardwareView
2
+ from annet.annlib.tabparser import AristaFormatter
3
+ from annet.vendors.base import AbstractVendor
4
+ from annet.vendors.registry import registry
5
+
6
+
7
+ @registry.register
8
+ class AristaVendor(AbstractVendor):
9
+ NAME = "arista"
10
+
11
+ def match(self) -> list[str]:
12
+ return ["Arista"]
13
+
14
+ @property
15
+ def reverse(self) -> str:
16
+ return "no"
17
+
18
+ @property
19
+ def hardware(self) -> HardwareView:
20
+ return HardwareView("Arista")
21
+
22
+ def svi_name(self, num: int) -> str:
23
+ return f"Vlan{num}"
24
+
25
+ def make_formatter(self, **kwargs) -> AristaFormatter:
26
+ return AristaFormatter(**kwargs)
27
+
28
+ @property
29
+ def exit(self) -> str:
30
+ return "exit"
@@ -0,0 +1,30 @@
1
+ from annet.annlib.netdev.views.hardware import HardwareView
2
+ from annet.annlib.tabparser import ArubaFormatter
3
+ from annet.vendors.base import AbstractVendor
4
+ from annet.vendors.registry import registry
5
+
6
+
7
+ @registry.register
8
+ class ArubaVendor(AbstractVendor):
9
+ NAME = "aruba"
10
+
11
+ def match(self) -> list[str]:
12
+ return ["Aruba"]
13
+
14
+ @property
15
+ def reverse(self) -> str:
16
+ return "no"
17
+
18
+ @property
19
+ def hardware(self) -> HardwareView:
20
+ return HardwareView("Aruba")
21
+
22
+ def make_formatter(self, **kwargs) -> ArubaFormatter:
23
+ return ArubaFormatter(**kwargs)
24
+
25
+ @property
26
+ def exit(self) -> str:
27
+ return "exit"
28
+
29
+ def diff(self, order: bool) -> str:
30
+ return "common.ordered_diff" if order else "aruba.default_diff"
@@ -0,0 +1,27 @@
1
+ from annet.annlib.netdev.views.hardware import HardwareView
2
+ from annet.annlib.tabparser import B4comFormatter
3
+ from annet.vendors.base import AbstractVendor
4
+ from annet.vendors.registry import registry
5
+
6
+
7
+ @registry.register
8
+ class B4ComVendor(AbstractVendor):
9
+ NAME = "b4com"
10
+
11
+ def match(self) -> list[str]:
12
+ return ["B4com"]
13
+
14
+ @property
15
+ def reverse(self) -> str:
16
+ return "no"
17
+
18
+ @property
19
+ def hardware(self) -> HardwareView:
20
+ return HardwareView("B4com")
21
+
22
+ def make_formatter(self, **kwargs) -> B4comFormatter:
23
+ return B4comFormatter(**kwargs)
24
+
25
+ @property
26
+ def exit(self) -> str:
27
+ return "exit"
@@ -0,0 +1,30 @@
1
+ from annet.annlib.netdev.views.hardware import HardwareView
2
+ from annet.annlib.tabparser import CiscoFormatter
3
+ from annet.vendors.base import AbstractVendor
4
+ from annet.vendors.registry import registry
5
+
6
+
7
+ @registry.register
8
+ class CiscoVendor(AbstractVendor):
9
+ NAME = "cisco"
10
+
11
+ def match(self) -> list[str]:
12
+ return ["Cisco"]
13
+
14
+ @property
15
+ def reverse(self) -> str:
16
+ return "no"
17
+
18
+ @property
19
+ def hardware(self) -> HardwareView:
20
+ return HardwareView("Cisco")
21
+
22
+ def svi_name(self, num: int) -> str:
23
+ return f"Vlan{num}"
24
+
25
+ def make_formatter(self, **kwargs) -> CiscoFormatter:
26
+ return CiscoFormatter(**kwargs)
27
+
28
+ @property
29
+ def exit(self) -> str:
30
+ return "exit"
@@ -0,0 +1,27 @@
1
+ from annet.annlib.netdev.views.hardware import HardwareView
2
+ from annet.annlib.tabparser import HuaweiFormatter
3
+ from annet.vendors.base import AbstractVendor
4
+ from annet.vendors.registry import registry
5
+
6
+
7
+ @registry.register
8
+ class H3CVendor(AbstractVendor):
9
+ NAME = "h3c"
10
+
11
+ def match(self) -> list[str]:
12
+ return ["H3C"]
13
+
14
+ @property
15
+ def reverse(self) -> str:
16
+ return "undo"
17
+
18
+ @property
19
+ def hardware(self) -> HardwareView:
20
+ return HardwareView("H3C")
21
+
22
+ def make_formatter(self, **kwargs) -> HuaweiFormatter:
23
+ return HuaweiFormatter(**kwargs)
24
+
25
+ @property
26
+ def exit(self) -> str:
27
+ return "quit"
@@ -0,0 +1,30 @@
1
+ from annet.annlib.netdev.views.hardware import HardwareView
2
+ from annet.annlib.tabparser import HuaweiFormatter
3
+ from annet.vendors.base import AbstractVendor
4
+ from annet.vendors.registry import registry
5
+
6
+
7
+ @registry.register
8
+ class HuaweiVendor(AbstractVendor):
9
+ NAME = "huawei"
10
+
11
+ def match(self) -> list[str]:
12
+ return ["Huawei"]
13
+
14
+ @property
15
+ def reverse(self) -> str:
16
+ return "undo"
17
+
18
+ @property
19
+ def hardware(self) -> HardwareView:
20
+ return HardwareView("Huawei")
21
+
22
+ def svi_name(self, num: int) -> str:
23
+ return f"Vlanif{num}"
24
+
25
+ def make_formatter(self, **kwargs) -> HuaweiFormatter:
26
+ return HuaweiFormatter(**kwargs)
27
+
28
+ @property
29
+ def exit(self) -> str:
30
+ return "quit"