annet 0.16.31__py3-none-any.whl → 0.16.33__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.

@@ -214,7 +214,7 @@ class NetboxDevice(Entity):
214
214
  return type(self) is type(other) and self.url == other.url
215
215
 
216
216
  def is_pc(self) -> bool:
217
- return self.device_type.manufacturer.name in ("Mellanox", "Moxa") or self.breed == "pc"
217
+ return self.device_type.manufacturer.name in ("Mellanox", "NVIDIA", "Moxa") or self.breed == "pc"
218
218
 
219
219
  def _make_interface(self, name: str, type: InterfaceType) -> Interface:
220
220
  return Interface(
@@ -20,6 +20,6 @@ class NetboxStatusClient(BaseNetboxClient):
20
20
  name_mapping(name_style=NameStyle.LOWER_KEBAB)
21
21
  ])
22
22
 
23
- @get("status")
23
+ @get("status/")
24
24
  def status(self) -> Status:
25
25
  ...
annet/bgp_models.py CHANGED
@@ -68,7 +68,7 @@ class BFDTimers:
68
68
  multiplier: int = 4
69
69
 
70
70
 
71
- Family = Literal["ipv4_unicast", "ipv6_unicast", "ipv4_labeled_unicast", "ipv6_labeled_unicast"]
71
+ Family = Literal["ipv4_unicast", "ipv6_unicast", "ipv4_labeled_unicast", "ipv6_labeled_unicast", "l2vpn_evpn"]
72
72
 
73
73
 
74
74
  @dataclass(frozen=True)
@@ -207,7 +207,7 @@ class PeerGroup:
207
207
  auth_key: bool = False
208
208
  add_path: bool = False
209
209
  multipath: bool = False
210
- multihop: bool = False
210
+ multihop: Optional[int] = None
211
211
  multihop_no_nexthop_change: bool = False
212
212
  af_no_install: bool = False
213
213
  bfd: bool = False
@@ -243,8 +243,10 @@ class VrfOptions:
243
243
  ipv6_unicast: FamilyOptions
244
244
  ipv4_labeled_unicast: FamilyOptions
245
245
  ipv6_labeled_unicast: FamilyOptions
246
+ l2vpn_evpn: FamilyOptions
246
247
 
247
248
  vrf_name_global: Optional[str] = None
249
+ l3vni: Optional[int] = None
248
250
  as_path_relax: bool = False
249
251
  rt_import: list[str] = field(default_factory=list)
250
252
  rt_export: list[str] = field(default_factory=list)
@@ -262,6 +264,7 @@ class GlobalOptions:
262
264
  ipv6_unicast: FamilyOptions
263
265
  ipv4_labeled_unicast: FamilyOptions
264
266
  ipv6_labeled_unicast: FamilyOptions
267
+ l2vpn_evpn: FamilyOptions
265
268
 
266
269
  as_path_relax: bool = False
267
270
  local_as: ASN = ASN(None)
@@ -299,6 +302,9 @@ def _used_redistribute_policies(opts: Union[GlobalOptions, VrfOptions]) -> Itera
299
302
  for red in opts.ipv6_labeled_unicast.redistributes:
300
303
  if red.policy:
301
304
  yield red.policy
305
+ for red in opts.l2vpn_evpn.redistributes:
306
+ if red.policy:
307
+ yield red.policy
302
308
 
303
309
 
304
310
  def extract_policies(config: BgpConfig) -> Sequence[str]:
@@ -43,11 +43,13 @@ class _FamiliesMixin:
43
43
  kwargs.setdefault("ipv6_unicast", FamilyOptions(family="ipv6_unicast"))
44
44
  kwargs.setdefault("ipv4_labeled_unicast", FamilyOptions(family="ipv4_labeled_unicast"))
45
45
  kwargs.setdefault("ipv6_labeled_unicast", FamilyOptions(family="ipv6_labeled_unicast"))
46
+ kwargs.setdefault("l2vpn_evpn", FamilyOptions(family="l2vpn_evpn"))
46
47
  super().__init__(**kwargs)
47
48
  ipv4_unicast: Annotated[FamilyOptions, Merge()]
48
49
  ipv6_unicast: Annotated[FamilyOptions, Merge()]
