netbox_utils

Constants

plugins.module_utils.netbox_utils.API_APPS_ENDPOINTS = {'circuits': ['circuits', 'circuit_types', 'circuit_terminations', 'providers'], 'dcim': ['cables', 'console_ports', 'console_port_templates', 'console_server_ports', 'console_server_port_templates', 'device_bays', 'device_bay_templates', 'devices', 'device_roles', 'device_types', 'front_ports', 'front_port_templates', 'interfaces', 'interface_templates', 'inventory_items', 'manufacturers', 'platforms', 'power_feeds', 'power_outlets', 'power_outlet_templates', 'power_panels', 'power_ports', 'power_port_templates', 'racks', 'rack_groups', 'rack_roles', 'rear_ports', 'rear_port_templates', 'regions', 'sites', 'virtual_chassis'], 'extras': ['tags'], 'ipam': ['aggregates', 'ip_addresses', 'prefixes', 'rirs', 'roles', 'vlans', 'vlan_groups', 'vrfs', 'services'], 'secrets': [], 'tenancy': ['tenants', 'tenant_groups'], 'virtualization': ['cluster_groups', 'cluster_types', 'clusters', 'virtual_machines']}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

plugins.module_utils.netbox_utils.QUERY_TYPES = {'circuit': 'cid', 'circuit_termination': 'circuit', 'circuit_type': 'slug', 'cluster': 'name', 'cluster_group': 'slug', 'cluster_type': 'slug', 'device': 'name', 'device_role': 'slug', 'device_type': 'slug', 'group': 'slug', 'installed_device': 'name', 'manufacturer': 'slug', 'nat_inside': 'address', 'nat_outside': 'address', 'parent_region': 'slug', 'platform': 'slug', 'power_panel': 'name', 'power_port': 'name', 'prefix_role': 'slug', 'primary_ip': 'address', 'primary_ip4': 'address', 'primary_ip6': 'address', 'provider': 'slug', 'rack': 'name', 'rack_group': 'slug', 'rack_role': 'slug', 'rear_port': 'name', 'rear_port_template': 'name', 'region': 'slug', 'rir': 'slug', 'site': 'slug', 'slug': 'slug', 'tenant': 'slug', 'tenant_group': 'slug', 'time_zone': 'timezone', 'virtual_machine': 'name', 'virtual_machine_role': 'slug', 'vlan': 'name', 'vlan_group': 'slug', 'vlan_role': 'name', 'vrf': 'name'}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

plugins.module_utils.netbox_utils.CONVERT_TO_ID = {'assigned_object': 'assigned_object', 'circuit': 'circuits', 'circuit_termination': 'circuit_terminations', 'circuit_type': 'circuit_types', 'circuits.circuittermination': 'circuit_terminations', 'cluster': 'clusters', 'cluster_group': 'cluster_groups', 'cluster_type': 'cluster_types', 'dcim.consoleport': 'console_ports', 'dcim.consoleserverport': 'console_server_ports', 'dcim.frontport': 'front_ports', 'dcim.interface': 'interfaces', 'dcim.powerfeed': 'power_feeds', 'dcim.poweroutlet': 'power_outlets', 'dcim.powerport': 'power_ports', 'dcim.rearport': 'rear_ports', 'device': 'devices', 'device_role': 'device_roles', 'device_type': 'device_types', 'group': 'tenant_groups', 'installed_device': 'devices', 'interface': 'interfaces', 'interface_template': 'interface_templates', 'ip_addresses': 'ip_addresses', 'ipaddresses': 'ip_addresses', 'lag': 'interfaces', 'manufacturer': 'manufacturers', 'master': 'devices', 'nat_inside': 'ip_addresses', 'nat_outside': 'ip_addresses', 'parent_region': 'regions', 'platform': 'platforms', 'power_panel': 'power_panels', 'power_port': 'power_ports', 'prefix_role': 'roles', 'primary_ip': 'ip_addresses', 'primary_ip4': 'ip_addresses', 'primary_ip6': 'ip_addresses', 'provider': 'providers', 'rack': 'racks', 'rack_group': 'rack_groups', 'rack_role': 'rack_roles', 'rear_port': 'rear_ports', 'rear_port_template': 'rear_port_templates', 'region': 'regions', 'rir': 'rirs', 'services': 'services', 'site': 'sites', 'tagged_vlans': 'vlans', 'tags': 'tags', 'tenant': 'tenants', 'tenant_group': 'tenant_groups', 'termination_a': 'interfaces', 'termination_b': 'interfaces', 'untagged_vlan': 'vlans', 'virtual_chassis': 'virtual_chassis', 'virtual_machine': 'virtual_machines', 'virtual_machine_role': 'device_roles', 'vlan': 'vlans', 'vlan_group': 'vlan_groups', 'vlan_role': 'roles', 'vrf': 'vrfs'}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

