sc-napalm 1.0.0__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.
- custom_napalm/__init__.py +30 -0
- custom_napalm/base.py +113 -0
- custom_napalm/eos/__init__.py +1 -0
- custom_napalm/eos/eos.py +93 -0
- custom_napalm/get.py +83 -0
- custom_napalm/iosxr/__init__.py +1 -0
- custom_napalm/iosxr/constants.py +144 -0
- custom_napalm/iosxr/iosxr.py +55 -0
- custom_napalm/junos/__init__.py +1 -0
- custom_napalm/junos/junos.py +223 -0
- custom_napalm/junos/junos_views.py +17 -0
- custom_napalm/junos/junos_views.yml +228 -0
- custom_napalm/models.py +27 -0
- custom_napalm/nos/__init__.py +1 -0
- custom_napalm/nos/constants.py +111 -0
- custom_napalm/nos/nos.py +230 -0
- custom_napalm/nxos/__init__.py +1 -0
- custom_napalm/nxos/nxos.py +88 -0
- custom_napalm/nxos/utils/textfsm_templates/sh_int_transceiver.tpl +27 -0
- custom_napalm/nxos/utils/textfsm_templates/sh_inventory.tpl +8 -0
- custom_napalm/srl/__init__.py +1 -0
- custom_napalm/srl/srl.py +160 -0
- custom_napalm/srl_ssh/__init__.py +1 -0
- custom_napalm/srl_ssh/srl_ssh.py +45 -0
- custom_napalm/sros/__init__.py +1 -0
- custom_napalm/sros/nc_filters.py +18 -0
- custom_napalm/sros/sros.py +59 -0
- custom_napalm/utils.py +74 -0
- sc_napalm-1.0.0.dist-info/METADATA +106 -0
- sc_napalm-1.0.0.dist-info/RECORD +32 -0
- sc_napalm-1.0.0.dist-info/WHEEL +4 -0
- sc_napalm-1.0.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# # pylint: disable=no-member
|
|
2
|
+
from typing import List
|
|
3
|
+
import re
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
from napalm.junos import JunOSDriver
|
|
7
|
+
from napalm.base.models import LLDPNeighborDict, ConfigDict
|
|
8
|
+
from ..models import InventoryDict
|
|
9
|
+
from ..base import SCBaseNetconfDriver
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from . import junos_views
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
XCVR_DESC_TO_INTERFACE_PREFIX = {
|
|
17
|
+
r"100GBASE-": "et-",
|
|
18
|
+
r"QSFP": "et-",
|
|
19
|
+
r"SFP28": "et-",
|
|
20
|
+
r"SFP\+": "xe-",
|
|
21
|
+
r"SFP-": "ge-",
|
|
22
|
+
r"CFP-": "et-",
|
|
23
|
+
r"(UNKNOWN|UNSUPPORTED)": "ge-", # default
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
DEFAULT_ARP_AGING_TIMER = 1200
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class SCJunOS(JunOSDriver, SCBaseNetconfDriver):
|
|
30
|
+
"""
|
|
31
|
+
Junos parser
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
netmiko_host_type = "juniper_junos"
|
|
35
|
+
|
|
36
|
+
# mapping of inventory name regex to their netbox types
|
|
37
|
+
INVENTORY_TO_TYPE = {
|
|
38
|
+
r"Fan Tray": "fan",
|
|
39
|
+
r"(PIC|MIC|FPC)": "linecard",
|
|
40
|
+
r"Xcvr": "optic",
|
|
41
|
+
r"(PEM|Power Supply)": "psu",
|
|
42
|
+
r"Routing Engine": "re",
|
|
43
|
+
# don't care about these inventory items
|
|
44
|
+
r"(CPU|PDM|FPM|Midplane|CB|SFB|TIB)": None,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
def _get_junos_inventory_type(self, name: str, model_number: str) -> str:
|
|
48
|
+
"""
|
|
49
|
+
Maps the name and part number of the Junos inventory item to its type
|
|
50
|
+
"""
|
|
51
|
+
# "Xcvr" parts are always optics
|
|
52
|
+
if name.startswith("Xcvr"):
|
|
53
|
+
return "optic"
|
|
54
|
+
|
|
55
|
+
# non-optic parts should always have a model number, if not
|
|
56
|
+
# we don't care about them
|
|
57
|
+
if not (model_number):
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
# EX switches and virtual chassis save their vc members and uplink modules
|
|
61
|
+
# as FPC X and PIC X - we want to classify those correctly
|
|
62
|
+
if re.match(r"EX[234]", model_number):
|
|
63
|
+
if re.search(r"FPC \d+", name):
|
|
64
|
+
return "stack-member"
|
|
65
|
+
|
|
66
|
+
if re.search(r"PIC \d+", name):
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
# uplink modules are also saved under PIC X, must classify based
|
|
70
|
+
# on their model number
|
|
71
|
+
if re.match(r"EX-UM", model_number):
|
|
72
|
+
return "uplink-module"
|
|
73
|
+
|
|
74
|
+
# otherwise we want to pattern-match based on the INVENTORY_TO_TYPE
|
|
75
|
+
# dictionary
|
|
76
|
+
return self._get_inventory_type(name)
|
|
77
|
+
|
|
78
|
+
def _get_xcvr_interface_prefix(self, xcvr_desc: str) -> str:
|
|
79
|
+
"""
|
|
80
|
+
Maps xcvr description from "show chassis hardware" to
|
|
81
|
+
interface prefix
|
|
82
|
+
"""
|
|
83
|
+
for pattern, prefix in XCVR_DESC_TO_INTERFACE_PREFIX.items():
|
|
84
|
+
if re.match(pattern, xcvr_desc):
|
|
85
|
+
return prefix
|
|
86
|
+
|
|
87
|
+
raise ValueError(f"{self.hostname}: Unknown xcvr type {xcvr_desc}")
|
|
88
|
+
|
|
89
|
+
def _get_mod_number(self, mod_name: str) -> str:
|
|
90
|
+
"""
|
|
91
|
+
Strips out "FPC|MIC|PIC" from a module name seen in "show chassis hardware"
|
|
92
|
+
"""
|
|
93
|
+
return re.sub(r"(MIC|PIC|FPC) ", "", mod_name)
|
|
94
|
+
|
|
95
|
+
def _get_inventory_part_number(self, item: any) -> str:
|
|
96
|
+
"""
|
|
97
|
+
Extracts the part number from an inventory item
|
|
98
|
+
which, depending on the specific item, is stashed in
|
|
99
|
+
the part number, model number, or description field
|
|
100
|
+
"""
|
|
101
|
+
if item.model_number and item.model_number != "model-number":
|
|
102
|
+
return item.model_number
|
|
103
|
+
return item.part_number
|
|
104
|
+
|
|
105
|
+
def _save_inventory_item(
|
|
106
|
+
self, output: list, item: any, parent: str = None, grandparent: str = None
|
|
107
|
+
) -> bool:
|
|
108
|
+
"""
|
|
109
|
+
Extracts data from a particular inventory item object.
|
|
110
|
+
Returns whether we care aobut this item or not (so we know whether or not)
|
|
111
|
+
to loop over its children
|
|
112
|
+
"""
|
|
113
|
+
# skip builtin types, or parts without model numbers that aren't transcievers
|
|
114
|
+
if item.part_number == "BUILTIN":
|
|
115
|
+
return False
|
|
116
|
+
|
|
117
|
+
# get inventory type based on item name and P/N
|
|
118
|
+
inv_type = self._get_junos_inventory_type(item.name, item.model_number)
|
|
119
|
+
|
|
120
|
+
if not inv_type:
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
# for transcievers, change the name from Xcvr X to be the junos interface name
|
|
124
|
+
# note that we expect transcievers to always be at the sub-sub module level
|
|
125
|
+
# and thus to have a grandparent and parent
|
|
126
|
+
m = re.search(r"Xcvr (\d+)", item.name)
|
|
127
|
+
if m:
|
|
128
|
+
if not (grandparent or parent):
|
|
129
|
+
raise ValueError(
|
|
130
|
+
f"{self.hostname}: No MIC and PIC found for {item.name}"
|
|
131
|
+
)
|
|
132
|
+
prefix = self._get_xcvr_interface_prefix(item.description)
|
|
133
|
+
|
|
134
|
+
item_name = f"{prefix}{self._get_mod_number(grandparent)}/{self._get_mod_number(parent)}/{m.group(1)}"
|
|
135
|
+
|
|
136
|
+
# for sub-linecards (mics or pics) we want to prepend the parent to the item name
|
|
137
|
+
elif parent:
|
|
138
|
+
item_name = f"{parent} {item.name}"
|
|
139
|
+
else:
|
|
140
|
+
item_name = item.name
|
|
141
|
+
|
|
142
|
+
output.append(
|
|
143
|
+
{
|
|
144
|
+
"type": inv_type,
|
|
145
|
+
"name": item_name,
|
|
146
|
+
"subtype": item.description,
|
|
147
|
+
"part_number": self._get_inventory_part_number(item),
|
|
148
|
+
"serial_number": item.serial_number,
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
return True
|
|
153
|
+
|
|
154
|
+
def get_config(
|
|
155
|
+
self, retrieve="all", full=False, sanitized=False, format="text"
|
|
156
|
+
) -> ConfigDict:
|
|
157
|
+
"""
|
|
158
|
+
pulling running config via ssh sow we can have it in 'display set' format.
|
|
159
|
+
"""
|
|
160
|
+
if format != "text":
|
|
161
|
+
return super().get_config(
|
|
162
|
+
retrieve=retrieve, full=full, sanitized=sanitized, format=format
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
config = {"startup": "", "running": "", "candidate": ""}
|
|
166
|
+
|
|
167
|
+
with self.ssh_conn() as ssh_device:
|
|
168
|
+
config["running"] = ssh_device.send_command(
|
|
169
|
+
"show configuration | display set"
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
return config
|
|
173
|
+
|
|
174
|
+
def get_lldp_neighbors(self) -> LLDPNeighborDict:
|
|
175
|
+
"""
|
|
176
|
+
Overrides napalm get_lldp_neighbors so that we actually get the remote
|
|
177
|
+
interface ID instead of the description.
|
|
178
|
+
|
|
179
|
+
NAPALM's get_lldp_neighbors_detail gets this for us - note that to get this detail,
|
|
180
|
+
you need to execute a command for each interface just like on the cli :(
|
|
181
|
+
"""
|
|
182
|
+
neighs = super().get_lldp_neighbors_detail()
|
|
183
|
+
output = {}
|
|
184
|
+
for port, neighs in neighs.items():
|
|
185
|
+
output[port] = []
|
|
186
|
+
for neigh in neighs:
|
|
187
|
+
output[port].append(
|
|
188
|
+
{
|
|
189
|
+
"hostname": neigh["remote_system_name"]
|
|
190
|
+
if neigh["remote_system_name"]
|
|
191
|
+
else neigh["remote_chassis_id"],
|
|
192
|
+
"port": neigh["remote_port"],
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
return output
|
|
196
|
+
|
|
197
|
+
def get_inventory(self) -> List[InventoryDict]:
|
|
198
|
+
"""
|
|
199
|
+
parses the get-chassis-inventory RPC call, which maps to "show chassis hardware"
|
|
200
|
+
"""
|
|
201
|
+
result = junos_views.junos_inventory(self.device).get()
|
|
202
|
+
|
|
203
|
+
output = []
|
|
204
|
+
for chassis in dict(result).values():
|
|
205
|
+
# note that the chassis model and s/n are at this level, but
|
|
206
|
+
# that doesn't count as an 'inventory item' so we're ignoring it
|
|
207
|
+
|
|
208
|
+
# saving modules, sub-modules and sub-sub modules
|
|
209
|
+
for module in dict(chassis.modules).values():
|
|
210
|
+
self._save_inventory_item(output, module)
|
|
211
|
+
|
|
212
|
+
for sub_module in dict(module.sub_modules).values():
|
|
213
|
+
self._save_inventory_item(output, sub_module, parent=module.name)
|
|
214
|
+
|
|
215
|
+
for sub_sub_module in dict(sub_module.sub_sub_modules).values():
|
|
216
|
+
self._save_inventory_item(
|
|
217
|
+
output,
|
|
218
|
+
sub_sub_module,
|
|
219
|
+
parent=sub_module.name,
|
|
220
|
+
grandparent=module.name,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
return output
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## https://www.juniper.net/documentation/us/en/software/junos-pyez/junos-pyez-developer/topics/task/junos-pyez-tables-views-loading.html
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Load tables/views
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from os.path import splitext
|
|
8
|
+
import yaml
|
|
9
|
+
from jnpr.junos.factory import FactoryLoader
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
_YAML_ = splitext(__file__)[0] + ".yml"
|
|
13
|
+
|
|
14
|
+
with open(_YAML_, encoding="utf-8") as f:
|
|
15
|
+
yaml_str = f.read()
|
|
16
|
+
|
|
17
|
+
globals().update(FactoryLoader().load(yaml.safe_load(yaml_str)))
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
### ip interfaces ###
|
|
2
|
+
junos_ip_interfaces:
|
|
3
|
+
rpc: get-interface-information
|
|
4
|
+
item: physical-interface/logical-interface/address-family/interface-address
|
|
5
|
+
key: ifa-local
|
|
6
|
+
view: junos_ip_interfaces_view
|
|
7
|
+
|
|
8
|
+
junos_ip_interfaces_view:
|
|
9
|
+
fields:
|
|
10
|
+
ip: ifa-local
|
|
11
|
+
subnet: ifa-destination
|
|
12
|
+
family: ../address-family-name
|
|
13
|
+
interface: ../../name
|
|
14
|
+
mtu: ../mtu
|
|
15
|
+
description: ../../description
|
|
16
|
+
primary: ifa-flags/ifaf-current-primary
|
|
17
|
+
preferred: ifa-flags/ifaf-current-preferred
|
|
18
|
+
admin_up: ../../if-config-flags/iff-up
|
|
19
|
+
device_down: ../../if-config-flags/iff-device-down
|
|
20
|
+
hardware_down: ../../if-config-flags/iff-hardware-down
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
junos_vrf_interfaces:
|
|
24
|
+
rpc: get-instance-information
|
|
25
|
+
args:
|
|
26
|
+
detail: True
|
|
27
|
+
item: instance-core/instance-interface
|
|
28
|
+
key: interface-name
|
|
29
|
+
view: junos_vrf_interfaces_view
|
|
30
|
+
|
|
31
|
+
junos_vrf_interfaces_view:
|
|
32
|
+
fields:
|
|
33
|
+
vrf: ../instance-name
|
|
34
|
+
|
|
35
|
+
## show route active-path ####
|
|
36
|
+
junos_route_table:
|
|
37
|
+
rpc: get-route-information
|
|
38
|
+
item: route-table/rt
|
|
39
|
+
args:
|
|
40
|
+
active-path: True
|
|
41
|
+
key:
|
|
42
|
+
- rt-destination
|
|
43
|
+
- ../table-name
|
|
44
|
+
view: junos_route_table_view
|
|
45
|
+
|
|
46
|
+
junos_route_table_view:
|
|
47
|
+
fields:
|
|
48
|
+
vrf: ../table-name
|
|
49
|
+
prefix: rt-destination
|
|
50
|
+
rt_entry: _entry_table
|
|
51
|
+
|
|
52
|
+
_entry_table:
|
|
53
|
+
item: rt-entry
|
|
54
|
+
key:
|
|
55
|
+
- protocol-name
|
|
56
|
+
- learned-from
|
|
57
|
+
view: _entry_view
|
|
58
|
+
|
|
59
|
+
_entry_view:
|
|
60
|
+
fields:
|
|
61
|
+
age: age
|
|
62
|
+
protocol: protocol-name
|
|
63
|
+
learned_from: gateway
|
|
64
|
+
next_hop: _nh_table
|
|
65
|
+
|
|
66
|
+
_nh_table:
|
|
67
|
+
item: nh
|
|
68
|
+
key:
|
|
69
|
+
- to
|
|
70
|
+
- via
|
|
71
|
+
view: _nh_view
|
|
72
|
+
|
|
73
|
+
_nh_view:
|
|
74
|
+
fields:
|
|
75
|
+
nh_ip: to
|
|
76
|
+
nh_interface: via
|
|
77
|
+
mpls_label: mpls-label
|
|
78
|
+
selected_next_hop: selected-next-hop
|
|
79
|
+
# nh_table_receive: nh-table-receive
|
|
80
|
+
# nh_table: nh-table
|
|
81
|
+
|
|
82
|
+
### show route table mpls ###
|
|
83
|
+
junos_mpls_table:
|
|
84
|
+
rpc: get-route-information
|
|
85
|
+
item: route-table/rt
|
|
86
|
+
args:
|
|
87
|
+
table: mpls.0
|
|
88
|
+
active-path: True
|
|
89
|
+
key:
|
|
90
|
+
- rt-destination
|
|
91
|
+
view: junos_mpls_table_view
|
|
92
|
+
|
|
93
|
+
junos_mpls_table_view:
|
|
94
|
+
fields:
|
|
95
|
+
prefix: rt-destination
|
|
96
|
+
rt_entry: _mpls_entry_table
|
|
97
|
+
|
|
98
|
+
_mpls_entry_table:
|
|
99
|
+
item: rt-entry
|
|
100
|
+
key:
|
|
101
|
+
- protocol-name
|
|
102
|
+
- learned-from
|
|
103
|
+
view: _mpls_entry_view
|
|
104
|
+
|
|
105
|
+
_mpls_entry_view:
|
|
106
|
+
fields:
|
|
107
|
+
next_hop: _mpls_nh_table
|
|
108
|
+
|
|
109
|
+
_mpls_nh_table:
|
|
110
|
+
item: nh
|
|
111
|
+
key:
|
|
112
|
+
- to
|
|
113
|
+
- via
|
|
114
|
+
view: _mpls_nh_view
|
|
115
|
+
|
|
116
|
+
_mpls_nh_view:
|
|
117
|
+
fields:
|
|
118
|
+
nh_ip: to
|
|
119
|
+
nh_interface: via
|
|
120
|
+
mpls_label: mpls-label
|
|
121
|
+
# selected_next_hop: selected-next-hop
|
|
122
|
+
nh_table_receive: nh-table-receive
|
|
123
|
+
nh_table: nh-table
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
### show chassis inventory ###
|
|
127
|
+
junos_inventory:
|
|
128
|
+
rpc: get-chassis-inventory
|
|
129
|
+
item: chassis
|
|
130
|
+
view: junos_inventory_view
|
|
131
|
+
|
|
132
|
+
junos_inventory_view:
|
|
133
|
+
fields:
|
|
134
|
+
system_serial: serial-number
|
|
135
|
+
system_description: description
|
|
136
|
+
modules: _module_table
|
|
137
|
+
|
|
138
|
+
_module_table:
|
|
139
|
+
item: chassis-module
|
|
140
|
+
key: name
|
|
141
|
+
view: _module_view
|
|
142
|
+
|
|
143
|
+
_module_view:
|
|
144
|
+
fields:
|
|
145
|
+
name: name
|
|
146
|
+
part_number: part-number
|
|
147
|
+
serial_number: serial-number
|
|
148
|
+
description: description
|
|
149
|
+
model_number: model-number
|
|
150
|
+
sub_modules: _sub_module_table
|
|
151
|
+
|
|
152
|
+
_sub_module_table:
|
|
153
|
+
item: chassis-sub-module
|
|
154
|
+
key: name
|
|
155
|
+
view: _sub_module_view
|
|
156
|
+
|
|
157
|
+
_sub_module_view:
|
|
158
|
+
fields:
|
|
159
|
+
name: name
|
|
160
|
+
part_number: part-number
|
|
161
|
+
serial_number: serial-number
|
|
162
|
+
description: description
|
|
163
|
+
model_number: model-number
|
|
164
|
+
sub_sub_modules: _sub_sub_module_table
|
|
165
|
+
|
|
166
|
+
_sub_sub_module_table:
|
|
167
|
+
item: chassis-sub-sub-module
|
|
168
|
+
key: name
|
|
169
|
+
view: _sub_sub_module_view
|
|
170
|
+
|
|
171
|
+
_sub_sub_module_view:
|
|
172
|
+
fields:
|
|
173
|
+
name: name
|
|
174
|
+
part_number: part-number
|
|
175
|
+
serial_number: serial-number
|
|
176
|
+
description: description
|
|
177
|
+
model_number: model-number
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
### show route summary (for determining VPNs for ARP table) ###
|
|
181
|
+
junos_route_summary:
|
|
182
|
+
rpc: get-route-summary-information
|
|
183
|
+
item: route-table
|
|
184
|
+
key: table-name
|
|
185
|
+
view: junos_route_summary_view
|
|
186
|
+
|
|
187
|
+
junos_route_summary_view:
|
|
188
|
+
fields:
|
|
189
|
+
table: table-name
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
junos_show_int_lag:
|
|
193
|
+
rpc: get-interface-information
|
|
194
|
+
args:
|
|
195
|
+
terse: True
|
|
196
|
+
item: physical-interface/logical-interface
|
|
197
|
+
key: name
|
|
198
|
+
view: junos_show_int_lag_view
|
|
199
|
+
|
|
200
|
+
junos_show_int_lag_view:
|
|
201
|
+
fields:
|
|
202
|
+
phy_admin_status: ../admin-status
|
|
203
|
+
admin_status: admin-status
|
|
204
|
+
oper_status: oper-status
|
|
205
|
+
lag_name: address-family/ae-bundle-name
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
junos_show_lacp:
|
|
209
|
+
rpc: get-lacp-interface-information
|
|
210
|
+
item: lacp-interface-information
|
|
211
|
+
key: lag-lacp-header/aggregate-name
|
|
212
|
+
view: show_lacp_view
|
|
213
|
+
|
|
214
|
+
show_lacp_view:
|
|
215
|
+
fields:
|
|
216
|
+
name: lag-lacp-header/aggregate-name
|
|
217
|
+
members: _lacp_member_table
|
|
218
|
+
|
|
219
|
+
_lacp_member_table:
|
|
220
|
+
item: lag-lacp-state
|
|
221
|
+
key: name
|
|
222
|
+
view: _show_lacp_member_view
|
|
223
|
+
|
|
224
|
+
_show_lacp_member_view:
|
|
225
|
+
fields:
|
|
226
|
+
lacp_timeout: lacp-timeout
|
|
227
|
+
lacp_activity: lacp-activity
|
|
228
|
+
|
custom_napalm/models.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
from typing_extensions import TypedDict
|
|
3
|
+
|
|
4
|
+
VALID_INVENTORY_TYPES = Literal[
|
|
5
|
+
"fabric_module",
|
|
6
|
+
"fan",
|
|
7
|
+
"linecard",
|
|
8
|
+
"optic",
|
|
9
|
+
"psu",
|
|
10
|
+
"re",
|
|
11
|
+
"stack_cable",
|
|
12
|
+
"stack_member",
|
|
13
|
+
"uplink_module",
|
|
14
|
+
"aoc",
|
|
15
|
+
"dac",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
InventoryDict = TypedDict(
|
|
19
|
+
"InventoryDict",
|
|
20
|
+
{
|
|
21
|
+
"type": VALID_INVENTORY_TYPES,
|
|
22
|
+
"subtype": str,
|
|
23
|
+
"name": str,
|
|
24
|
+
"part_number": str,
|
|
25
|
+
"serial_number": str,
|
|
26
|
+
},
|
|
27
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .nos import SCNOSDriver
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
NS = {
|
|
2
|
+
"dn-top": "http://drivenets.com/ns/yang/dn-top",
|
|
3
|
+
"dn-sys": "http://drivenets.com/ns/yang/dn-system",
|
|
4
|
+
"dn-sys-dns": "http://drivenets.com/ns/yang/dn-sys-dns",
|
|
5
|
+
"dn-sys-ncp": "http://drivenets.com/ns/yang/dn-sys-ncp",
|
|
6
|
+
"dn-platform": "http://drivenets.com/ns/yang/dn-platform",
|
|
7
|
+
"dn-if": "http://drivenets.com/ns/yang/dn-interfaces",
|
|
8
|
+
"dn-trans": "http://drivenets.com/ns/yang/dn-transceivers",
|
|
9
|
+
"dn-lldp": "http://drivenets.com/ns/yang/dn-lldp",
|
|
10
|
+
"dn-proto": "http://drivenets.com/ns/yang/dn-protocol",
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
FACTS_RPC_REQ = """<get xmlns="urn:ietf:params:xml:ns:netconf:base:1.1">
|
|
14
|
+
<filter>
|
|
15
|
+
<drivenets-top xmlns="http://drivenets.com/ns/yang/dn-top">
|
|
16
|
+
<system xmlns="http://drivenets.com/ns/yang/dn-system">
|
|
17
|
+
<oper-items>
|
|
18
|
+
<system-type/>
|
|
19
|
+
<system-uptime/>
|
|
20
|
+
<system-version/>
|
|
21
|
+
</oper-items>
|
|
22
|
+
<config-items>
|
|
23
|
+
<name/>
|
|
24
|
+
</config-items>
|
|
25
|
+
<ncps xmlns="http://drivenets.com/ns/yang/dn-sys-ncp">
|
|
26
|
+
<ncp>
|
|
27
|
+
<config-items>
|
|
28
|
+
<platform>
|
|
29
|
+
<oper-items>
|
|
30
|
+
<serial-number/>
|
|
31
|
+
</oper-items>
|
|
32
|
+
</platform>
|
|
33
|
+
</config-items>
|
|
34
|
+
</ncp>
|
|
35
|
+
</ncps>
|
|
36
|
+
<dns xmlns="http://drivenets.com/ns/yang/dn-sys-dns">
|
|
37
|
+
<config-items>
|
|
38
|
+
<domain-name/>
|
|
39
|
+
</config-items>
|
|
40
|
+
</dns>
|
|
41
|
+
</system>
|
|
42
|
+
<interfaces xmlns="http://drivenets.com/ns/yang/dn-interfaces">
|
|
43
|
+
<interface>
|
|
44
|
+
<name/>
|
|
45
|
+
</interface>
|
|
46
|
+
</interfaces>
|
|
47
|
+
</drivenets-top>
|
|
48
|
+
</filter>
|
|
49
|
+
</get>
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
OPTICS_RPC_REQ = """<get xmlns="urn:ietf:params:xml:ns:netconf:base:1.1">
|
|
53
|
+
<filter>
|
|
54
|
+
<drivenets-top xmlns="http://drivenets.com/ns/yang/dn-top">
|
|
55
|
+
<interfaces xmlns="http://drivenets.com/ns/yang/dn-interfaces">
|
|
56
|
+
<interface>
|
|
57
|
+
<transceivers xmlns="http://drivenets.com/ns/yang/dn-transceivers">
|
|
58
|
+
<oper-items>
|
|
59
|
+
<digital-optical-monitoring/>
|
|
60
|
+
</oper-items>
|
|
61
|
+
</transceivers>
|
|
62
|
+
</interface>
|
|
63
|
+
</interfaces>
|
|
64
|
+
</drivenets-top>
|
|
65
|
+
</filter>
|
|
66
|
+
</get>
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
LLDP_NEIGH_RPC_REQ = """<get xmlns="urn:ietf:params:xml:ns:netconf:base:1.1">
|
|
70
|
+
<filter>
|
|
71
|
+
<drivenets-top xmlns="http://drivenets.com/ns/yang/dn-top">
|
|
72
|
+
<protocols xmlns="http://drivenets.com/ns/yang/dn-protocol">
|
|
73
|
+
<lldp xmlns="http://drivenets.com/ns/yang/dn-lldp">
|
|
74
|
+
<interfaces>
|
|
75
|
+
<interface>
|
|
76
|
+
<neighbors>
|
|
77
|
+
<neighbor/>
|
|
78
|
+
</neighbors>
|
|
79
|
+
</interface>
|
|
80
|
+
</interfaces>
|
|
81
|
+
</lldp>
|
|
82
|
+
</protocols>
|
|
83
|
+
</drivenets-top>
|
|
84
|
+
</filter>
|
|
85
|
+
</get>
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
INVENTORY_RPC_REQ = """<get xmlns="urn:ietf:params:xml:ns:netconf:base:1.1">
|
|
89
|
+
<filter>
|
|
90
|
+
<drivenets-top xmlns="http://drivenets.com/ns/yang/dn-top">
|
|
91
|
+
<interfaces xmlns="http://drivenets.com/ns/yang/dn-interfaces">
|
|
92
|
+
<interface>
|
|
93
|
+
<oper-items>
|
|
94
|
+
<interface-speed/>
|
|
95
|
+
</oper-items>
|
|
96
|
+
<transceivers xmlns="http://drivenets.com/ns/yang/dn-transceivers">
|
|
97
|
+
<oper-items>
|
|
98
|
+
<form-factor/>
|
|
99
|
+
<ethernet-pmd/>
|
|
100
|
+
<vendor/>
|
|
101
|
+
<vendor-part/>
|
|
102
|
+
<serial-no/>
|
|
103
|
+
<wavelength/>
|
|
104
|
+
</oper-items>
|
|
105
|
+
</transceivers>
|
|
106
|
+
</interface>
|
|
107
|
+
</interfaces>
|
|
108
|
+
</drivenets-top>
|
|
109
|
+
</filter>
|
|
110
|
+
</get>
|
|
111
|
+
"""
|