49
50
  ipv4_labeled_unicast: Annotated[FamilyOptions, Merge()]
50
51
  ipv6_labeled_unicast: Annotated[FamilyOptions, Merge()]
52
+ l2vpn_evpn: Annotated[FamilyOptions, Merge()]
51
53
 
52
54
 
53
55
  class VrfOptions(_FamiliesMixin, BaseMeshModel):
@@ -56,6 +58,7 @@ class VrfOptions(_FamiliesMixin, BaseMeshModel):
56
58
  kwargs.setdefault("ipv6_unicast", FamilyOptions(family="ipv6_unicast", vrf_name=vrf_name))
57
59
  kwargs.setdefault("ipv4_labeled_unicast", FamilyOptions(family="ipv4_labeled_unicast", vrf_name=vrf_name))
58
60
  kwargs.setdefault("ipv6_labeled_unicast", FamilyOptions(family="ipv6_labeled_unicast", vrf_name=vrf_name))
61
+ kwargs.setdefault("l2vpn_evpn", FamilyOptions(family="l2vpn_evpn", vrf_name=vrf_name))
59
62
  kwargs.setdefault("groups", KeyDefaultDict(lambda x: MeshPeerGroup(name=x)))
60
63
  super().__init__(vrf_name=vrf_name, **kwargs)
61
64
 
@@ -64,6 +67,7 @@ class VrfOptions(_FamiliesMixin, BaseMeshModel):
64
67
  as_path_relax: bool
65
68
  import_policy: Optional[str]
66
69
  export_policy: Optional[str]
70
+ l3vni: Optional[int]
67
71
  rt_import: Annotated[tuple[str, ...], Concat()]
68
72
  rt_export: Annotated[tuple[str, ...], Concat()]
69
73
  rt_import_v4: Annotated[tuple[str, ...], Concat()]
annet/mesh/peer_models.py CHANGED
@@ -3,7 +3,7 @@ from typing import Literal, Annotated, Union, Optional
3
3
  from .basemodel import BaseMeshModel, Concat, Unite
4
4
  from ..bgp_models import BFDTimers
5
5
 
6
- FamilyName = Literal["ipv4_unicast", "ipv6_unicast", "ipv4_labeled_unicast", "ipv6_labeled_unicast"]
6
+ FamilyName = Literal["ipv4_unicast", "ipv6_unicast", "ipv4_labeled_unicast", "ipv6_labeled_unicast", "l2vpn_evpn"]
7
7
 
8
8
 
9
9
  class _SharedOptionsDTO(BaseMeshModel):
@@ -53,7 +53,7 @@ class _OptionsDTO(_SharedOptionsDTO):
53
53
  advertise_bgp_static: bool
54
54
  allowas_in: bool
55
55
  auth_key: bool
56
- multihop: bool
56
+ multihop: Optional[int]
57
57
  multihop_no_nexthop_change: bool
58
58
  af_no_install: bool
59
59
  rib: bool
@@ -101,7 +101,7 @@ class IndirectPeerDTO(MeshSession, _OptionsDTO):
101
101
 
102
102
 
103
103
  class VirtualLocalDTO(_OptionsDTO):
104
- asnum: int
104
+ asnum: Union[int, str]
105
105
  pod: int
106
106
  addr: str
107
107
  description: str
@@ -100,7 +100,7 @@ class CumulusPolicyGenerator(ABC):
100
100
  ip_type,
101
101
  "prefix-list",
102
102
  name,
103
- f"seq {i * 10 + 5}",
103
+ f"seq {i * 5 + 5}",
104
104
  "permit", f"{addr_mask.ip}/{addr_mask.network.prefixlen}",
105
105
  ) + (
106
106
  ("ge", str(match.greater_equal)) if match.greater_equal is not None else ()
@@ -151,13 +151,14 @@ class CumulusPolicyGenerator(ABC):
151
151
  return get_used_united_community_lists(communities=communities.values(), policies=policies)
152
152
 
153
153
  def _cumulus_community(
154
- self, name: str, cmd: str, member: str, use_regex: bool,
154
+ self, name: str, cmd: str, member: str, use_regex: bool, seq: int,
155
155
  ) -> Iterable[Sequence[str]]:
156
156
  if use_regex:
157
157
  yield (
158
158
  cmd,
159
159
  "expanded",
160
160
  name,
161
+ f"seq {seq}",
161
162
  "permit",
162
163
  member,
163
164
  )
@@ -166,6 +167,7 @@ class CumulusPolicyGenerator(ABC):
166
167
  cmd,
167
168
  "standard",
168
169
  name,
170
+ f"seq {seq}",
169
171
  "permit",
170
172
  member,
171
173
  )