plugins.module_utils.netbox_utils.ENDPOINT_NAME_MAPPING = {'aggregates': 'aggregate', 'cables': 'cable', 'circuit_terminations': 'circuit_termination', 'circuit_types': 'circuit_type', 'circuits': 'circuit', 'cluster_groups': 'cluster_group', 'cluster_types': 'cluster_type', 'clusters': 'cluster', 'console_port_templates': 'console_port_template', 'console_ports': 'console_port', 'console_server_port_templates': 'console_server_port_template', 'console_server_ports': 'console_server_port', 'device_bay_templates': 'device_bay_template', 'device_bays': 'device_bay', 'device_roles': 'device_role', 'device_types': 'device_type', 'devices': 'device', 'front_port_templates': 'front_port_template', 'front_ports': 'front_port', 'interface_templates': 'interface_template', 'interfaces': 'interface', 'inventory_items': 'inventory_item', 'ip_addresses': 'ip_address', 'manufacturers': 'manufacturer', 'platforms': 'platform', 'power_feeds': 'power_feed', 'power_outlet_templates': 'power_outlet_template', 'power_outlets': 'power_outlet', 'power_panels': 'power_panel', 'power_port_templates': 'power_port_template', 'power_ports': 'power_port', 'prefixes': 'prefix', 'providers': 'provider', 'rack_groups': 'rack_group', 'rack_roles': 'rack_role', 'racks': 'rack', 'rear_port_templates': 'rear_port_template', 'rear_ports': 'rear_port', 'regions': 'region', 'rirs': 'rir', 'roles': 'role', 'services': 'services', 'sites': 'site', 'tags': 'tags', 'tenant_groups': 'tenant_group', 'tenants': 'tenant', 'virtual_chassis': 'virtual_chassis', 'virtual_machines': 'virtual_machine', 'vlan_groups': 'vlan_group', 'vlans': 'vlan', 'vrfs': 'vrf'}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

