bin/pvl.hosts-lldp
author Tero Marttila <terom@paivola.fi>
Tue, 18 Mar 2014 21:25:35 +0200
changeset 398 de275bf6db70
parent 395 9de553b50128
permissions -rw-r--r--
pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
#!/usr/bin/env python
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
    Requirements:
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
     5
        pydot
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
"""
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
import pvl.args
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
import pvl.hosts
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    10
from pvl.invoke import merge
395
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    11
from pvl.snmp import snmp, lldp, vlan, bridge
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    13
import logging; log = logging.getLogger('pvl.hosts-lldp')
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    14
import optparse
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    15
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    16
def hosts_snmp (options, hosts) :
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    17
    """
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    18
        Discover SNMP-supporting hosts.
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    19
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    20
        Yields Host, snmpdata
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    21
    """
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    22
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    23
    for host in hosts :
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    24
        host_snmp = host.extensions.get('snmp')
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    25
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    26
        if not host_snmp :
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    27
            log.debug("%s: skip non-snmp host", host)
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    28
            continue
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    29
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    30
        elif host.down :
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    31
            log.debug("%s: skip down host", host)
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    32
            continue
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    33
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    34
        else :
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    35
            log.debug("%s: %s", host, host_snmp)
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    36
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    37
        yield host, host_snmp
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    38
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    39
def hosts_lldp (options, hosts) :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    40
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    41
        Discover LLDP-supporting hosts.
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    42
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    43
        Yields Host, LLDPAgent
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    44
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    45
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    46
    for host, host_snmp in hosts_snmp(options, hosts) :
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    47
        agent = lldp.LLDPAgent.apply(options, host.fqdn(), community=host_snmp.get('community'))
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    48
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    49
        try :
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    50
            local = agent.local
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    51
        except snmp.SNMPError as ex :
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    52
            log.warning("%s: %s", host, ex)
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    53
            continue
398
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
    54
        
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
    55
        if not local :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
    56
            log.info("%s: no lldp support", host)
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
    57
            continue
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    58
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    59
        log.info("%s: %s", host, local)
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    60
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    61
        if local['sys_name'] != host.host :
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    62
            log.warning("%s: SNMP sys_name mismatch: %s", host, local['sys_name'])
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    63
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
    64
        yield host, agent
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    65
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    66
def hosts_vlan (options, hosts) :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    67
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    68
        Discover VLAN-supporting hosts.
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    69
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    70
        Yields Host, VLANAgent
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    71
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    72
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    73
    for host, host_snmp in hosts_snmp(options, hosts) :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    74
        agent = vlan.VLANAgent.apply(options, host.fqdn(), community=host_snmp.get('community'))
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    75
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    76
        try :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    77
            count = agent.count
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    78
        except snmp.SNMPError as ex :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    79
            log.warning("%s: %s", host, ex)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    80
            continue
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    81
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    82
        log.info("%s: %s", host, count)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    83
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    84
        yield host, agent
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    85
395
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    86
def hosts_bridge (options, hosts) :
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    87
    """
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    88
        Discover Bridge-supporting hosts.
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    89
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    90
        Yields Host, BridgeAgent
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    91
    """
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    92
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    93
    for host, host_snmp in hosts_snmp(options, hosts) :
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    94
        agent = bridge.BridgeAgent.apply(options, host.fqdn(), community=host_snmp.get('community'))
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    95
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    96
        try :
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    97
            agent.ping()
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    98
        except snmp.SNMPError as ex :
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
    99
            log.warning("%s: %s", host, ex)
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   100
            continue
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   101
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   102
        log.info("%s", host)
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   103
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   104
        yield host, agent
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   105
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   106
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   107
def apply_hosts_lldp (options, hosts) :
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   108
    """
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   109
        Query host LLDP info.
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   110
    """
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   111
    
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   112
    _hosts_lldp = list(hosts_lldp(options, hosts))
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   113
    hosts_by_chassis = { }
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   114
    
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   115
    # first pass to discover hosts
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   116
    for host, agent in _hosts_lldp :
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   117
        chassis = agent.local['chassis']
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   118
        log.info("%s: %s", host, chassis)
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   119
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   120
        hosts_by_chassis[chassis] = host
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   121
    
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   122
    # second pass to discver links
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   123
    for host, agent in _hosts_lldp :
398
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   124
        try :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   125
            remotes = list(agent.remotes())
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   126
        except snmp.SNMPError as ex :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   127
            log.warn("%s: broken lldp remotes: %s", host, ex)
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   128
            continue
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   129
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   130
        for port, remote in remotes :
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   131
            port = agent.port(port)
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   132
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   133
            remote_chassis = remote['chassis']
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   134
            remote_host = hosts_by_chassis.get(remote_chassis)
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   135
            
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   136
            log.info("%s: %s: %s (%s)", host, port, remote, remote_host)
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   137
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   138
            yield host, merge(agent.local, port), remote, remote_host
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   139
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   140
import collections
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   141
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   142
def apply_hosts_vlan (options, hosts) :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   143
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   144
        Query host VLAN ports.
395
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   145
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   146
        Yields host, { port: (untagged, [tagged]) }
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   147
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   148
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   149
    _hosts_vlan = list(hosts_vlan(options, hosts))
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   150
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   151
    for host, agent in _hosts_vlan :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   152
        # only one untagged vlan / port
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   153
        vlan_untagged = { }
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   154
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   155
        # multiple taggd vlans / port
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   156
        vlan_tagged = collections.defaultdict(set)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   157
398
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   158
        for vlan, (tagged, untagged) in agent.vlan_ports() :
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   159
            log.info("%s: %s: %s + %s", host, vlan, tagged, untagged)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   160
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   161
            for port in tagged :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   162
                vlan_tagged[port].add(vlan)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   163
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   164
            for port in untagged :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   165
                if port in vlan_untagged :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   166
                    log.warning("%s: duplicate untagged vlan %s for port %s on vlan %s", host, vlan, port, vlan_untagged[port])
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   167
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   168
                vlan_untagged[port] = vlan
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   169
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   170
        # pack into {port: (untagged, [tagged]) }
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   171
        yield host, dict(
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   172
            (
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   173
                    port, (vlan_untagged.get(port), tuple(vlan_tagged[port]))
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   174
            ) for port in set(vlan_untagged) | set(vlan_tagged)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   175
        )
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   176
395
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   177
def apply_hosts_bridge (options, hosts) :
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   178
    """
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   179
        Query host bridge tables.
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   180
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   181
        Yields host, { port: (macs) }
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   182
    """
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   183
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   184
    for host, agent in hosts_bridge(options, hosts) :
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   185
        ports = collections.defaultdict(list)
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   186
398
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   187
        try :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   188
            vlan_fdb_ports = list(agent.vlan_fdb_ports())
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   189
        except snmp.SNMPError as ex :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   190
            log.warn("%s: broken dot1q fdb: %s", host, ex)
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   191
            continue
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   192
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   193
        if vlan_fdb_ports :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   194
            log.info("%s: have dot1q ports", host)
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   195
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   196
            for ether, port, vlan in agent.vlan_fdb_ports() :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   197
                if not port :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   198
                    # XXX: unknown?
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   199
                    continue
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   200
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   201
                ports[(port, vlan)].append(ether)
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   202
        else :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   203
            try :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   204
                fdb_ports = list(agent.fdb_ports())
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   205
            except snmp.SNMPError as ex :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   206
                log.warn("%s: broken dot1q fdb: %s", host, ex)
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   207
                continue
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   208
            
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   209
            # fallback to dot1d fdb
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   210
            log.info("%s: fallback to dot1d", host)
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   211
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   212
            for ether, port in agent.fdb_ports() :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   213
                if not port :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   214
                    # XXX: unknown?
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   215
                    continue
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   216
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   217
                ports[(port, None)].append(ether)
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   218
395
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   219
        yield host, ports
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   220
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   221
COLOR_VLANS = {
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   222
    1:      'grey',         # pvl-lan
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   223
    2:      'blue',         # pvl-lan2
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   224
    3:      'red',          # pvl-san
392
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   225
    4:      'green',        # pvl-veturi
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   226
    7:      'orange',       # pvl-ranssi
392
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   227
    8:      'yellow',       # pvl-mgmt
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   228
    10:     'brown',        # pvl-public
392
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   229
    100:    'navyblue',     # pvl-test
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   230
    103:    'red4',         # pvl-test-san
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   231
    104:    'red2',         # pvl-ganeti
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   232
    192:    'purple',       # paivola-services
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   233
    255:    'magenta',      # pvl-sonera
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   234
}
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   235
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   236
def apply_graph (options, items, vlans={}) :
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   237
    import pydot
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   238
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   239
    dot = pydot.Dot(graph_name='lldp_hosts', graph_type='digraph',
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   240
            # XXX: breaks multi-edges?
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   241
            #splines     = 'true',
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   242
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   243
            sep             = '+25,25',
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   244
            overlap         = 'scalexy',
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   245
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   246
            # only applies to loops
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   247
            nodesep     = 0.5,
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   248
    )
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   249
    dot.set_edge_defaults(
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   250
            labeldistance   = 3.0,
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   251
            penwidth        = 2.0,
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   252
    )
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   253
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   254
    nodes = { }
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   255
    edges = { }
392
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   256
    vlan_colors = { } # { vlan: color }
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   257
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   258
    for host, local, remote, remote_host in items :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   259
        # src
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   260
        src_name = str(host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   261
        src_label = '"{host.location}"'.format(host=host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   262
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   263
        if src_name in nodes :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   264
            src = nodes[src_name]
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   265
        else :
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   266
            src = nodes[src_name] = pydot.Node(src_name,
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   267
                    label       = src_label,
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   268
                    fontsize    = 18,
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   269
            )
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   270
            dot.add_node(src)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   271
        
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   272
        # dst
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   273
        if remote_host :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   274
            dst_name = str(remote_host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   275
            dst_label = '"{host.location}"'.format(host=remote_host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   276
        else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   277
            dst_name = remote['chassis'].replace(':', '-')
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   278
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   279
            # XXX: pydot is not smart enough to quote this
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   280
            if remote['sys_name'] :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   281
                dst_label = '"{remote[chassis]} ({remote[sys_name]})"'.format(remote=remote)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   282
            else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   283
                dst_label = '"{remote[chassis]}"'.format(remote=remote)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   284
        
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   285
        if dst_name in nodes :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   286
            dst = nodes[dst_name]
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   287
        else :
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   288
            dst = nodes[dst_name] = pydot.Node(dst_name,
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   289
                    label       = dst_label,
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   290
                    fontsize    = 18,
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   291
            )
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   292
            dot.add_node(dst)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   293
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   294
        # edges
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   295
        headlabel = '"{remote[port]}"'.format(remote=remote)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   296
        taillabel = '"{local[port]}"'.format(local=local)
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   297
        fillcolor = 'black'
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   298
        color = 'black'
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   299
        untag = tagged = None
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   300
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   301
        # vlans?
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   302
        if vlans and host in vlans and local['port_id'] in vlans[host] :
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   303
            untag, tagged = vlans[host][local['port_id']]
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   304
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   305
            log.debug("%s#%s: %s+%s", host, local['port_id'], untag, tagged)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   306
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   307
            colors = []
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   308
            for tag in sorted(tagged) :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   309
                if tag in COLOR_VLANS :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   310
                    colors.append(COLOR_VLANS[tag])
392
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   311
                elif tag in vlan_colors :
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   312
                    colors.append(vlan_colors[tag])
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   313
                else :
392
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   314
                    color = '/paired12/{count}'.format(count=1+len(vlan_colors))
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   315
                    
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   316
                    log.info("%s#%s: chosing new vlan %s color %s", host, local['port_id'], tag, color)
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   317
392
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   318
                    vlan_colors[tag] = color
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   319
                    colors.append(color)
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   320
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   321
            if not untag :
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   322
                pass
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   323
            elif untag in COLOR_VLANS :
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   324
                fillcolor = COLOR_VLANS[untag]
392
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   325
            elif untag in vlan_colors :
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   326
                fillcolor = vlan_colors[untag]
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   327
            else :
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   328
                color = '/paired12/{count}'.format(count=1+len(vlan_colors))
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   329
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   330
                log.warn("%s#%s: chosing new vlan %s color %s", host, local['port_id'], untag, color)
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   331
                    
e7a55db74072 pvl.hosts-lldp: tweaked vlan colors
Tero Marttila <terom@paivola.fi>
parents: 391
diff changeset
   332
                fillcolor = vlan_colors[tag] = color
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   333
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   334
            # first color overrides fillcolor for heads
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   335
            if colors and untag :
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   336
                color = ':'.join([fillcolor] + colors)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   337
            elif colors :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   338
                color = ':'.join(colors)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   339
            elif fillcolor :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   340
                color = fillcolor
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   341
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   342
        elif vlans :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   343
            # XXX: this happens when LLDP gives us the LACP ports but the VLANS are on the TRK port
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   344
            log.warn("%s#%s: unknown port for vlans: %s", host, local['port_id'], vlans.get(host))
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   345
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   346
        # edge
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   347
        if (src_name, local['port'], dst_name, remote['port']) in edges :
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   348
            log.warning("%s:%s <- %s:%s: duplicate", src_name, local['port'], dst_name, remote['port'])
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   349
        
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   350
        elif (dst_name, remote['port'], src_name, local['port']) in edges :
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   351
            log.info("%s <-> %s", src_name, dst_name)
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   352
            edge = edges[(dst_name, remote['port'], src_name, local['port'])]
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   353
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   354
            if edge.get('headlabel') != taillabel :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   355
                log.warn("%s -> %s: local port mismatch: %s vs %s", src_name, dst_name, local['port'], edge.get('headlabel'))
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   356
            
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   357
            if edge.get('taillabel') != headlabel :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   358
                log.warn("%s -> %s: remote port mismatch: %s vs %s", src_name, dst_name, remote['port'], edge.get('taillabel'))
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   359
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   360
            if edge.get('fillcolor') != fillcolor :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   361
                log.warn("%s#%s -> %s#%s: remote untag mismatch: %s vs %s", src_name, local['port'], dst_name, remote['port'], fillcolor, edge.get('fillcolor'))
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   362
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   363
            if edge.get('color') != '"' + color + '"' :
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   364
                log.warn("%s#%s -> %s#%s: remote tagged mismatch: %s vs %s", src_name, local['port'], dst_name, remote['port'], color, edge.get('color'))
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   365
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   366
            # mark as bidirectional
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   367
            edges[(src_name, local['port'], dst_name, remote['port'])] = edge
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   368
            
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   369
            edge.set('dir', 'both' if untag else 'none')
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   370
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   371
            # set second color for tail
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   372
            if untag :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   373
                edge.set('color', '"{headcolor}:{tailcolor}{tagcolors}"'.format(
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   374
                    headcolor   = edge.get('fillcolor'),
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   375
                    tailcolor   = fillcolor,
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   376
                    tagcolors   = ':' + ':'.join(colors) if colors else '',
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   377
                ))
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   378
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   379
        else :
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   380
            edge = edges[(src_name, local['port'], dst_name, remote['port'])] = pydot.Edge(src, dst,
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   381
                    dir         = 'forward' if untag else 'none',
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   382
                    headlabel   = headlabel,
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   383
                    taillabel   = taillabel,
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   384
                    color       = '"{color}"'.format(color=color),
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   385
                    fillcolor   = fillcolor,
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   386
            )
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   388
            dot.add_edge(edge)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   389
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   390
    if options.graph_dot :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   391
        dot.write(options.graph_dot)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   392
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   393
def main (argv) :
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   394
    """
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   395
        SNMP polling.
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   396
    """
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   397
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   398
    parser = optparse.OptionParser(main.__doc__)
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   399
    parser.add_option_group(pvl.args.parser(parser))
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   400
    parser.add_option_group(pvl.hosts.optparser(parser))
384
caa3dbbdbe83 split upt pvl.hosts-lldp into pvl.snmp.snmp and pvl.snmp.lldp, match remote hosts, better formatting
Tero Marttila <terom@paivola.fi>
parents: 382
diff changeset
   401
    parser.add_option_group(pvl.snmp.snmp.options(parser))
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   402
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   403
    parser.add_option('--graph-dot',
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   404
            help="Output .dot graph data")
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   405
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   406
    parser.add_option('--no-vlans', action='store_const', dest='vlans', const=False,
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   407
            help="Do not color VLANs")
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   408
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   409
    # input
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   410
    options, args = parser.parse_args(argv[1:])
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   411
    pvl.args.apply(options)
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   412
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   413
    hosts = pvl.hosts.apply(options, args)
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   414
    
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   415
    # lookup host-port-vlan mappings
393
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   416
    if options.vlans is False :
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   417
        vlans = None
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   418
    else :
8321a569d5c0 pvl.hosts-lldp: --no-vlans, bump font size, tweak vlan color logics again
Tero Marttila <terom@paivola.fi>
parents: 392
diff changeset
   419
        vlans = dict(apply_hosts_vlan(options, hosts))
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   420
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   421
    # discover node/port graph
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   422
    items = apply_hosts_lldp(options, hosts)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   423
395
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   424
    # discover edge nodes
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   425
    leafs = apply_hosts_bridge(options, hosts)
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   426
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   427
    # print
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   428
    if options.graph_dot :
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   429
        apply_graph(options, items, vlans)
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   430
    else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   431
        for host, local, remote, remote_host in items :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   432
            if remote_host :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   433
                print "{host:30} {host.location:>30} {local[port]:>25} <-> {remote[port]:<25} {remote_host.location:>30} # {remote[chassis]} ({remote_host})".format(host=host, local=local, remote=remote, remote_host=remote_host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   434
            else :
398
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   435
                print "{host:30} {host.location:>30} {local[port]:>25} --> {remote[port]:<25} {empty:30} # {remote[chassis]} ({remote[sys_name]})".format(host=host, local=local, remote=remote, empty='')
395
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   436
       
398
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   437
        for host, ports in vlans.iteritems() :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   438
            for port, (untag, tagged) in ports.iteritems() :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   439
                print "{host:30} {host.location:>30} {port:25} {untag}{tagged}".format(host=host, port=port,
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   440
                        untag       = '({untag}) '.format(untag=untag) if untag else '',
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   441
                        tagged      = ' '.join('<{tag}>'.format(tag=tag) for tag in tagged),
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   442
                )
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   443
395
9de553b50128 pvl.snmp.bridge: query bridge FDB for hosts
Tero Marttila <terom@paivola.fi>
parents: 393
diff changeset
   444
        for host, ports in leafs :
398
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   445
            for (port, vlan), ethers in ports.iteritems() :
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   446
                print "{host:30} {host.location:>30} {port:25} <-- {vlan} # {ethers}".format(
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   447
                        host        = host,
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   448
                        port        = port,
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   449
                        vlan        = '<{vlan}>'.format(vlan=vlan) if vlan else '',
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   450
                        ethers      = ' '.join(ethers),
de275bf6db70 pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d
Tero Marttila <terom@paivola.fi>
parents: 395
diff changeset
   451
                )
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   452
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   453
if __name__ == '__main__':
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   454
    pvl.args.main(main)