Source code for _modules.netbox

# -*- coding: utf-8 -*-
"""
NetBox
======

Module to query NetBox

:codeauthor: Zach Moody <zmoody@do.co>
:maturity:   new
:depends:    pynetbox

.. note::

    This code, distributed as part of ``salt-sproxy``, has been copied from the
    main Salt project, maintained by SaltStack, to provide various enhancements
    and fixes to the original module.

The following config should be in the minion config file. In order to
work with ``secrets`` you should provide a token and path to your
private key file:

.. code-block:: yaml

  netbox:
    url: <NETBOX_URL>
    token: <NETBOX_USERNAME_API_TOKEN (OPTIONAL)>
    keyfile: </PATH/TO/NETBOX/KEY (OPTIONAL)>

.. versionadded:: 2018.3.0

    This module has been introduced in Salt release 2018.3.0.

    In ``salt-sproxy``, this module has been included beginning with version
    2019.10.0.
"""
from __future__ import absolute_import, unicode_literals, print_function

import re
import logging

from salt.exceptions import CommandExecutionError

try:
    import pynetbox
    from pynetbox import RequestError

    HAS_PYNETBOX = True
except ImportError:
    HAS_PYNETBOX = False

log = logging.getLogger(__name__)

AUTH_ENDPOINTS = ("secrets",)

__func_alias__ = {"filter_": "filter", "get_": "get"}


def __virtual__():
    """
    pynetbox must be installed.
    """
    if not HAS_PYNETBOX:
        return (
            False,
            "The netbox execution module cannot be loaded: "
            "pynetbox library is not installed.",
        )
    else:
        return True


def _config():
    config = __salt__["config.get"]("netbox")
    if not config:
        raise CommandExecutionError(
            "NetBox execution module configuration could not be found"
        )
    return config


def _nb_obj(auth_required=False):
    pynb_kwargs = {}
    pynb_kwargs["token"] = _config().get("token")
    if auth_required:
        pynb_kwargs["private_key_file"] = _config().get("keyfile")
    return pynetbox.api(_config().get("url"), **pynb_kwargs)


def _strip_url_field(input_dict):
    if "url" in input_dict.keys():
        del input_dict["url"]
    for k, v in input_dict.items():
        if isinstance(v, dict):
            _strip_url_field(v)
    return input_dict


def _dict(iterable):
    if iterable:
        return dict(iterable)
    else:
        return {}


def _add(app, endpoint, payload):
    """
    POST a payload
    """
    nb = _nb_obj(auth_required=True)
    try:
        return getattr(getattr(nb, app), endpoint).create(**payload)
    except RequestError as e:  # pylint: disable=undefined-variable
        log.error("%s, %s, %s", e.req.request.headers, e.request_body, e.error)
        return False


