Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 31 additions & 8 deletions plugins/lookup/nb_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,6 @@ def get_endpoint(netbox, term):
"job-results": {"endpoint": netbox.extras.job_results},
"journal-entries": {"endpoint": netbox.extras.journal_entries},
"locations": {"endpoint": netbox.dcim.locations},
"l2vpn-terminations": {"endpoint": netbox.ipam.l2vpn_terminations},
"l2vpns": {"endpoint": netbox.ipam.l2vpns},
"manufacturers": {"endpoint": netbox.dcim.manufacturers},
"module-bays": {"endpoint": netbox.dcim.module_bays},
"module-bay-templates": {"endpoint": netbox.dcim.module_bay_templates},
Expand Down Expand Up @@ -257,9 +255,10 @@ def get_endpoint(netbox, term):
"webhooks": {"endpoint": netbox.extras.webhooks},
}

major, minor, patch = map(int, pynetbox.__version__.split("."))
major, minor, patch = tuple(map(int, pynetbox.__version__.split(".")))
netbox_versiontuple = tuple(map(int, netbox.version.split(".")))

if major >= 6 and minor >= 4 and patch >= 0:
if (major, minor, patch) >= (6, 4):
netbox_endpoint_map["wireless-lan-groups"] = {
"endpoint": netbox.wireless.wireless_lan_groups
}
Expand All @@ -273,17 +272,41 @@ def get_endpoint(netbox, term):
"endpoint": netbox.wireless.wireless_links
}

if major < 7 and minor >= 0 and patch >= 1:
netbox_endpoint_map["secret-roles"] = {"endpoint": netbox.secrets.secret_roles}
netbox_endpoint_map["secrets"] = {"endpoint": netbox.secrets.secrets}

else:
if "wireless" in term:
Display().v(
"pynetbox version %d.%d.%d does not support wireless app; please update to v6.4.0 or newer."
% (major, minor, patch)
)

if (major, minor, patch) < (7, 0, 1):
netbox_endpoint_map["secret-roles"] = {"endpoint": netbox.secrets.secret_roles}
netbox_endpoint_map["secrets"] = {"endpoint": netbox.secrets.secrets}

if netbox_versiontuple >= (3, 7):
if (major, minor, patch) >= (7, 3):
netbox_endpoint_map["l2vpn-terminations"] = {
"endpoint": netbox.vpn.l2vpn_terminations
}
netbox_endpoint_map["l2vpns"] = {"endpoint": netbox.vpn.l2vpns}
netbox_endpoint_map["tunnel-terminations"] = {
"endpoint": netbox.vpn.tunnel_terminations
}
netbox_endpoint_map["tunnels"] = {"endpoint": netbox.vpn.tunnels}

else:
if "l2vpn" in term:
Display().v(
"pynetbox version %d.%d.%d does not support vpn app; please update to v7.3.0 or newer."
% (major, minor, patch)
)

else:
netbox_endpoint_map["l2vpn-terminations"] = {
"endpoint": netbox.ipam.l2vpn_terminations
}
netbox_endpoint_map["l2vpns"] = {"endpoint": netbox.ipam.l2vpns}

return netbox_endpoint_map[term]["endpoint"]


Expand Down
194 changes: 110 additions & 84 deletions plugins/module_utils/netbox_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,89 +32,103 @@

# Used to map endpoints to applications dynamically
API_APPS_ENDPOINTS = dict(
circuits=[
"circuits",
"circuit_types",
"circuit_terminations",
"providers",
"provider_networks",
],
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",
"inventory_item_roles",
"locations",
"manufacturers",
"module_types",
"platforms",
"power_feeds",
"power_outlets",
"power_outlet_templates",
"power_panels",
"power_ports",
"power_port_templates",
"racks",
"rack_groups",
"rack_roles",
"rear_ports",
"rear-ports",
"rear_port_templates",
"regions",
"sites",
"site_groups",
"virtual_chassis",
],
extras=[
"config_contexts",
"config_templates",
"tags",
"custom_fields",
"custom_links",
"export_templates",
"journal_entries",
"webhooks",
],
ipam=[
"aggregates",
"asns",
"fhrp_groups",
"fhrp_group_assignments",
"ip_addresses",
"l2vpns",
"l2vpn_terminations",
"prefixes",
"rirs",
"roles",
"route_targets",
"service_templates",
"vlans",
"vlan_groups",
"vrfs",
"services",
],
secrets=[],
tenancy=["tenants", "tenant_groups", "contacts", "contact_groups", "contact_roles"],
virtualization=[
"cluster_groups",
"cluster_types",
"clusters",
"virtual_machines",
"virtual_disks",
],
wireless=["wireless_lans", "wireless_lan_groups", "wireless_links"],
circuits={
"circuits": {},
"circuit_types": {},
"circuit_terminations": {},
"providers": {},
"provider_networks": {},
},
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": {},
"inventory_item_roles": {},
"locations": {},
"manufacturers": {},
"module_types": {},
"platforms": {},
"power_feeds": {},
"power_outlets": {},
"power_outlet_templates": {},
"power_panels": {},
"power_ports": {},
"power_port_templates": {},
"racks": {},
"rack_groups": {},
"rack_roles": {},
"rear_ports": {},
"rear-ports": {},
"rear_port_templates": {},
"regions": {},
"sites": {},
"site_groups": {},
"virtual_chassis": {},
},
extras={
"config_contexts": {},
"config_templates": {},
"tags": {},
"custom_fields": {},
"custom_links": {},
"export_templates": {},
"journal_entries": {},
"webhooks": {},
},
ipam={
"aggregates": {},
"asns": {},
"fhrp_groups": {},
"fhrp_group_assignments": {},
"ip_addresses": {},
"l2vpns": {"deprecated": "3.7"},
"l2vpn_terminations": {"deprecated": "3.7"},
"prefixes": {},
"rirs": {},
"roles": {},
"route_targets": {},
"service_templates": {},
"vlans": {},
"vlan_groups": {},
"vrfs": {},
"services": {},
},
secrets={},
tenancy={
"tenants": {},
"tenant_groups": {},
"contacts": {},
"contact_groups": {},
"contact_roles": {},
},
virtualization={
"cluster_groups": {},
"cluster_types": {},
"clusters": {},
"virtual_machines": {},
"virtual_disks": {},
},
wireless={
"wireless_lans": {},
"wireless_lan_groups": {},
"wireless_links": {},
},
vpn={
"l2vpns": {"introduced": "3.7"},
"l2vpn_terminations": {"introduced": "3.7"},
},
)

