annet 0.13.3__tar.gz → 0.13.4__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.
Files changed (140) hide show
  1. {annet-0.13.3/annet.egg-info → annet-0.13.4}/PKG-INFO +1 -1
  2. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/common/models.py +32 -1
  3. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/v37/storage.py +77 -12
  4. {annet-0.13.3 → annet-0.13.4}/annet/annlib/netdev/views/hardware.py +4 -0
  5. {annet-0.13.3 → annet-0.13.4}/annet/gen.py +11 -9
  6. {annet-0.13.3 → annet-0.13.4/annet.egg-info}/PKG-INFO +1 -1
  7. {annet-0.13.3 → annet-0.13.4}/AUTHORS +0 -0
  8. {annet-0.13.3 → annet-0.13.4}/LICENSE +0 -0
  9. {annet-0.13.3 → annet-0.13.4}/MANIFEST.in +0 -0
  10. {annet-0.13.3 → annet-0.13.4}/README.md +0 -0
  11. {annet-0.13.3 → annet-0.13.4}/annet/__init__.py +0 -0
  12. {annet-0.13.3 → annet-0.13.4}/annet/adapters/__init__.py +0 -0
  13. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/__init__.py +0 -0
  14. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/common/__init__.py +0 -0
  15. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/common/client.py +0 -0
  16. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/common/manufacturer.py +0 -0
  17. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/common/query.py +0 -0
  18. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/common/status_client.py +0 -0
  19. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/common/storage_opts.py +0 -0
  20. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/provider.py +0 -0
  21. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/v24/__init__.py +0 -0
  22. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/v24/storage.py +0 -0
  23. {annet-0.13.3 → annet-0.13.4}/annet/adapters/netbox/v37/__init__.py +0 -0
  24. {annet-0.13.3 → annet-0.13.4}/annet/annet.py +0 -0
  25. {annet-0.13.3 → annet-0.13.4}/annet/annlib/__init__.py +0 -0
  26. {annet-0.13.3 → annet-0.13.4}/annet/annlib/command.py +0 -0
  27. {annet-0.13.3 → annet-0.13.4}/annet/annlib/diff.py +0 -0
  28. {annet-0.13.3 → annet-0.13.4}/annet/annlib/errors.py +0 -0
  29. {annet-0.13.3 → annet-0.13.4}/annet/annlib/filter_acl.py +0 -0
  30. {annet-0.13.3 → annet-0.13.4}/annet/annlib/jsontools.py +0 -0
  31. {annet-0.13.3 → annet-0.13.4}/annet/annlib/lib.py +0 -0
  32. {annet-0.13.3 → annet-0.13.4}/annet/annlib/netdev/__init__.py +0 -0
  33. {annet-0.13.3 → annet-0.13.4}/annet/annlib/netdev/db.py +0 -0
  34. {annet-0.13.3 → annet-0.13.4}/annet/annlib/netdev/devdb/__init__.py +0 -0
  35. {annet-0.13.3 → annet-0.13.4}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
  36. {annet-0.13.3 → annet-0.13.4}/annet/annlib/netdev/views/__init__.py +0 -0
  37. {annet-0.13.3 → annet-0.13.4}/annet/annlib/netdev/views/dump.py +0 -0
  38. {annet-0.13.3 → annet-0.13.4}/annet/annlib/output.py +0 -0
  39. {annet-0.13.3 → annet-0.13.4}/annet/annlib/patching.py +0 -0
  40. {annet-0.13.3 → annet-0.13.4}/annet/annlib/rbparser/__init__.py +0 -0
  41. {annet-0.13.3 → annet-0.13.4}/annet/annlib/rbparser/acl.py +0 -0
  42. {annet-0.13.3 → annet-0.13.4}/annet/annlib/rbparser/deploying.py +0 -0
  43. {annet-0.13.3 → annet-0.13.4}/annet/annlib/rbparser/ordering.py +0 -0
  44. {annet-0.13.3 → annet-0.13.4}/annet/annlib/rbparser/platform.py +0 -0
  45. {annet-0.13.3 → annet-0.13.4}/annet/annlib/rbparser/syntax.py +0 -0
  46. {annet-0.13.3 → annet-0.13.4}/annet/annlib/rulebook/__init__.py +0 -0
  47. {annet-0.13.3 → annet-0.13.4}/annet/annlib/rulebook/common.py +0 -0
  48. {annet-0.13.3 → annet-0.13.4}/annet/annlib/tabparser.py +0 -0
  49. {annet-0.13.3 → annet-0.13.4}/annet/annlib/types.py +0 -0
  50. {annet-0.13.3 → annet-0.13.4}/annet/api/__init__.py +0 -0
  51. {annet-0.13.3 → annet-0.13.4}/annet/argparse.py +0 -0
  52. {annet-0.13.3 → annet-0.13.4}/annet/cli.py +0 -0
  53. {annet-0.13.3 → annet-0.13.4}/annet/cli_args.py +0 -0
  54. {annet-0.13.3 → annet-0.13.4}/annet/configs/context.yml +0 -0
  55. {annet-0.13.3 → annet-0.13.4}/annet/configs/logging.yaml +0 -0
  56. {annet-0.13.3 → annet-0.13.4}/annet/connectors.py +0 -0
  57. {annet-0.13.3 → annet-0.13.4}/annet/deploy.py +0 -0
  58. {annet-0.13.3 → annet-0.13.4}/annet/diff.py +0 -0
  59. {annet-0.13.3 → annet-0.13.4}/annet/executor.py +0 -0
  60. {annet-0.13.3 → annet-0.13.4}/annet/filtering.py +0 -0
  61. {annet-0.13.3 → annet-0.13.4}/annet/generators/__init__.py +0 -0
  62. {annet-0.13.3 → annet-0.13.4}/annet/generators/base.py +0 -0
  63. {annet-0.13.3 → annet-0.13.4}/annet/generators/common/__init__.py +0 -0
  64. {annet-0.13.3 → annet-0.13.4}/annet/generators/common/initial.py +0 -0
  65. {annet-0.13.3 → annet-0.13.4}/annet/generators/entire.py +0 -0
  66. {annet-0.13.3 → annet-0.13.4}/annet/generators/exceptions.py +0 -0
  67. {annet-0.13.3 → annet-0.13.4}/annet/generators/jsonfragment.py +0 -0
  68. {annet-0.13.3 → annet-0.13.4}/annet/generators/partial.py +0 -0
  69. {annet-0.13.3 → annet-0.13.4}/annet/generators/perf.py +0 -0
  70. {annet-0.13.3 → annet-0.13.4}/annet/generators/ref.py +0 -0
  71. {annet-0.13.3 → annet-0.13.4}/annet/generators/result.py +0 -0
  72. {annet-0.13.3 → annet-0.13.4}/annet/hardware.py +0 -0
  73. {annet-0.13.3 → annet-0.13.4}/annet/implicit.py +0 -0
  74. {annet-0.13.3 → annet-0.13.4}/annet/lib.py +0 -0
  75. {annet-0.13.3 → annet-0.13.4}/annet/output.py +0 -0
  76. {annet-0.13.3 → annet-0.13.4}/annet/parallel.py +0 -0
  77. {annet-0.13.3 → annet-0.13.4}/annet/patching.py +0 -0
  78. {annet-0.13.3 → annet-0.13.4}/annet/reference.py +0 -0
  79. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/__init__.py +0 -0
  80. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/arista/__init__.py +0 -0
  81. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/arista/iface.py +0 -0
  82. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/aruba/__init__.py +0 -0
  83. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/aruba/ap_env.py +0 -0
  84. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/aruba/misc.py +0 -0
  85. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/cisco/__init__.py +0 -0
  86. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/cisco/iface.py +0 -0
  87. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/cisco/misc.py +0 -0
  88. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/cisco/vlandb.py +0 -0
  89. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/common.py +0 -0
  90. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/deploying.py +0 -0
  91. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/huawei/__init__.py +0 -0
  92. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/huawei/aaa.py +0 -0
  93. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/huawei/bgp.py +0 -0
  94. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/huawei/iface.py +0 -0
  95. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/huawei/misc.py +0 -0
  96. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/huawei/vlandb.py +0 -0
  97. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/juniper/__init__.py +0 -0
  98. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/nexus/__init__.py +0 -0
  99. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/nexus/iface.py +0 -0
  100. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/patching.py +0 -0
  101. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/ribbon/__init__.py +0 -0
  102. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/arista.deploy +0 -0
  103. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/arista.order +0 -0
  104. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/arista.rul +0 -0
  105. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/aruba.deploy +0 -0
  106. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/aruba.order +0 -0
  107. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/aruba.rul +0 -0
  108. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/cisco.deploy +0 -0
  109. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/cisco.order +0 -0
  110. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/cisco.rul +0 -0
  111. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/huawei.deploy +0 -0
  112. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/huawei.order +0 -0
  113. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/huawei.rul +0 -0
  114. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/juniper.rul +0 -0
  115. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/nexus.deploy +0 -0
  116. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/nexus.order +0 -0
  117. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/nexus.rul +0 -0
  118. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/nokia.rul +0 -0
  119. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/pc.order +0 -0
  120. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/pc.rul +0 -0
  121. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/ribbon.deploy +0 -0
  122. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/ribbon.rul +0 -0
  123. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/routeros.order +0 -0
  124. {annet-0.13.3 → annet-0.13.4}/annet/rulebook/texts/routeros.rul +0 -0
  125. {annet-0.13.3 → annet-0.13.4}/annet/storage.py +0 -0
  126. {annet-0.13.3 → annet-0.13.4}/annet/tabparser.py +0 -0
  127. {annet-0.13.3 → annet-0.13.4}/annet/text_term_format.py +0 -0
  128. {annet-0.13.3 → annet-0.13.4}/annet/tracing.py +0 -0
  129. {annet-0.13.3 → annet-0.13.4}/annet/types.py +0 -0
  130. {annet-0.13.3 → annet-0.13.4}/annet.egg-info/SOURCES.txt +0 -0
  131. {annet-0.13.3 → annet-0.13.4}/annet.egg-info/dependency_links.txt +0 -0
  132. {annet-0.13.3 → annet-0.13.4}/annet.egg-info/entry_points.txt +0 -0
  133. {annet-0.13.3 → annet-0.13.4}/annet.egg-info/requires.txt +0 -0
  134. {annet-0.13.3 → annet-0.13.4}/annet.egg-info/top_level.txt +0 -0
  135. {annet-0.13.3 → annet-0.13.4}/annet_generators/__init__.py +0 -0
  136. {annet-0.13.3 → annet-0.13.4}/annet_generators/example/__init__.py +0 -0
  137. {annet-0.13.3 → annet-0.13.4}/annet_generators/example/lldp.py +0 -0
  138. {annet-0.13.3 → annet-0.13.4}/requirements.txt +0 -0
  139. {annet-0.13.3 → annet-0.13.4}/setup.cfg +0 -0
  140. {annet-0.13.3 → annet-0.13.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: annet
3
- Version: 0.13.3
3
+ Version: 0.13.4
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -39,6 +39,22 @@ class DeviceIp:
39
39
  family: int
40
40
 
41
41
 
42
+ @dataclass
43
+ class Prefix:
44
+ id: int
45
+ prefix: str
46
+ site: Entity | None
47
+ vrf: Entity | None
48
+ tenant: Entity | None
49
+ vlan: Entity | None
50
+ role: Entity | None
51
+ status: Label
52
+ is_pool: bool
53
+ custom_fields: dict[str, Any]
54
+ created: datetime
55
+ last_updated: datetime
56
+
57
+
42
58
  @dataclass
43
59
  class IpAddress:
44
60
  id: int
@@ -50,12 +66,27 @@ class IpAddress:
50
66
  tags: List[Entity]
51
67
  created: datetime
52
68
  last_updated: datetime
69
+ prefix: Optional[Prefix] = None
70
+
71
+
72
+ @dataclass
73
+ class InterfaceConnectedEndpoint(Entity):
74
+ device: Entity
75
+
76
+
77
+ @dataclass
78
+ class InterfaceType:
79
+ value: str
80
+ label: str
53
81
 
54
82
 
55
83
  @dataclass
56
84
  class Interface(Entity):
57
85
  device: Entity
58
86
  enabled: bool
87
+ description: str
88
+ type: InterfaceType
89
+ connected_endpoints: Optional[list[InterfaceConnectedEndpoint]]
59
90
  display: str = ""
60
91
  ip_addresses: List[IpAddress] = field(default_factory=list)
61
92
 
@@ -64,7 +95,6 @@ class Interface(Entity):
64
95
  class NetboxDevice(Entity):
65
96
  url: str
66
97
  storage: Storage
67
- neighbours_ids: List[int]
68
98
 
69
99
  display: str
70
100
  device_type: DeviceType
@@ -92,6 +122,7 @@ class NetboxDevice(Entity):
92
122
  breed: str
93
123
 
94
124
  interfaces: List[Interface]
125
+ neighbours: Optional[List["NetboxDevice"]]
95
126
 
96
127
  # compat
97
128
 
@@ -1,5 +1,7 @@
1
1
  from logging import getLogger
2
- from typing import Optional, List, Union
2
+ from typing import Optional, List, Union, Dict
3
+ from ipaddress import ip_interface
4
+ from collections import defaultdict
3
5
 
4
6
  from adaptix import P
5
7
  from adaptix.conversion import impl_converter, link
@@ -28,18 +30,21 @@ def extend_device_base(
28
30
  interfaces: List[models.Interface],
29
31
  hw: Optional[HardwareView],
30
32
  breed: str,
33
+ neighbours: Optional[List[models.NetboxDevice]],
31
34
  storage: Storage,
32
- neighbours_ids: List[int],
33
35
  ) -> models.NetboxDevice:
34
36
  ...
35
37
 
36
38
 
37
39
  def extend_device(
38
- device: api_models.Device, storage: Storage,
40
+ device: api_models.Device,
41
+ interfaces: List[models.Interface],
42
+ neighbours: Optional[List[models.NetboxDevice]],
43
+ storage: Storage,
39
44
  ) -> models.NetboxDevice:
40
45
  return extend_device_base(
41
46
  device=device,
42
- interfaces=[],
47
+ interfaces=interfaces,
43
48
  breed=get_breed(
44
49
  device.device_type.manufacturer.name,
45
50
  device.device_type.model,
@@ -48,7 +53,7 @@ def extend_device(
48
53
  device.device_type.manufacturer.name,
49
54
  device.device_type.model,
50
55
  ),
51
- neighbours_ids=[],
56
+ neighbours=neighbours,
52
57
  storage=storage,
53
58
  )
54
59
 
@@ -61,6 +66,13 @@ def extend_interface(
61
66
  ...
62
67
 
63
68
 
69
+ @impl_converter
70
+ def extend_ip_address(
71
+ ip_address: models.IpAddress, prefix: Optional[models.Prefix],
72
+ ) -> models.IpAddress:
73
+ ...
74
+
75
+
64
76
  class NetboxStorageV37(Storage):
65
77
  def __init__(self, opts: Optional[NetboxStorageOpts] = None):
66
78
  self.netbox = NetboxV37(
@@ -95,15 +107,29 @@ class NetboxStorageV37(Storage):
95
107
  if isinstance(query, list):
96
108
  query = NetboxQuery.new(query)
97
109
  device_ids = {
98
- device.id: extend_device(device=device, storage=self)
110
+ device.id: extend_device(
111
+ device=device,
112
+ interfaces=[],
113
+ neighbours=[],
114
+ storage=self,
115
+ )
99
116
  for device in self._load_devices(query)
100
117
  }
101
118
  if not device_ids:
102
119
  return []
103
120
 
104
121
  interfaces = self._load_interfaces(list(device_ids))
122
+ neighbours = {x.id: x for x in self._load_neighbours(interfaces)}
123
+ neighbours_seen = defaultdict(set)
124
+
105
125
  for interface in interfaces:
106
126
  device_ids[interface.device.id].interfaces.append(interface)
127
+ for e in interface.connected_endpoints or []:
128
+ neighbour = neighbours[e.device.id]
129
+ if neighbour.id not in neighbours_seen[interface.device.id]:
130
+ neighbours_seen[interface.device.id].add(neighbour.id)
131
+ device_ids[interface.device.id].neighbours.append(neighbour)
132
+
107
133
  return list(device_ids.values())
108
134
 
109
135
  def _load_devices(self, query: NetboxQuery) -> List[api_models.Device]:
@@ -118,26 +144,65 @@ class NetboxStorageV37(Storage):
118
144
  if is_supported(device.device_type.manufacturer.name)
119
145
  ]
120
146
 
121
- def _load_interfaces(self, device_ids: List[int]) -> List[
122
- models.Interface]:
123
- interfaces = self.netbox.dcim_all_interfaces(device_id=device_ids)
147
+ def _extend_interfaces(self, interfaces: List[models.Interface]) -> List[models.Interface]:
124
148
  extended_ifaces = {
125
149
  interface.id: extend_interface(interface, [])
126
- for interface in interfaces.results
150
+ for interface in interfaces
127
151
  }
128
152
 
129
153
  ips = self.netbox.ipam_all_ip_addresses(interface_id=list(extended_ifaces))
154
+ ip_to_cidrs: Dict[str, str] = {ip.address: str(ip_interface(ip.address).network) for ip in ips.results}
155
+ prefixes = self.netbox.ipam_all_prefixes(prefix=list(ip_to_cidrs.values()))
156
+ cidr_to_prefix: Dict[str, models.Prefix] = {x.prefix: x for x in prefixes.results}
157
+
130
158
  for ip in ips.results:
159
+ cidr = ip_to_cidrs[ip.address]
160
+ ip = extend_ip_address(ip, prefix=cidr_to_prefix.get(cidr))
131
161
  extended_ifaces[ip.assigned_object_id].ip_addresses.append(ip)
132
162
  return list(extended_ifaces.values())
133
163
 
164
+ def _load_interfaces(self, device_ids: List[int]) -> List[
165
+ models.Interface]:
166
+ interfaces = self.netbox.dcim_all_interfaces(device_id=device_ids)
167
+ return self._extend_interfaces(interfaces.results)
168
+
169
+ def _load_interfaces_by_id(self, ids: List[int]) -> List[models.Interface]:
170
+ interfaces = self.netbox.dcim_all_interfaces_by_id(id=ids)
171
+ return self._extend_interfaces(interfaces.results)
172
+
173
+ def _load_neighbours(self, interfaces: List[models.Interface]) -> List[models.NetboxDevice]:
174
+ endpoints = [e for i in interfaces for e in i.connected_endpoints or []]
175
+ remote_interfaces_ids = [e.id for e in endpoints]
176
+ neighbours_ids = [e.device.id for e in endpoints]
177
+ neighbours_ifaces_dics = defaultdict(list)
178
+ # load only the connected interface to speed things up
179
+ for iface in self._load_interfaces_by_id(remote_interfaces_ids):
180
+ neighbours_ifaces_dics[iface.device.id].append(iface)
181
+ neighbours = []
182
+ for neighbour in self.netbox.dcim_all_devices_by_id(id=neighbours_ids).results:
183
+ extended_neighbour = extend_device(
184
+ device=neighbour,
185
+ storage=self,
186
+ interfaces=neighbours_ifaces_dics[neighbour.id],
187
+ neighbours=None, # do not load recursively
188
+ )
189
+ neighbours.append(extended_neighbour)
190
+ return neighbours
191
+
134
192
  def get_device(
135
193
  self, obj_id, preload_neighbors=False, use_mesh=None,
136
194
  **kwargs,
137
195
  ) -> models.NetboxDevice:
138
196
  device = self.netbox.dcim_device(obj_id)
139
- res = extend_device(device=device, storage=self)
140
- res.interfaces = self._load_interfaces([device.id])
197
+ interfaces = self._load_interfaces([device.id])
198
+ neighbours = self._load_neighbours(interfaces)
199
+
200
+ res = extend_device(
201
+ device=device,
202
+ storage=self,
203
+ interfaces=interfaces[device.id],
204
+ neighbours=neighbours,
205
+ )
141
206
  return res
142
207
 
143
208
  def flush_perf(self):
@@ -61,6 +61,10 @@ class HardwareView(HardwareLeaf):
61
61
  def vendor(self) -> Optional[str]:
62
62
  return hw_to_vendor(self)
63
63
 
64
+ @property
65
+ def soft(self) -> str:
66
+ return self._soft
67
+
64
68
  def __hash__(self):
65
69
  return hash(self.model)
66
70
 
@@ -513,9 +513,11 @@ def worker(device_id, args: ShowGenOptions, stdin, loader: "Loader", filterer: F
513
513
  dumped_data = json.dumps(data, indent=4, sort_keys=True, ensure_ascii=False)
514
514
  yield (output_driver.entire_config_dest_path(device, path), dumped_data, False)
515
515
 
516
- has_file_result = new_files or new_file_fragments
517
- has_partial_result = new or not has_file_result
518
- if device.hw.vendor in platform.VENDOR_REVERSES and has_partial_result:
516
+ # Consider result of partial run empty and create an empty dest file
517
+ # only if there are some acl rules that has been matched.
518
+ # Otherwise treat it as if no supported generators have been found.
519
+ acl_rules = res.get_acl_rules(args.acl_safe)
520
+ if device.hw.vendor in platform.VENDOR_REVERSES and acl_rules:
519
521
  orderer = patching.Orderer.from_hw(device.hw)
520
522
  yield (output_driver.cfg_file_names(device)[0],
521
523
  format_config_blocks(
@@ -606,14 +608,14 @@ def _print_perf(gen_type, perf):
606
608
  (
607
609
  (gen if not method else None),
608
610
  (method or "." * 30),
609
- sum(map(itemgetter("time"), stat)),
610
- (min(map(itemgetter("time"), stat)) if method else None),
611
- (percentile(stat, 0.95, itemgetter("time")) if method else None),
612
- (max(map(itemgetter("time"), stat)) if method else None),
613
- (len(stat) if method else None),
611
+ sum(map(itemgetter("time"), stat) if stat else None),
612
+ (min(map(itemgetter("time"), stat)) if stat else None),
613
+ (percentile(stat, 0.95, itemgetter("time")) if stat else None),
614
+ (max(map(itemgetter("time"), stat)) if stat else None),
615
+ (len(stat) if stat else None),
614
616
  (len(list(filter(
615
617
  lambda item: item in ["call", "disk_write"],
616
- map(itemgetter("op"), stat)))) if method else None),
618
+ map(itemgetter("op"), stat)))) if stat else None),
617
619
  )
618
620
 
619
621
  for (gen, gen_perf) in sorted(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: annet
3
- Version: 0.13.3
3
+ Version: 0.13.4
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes