Determine DHCP vs static via nmcli; fall back to APIPA / heuristic. Returns 'dhcp', 'static', 'dhcp-failed' (APIPA 169.254), 'link-down', or 'unknown'.
(iface, v4)
| 527 | ifaces = data.get('lldp', {}).get('interface', []) |
| 528 | if isinstance(ifaces, dict): |
| 529 | ifaces = [ifaces] |
| 530 | for entry in ifaces: |
| 531 | for local_if, info in entry.items(): |
| 532 | neighbors.append(_parse_lldp_iface(local_if, info)) |
| 533 | except ValueError as e: |
| 534 | return {'success': False, 'error': f'could not parse lldpctl output: {e}', |
| 535 | 'interface': interface, 'neighbors': [], 'output': res['out']} |
| 536 | if not neighbors: |
| 537 | note = ('No neighbors yet? Switches announce every ~30s; give it up ' |
| 538 | 'to a minute after connecting, and ensure the port isn\'t on a hub.') |
| 539 | if interface: |
| 540 | note = (f'No neighbours on {interface}. ' + note + |
| 541 | ' If the cable is on a different port, switch to Auto (all ' |
| 542 | 'interfaces) to see every neighbour this box can hear.') |
| 543 | else: |
| 544 | note = None |
| 545 | return {'success': True, 'interface': interface, 'neighbors': neighbors, |
| 546 | 'note': note} |
| 547 | |
| 548 | |
| 549 | def _first_key(d): |
| 550 | """lldpctl json nests some objects under a single dynamic key (e.g. the |
| 551 | chassis name). Return (key, value) of the first item, or (None, {}).""" |
| 552 | if isinstance(d, dict) and d: |
| 553 | k = next(iter(d)) |
| 554 | return k, d[k] |
| 555 | return None, {} |
| 556 |
no test coverage detected