# Used to normalize data for the respective query types used to find endpoints
Expand Down Expand Up @@ -1122,7 +1136,19 @@ def _find_app(self, endpoint):
"""
nb_app = None
for k, v in API_APPS_ENDPOINTS.items():
if endpoint in v:
if endpoint in v.keys():
if "introduced" in v[endpoint]:
pre_introduction = self._version_check_greater(
v[endpoint]["introduced"], self.version
)
if pre_introduction:
continue
if "deprecated" in v[endpoint]:
after_deprecation = self._version_check_greater(
self.version, v[endpoint]["deprecated"], greater_or_equal=True
)
if after_deprecation:
continue
nb_app = k

if nb_app:
Expand Down
76 changes: 76 additions & 0 deletions plugins/module_utils/netbox_vpn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Mikhail Yohman (@fragmentedpacket) <[email protected]>
# Copyright: (c) 2024, Fred De Backer (@freddebacker) <[email protected]>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function

__metaclass__ = type

# Import necessary packages

from ansible_collections.netbox.netbox.plugins.module_utils.netbox_utils import (
NetboxModule,
ENDPOINT_NAME_MAPPING,
SLUG_REQUIRED,
)


NB_L2VPNS = "l2vpns"
NB_L2VPN_TERMINATIONS = "l2vpn_terminations"


class NetboxVpnModule(NetboxModule):
def __init__(self, module, endpoint):
super().__init__(module, endpoint)

def run(self):
"""
This function should have all necessary code for endpoints within the application
to create/update/delete the endpoint objects
Supported endpoints:
- l2vpns
- l2vpn_terminations
"""
# Used to dynamically set key when returning results
endpoint_name = ENDPOINT_NAME_MAPPING[self.endpoint]

self.result = {"changed": False}

application = self._find_app(self.endpoint)
nb_app = getattr(self.nb, application)
nb_endpoint = getattr(nb_app, self.endpoint)
user_query_params = self.module.params.get("query_params")

data = self.data

if self.endpoint == "l2vpn_terminations":
name = "l2vpn %s <> %s %s" % (
data.get("l2vpn"),
data.get("assigned_object_type"),
data.get("assigned_object_id"),
)
else:
name = data.get("name")

if self.endpoint in SLUG_REQUIRED:
if not data.get("slug"):
data["slug"] = self._to_slug(name)

object_query_params = self._build_query_params(
endpoint_name, data, user_query_params
)
self.nb_object = self._nb_endpoint_get(nb_endpoint, object_query_params, name)

if self.state == "present":
self._ensure_object_exists(nb_endpoint, endpoint_name, name, data)
elif self.state == "absent":
self._ensure_object_absent(endpoint_name, name)

try:
serialized_object = self.nb_object.serialize()
except AttributeError:
serialized_object = self.nb_object

self.result.update({endpoint_name: serialized_object})

self.module.exit_json(**self.result)
14 changes: 12 additions & 2 deletions plugins/modules/netbox_l2vpn.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,16 @@

from ansible_collections.netbox.netbox.plugins.module_utils.netbox_utils import (
NetboxAnsibleModule,
NetboxModule,
NETBOX_ARG_SPEC,
)
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_ipam import (
NetboxIpamModule,
NB_L2VPNS,
NB_L2VPNS as NB_IPAM_L2VPNS,
)
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_vpn import (
NetboxVpnModule,
NB_L2VPNS as NB_VPN_L2VPNS,
)
from copy import deepcopy

Expand Down Expand Up @@ -186,7 +191,12 @@ def main():
argument_spec=argument_spec, supports_check_mode=True, required_if=required_if
)

netbox_l2vpn = NetboxIpamModule(module, NB_L2VPNS)
netbox_l2vpn = NetboxModule(module, "")
if netbox_l2vpn._find_app(NB_IPAM_L2VPNS) == "ipam":
netbox_l2vpn = NetboxIpamModule(module, NB_IPAM_L2VPNS)
if netbox_l2vpn._find_app(NB_VPN_L2VPNS) == "vpn":
netbox_l2vpn = NetboxVpnModule(module, NB_VPN_L2VPNS)

netbox_l2vpn.run()


Expand Down
Loading