summaryrefslogtreecommitdiff
path: root/src/op_mode/lldp_op.py
blob: 5f86ad7a5bdde233a3c1a197f14e1f52ee70d34e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python3
#
# Copyright (C) 2019 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 argparse
import jinja2
import json

from sys import exit
from tabulate import tabulate

from vyos.util import cmd
from vyos.config import Config

parser = argparse.ArgumentParser()
parser.add_argument("-a", "--all", action="store_true", help="Show LLDP neighbors on all interfaces")
parser.add_argument("-d", "--detail", action="store_true", help="Show detailes LLDP neighbor information on all interfaces")
parser.add_argument("-i", "--interface", action="store", help="Show LLDP neighbors on specific interface")

# Please be careful if you edit the template.
lldp_out = """Capability Codes: R - Router, B - Bridge, W - Wlan r - Repeater, S - Station
                  D - Docsis, T - Telephone, O - Other

Device ID                 Local     Proto  Cap   Platform             Port ID
---------                 -----     -----  ---   --------             -------
{% for neighbor in neighbors %}
{%   for local_if, info in neighbor.items() %}
{{ "%-25s" | format(info.chassis) }} {{ "%-9s" | format(local_if) }} {{ "%-6s" | format(info.proto) }} {{ "%-5s" | format(info.capabilities) }} {{ "%-20s" | format(info.platform[:18]) }} {{ info.remote_if }}
{%   endfor %}
{% endfor %}
"""

def get_neighbors():
    return cmd('/usr/sbin/lldpcli -f json show neighbors')

def parse_data(data):
    output = []
    for local_if, values in data.items():
        for chassis, c_value in values.get('chassis', {}).items():
            capabilities = c_value['capability']
            if isinstance(capabilities, dict):
                capabilities = [capabilities]

            cap = ''
            for capability in capabilities:
                if capability['enabled']:
                    if capability['type'] == 'Router':
                        cap += 'R'
                    if capability['type'] == 'Bridge':
                        cap += 'B'
                    if capability['type'] == 'Wlan':
                        cap += 'W'
                    if capability['type'] == 'Station':
                        cap += 'S'
                    if capability['type'] == 'Repeater':
                        cap += 'r'
                    if capability['type'] == 'Telephone':
                        cap += 'T'
                    if capability['type'] == 'Docsis':
                        cap += 'D'
                    if capability['type'] == 'Other':
                        cap += 'O'


        remote_if = 'Unknown'
        if 'descr' in values.get('port', {}):
            remote_if = values.get('port', {}).get('descr')
        elif 'id' in values.get('port', {}):
            remote_if = values.get('port', {}).get('id').get('value', 'Unknown')

        output.append({local_if: {'chassis': chassis,
                                   'remote_if': remote_if,
                                   'proto': values.get('via','Unknown'),
                                   'platform': c_value.get('descr', 'Unknown'),
                                   'capabilities': cap}})


    output = {'neighbors': output}
    return output

if __name__ == '__main__':
    args = parser.parse_args()
    tmp = { 'neighbors' : [] }

    c = Config()
    if not c.exists_effective(['service', 'lldp']):
        print('Service LLDP is not configured')
        exit(0)

    if args.detail:
        print(cmd('/usr/sbin/lldpctl -f plain'))
        exit(0)
    elif args.all or args.interface:
        tmp = json.loads(get_neighbors())

        if args.all:
            neighbors = tmp['lldp']['interface']
        elif args.interface:
            neighbors = dict()
            if args.interface in tmp['lldp']['interface']:
                neighbors[args.interface] = tmp['lldp']['interface'][args.interface]

    else:
        parser.print_help()
        exit(1)

    tmpl = jinja2.Template(lldp_out, trim_blocks=True)
    config_text = tmpl.render(parse_data(neighbors))
    print(config_text)

    exit(0)