167 Combine given snmp data and { host: Host } into |
167 Combine given snmp data and { host: Host } into |
168 { node: label } |
168 { node: label } |
169 { (remote, remote_port, local_port, local): (local_untag, tagged, remote_untag) } |
169 { (remote, remote_port, local_port, local): (local_untag, tagged, remote_untag) } |
170 """ |
170 """ |
171 |
171 |
172 nodes = { } |
172 nodes = { } # host: label |
173 links = { } |
173 links = { } |
|
174 |
|
175 hosts_by_lldp = { } |
174 |
176 |
175 # first scan: lldp hosts |
177 # first scan: lldp hosts |
176 for host, host_attrs in snmp.iteritems() : |
178 for host, host_attrs in snmp.iteritems() : |
177 lldp = host_attrs.get('lldp') |
179 lldp = host_attrs.get('lldp') |
178 |
180 |
179 if lldp : |
181 if lldp : |
180 lldp_local = lldp['local'] |
182 lldp_local = lldp['local'] |
|
183 local = lldp_local['chassis'] |
181 |
184 |
182 nodes[lldp_local['chassis']] = host.location |
185 nodes[host] = host.location |
|
186 hosts_by_lldp[local] = host |
183 |
187 |
184 # second scan: lldp remotes |
188 # second scan: lldp remotes |
185 for host, host_attrs in snmp.iteritems() : |
189 for host, host_attrs in snmp.iteritems() : |
186 lldp = host_attrs.get('lldp') |
190 lldp = host_attrs.get('lldp') |
187 |
191 |
188 if not lldp : |
192 if not lldp : |
189 continue |
193 continue |
190 |
194 |
191 local = lldp['local']['chassis'] |
195 local = lldp['local']['chassis'] |
|
196 local_node = host |
192 |
197 |
193 if 'vlan' in host_attrs : |
198 if 'vlan' in host_attrs : |
194 vlans = dict(host_vlans(host, host_attrs['vlan'])) |
199 vlans = dict(host_vlans(host, host_attrs['vlan'])) |
195 else : |
200 else : |
196 vlans = None |
201 vlans = None |
197 |
202 |
198 for port, port_attrs in lldp.get('port', { }).iteritems() : |
203 for port, port_attrs in lldp.get('port', { }).iteritems() : |
199 local_port = port_attrs['local']['port'] |
204 local_port = port_attrs['local']['port'] |
200 |
205 |
201 for remote, remote_attrs in port_attrs['remote'].iteritems() : |
206 for remote, remote_attrs in port_attrs['remote'].iteritems() : |
202 if remote not in nodes : |
207 if remote in hosts_by_lldp : |
203 nodes[remote] = remote_attrs['sys_name'] |
208 remote_node = hosts_by_lldp[remote] |
|
209 else : |
|
210 remote_node = remote |
|
211 |
|
212 # non-snmp lldp host |
|
213 nodes[remote_node] = remote_attrs['sys_name'] |
204 |
214 |
205 remote_port = remote_attrs['port'] |
215 remote_port = remote_attrs['port'] |
206 |
216 |
207 # local vlans |
217 # local vlans |
208 if vlans : |
218 if vlans : |
212 |
222 |
213 if port_vlans : |
223 if port_vlans : |
214 local_untag, local_tagged = port_vlans |
224 local_untag, local_tagged = port_vlans |
215 |
225 |
216 # bidirectional mappings |
226 # bidirectional mappings |
217 forward = (local, local_port, remote_port, remote) |
227 forward = (local_node, local_port, remote_port, remote_node) |
218 reverse = (remote, remote_port, local_port, local) |
228 reverse = (remote_node, remote_port, local_port, local_node) |
219 |
229 |
220 if reverse not in links : |
230 if reverse not in links : |
221 links[forward] = (local_untag, local_tagged, None) |
231 links[forward] = (local_untag, local_tagged, None) |
222 else : |
232 else : |
223 remote_untag, remote_tagged, _ = links[reverse] |
233 remote_untag, remote_tagged, _ = links[reverse] |
224 |
234 |
225 # merge |
235 # merge |
226 if remote_untag != local_untag : |
236 if remote_untag != local_untag : |
227 log.warning("%s:%s untag %s <=> %s untag %s:%s", |
237 log.warning("%s:%s untag %s <=> %s untag %s:%s", |
228 nodes[local], local_port, local_untag, |
238 host, local_port, local_untag, |
229 remote_untag, nodes[remote], remote_port |
239 remote_untag, remote_node, remote_port |
230 ) |
240 ) |
231 |
241 |
232 if remote_tagged != local_tagged : |
242 if remote_tagged != local_tagged : |
233 log.warning("%s:%s tagged %s <-> %s tagged %s:%s", |
243 log.warning("%s:%s tagged %s <-> %s tagged %s:%s", |
234 nodes[local], local_port, ':'.join(str(x) for x in sorted(local_tagged)), |
244 host, local_port, ':'.join(str(x) for x in sorted(local_tagged)), |
235 ':'.join(str(x) for x in sorted(remote_tagged)), nodes[remote], remote_port |
245 ':'.join(str(x) for x in sorted(remote_tagged)), remote_node, remote_port |
236 ) |
246 ) |
237 |
247 |
238 links[reverse] = (remote_untag, remote_tagged, local_untag) |
248 links[reverse] = (remote_untag, remote_tagged, local_untag) |
239 |
249 |
240 return nodes, links |
250 return nodes, links |