diff options
| author | Daniil Baturin <daniil@baturin.org> | 2017-09-21 03:09:10 +0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-09-21 03:09:10 +0700 | 
| commit | 385a05d2020921fe05c2b9aaa1661347e5169348 (patch) | |
| tree | 07715f7dc8dff592971eb45e00dffd34f6eb9710 /src | |
| parent | 793c2707b976f3efff886dcae283b54466402f9b (diff) | |
| parent | 9194771d779b1727a091a4f0ea9adc72a68b3006 (diff) | |
| download | vyos-1x-385a05d2020921fe05c2b9aaa1661347e5169348.tar.gz vyos-1x-385a05d2020921fe05c2b9aaa1661347e5169348.zip  | |
Merge pull request #1 from Taniadz/request
T393: Migrate vyatta-lldpd to vyos-1x: partial implementation of the config script
Diffstat (limited to 'src')
| -rw-r--r-- | src/conf-mode/vyos-config-lldp.py | 218 | 
1 files changed, 218 insertions, 0 deletions
diff --git a/src/conf-mode/vyos-config-lldp.py b/src/conf-mode/vyos-config-lldp.py new file mode 100644 index 000000000..ba7e9cb13 --- /dev/null +++ b/src/conf-mode/vyos-config-lldp.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2017 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. +# +# +# + +import re +import sys + +from vyos.config import Config +from vyos.util import ConfigError + + + +def get_options(config): +    options ={} +    config.set_level('service lldp') +    options['listen_vlan'] = config.exists('listen-vlan') + +    options["addr"] = config.return_value('management-address') + +    snmp = config.exists('snmp enable') +    options["snmp"] = snmp +    if snmp: +        config.set_level('') +        options["sys_snmp"] = config.exists('service snmp') +        config.set_level('service lldp') + +    config.set_level('service lldp legacy-protocols') +    options["cdp"] = config.exists("cdp") +    options["edp"] = config.exists("edp") +    options["fdp"] = config.exists("fdp") +    options["sonmp"] = config.exists("sonmp") +    return options + + +def get_interface_list(config): +    config.set_level('service lldp') +    intfs_names = config.list_nodes('interface') +    if len(intfs_names) < 0: +        return 0 +    interface_list = [] +    for name in intfs_names: +        config.set_level("service lldp interface {0}".format(name)) +        disable = config.exists('disable') +        intf = { +            "name": name, +            "disable": disable +        } +        interface_list.append(intf) +    return interface_list + + +def get_location_intf(config, name): +    path = "service lldp interface {0}".format(name) +    config.set_level(path) +    if config.exists("location"): +        return 0 +    config.set_level("{} location".format(path)) +    civic_based = {} +    elin = None +    coordinate_based = {} + +    if config.exists('civic-based'): +        config.set_level("{} location civic-based".format(path)) +        cc = config.return_value("country-code") +        civic_based["country_code"] = cc +        civic_based["ca_type"] = [] +        ca_types_names = config.list_nodes('ca-type') +        if ca_types_names: +            for ca_types_name in ca_types_names: +                config.set_level("{0} location civic-based ca-type {1}".format(path, ca_types_name)) +                ca_val = config.return_value('ca-value') +                ca_type = { +                    "name": ca_types_name, +                    "ca_val": ca_val +                } +                civic_based["ca_type"].append(ca_type) + +    elif config.exists("elin"): +        elin = config.return_value("elin") + +    elif config.exists("coordinate-based"): +        config.set_level("{} location coordinate-based".format(path)) +        alt = config.return_value("altitude") +        lat = config.return_value("latitude") +        long = config.return_value("longitude") +        datum = config.return_value("datum") +        coordinate_based["altitude"] = alt +        coordinate_based["latitude"] = lat +        coordinate_based["longitude"] = long +        coordinate_based["datum"] = datum + +    intf = { +        "name": name, +        "civic_based": civic_based, +        "elin": elin, +        "coordinate_based": coordinate_based + +    } +    return intf + + +def get_location(config): +    config.set_level('service lldp') +    intfs_names = config.list_nodes('interface') +    if len(intfs_names) < 0: +        return 0 +    if config.exists("disable"): +        return 0 +    intfs_location = [] +    for name in intfs_names: +        intf = get_location_intf(config, name) +        intfs_location.append(intf) +    return intfs_location + + +def get_config(): +    conf = Config() +    options = get_options(conf) +    interface_list = get_interface_list(conf) +    location = get_location(conf) +    lldp = {"options": options, "interface_list": interface_list, "location": location} +    return lldp + + +def verify(lldp): + +    # check location +    for location in lldp["location"]: + +        # check civic-based +        if len(location["civic_based"]) > 0: +            if len(location["coordinate_based"]) > 0 or location["elin"]: +                raise ConfigError("Can only configure 1 location type for interface {0}".format(location["name"])) + +            # check country-code +            if not location["civic_based"]["country_code"]: +                raise ConfigError("Invalid location for interface {0}: must configure the country code".format(location["name"])) + +            if not re.match(r"^[a-zA-Z]{2}$", location["civic_based"]["country_code"]): +                raise ConfigError("Invalid location for interface {0}: country-code must be 2 characters".format(location["name"])) +            # check ca-type +            if len(location["civic_based"]["ca_type"]) < 0: +                raise ConfigError("Invalid location for interface {0}: must define at least 1 ca-type".format(location["name"])) + +            for ca_type in location["civic_based"]["ca_type"]: +                if not int(ca_type["name"]) in range(0, 129): +                    raise ConfigError("Invalid location for interface {0}: ca-type must between 0-128".format(location["name"])) + +                if not ca_type["ca_val"]: +                    raise ConfigError("Invalid location for interface {0}: must configure the ca-value for ca-type {1}".format(location["name"],ca_type["name"])) + +        # check coordinate-based +        elif len(location["coordinate_based"]) > 0: +            # check longitude and latitude +            if not location["coordinate_based"]["longitude"]: +                raise ConfigError("Must define longitude for interface {0}".format(location["name"])) + +            if not location["coordinate_based"]["latitude"]: +                raise ConfigError("Must define latitude for interface {0}".format(location["name"])) + +            if not re.match(r"^(\d+)(\.\d+)?[nNsS]$", location["coordinate_based"]["latitude"]): +                raise ConfigError("Invalid location for interface {0}: latitude should be a number followed by S or N".format(location["name"])) + +            if not re.match(r"^(\d+)(\.\d+)?[eEwW]$", location["coordinate_based"]["longitude"]): +                raise ConfigError("Invalid location for interface {0}: longitude should be a number followed by E or W".format(location["name"])) + +            # check altitude and datum if exist +            if location["coordinate_based"]["altitude"]: +                if not re.match(r"^[-+0-9\.]+$", location["coordinate_based"]["altitude"]): +                    raise ConfigError("Invalid location for interface {0}: altitude should be a positive or negative number".format(location["name"])) + +            if location["coordinate_based"]["datum"]: +                if not re.match(r"^(WGS84|NAD83|MLLW)$", location["coordinate_based"]["datum"]): +                    raise ConfigError("Invalid location for interface {0}: datum should be WGS84, NAD83, or MLLW".format(location["name"])) + +        # check elin +        elif len(location["elin"]) > 0: +            if not re.match(r"^[0-9]{10,25}$", location["elin"]): +                raise ConfigError("Invalid location for interface {0}: ELIN number must be between 10-25 numbers".format(location["name"])) + +    # check options +    if lldp["options"]["snmp"]: +        if not lldp["options"]["sys_snmp"]: +            raise ConfigError("SNMP must be configured to enable LLDP SNMP") + + +def generate(config): +    pass + + +def apply(config): +    pass + +if __name__ == '__main__': +    try: +        c = get_config() +        verify(c) +        generate(c) +        apply(c) +    except ConfigError as e: +        print(e) +        sys.exit(1) +  | 