[docs]def slugify(value): """' Slugify given value. Credit to Djangoproject https://docs.djangoproject.com/en/2.0/_modules/django/utils/text/#slugify """ value = re.sub(r"[^\w\s-]", "", value).strip().lower() return re.sub(r"[-\s]+", "-", value)
def _get(app, endpoint, id=None, auth_required=False, **kwargs): """ Helper function to do a GET request to Netbox. Returns the actual pynetbox object, which allows manipulation from other functions. """ nb = _nb_obj(auth_required=auth_required) if id: item = getattr(getattr(nb, app), endpoint).get(id) else: kwargs = __utils__["args.clean_kwargs"](**kwargs) item = getattr(getattr(nb, app), endpoint).get(**kwargs) return item def _if_name_unit(if_name): if_name_split = if_name.split(".") if len(if_name_split) == 2: return if_name_split return if_name, "0"
[docs]def filter_(app, endpoint, **kwargs): """ Get a list of items from NetBox. app String of netbox app, e.g., ``dcim``, ``circuits``, ``ipam`` endpoint String of app endpoint, e.g., ``sites``, ``regions``, ``devices`` kwargs Optional arguments that can be used to filter. All filter keywords are available in Netbox, which can be found by surfing to the corresponding API endpoint, and clicking Filters. e.g., ``role=router`` Returns a list of dictionaries .. code-block:: bash salt myminion netbox.filter dcim devices status=1 role=router """ ret = [] nb = _nb_obj(auth_required=True if app in AUTH_ENDPOINTS else False) clean_kwargs = __utils__["args.clean_kwargs"](**kwargs) if not clean_kwargs: nb_query = getattr(getattr(nb, app), endpoint).all() else: nb_query = getattr(getattr(nb, app), endpoint).filter(**clean_kwargs) if nb_query: ret = [_strip_url_field(dict(i)) for i in nb_query] return ret
[docs]def get_(app, endpoint, id=None, **kwargs): """ Get a single item from NetBox. app String of netbox app, e.g., ``dcim``, ``circuits``, ``ipam`` endpoint String of app endpoint, e.g., ``sites``, ``regions``, ``devices`` Returns a single dictionary To get an item based on ID. .. code-block:: bash salt myminion netbox.get dcim devices id=123 Or using named arguments that correspond with accepted filters on the NetBox endpoint. .. code-block:: bash salt myminion netbox.get dcim devices name=my-router """ return _dict( _get( app, endpoint, id=id, auth_required=True if app in AUTH_ENDPOINTS else False, **kwargs ) )
[docs]def create_manufacturer(name): """ .. versionadded:: 2019.2.0 Create a device manufacturer. name The name of the manufacturer, e.g., ``Juniper`` CLI Example: .. code-block:: bash salt myminion netbox.create_manufacturer Juniper """ nb_man = get_("dcim", "manufacturers", name=name) if nb_man: return False else: payload = {"name": name, "slug": slugify(name)} man = _add("dcim", "manufacturers", payload) if man: return {"dcim": {"manufacturers": payload}} else: return False
[docs]def create_device_type(model, manufacturer): """ .. versionadded:: 2019.2.0 Create a device type. If the manufacturer doesn't exist, create a new manufacturer. model String of device model, e.g., ``MX480`` manufacturer String of device manufacturer, e.g., ``Juniper`` CLI Example: .. code-block:: bash salt myminion netbox.create_device_type MX480 Juniper """ nb_type = get_("dcim", "device-types", model=model) if nb_type: return False nb_man = get_("dcim", "manufacturers", name=manufacturer) new_man = None if not nb_man: new_man = create_manufacturer(manufacturer) payload = {"model": model, "manufacturer": nb_man["id"], "slug": slugify(model)} typ = _add("dcim", "device-types", payload) ret_dict = {"dcim": {"device-types": payload}} if new_man: ret_dict["dcim"].update(new_man["dcim"]) if typ: return ret_dict else: return False
[docs]def create_device_role(role, color): """ .. versionadded:: 2019.2.0 Create a device role role String of device role, e.g., ``router`` CLI Example: .. code-block:: bash salt myminion netbox.create_device_role router """ nb_role = get_("dcim", "device-roles", name=role) if nb_role: return False else: payload = {"name": role, "slug": slugify(role), "color": color} role = _add("dcim", "device-roles", payload) if role: return {"dcim": {"device-roles": payload}} else: return False
[docs]def create_platform(platform): """ .. versionadded:: 2019.2.0 Create a new device platform platform String of device platform, e.g., ``junos`` CLI Example: .. code-block:: bash salt myminion netbox.create_platform junos """ nb_platform = get_("dcim", "platforms", slug=slugify(platform)) if nb_platform: return False else: payload = {"name": platform, "slug": slugify(platform)} plat = _add("dcim", "platforms", payload) if plat: return {"dcim": {"platforms": payload}} else: return False
[docs]def create_site(site): """ .. versionadded:: 2019.2.0 Create a new device site site String of device site, e.g., ``BRU`` CLI Example: .. code-block:: bash salt myminion netbox.create_site BRU """ nb_site = get_("dcim", "sites", name=site) if nb_site: return False else: payload = {"name": site, "slug": slugify(site)} site = _add("dcim", "sites", payload) if site: return {"dcim": {"sites": payload}} else: return False
[docs]def create_device(name, role, model, manufacturer, site): """ .. versionadded:: 2019.2.0 Create a new device with a name, role, model, manufacturer and site. All these components need to be already in Netbox. name The name of the device, e.g., ``edge_router`` role String of device role, e.g., ``router`` model String of device model, e.g., ``MX480`` manufacturer String of device manufacturer, e.g., ``Juniper`` site String of device site, e.g., ``BRU`` CLI Example: .. code-block:: bash salt myminion netbox.create_device edge_router router MX480 Juniper BRU """ try: nb_role = get_("dcim", "device-roles", name=role) if not nb_role: return False nb_type = get_("dcim", "device-types", model=model) if not nb_type: return False nb_site = get_("dcim", "sites", name=site) if not nb_site: return False status = {"label": "Active", "value": 1} except RequestError as e: # pylint: disable=undefined-variable log.error("%s, %s, %s", e.req.request.headers, e.request_body, e.error) return False payload = { "name": name, "display_name": name, "slug": slugify(name), "device_type": nb_type["id"], "device_role": nb_role["id"], "site": nb_site["id"], } new_dev = _add("dcim", "devices", payload) if new_dev: return {"dcim": {"devices": payload}} else: return False
[docs]def update_device(name, **kwargs): """ .. versionadded:: 2019.2.0 Add attributes to an existing device, identified by name. name The name of the device, e.g., ``edge_router`` kwargs Arguments to change in device, e.g., ``serial=JN2932930`` CLI Example: .. code-block:: bash salt myminion netbox.update_device edge_router serial=JN2932920 """ kwargs = __utils__["args.clean_kwargs"](**kwargs) nb_device = _get("dcim", "devices", auth_required=True, name=name) for k, v in kwargs.items(): setattr(nb_device, k, v) try: nb_device.save() return {"dcim": {"devices": kwargs}} except RequestError as e: # pylint: disable=undefined-variable log.error("%s, %s, %s", e.req.request.headers, e.request_body, e.error) return False
[docs]def create_inventory_item( device_name, item_name, manufacturer_name=None, serial="", part_id="", description="", ): """ .. versionadded:: 2019.2.0 Add an inventory item to an existing device. device_name The name of the device, e.g., ``edge_router``. item_name String of inventory item name, e.g., ``Transceiver``. manufacturer_name String of inventory item manufacturer, e.g., ``Fiberstore``. serial String of inventory item serial, e.g., ``FS1238931``. part_id String of inventory item part id, e.g., ``740-01234``. description String of inventory item description, e.g., ``SFP+-10G-LR``. CLI Example: .. code-block:: bash salt myminion netbox.create_inventory_item edge_router Transceiver part_id=740-01234 """ nb_device = get_("dcim", "devices", name=device_name) if not nb_device: return False if manufacturer_name: nb_man = get_("dcim", "manufacturers", name=manufacturer_name) if not nb_man: create_manufacturer(manufacturer_name) nb_man = get_("dcim", "manufacturers", name=manufacturer_name) payload = { "device": nb_device["id"], "name": item_name, "description": description, "serial": serial, "part_id": part_id, "parent": None, } if manufacturer_name: payload["manufacturer"] = nb_man["id"] done = _add("dcim", "inventory-items", payload) if done: return {"dcim": {"inventory-items": payload}} else: return done
[docs]def delete_inventory_item(item_id): """ .. versionadded:: 2019.2.0 Remove an item from a devices inventory. Identified by the netbox id item_id Integer of item to be deleted CLI Example: .. code-block:: bash salt myminion netbox.delete_inventory_item 1354 """ nb_inventory_item = _get("dcim", "inventory-items", auth_required=True, id=item_id) nb_inventory_item.delete() return {"DELETE": {"dcim": {"inventory-items": item_id}}}
[docs]def create_interface_connection(interface_a, interface_b): """ .. versionadded:: 2019.2.0 Create an interface connection between 2 interfaces interface_a Interface id for Side A interface_b Interface id for Side B CLI Example: .. code-block:: bash salt myminion netbox.create_interface_connection 123 456 """ payload = {"interface_a": interface_a, "interface_b": interface_b} ret = _add("dcim", "interface-connections", payload) if ret: return {"dcim": {"interface-connections": {ret["id"]: payload}}} else: return ret
[docs]def get_interfaces(device_name=None, **kwargs): """ .. versionadded:: 2019.2.0 Returns interfaces for a specific device using arbitrary netbox filters device_name The name of the device, e.g., ``edge_router`` kwargs Optional arguments to be used for filtering CLI Example: .. code-block:: bash salt myminion netbox.get_interfaces edge_router name="et-0/0/5" """ if not device_name: device_name = __opts__["id"] netbox_device = get_("dcim", "devices", name=device_name) return filter_("dcim", "interfaces", device_id=netbox_device["id"], **kwargs)
[docs]def openconfig_interfaces(device_name=None): """ .. versionadded:: 2019.2.0 Return a dictionary structured as standardised in the `openconfig-interfaces <http://ops.openconfig.net/branches/master/openconfig-interfaces.html>`_ YANG model, containing physical and configuration data available in Netbox, e.g., IP addresses, MTU, enabled / disabled, etc. device_name: ``None`` The name of the device to query the interface data for. If not provided, will use the Minion ID. CLI Example: .. code-block:: bash salt '*' netbox.openconfig_interfaces salt '*' netbox.openconfig_interfaces device_name=cr1.thn.lon """ oc_if = {} interfaces = get_interfaces(device_name=device_name) ipaddresses = get_ipaddresses(device_name=device_name) for interface in interfaces: if_name, if_unit = _if_name_unit(interface["name"]) if if_name not in oc_if: oc_if[if_name] = { "config": {"name": if_name}, "subinterfaces": {"subinterface": {}}, } if if_unit == "0": oc_if[if_name]["config"]["enabled"] = interface["enabled"] if interface["description"]: if if_name == interface["name"]: # When that's a real unit 0 interface # Otherwise it will inherit the description from the subif oc_if[if_name]["config"]["description"] = str( interface["description"] ) else: subif_descr = { "subinterfaces": { "subinterface": { if_unit: { "config": { "description": str(interface["description"]) } } } } } oc_if[if_name] = __utils__["dictupdate.update"]( oc_if[if_name], subif_descr ) if interface["mtu"]: oc_if[if_name]["config"]["mtu"] = int(interface["mtu"]) else: oc_if[if_name]["subinterfaces"]["subinterface"][if_unit] = { "config": {"index": int(if_unit), "enabled": interface["enabled"]} } if interface["description"]: oc_if[if_name]["subinterfaces"]["subinterface"][if_unit]["config"][ "description" ] = str(interface["description"]) for ipaddress in ipaddresses: ip, prefix_length = ipaddress["address"].split("/") if_name = ipaddress["interface"]["name"] if_name, if_unit = _if_name_unit(if_name) ipvkey = "ipv{}".format(ipaddress["family"]) if if_unit not in oc_if[if_name]["subinterfaces"]["subinterface"]: oc_if[if_name]["subinterfaces"]["subinterface"][if_unit] = { "config": {"index": int(if_unit), "enabled": True} } if ipvkey not in oc_if[if_name]["subinterfaces"]["subinterface"][if_unit]: oc_if[if_name]["subinterfaces"]["subinterface"][if_unit][ipvkey] = { "addresses": {"address": {}} } oc_if[if_name]["subinterfaces"]["subinterface"][if_unit][ipvkey]["addresses"][ "address" ][ip] = {"config": {"ip": ip, "prefix_length": int(prefix_length)}} return {"interfaces": {"interface": oc_if}}
[docs]def openconfig_lacp(device_name=None): """ .. versionadded:: 2019.2.0 Return a dictionary structured as standardised in the `openconfig-lacp <http://ops.openconfig.net/branches/master/openconfig-lacp.html>`_ YANG model, with configuration data for Link Aggregation Control Protocol (LACP) for aggregate interfaces. .. note:: The ``interval`` and ``lacp_mode`` keys have the values set as ``SLOW`` and ``ACTIVE`` respectively, as this data is not currently available in Netbox, therefore defaulting to the values defined in the standard. See `interval <http://ops.openconfig.net/branches/master/docs/openconfig-lacp.html#lacp-interfaces-interface-config-interval>`_ and `lacp-mode <http://ops.openconfig.net/branches/master/docs/openconfig-lacp.html#lacp-interfaces-interface-config-lacp-mode>`_ for further details. device_name: ``None`` The name of the device to query the LACP information for. If not provided, will use the Minion ID. CLI Example: .. code-block:: bash salt '*' netbox.openconfig_lacp salt '*' netbox.openconfig_lacp device_name=cr1.thn.lon """ oc_lacp = {} interfaces = get_interfaces(device_name=device_name) for interface in interfaces: if not interface["lag"]: continue if_name, if_unit = _if_name_unit(interface["name"]) parent_if = interface["lag"]["name"] if parent_if not in oc_lacp: oc_lacp[parent_if] = { "config": { "name": parent_if, "interval": "SLOW", "lacp_mode": "ACTIVE", }, "members": {"member": {}}, } oc_lacp[parent_if]["members"]["member"][if_name] = {} return {"lacp": {"interfaces": {"interface": oc_lacp}}}
[docs]def create_interface( device_name, interface_name, mac_address=None, description=None, enabled=None, lag=None, lag_parent=None, form_factor=None, ): """ .. versionadded:: 2019.2.0 Attach an interface to a device. If not all arguments are provided, they will default to Netbox defaults. device_name The name of the device, e.g., ``edge_router`` interface_name The name of the interface, e.g., ``TenGigE0/0/0/0`` mac_address String of mac address, e.g., ``50:87:89:73:92:C8`` description String of interface description, e.g., ``NTT`` enabled String of boolean interface status, e.g., ``True`` lag: Boolean of interface lag status, e.g., ``True`` lag_parent String of interface lag parent name, e.g., ``ae13`` form_factor Integer of form factor id, obtained through _choices API endpoint, e.g., ``200`` CLI Example: .. code-block:: bash salt myminion netbox.create_interface edge_router ae13 description="Core uplink" """ nb_device = get_("dcim", "devices", name=device_name) if not nb_device: return False if lag_parent: lag_interface = get_( "dcim", "interfaces", device_id=nb_device["id"], name=lag_parent ) if not lag_interface: return False if not description: description = "" if not enabled: enabled = "false" # Set default form factor to 1200. This maps to SFP+ (10GE). This should be addressed by # the _choices endpoint. payload = { "device": nb_device["id"], "name": interface_name, "description": description, "enabled": enabled, "form_factor": 1200, } if form_factor is not None: payload["form_factor"] = form_factor if lag: payload["form_factor"] = 200 if lag_parent: payload["lag"] = lag_interface["id"] if mac_address: payload["mac_address"] = mac_address nb_interface = get_( "dcim", "interfaces", device_id=nb_device["id"], name=interface_name ) if not nb_interface: nb_interface = _add("dcim", "interfaces", payload) if nb_interface: return {"dcim": {"interfaces": {nb_interface["id"]: payload}}} else: return nb_interface
[docs]def update_interface(device_name, interface_name, **kwargs): """ .. versionadded:: 2019.2.0 Update an existing interface with new attributes. device_name The name of the device, e.g., ``edge_router`` interface_name The name of the interface, e.g., ``ae13`` kwargs Arguments to change in interface, e.g., ``mac_address=50:87:69:53:32:D0`` CLI Example: .. code-block:: bash salt myminion netbox.update_interface edge_router ae13 mac_address=50:87:69:53:32:D0 """ nb_device = get_("dcim", "devices", name=device_name) nb_interface = _get( "dcim", "interfaces", auth_required=True, device_id=nb_device["id"], name=interface_name, ) if not nb_device: return False if not nb_interface: return False else: for k, v in __utils__["args.clean_kwargs"](**kwargs).items(): setattr(nb_interface, k, v) try: nb_interface.save() return {"dcim": {"interfaces": {nb_interface.id: dict(nb_interface)}}} except RequestError as e: # pylint: disable=undefined-variable log.error("%s, %s, %s", e.req.request.headers, e.request_body, e.error) return False
[docs]def delete_interface(device_name, interface_name): """ .. versionadded:: 2019.2.0 Delete an interface from a device. device_name The name of the device, e.g., ``edge_router``. interface_name The name of the interface, e.g., ``ae13`` CLI Example: .. code-block:: bash salt myminion netbox.delete_interface edge_router ae13 """ nb_device = get_("dcim", "devices", name=device_name) nb_interface = _get( "dcim", "interfaces", auth_required=True, device_id=nb_device["id"], name=interface_name, ) if nb_interface: nb_interface.delete() return { "DELETE": {"dcim": {"interfaces": {nb_interface.id: nb_interface.name}}} } return False
[docs]def make_interface_lag(device_name, interface_name): """ .. versionadded:: 2019.2.0 Update an interface to be a LAG. device_name The name of the device, e.g., ``edge_router``. interface_name The name of the interface, e.g., ``ae13``. CLI Example: .. code-block:: bash salt myminion netbox.make_interface_lag edge_router ae13 """ return update_interface(device_name, interface_name, form_factor=200)
[docs]def make_interface_child(device_name, interface_name, parent_name): """ .. versionadded:: 2019.2.0 Set an interface as part of a LAG. device_name The name of the device, e.g., ``edge_router``. interface_name The name of the interface to be attached to LAG, e.g., ``xe-1/0/2``. parent_name The name of the LAG interface, e.g., ``ae13``. CLI Example: .. code-block:: bash salt myminion netbox.make_interface_child xe-1/0/2 ae13 """ nb_device = get_("dcim", "devices", name=device_name) nb_parent = get_("dcim", "interfaces", device_id=nb_device["id"], name=parent_name) if nb_device and nb_parent: return update_interface(device_name, interface_name, lag=nb_parent["id"]) else: return False
[docs]def get_ipaddresses(device_name=None, **kwargs): """ .. versionadded:: 2019.2.0 Filters for an IP address using specified filters device_name The name of the device to check for the IP address kwargs Optional arguments that can be used to filter, e.g., ``family=4`` CLI Example: .. code-block:: bash salt myminion netbox.get_ipaddresses device_name family=4 """ if not device_name: device_name = __opts__["id"] netbox_device = get_("dcim", "devices", name=device_name) return filter_("ipam", "ip-addresses", device_id=netbox_device["id"], **kwargs)
[docs]def create_ipaddress(ip_address, family, device=None, interface=None): """ .. versionadded:: 2019.2.0 Add an IP address, and optionally attach it to an interface. ip_address The IP address and CIDR, e.g., ``192.168.1.1/24`` family Integer of IP family, e.g., ``4`` device The name of the device to attach IP to, e.g., ``edge_router`` interface The name of the interface to attach IP to, e.g., ``ae13`` CLI Example: .. code-block:: bash salt myminion netbox.create_ipaddress 192.168.1.1/24 4 device=edge_router interface=ae13 """ nb_addr = None payload = {"family": family, "address": ip_address} if interface and device: nb_device = get_("dcim", "devices", name=device) if not nb_device: return False nb_interface = get_( "dcim", "interfaces", device_id=nb_device["id"], name=interface ) if not nb_interface: return False nb_addr = get_( "ipam", "ip-addresses", q=ip_address, interface_id=nb_interface["id"], family=family, ) if nb_addr: log.error(nb_addr) return False else: payload["interface"] = nb_interface["id"] ipaddr = _add("ipam", "ip-addresses", payload) if ipaddr: return {"ipam": {"ip-addresses": payload}} else: return ipaddr
[docs]def delete_ipaddress(ipaddr_id): """ .. versionadded:: 2019.2.0 Delete an IP address. IP addresses in Netbox are a combination of address and the interface it is assigned to. id The Netbox id for the IP address. CLI Example: .. code-block:: bash salt myminion netbox.delete_ipaddress 9002 """ nb_ipaddr = _get("ipam", "ip-addresses", auth_required=True, id=ipaddr_id) if nb_ipaddr: nb_ipaddr.delete() return {"DELETE": {"ipam": {"ip-address": ipaddr_id}}} return False
[docs]def create_circuit_provider(name, asn=None): """ .. versionadded:: 2019.2.0 Create a new Netbox circuit provider name The name of the circuit provider asn The ASN of the circuit provider CLI Example: .. code-block:: bash salt myminion netbox.create_circuit_provider Telia 1299 """ nb_circuit_provider = get_("circuits", "providers", name=name) payload = {} if nb_circuit_provider: if nb_circuit_provider["asn"] == asn: return False else: log.error("Duplicate provider with different ASN: %s: %s", name, asn) raise CommandExecutionError( "Duplicate provider with different ASN: {}: {}".format(name, asn) ) else: payload = {"name": name, "slug": slugify(name)} if asn: payload["asn"] = asn circuit_provider = _add("circuits", "providers", payload) if circuit_provider: return {"circuits": {"providers": {circuit_provider["id"]: payload}}} else: return circuit_provider
[docs]def get_circuit_provider(name, asn=None): """ .. versionadded:: 2019.2.0 Get a circuit provider with a given name and optional ASN. name The name of the circuit provider asn The ASN of the circuit provider CLI Example: .. code-block:: bash salt myminion netbox.get_circuit_provider Telia 1299 """ if asn: nb_circuit_provider = get_("circuits", "providers", asn=asn) else: nb_circuit_provider = get_("circuits", "providers", name=name) return nb_circuit_provider
[docs]def create_circuit_type(name): """ .. versionadded:: 2019.2.0 Create a new Netbox circuit type. name The name of the circuit type CLI Example: .. code-block:: bash salt myminion netbox.create_circuit_type Transit """ nb_circuit_type = get_("circuits", "circuit-types", slug=slugify(name)) if nb_circuit_type: return False else: payload = {"name": name, "slug": slugify(name)} circuit_type = _add("circuits", "circuit-types", payload) if circuit_type: return {"circuits": {"circuit-types": {circuit_type["id"]: payload}}} else: return circuit_type
[docs]def create_circuit(name, provider_id, circuit_type, description=None): """ .. versionadded:: 2019.2.0 Create a new Netbox circuit name Name of the circuit provider_id The netbox id of the circuit provider circuit_type The name of the circuit type asn The ASN of the circuit provider description The description of the circuit CLI Example: .. code-block:: bash salt myminion netbox.create_circuit NEW_CIRCUIT_01 Telia Transit 1299 "New Telia circuit" """ nb_circuit_provider = get_("circuits", "providers", provider_id) nb_circuit_type = get_("circuits", "circuit-types", slug=slugify(circuit_type)) if nb_circuit_provider and nb_circuit_type: payload = { "cid": name, "provider": nb_circuit_provider["id"], "type": nb_circuit_type["id"], } if description: payload["description"] = description nb_circuit = get_("circuits", "circuits", cid=name) if nb_circuit: return False circuit = _add("circuits", "circuits", payload) if circuit: return {"circuits": {"circuits": {circuit["id"]: payload}}} else: return circuit else: return False
[docs]def create_circuit_termination( circuit, interface, device, speed, xconnect_id=None, term_side="A" ): """ .. versionadded:: 2019.2.0 Terminate a circuit on an interface circuit The name of the circuit interface The name of the interface to terminate on device The name of the device the interface belongs to speed The speed of the circuit, in Kbps xconnect_id The cross-connect identifier term_side The side of the circuit termination CLI Example: .. code-block:: bash salt myminion netbox.create_circuit_termination NEW_CIRCUIT_01 xe-0/0/1 myminion 10000 xconnect_id=XCON01 """ nb_device = get_("dcim", "devices", name=device) nb_interface = get_("dcim", "interfaces", device_id=nb_device["id"], name=interface) nb_circuit = get_("circuits", "circuits", cid=circuit) if nb_circuit and nb_device: nb_termination = get_("circuits", "circuit-terminations", q=nb_circuit["cid"]) if nb_termination: return False payload = { "circuit": nb_circuit["id"], "interface": nb_interface["id"], "site": nb_device["site"]["id"], "port_speed": speed, "term_side": term_side, } if xconnect_id: payload["xconnect_id"] = xconnect_id circuit_termination = _add("circuits", "circuit-terminations", payload) if circuit_termination: return { "circuits": { "circuit-terminations": {circuit_termination["id"]: payload} } } else: return circuit_termination