bin/pvl.hosts-graph
changeset 404 78e3d83135ab
parent 402 3b6fb4ae56fb
child 405 97b436f9363a
equal deleted inserted replaced
403:9bae04e1780c 404:78e3d83135ab
    41     if part.isdigit() :
    41     if part.isdigit() :
    42         return int(part)
    42         return int(part)
    43     else :
    43     else :
    44         return part
    44         return part
    45 
    45 
    46 def _parse_snmp_line (line) :
    46 def _parse_snmp_attr (line) :
    47     for part in line.split() :
    47     for part in line.split() :
    48         yield _parse_snmp_part(part)
    48         yield _parse_snmp_part(part)
    49 
    49 
    50 def _parse_snmp_attr (line) :
    50 def _parse_snmp_value (line) :
    51     parts = line.split()
    51     if '\t' in line :
    52 
    52         key, value = line.split('\t', 1)
    53     key = parts.pop(0)
    53 
    54 
    54         return { _parse_snmp_part(key): _parse_snmp_part(value) }
    55     if len(parts) == 0 :
       
    56         return key, None
       
    57 
       
    58     elif len(parts) == 1 :
       
    59         value, = parts
       
    60 
       
    61         return key, value
       
    62 
    55 
    63     else :
    56     else :
    64         return key, parts
    57         return set((_parse_snmp_part(line), ))
    65 
    58     
    66 def _load_snmp_data (options, file) :
    59 def _load_snmp_data (options, file) :
    67     """
    60     """
    68         Load a data dict generated by pvl.hosts-snmp from a file.
    61         Load a data dict generated by pvl.hosts-snmp from a file.
    69 
    62 
    70         Yields (host, attr, value)
    63         Yields (host, attr, value)
    71     """
    64     """
    72 
    65 
    73     host = None
    66     host = None
    74     attr = None
    67     attr = None
    75     value = None
    68     value = None
    76     values = None
       
    77     
    69     
    78     for idx, line in enumerate(file, 1) :
    70     for idx, line in enumerate(file, 1) :
    79         indent = 0
    71         indent = 0
    80 
    72 
    81         while line.startswith('\t') :
    73         while line.startswith('\t') :
    82             indent += 1
    74             indent += 1
    83             line = line[1:]
    75             line = line[1:]
    84 
    76 
    85         line = line.strip()
    77         line = line.lstrip('\t').rstrip('\n')
    86 
       
    87         if '\t' in line :
       
    88             args = line.split('\t')
       
    89 
       
    90             line = args.pop(0)
       
    91             args = tuple(args)
       
    92         else :
       
    93             args = None
       
    94 
    78 
    95         if indent == 0 :
    79         if indent == 0 :
    96             host = line
    80             host = line
    97             attr = None
    81             attr = None
    98             value = None
    82             value = None
    99             values = None
       
   100 
    83 
   101         elif indent == 1 :
    84         elif indent == 1 :
   102             if attr and not value and not values :
    85             attr = tuple(_parse_snmp_attr(line))
   103                 raise ParseError(file, line, "[%s] %s: no value" % (host, attr))
    86             value = None
   104 
    87 
   105             attr = tuple(_parse_snmp_line(line))
    88             yield host, attr, None
   106 
       
   107             if args :
       
   108                 value = dict(_parse_snmp_attr(arg) for arg in args)
       
   109             else :
       
   110                 value = None
       
   111             
       
   112             values = None
       
   113 
       
   114             if value :
       
   115                 yield host, attr, value
       
   116 
    89 
   117         elif indent == 2 :
    90         elif indent == 2 :
   118             if not attr :
    91             if not attr :
   119                 raise ParseError(file, line, "[%s] %s: value outside of attr" % (host, attr))
    92                 raise ParseError(file, line, "[%s] %s: value outside of attr" % (host, attr))
   120             
    93             
   121             if value :
    94             value = _parse_snmp_value(line)
   122                 raise ParseError(file, line, "[%s] %s: values with value" % (host, attr))
    95 
   123 
    96             yield host, attr, value
   124             values = _parse_snmp_part(line)
       
   125 
       
   126             yield host, attr, set((values, ))
       
   127 
    97 
   128 def load_snmp_data (options, file, hosts) :
    98 def load_snmp_data (options, file, hosts) :
   129     """
    99     """
   130         Load snmp data as dict, from given file path, or stdin.
   100         Load snmp data as dict, from given file path, or stdin.
   131     """
   101     """
   137 
   107 
   138     root = { }
   108     root = { }
   139 
   109 
   140     for host_name, attr, value in _load_snmp_data(options, file) :
   110     for host_name, attr, value in _load_snmp_data(options, file) :
   141         host = hosts.get(host_name)
   111         host = hosts.get(host_name)
   142 
   112         
   143         log.info("[%s] %s%s", host, ' '.join(str(a) for a in attr), (': ' + str(value)) if value else '')
   113         if value :
       
   114             log.info("[%s] %s: %s", host, ' '.join(str(a) for a in attr), value)
       
   115         else :
       
   116             log.info("[%s] %s", host, ' '.join(str(a) for a in attr),)
   144 
   117 
   145         item = root.setdefault(host, { })
   118         item = root.setdefault(host, { })
   146         
   119         
   147         for a in attr[:-1] :
   120         for a in attr[:-1] :
   148             item = item.setdefault(a, {})
   121             item = item.setdefault(a, {})
   149 
   122 
   150         a = attr[-1]
   123         a = attr[-1]
   151         
   124         
   152         if isinstance(value, set) :
   125         if value is None :
       
   126             pass
       
   127 
       
   128         elif isinstance(value, set) :
   153             item.setdefault(a, set()).update(value)
   129             item.setdefault(a, set()).update(value)
       
   130 
       
   131         elif isinstance(value, dict) :
       
   132             item.setdefault(a, dict()).update(value)
   154 
   133 
   155         else :
   134         else :
   156             item[a] = value
   135             item[a] = value
   157             
   136             
   158     return root
   137     return root
   170             for port in snmp[host]['vlan'][vlan].get('tagged', ()) :
   149             for port in snmp[host]['vlan'][vlan].get('tagged', ()) :
   171                 ports.add(port)
   150                 ports.add(port)
   172                 vlans_tagged[port].add(vlan)
   151                 vlans_tagged[port].add(vlan)
   173             
   152             
   174             for port in snmp[host]['vlan'][vlan].get('untagged', ()) :
   153             for port in snmp[host]['vlan'][vlan].get('untagged', ()) :
       
   154                 ports.add(port)
   175                 vlans_untagged[port] = vlan
   155                 vlans_untagged[port] = vlan
   176         
   156         
   177         out = { }
   157         out = { }
   178         for port in ports :
   158         for port in ports :
   179             untag = vlans_untagged.get(port)
   159             untag = vlans_untagged.get(port)
   180             tagged = vlans_tagged.get(port)
   160             tagged = vlans_tagged.get(port, ())
   181 
   161 
   182             log.info("%s: %s: untag=%s tag=%s", host, port, untag, tagged)
   162             log.info("%s: %s: untag=%s tag=%s", host, port, untag, tagged)
   183 
   163 
   184             out[port] = (untag, tagged)
   164             out[port] = (untag, tagged)
   185 
   165