annet 3.14.1__py3-none-any.whl → 3.14.3__py3-none-any.whl

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/api/__init__.py CHANGED
@@ -683,7 +683,7 @@ async def adeploy(
683
683
  ) -> ExitCode:
684
684
  """ Сгенерировать конфиг для устройств и задеплоить его """
685
685
  ret: ExitCode = 0
686
- ann_gen.live_configs = await fetcher.fetch(devices=loader.devices, processes=args.parallel)
686
+ ann_gen.live_configs = await fetcher.fetch(devices=loader.devices, processes=args.parallel, max_slots=args.max_slots)
687
687
 
688
688
  device_ids = [d.id for d in loader.devices]
689
689
  for res in ann_gen.old_new(
annet/bgp_models.py CHANGED
@@ -201,6 +201,24 @@ class PeerOptions:
201
201
  not_active: Optional[bool] = None
202
202
  mtu: Optional[int] = None
203
203
  password: Optional[str] = None
204
+ cluster_id: Optional[str] = None
205
+
206
+
207
+ @dataclass
208
+ class PeerFamilyOption:
209
+ af_loops: Optional[int] = None
210
+ import_limit: Optional[int] = None
211
+
212
+
213
+ @dataclass
214
+ class PeerFamilyOptions:
215
+ ipv4_unicast: PeerFamilyOption = field(default_factory=PeerFamilyOption)
216
+ ipv6_unicast: PeerFamilyOption = field(default_factory=PeerFamilyOption)
217
+ ipv4_vpn_unicast: PeerFamilyOption = field(default_factory=PeerFamilyOption)
218
+ ipv6_vpn_unicast: PeerFamilyOption = field(default_factory=PeerFamilyOption)
219
+ ipv4_labeled_unicast: PeerFamilyOption = field(default_factory=PeerFamilyOption)
220
+ ipv6_labeled_unicast: PeerFamilyOption = field(default_factory=PeerFamilyOption)
221
+ l2vpn_evpn: PeerFamilyOption = field(default_factory=PeerFamilyOption)
204
222
 
205
223
 
206
224
  @dataclass
@@ -209,6 +227,7 @@ class Peer:
209
227
  interface: Optional[str]
210
228
  remote_as: ASN
211
229
  families: set[Family] = field(default_factory=set)
230
+ family_options: PeerFamilyOptions = field(default_factory=PeerFamilyOptions)
212
231
  description: str = ""
213
232
  vrf_name: str = ""
214
233
  group_name: str = ""
@@ -264,6 +283,7 @@ class PeerGroup:
264
283
  name: str
265
284
  remote_as: ASN = ASN(None)
266
285
  families: set[Family] = field(default_factory=set)
286
+ family_options: PeerFamilyOptions = field(default_factory=PeerFamilyOptions)
267
287
  internal_name: str = ""
268
288
  description: str = ""
269
289
  update_source: str = ""
@@ -320,6 +340,7 @@ class PeerGroup:
320
340
  not_active: bool = False
321
341
  mtu: int = 0
322
342
  password: Optional[str] = None
343
+ cluster_id: Optional[str] = None
323
344
 
324
345
 
325
346
  @dataclass
@@ -371,6 +392,8 @@ class GlobalOptions:
371
392
  loops: int = 0
372
393
  multipath: int = 0
373
394
  router_id: str = ""
395
+ cluster_id: Optional[str] = None
396
+
374
397
  vrf: dict[str, VrfOptions] = field(default_factory=dict)
375
398
  groups: list[PeerGroup] = field(default_factory=list)
376
399
  l2vpn: dict[str, L2VpnOptions] = field(default_factory=dict)
annet/implicit.py CHANGED
@@ -73,7 +73,6 @@ def _implicit_tree(device):
73
73
  text = """
74
74
  !interface *
75
75
  !port link-type hybrid
76
- dot1x enable
77
76
  interface NULL0
78
77
  """
79
78
  else:
annet/mesh/basemodel.py CHANGED
@@ -1,8 +1,9 @@
1
1
  from abc import ABC
2
2
  from copy import copy
3
3
  from enum import Enum
4
+ from dataclasses import is_dataclass, replace, fields, MISSING
4
5
  from typing import (
5
- TypeVar, Any, Annotated, get_origin, get_type_hints, get_args, Callable, Union, ClassVar, overload,
6
+ TypeVar, Any, Annotated, get_origin, get_type_hints, get_args, Callable, Union, ClassVar, overload, cast,
6
7
  )
7
8
 
8
9
 
@@ -143,13 +144,15 @@ ModelT = TypeVar("ModelT", bound=BaseMeshModel)
143
144
  def _merge(a: ModelT, b: BaseMeshModel) -> ModelT:
144
145
  result = copy(a)
145
146
  for attr_name, merger in a._field_mergers.items():
146
- new_value = merger(
147
- attr_name,
148
- getattr(a, attr_name, Special.NOT_SET),
149
- getattr(b, attr_name, Special.NOT_SET),
150
- )
151
- if new_value is not Special.NOT_SET:
152
- setattr(result, attr_name, new_value)
147
+ aval = getattr(a, attr_name, Special.NOT_SET)
148
+ bval = getattr(b, attr_name, Special.NOT_SET)
149
+ if is_dataclass(aval) and is_dataclass(bval):
150
+ new_dto = merge_dataclass(aval, bval)
151
+ setattr(result, attr_name, new_dto)
152
+ else:
153
+ new_value = merger(attr_name, aval, bval)
154
+ if new_value is not Special.NOT_SET:
155
+ setattr(result, attr_name, new_value)
153
156
  return result
154
157
 
155
158
 
@@ -178,6 +181,64 @@ def merge(first: Any, /, *others: Any) -> Any:
178
181
  return first
179
182
 
180
183
 
184
+ def merge_dataclass(a: Any, b: Any) -> Any:
185
+ if a.__class__ != b.__class__:
186
+ raise MergeForbiddenError(
187
+ f"Dataclasses belonging to different instaces can't be merged:\n"
188
+ f"Old: {a}\n"
189
+ f"New: {b}"
190
+ )
191
+
192
+ if a == b:
193
+ return replace(a)
194
+
195
+ empty = dataclass_default(a.__class__)
196
+ merged = {}
197
+ for f in fields(empty):
198
+ default = getattr(empty, f.name)
199
+ aval = getattr(a, f.name)
200
+ bval = getattr(b, f.name)
201
+ if aval == default:
202
+ merged[f.name] = bval
203
+ elif bval == default:
204
+ merged[f.name] = aval
205
+ elif aval == bval:
206
+ merged[f.name] = aval
207
+ elif is_dataclass(aval) and is_dataclass(bval):
208
+ merged[f.name] = merge_dataclass(aval, bval)
209
+ else:
210
+ raise MergeForbiddenError(
211
+ f"Dataclasses with non-equal field {f.name} can't be merged:\n"
212
+ f"Old: {aval}\n"
213
+ f"New: {bval}"
214
+ )
215
+
216
+ return replace(empty, **merged)
217
+
218
+
219
+ def is_dataclass_empty(a: Any) -> bool:
220
+ try:
221
+ dataclass_default(a.__class__)
222
+ except ValueError:
223
+ return False
224
+ return True
225
+
226
+
227
+ def dataclass_default(dataclass_cls: type[T]) -> T:
228
+ if not is_dataclass(dataclass_cls):
229
+ raise TypeError(f"Class {dataclass_cls} is not a dataclass")
230
+
231
+ non_default_fields = []
232
+ for f in fields(dataclass_cls):
233
+ if f.default == MISSING and f.default_factory == MISSING:
234
+ non_default_fields.append(f.name)
235
+
236
+ if non_default_fields:
237
+ raise ValueError(f"Class {dataclass_cls} has non-default fields: {' '.join(non_default_fields)}")
238
+
239
+ return cast(T, dataclass_cls())
240
+
241
+
181
242
  class KeyDefaultDict(dict):
182
243
  def __init__(self, factory: Callable[[str], Any]):
183
244
  super().__init__()
@@ -108,6 +108,7 @@ class GlobalOptionsDTO(_FamiliesMixin, BaseMeshModel):
108
108
  loops: int
109
109
  multipath: int
110
110
  router_id: str
111
+ cluster_id: Optional[str]
111
112
  vrf: Annotated[dict[str, VrfOptions], DictMerge(Merge())]
112
113
  groups: Annotated[dict[str, MeshPeerGroup], DictMerge(Merge())]
113
114
  l2vpn: Annotated[dict[str, L2VpnOptions], DictMerge(Merge())]
@@ -7,7 +7,7 @@ from adaptix import Retort, loader, Chain, name_mapping, as_is_loader
7
7
  from .peer_models import DirectPeerDTO, IndirectPeerDTO, VirtualPeerDTO, VirtualLocalDTO
8
8
  from ..bgp_models import (
9
9
  Aggregate, GlobalOptions, VrfOptions, FamilyOptions, Peer, PeerGroup, ASN, PeerOptions,
10
- Redistribute, BFDTimers, L2VpnOptions, VidCollection,
10
+ Redistribute, BFDTimers, L2VpnOptions, VidCollection, PeerFamilyOptions, PeerFamilyOption
11
11
  )
12
12
 
13
13
 
@@ -56,6 +56,8 @@ retort = Retort(
56
56
  loader(FamilyOptions, ObjMapping, Chain.FIRST),
57
57
  loader(Aggregate, ObjMapping, Chain.FIRST),
58
58
  loader(PeerOptions, ObjMapping, Chain.FIRST),
59
+ loader(PeerFamilyOptions, ObjMapping, Chain.FIRST),
60
+ loader(PeerFamilyOption, ObjMapping, Chain.FIRST),
59
61
  as_is_loader(Redistribute),
60
62
  as_is_loader(BFDTimers),
61
63
  name_mapping(PeerOptions, map={
@@ -98,4 +100,5 @@ def to_bgp_peer(local: LocalDTO, connected: PeerDTO, connected_hostname: str, in
98
100
  result.import_policy = getattr(local, "import_policy", result.import_policy)
99
101
  result.export_policy = getattr(local, "export_policy", result.export_policy)
100
102
  result.update_source = getattr(local, "update_source", result.update_source)
103
+ result.family_options = getattr(local, "family_options", result.family_options)
101
104
  return result
annet/mesh/peer_models.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from typing import Literal, Annotated, Union, Optional
2
2
 
3
3
  from .basemodel import BaseMeshModel, Concat, Unite
4
- from ..bgp_models import BFDTimers
4
+ from ..bgp_models import BFDTimers, PeerFamilyOptions
5
5
 
6
6
  FamilyName = Literal["ipv4_unicast", "ipv6_unicast", "ipv4_labeled_unicast", "ipv6_labeled_unicast", "l2vpn_evpn"]
7
7
 
@@ -39,6 +39,9 @@ class _OptionsDTO(_SharedOptionsDTO):
39
39
  """
40
40
  Options which can be set on group of peers or peer itself
41
41
  """
42
+ def __init__(self, **kwargs):
43
+ kwargs.setdefault("family_options", PeerFamilyOptions())
44
+ super().__init__(**kwargs)
42
45
  unnumbered: bool
43
46
  rr_client: bool
44
47
  next_hop_self: bool
@@ -77,6 +80,8 @@ class _OptionsDTO(_SharedOptionsDTO):
77
80
  soft_reconfiguration_inbound: bool
78
81
  not_active: bool
79
82
  mtu: int
83
+ family_options: PeerFamilyOptions
84
+ cluster_id: Optional[str]
80
85
 
81
86
 
82
87
  class DirectPeerDTO(MeshSession, _OptionsDTO):
annet/mesh/registry.py CHANGED
@@ -6,6 +6,7 @@ from .match_args import MatchedArgs
6
6
  from .device_models import GlobalOptionsDTO
7
7
  from .peer_models import MeshSession, IndirectPeerDTO, VirtualLocalDTO, VirtualPeerDTO, DirectPeerDTO
8
8
  from .port_processor import PortProcessor, united_ports
9
+ from .basemodel import is_dataclass_empty
9
10
 
10
11
 
11
12
  class DirectPeer(DirectPeerDTO):
@@ -22,7 +23,9 @@ class DirectPeer(DirectPeerDTO):
22
23
  self.all_connected_ports = all_connected_ports
23
24
 
24
25
  def is_empty(self):
25
- return self.__dict__.keys() == {"match", "device", "ports", "all_connected_ports"}
26
+ if not is_dataclass_empty(self.family_options):
27
+ return False
28
+ return self.__dict__.keys() == {"match", "device", "ports", "all_connected_ports", "family_options"}
26
29
 
27
30
 
28
31
  class IndirectPeer(IndirectPeerDTO):
@@ -35,7 +38,9 @@ class IndirectPeer(IndirectPeerDTO):
35
38
  self.device = device
36
39
 
37
40
  def is_empty(self):
38
- return self.__dict__.keys() == {"match", "device"}
41
+ if not is_dataclass_empty(self.family_options):
42
+ return False
43
+ return self.__dict__.keys() == {"match", "device", "family_options"}
39
44
 
40
45
 
41
46
  class VirtualLocal(VirtualLocalDTO):
@@ -48,7 +53,9 @@ class VirtualLocal(VirtualLocalDTO):
48
53
  self.device = device
49
54
 
50
55
  def is_empty(self):
51
- return self.__dict__.keys() == {"match", "device"}
56
+ if not is_dataclass_empty(self.family_options):
57
+ return False
58
+ return self.__dict__.keys() == {"match", "device", "family_options"}
52
59
 
53
60
 
54
61
  class VirtualPeer(VirtualPeerDTO):
@@ -39,6 +39,7 @@ save
39
39
  dialog: Please input the file name(*.cfg, *.zip, *.dat): ::: vrpcfg.zip
40
40
  undo rsa peer-public-key
41
41
  dialog: /Do you want to remove the public key named .*\? \[Y/N\]:/ ::: Y
42
+ dialog: /% Do you really want to remove the public key named .*\? \[y/n\]:/ ::: y
42
43
  undo stelnet server enable
43
44
  dialog: Warning: The operation will stop the STelnet server. Do you want to continue? [Y/N]: ::: Y
44
45
  undo telnet * server enable
@@ -177,6 +178,7 @@ info-center max-logfile-number *
177
178
 
178
179
  rsa peer-public-key *
179
180
  dialog: Do you really want to replace it? [Y/N]: ::: Y
181
+ dialog: /% You already have RSA public key named .*.\r\n% Do you really want to replace it\? \[y/n\]:/ ::: y
180
182
 
181
183
  ip binding vpn-instance
182
184
  dialog: Warning: This operation will modify the router ID to 0.0.0.0, which may affect the establishment of BGP peer relationships. Continue? [Y/N]: ::: Y
@@ -193,4 +195,7 @@ undo local-aaa-user change-password verify
193
195
  undo local-user ~
194
196
  dialog: Warning: This operation may affect online users, are you sure to change the user privilege level ?[Y/N] ::: Y
195
197
 
198
+ hwtacacs-server shared-key cipher *
199
+ dialog: Warning: The shared-key complexity is low. It is recommended that the password contain at least sixteen characters and be a combination of at least two of the following categories: Uppercase letters <A-Z>; Lowercase letters <a-z>; Numerals <0-9>; Symbols (all characters not defined as letters or numerals), such as !,$,#, and %. Continue? [Y/N]: ::: Y
200
+
196
201
  # vim: set syntax=annrulebook:
@@ -492,6 +492,9 @@ cpu-defend-policy
492
492
  slot *
493
493
  cpu-defend-policy
494
494
 
495
+ user-interface con 0
496
+ set authentication password cipher
497
+
495
498
  description %global
496
499
 
497
500
  undo ~ %global
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annet
3
- Version: 3.14.1
3
+ Version: 3.14.3
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
1
  annet/__init__.py,sha256=eDQub3o0HdHcTWU4ZJpySrJuffGkbWts5CHXZYwVV9A,1915
2
2
  annet/annet.py,sha256=vyQ__n5hkjub3aWO8tksHPoUSbTeK97MyMcR_U8_BSU,1016
3
3
  annet/argparse.py,sha256=v1MfhjR0B8qahza0WinmXClpR8UiDFhmwDDWtNroJPA,12855
4
- annet/bgp_models.py,sha256=QTzA6wu2_XWIr-Omq303LOfaNo3z_pHbc5g_zm0vz7g,13062
4
+ annet/bgp_models.py,sha256=roSDKhxzcg9N8iEh9zI4Jww1vOObWcwRVzMl9FJnh1M,14046
5
5
  annet/cli.py,sha256=shq3hHzrTxFL3x1_zTOR43QHo0JYs8QSwyOvGtL86Co,12733
6
6
  annet/cli_args.py,sha256=d0WuGiZfe42-nMvurX1bOb3iUMg0TSK-hxk8J1THxSY,13728
7
7
  annet/connectors.py,sha256=aoiDVLPizx8CW2p8SAwGCzyO_WW8H9xc2aujbGC4bDg,4882
@@ -11,7 +11,7 @@ annet/diff.py,sha256=kD_2kxz5wc2TP10xj-BHs6IPq1yNKkXxIco8czjeC6M,9497
11
11
  annet/filtering.py,sha256=ZtqxPsKdV9reZoRxtQyBg22BqyMqd-2SotYcxZ-68AQ,903
12
12
  annet/gen.py,sha256=y9e7P551uJ-thjBS2p-ZRMgwQa8kPF_JAoEXJ3am77Y,30683
13
13
  annet/hardware.py,sha256=O2uadehcavZ10ssPr-db3XYHK8cpbG7C7XFkO-I6r_s,1161
14
- annet/implicit.py,sha256=xR9YcTsmmMmnxL0WQqfKJSNAt6Q6wlm6ivVtiScswLI,6659
14
+ annet/implicit.py,sha256=SkACAc32eUGJSHfUIDL3cWoBguST42-HJDzScJuvJIc,6626
15
15
  annet/lib.py,sha256=4N4X6jCCrig5rk7Ua4AofrV9zK9jhzkBq57fLsfBJjw,4812
16
16
  annet/output.py,sha256=se8EpyNS9f9kPOlOaAV0ht4DjzDoBr8F2UafiezLPYw,7743
17
17
  annet/parallel.py,sha256=yM53RYaSpbIOUuBx4y07B_3jW8J-w3taiZWjcq_1r6A,17397
@@ -75,7 +75,7 @@ annet/annlib/rbparser/platform.py,sha256=d1jFH8hGMOf_qiveKE4H-c0OfNnzwmt2VYpSiSO
75
75
  annet/annlib/rbparser/syntax.py,sha256=PlKyWqS3zwPwumILmKIci-DmEAbfZp8YycpW1mNqADM,3602
76
76
  annet/annlib/rulebook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  annet/annlib/rulebook/common.py,sha256=6A3sOkOanDRTuR7F426zakShGaGKRBmBLDCnqBbBJr8,13531
78
- annet/api/__init__.py,sha256=yVF4742g45sdvVDtJrM4pIwchy5AsxROEmXcz31xFno,34090
78
+ annet/api/__init__.py,sha256=5YzScmeCDsHiDhtT3RwY_lMuikRZ6o7CVrlnJCln2A8,34116
79
79
  annet/configs/context.yml,sha256=RVLrKLIHpCty7AGwOnmqf7Uu0iZQCn-AjYhophDJer8,259
80
80
  annet/configs/logging.yaml,sha256=EUagfir99QqA73Scc3k7sfQccbU3E1SvEQdyhLFtCl4,997
81
81
  annet/generators/__init__.py,sha256=LnW6G_7K5ScGYkFjFk7_QfuUaFAk5oTSHYaTaL6xUwA,16735
@@ -90,14 +90,14 @@ annet/generators/result.py,sha256=8fBfKQ7vWi9DlGOUFYz0y47UlCI1gTqix3riX2CgQng,50
90
90
  annet/generators/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
91
  annet/generators/common/initial.py,sha256=qYBxXFhyOPy34cxc6hsIXseod-lYCmmbuNHpM0uteY0,1244
92
92
  annet/mesh/__init__.py,sha256=lcgdnBIxc2MAN7Er1bcErEKPqrjWO4uIp_1FldMXTYg,557
93
- annet/mesh/basemodel.py,sha256=E6NTOneiMDwB1NCpjDRECoaeQ0f3n_fmTLnKTrSHTU4,4917
94
- annet/mesh/device_models.py,sha256=K_JqI03GyikROM6MmfV03jjA1Raxr8btuAoANOY0aEo,4895
93
+ annet/mesh/basemodel.py,sha256=zq-ffVYS4gOs49BFdLCHQtLGJhGuQjHCJogbBQ4bXpI,6859
94
+ annet/mesh/device_models.py,sha256=uJrWwExq8fyD-cbcxlDvImaRLAXKxOeHAMT5S6YEO7g,4925
95
95
  annet/mesh/executor.py,sha256=gfRQXSTivL0DJrhnGH-4kmCTiIxDS_vReQyle3bF2FI,17970
96
96
  annet/mesh/match_args.py,sha256=CR3kdIV9NGtyk9E2JbcOQ3TRuYEryTWP3m2yCo2VCWg,5751
97
- annet/mesh/models_converter.py,sha256=nCtzFR3s65MVkCE_xJm1Ci5c2hUwsr6ajfBiSmy3r_8,3565
98
- annet/mesh/peer_models.py,sha256=9fx-JiLTJ6E-CVBmu0BpkJwH4JwpdTOozJYlY2uH_Q4,2796
97
+ annet/mesh/models_converter.py,sha256=1S6D80jrpJNNRa1dq9UrTi-n-tc7L9mX_s6zIsXss70,3804
98
+ annet/mesh/peer_models.py,sha256=4QRQ4HSImEhru83k8-VH1fbAm7Ih71VRwMfKZRIyLsY,3017
99
99
  annet/mesh/port_processor.py,sha256=RHiMS5W8qoDkTKiarQ748bcr8bNx4g_R4Y4vZg2k4TU,478
100
- annet/mesh/registry.py,sha256=xmWF7yxWXmwqX2_jyMAKrbGd2G9sjb4rYDx4Xk61QKc,9607
100
+ annet/mesh/registry.py,sha256=PiopHMYXXxxGDtajPIz4mivcYROXtOFPEX1rMwehD0w,9946
101
101
  annet/rpl/__init__.py,sha256=8nSiFpXH4OhzRGKr-013nHwwKk5Y50uh2gL7d_IoV8U,757
102
102
  annet/rpl/action.py,sha256=PY6W66j908RuqQ1_ioxayqVN-70rxDk5Z59EGHtxI98,1246
103
103
  annet/rpl/condition.py,sha256=MJri4MbWtPkLHIsLMAtsIEF7e8IAS9dIImjmJs5vS5U,3418
@@ -158,9 +158,9 @@ annet/rulebook/texts/b4com.rul,sha256=WAhAV5HEotXtQU0CVyS3UScDsnCjQ2qDVNdC87s3vI
158
158
  annet/rulebook/texts/cisco.deploy,sha256=Hu0NkcGv3f1CWUrnbzI3eQOPXJxtH4NNOPRV68IrW4U,1226
159
159
  annet/rulebook/texts/cisco.order,sha256=DarNICBBAEXR8VOFV8SNnuQmwGAG-TGwXlMWpFMTCDE,1927
160
160
  annet/rulebook/texts/cisco.rul,sha256=cX9CyqKpgpr8B1Qe3aEe66wZpfaGg7fmsIsmgW6Yip4,3619
161
- annet/rulebook/texts/huawei.deploy,sha256=5vrvhai2BjaJ793A3EHHCthic3dnGKp2_rAgViVIouI,10951
161
+ annet/rulebook/texts/huawei.deploy,sha256=wd2xBldTBCGzo6YtpBEQeyiTtFyMuPGk6xANs29yckY,11552
162
162
  annet/rulebook/texts/huawei.order,sha256=4qXuoqfJ8Hck11LACKwaWP2ARHwPrtLfCut1BDRAg7E,11244
163
- annet/rulebook/texts/huawei.rul,sha256=asuQeZgADkOYsNMP5t2tIRbJnlTYgicxSV6S94ozYXw,13816
163
+ annet/rulebook/texts/huawei.rul,sha256=5Xdy_pJYnLHwrCmnj8q6FsOhWk-MZFr4vBLiBCf0w70,13877
164
164
  annet/rulebook/texts/iosxr.deploy,sha256=Hu0NkcGv3f1CWUrnbzI3eQOPXJxtH4NNOPRV68IrW4U,1226
165
165
  annet/rulebook/texts/iosxr.order,sha256=gUp6XHwzqkDsArCUAwtx3rR1qlGfYsHy2vP9oZN2oDk,1922
166
166
  annet/rulebook/texts/iosxr.rul,sha256=JMFJ94ORNeDQo_X73iPS6pFUmXYTBuL5pkUypgHcOig,2966
@@ -199,8 +199,8 @@ annet/vendors/library/optixtrans.py,sha256=VdME69Ca4HAEgoaKN21fZxnmmsqqaxOe_HZja
199
199
  annet/vendors/library/pc.py,sha256=vfv31_NPi7M-4AUDL89UcpawK2E6xvCpELA209cd1ho,1086
200
200
  annet/vendors/library/ribbon.py,sha256=DDOBq-_-FL9dCxqXs2inEWZ-pvw-dJ-A-prA7cKMhec,1216
201
201
  annet/vendors/library/routeros.py,sha256=iQa7m_4wjuvcgBOI9gyZwlw1BvzJfOkvUbyoEk-NI9I,1254
202
- annet-3.14.1.dist-info/licenses/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
203
- annet-3.14.1.dist-info/licenses/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
202
+ annet-3.14.3.dist-info/licenses/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
203
+ annet-3.14.3.dist-info/licenses/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
204
204
  annet_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
205
  annet_generators/example/__init__.py,sha256=OJ77uj8axc-FIyIu_Xdcnzmde3oQW5mk5qbODkhuVc8,355
206
206
  annet_generators/example/hostname.py,sha256=RloLzNVetEoWPLITzfJ13Nk3CC0yi-cZB1RTd6dnuhI,2541
@@ -213,8 +213,8 @@ annet_generators/rpl_example/generator.py,sha256=EWah19gOH8G-QyNyWqxCqdRi0BK7GbM
213
213
  annet_generators/rpl_example/items.py,sha256=HPgxScDvSqJPdz0c2SppDrH82DZYC4zUaniQwcWmh4A,1176
214
214
  annet_generators/rpl_example/mesh.py,sha256=z_WgfDZZ4xnyh3cSf75igyH09hGvtexEVwy1gCD_DzA,288
215
215
  annet_generators/rpl_example/route_policy.py,sha256=z6nPb0VDeQtKD1NIg9sFvmUxBD5tVs2frfNIuKdM-5c,2318
216
- annet-3.14.1.dist-info/METADATA,sha256=BKLGnMeB4wRe5P-wSYsu3zPFBxoTIS6_y75rZJ6lz04,816
217
- annet-3.14.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
218
- annet-3.14.1.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
219
- annet-3.14.1.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
220
- annet-3.14.1.dist-info/RECORD,,
216
+ annet-3.14.3.dist-info/METADATA,sha256=oOmmrA_5GQH9B_GK2zSet72zauJiZs47naDVeX7JwIQ,816
217
+ annet-3.14.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
218
+ annet-3.14.3.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
219
+ annet-3.14.3.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
220
+ annet-3.14.3.dist-info/RECORD,,
File without changes