Skip to content

Commit d2d9c71

Browse files
authored
Merge pull request #1287 from richbibby/1156-feature-netbox-37-vpn
2 parents eea1aec + 73c6565 commit d2d9c71

File tree

11 files changed

+760
-0
lines changed

11 files changed

+760
-0
lines changed

meta/runtime.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ action_groups:
7878
- netbox_tag
7979
- netbox_tenant
8080
- netbox_tenant_group
81+
- netbox_tunnel
82+
- netbox_tunnel_group
8183
- netbox_virtual_chassis
8284
- netbox_virtual_machine
8385
- netbox_vlan

plugins/module_utils/netbox_utils.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@
131131
vpn={
132132
"l2vpns": {"introduced": "3.7"},
133133
"l2vpn_terminations": {"introduced": "3.7"},
134+
"tunnels": {"introduced": "3.7"},
135+
"tunnel_groups": {"introduced": "3.7"},
136+
"ipsec_profiles": {"introduced": "3.7"},
134137
},
135138
)
136139

@@ -201,6 +204,7 @@
201204
site_group="slug",
202205
tenant="slug",
203206
tenant_group="slug",
207+
tunnel="name",
204208
time_zone="timezone",
205209
virtual_chassis="name",
206210
virtual_machine="name",
@@ -257,6 +261,7 @@
257261
"inventory_item_role": "inventory_item_roles",
258262
"ip_addresses": "ip_addresses",
259263
"ipaddresses": "ip_addresses",
264+
"ipsec_profile": "ipsec_profiles",
260265
"location": "locations",
261266
"lag": "interfaces",
262267
"manufacturer": "manufacturers",
@@ -313,6 +318,7 @@
313318
"tenant_groups": "tenant_groups",
314319
"termination_a": "interfaces",
315320
"termination_b": "interfaces",
321+
"tunnel_group": "tunnel_groups",
316322
"untagged_vlan": "vlans",
317323
"virtual_chassis": "virtual_chassis",
318324
"virtual_machine": "virtual_machines",
@@ -399,6 +405,8 @@
399405
"tags": "tags",
400406
"tenants": "tenant",
401407
"tenant_groups": "tenant_group",
408+
"tunnels": "tunnel",
409+
"tunnel_groups": "tunnel_group",
402410
"virtual_chassis": "virtual_chassis",
403411
"virtual_machines": "virtual_machine",
404412
"virtual_disks": "virtual_disk",
@@ -537,6 +545,8 @@
537545
"tenant_group": set(["slug"]),
538546
"termination_a": set(["name", "device", "virtual_machine"]),
539547
"termination_b": set(["name", "device", "virtual_machine"]),
548+
"tunnel": set(["name"]),
549+
"tunnel_group": set(["slug"]),
540550
"untagged_vlan": set(["group", "name", "site", "vid", "vlan_group", "tenant"]),
541551
"virtual_chassis": set(["name", "master"]),
542552
"virtual_machine": set(["name", "cluster"]),
@@ -630,6 +640,7 @@
630640
"tenant_group": "group",
631641
"termination_a": "termination_a_id",
632642
"termination_b": "termination_b_id",
643+
"tunnel_group": "group",
633644
"virtual_machine_role": "role",
634645
"vlan_role": "role",
635646
"vlan_group": "group",
@@ -660,6 +671,7 @@
660671
"tags",
661672
"tenants",
662673
"tenant_groups",
674+
"tunnel_groups",
663675
"manufacturers",
664676
"platforms",
665677
"providers",

plugins/module_utils/netbox_vpn.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
NB_L2VPNS = "l2vpns"
1919
NB_L2VPN_TERMINATIONS = "l2vpn_terminations"
20+
NB_TUNNELS = "tunnels"
21+
NB_TUNNEL_GROUPS = "tunnel_groups"
2022

2123

