Wei-Yu Chen | bd495ba | 2021-08-31 19:46:35 +0800 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | # SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org> |
| 4 | # SPDX-License-Identifier: Apache-2.0 |
| 5 | |
| 6 | # nbhelper.py |
| 7 | # Helper functions for building YAML output from Netbox API calls |
| 8 | |
| 9 | import netaddr |
| 10 | |
| 11 | from .utils import logger, check_name_dns |
| 12 | from .container import PrefixContainer |
Wei-Yu Chen | bd495ba | 2021-08-31 19:46:35 +0800 | [diff] [blame] | 13 | |
| 14 | |
| 15 | class Prefix: |
| 16 | def __init__(self, data, name_segments): |
| 17 | from .utils import netboxapi |
| 18 | |
| 19 | self.data = data |
| 20 | self.name_segments = name_segments |
| 21 | self.nbapi = netboxapi |
| 22 | |
| 23 | if self.data.description: |
| 24 | self.domain_extension = check_name_dns(self.data.description) |
| 25 | |
| 26 | # ip centric info |
| 27 | self.subnet = self.data.prefix |
| 28 | self.dhcp_range = list() |
| 29 | self.routes = list() |
| 30 | self.reserved_ips = {} |
| 31 | |
| 32 | self.neighbor = list() |
| 33 | |
| 34 | # build item lists |
| 35 | self.build_prefix() |
| 36 | |
| 37 | # Find the neighbor relationship in prefix level |
| 38 | self.find_neighbor() |
| 39 | |
| 40 | PrefixContainer().add(self.data.prefix, self) |
| 41 | |
| 42 | def __repr__(self): |
| 43 | return str(self.data.prefix) |
| 44 | |
| 45 | def check_ip_belonging(self, ip): |
| 46 | """ |
| 47 | Check if an IP address is belonging to this prefix |
| 48 | """ |
| 49 | return ip in netaddr.IPSet([self.data.prefix]) |
| 50 | |
| 51 | def find_neighbor(self): |
| 52 | |
| 53 | parent_prefixes = list() |
| 54 | for prefix in PrefixContainer().all(): |
| 55 | if not prefix.data.description: |
| 56 | parent_prefixes.append(prefix) |
| 57 | |
| 58 | for prefix in PrefixContainer().all(): |
| 59 | if not prefix.data.description: |
| 60 | continue |
| 61 | |
| 62 | targetSubnet = netaddr.IPNetwork(prefix.subnet) |
| 63 | mySubnet = netaddr.IPNetwork(self.subnet) |
| 64 | |
| 65 | for parent in parent_prefixes: |
| 66 | parentSubnet = netaddr.IPNetwork(parent.subnet) |
| 67 | if mySubnet in parentSubnet and targetSubnet in parentSubnet: |
| 68 | if prefix not in self.neighbor: |
| 69 | self.neighbor.append(prefix) |
| 70 | if self not in prefix.neighbor: |
| 71 | prefix.neighbor.append(self) |
| 72 | |
Wei-Yu Chen | bd495ba | 2021-08-31 19:46:35 +0800 | [diff] [blame] | 73 | def build_prefix(self): |
| 74 | """ |
| 75 | find ip information for items (devices/vms, reserved_ips, dhcp_range) in prefix |
| 76 | """ |
| 77 | ips = self.nbapi.ipam.ip_addresses.filter(parent=self.data.prefix) |
| 78 | |
| 79 | for ip in sorted(ips, key=lambda k: k["address"]): |
| 80 | |
| 81 | logger.debug("prefix_item ip: %s, data: %s", ip, dict(ip)) |
| 82 | |
| 83 | # if it's a DHCP range, add that range to the dev list as prefix_dhcp |
| 84 | if ip.status.value == "dhcp": |
| 85 | self.dhcp_range.append(str(ip.address)) |
| 86 | |
| 87 | # reserved IPs |
| 88 | if ip.status.value == "reserved": |
| 89 | self.reserved_ips[str(ip)] = { |
| 90 | "name": ip.description.lower().split(" ")[0], |
| 91 | "description": ip.description, |
| 92 | "ip4": str(ip.address), |
| 93 | "custom_fields": ip.custom_fields, |
| 94 | } |
Wei-Yu Chen | c7d6831 | 2021-09-14 17:12:34 +0800 | [diff] [blame] | 95 | |
| 96 | rfc3442routes = ip.custom_fields.get("rfc3442routes") |
| 97 | rfc3442routes = rfc3442routes.split(",") if rfc3442routes else list() |
| 98 | |
Wei-Yu Chen | bd495ba | 2021-08-31 19:46:35 +0800 | [diff] [blame] | 99 | self.routes.append( |
| 100 | { |
Wei-Yu Chen | c7d6831 | 2021-09-14 17:12:34 +0800 | [diff] [blame] | 101 | "ip": str(netaddr.IPNetwork(ip.address).ip), |
| 102 | "rfc3442routes": rfc3442routes, |
Wei-Yu Chen | bd495ba | 2021-08-31 19:46:35 +0800 | [diff] [blame] | 103 | } |
| 104 | ) |