plugins.module_utils.netbox_utils.ALLOWED_QUERY_PARAMS = {'aggregate': {'prefix', 'rir'}, 'assigned_object': {'device', 'name', 'virtual_machine'}, 'circuit': {'cid'}, 'circuit_termination': {'circuit', 'term_side'}, 'circuit_type': {'slug'}, 'circuits.circuittermination': {'circuit', 'term_side'}, 'cluster': {'name', 'type'}, 'cluster_group': {'slug'}, 'cluster_type': {'slug'}, 'console_port': {'device', 'name'}, 'console_port_template': {'device_type', 'name'}, 'console_server_port': {'device', 'name'}, 'console_server_port_template': {'device_type', 'name'}, 'dcim.consoleport': {'device', 'name'}, 'dcim.consoleserverport': {'device', 'name'}, 'dcim.frontport': {'device', 'name', 'rear_port'}, 'dcim.interface': {'device', 'name', 'virtual_machine'}, 'dcim.powerfeed': {'name', 'power_panel'}, 'dcim.poweroutlet': {'device', 'name'}, 'dcim.powerport': {'device', 'name'}, 'dcim.rearport': {'device', 'name'}, 'device': {'name'}, 'device_bay': {'device', 'name'}, 'device_bay_template': {'device_type', 'name'}, 'device_role': {'slug'}, 'device_type': {'slug'}, 'front_port': {'device', 'name', 'rear_port'}, 'front_port_template': {'device_type', 'name', 'rear_port'}, 'installed_device': {'name'}, 'interface': {'device', 'name', 'virtual_machine'}, 'interface_template': {'device_type', 'name'}, 'inventory_item': {'device', 'name'}, 'ip_address': {'address', 'interface', 'vrf'}, 'ip_addresses': {'address', 'device', 'interface', 'vrf'}, 'ipaddresses': {'address', 'device', 'interface', 'vrf'}, 'lag': {'name'}, 'manufacturer': {'slug'}, 'master': {'name'}, 'nat_inside': {'address', 'vrf'}, 'parent_region': {'slug'}, 'platform': {'slug'}, 'power_feed': {'name', 'power_panel'}, 'power_outlet': {'device', 'name'}, 'power_outlet_template': {'device_type', 'name'}, 'power_panel': {'name', 'site'}, 'power_port': {'device', 'name'}, 'power_port_template': {'device_type', 'name'}, 'prefix': {'prefix', 'vrf'}, 'primary_ip4': {'address', 'vrf'}, 'primary_ip6': {'address', 'vrf'}, 'provider': {'slug'}, 'rack': {'name', 'site'}, 'rack_group': {'slug'}, 'rack_role': {'slug'}, 'rear_port': {'device', 'name'}, 'rear_port_template': {'device_type', 'name'}, 'region': {'slug'}, 'rir': {'slug'}, 'role': {'slug'}, 'services': {'device', 'name', 'port', 'protocol', 'virtual_machine'}, 'site': {'slug'}, 'tagged_vlans': {'group', 'name', 'site', 'tenant', 'vid', 'vlan_group'}, 'tags': {'slug'}, 'tenant': {'slug'}, 'tenant_group': {'slug'}, 'termination_a': {'device', 'name', 'virtual_machine'}, 'termination_b': {'device', 'name', 'virtual_machine'}, 'untagged_vlan': {'group', 'name', 'site', 'tenant', 'vid', 'vlan_group'}, 'virtual_chassis': {'master'}, 'virtual_machine': {'cluster', 'name'}, 'vlan': {'group', 'name', 'site', 'tenant', 'vid', 'vlan_group'}, 'vlan_group': {'site', 'slug'}, 'vrf': {'name', 'tenant'}}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

plugins.module_utils.netbox_utils.QUERY_PARAMS_IDS = {'circuit', 'cluster', 'device', 'group', 'interface', 'rir', 'site', 'tenant', 'type', 'virtual_machine', 'vrf'}

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

plugins.module_utils.netbox_utils.REQUIRED_ID_FIND = {'cables': {'length_unit', 'status', 'type'}, 'circuits': {'status'}, 'console_port_templates': {'type'}, 'console_ports': {'type'}, 'console_server_port_templates': {'type'}, 'console_server_ports': {'type'}, 'device_types': {'subdevice_role'}, 'devices': {'face', 'status'}, 'front_port_templates': {'type'}, 'front_ports': {'type'}, 'interface_templates': {'type'}, 'interfaces': {'form_factor', 'mode', 'type'}, 'ip_addresses': {'role', 'status'}, 'power_feeds': {'phase', 'status', 'supply', 'type'}, 'power_outlet_templates': {'feed_leg', 'type'}, 'power_outlets': {'feed_leg', 'type'}, 'power_port_templates': {'type'}, 'power_ports': {'type'}, 'prefixes': {'status'}, 'racks': {'outer_unit', 'status', 'type'}, 'rear_port_templates': {'type'}, 'rear_ports': {'type'}, 'services': {'protocol'}, 'sites': {'status'}, 'virtual_machines': {'face', 'status'}, 'vlans': {'status'}}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

