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

@@ -101,7 +101,7 @@ class IpAddress(DumpableView, Generic[_PrefixT]):
101
101
 
102
102
  @dataclass
103
103
  class InterfaceConnectedEndpoint(Entity):
104
- device: Entity
104
+ device: Entity | None
105
105
 
106
106
 
107
107
  @dataclass
@@ -207,6 +207,8 @@ class NetboxDevice(Entity, Generic[_InterfaceT]):
207
207
  created: datetime
208
208
  last_updated: datetime
209
209
  cluster: Optional[Entity]
210
+ config_context: Optional[dict[str, Any]]
211
+ config_template: Optional[dict[str, Any]]
210
212
 
211
213
  fqdn: str
212
214
  hostname: str
annet/annlib/command.py CHANGED
@@ -12,6 +12,7 @@ class Question:
12
12
  question: str # frame it using / if it is a regular expression
13
13
  answer: str
14
14
  is_regexp: Optional[bool] = False
15
+ not_send_nl: bool = False
15
16
 
16
17
 
17
18
  @dataclass
@@ -19,7 +20,8 @@ class Command:
19
20
  cmd: str
20
21
  questions: Optional[List[Question]] = None
21
22
  exc_handler: Optional[List[Question]] = None
22
- timeout: Optional[int] = None
23
+ timeout: Optional[int] = None # total timeout
24
+ read_timeout: Optional[int] = None # timeout between consecutive reads
23
25
  suppress_nonzero: bool = False
24
26
  suppress_eof: bool = False
25
27
 
@@ -10,7 +10,7 @@ from annet.vendors import registry_connector
10
10
  # =====
11
11
  def default(rule, key, diff, **_):
12
12
  r"""
13
- Функция default() обеспичвает базовую логику обработки всех правил. Ее можно заменить с помощью
13
+ Функция default() обеспечивает базовую логику обработки всех правил. Ее можно заменить с помощью
14
14
  параметра %logic в текстовом рулбуке. Она вызывается для каждой команды с уникальным ключом и
15
15
  должна возвратить сгенерированный текст патча на основе предоставленного диффа, и, при необходимости,
16
16
  вызвать обработку дочерних правил/данных.
@@ -49,8 +49,8 @@ def default(rule, key, diff, **_):
49
49
  """
50
50
  for op in [Op.ADDED, Op.REMOVED, Op.AFFECTED, Op.MOVED]:
51
51
  # Дефолтная функция генерации патчей считает, что не бывает команд с одинаковыми
52
- # ключами и разным значением. при этом unchanged мы так не проверяем поскольку
53
- # такие случаи возможны когда у нас подмешиваются implicit команды
52
+ # ключами и разным значением. При этом unchanged мы так не проверяем, поскольку
53
+ # такие случаи возможны, когда у нас подмешиваются implicit команды
54
54
  assert 0 <= len(diff[op]) <= 1, "Too many %s actions for rows %r" % (op, [x["row"] for x in diff[op]])
55
55
  if diff[Op.AFFECTED]:
56
56
  # При изменении блока нужно вызвать обработку чилдов
@@ -60,7 +60,7 @@ def default(rule, key, diff, **_):
60
60
  # При модификации строки удаление нас не интересует, добавление проходит как affected
61
61
  yield (True, diff[key][0]["row"], diff[key][0]["children"])
62
62
  elif diff[Op.REMOVED]:
63
- # При удалении или перемещеннии блока просто снести строку
63
+ # При удалении или перемещении блока просто снести строку
64
64
  yield (False, rule["reverse"].format(*key), None)
65
65
 
66
66
 
