annet 2.5.4__tar.gz → 2.6.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.
- {annet-2.5.4/annet.egg-info → annet-2.6.0}/PKG-INFO +1 -1
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/manufacturer.py +1 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/models.py +1 -1
- {annet-2.5.4 → annet-2.6.0}/annet/annet.py +8 -1
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/netdev/devdb/data/devdb.json +1 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/netdev/views/hardware.py +3 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/rbparser/platform.py +4 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/rulebook/common.py +1 -1
- {annet-2.5.4 → annet-2.6.0}/annet/generators/__init__.py +1 -1
- {annet-2.5.4 → annet-2.6.0}/annet/parallel.py +28 -9
- annet-2.6.0/annet/rulebook/texts/arista.rul +82 -0
- annet-2.6.0/annet/rulebook/texts/iosxr.deploy +27 -0
- annet-2.6.0/annet/rulebook/texts/iosxr.order +85 -0
- annet-2.6.0/annet/rulebook/texts/iosxr.rul +110 -0
- {annet-2.5.4 → annet-2.6.0}/annet/tabparser.py +1 -1
- {annet-2.5.4 → annet-2.6.0/annet.egg-info}/PKG-INFO +1 -1
- {annet-2.5.4 → annet-2.6.0}/annet.egg-info/SOURCES.txt +3 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/rpl_example/generator.py +3 -0
- annet-2.5.4/annet/rulebook/texts/arista.rul +0 -60
- {annet-2.5.4 → annet-2.6.0}/AUTHORS +0 -0
- {annet-2.5.4 → annet-2.6.0}/LICENSE +0 -0
- {annet-2.5.4 → annet-2.6.0}/MANIFEST.in +0 -0
- {annet-2.5.4 → annet-2.6.0}/README.md +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/fetchers/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/fetchers/stub/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/fetchers/stub/fetcher.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/file/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/file/provider.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/adapter.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/client.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/query.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/status_client.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/storage_base.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/common/storage_opts.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/provider.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v24/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v24/models.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v24/storage.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v37/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v37/models.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v37/storage.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v41/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v41/models.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v41/storage.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v42/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v42/models.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/adapters/netbox/v42/storage.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/command.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/diff.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/errors.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/filter_acl.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/jsontools.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/lib.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/netdev/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/netdev/db.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/netdev/devdb/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/netdev/views/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/netdev/views/dump.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/output.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/patching.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/rbparser/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/rbparser/acl.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/rbparser/deploying.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/rbparser/ordering.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/rbparser/syntax.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/rulebook/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/tabparser.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/annlib/types.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/api/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/argparse.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/bgp_models.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/cli.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/cli_args.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/configs/context.yml +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/configs/logging.yaml +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/connectors.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/deploy.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/deploy_ui.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/diff.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/executor.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/filtering.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/gen.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/base.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/common/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/common/initial.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/entire.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/exceptions.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/jsonfragment.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/partial.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/perf.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/ref.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/generators/result.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/hardware.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/implicit.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/lib.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/basemodel.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/device_models.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/executor.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/match_args.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/models_converter.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/peer_models.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/port_processor.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/mesh/registry.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/output.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/patching.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/reference.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl/action.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl/condition.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl/match_builder.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl/policy.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl/result.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl/routemap.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl/statement_builder.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/aspath.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/community.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/cumulus_frr.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/entities.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/execute.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/policy.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/prefix_lists.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rpl_generators/rd.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/arista/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/arista/aaa.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/arista/iface.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/aruba/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/aruba/ap_env.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/aruba/misc.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/b4com/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/b4com/file.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/b4com/iface.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/cisco/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/cisco/iface.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/cisco/misc.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/cisco/vlandb.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/common.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/deploying.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/huawei/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/huawei/aaa.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/huawei/bgp.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/huawei/iface.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/huawei/misc.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/huawei/vlandb.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/juniper/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/nexus/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/nexus/iface.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/patching.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/routeros/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/routeros/file.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/arista.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/arista.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/aruba.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/aruba.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/aruba.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/b4com.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/b4com.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/b4com.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/cisco.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/cisco.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/cisco.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/huawei.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/huawei.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/huawei.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/juniper.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/juniper.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/nexus.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/nexus.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/nexus.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/nokia.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/optixtrans.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/optixtrans.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/optixtrans.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/pc.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/pc.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/pc.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/ribbon.deploy +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/ribbon.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/routeros.order +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/rulebook/texts/routeros.rul +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/storage.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/text_term_format.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/tracing.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet/types.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet.egg-info/dependency_links.txt +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet.egg-info/entry_points.txt +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet.egg-info/requires.txt +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet.egg-info/top_level.txt +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/example/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/example/lldp.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/mesh_example/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/mesh_example/bgp.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/mesh_example/mesh_logic.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/rpl_example/__init__.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/rpl_example/items.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/rpl_example/mesh.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/annet_generators/rpl_example/route_policy.py +0 -0
- {annet-2.5.4 → annet-2.6.0}/requirements.txt +0 -0
- {annet-2.5.4 → annet-2.6.0}/setup.cfg +0 -0
- {annet-2.5.4 → annet-2.6.0}/setup.py +0 -0
|
@@ -140,7 +140,7 @@ class Interface(Entity, Generic[_IpAddressT]):
|
|
|
140
140
|
mode: Optional[InterfaceMode]
|
|
141
141
|
untagged_vlan: Optional[InterfaceVlan]
|
|
142
142
|
tagged_vlans: Optional[List[InterfaceVlan]]
|
|
143
|
-
tags: List[EntityWithSlug]
|
|
143
|
+
tags: List[EntityWithSlug] = field(default_factory=list)
|
|
144
144
|
display: str = ""
|
|
145
145
|
ip_addresses: List[_IpAddressT] = field(default_factory=list)
|
|
146
146
|
vrf: Optional[Entity] = None
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
import logging
|
|
2
3
|
import sys
|
|
3
4
|
|
|
4
5
|
import annet
|
|
@@ -18,8 +19,14 @@ def main():
|
|
|
18
19
|
parser.add_commands(parser.find_subcommands(cli.list_subcommands()))
|
|
19
20
|
try:
|
|
20
21
|
return parser.dispatch(pre_call=annet.init, add_help_command=True)
|
|
21
|
-
except (generators.GeneratorError, annet.ExecError):
|
|
22
|
+
except (generators.GeneratorError, annet.ExecError) as e:
|
|
23
|
+
logging.error(e)
|
|
22
24
|
return 1
|
|
25
|
+
except BaseException as e:
|
|
26
|
+
if formatted_output := getattr(e, "formatted_output", None):
|
|
27
|
+
logging.error(formatted_output)
|
|
28
|
+
return 1
|
|
29
|
+
raise e
|
|
23
30
|
|
|
24
31
|
|
|
25
32
|
if __name__ == "__main__":
|
|
@@ -75,6 +75,8 @@ class HardwareView(HardwareLeaf):
|
|
|
75
75
|
def hw_to_vendor(hw: HardwareView) -> Optional[str]:
|
|
76
76
|
if hw.Nexus:
|
|
77
77
|
return "nexus"
|
|
78
|
+
elif hw.Cisco.XR or hw.Cisco.ASR or hw.Cisco.XRV:
|
|
79
|
+
return "iosxr"
|
|
78
80
|
elif hw.Cisco:
|
|
79
81
|
return "cisco"
|
|
80
82
|
elif hw.OptiXtrans:
|
|
@@ -108,6 +110,7 @@ def vendor_to_hw(vendor):
|
|
|
108
110
|
"cisco": "Cisco",
|
|
109
111
|
"catalyst": "Cisco Catalyst",
|
|
110
112
|
"nexus": "Cisco Nexus",
|
|
113
|
+
"iosxr": "Cisco XR",
|
|
111
114
|
"huawei": "Huawei",
|
|
112
115
|
"optixtrans": "Huawei OptiXtrans",
|
|
113
116
|
"juniper": "Juniper",
|
|
@@ -3,6 +3,7 @@ VENDOR_REVERSES = {
|
|
|
3
3
|
"h3c": "undo",
|
|
4
4
|
"optixtrans": "undo",
|
|
5
5
|
"cisco": "no",
|
|
6
|
+
"iosxr": "no",
|
|
6
7
|
"nexus": "no",
|
|
7
8
|
"juniper": "delete",
|
|
8
9
|
"arista": "no",
|
|
@@ -18,6 +19,7 @@ VENDOR_DIFF = {
|
|
|
18
19
|
"huawei": "common.default_diff",
|
|
19
20
|
"optixtrans": "common.default_diff",
|
|
20
21
|
"cisco": "common.default_diff",
|
|
22
|
+
"iosxr": "common.default_diff",
|
|
21
23
|
"nexus": "common.default_diff",
|
|
22
24
|
"juniper": "juniper.default_diff",
|
|
23
25
|
"arista": "common.default_diff",
|
|
@@ -33,6 +35,7 @@ VENDOR_DIFF_ORDERED = {
|
|
|
33
35
|
"huawei": "common.ordered_diff",
|
|
34
36
|
"optixtrans": "common.ordered_diff",
|
|
35
37
|
"cisco": "common.ordered_diff",
|
|
38
|
+
"iosxr": "common.ordered_diff",
|
|
36
39
|
"nexus": "common.ordered_diff",
|
|
37
40
|
"juniper": "juniper.ordered_diff",
|
|
38
41
|
"arista": "common.ordered_diff",
|
|
@@ -49,6 +52,7 @@ VENDOR_EXIT = {
|
|
|
49
52
|
"h3c": "quit",
|
|
50
53
|
"optixtrans": "quit",
|
|
51
54
|
"cisco": "exit",
|
|
55
|
+
"iosxr": "exit",
|
|
52
56
|
"nexus": "exit",
|
|
53
57
|
"arista": "exit",
|
|
54
58
|
"juniper": "",
|
|
@@ -297,7 +297,7 @@ def apply(hw, do_commit, do_finalize, **_):
|
|
|
297
297
|
after.add_cmd(Command("abort")) # просто exit оставит висеть configure session
|
|
298
298
|
if do_finalize:
|
|
299
299
|
after.add_cmd(Command("write memory"))
|
|
300
|
-
elif hw.ASR or hw.XRV:
|
|
300
|
+
elif hw.ASR or hw.XRV or hw.XR:
|
|
301
301
|
# коммит сам сохраняет изменения в стартап do_finalize не применим
|
|
302
302
|
before.add_cmd(Command("configure exclusive"))
|
|
303
303
|
if do_commit:
|
|
@@ -197,7 +197,7 @@ def _run_partial_generator(gen: "PartialGenerator", run_args: GeneratorPartialRu
|
|
|
197
197
|
raise
|
|
198
198
|
except Exception as err:
|
|
199
199
|
filename, lineno = gen.get_running_line()
|
|
200
|
-
logger.
|
|
200
|
+
logger.error("Generator error in file '%s:%i'", filename, lineno)
|
|
201
201
|
raise GeneratorError(f"{gen} on {device}") from err
|
|
202
202
|
|
|
203
203
|
fmtr = tabparser.make_formatter(device.hw)
|
|
@@ -15,13 +15,14 @@ import tempfile
|
|
|
15
15
|
import time
|
|
16
16
|
import traceback
|
|
17
17
|
import warnings
|
|
18
|
-
from typing import Any, List, Optional, Type
|
|
18
|
+
from typing import Any, List, Optional, Type, Callable
|
|
19
19
|
from uuid import uuid4
|
|
20
20
|
|
|
21
21
|
from contextlog import get_logger
|
|
22
22
|
|
|
23
23
|
import annet
|
|
24
24
|
from annet import tracing
|
|
25
|
+
from annet.connectors import Connector
|
|
25
26
|
from annet.lib import catch_ctrl_c, find_exc_in_stack
|
|
26
27
|
from annet.output import capture_output
|
|
27
28
|
from annet.tracing import tracing_connector
|
|
@@ -38,6 +39,20 @@ class PoolWorkerTask:
|
|
|
38
39
|
payload: Optional[Any] = None
|
|
39
40
|
|
|
40
41
|
|
|
42
|
+
class _PickleSafeTracebackFormatterConnector(Connector[Callable[[BaseException], str]]):
|
|
43
|
+
name = "PickleSafeTraceBackFormatter"
|
|
44
|
+
ep_name = "pickle_safe_traceback_formatter"
|
|
45
|
+
|
|
46
|
+
def _get_default(self) -> Callable[[], Callable[[BaseException], str]]:
|
|
47
|
+
def wrapper():
|
|
48
|
+
return lambda x: "".join(traceback.format_exception(x))
|
|
49
|
+
|
|
50
|
+
return wrapper
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
pickle_safe_traceback_formatter_connector = _PickleSafeTracebackFormatterConnector()
|
|
54
|
+
|
|
55
|
+
|
|
41
56
|
class PickleSafeException(Exception):
|
|
42
57
|
"""An exception that can be safely pickled and passed between processes."""
|
|
43
58
|
|
|
@@ -59,9 +74,14 @@ class PickleSafeException(Exception):
|
|
|
59
74
|
pretty_lines.append(self.formatted_output)
|
|
60
75
|
return "\n".join(pretty_lines)
|
|
61
76
|
|
|
62
|
-
@
|
|
63
|
-
def from_exc(orig_exc: Exception, device_id: str
|
|
64
|
-
return PickleSafeException(
|
|
77
|
+
@classmethod
|
|
78
|
+
def from_exc(cls, orig_exc: Exception, device_id: str) -> "PickleSafeException":
|
|
79
|
+
return PickleSafeException(
|
|
80
|
+
orig_exc.__class__,
|
|
81
|
+
str(orig_exc),
|
|
82
|
+
device_id,
|
|
83
|
+
pickle_safe_traceback_formatter_connector.get()(orig_exc)
|
|
84
|
+
)
|
|
65
85
|
|
|
66
86
|
|
|
67
87
|
@catch_ctrl_c
|
|
@@ -164,7 +184,7 @@ def _pool_worker(pool, index, task_queue, done_queue):
|
|
|
164
184
|
except KeyboardInterrupt: # pylint: disable=try-except-raise
|
|
165
185
|
raise
|
|
166
186
|
except Exception as exc:
|
|
167
|
-
safe_exc = PickleSafeException.from_exc(exc, task.payload
|
|
187
|
+
safe_exc = PickleSafeException.from_exc(exc, task.payload)
|
|
168
188
|
ret_exc = safe_exc
|
|
169
189
|
task_result.exc = safe_exc
|
|
170
190
|
task_result.result = None
|
|
@@ -301,11 +321,10 @@ class Parallel:
|
|
|
301
321
|
**self.kwargs
|
|
302
322
|
)
|
|
303
323
|
except Exception as exc:
|
|
324
|
+
safe_exc = PickleSafeException.from_exc(exc, device_id)
|
|
304
325
|
if not tolerate_fails:
|
|
305
|
-
raise
|
|
306
|
-
exc
|
|
307
|
-
exc.formatted_output = traceback.format_exc()
|
|
308
|
-
task_result.exc = exc
|
|
326
|
+
raise safe_exc
|
|
327
|
+
task_result.exc = safe_exc
|
|
309
328
|
if self.capture_output:
|
|
310
329
|
task_result.extra["cap_stdout"] = cap_stdout.read()
|
|
311
330
|
task_result.extra["cap_stderr"] = cap_stderr.read()
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
description %global
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
qos profile *
|
|
5
|
+
~ %global
|
|
6
|
+
|
|
7
|
+
username * ssh-key
|
|
8
|
+
username * %logic=arista.aaa.user
|
|
9
|
+
|
|
10
|
+
aaa group ~
|
|
11
|
+
~ %global
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
role *
|
|
15
|
+
~ %global
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
vrf instance *
|
|
19
|
+
~ %global
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
interface * %logic=arista.iface.permanent
|
|
23
|
+
no switchport
|
|
24
|
+
description *
|
|
25
|
+
channel-group *
|
|
26
|
+
lacp rate *
|
|
27
|
+
service-profile *
|
|
28
|
+
~ %global
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
ip access-list standard *
|
|
32
|
+
* %logic=common.undo_redo
|
|
33
|
+
|
|
34
|
+
ipv6 access-list standard *
|
|
35
|
+
* %logic=common.undo_redo
|
|
36
|
+
|
|
37
|
+
ipv6 access-list *
|
|
38
|
+
* %logic=common.undo_redo
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# ios-like way of configuring prefix lists
|
|
42
|
+
# should be kept above a eos-native one in arista.rul
|
|
43
|
+
# since beginnig of commands are the same
|
|
44
|
+
# if you use it keep all prefix lists in this format
|
|
45
|
+
|
|
46
|
+
ip prefix-list * seq * %logic=common.undo_redo
|
|
47
|
+
ipv6 prefix-list * seq * %logic=common.undo_redo
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# arista eos native way of configuring prefix lists
|
|
51
|
+
# should be below to not collide with ios-like one
|
|
52
|
+
# only one format is supported at the time for one family
|
|
53
|
+
# prefer this one over the ios-like one
|
|
54
|
+
|
|
55
|
+
ip prefix-list *
|
|
56
|
+
seq * %logic=common.undo_redo
|
|
57
|
+
|
|
58
|
+
ipv6 prefix-list *
|
|
59
|
+
seq * %logic=common.undo_redo
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
route-map * * *
|
|
63
|
+
~ %global
|
|
64
|
+
|
|
65
|
+
router bfd
|
|
66
|
+
~ %global
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
router bgp *
|
|
70
|
+
no bgp default *
|
|
71
|
+
neighbor * maximum-routes
|
|
72
|
+
! no neighbor * shutdown
|
|
73
|
+
~ %global
|
|
74
|
+
|
|
75
|
+
ip load-sharing trident fields * %logic=common.default_instead_undo
|
|
76
|
+
|
|
77
|
+
management *
|
|
78
|
+
~ %global
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
no ~ %global
|
|
82
|
+
~ %global
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Рулбук деплоя на устройства
|
|
2
|
+
#
|
|
3
|
+
# Операторы:
|
|
4
|
+
# * Один аргумент
|
|
5
|
+
# ~ Несколько аргументов (минимум один)
|
|
6
|
+
#
|
|
7
|
+
# Параметры:
|
|
8
|
+
# %timeout=... Таймаут выполнения команды (в секундах, по умолчанию 30)
|
|
9
|
+
#
|
|
10
|
+
# Ответы на вопросы
|
|
11
|
+
#
|
|
12
|
+
# <команда>
|
|
13
|
+
# dialog: <вопрос> ::: <ответ> <параметры>
|
|
14
|
+
#
|
|
15
|
+
# Если <вопрос> заключён в слеши (//), то воспринимается как регулярка, иначе - точное совпадение.
|
|
16
|
+
# Параметы:
|
|
17
|
+
# %send_nl=... Посылать ли перевод строки после ответа (bool, по умолчанию true)
|
|
18
|
+
# -----
|
|
19
|
+
|
|
20
|
+
crypto key generate rsa %timeout=60
|
|
21
|
+
dialog: Do you really want to replace them? [yes/no]: ::: no
|
|
22
|
+
dialog: How many bits in the modulus [512]: ::: 2048
|
|
23
|
+
no username * privilege * secret * *
|
|
24
|
+
dialog: This operation will remove all username related configurations with same name.Do you want to continue? [confirm] ::: Y %send_nl=0
|
|
25
|
+
|
|
26
|
+
copy running-config startup-config
|
|
27
|
+
dialog: Destination filename [startup-config]? ::: startup-config
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# В этом файле определяется порядок команд, в котором их следует подавать на устройство.
|
|
2
|
+
# - Если порядок команды не важен - ее можно не писать сюда совсем.
|
|
3
|
+
# - Если команда начинается с undo и прописан параметр %order_reverse - команда считается
|
|
4
|
+
# обратной, но занимает место между прямыми там, где указано.
|
|
5
|
+
|
|
6
|
+
banner login %order_reverse
|
|
7
|
+
|
|
8
|
+
# Фичи должны быть включены прежде всего
|
|
9
|
+
feature
|
|
10
|
+
# За ним сервисы
|
|
11
|
+
service
|
|
12
|
+
|
|
13
|
+
aaa new-model
|
|
14
|
+
aaa ~
|
|
15
|
+
|
|
16
|
+
no password strength-check
|
|
17
|
+
username
|
|
18
|
+
tacacs-server
|
|
19
|
+
|
|
20
|
+
radius
|
|
21
|
+
radius-server
|
|
22
|
+
dot1x
|
|
23
|
+
|
|
24
|
+
privilege
|
|
25
|
+
file
|
|
26
|
+
|
|
27
|
+
ip access-list
|
|
28
|
+
ipv6 access-list
|
|
29
|
+
class-map
|
|
30
|
+
policy-map
|
|
31
|
+
system qos
|
|
32
|
+
control-plane
|
|
33
|
+
|
|
34
|
+
snmp-server source-interface
|
|
35
|
+
snmp-server user
|
|
36
|
+
snmp-server host
|
|
37
|
+
snmp-server enable
|
|
38
|
+
snmp-server context
|
|
39
|
+
snmp-server community
|
|
40
|
+
snmp-server mib
|
|
41
|
+
|
|
42
|
+
ntp distribute
|
|
43
|
+
ntp server
|
|
44
|
+
ntp commit
|
|
45
|
+
|
|
46
|
+
vlan
|
|
47
|
+
vlan group
|
|
48
|
+
|
|
49
|
+
spanning-tree
|
|
50
|
+
|
|
51
|
+
# перед тем, как менять mtu на интерфейсах, надо выставить максимальный
|
|
52
|
+
no system jumbomtu %order_reverse
|
|
53
|
+
system jumbomtu
|
|
54
|
+
|
|
55
|
+
service dhcp
|
|
56
|
+
ip dhcp relay
|
|
57
|
+
ipv6 dhcp relay
|
|
58
|
+
|
|
59
|
+
vrf context
|
|
60
|
+
|
|
61
|
+
interface */Vlan\d+/
|
|
62
|
+
interface *
|
|
63
|
+
no switchport
|
|
64
|
+
encapsulation
|
|
65
|
+
vrf member
|
|
66
|
+
ip
|
|
67
|
+
ipv6
|
|
68
|
+
no ipv6 nd %order_reverse
|
|
69
|
+
ipv6 nd
|
|
70
|
+
~
|
|
71
|
+
channel-group
|
|
72
|
+
|
|
73
|
+
interface */\S+\.\d+/
|
|
74
|
+
|
|
75
|
+
route-map
|
|
76
|
+
|
|
77
|
+
# удалять eth-trunk можно только после того, как вычистим member interfaces
|
|
78
|
+
undo interface */port-channel\d+/ %order_reverse
|
|
79
|
+
|
|
80
|
+
# remote as of neighbors should be assigned before peer-group, the rule is applied to neighbors, not peer-groups
|
|
81
|
+
router bgp
|
|
82
|
+
neighbor */[\da-f\.\:]+/ remote-as
|
|
83
|
+
neighbor */[\da-f\.\:]+/ peer-group
|
|
84
|
+
|
|
85
|
+
line
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Операторы:
|
|
2
|
+
# * Один аргумент в undo
|
|
3
|
+
# ~ Несколько аргументов (минимум один) в undo
|
|
4
|
+
#
|
|
5
|
+
# Параметры:
|
|
6
|
+
# %global Команда действует на любом уровне ниже
|
|
7
|
+
# %logic=... Кастомная функция обработки правила
|
|
8
|
+
# %diff_logic=... Кастомная функция построения диффа.
|
|
9
|
+
# данная функция работает для подблоков (в отличие от %logic)
|
|
10
|
+
# %comment=... Добавить коммент после строки который будет видно с опцией patch --add-comments
|
|
11
|
+
# Сделано в основном для того чтобы генерировать специальные команды для наливки
|
|
12
|
+
# -----
|
|
13
|
+
|
|
14
|
+
ip domain-name *
|
|
15
|
+
hostname *
|
|
16
|
+
|
|
17
|
+
banner login * %logic=cisco.misc.banner_login
|
|
18
|
+
|
|
19
|
+
ip community-list standard ~
|
|
20
|
+
|
|
21
|
+
!vrf context management
|
|
22
|
+
vrf context *
|
|
23
|
+
|
|
24
|
+
vlan group * vlan-list %logic=cisco.vlandb.simple
|
|
25
|
+
vlan */[^\d].*/
|
|
26
|
+
vlan %logic=cisco.vlandb.simple
|
|
27
|
+
name
|
|
28
|
+
|
|
29
|
+
ip ssh version 2 %logic=cisco.misc.ssh_key
|
|
30
|
+
|
|
31
|
+
# ordering of SNMP blocks
|
|
32
|
+
ip access-list ~
|
|
33
|
+
snmp-server view ~
|
|
34
|
+
snmp-server community ~
|
|
35
|
+
snmp-server host ~
|
|
36
|
+
# Deleting a user using either SNMP or the CLI results in the user being deleted for both SNMP and the CLI.
|
|
37
|
+
# User-role mapping changes are synchronized in SNMP and the CLI.
|
|
38
|
+
!snmp-server user admin ~
|
|
39
|
+
!snmp-server user *
|
|
40
|
+
# Disabling this SNMP option throws WARNING which stops mpdaemon set-up process
|
|
41
|
+
no snmp-server sysobjectid type stack-oid
|
|
42
|
+
|
|
43
|
+
!interface */(mgmt|ipmi|Vlan1$)/
|
|
44
|
+
|
|
45
|
+
interface Loopback
|
|
46
|
+
ipv6 address *
|
|
47
|
+
ip address ~
|
|
48
|
+
! no ip address
|
|
49
|
+
|
|
50
|
+
# SVI/Subifs/Lagg
|
|
51
|
+
interface */(Vlan|Ethernet.*\.|port-channel.*\.?)\d+$/ %diff_logic=cisco.iface.diff
|
|
52
|
+
vrf member
|
|
53
|
+
ipv6 link-local
|
|
54
|
+
ipv6 address *
|
|
55
|
+
ipv6 nd ~ %logic=cisco.misc.no_ipv6_nd_suppress_ra
|
|
56
|
+
ip address ~
|
|
57
|
+
! no ip address
|
|
58
|
+
mtu
|
|
59
|
+
|
|
60
|
+
# Physical
|
|
61
|
+
interface */\w*Ethernet[0-9\/]+$/ %logic=common.permanent %diff_logic=cisco.iface.diff
|
|
62
|
+
switchport mode
|
|
63
|
+
switchport trunk native vlan
|
|
64
|
+
switchport access vlan
|
|
65
|
+
switchport trunk allowed vlan %logic=cisco.vlandb.swtrunk
|
|
66
|
+
vrf member
|
|
67
|
+
ipv6 link-local
|
|
68
|
+
ipv6 address *
|
|
69
|
+
ip address ~
|
|
70
|
+
! no ip address
|
|
71
|
+
channel-group
|
|
72
|
+
mtu
|
|
73
|
+
storm-control * level
|
|
74
|
+
spanning-tree portfast
|
|
75
|
+
|
|
76
|
+
router bgp
|
|
77
|
+
router-id
|
|
78
|
+
vrf *
|
|
79
|
+
router-id
|
|
80
|
+
address-family ~
|
|
81
|
+
maximum-paths
|
|
82
|
+
neighbor ~
|
|
83
|
+
update-source
|
|
84
|
+
|
|
85
|
+
policy-map type qos *
|
|
86
|
+
class * %ordered
|
|
87
|
+
~
|
|
88
|
+
|
|
89
|
+
prefix-set *
|
|
90
|
+
~ %rewrite %global
|
|
91
|
+
|
|
92
|
+
as-path-set *
|
|
93
|
+
~ %rewrite %global
|
|
94
|
+
|
|
95
|
+
community-set *
|
|
96
|
+
~ %rewrite %global
|
|
97
|
+
|
|
98
|
+
route-policy *
|
|
99
|
+
~ %rewrite %global
|
|
100
|
+
|
|
101
|
+
line ~
|
|
102
|
+
exec-timeout
|
|
103
|
+
transport input
|
|
104
|
+
|
|
105
|
+
description %global
|
|
106
|
+
|
|
107
|
+
no ~ %global
|
|
108
|
+
~ %global
|
|
109
|
+
|
|
110
|
+
# vim: set syntax=annrulebook:
|
|
@@ -23,7 +23,7 @@ def make_formatter(hw, **kwargs):
|
|
|
23
23
|
cls = OptixtransFormatter
|
|
24
24
|
elif hw.Huawei:
|
|
25
25
|
cls = HuaweiFormatter
|
|
26
|
-
elif hw.Cisco.ASR or hw.Cisco.XRV:
|
|
26
|
+
elif hw.Cisco.ASR or hw.Cisco.XRV or hw.Cisco.XR:
|
|
27
27
|
cls = AsrFormatter
|
|
28
28
|
elif hw.Nexus:
|
|
29
29
|
cls = NexusFormatter
|
|
@@ -173,6 +173,9 @@ annet/rulebook/texts/cisco.rul
|
|
|
173
173
|
annet/rulebook/texts/huawei.deploy
|
|
174
174
|
annet/rulebook/texts/huawei.order
|
|
175
175
|
annet/rulebook/texts/huawei.rul
|
|
176
|
+
annet/rulebook/texts/iosxr.deploy
|
|
177
|
+
annet/rulebook/texts/iosxr.order
|
|
178
|
+
annet/rulebook/texts/iosxr.rul
|
|
176
179
|
annet/rulebook/texts/juniper.order
|
|
177
180
|
annet/rulebook/texts/juniper.rul
|
|
178
181
|
annet/rulebook/texts/nexus.deploy
|
|
@@ -30,6 +30,9 @@ class CommunityGenerator(CommunityListGenerator):
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class PolicyGenerator(RoutingPolicyGenerator):
|
|
33
|
+
def get_prefix_lists(self, device: Any) -> list[IpPrefixList]:
|
|
34
|
+
return PREFIX_LISTS
|
|
35
|
+
|
|
33
36
|
def get_policies(self, device: Any) -> list[RoutingPolicy]:
|
|
34
37
|
return get_policies(
|
|
35
38
|
routemap=routemap,
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
description %global
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
qos profile *
|
|
5
|
-
~ %global
|
|
6
|
-
|
|
7
|
-
username * ssh-key
|
|
8
|
-
username * %logic=arista.aaa.user
|
|
9
|
-
|
|
10
|
-
aaa group ~
|
|
11
|
-
~ %global
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
role *
|
|
15
|
-
~ %global
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
vrf instance *
|
|
19
|
-
~ %global
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
interface * %logic=arista.iface.permanent
|
|
23
|
-
no switchport
|
|
24
|
-
description *
|
|
25
|
-
channel-group *
|
|
26
|
-
lacp rate *
|
|
27
|
-
service-profile *
|
|
28
|
-
~ %global
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
ip access-list standard *
|
|
32
|
-
* %logic=huawei.misc.undo_redo
|
|
33
|
-
|
|
34
|
-
ipv6 access-list standard *
|
|
35
|
-
* %logic=huawei.misc.undo_redo
|
|
36
|
-
|
|
37
|
-
ipv6 access-list *
|
|
38
|
-
* %logic=huawei.misc.undo_redo
|
|
39
|
-
|
|
40
|
-
route-map * * *
|
|
41
|
-
~ %global
|
|
42
|
-
|
|
43
|
-
router bfd
|
|
44
|
-
~ %global
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
router bgp *
|
|
48
|
-
no bgp default *
|
|
49
|
-
neighbor * maximum-routes
|
|
50
|
-
! no neighbor * shutdown
|
|
51
|
-
~ %global
|
|
52
|
-
|
|
53
|
-
ip load-sharing trident fields * %logic=common.default_instead_undo
|
|
54
|
-
|
|
55
|
-
management *
|
|
56
|
-
~ %global
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
no ~ %global
|
|
60
|
-
~ %global
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|