plugins.module_utils.netbox_utils.CONVERT_KEYS = {'assigned_object': 'assigned_object_id', 'circuit_type': 'type', 'cluster_group': 'group', 'cluster_type': 'type', 'parent_region': 'parent', 'prefix_role': 'role', 'rack_group': 'group', 'rack_role': 'role', 'rear_port_template': 'rear_port', 'rear_port_template_position': 'rear_port_position', 'tenant_group': 'group', 'termination_a': 'termination_a_id', 'termination_b': 'termination_b_id', 'virtual_machine_role': 'role', 'vlan_group': 'group', 'vlan_role': 'role'}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

plugins.module_utils.netbox_utils.SLUG_REQUIRED = {'circuit_types', 'cluster_groups', 'cluster_types', 'device_roles', 'device_types', 'ipam_roles', 'manufacturers', 'platforms', 'providers', 'rack_groups', 'rack_roles', 'regions', 'rirs', 'roles', 'sites', 'tags', 'tenant_groups', 'tenants', 'vlan_groups'}

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

plugins.module_utils.netbox_utils.NETBOX_ARG_SPEC = {'netbox_token': {'no_log': True, 'required': True, 'type': 'str'}, 'netbox_url': {'required': True, 'type': 'str'}, 'query_params': {'elements': 'str', 'required': False, 'type': 'list'}, 'state': {'choices': ['present', 'absent'], 'default': 'present', 'required': False}, 'validate_certs': {'default': True, 'type': 'raw'}}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

Classes

class plugins.module_utils.netbox_utils.NetboxAnsibleModule(argument_spec, bypass_checks=False, no_log=False, mutually_exclusive=None, required_together=None, required_one_of=None, add_file_common_args=False, supports_check_mode=False, required_if=None, required_by=None)

Creating this due to needing to override some functionality to provide required_together, required_if and will be able to override more in the future. This is due to the Netbox modules having the module arguments within a key in the argument spec, using suboptions rather than having all module arguments within the regular argument spec.

Didn’t want to change that functionality of the Netbox modules as its disruptive and we’re required to send a specific payload to the Netbox API

__init__(argument_spec, bypass_checks=False, no_log=False, mutually_exclusive=None, required_together=None, required_one_of=None, add_file_common_args=False, supports_check_mode=False, required_if=None, required_by=None)

Common code for quickly building an ansible module in Python (although you can write modules with anything that can return JSON).

See developing_modules_general for a general introduction and developing_program_flow_modules for more detailed explanation.

_check_mutually_exclusive(spec, param=None)
_check_required_if(spec, param=None)

ensure that parameters which conditionally required are present

_check_required_one_of(spec, param=None)
_check_required_together(spec, param=None)
check_mutually_exclusive(terms, module_parameters)

Check mutually exclusive terms against argument parameters Accepts a single list or list of lists that are groups of terms that should be mutually exclusive with one another :arg terms: List of mutually exclusive module parameters :arg module_parameters: Dictionary of module parameters :returns: Empty list or raises TypeError if the check fails.

check_required_if(requirements, module_parameters)
check_required_one_of(terms, module_parameters)

Check each list of terms to ensure at least one exists in the given module parameters Accepts a list of lists or tuples :arg terms: List of lists of terms to check. For each list of terms, at

least one is required.

Parameters

module_parameters – Dictionary of module parameters

Returns

Empty list or raises TypeError if the check fails.

check_required_together(terms, module_parameters)

Check each list of terms to ensure every parameter in each list exists in the given module parameters Accepts a list of lists or tuples :arg terms: List of lists of terms to check. Each list should include

parameters that are all required when at least one is specified in the module_parameters.

Parameters

module_parameters – Dictionary of module parameters

Returns

Empty list or raises TypeError if the check fails.

count_terms(terms, module_parameters)

Count the number of occurrences of a key in a given dictionary :arg terms: String or iterable of values to check :arg module_parameters: Dictionary of module parameters :returns: An integer that is the number of occurrences of the terms values in the provided dictionary.

class plugins.module_utils.netbox_utils.NetboxModule(module, endpoint, nb_client=None)