@@ -182,6 +184,7 @@ class CumulusPolicyGenerator(ABC):
182
184
  return
183
185
  for community_list_union in community_unions:
184
186
  name = mangle_united_community_list_name([c.name for c in community_list_union])
187
+ comm_number = 0
185
188
 
186
189
  for clist in community_list_union:
187
190
  if clist.type is CommunityType.BASIC:
@@ -207,13 +210,15 @@ class CumulusPolicyGenerator(ABC):
207
210
  else:
208
211
  member = " ".join(f"{member_prefix}{m}" for m in clist.members)
209
212
  yield from self._cumulus_community(
210
- name=name, cmd=cmd, member=member, use_regex=clist.use_regex,
213
+ name=name, cmd=cmd, member=member, use_regex=clist.use_regex, seq=(comm_number + 1) * 10,
211
214
  )
212
215
  else:
213
- for member_value in clist.members:
216
+ for comm_number, member_value in enumerate(clist.members, start=comm_number):
214
217
  yield from self._cumulus_community(
215
218
  name=name, cmd=cmd, member=member_prefix + member_value, use_regex=clist.use_regex,
219
+ seq=(comm_number + 1) * 10,
216
220
  )
221
+ comm_number += 1
217
222
  yield "!"
218
223
 
219
224
  def _get_match_community_names(self, condition: SingleCondition[Sequence[str]]) -> Sequence[str]:
@@ -278,7 +283,7 @@ class CumulusPolicyGenerator(ABC):
278
283
  action: SingleAction[CommunityActionValue],
279
284
  ) -> Iterator[Sequence[str]]:
280
285
  if action.value.replaced is not None:
281
- if action.value.added or action.value.replaced:
286
+ if action.value.added or action.value.removed:
282
287
  raise NotImplementedError(
283
288
  "Cannot set community together with add/replace on cumulus",
284
289
  )
@@ -65,7 +65,7 @@ class PrefixListFilterGenerator(PartialGenerator, ABC):
65
65
  "ip",
66
66
  prefix_type,
67
67
  name,
68
- f"index {i * 10 + 5}",
68
+ f"index {i * 5 + 5}",
69
69
  "permit",
70
70
  str(addr_mask.ip).upper(),
71
71
  str(addr_mask.network.prefixlen),
@@ -126,7 +126,7 @@ class PrefixListFilterGenerator(PartialGenerator, ABC):
126
126
  prefix_type,
127
127
  "prefix-list",
128
128
  name,
129
- f"seq {i * 10 + 5}",
129
+ f"seq {i * 5 + 5}",
130
130
  "permit",
131
131
  str(addr_mask.ip).upper(),
132
132
  str(addr_mask.network.prefixlen),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: annet
3
- Version: 0.16.31
3
+ Version: 0.16.33
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=W8kkZ3Axu-6VJwgQ0cn4UeOVNy6jab0cqgHKLQny1D0,2141
2
2
  annet/annet.py,sha256=TMdEuM7GJQ4TjRVmuK3bCTZN-21lxjQ9sXqEdILUuBk,725
3
3
  annet/argparse.py,sha256=v1MfhjR0B8qahza0WinmXClpR8UiDFhmwDDWtNroJPA,12855
4
- annet/bgp_models.py,sha256=5FnXMeIbZJIQRdUk6Jf2f3YlkQSLAgmBH8bq2o94MUM,9457
4
+ annet/bgp_models.py,sha256=I9DQpf3LU71RBk9kCUdA-RnGkA3eORngYkC3_obsLmk,9669
5
5
  annet/cli.py,sha256=hDpjIr3w47lgQ_CvCQS1SXFDK-SJrf5slbT__5u6GIA,12342
6
6
  annet/cli_args.py,sha256=KQlihxSl-Phhq1-9oJDdNSbIllEX55LlPfH6viEKOuw,13483
