|
@@ -6,6 +6,8 @@ import ipaddress
|
|
|
import re
|
|
|
from copy import deepcopy
|
|
|
|
|
|
+import ffho
|
|
|
+
|
|
|
mac_prefix = "f2"
|
|
|
|
|
|
# VRF configuration map
|
|
@@ -82,19 +84,6 @@ loopback_prefix = {
|
|
|
}
|
|
|
|
|
|
|
|
|
-# The DNS zone base names used for generating zone files from IP address
|
|
|
-# configured on nodes interfaces.
|
|
|
-DNS_zone_names = {
|
|
|
- 'forward' : 'ffho.net',
|
|
|
- 'rev_v4' : [
|
|
|
- '132.10.in-addr.arpa',
|
|
|
- '30.172.in-addr.arpa',
|
|
|
- ],
|
|
|
- 'rev_v6' : [
|
|
|
- '2.4.3.2.0.6.2.2.3.0.a.2.ip6.arpa',
|
|
|
- ]
|
|
|
-}
|
|
|
-
|
|
|
# MTU configuration
|
|
|
MTU = {
|
|
|
# The default MTU for any interface which does not have a MTU configured
|
|
@@ -1023,21 +1012,13 @@ def get_interface_config (node_config, sites_config, node_id = ""):
|
|
|
|
|
|
vlan_vxlan_iface_re = re.compile (r'^vlan(\d+)|^vx_v(\d+)_(\w+)')
|
|
|
|
|
|
-def _cmp (x, y):
|
|
|
- if x < y:
|
|
|
- return -1
|
|
|
- elif x == y:
|
|
|
- return 0
|
|
|
- else:
|
|
|
- return 1
|
|
|
-
|
|
|
def _iface_sort (iface_a, iface_b):
|
|
|
a = vlan_vxlan_iface_re.search (iface_a)
|
|
|
b = vlan_vxlan_iface_re.search (iface_b)
|
|
|
|
|
|
# At least one interface didn't match, do regular comparison
|
|
|
if not a or not b:
|
|
|
- return _cmp (iface_a, iface_b)
|
|
|
+ return ffho.cmp (iface_a, iface_b)
|
|
|
|
|
|
# Extract VLAN ID from VLAN interface (if given) or VXLAN
|
|
|
vid_a = a.group (1) if a.group (1) else a.group (2)
|
|
@@ -1045,17 +1026,17 @@ def _iface_sort (iface_a, iface_b):
|
|
|
|
|
|
# If it's different type of interfaces (one VLAN, one VXLAN), do regular comparison
|
|
|
if (a.group (1) == None) != (b.group (1) == None):
|
|
|
- return _cmp (iface_a, iface_b)
|
|
|
+ return ffho.cmp (iface_a, iface_b)
|
|
|
|
|
|
# Ok, t's two VLAN or two VXLAN interfaces
|
|
|
|
|
|
# If it's VXLAN interfaces and the VLAN ID is the same, sort by site name
|
|
|
if a.group (2) and vid_a == vid_b:
|
|
|
- return _cmp (a.groups (2), b.groups (2))
|
|
|
+ return ffho.cmp (a.groups (2), b.groups (2))
|
|
|
|
|
|
# If it's two VLANs or two VXLANs with different VLAN IDs, sort by VLAN ID
|
|
|
else:
|
|
|
- return _cmp (int (vid_a), int (vid_b))
|
|
|
+ return ffho.cmp (int (vid_a), int (vid_b))
|
|
|
|
|
|
|
|
|
def get_interface_list (ifaces):
|
|
@@ -1415,93 +1396,6 @@ def get_te_prefixes (te_node_config, grains_id, proto):
|
|
|
return te_config
|
|
|
|
|
|
|
|
|
-
|
|
|
-def generate_DNS_entries (nodes_config, sites_config):
|
|
|
- forward_zone_name = ""
|
|
|
- forward_zone = []
|
|
|
- zones = {
|
|
|
- # <forward_zone_name>: [],
|
|
|
- # <rev_zone1_name>: [],
|
|
|
- # <rev_zone2_name>: [],
|
|
|
- # ...
|
|
|
- }
|
|
|
-
|
|
|
- # Fill zones dict with zones configured in DNS_zone_names at the top of this file.
|
|
|
- # Make sure the zone base names provided start with a leading . so the string
|
|
|
- # operations later can be done easily and safely. Proceed with fingers crossed.
|
|
|
- for entry, value in DNS_zone_names.items ():
|
|
|
- if entry == "forward":
|
|
|
- zone = value
|
|
|
- if not zone.startswith ('.'):
|
|
|
- zone = ".%s" % zone
|
|
|
-
|
|
|
- zones[zone] = forward_zone
|
|
|
- forward_zone_name = zone
|
|
|
-
|
|
|
- if entry in [ 'rev_v4', 'rev_v6' ]:
|
|
|
- for zone in value:
|
|
|
- if not zone.startswith ('.'):
|
|
|
- zone = ".%s" % zone
|
|
|
-
|
|
|
- zones[zone] = []
|
|
|
-
|
|
|
-
|
|
|
- # Process all interfaace of all nodes defined in pillar and generate forward
|
|
|
- # and reverse entries for all zones defined in DNS_zone_names. Automagically
|
|
|
- # put reverse entries into correct zone.
|
|
|
- for node_id in sorted (nodes_config):
|
|
|
- node_config = nodes_config.get (node_id)
|
|
|
- ifaces = get_interface_config (node_config, sites_config, node_id)
|
|
|
-
|
|
|
- for iface in sorted (ifaces):
|
|
|
- iface_config = ifaces.get (iface)
|
|
|
-
|
|
|
- # We only care for interfaces with IPs configured
|
|
|
- prefixes = iface_config.get ("prefixes", None)
|
|
|
- if prefixes == None:
|
|
|
- continue
|
|
|
-
|
|
|
- # Ignore any interface in $VRF
|
|
|
- if iface_config.get ('vrf', "") in [ 'vrf_external' ]:
|
|
|
- continue
|
|
|
-
|
|
|
- for prefix in sorted (prefixes):
|
|
|
- ip = ipaddress.ip_address (u'%s' % prefix.split ('/')[0])
|
|
|
- proto = 'v%s' % ip.version
|
|
|
-
|
|
|
- # The entry name is
|
|
|
- # <node_id> when interface 'lo'
|
|
|
- # <node_name>.srv.<residual> when interface 'srv' (or magically detected internal srv record)
|
|
|
- # <interface>.<node_id> else
|
|
|
- entry_name = node_id
|
|
|
- if iface != "lo":
|
|
|
- entry_name = "%s.%s" % (iface, node_id)
|
|
|
-
|
|
|
- elif iface == 'srv' or re.search (r'^(10.132.251|2a03:2260:2342:f251:)', prefix):
|
|
|
- entry_name = re.sub (r'^([^.]+)\.(.+)$', r'\g<1>.srv.\g<2>', entry_name)
|
|
|
-
|
|
|
-
|
|
|
- # Strip forward zone name from entry_name and store forward entry
|
|
|
- # with correct entry type for found IP address.
|
|
|
- forward_entry_name = re.sub (forward_zone_name, "", entry_name)
|
|
|
- forward_entry_name = re.sub (forward_zone_name, "", entry_name)
|
|
|
- forward_entry_typ = "A" if ip.version == 4 else "AAAA"
|
|
|
- forward_zone.append ("%s IN %s %s" % (forward_entry_name, forward_entry_typ, ip))
|
|
|
-
|
|
|
- # Find correct reverse zone, if configured and strip reverse zone name
|
|
|
- # from calculated reverse pointer name. Store reverse entry if we found
|
|
|
- # a zone for it. If no configured reverse zone did match, this reverse
|
|
|
- # entry will be ignored.
|
|
|
- for zone in zones:
|
|
|
- if ip.reverse_pointer.find (zone) > 0:
|
|
|
- PTR_entry = re.sub (zone, "", ip.reverse_pointer)
|
|
|
- zones[zone].append ("%s IN PTR %s." % (PTR_entry, entry_name))
|
|
|
-
|
|
|
- break
|
|
|
-
|
|
|
- return zones
|
|
|
-
|
|
|
-
|
|
|
# Convert the CIDR network from the given prefix into a dotted netmask
|
|
|
def cidr_to_dotted_mask (prefix):
|
|
|
return str (ipaddress.ip_network (prefix, strict = False).netmask)
|