Commit 9f190197 authored by bee26's avatar bee26
Browse files

Merge branch 'cdata' into 'master'

Add support for CData.xPON profile

See merge request noc/noc!6024
parents be8f8804 ef77d14c
{
"name": "C-Data",
"uuid": "ee76423d-cef1-4791-bea2-aad1f67034bc",
"full_name": "C-Data",
"code": ["CDATA"],
"site": "https://cdatatec.com.cn/",
"$collection": "inv.vendors"
}
{
"name": "CData | xPON | sysObjectID",
"$collection": "sa.profilecheckrules",
"uuid": "4c7c635a-97f5-478d-9df7-b7bf9cf3b32c",
"description": "",
"preference": 10,
"method": "snmp_v2c_get",
"param": "SNMPv2-MIB::sysObjectID.0",
"match_method": "eq",
"value": "1.3.6.1.4.1.17409",
"action": "match",
"profile__name": "CData.xPON"
}
{"description": "", "$collection": "sa.profiles", "name": "CData.xPON", "uuid": "130563fc-6776-4db3-94a6-1e03c5583620"}
\ No newline at end of file
---
uuid: cbfab1e2-2dc7-43fd-96a4-be54c8933ad2
---
# CData.xPON
<!-- prettier-ignore -->
!!! todo
Describe *CData.xPON* profile
## Supported Scripts
{{ supported_scripts("CData.xPON") }}
---
uuid: 387de512-e7c1-4383-8f23-7fbdb8f90431
---
# CData
`CData.*` family of profiles support various [C-Data](https://cdatatec.com.cn/)
network equipment.
## Supported Profiles
- [CData.xPON](CData.xPON.md)
## Supported Platforms
{{ supported_platforms('CDATA') }}
......@@ -140,6 +140,9 @@ nav:
- Brocade.CER: user/reference/profiles/Brocade/Brocade.CER.md
- Brocade.FabricOS: user/reference/profiles/Brocade/Brocade.FabricOS.md
- Brocade.IronWare: user/reference/profiles/Brocade/Brocade.IronWare.md
- CData:
- Overview: user/reference/profiles/CData/index.md
- CData.xPON: user/reference/profiles/CData/CData.xPON.md
- Cambium:
- Overview: user/reference/profiles/Cambium/index.md
- Cambium.ePMP: user/reference/profiles/Cambium/Cambium.ePMP.md
......
---
uuid: cbfab1e2-2dc7-43fd-96a4-be54c8933ad2
---
# CData.xPON
<!-- prettier-ignore -->
!!! todo
Describe *CData.xPON* profile
## Supported Scripts
{{ supported_scripts("CData.xPON") }}
---
uuid: 387de512-e7c1-4383-8f23-7fbdb8f90431
---
# CData
`CData.*` family of profiles support various [C-Data](https://cdatatec.com.cn/)
network equipment.
## Supported Profiles
- [CData.xPON](CData.xPON.md)
## Supported Platforms
{{ supported_platforms('CDATA') }}
......@@ -151,6 +151,9 @@ nav:
- Brocade.CER: user/reference/profiles/Brocade/Brocade.CER.md
- Brocade.FabricOS: user/reference/profiles/Brocade/Brocade.FabricOS.md
- Brocade.IronWare: user/reference/profiles/Brocade/Brocade.IronWare.md
- CData:
- Overview: user/reference/profiles/CData/index.md
- CData.xPON: user/reference/profiles/CData/CData.xPON.md
- Cambium:
- Overview: user/reference/profiles/Cambium/index.md
- Cambium.ePMP: user/reference/profiles/Cambium/Cambium.ePMP.md
......
# ---------------------------------------------------------------------
# CData.xPON.get_arp
# ---------------------------------------------------------------------
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
# Python modules
import re
# NOC modules
from noc.core.script.base import BaseScript
from noc.sa.interfaces.igetarp import IGetARP
class Script(BaseScript):
name = "CData.xPON.get_arp"
interface = IGetARP
rx_line = re.compile(
r"^(?P<ip>\S+)\s+(?P<mac>\S+)\s+\d+\s+(?P<interface>[xgpl]\S+\d)\s+\S+\s+\d+\s*\n",
re.MULTILINE,
)
rx_line2 = re.compile(
r"^(?P<ip>\S+)\s+(?P<mac>\S+)\s+\d+\s+s\s+\S+\s+\d+\s+(?P<interface>[xgpl]\S+\d)\s+.+\n",
re.MULTILINE,
)
def execute_cli(self):
r = []
with self.configure():
try:
v = self.cli("show arp all")
for match in self.rx_line.finditer(v):
r += [match.groupdict()]
except self.CLISyntaxError:
v = self.cli("show arp entry all")
for match in self.rx_line2.finditer(v):
r += [match.groupdict()]
return r
# ----------------------------------------------------------------------
# CData.xPON.get_capabilities
# ----------------------------------------------------------------------
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
# NOC modules
from noc.sa.profiles.Generic.get_capabilities import Script as BaseScript
from noc.sa.profiles.Generic.get_capabilities import false_on_cli_error
class Script(BaseScript):
name = "CData.xPON.get_capabilities"
@false_on_cli_error
def has_lldp_cli(self):
"""
Check box has LLDP enabled
"""
with self.configure():
cmd = self.cli("show lldp configuration")
return "Enable" in cmd
# ---------------------------------------------------------------------
# CData.xPON.get_chassis_id
# ---------------------------------------------------------------------
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
# Python modules
import re
# NOC modules
from noc.sa.profiles.Generic.get_chassis_id import Script as BaseScript
from noc.sa.interfaces.igetchassisid import IGetChassisID
class Script(BaseScript):
name = "CData.xPON.get_chassis_id"
interface = IGetChassisID
cache = True
rx_mac = re.compile(r"^\s+Device MAC address\s+: (?P<mac>\S+)\n", re.MULTILINE)
def execute_cli(self):
v = self.cli("show device", cached=True)
match = self.rx_mac.search(v)
if match:
mac = match.group("mac")
return {"first_chassis_mac": mac, "last_chassis_mac": mac}
else:
raise self.NotSupportedError()
# ---------------------------------------------------------------------
# CData.xPON.get_config
# ---------------------------------------------------------------------
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
# NOC modules
from noc.core.script.base import BaseScript
from noc.sa.interfaces.igetconfig import IGetConfig
class Script(BaseScript):
name = "CData.xPON.get_config"
interface = IGetConfig
def execute_cli(self, **kwargs):
try:
config = self.cli("show current-config")
except self.CLISyntaxError:
with self.configure():
config = self.cli("show current-config")
config = self.strip_first_lines(config, 2)
return self.cleaned_config(config)
# ---------------------------------------------------------------------
# CData.xPON.get_interfaces
# ---------------------------------------------------------------------
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
# Python modules
import re
# NOC modules
from noc.sa.profiles.Generic.get_interfaces import Script as BaseScript
from noc.sa.interfaces.igetinterfaces import IGetInterfaces
from noc.core.ip import IPv4
from noc.core.text import split_alnum
class Script(BaseScript):
name = "CData.xPON.get_interfaces"
interface = IGetInterfaces
rx_vlan = re.compile(
r"^\s*Vlan-ID: (?P<vlan_id>\d+)\s+Vlan-Name: (?P<vlan_name>.+)\n"
r"(^\s*User-bridge: .+\n)?"
r"^\s*Untagged-Ports:(?P<untagged>.+)\n"
r"^\s*Tagged-Ports:(?P<tagged>.+)\n",
re.MULTILINE | re.DOTALL,
)
rx_port = re.compile(
r"ifIndex:\s+(?P<snmp_ifindex>\d+), linkStatus: (?P<oper_status>\d+), "
r"portName:\s+(?P<ifname>\S+),"
)
rx_agg = re.compile(
r"^\s*(?P<num>\d+)\s+(?P<type>Lacp|Manual)\s+(?P<ifaces>[xg]\S+\d), ", re.MULTILINE
)
rx_mgmt = re.compile(
r"^Status : (?P<oper_status>\S+)\s*\n"
r"^The Maximum Transmit Unit is (?P<mtu>\d+) bytes\s*\n"
r"^Internet Address is (?P<ip>\S+), netmask (?P<mask>\S+)\s*\n"
r"^Hardware address is (?P<mac>\S+)\s*\n",
re.MULTILINE,
)
rx_mgmt2 = re.compile(
r"^\s*(?P<ifname>\S+) current state: (?P<admin_status>\S+)\s*\n"
r"^\s*Line protocol current state: (?P<oper_status>\S+)\s*\n"
r"^\s*Description: (?P<descr>.+)\n"
r"^\s*Internet Address is (?P<ip_address>\S+)\s*\n"
r"^\s*The Maximum Transmit Unit is (?P<mtu>\d+) bytes\s*\n"
r"^\s*IP Sending Frames.*\n"
r"^\s*Hardware Address is (?P<mac>\S+)\s*\n",
re.MULTILINE,
)
rx_vlanif = re.compile(
r"^Description : Inband interface (?P<ifname>vlanif\d+) is (?P<oper_status>\S+), "
r"administrator status is (?P<admin_status>\S+)\s*\n"
r"^The Maximum Transmit Unit is (?P<mtu>\d+) bytes\s*\n"
r"^Internet Address is (?P<ip>\S+), netmask (?P<mask>\S+)\s*\n"
r"^Hardware address is (?P<mac>\S+)\s*\n",
re.MULTILINE,
)
rx_vlanif2 = re.compile(
r"^\s*(?P<ifname>Vlanif\d+) current state: (?P<admin_status>\S+)\s*\n"
r"^\s*Line protocol current state: (?P<oper_status>\S+)\s*\n"
r"^\s*Description: (?P<descr>.+)\n"
r"^\s*Internet Address is (?P<ip_address>\S+)\s*\n"
r"^\s*The Maximum Transmit Unit is (?P<mtu>\d+) bytes\s*\n"
r"^\s*IP Sending Frames.*\n"
r"^\s*Hardware Address is (?P<mac>\S+)\s*\n",
re.MULTILINE,
)
rx_vlanid = re.compile(r"[Vv]lanif(?P<vlan_id>\d+)")
@staticmethod
def iter_range(s):
if "-" not in s:
yield s
else:
first, last = s.rsplit("-", 1)
parts = split_alnum(first)
prefix = parts[:-1]
last = last.rsplit("/", 1)[1]
for i in range(int(parts[-1]), int(last) + 1):
yield "".join([str(x) for x in prefix + [i]])
def execute_cli(self, **kwargs):
vlans = []
interfaces = []
with self.configure():
v = self.cli("show vlan all")
for vlan in v.split("-----\n"):
match = self.rx_vlan.search(vlan)
if match:
vlan_id = match.group("vlan_id")
tagged = match.group("tagged").split()
untagged = match.group("untagged").split()
vlans += [
{
"vlan_id": vlan_id,
"untagged": untagged,
"tagged": tagged,
}
]
v = self.cli("show lacp system port")
for match in self.rx_port.finditer(v):
ifname = match.group("ifname")
iface = {
"name": ifname,
"type": "physical",
"snmp_ifindex": match.group("snmp_ifindex"),
"admin_status": True,
"oper_status": match.group("oper_status").lower() == "1",
"enabled_protocols": [],
"subinterfaces": [],
}
sub = {
"name": ifname,
"admin_status": True,
"oper_status": match.group("oper_status").lower() == "1",
"enabled_afi": ["BRIDGE"],
"enabled_protocols": [],
}
for vlan in vlans:
if ifname in vlan["untagged"]:
sub["untagged_vlan"] = vlan["vlan_id"]
if ifname in vlan["tagged"]:
if "tagged_vlans" in sub:
sub["tagged_vlans"] += [vlan["vlan_id"]]
else:
sub["tagged_vlans"] = [vlan["vlan_id"]]
iface["subinterfaces"] += [sub]
interfaces += [iface]
v = self.cli("show link-aggregation group summary")
for match in self.rx_agg.finditer(v):
if match.group("type") == "Manual":
ifname = "lag" + match.group("num")
else:
ifname = "lagL" + match.group("num")
iface = {
"name": ifname,
"type": "aggregated",
"admin_status": True,
"oper_status": True,
"subinterfaces": [
{
"name": ifname,
"admin_status": True,
"oper_status": True,
"enabled_afi": ["BRIDGE"],
}
],
}
interfaces += [iface]
for vlan in vlans:
if (ifname not in vlan["untagged"]) and (ifname not in vlan["tagged"]):
continue
for phys_iface in self.iter_range(match.group("ifaces")):
for phys_ifaces in interfaces:
if phys_iface == phys_ifaces["name"]:
phys_ifaces["aggregated_interface"] = ifname
if "L" in ifname:
phys_ifaces["protovols"] = ["LACP"]
sub = phys_ifaces["subinterfaces"][0]
if ifname in vlan["untagged"]:
sub["untagged_vlan"] = vlan["vlan_id"]
if ifname in vlan["tagged"]:
if "tagged_vlans" in sub:
sub["tagged_vlans"] += [vlan["vlan_id"]]
else:
sub["tagged_vlans"] = [vlan["vlan_id"]]
try:
v = self.cli("show interface vlanif")
for match in self.rx_vlanif.finditer(v):
ifname = match.group("ifname")
ip_address = match.group("ip")
ip_mask = match.group("mask")
ip_address = "%s/%s" % (ip_address, IPv4.netmask_to_len(ip_mask))
vlan_id = self.rx_vlanid.search(ifname).group("vlan_id")
iface = {
"name": ifname,
"type": "SVI",
"admin_status": match.group("admin_status").lower() == "up",
"oper_status": match.group("oper_status").lower() == "up",
"mac": match.group("mac"),
"subinterfaces": [
{
"name": ifname,
"admin_status": match.group("admin_status").lower() == "up",
"oper_status": match.group("oper_status").lower() == "up",
"mtu": match.group("mtu"),
"enabled_afi": ["IPv4"],
"ipv4_addresses": [ip_address],
"vlan_id": vlan_id,
}
],
}
interfaces += [iface]
for match in self.rx_vlanif2.finditer(v):
ifname = match.group("ifname")
vlan_id = self.rx_vlanid.search(ifname).group("vlan_id")
iface = {
"name": ifname,
"type": "SVI",
"admin_status": match.group("admin_status").lower() == "up",
"oper_status": match.group("oper_status").lower() == "up",
"mac": match.group("mac"),
"subinterfaces": [
{
"name": ifname,
"admin_status": match.group("admin_status").lower() == "up",
"oper_status": match.group("oper_status").lower() == "up",
"mtu": match.group("mtu"),
"enabled_afi": ["IPv4"],
"ipv4_addresses": [match.group("ip_address")],
"vlan_id": vlan_id,
}
],
}
interfaces += [iface]
except self.CLISyntaxError:
pass
try:
v = self.cli("show interface mgmt")
match = self.rx_mgmt.search(v)
if match:
ip_address = match.group("ip")
ip_mask = match.group("mask")
ip_address = "%s/%s" % (ip_address, IPv4.netmask_to_len(ip_mask))
iface = {
"name": "mgmt",
"type": "management",
"admin_status": True,
"oper_status": match.group("oper_status").lower() == "enable",
"mac": match.group("mac"),
"subinterfaces": [
{
"name": "mgmt",
"admin_status": True,
"oper_status": match.group("oper_status").lower() == "enable",
"mtu": match.group("mtu"),
"enabled_afi": ["IPv4"],
"ipv4_addresses": [ip_address],
}
],
}
interfaces += [iface]
else:
match = self.rx_mgmt2.search(v)
if match:
iface = {
"name": match.group("ifname"),
"type": "management",
"admin_status": match.group("admin_status").lower() == "up",
"oper_status": match.group("oper_status").lower() == "up",
"mac": match.group("mac"),
"subinterfaces": [
{
"name": match.group("ifname"),
"admin_status": match.group("admin_status").lower() == "up",
"oper_status": match.group("oper_status").lower() == "up",
"mtu": match.group("mtu"),
"enabled_afi": ["IPv4"],
"ipv4_addresses": [match.group("ip_address")],
}
],
}
interfaces += [iface]
except self.CLISyntaxError:
pass
return [{"interfaces": interfaces}]
# ---------------------------------------------------------------------
# CData.xPON.get_mac_address_table
# ---------------------------------------------------------------------
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
# Python modules
import re
# NOC modules
from noc.core.script.base import BaseScript
from noc.sa.interfaces.igetmacaddresstable import IGetMACAddressTable
class Script(BaseScript):
name = "CData.xPON.get_mac_address_table"
interface = IGetMACAddressTable
rx_line = re.compile(
r"^\s*(?P<mac>\S+)\s+(?P<vlan_id>\d+)\s+(?:\-|\d+)\s+(?P<interface>[xgpl]\S+\d)\s+"
r"(?:\-|\d+)\s+(?:\-|\d+)\s+(?P<type>dynamic|static)\s*\n",
re.MULTILINE,
)
rx_line2 = re.compile(
r"^\s*(?P<mac>\S+)\s+(?P<vlan_id>\d+)\s+(?P<interface>[xgpl]\S+\d)\s+(?P<type>dynamic|static)\s*\n",
re.MULTILINE,
)
def execute_cli(self, interface=None, vlan=None, mac=None, **kwargs):
r = []
with self.configure():
cmd = "show mac-address "
if interface is not None:
cmd += "port %s" % interface
elif vlan is not None:
cmd += "vlan %s" % vlan
else:
cmd += "all"
v = self.cli(cmd)
for match in self.rx_line.finditer(v):
if mac is not None:
if match.group("mac") != mac:
continue
r += [
{
"vlan_id": match.group("vlan_id"),
"mac": match.group("mac"),
"interfaces": [match.group("interface")],
"type": {"dynamic": "D", "static": "S"}[match.group("type").lower()],
}
]
if len(r) == 0:
for match in self.rx_line2.finditer(v):
if mac is not None:
if match.group("mac") != mac:
continue
r += [
{
"vlan_id": match.group("vlan_id"),
"mac": match.group("mac"),
"interfaces": [match.group("interface")],
"type": {"dynamic": "D", "static": "S"}[match.group("type").lower()],
}
]
return r
# ---------------------------------------------------------------------
# CData.xPON.get_version
# ---------------------------------------------------------------------
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
# Python modules
import re
# NOC modules