/demo-gc-templates

Nautobot Demo Data: Golden Configuration Demo Templates

Primary LanguageJinja

nautobot-gc-templates

This is demo repo to hold backup configurations for the purpose nautobot golden config plugin.

The templates provided here are leveraging the the following GraphQL Query and transposer with Shorten the SoT data returned turned on.

query ($device: String!) {
  devices(name: $device) {
    config_context
    name
    position
    serial
    primary_ip4 {
      id
      primary_ip4_for {
        id
        name
      }
    }
    tenant {
      name
    }
    tags {
      name
      slug
    }
    device_role {
      name
    }
    platform {
      name
      slug
      manufacturer {
        name
      }
      napalm_driver
    }
    site {
      name
      slug
      vlans {
        id
        name
        vid
      }
      vlan_groups {
        id
      }
    }
    interfaces {
      description
      mac_address
      enabled
      name
      cpf_ntc_description
      ip_addresses {
        address
        tags {
          id
        }
      }
      connected_circuit_termination {
        circuit {
          cid
          commit_rate
          provider {
            name
          }
        }
      }
      tagged_vlans {
        id
      }
      untagged_vlan {
        id
      }
      cable {
        termination_a_type
        status {
          name
        }
        color
      }
      tagged_vlans {
        site {
          name
        }
        id
      }
      tags {
        id
      }
    }
  }
}

Transposer

"""Details."""
import ipaddress
# Can take the returned data from the graphql query and can modify the data before sending to the jinja2 template.
def transposer(data):
    """Some."""
    if len(data["site"]["vlans"]) > 0:
        data["vlans_merged_list"] = vlan_parser(
            [vlan["vid"] for vlan in data["site"]["vlans"]]
        )
    if data["platform"]["slug"] == "cisco_ios":
        expand_prefix(data["interfaces"])
    if data["platform"]["slug"] == "cisco_nxos":
        format_mac_to_nxos(data["interfaces"])
    return data
    # return data["interfaces"]
def expand_prefix(interfaces):
    """Some."""
    for interface in interfaces:
        if len(interface["ip_addresses"]) > 0:
            for addr in interface["ip_addresses"]:
                addr["address"] = ipaddress.ip_interface(addr["address"]).with_netmask.replace("/", " ")
    return interfaces
def format_mac_to_nxos(interfaces):
    """Some."""
    for interface in interfaces:
        if interface.get("mac_address"):
            mac = ".".join(interface.get("mac_address").lower().replace(":", "")[i : i + 4] for i in range(0, 12, 4))
            interface["mac_address"] = mac
    return interfaces
# reference: https://github.com/ansible/ansible/blob/stable-2.9/lib/ansible/plugins/filter/network.py
def vlan_parser(vlan_list, first_line_len=48, other_line_len=44):  # pylint: disable=too-many-branches
    """Input: Unsorted list of vlan integer.

    Output: Sorted string list of integers according to cisco_ios-like vlan list rules
    1. Vlans are listed in ascending order
    2. Runs of 3 or more consecutive vlans are listed with a dash
    3. The first line of the list can be first_line_len characters long
    4. Subsequent list lines can be other_line_len characters
    """
    # Sort and remove duplicates
    sorted_list = sorted(set(vlan_list))
    if sorted_list[0] < 1 or sorted_list[-1] > 4094:
        raise ValueError("Valid VLAN range is 1-4094")
    parse_list = []
    idx = 0
    while idx < len(sorted_list):
        start = idx
        end = start
        while end < len(sorted_list) - 1:
            if sorted_list[end + 1] - sorted_list[end] == 1:
                end += 1
            else:
                break
        if start == end:
            # Single VLAN
            parse_list.append(str(sorted_list[idx]))
        elif start + 1 == end:
            # Run of 2 VLANs
            parse_list.append(str(sorted_list[start]))
            parse_list.append(str(sorted_list[end]))
        else:
            # Run of 3 or more VLANs
            parse_list.append(str(sorted_list[start]) + "-" + str(sorted_list[end]))
        idx = end + 1
    line_count = 0
    result = [""]
    for vlans in parse_list:
        # First line (" switchport trunk allowed vlan ")
        if line_count == 0:
            if len(result[line_count] + vlans) > first_line_len:
                result.append("")
                line_count += 1
                result[line_count] += vlans + ","
            else:
                result[line_count] += vlans + ","
        # Subsequent lines (" switchport trunk allowed vlan add ")
        else:
            if len(result[line_count] + vlans) > other_line_len:
                result.append("")
                line_count += 1
                result[line_count] += vlans + ","
            else:
                result[line_count] += vlans + ","
    # Remove trailing orphan commas
    for idx, value in enumerate(result):
        result[idx] = value.rstrip(",")
    # Sometimes text wraps to next line, but there are no remaining VLANs
    if "" in result:
        result.remove("")
    return result