2224
class NetboxVpnModule(NetboxModule):
@@ -30,6 +32,8 @@ def run(self):
3032
Supported endpoints:
3133
- l2vpns
3234
- l2vpn_terminations
35+
- tunnels
36+
- tunnel_groups
3337
"""
3438
# Used to dynamically set key when returning results
3539
endpoint_name = ENDPOINT_NAME_MAPPING[self.endpoint]

plugins/modules/netbox_tunnel.py

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
# Copyright: (c) 2024, Rich Bibby, NetBox Labs (@richbibby)
4+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5+
6+
from __future__ import absolute_import, division, print_function
7+
8+
__metaclass__ = type
9+
10+
DOCUMENTATION = r"""
11+
---
12+
module: netbox_tunnel
13+
short_description: Create, update or delete tunnels within NetBox
14+
description:
15+
- Creates, updates or removes tunnels from NetBox
16+
notes:
17+
- Tags should be defined as a YAML list
18+
- This should be ran with connection C(local) and hosts C(localhost)
19+
author:
20+
- Rich Bibby, NetBox Labs (@richbibby)
21+
requirements:
22+
- pynetbox
23+
version_added: '3.20.0'
24+
extends_documentation_fragment:
25+
- netbox.netbox.common
26+
options:
27+
data:
28+
type: dict
29+
description:
30+
- Defines the tunnel configuration
31+
suboptions:
32+
name:
33+
description:
34+
- The name of the tunnel
35+
required: true
36+
type: str
37+
status:
38+
description:
39+
- Status of the tunnel
40+
required: false
41+
type: raw
42+
tunnel_group:
43+
description:
44+
- The Tunnel group the VLAN will be associated with. Must exist in NetBox
45+
required: false
46+
type: raw
47+
encapsulation:
48+
description:
49+
- The encapsulation protocol or technique employed to effect the tunnel
50+
choices:
51+
- ipsec-transport
52+
- ipsec-tunnel
53+
- ip-ip
54+
- gre
55+
required: true
56+
type: str
57+
ipsec_profile:
58+
description:
59+
- The IPSec Profile employed to negotiate security associations
60+
required: false
61+
type: raw
62+
tenant:
63+
description:
64+
- The tenant that the tunnel will be associated with
65+
required: false
66+
type: raw
67+
tunnel_id:
68+
description:
69+
- The ID of the tunnel
70+
required: false
71+
type: int
72+
description:
73+
description:
74+
- The description of the tunnel
75+
required: false
76+
type: str
77+
comments:
78+
description:
79+
- Comments that may include additional information in regards to the tunnel
80+
required: false
81+
type: str
82+
tags:
83+
description:
84+
- Any tags that the tunnel may need to be associated with
85+
required: false
86+
type: list
87+
elements: raw
88+
custom_fields:
89+
description:
90+
- Must exist in NetBox
91+
required: false
92+
type: dict
93+
required: true
94+
"""
95+
96+
EXAMPLES = r"""
97+
- name: "Test NetBox modules"
98+
connection: local
99+
hosts: localhost
100+
gather_facts: false
101+
102+
tasks:
103+
- name: Create tunnel within NetBox with only required information
104+
netbox.netbox.netbox_tunnel:
105+
netbox_url: http://netbox.local
106+
netbox_token: thisIsMyToken
107+
data:
108+
name: Test Tunnel
109+
encapsulation: ipsec-tunnel
110+
state: present
111+
112+
- name: Delete tunnel within NetBox
113+
netbox.netbox.netbox_tunnel:
114+
netbox_url: http://netbox.local
115+
netbox_token: thisIsMyToken
116+
data:
117+
name: Test Tunnel
118+
encapsulation: ipsec-tunnel
119+
state: absent
120+
121+
- name: Create tunnel with all information
122+
netbox.netbox.netbox_tunnel:
123+
netbox_url: http://netbox.local
124+
netbox_token: thisIsMyToken
125+
data:
126+
name: Test Tunnel
127+
status: planned
128+
tunnel_group: Test Tunnel Group
129+
encapsulation: ipsec-tunnel
130+
ipsec_profile: ipsec-profile
131+
description: Test Description
132+
tenant: Test Tenant
133+
tunnel_id: 200
134+
tags:
135+
- Schnozzberry
136+
state: present
137+
"""
138+
139+
RETURN = r"""
140+
tunnel:
141+
description: Serialized object as created or already existent within NetBox
142+
returned: success (when I(state=present))
143+
type: dict
144+
msg:
145+
description: Message indicating failure or info about what has been achieved
146+
returned: always
147+
type: str
148+
"""
149+
150+
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_utils import (
151+
NetboxAnsibleModule,
152+
NETBOX_ARG_SPEC,
153+
)
154+
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_vpn import (
155+
NetboxVpnModule,
156+
NB_TUNNELS,
157+
)
158+
from copy import deepcopy
159+
160+
161+
def main():
162+
"""
163+
Main entry point for module execution
164+
"""
165+
argument_spec = deepcopy(NETBOX_ARG_SPEC)
166+
argument_spec.update(
167+
dict(
168+
data=dict(
169+
type="dict",
170+
required=True,
171+
options=dict(
172+
name=dict(required=True, type="str"),
173+
status=dict(required=False, type="raw"),
174+
tunnel_group=dict(required=False, type="raw"),
175+
encapsulation=dict(
176+
required=True,
177+
type="str",
178+
choices=[
179+
"ipsec-transport",
180+
"ipsec-tunnel",
181+
"ip-ip",
182+
"gre",
183+
],
184+
),
185+
ipsec_profile=dict(required=False, type="raw"),
186+
tenant=dict(required=False, type="raw"),
187+
tunnel_id=dict(required=False, type="int"),
188+
description=dict(required=False, type="str"),
189+
comments=dict(required=False, type="str"),
190+
tags=dict(required=False, type="list", elements="raw"),
191+
custom_fields=dict(required=False, type="dict"),
192+
),
193+
),
194+
)
195+
)
196+
197+
required_if = [
198+
("state", "present", ["name", "encapsulation"]),
199+
("state", "absent", ["name", "encapsulation"]),
200+
]
201+
202+
module = NetboxAnsibleModule(
203+
argument_spec=argument_spec, supports_check_mode=True, required_if=required_if
204+
)
205+
206+
netbox_tunnel = NetboxVpnModule(module, NB_TUNNELS)
207+
netbox_tunnel.run()
208+
209+
210+
if __name__ == "__main__": # pragma: no cover
211+
main()

0 commit comments

Comments
 (0)