7
7
  annet/connectors.py,sha256=-Lghz3PtWCBU8Ohrp0KKQcmm1AUZtN0EnOaZ6IQgCQI,5105
@@ -33,9 +33,9 @@ annet/adapters/netbox/provider.py,sha256=3IrfZ6CfCxf-lTnJlIC2TQ8M_rDxOB_B7HGXZ92
33
33
  annet/adapters/netbox/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  annet/adapters/netbox/common/client.py,sha256=PaxHG4W9H8_uunIwMBNYkLq4eQJYoO6p6gY-ciQs7Nc,2563
35
35
  annet/adapters/netbox/common/manufacturer.py,sha256=LAPT6OlV_ew96GhtwNrCpeiT0IGrg2_9__MMdZk431U,1733
36
- annet/adapters/netbox/common/models.py,sha256=TnWEKI6_MxuZe24xfpkAijofkn-dOXwWe_ZOCWaYX58,7374
36
+ annet/adapters/netbox/common/models.py,sha256=Xq6Dc3kY9_QyvS9DiKEq1AxjTxiF4qEKhs1EMtBw-k4,7384
37
37
  annet/adapters/netbox/common/query.py,sha256=ziUFM7cUEbEIf3k1szTll4aO-OCUa-2Ogxbebi7Tegs,646
38
- annet/adapters/netbox/common/status_client.py,sha256=W4nTb2yvBlJ2UkWUmUhKQ2PaSQb1shjhHj5ebb4s2s4,591
38
+ annet/adapters/netbox/common/status_client.py,sha256=XXx0glomaBaglmkUEy6YtFOxQQkHb59CDA0h1I-IhxM,592
39
39
  annet/adapters/netbox/common/storage_opts.py,sha256=5tt6wxUUJTIzNbOVXMnYBwZedNAIqYlve3YWl6GdbZM,1197
40
40
  annet/adapters/netbox/v24/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  annet/adapters/netbox/v24/storage.py,sha256=THI592VLx3ehixsPZQ1Ko3mYIAZQbnDY-toIziqBbL8,6005
@@ -83,11 +83,11 @@ annet/generators/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
83
83
  annet/generators/common/initial.py,sha256=qYBxXFhyOPy34cxc6hsIXseod-lYCmmbuNHpM0uteY0,1244
84
84
  annet/mesh/__init__.py,sha256=lcgdnBIxc2MAN7Er1bcErEKPqrjWO4uIp_1FldMXTYg,557
85
85
  annet/mesh/basemodel.py,sha256=E6NTOneiMDwB1NCpjDRECoaeQ0f3n_fmTLnKTrSHTU4,4917
86
- annet/mesh/device_models.py,sha256=YcL6_vGjnt67BTovN8Eq38U5wGcbJDhqiq8613WpYtQ,3381
86
+ annet/mesh/device_models.py,sha256=KkbD8tuWfnh4gR8iOV9C7ihLR4jxjyuF52AU2DPPLXA,3627
87
87
  annet/mesh/executor.py,sha256=0RLsdtldozoFgDGFuhU5mdckuMwGg0y_DFIji1RfTQg,16969
88
88
  annet/mesh/match_args.py,sha256=CR3kdIV9NGtyk9E2JbcOQ3TRuYEryTWP3m2yCo2VCWg,5751
89
89
  annet/mesh/models_converter.py,sha256=3q2zs7K8S3pfYSUKKRdtl5CJGbeg4TtYxofAVs_MBsk,3085
90
- annet/mesh/peer_models.py,sha256=uD3h7HWl9_zNdBlQqZCMcjCnzjr8dTbSFqc8216JDu0,2735
90
+ annet/mesh/peer_models.py,sha256=9vn5ENiEZqOZFRFSOJReT8E3E2GzBte628mkmS3cplI,2770
91
91
  annet/mesh/port_processor.py,sha256=RHiMS5W8qoDkTKiarQ748bcr8bNx4g_R4Y4vZg2k4TU,478
92
92
  annet/mesh/registry.py,sha256=BCRIOrINP0krcgvF59uFJqyhmSviQ03GSzWpxLVYlIg,9527