@@ -179,7 +179,7 @@ def multiline_diff(old: odict, new: odict, diff_pre: odict, _pops: tuple[Op, ...
179
179
  Особая логика diff'a для хуавейных мультилайнов.
180
180
  Она трактует все дочерние элементы %multiline-команды как
181
181
  одну общую команду, покидывая внутрь тот Op который был
182
- определен на вернем уровне
182
+ определен на верхнем уровне
183
183
  """
184
184
 
185
185
  def process_multiline(op, tree):
annet/bgp_models.py CHANGED
@@ -199,6 +199,7 @@ class PeerOptions:
199
199
  soft_reconfiguration_inbound: Optional[bool] = None
200
200
  not_active: Optional[bool] = None
201
201
  mtu: Optional[int] = None
202
+ password: Optional[str] = None
202
203
 
203
204
 
204
205
  @dataclass
@@ -312,6 +313,7 @@ class PeerGroup:
312
313
  soft_reconfiguration_inbound: bool = False
313
314
  not_active: bool = False
314
315
  mtu: int = 0
316
+ password: Optional[str] = None
315
317
 
316
318
 
317
319
  @dataclass
annet/cli_args.py CHANGED
@@ -248,6 +248,11 @@ opt_max_slots = Arg(
248
248
  help="The amount of devices parsed at the same time with asyncio"
249
249
  )
250
250
 
251
+ opt_max_deploy = Arg(
252
+ "--max-deploy", default=0, type=int,
253
+ help="The amount of devices deployed at the same time"
254
+ )
255
+
251
256
  opt_hosts_range = Arg(
252
257
  "--hosts-range", type=valid_range,
253
258
  help="Only work with the specified hosts range: 10 - the first 10. 10:20 - host from 10th up to 20th"
@@ -498,6 +503,7 @@ class DeployOptions(ShowDiffOptions, PatchOptions, DeviceCliOptions):
498
503
  no_check_diff = opt_no_check_diff
499
504
  entire_reload = opt_entire_reload
500
505
  rollback = opt_rollback
506
+ max_parallel = opt_max_deploy
501
507
 
502
508
 
503
509
  class SelectContext(ArgGroup):
annet/deploy.py CHANGED
@@ -157,14 +157,13 @@ class RulebookQuestionHandler:
157
157
 
158
158
 
159
159
  def rb_question_to_question(q: MakeMessageMatcher, a: Answer) -> Question: # TODO: drop MakeMessageMatcher
160
- if not a.send_nl:
161
- raise Exception("not supported false send_nl")
162
160
  text: str = q._text # pylint: disable=protected-access
161
+ answer: str = a.text
163
162
  is_regexp = False
164
163
  if text.startswith("/") and text.endswith("/"):
165
164
  is_regexp = True
166
165
  text = text[1:-1]
167
- res = Question(question=text, answer=a.text, is_regexp=is_regexp)
166
+ res = Question(question=text, answer=answer, is_regexp=is_regexp, not_send_nl=not a.send_nl)
168
167
  return res
169
168
 
170
169
 
annet/deploy_ui.py CHANGED
@@ -5,6 +5,7 @@ import os
5
5
  import sys
6
6
  import math
7
7
  import asyncio
8
+ import platform
8
9
  import textwrap
9
10
  import time
10
11
  import traceback
@@ -23,7 +24,7 @@ try:
23
24
  except ImportError:
24
25
  curses = None
25
26
 
26
- uname = os.uname()[0]
27
+ uname = platform.uname()[0]
27
28
  NCURSES_SIZE_T = 2 ** 15 - 1
28
29
  MIN_CONTENT_HEIGHT = 20
29
30
 
annet/executor.py CHANGED
@@ -162,7 +162,7 @@ class DeferredFileWrite:
162
162
  raise Exception()
163
163
 
164
164
  def write(self, data):
165
- with open(self._file, self._mode) as fh:
165
+ with open(self._file, self._mode, encoding="utf-8") as fh:
166
166
  fh.write(data)
167
167
 
168
168
  def close(self):
annet/implicit.py CHANGED
@@ -133,9 +133,9 @@ def _implicit_tree(device):
133
133
  no shutdown
134
134
  """
135
135
  elif device.hw.Cisco:
136
- # C2900/C3500/C3600 does not support the MTU on a per-interface basis
136
+ # C2900/C3500/C3600/AIR does not support the MTU on a per-interface basis
137
137
  if device.hw.Cisco.Catalyst.C2900 or device.hw.Cisco.Catalyst.C3500 \
138
- or device.hw.Cisco.Catalyst.C3600:
138
+ or device.hw.Cisco.Catalyst.C3600 or device.hw.Cisco.AIR:
139
139
  text += r"""
140
140
  !interface */\S*Ethernet\S+/
141
141
  no shutdown
annet/mesh/executor.py CHANGED
@@ -370,7 +370,7 @@ class MeshExecutor:
370
370
  device,
371
371
  direct_pair.device,
372
372
  direct_pair.ports,
373
- to_interface_changes(direct_pair.local),
373
+ to_interface_changes(direct_pair.local, direct_pair.connected),
374
374
  )
375
375
  peers.append(self._to_bgp_peer(direct_pair, target_interface))
376
376
 
@@ -378,7 +378,7 @@ class MeshExecutor:
378
378
  target_interface = self._apply_nondirect_interface_changes(
379
379
  device,
380
380
  getattr(virtual_pair.local, "ifname", None),
381
- to_interface_changes(virtual_pair.local),
381
+ to_interface_changes(virtual_pair.local, virtual_pair.connected),
382
382
  )
383
383
  peers.append(self._virtual_to_bgp_peer(virtual_pair, target_interface))
384
384
 
@@ -386,7 +386,7 @@ class MeshExecutor:
386
386
  target_interface = self._apply_nondirect_interface_changes(
387
387
  device,
388
388
  getattr(connected_pair.local, "ifname", None),
389
- to_interface_changes(connected_pair.local),
389
+ to_interface_changes(connected_pair.local, connected_pair.connected),
390
390
  )
391
391
  peers.append(self._to_bgp_peer(connected_pair, target_interface))
392
392
 
@@ -67,7 +67,17 @@ retort = Retort(
67
67
  )
68
68
 
69
69
  to_bgp_global_options = retort.get_loader(GlobalOptions)
70
- to_interface_changes = retort.get_loader(InterfaceChanges)
70
+
71
+
72
+ def to_interface_changes(local: LocalDTO, peer: PeerDTO) -> InterfaceChanges:
73
+ return InterfaceChanges(
74
+ addr=getattr(local, "addr", None),
75
+ lag_links_min=getattr(local, "lag_links_min", None),
76
+ svi=getattr(local, "svi", None),
77
+ subif=getattr(local, "subif", None),
78
+ vrf=getattr(peer, "vrf", None),
79
+ lag=getattr(local, "lag", None),
80
+ )
71
81
 
72
82
 
73
83
  def to_bgp_peer(local: LocalDTO, connected: PeerDTO, connected_hostname: str, interface: Optional[str]) -> Peer:
annet/mesh/peer_models.py CHANGED
@@ -17,6 +17,7 @@ class _SharedOptionsDTO(BaseMeshModel):
17
17
  send_community: bool
18
18
  bfd: bool
19
19
  bfd_timers: BFDTimers
20
+ password: str
20
21
 
21
22
 
22
23
  class MeshSession(_SharedOptionsDTO):
@@ -99,7 +99,7 @@ class DefaultRulebookProvider(RulebookProvider):
99
99
  return self._escaped_rul_cache[name]
100
100
  for root_dir in self.root_dir:
101
101
  try:
102
- with open(path.join(root_dir, "texts", name), "r") as f:
102
+ with open(path.join(root_dir, "texts", name), "r", encoding="utf-8") as f:
103
103
  self._escaped_rul_cache[name] = self._escape_mako(f.read())
104
104
  return self._escaped_rul_cache[name]
105
105
  except FileNotFoundError:
@@ -3,6 +3,72 @@ from annet.annlib.types import Op
3
3
  from annet.rulebook import common
4
4
 
5
5
 
6
+ def diff(old, new, diff_pre, _pops=(Op.AFFECTED,)):
7
+ for iface_row in old:
8
+ _filter_channel_members(old[iface_row])
9
+ for iface_row in new:
10
+ _filter_channel_members(new[iface_row])
11
+
12
+ ret = common.default_diff(old, new, diff_pre, _pops)
13
+ vpn_changed = False
14
+ for (op, cmd, _, _) in ret:
15
+ if op in {Op.ADDED, Op.REMOVED}:
16
+ vpn_changed |= is_vpn_cmd(cmd)
17
+ if vpn_changed:
18
+ for cmd in list(old.keys()):
19
+ if is_ip_cmd(cmd) and not is_vpn_cmd(cmd):
20
+ del old[cmd]
21
+ ret = common.default_diff(old, new, diff_pre, _pops)
22
+ return ret
23
+
24
+
25
+ # ===
26
+
27
+ # Вырезает все команды не разрешенные
28
+ # на членах агрегата. В running-config
29
+ # листинге они наследуются от самого port-channel
30
+
31
+
32
+ def _filter_channel_members(tree):
33
+ if any(is_in_channel(x) for x in tree):
34
+ for cmd in list(tree.keys()):
35
+ if not _is_allowed_on_channel(cmd):
36
+ del tree[cmd]
37
+
38
+
39
+ def is_in_channel(cmd_line):
40
+ """
41
+ Признак того, что это lagg member
42
+ """
43
+ return cmd_line.startswith("channel-group")
44
+
45
+
46
+ # Возможно тут есть еще какие-то команды
47
+ def _is_allowed_on_channel(cmd_line):
48
+ return cmd_line.startswith((
49
+ "channel-group",
50
+ "cdp",
51
+ "description",
52
+ "inherit",
53
+ "ip port",
54
+ "ipv6 port",
55
+ "mac port",
56
+ "lacp",
57
+ "switchport host",
58
+ "shutdown",
59
+ "rate-limit cpu",
60
+ "snmp trap link-status",
61
+ ))
62
+
63
+
64
+ def is_vpn_cmd(cmd):
65
+ return cmd.startswith("vrf member")
66
+
67
+
68
+ def is_ip_cmd(cmd):
69
+ return cmd.startswith(("ip ", "ipv6 "))
70
+
71
+
6
72
  def mtu(rule, key, diff, **kwargs):
7
73
  """
8
74
  Удаляем mtu без указания значения
@@ -28,25 +94,26 @@ def sflow(rule, key, diff, **kwargs):
28
94
  Команда sflow sampling-rate * direction ingress max-header-size *
29
95
  сносится без указания sampling-rate и max-header-size
30
96
  """
31
- result = common.default(rule, key, diff, **kwargs)
32
- for op, cmd, ch in result:
33
- if diff[Op.REMOVED]:
34
- if "ingress" in diff[Op.REMOVED][0]["row"]:
35
- yield (op, "no sflow sampling-rate direction ingress", ch)
36
- elif "egress" in diff[Op.REMOVED][0]["row"]:
37
- yield (op, "no sflow sampling-rate direction egress", ch)
38
- else:
39
- yield (op, cmd, ch)
40
- return result
97
+ if diff[Op.REMOVED]:
98
+ if "ingress" in diff[Op.REMOVED][0]["row"]:
99
+ yield (False, "no sflow sampling-rate direction ingress", None)
100
+ elif "egress" in diff[Op.REMOVED][0]["row"]:
101
+ yield (False, "no sflow sampling-rate direction egress", None)
102
+ else:
103
+ yield from common.default(rule, key, diff, **kwargs)
41
104
 
42
105
 
43
106
  def lldp(rule, key, diff, **kwargs):
44
107
  """
45
- Не удаляем все что начинается с set, т.к. set перезаписывает предыдущий конфиг
108
+ Обрабатываем блок lldp-agent
46
109
  """
47
110
  result = common.default(rule, key, diff, **kwargs)
48
111
  for op, cmd, ch in result:
112
+ # Не удаляем все что начинается с set, т.к. set перезаписывает предыдущий конфиг
49
113
  if diff[Op.REMOVED] and "set lldp" in cmd:
50
114
  pass
115
+ # В случае lldp tlv ... select удаляем все что до select
116
+ elif diff[Op.REMOVED] and cmd.endswith("select"):
117
+ yield (op, " ".join(cmd.split()[:-1]), ch)
51
118
  else:
52
119
  yield (op, cmd, ch)
@@ -23,7 +23,7 @@ def diff(old, new, diff_pre, _pops=(Op.AFFECTED,)):
23
23
 
24
24
 
25
25
  def is_vpn_cmd(cmd):
26
- return cmd.startswith("vrf member")
26
+ return cmd.startswith(("ip vrf forwarding", "vrf forwarding"))
27
27
 
28
28
 
29
29
  def is_ip_cmd(cmd):
File without changes
@@ -0,0 +1,14 @@
1
+ from annet.annlib.types import Op
2
+
3
+ from annet.rulebook import common
4
+
5
+
6
+ def remove_last_param(rule, key, diff, **_):
7
+ if diff[Op.REMOVED]:
8
+ for rem in diff[Op.REMOVED]:
9
+ # Обрабатывать удаление последнего параметра команды
10
+ cmd_parts = rem["row"].split(" ")
11
+ cmd_parts.remove(cmd_parts[len(cmd_parts) - 1])
12
+ yield False, "undo %s" % " ".join(cmd_parts), None
13
+ else:
14
+ yield from common.default(rule, key, diff)
@@ -14,13 +14,24 @@ def user(key, diff, **_):
14
14
  check_for_remove = False
15
15
  if check_for_remove:
16
16
  for rem in diff[Op.REMOVED]:
17
- # Обрабатывать удаление только пароля, если меняется что-то другое, можно просто накатить без удаления
17
+ # Обрабатывать удаление только пароля или привилегий, если меняется что-то другое, можно просто накатить без удаления
18
18
  if rem["row"].startswith("local-user %s password" % key[0]):
19
19
  yield (False, "undo local-user %s" % key[0], None)
20
20
  return
21
+ if (rem["row"].startswith("local-user %s privilege" % key[0])
22
+ and not _added_contains(diff[Op.ADDED], "local-user %s privilege" % key[0])):
23
+ yield (False, "undo local-user %s" % key[0], None)
24
+ return
21
25
  yield from added
22
26
 
23
27
 
28
+ def _added_contains(array: list[dict], lookup_string: str) -> bool:
29
+ for item in array:
30
+ if item["row"].startswith(lookup_string):
31
+ return True
32
+ return False
33
+
34
+
24
35
  def domain(rule, key, diff, **_):
25
36
  """
26
37
  При удалении метода для accounting|authorization|authentication
@@ -6,6 +6,10 @@
6
6
  # Фичи должны быть включены прежде всего
7
7
  feature
8
8
  # Далее нужно будет указать команды и их порядок
9
+ sflow
10
+ ip prefix-list
11
+ ipv6 prefix-list
12
+ route-map
9
13
  interface *
10
14
  description
11
15
  ip vrf forwarding
@@ -17,3 +21,4 @@ interface *
17
21
  dcbx
18
22
  exit
19
23
  sflow
24
+ ip community-list
@@ -11,16 +11,25 @@
11
11
  # Сделано в основном для того чтобы генерировать специальные команды для наливки
12
12
  # -----
13
13
  # Physical
14
- sflow *
15
-
16
- interface */(ce|xe|eth)[0-9\/]+$/ %logic=common.permanent %diff_logic=cisco.iface.diff
17
- description * %logic=b4com.iface.description
14
+ sflow
15
+ aaa group server tacacs\+ *
16
+ ~ %global
17
+ ip prefix-list *
18
+ ~ %global
19
+ ipv6 prefix-list *
20
+ ~ %global
21
+ route-map ~
22
+ ~ %global
23
+ interface */(ce|xe|po|eth|vlan1\.)[0-9\/]+$/ %logic=common.permanent %diff_logic=b4com.iface.diff
24
+ description
18
25
  ip vrf forwarding *
19
26
  ip address *
20
27
  ipv6 address *
21
- mtu * %logic=b4com.iface.mtu
28
+ ipv6 nd *
29
+ mtu
22
30
  sflow * %logic=b4com.iface.sflow
23
31
  lldp-agent
24
32
  ~ %global %logic=b4com.iface.lldp
25
33
  !dcbx *
26
34
  !exit
35
+ ip community-list ~
@@ -64,7 +64,6 @@ interface *
64
64
  encapsulation
65
65
  ip vrf forwarding
66
66
  vrf forwarding
67
- vrf member
68
67
  ip
69
68
  ipv6
70
69
  no ipv6 nd %order_reverse
@@ -40,34 +40,35 @@ snmp-server host ~
40
40
  # Disabling this SNMP option throws WARNING which stops mpdaemon set-up process
41
41
  no snmp-server sysobjectid type stack-oid
42
42
 
43
- !interface */(mgmt|ipmi|Vlan1$)/
44
-
45
- interface Loopback
46
- ipv6 address *
47
- ip address ~
48
- ! no ip address
49
-
50
43
  # SVI/Subifs/Lagg
51
- interface */(Vlan|Ethernet.*\.|port-channel.*\.?)\d+$/ %diff_logic=cisco.iface.diff
52
- vrf member
44
+ interface */(Loopback|vasileft|vasiright|Tunnel|BDI|multiservice|Virtual-Template|Vlan|\w*Ethernet.*\.|[Pp]ort-channel.*\.?)\d+/
45
+ ip vrf forwarding %diff_logic=cisco.iface.diff
46
+ vrf forwarding %diff_logic=cisco.iface.diff
47
+ ip address ~ %diff_logic=cisco.iface.diff
48
+ ip unnumbered * %diff_logic=cisco.iface.diff
49
+ ! no ip address
53
50
  ipv6 link-local
54
- ipv6 address *
51
+ ipv6 address ~ %diff_logic=cisco.iface.diff
52
+ ipv6 unnumbered * %diff_logic=cisco.iface.diff
53
+ ipv6 enable %diff_logic=cisco.iface.diff
55
54
  ipv6 nd ~ %logic=cisco.misc.no_ipv6_nd_suppress_ra
56
- ip address ~
57
- ! no ip address
58
55
  mtu
59
56
 
60
57
  # Physical
61
- interface */\w*Ethernet[0-9\/]+$/ %logic=common.permanent %diff_logic=cisco.iface.diff
58
+ interface */\w*Ethernet[0-9\/]+$/ %logic=common.permanent %diff_logic=cisco.iface.diff
62
59
  switchport mode
63
60
  switchport trunk native vlan
64
61
  switchport access vlan
65
62
  switchport trunk allowed vlan %logic=cisco.vlandb.swtrunk
66
- vrf member
67
- ipv6 link-local
68
- ipv6 address *
69
- ip address ~
63
+ ip vrf forwarding %diff_logic=cisco.iface.diff
64
+ vrf forwarding %diff_logic=cisco.iface.diff
65
+ ip address ~ %diff_logic=cisco.iface.diff
66
+ ip unnumbered * %diff_logic=cisco.iface.diff
70
67
  ! no ip address
68
+ ipv6 link-local
69
+ ipv6 address ~ %diff_logic=cisco.iface.diff
70
+ ipv6 unnumbered * %diff_logic=cisco.iface.diff
71
+ ipv6 enable %diff_logic=cisco.iface.diff
71
72
  channel-group
72
73
  mtu
73
74
  storm-control * level
@@ -105,6 +105,8 @@ system tcam acl
105
105
  local-user * privilege level
106
106
  dialog: Warning: This operation may affect online users, are you sure to change the user privilege level ?[Y/N] ::: Y
107
107
  dialog: Warning: This operation may affect online users and will change the user privilege level, Continue? [Y/N]: ::: Y
108
+ local-user * password
109
+ dialog: Warning: The user using this account will be logged out, and needs to log in again. Do you want to continue? [Y/N] ::: Y
108
110
 
109
111
  stp *
110
112
  dialog: Warning: The global STP state will be changed. Continue? [Y/N] ::: Y
@@ -185,4 +187,10 @@ force transceiver *
185
187
  undo force transceiver *
186
188
  dialog: /.*Continue\?/ ::: Y
187
189
 
190
+ undo local-aaa-user change-password verify
191
+ dialog: Warning: This command will disable the function of verifying the old password when administrators changes their own passwords. Continue?[Y/N] ::: Y
192
+
193
+ undo local-user ~
194
+ dialog: Warning: This operation may affect online users, are you sure to change the user privilege level ?[Y/N] ::: Y
195
+
188
196
  # vim: set syntax=annrulebook:
@@ -95,6 +95,7 @@ vlan
95
95
 
96
96
  hwtacacs-server
97
97
  hwtacacs server
98
+ radius-server
98
99
 
99
100
  aaa
100
101
  undo local-user policy security-enhance
@@ -112,6 +113,12 @@ aaa
112
113
 
113
114
  task-group
114
115
  user-group
116
+
117
+ #pin removal order to ensure that local-user will be deleted last
118
+ undo local-user * ftp-directory %order_reverse
119
+ undo local-user * privilege %order_reverse
120
+ undo local-user * level %order_reverse
121
+ undo local-user * %order_reverse
115
122
  ~
116
123
 
117
124
 
@@ -257,6 +264,9 @@ bgp
257
264
  peer * as-number *
258
265
  peer * enable
259
266
  peer * ~
267
+ l2vpn-ad-family
268
+ peer * enable
269
+ peer * ~
260
270
  # [NOCDEV-2043] Остальное в глобальном блоке делаем тут
261
271
  undo peer * description %order_reverse
262
272
  undo peer * * * %order_reverse
@@ -385,4 +395,8 @@ undo sflow %order_reverse
385
395
  # индекс референсится в логике патчинга префикс-листа huawei.misc.prefix_list
386
396
  undo ip */(ip|ipv6)/-prefix * index 99999999 %order_reverse
387
397
 
398
+ #remove template only after all references will be cleared
399
+ undo radius-server template %order_reverse
400
+ undo hwtacacs-server template %order_reverse
401
+
388
402
  ~
@@ -55,6 +55,11 @@ dhcp snooping user-bind http
55
55
 
56
56
  ntp server disable
57
57
  ntp ipv6 server disable
58
+ ntp unicast-server domain *
59
+ ntp unicast-server ipv6 *
60
+ ntp unicast-server *
61
+ ntp-service unicast-server ipv6 *
62
+ ntp-service unicast-server *
58
63
  ntp ~
59
64
  dns snooping ttl delay-time
60
65
  dns ~
@@ -175,13 +180,23 @@ aaa
175
180
  undo user-password complexity-check
176
181
  task-group *
177
182
  task *
178
- local-user * privilege level %diff_logic=huawei.aaa.local_user_diff
183
+ local-user * ftp-directory
184
+ local-user * privilege level %diff_logic=huawei.aaa.local_user_diff %logic=huawei.aaa.user
179
185
  local-user * level %diff_logic=huawei.aaa.local_user_diff
180
186
  local-user * %diff_logic=huawei.aaa.local_user_diff %logic=huawei.aaa.user
181
187
  */(accounting|authentication|authorization)/-scheme *
182
188
  */(accounting|authentication|authorization)/-mode
189
+
190
+ domain default
191
+ */(accounting|authentication|authorization)/-scheme * %logic=huawei.aaa.domain
192
+ !radius-server default
193
+ radius-server * %logic=generic.misc.remove_last_param
194
+ hwtacacs-server * %logic=generic.misc.remove_last_param
195
+
183
196
  domain *
184
197
  */(accounting|authentication|authorization)/-scheme * %logic=huawei.aaa.domain
198
+ radius-server * %logic=generic.misc.remove_last_param
199
+ hwtacacs-server * %logic=generic.misc.remove_last_param
185
200
  ~ %global
186
201
 
187
202
  hwtacacs-server template *
@@ -190,6 +205,8 @@ hwtacacs-server template *
190
205
  hwtacacs server template *
191
206
  hwtacacs server shared-key
192
207
 
208
+ !radius-server template default
209
+
193
210
  radius-server template *
194
211
  radius-server accounting * *
195
212
  radius-server authentication * *
@@ -18,6 +18,11 @@ system
18
18
  ntp
19
19
  server *
20
20
  source-address *
21
+ syslog
22
+ host *
23
+ match
24
+ file messages
25
+ match
21
26
 
22
27
  routing-options
23
28
  autonomous-system *
@@ -44,3 +44,6 @@ class B4ComVendor(AbstractVendor):
44
44
  @property
45
45
  def exit(self) -> str:
46
46
  return "exit"
47
+
48
+ def svi_name(self, num: int) -> str:
49
+ return f"vlan1.{num}"
@@ -14,7 +14,7 @@ class IosXrVendor(AbstractVendor):
14
14
 
15
15
  before.add_cmd(Command("configure exclusive"))
16
16
  if do_commit:
17
- after.add_cmd(Command("commit"))
17
+ after.add_cmd(Command("commit show-error"))
18
18
  after.add_cmd(Command("exit"))
19
19
 
20
20
  return before, after
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annet
3
- Version: 3.4.2
3
+ Version: 3.5.1
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -1,18 +1,18 @@
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=KarLH0TXfGvcT4lDHmh0mRF5Hfh-PpbIxeN6OBPLQOM,12432
4
+ annet/bgp_models.py,sha256=n29UBUbmeO7xdY0hyMi1VxkVmeSEZH8ZzYPfZmG3U7w,12502
5
5
  annet/cli.py,sha256=shq3hHzrTxFL3x1_zTOR43QHo0JYs8QSwyOvGtL86Co,12733
6
- annet/cli_args.py,sha256=jzMKRezWe_87k7VBNzgwPjWGMROJksbgrlX-GDd6oQs,13533
6
+ annet/cli_args.py,sha256=DMVBD4eC8zbaULpsu_B36ADNPBrZBHCw8r0ibNnx0No,13692
7
7
  annet/connectors.py,sha256=aoiDVLPizx8CW2p8SAwGCzyO_WW8H9xc2aujbGC4bDg,4882
8
- annet/deploy.py,sha256=JCcJ2hUmUsaOSrcxFuW8SlN0ubXSnHQ7H_nP_tx-PgE,7698
9
- annet/deploy_ui.py,sha256=KcP1g_c1HSA3n5qFxbGHd8t_arL4_xJV46PFO-7FLg8,28650
8
+ annet/deploy.py,sha256=ZTZcomYm2KJkKMyG6XzZaAMPr-Tduwcv67BhsoLARkY,7673
9
+ annet/deploy_ui.py,sha256=XsN1i7E9cNp1SAf1YBwhEBuwN91MvlNMSrLhnQrumA8,28672
10
10
  annet/diff.py,sha256=kD_2kxz5wc2TP10xj-BHs6IPq1yNKkXxIco8czjeC6M,9497
11
- annet/executor.py,sha256=lcKI-EbYqeCiBNpL729kSltduzxbAzOkQ1L_QK7tNv8,5112
11
+ annet/executor.py,sha256=INlWAZFLpHurg8GTXclbSzaeSIXgZo4ccmcRulQqr88,5130
12
12
  annet/filtering.py,sha256=ZtqxPsKdV9reZoRxtQyBg22BqyMqd-2SotYcxZ-68AQ,903
13
13
  annet/gen.py,sha256=j6SUrhEbfVQJrF2pOuWQaaBABwABk8cYzOln78jJ320,31956
14
14
  annet/hardware.py,sha256=e7RWc5yPdEDT5hxNqcqWv9g9DRWIgwAieA2iT4FdPqc,1158
15
- annet/implicit.py,sha256=G6EwZbrtUp089qRAwh96hminp236-1pJbeKAedoEafg,6056
15
+ annet/implicit.py,sha256=i6UxQAQESXWlIBohNuFQuSEgvdsydRzyBu1r7nrR2F4,6083
16
16
  annet/lib.py,sha256=4N4X6jCCrig5rk7Ua4AofrV9zK9jhzkBq57fLsfBJjw,4812
17
17
  annet/output.py,sha256=se8EpyNS9f9kPOlOaAV0ht4DjzDoBr8F2UafiezLPYw,7743
18
18
  annet/parallel.py,sha256=yM53RYaSpbIOUuBx4y07B_3jW8J-w3taiZWjcq_1r6A,17397
@@ -34,7 +34,7 @@ annet/adapters/netbox/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
34
34
  annet/adapters/netbox/common/adapter.py,sha256=-YcO3371D8hupNXKf5f4-FdFSjTto-7VKDvz29Gid38,2016
35
35
  annet/adapters/netbox/common/client.py,sha256=PaxHG4W9H8_uunIwMBNYkLq4eQJYoO6p6gY-ciQs7Nc,2563
36
36
  annet/adapters/netbox/common/manufacturer.py,sha256=n1RxJSGqXilKcGSqwIc7d2jD1NCaUXG5kQcOO93WTxw,1319
37
- annet/adapters/netbox/common/models.py,sha256=PK4a8YBSp6mNe1V7oI2rILbVL9QnsRRIJQ4YN6aIz0w,7899
37
+ annet/adapters/netbox/common/models.py,sha256=SrzUmeqjdOkeb5og-pR0d6aNHeYC3C7LHbeZAvcZ0d8,7997
38
38
  annet/adapters/netbox/common/query.py,sha256=kbNQSZwkjFeDArHwA8INHUauxCxYElXtNh58pZipWdo,1867
39
39
  annet/adapters/netbox/common/status_client.py,sha256=POaqiQJ0jPcqUQH-X_fWHVnKB7TBYveNriaT0eNTlfI,769
40
40
  annet/adapters/netbox/common/storage_base.py,sha256=3dn42CWTEZVBig4ABhy5BMQQ3YGb28InncWZoGvrgKk,8768
@@ -52,7 +52,7 @@ annet/adapters/netbox/v42/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
52
52
  annet/adapters/netbox/v42/models.py,sha256=UWrnRh1k3a048XsVmqh50dF91dunrolIJzmTLT0QExw,1920
53
53
  annet/adapters/netbox/v42/storage.py,sha256=iMhdrdAAYZXS_VHoqi_5azFB3BVmp4daK4TVCI9vhxM,4666
54
54
  annet/annlib/__init__.py,sha256=fT1l4xV5fqqg8HPw9HqmZVN2qwS8i6X1aIm2zGDjxKY,252
55
- annet/annlib/command.py,sha256=uuBddMQphtn8P5MO5kzIa8_QrtMns-k05VeKv1bcAuA,1043
55
+ annet/annlib/command.py,sha256=SUoMAmzo7AurMWyAiJNETdcHiwyGQe1YG9f7ZCc1gWQ,1166
56
56
  annet/annlib/diff.py,sha256=MZ6eQAU3cadQp8KaSE6uAYFtcfMDCIe_eNuVROnYkCk,4496
57
57
  annet/annlib/errors.py,sha256=jBcSFzY6Vj-FxR__vqjFm-87AwYQ0xHuAopTirii5AU,287
58
58
  annet/annlib/filter_acl.py,sha256=ZJvNpSwE5MzJS_sKLenQpZgTuM-IrngwcbukQRq90do,7195
@@ -75,7 +75,7 @@ annet/annlib/rbparser/ordering.py,sha256=XknggB92N4IbhHBZZHL0StwCCITt8mkho4D4Nu5
75
75
  annet/annlib/rbparser/platform.py,sha256=d1jFH8hGMOf_qiveKE4H-c0OfNnzwmt2VYpSiSOn9qc,42
76
76
  annet/annlib/rbparser/syntax.py,sha256=PlKyWqS3zwPwumILmKIci-DmEAbfZp8YycpW1mNqADM,3602
77
77
  annet/annlib/rulebook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
- annet/annlib/rulebook/common.py,sha256=2ZMu7Z47Ip7d8yMjihDNKKhwl9aV5U4IeCcyXM4CjeA,13527
78
+ annet/annlib/rulebook/common.py,sha256=6A3sOkOanDRTuR7F426zakShGaGKRBmBLDCnqBbBJr8,13531
79
79
  annet/api/__init__.py,sha256=-VLQ-Uf2WSdNHXirzdMjgaY8UzrXbGpPHmUnwzB_5YI,33763
80
80
  annet/configs/context.yml,sha256=RVLrKLIHpCty7AGwOnmqf7Uu0iZQCn-AjYhophDJer8,259
81
81
  annet/configs/logging.yaml,sha256=EUagfir99QqA73Scc3k7sfQccbU3E1SvEQdyhLFtCl4,997
@@ -93,10 +93,10 @@ annet/generators/common/initial.py,sha256=qYBxXFhyOPy34cxc6hsIXseod-lYCmmbuNHpM0
93
93
  annet/mesh/__init__.py,sha256=lcgdnBIxc2MAN7Er1bcErEKPqrjWO4uIp_1FldMXTYg,557
94
94
  annet/mesh/basemodel.py,sha256=E6NTOneiMDwB1NCpjDRECoaeQ0f3n_fmTLnKTrSHTU4,4917
95
95
  annet/mesh/device_models.py,sha256=Vt9yOYBn3b67_Lz0-xnwe4QP-0gCDkX2XvhaZ1JizOM,4710
96
- annet/mesh/executor.py,sha256=rw_xr01kkcTn3U_s4ozGxRfCNdO4Mgg5kqmrAA-ySdE,17162
96
+ annet/mesh/executor.py,sha256=U-3LlAkd34SUD-xZK2K0KaQNy0b2xnVGFkTWlftJXWs,17235
97
97
  annet/mesh/match_args.py,sha256=CR3kdIV9NGtyk9E2JbcOQ3TRuYEryTWP3m2yCo2VCWg,5751
98
- annet/mesh/models_converter.py,sha256=qTd-411215LBOsGHGBbYcmben58HdV4BRkMmspd5FgY,3238
99
- annet/mesh/peer_models.py,sha256=Ta0q3MwECz_zzHISbKKvbrGyVXi2Kdg5ZwpbZr8qqJA,2730
98
+ annet/mesh/models_converter.py,sha256=nCtzFR3s65MVkCE_xJm1Ci5c2hUwsr6ajfBiSmy3r_8,3565
99
+ annet/mesh/peer_models.py,sha256=otemIgQCOpUy4kJ5pu5t_H1tjTSv6DoabEqBkUx7hWM,2748
100
100
  annet/mesh/port_processor.py,sha256=RHiMS5W8qoDkTKiarQ748bcr8bNx4g_R4Y4vZg2k4TU,478
101
101
  annet/mesh/registry.py,sha256=xmWF7yxWXmwqX2_jyMAKrbGd2G9sjb4rYDx4Xk61QKc,9607
102
102
  annet/rpl/__init__.py,sha256=8nSiFpXH4OhzRGKr-013nHwwKk5Y50uh2gL7d_IoV8U,757
@@ -116,7 +116,7 @@ annet/rpl_generators/execute.py,sha256=wS6e6fwcPWywsHB0gBMqZ17eF0s4YOBgDgwPB_cr5
116
116
  annet/rpl_generators/policy.py,sha256=W_wlw37CIIqkdl_Og7c9-RxS55ojosLGHVEgTs80M6U,52348
117
117
  annet/rpl_generators/prefix_lists.py,sha256=sxTPeOJufwogguuhjjMbrGSgW3wm2HNboX9tN3qLitU,6910
118
118
  annet/rpl_generators/rd.py,sha256=-l0Dy-t1lIFCLLIzRb_okwU1jxr_kNEds92FyoVS7qs,1999
119
- annet/rulebook/__init__.py,sha256=Zm2RycKvIa-x-FwvaLSdJEV3t-V1QhsnjjkQ5dB7SzI,3979
119
+ annet/rulebook/__init__.py,sha256=AmcqrLYaoU1-sO2vmtjWZbzsZ44_w7nXncoEVa_hpyk,3997
120
120
  annet/rulebook/common.py,sha256=zK1s2c5lc5HQbIlMUQ4HARQudXSgOYiZ_Sxc2I_tHqg,721
121
121
  annet/rulebook/deploying.py,sha256=9CMeOUw5L1OWdrccSRfpJyH9H_jH7xWNU1JldviBNrk,3015
122
122
  annet/rulebook/patching.py,sha256=7iZvtjR7T8_bK6mCsGlC5uPmntCDQ9OkkDHRWupnMNA,5045
@@ -128,13 +128,15 @@ annet/rulebook/aruba/ap_env.py,sha256=5fUVLhXH4-0DAtv8t0yoqJUibaRMuzF8Q7mGFzNsEN
128
128
  annet/rulebook/aruba/misc.py,sha256=O0p_wsR07gtB8rm1eJvJ7VYnGm5T8Uau_SVKR9FVInI,234
129
129
  annet/rulebook/b4com/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
130
  annet/rulebook/b4com/file.py,sha256=zK7RwBk1YaVoDSFSg1u7Pt8u0Fk3nhhu27aJRngemwc,137
131
- annet/rulebook/b4com/iface.py,sha256=FGOYeeL3ZcogT8bDrmMYPG0KiZ5Q7iz5R19e1zrE0P8,1683
131
+ annet/rulebook/b4com/iface.py,sha256=g_QKRT2urqcMgnQeNYT2W2kdT49740qs2x8ss0JSdyc,3565
132
132
  annet/rulebook/cisco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
133
- annet/rulebook/cisco/iface.py,sha256=WISkzjp_G7WKPpg098FCIm4b7ipOxtRLOQbu-7gMUL0,1792
133
+ annet/rulebook/cisco/iface.py,sha256=9urjx0obUdS_HULilQLkGZfiP-U_PZ_k6WWt_xRB2dU,1819
134
134
  annet/rulebook/cisco/misc.py,sha256=zgKdWGmjRYmvq58dh7Lbn7ofwSYZoISgXsUh5lkGKF8,2318
135
135
  annet/rulebook/cisco/vlandb.py,sha256=pdQ0Ca976_5_cNBbTI6ADN1SP8aAngVBs1AZWltmpsw,3319
136
+ annet/rulebook/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
+ annet/rulebook/generic/misc.py,sha256=dp8mWMN0v4dkvGjthXvIwvyBNSag_3HruTyhRV7E8sA,519
136
138
  annet/rulebook/huawei/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
- annet/rulebook/huawei/aaa.py,sha256=Xi8nWyBFaUz4SgoN1NQeOcXzBGCfINQDNiC-crq08uA,3445
139
+ annet/rulebook/huawei/aaa.py,sha256=RyFwnfp7I2Y3Kizc2f3SXSzBm6UbhaHE6TtisBeuD68,3919
138
140
  annet/rulebook/huawei/bgp.py,sha256=dN8T3-44ggGEapt4u4sT3bTn_dsoCbS5qdNeSQ8LSTs,4015
139
141
  annet/rulebook/huawei/iface.py,sha256=DvLtQ7tfbDQWFmIYV4lxfih13Tdrt24L4-ZS29mCkuc,1126
140
142
  annet/rulebook/huawei/misc.py,sha256=Rpwhtm42IgcueDq4K6VOzN2qORoIDYh42Jb7iWL8AII,14424
@@ -151,19 +153,19 @@ annet/rulebook/texts/aruba.deploy,sha256=hI432Bq-of_LMXuUflCu7eNSEFpx6qmj0KItEw6
151
153
  annet/rulebook/texts/aruba.order,sha256=ZMakkn0EJ9zomgY6VssoptJImrHrUmYnCqivzLBFTRo,1158
152
154
  annet/rulebook/texts/aruba.rul,sha256=zvGVpoYyJvMoL0fb1NQ8we_GCLZXno8nwWpZIOScLQQ,2584
153
155
  annet/rulebook/texts/b4com.deploy,sha256=SVX8-yLHM90tJC4M-ekpGuGM1aQZW3euSGyg67l--R0,781
154
- annet/rulebook/texts/b4com.order,sha256=nzPSPpq8f6WnVazOekJUEgt7ueEtf3Ietdl1m1X2qF8,867
155
- annet/rulebook/texts/b4com.rul,sha256=JhnaGx6Hc7sEMUGgFyru2PfmTNgFhcF-lgckopMMSP8,1334
156
+ annet/rulebook/texts/b4com.order,sha256=k_9qPnc3olAUTrAeefLwe91rUK9hYgkp8hFl9LRU0V0,932
157
+ annet/rulebook/texts/b4com.rul,sha256=G64FljT5wjCVpejbNmCebfCSGo-YIUrlHrpcn3GdXHc,1409
156
158
  annet/rulebook/texts/cisco.deploy,sha256=Hu0NkcGv3f1CWUrnbzI3eQOPXJxtH4NNOPRV68IrW4U,1226
157
- annet/rulebook/texts/cisco.order,sha256=ecwktxyY2_W63oqv2aqVhvfViuia42fZb-2uLP0Efg8,1942
158
- annet/rulebook/texts/cisco.rul,sha256=jgL5_xnSwd_H4E8cx4gcneSvJC5W1zz6_BWSb64iuxI,3017
159
- annet/rulebook/texts/huawei.deploy,sha256=uUsZCHUrC5Zyb_MePrR5svnE1QyGQlg7UxcKf00sJyg,10451
160
- annet/rulebook/texts/huawei.order,sha256=_X2LmxD9FGcIcb8ziwc13Imy1tBtQJgafrQGmvHPZLM,10649
161
- annet/rulebook/texts/huawei.rul,sha256=02Fi1RG4YYea2clHCluBuJDKNbT0hS9jtsk6_h6GK8k,12958
159
+ annet/rulebook/texts/cisco.order,sha256=DarNICBBAEXR8VOFV8SNnuQmwGAG-TGwXlMWpFMTCDE,1927
160
+ annet/rulebook/texts/cisco.rul,sha256=DLve1CQYto-cn-sojGl4qBaWQnCyn3W1qYmPuTxSfqU,3627
161
+ annet/rulebook/texts/huawei.deploy,sha256=5vrvhai2BjaJ793A3EHHCthic3dnGKp2_rAgViVIouI,10951
162
+ annet/rulebook/texts/huawei.order,sha256=XuIaP2CpgxR0v8sIniY9DjVE_LR71tLBRENNjdQvCoY,11119
163
+ annet/rulebook/texts/huawei.rul,sha256=-O597iFqiYpuo3yrfvIUbE0IulabStqGkBS-Drl3KrE,13574
162
164
  annet/rulebook/texts/iosxr.deploy,sha256=Hu0NkcGv3f1CWUrnbzI3eQOPXJxtH4NNOPRV68IrW4U,1226
163
165
  annet/rulebook/texts/iosxr.order,sha256=gUp6XHwzqkDsArCUAwtx3rR1qlGfYsHy2vP9oZN2oDk,1922
164
166
  annet/rulebook/texts/iosxr.rul,sha256=MhIoIbOrfqisbyprZLy86DvO4rl6LtPESFnDU9nQUY0,2974
165
167
  annet/rulebook/texts/juniper.order,sha256=PpxmcCgeaeP3TyYe3BWvtb24MKYV_BujjCH3HD4lsc8,256
166
- annet/rulebook/texts/juniper.rul,sha256=EmtrEJZesnmc2nXjURRD2G0WOq4zLluI_PNupKhSOJs,2654
168
+ annet/rulebook/texts/juniper.rul,sha256=yo5hUt6XuxagquHHLD9zUw0YX-T2eo0CecryDRn4IW0,2738
167
169
  annet/rulebook/texts/nexus.deploy,sha256=9YNAQEw7aQxtYZJbE-dMD6qJrTzs_G92Ifrx3Ft4Wn4,1120
168
170
  annet/rulebook/texts/nexus.order,sha256=AZMKCD5Zf_mBOlE36aMDvO4w5rdbepTz1Dsyv7xP9Qs,1834
169
171
  annet/rulebook/texts/nexus.rul,sha256=veixbi_ztbX6OMV_WjdkgpEXa47yDxOkPE0YQ6r4wqs,2558
@@ -185,11 +187,11 @@ annet/vendors/tabparser.py,sha256=9AsBUY89YQstbLk2eia-NmuVXaJOG1fd2bIVcI5L43M,31
185
187
  annet/vendors/library/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
186
188
  annet/vendors/library/arista.py,sha256=J4ltZ7sS_TgIECg2U7fizvxwfS4-s35Of0tNDNWWYbE,1302
187
189
  annet/vendors/library/aruba.py,sha256=tvrSFSA43n0uelCv-NLQnqxO01d0y2mrfhncpOX7zoQ,1257
188
- annet/vendors/library/b4com.py,sha256=fX9Rh_yUrZY0imuPdI4RBxEwmVlW_FkoKXebYSqF7Wk,1390
190
+ annet/vendors/library/b4com.py,sha256=EABOc-w8XqFGI0hcGU5JjCfXAf9v_Uf4MVdFT5gLZ7Q,1462
189
191
  annet/vendors/library/cisco.py,sha256=3-hWdMaQPnUVFJzKX4gNwIIoGxrSqrGrrE0p7QvedyU,1176
190
192
  annet/vendors/library/h3c.py,sha256=QOO670R-r9Ge_5T7a7b5FajA4j0HcqJKCCsn4ctbcxc,1045
191
193
  annet/vendors/library/huawei.py,sha256=79RINBbuob8KJXQvULbEGVVaGhn3-LzCYuqWQ847eds,1261
192
- annet/vendors/library/iosxr.py,sha256=f_i09WH3TfOKrQ0RpnzeJD30eNoVQIwrJyhi-DyeoOM,1174
194
+ annet/vendors/library/iosxr.py,sha256=0eFPbiE0jry_IATDxK3-UsPPMkK2gs9-avR51v2HAWw,1185
193
195
  annet/vendors/library/juniper.py,sha256=BDljknxDJ0JxEXb3HCbZSC38BuA7OF5mtcQLLftXx_o,1289
194
196
  annet/vendors/library/nexus.py,sha256=naTtiaFzNt1YZmxUSR9UCa-z766r1oav0tPXinA2tho,1118
195
197
  annet/vendors/library/nokia.py,sha256=RhynYZpti5ftud88vaphLAA3ZrCEKdR8BESXWlUZIH8,1152
@@ -197,8 +199,8 @@ annet/vendors/library/optixtrans.py,sha256=VdME69Ca4HAEgoaKN21fZxnmmsqqaxOe_HZja
197
199
  annet/vendors/library/pc.py,sha256=vfv31_NPi7M-4AUDL89UcpawK2E6xvCpELA209cd1ho,1086
198
200
  annet/vendors/library/ribbon.py,sha256=DDOBq-_-FL9dCxqXs2inEWZ-pvw-dJ-A-prA7cKMhec,1216
199
201
  annet/vendors/library/routeros.py,sha256=iQa7m_4wjuvcgBOI9gyZwlw1BvzJfOkvUbyoEk-NI9I,1254
200
- annet-3.4.2.dist-info/licenses/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
201
- annet-3.4.2.dist-info/licenses/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
202
+ annet-3.5.1.dist-info/licenses/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
203
+ annet-3.5.1.dist-info/licenses/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
202
204
  annet_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
203
205
  annet_generators/example/__init__.py,sha256=OJ77uj8axc-FIyIu_Xdcnzmde3oQW5mk5qbODkhuVc8,355
204
206
  annet_generators/example/hostname.py,sha256=RloLzNVetEoWPLITzfJ13Nk3CC0yi-cZB1RTd6dnuhI,2541
@@ -211,8 +213,8 @@ annet_generators/rpl_example/generator.py,sha256=EWah19gOH8G-QyNyWqxCqdRi0BK7GbM
211
213
  annet_generators/rpl_example/items.py,sha256=HPgxScDvSqJPdz0c2SppDrH82DZYC4zUaniQwcWmh4A,1176
212
214
  annet_generators/rpl_example/mesh.py,sha256=z_WgfDZZ4xnyh3cSf75igyH09hGvtexEVwy1gCD_DzA,288
213
215
  annet_generators/rpl_example/route_policy.py,sha256=z6nPb0VDeQtKD1NIg9sFvmUxBD5tVs2frfNIuKdM-5c,2318
214
- annet-3.4.2.dist-info/METADATA,sha256=bLeca3jp_YNTggKhc9n3N4rJuqXXgls45oww9mR_kJ8,815
215
- annet-3.4.2.dist-info/WHEEL,sha256=ooBFpIzZCPdw3uqIQsOo4qqbA4ZRPxHnOH7peeONza0,91
216
- annet-3.4.2.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
217
- annet-3.4.2.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
218
- annet-3.4.2.dist-info/RECORD,,
216
+ annet-3.5.1.dist-info/METADATA,sha256=FzDUT_CYHtfBoKd7gyzhTmLsWcbRxt10zyZuFGRYI9g,815
217
+ annet-3.5.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
218
+ annet-3.5.1.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
219
+ annet-3.5.1.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
220
+ annet-3.5.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.0.1)
2
+ Generator: setuptools (80.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5