Initialize connection to Netbox, sets AnsibleModule passed in to self.module to be used throughout the class :params module (obj): Ansible Module object :params endpoint (str): Used to tell class which endpoint the logic needs to follow :params nb_client (obj): pynetbox.api object passed in (not required)

__init__(module, endpoint, nb_client=None)

Initialize self. See help(type(self)) for accurate signature.

_build_diff(before=None, after=None)

Builds diff of before and after changes

_build_query_params(parent, module_data, user_query_params=None, child=None)
Returns dict(query_dict)

Returns a query dictionary built using mappings to dynamically

build available query params for Netbox endpoints :params parent(str): This is either a key from _find_ids or a string passed in to determine which keys in the data that we need to use to construct query_dict :params module_data(dict): Uses the data provided to the Netbox module :params child(dict): This is used within _find_ids and passes the inner dictionary to build the appropriate query_dict for the parent

_change_choices_id(endpoint, data)

Used to change data that is static and under _choices for the application. ex. DEVICE_STATUS :returns data (dict): Returns the user defined data back with updated fields for _choices :params endpoint (str): The endpoint that will be used for mapping to required _choices :params data (dict): User defined data passed into the module

_connect_netbox_api(url, token, ssl_verify)
_convert_identical_keys(data)

Used to change non-clashing keys for each module into identical keys that are required to be passed to pynetbox ex. rack_role back into role to pass to Netbox Returns data :params data (dict): Data dictionary after _find_ids method ran

_create_netbox_object(nb_endpoint, data)

Create a Netbox object. :returns tuple(serialized_nb_obj, diff): tuple of the serialized created Netbox object and the Ansible diff.

_delete_netbox_object()

Delete a Netbox object. :returns diff (dict): Ansible diff

_ensure_object_absent(endpoint_name, name)

Used when state is absent to make sure object does not exist :params endpoint_name (str): Endpoint name that was created/updated. ex. device :params name (str): Name of the object

_ensure_object_exists(nb_endpoint, endpoint_name, name, data)

Used when state is present to make sure object exists or if the object exists that it is updated :params nb_endpoint (pynetbox endpoint object): This is the nb endpoint to be used to create or update the object :params endpoint_name (str): Endpoint name that was created/updated. ex. device :params name (str): Name of the object :params data (dict): User defined data passed into the module

_fetch_choice_value(search, endpoint)
_find_app(endpoint)

Dynamically finds application of endpoint passed in using the API_APPS_ENDPOINTS for mapping :returns nb_app (str): The application the endpoint lives under :params endpoint (str): The endpoint requiring resolution to application

_find_ids(data, user_query_params)

Will find the IDs of all user specified data if resolvable :returns data (dict): Returns the updated dict with the IDs of user specified data :params data (dict): User defined data passed into the module

_get_query_param_id(match, data)

Used to find IDs of necessary searches when required under _build_query_params :returns id (int) or data (dict): Either returns the ID or original data passed in :params match (str): The key within the user defined data that is required to have an ID :params data (dict): User defined data passed into the module

_handle_errors(msg)

Returns message and changed = False :params msg (str): Message indicating why there is no change

_nb_endpoint_get(nb_endpoint, query_params, search_item)
_normalize_data(data)
Returns data (dict)

Normalized module data to formats accepted by Netbox searches

such as changing from user specified value to slug ex. Test Rack -> test-rack :params data (dict): Original data from Netbox module

_remove_arg_spec_default(data)

Used to remove any data keys that were not provided by user, but has the arg spec default values

_to_slug(value)
Returns slug (str)

Slugified value

Params value (str)

Value that needs to be changed to slug format

_update_netbox_object(data)

Update a Netbox object. :returns tuple(serialized_nb_obj, diff): tuple of the serialized updated Netbox object and the Ansible diff.

_validate_query_params(query_params)

Validate query_params that are passed in by users to make sure they’re valid and return error if they’re not valid.

_version_check_greater(greater, lesser, greater_or_equal=False)

Determine if first argument is greater than second argument.

Parameters
  • greater (str) – decimal string

  • lesser (str) – decimal string

run()

Must be implemented in subclasses