93
93
  annet/rpl/__init__.py,sha256=0kcIktE3AmS0rlm9xzVDf53xk08OeZXgD-6ZLCt_KCs,731
@@ -101,11 +101,11 @@ annet/rpl/statement_builder.py,sha256=sVGOYsCV0s_SFQUy2WtUyQqKy5H4MOfmRCJWGj-UOJ
101
101
  annet/rpl_generators/__init__.py,sha256=ZLWs-flcpyIbdhxSDfNt-ORDrLe8ins25sWdXTWeUoA,748
102
102
  annet/rpl_generators/aspath.py,sha256=kZakwPLfGGiXu9fC6I1z-pvy7Fe-4dy93_-lYcx39_4,2038
103
103
  annet/rpl_generators/community.py,sha256=SWpaOvoQUNISuRm41-IvGPFmntvgFv9ee4zegsMyeo0,11496
104
- annet/rpl_generators/cumulus_frr.py,sha256=D8JnnXTXYaIUayPwL_KORUCkpBV32-CHatlyKQSSJWw,20855
104
+ annet/rpl_generators/cumulus_frr.py,sha256=F-LRT-UPnztUqinp3KYKqh796L9dqkzPKBUxMkiFjF8,21111
105
105
  annet/rpl_generators/entities.py,sha256=DIpgAQ8Tslo2hq6iFBaYkJX12BFBiccN8GOaRVxR1Uk,1985
106
106
  annet/rpl_generators/execute.py,sha256=wS6e6fwcPWywsHB0gBMqZ17eF0s4YOBgDgwPB_cr5Rw,431
107
107
  annet/rpl_generators/policy.py,sha256=NeqB0reRN_KuY8LYkeGT3dRPe2HFDT9RfmVy5fcA3zw,32570
108
- annet/rpl_generators/prefix_lists.py,sha256=2x2NO52npcB3VKcQ4tthsWFwirVpexLdLtWPA5sHzjg,7246
108
+ annet/rpl_generators/prefix_lists.py,sha256=GyNbqXvRVGiuetLSXG2kQidRUXPMEAhR74AJJFSDQZc,7244
109
109
  annet/rpl_generators/rd.py,sha256=YGXgx1D2D0-pixgspXJzA6NvW8lx3AmHMxIY2l5rraI,1457
110
110
  annet/rulebook/__init__.py,sha256=oafL5HC8QHdkO9CH2q_fxohPMxOgjn-dNQa5kPjuqsA,3942
111
111
  annet/rulebook/common.py,sha256=zK1s2c5lc5HQbIlMUQ4HARQudXSgOYiZ_Sxc2I_tHqg,721
@@ -175,10 +175,10 @@ annet_generators/rpl_example/generator.py,sha256=zndIGfV4ZlTxPgAGYs7bMQvTc_tYScO
175
175
  annet_generators/rpl_example/items.py,sha256=Ez1RF5YhcXNCusBmeApIjRL3rBlMazNZd29Gpw1_IsA,766
176
176
  annet_generators/rpl_example/mesh.py,sha256=z_WgfDZZ4xnyh3cSf75igyH09hGvtexEVwy1gCD_DzA,288
177
177
  annet_generators/rpl_example/route_policy.py,sha256=z6nPb0VDeQtKD1NIg9sFvmUxBD5tVs2frfNIuKdM-5c,2318
178
- annet-0.16.31.dist-info/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
179
- annet-0.16.31.dist-info/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
180
- annet-0.16.31.dist-info/METADATA,sha256=CpR6RlgdzRXD13wUkktgrcw2nuWeqI0dZNJ1dyNn7hE,854
181
- annet-0.16.31.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
182
- annet-0.16.31.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
183
- annet-0.16.31.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
184
- annet-0.16.31.dist-info/RECORD,,
178
+ annet-0.16.33.dist-info/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
179
+ annet-0.16.33.dist-info/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
180
+ annet-0.16.33.dist-info/METADATA,sha256=4FDrHTUVwwM6GIzoAZ96e3XHrSiSHvSShAY7v7jw4qg,854
181
+ annet-0.16.33.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
182
+ annet-0.16.33.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
183
+ annet-0.16.33.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
184
+ annet-0.16.33.dist-info/RECORD,,