bin/pvl.hosts-lldp
author Tero Marttila <terom@paivola.fi>
Mon, 17 Mar 2014 23:55:11 +0200
changeset 391 e2c367b1556f
parent 388 5a034dbd641c
child 392 e7a55db74072
permissions -rw-r--r--
pvl.hosts-lldp: add VLAN support
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
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    11
from pvl.snmp import snmp, lldp, vlan
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
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    54
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
    55
        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
    56
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    57
        if local['sys_name'] != host.host :
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    58
            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
    59
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
    60
        yield host, agent
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    61
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    62
def hosts_vlan (options, hosts) :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    63
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    64
        Discover VLAN-supporting hosts.
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    65
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    66
        Yields Host, VLANAgent
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
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    69
    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
    70
        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
    71
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    72
        try :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    73
            count = agent.count
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    74
        except snmp.SNMPError as ex :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    75
            log.warning("%s: %s", host, ex)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    76
            continue
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    77
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    78
        log.info("%s: %s", host, count)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    79
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    80
        yield host, agent
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
    81
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    82
def apply_hosts_lldp (options, hosts) :
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    83
    """
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    84
        Query host LLDP info.
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    85
    """
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
    86
    
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
    87
    _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
    88
    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
    89
    
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
    90
    # 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
    91
    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
    92
        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
    93
        log.info("%s: %s", host, chassis)
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
    94
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
    95
        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
    96
    
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
    97
    # 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
    98
    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
    99
        for port, remote in agent.remotes() :
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
   100
            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
   101
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
   102
            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
   103
            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
   104
            
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
   105
            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
   106
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
   107
            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
   108
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   109
import collections
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   110
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   111
def apply_hosts_vlan (options, hosts) :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   112
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   113
        Query host VLAN ports.
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   114
    """
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   115
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   116
    _hosts_vlan = list(hosts_vlan(options, hosts))
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   117
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   118
    for host, agent in _hosts_vlan :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   119
        # only one untagged vlan / port
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   120
        vlan_untagged = { }
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   121
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   122
        # multiple taggd vlans / port
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   123
        vlan_tagged = collections.defaultdict(set)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   124
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   125
        for vlan, (tagged, untagged) in agent.vlans() :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   126
            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
   127
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   128
            for port in tagged :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   129
                vlan_tagged[port].add(vlan)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   130
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   131
            for port in untagged :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   132
                if port in vlan_untagged :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   133
                    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
   134
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   135
                vlan_untagged[port] = vlan
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   136
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   137
        # pack into {port: (untagged, [tagged]) }
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   138
        yield host, dict(
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   139
            (
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   140
                    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
   141
            ) 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
   142
        )
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
COLOR_VLANS = {
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   145
    1:      'grey',         # pvl-lan
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   146
    2:      'blue',         # pvl-lan2
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   147
    3:      'red',          # pvl-san
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   148
    4:      'yellow',       # pvl-veturi
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   149
    7:      'orange',       # pvl-ranssi
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   150
    8:      'green',        # pvl-mgmt
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   151
    10:     'brown',        # pvl-public
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   152
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   153
    100:    'red',          # test
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   154
    102:    'red',          # ganeti
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   155
    103:    'red',          # test-san
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   156
    104:    'red',          # pvl-ganeti
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   157
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   158
    192:    'green',        # paivola-services
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   159
    255:    'purple',       # pvl-sonera
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
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   162
def apply_graph (options, items, vlans={}) :
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   163
    import pydot
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   164
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   165
    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
   166
            # XXX: breaks multi-edges?
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   167
            #splines     = 'true',
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   168
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   169
            sep             = '+25,25',
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   170
            overlap         = 'scalexy',
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   171
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   172
            # only applies to loops
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   173
            nodesep     = 0.5,
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   174
    )
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   175
    dot.set_edge_defaults(
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   176
            labeldistance   = 3.0,
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   177
            penwidth        = 2.0,
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   178
    )
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   179
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   180
    nodes = { }
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   181
    edges = { }
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   182
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   183
    for host, local, remote, remote_host in items :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   184
        # src
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   185
        src_name = str(host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   186
        src_label = '"{host.location}"'.format(host=host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   187
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   188
        if src_name in nodes :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   189
            src = nodes[src_name]
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   190
        else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   191
            src = nodes[src_name] = pydot.Node(src_name, label=src_label)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   192
            dot.add_node(src)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   193
        
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   194
        # dst
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   195
        if remote_host :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   196
            dst_name = str(remote_host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   197
            dst_label = '"{host.location}"'.format(host=remote_host)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   198
        else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   199
            dst_name = remote['chassis'].replace(':', '-')
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   200
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   201
            # 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
   202
            if remote['sys_name'] :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   203
                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
   204
            else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   205
                dst_label = '"{remote[chassis]}"'.format(remote=remote)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   206
        
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   207
        if dst_name in nodes :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   208
            dst = nodes[dst_name]
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   209
        else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   210
            dst = nodes[dst_name] = pydot.Node(dst_name, label=dst_label)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   211
            dot.add_node(dst)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   212
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   213
        # edges
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   214
        headlabel = '"{remote[port]}"'.format(remote=remote)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   215
        taillabel = '"{local[port]}"'.format(local=local)
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   216
        fillcolor = None
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   217
        color = None
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   218
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   219
        # vlans?
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   220
        if host in vlans and local['port_id'] in vlans[host] :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   221
            untag, tagged = vlans[host][local['port_id']]
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   222
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   223
            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
   224
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   225
            colors = []
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   226
            for tag in sorted(tagged) :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   227
                if tag in COLOR_VLANS :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   228
                    colors.append(COLOR_VLANS[tag])
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   229
                else :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   230
                    log.warn("%s#%s: unknown vlan %s", host, local['port_id'], tag)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   231
                    colors.append('black')
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   232
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   233
            if untag and untag in COLOR_VLANS :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   234
                fillcolor = COLOR_VLANS[untag]
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   235
            elif untag :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   236
                log.warn("%s#%s: no color for vlan %s", host, local['port_id'], untag)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   237
            
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   238
            # first color overrides fillcolor for heads
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   239
            if colors and fillcolor :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   240
                color = ':'.join([fillcolor] + colors)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   241
            elif colors :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   242
                color = ':'.join(colors)
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   243
            elif fillcolor :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   244
                color = fillcolor
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   245
            else :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   246
                color = 'black'
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   247
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   248
            if not fillcolor :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   249
                fillcolor = 'black'
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   250
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   251
        elif vlans :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   252
            # 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
   253
            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
   254
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   255
            untag = tag = None
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   256
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   257
        # edge
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   258
        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
   259
            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
   260
        
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   261
        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
   262
            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
   263
            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
   264
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   265
            if edge.get('headlabel') != taillabel :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   266
                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
   267
            
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   268
            if edge.get('taillabel') != headlabel :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   269
                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
   270
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   271
            if edge.get('fillcolor') != fillcolor :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   272
                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
   273
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   274
            if edge.get('color') != '"' + color + '"' :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   275
                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
   276
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   277
            # mark as bidirectional
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   278
            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
   279
            
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   280
            edge.set('dir', 'both' if untag else 'none')
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   281
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   282
            # set second color for tail
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   283
            if untag :
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   284
                edge.set('color', '"{headcolor}:{tailcolor}{tagcolors}"'.format(
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   285
                    headcolor   = edge.get('fillcolor'),
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   286
                    tailcolor   = fillcolor,
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   287
                    tagcolors   = ':' + ':'.join(colors) if colors else '',
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   288
                ))
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   289
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   290
        else :
388
5a034dbd641c pvl.hosts-lldp: support multiple edges between nodes
Tero Marttila <terom@paivola.fi>
parents: 387
diff changeset
   291
            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
   292
                    dir         = 'forward' if untag else 'none',
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   293
                    headlabel   = headlabel,
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   294
                    taillabel   = taillabel,
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   295
                    color       = '"{color}"'.format(color=color) if color else 'black',
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   296
                    fillcolor   = fillcolor or 'black',
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   297
            )
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   298
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   299
            dot.add_edge(edge)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   300
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   301
    if options.graph_dot :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   302
        dot.write(options.graph_dot)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   303
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   304
def main (argv) :
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   305
    """
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   306
        SNMP polling.
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   307
    """
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   308
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   309
    parser = optparse.OptionParser(main.__doc__)
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   310
    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
   311
    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
   312
    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
   313
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   314
    parser.add_option('--graph-dot',
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   315
            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
   316
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   317
    # input
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   318
    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
   319
    pvl.args.apply(options)
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   320
382
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   321
    hosts = pvl.hosts.apply(options, args)
ba47a64f61f9 pvl.hosts-lldp: refactor lldp collection schema
Tero Marttila <terom@paivola.fi>
parents: 380
diff changeset
   322
    
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   323
    # lookup host-port-vlan mappings
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   324
    vlans = dict(apply_hosts_vlan(options, hosts))
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   325
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   326
    # discover node/port graph
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   327
    items = apply_hosts_lldp(options, hosts)
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   328
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   329
    # print
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   330
    if options.graph_dot :
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   331
        apply_graph(options, items, vlans)
387
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   332
    else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   333
        for host, local, remote, remote_host in items :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   334
            if remote_host :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   335
                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
   336
            else :
75158fd28784 pvl.hosts-lldp: --graph-dot support
Tero Marttila <terom@paivola.fi>
parents: 386
diff changeset
   337
                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='')
391
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   338
        
e2c367b1556f pvl.hosts-lldp: add VLAN support
Tero Marttila <terom@paivola.fi>
parents: 388
diff changeset
   339
380
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   340
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   341
if __name__ == '__main__':
78f192fe9e2c pvl.hosts-lldp: snmp-based lldp discovery of connected switches
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   342
    pvl.args.main(main)