Skip to content

Commit 45f8c22

Browse files
authored
New module: netbox_interface_template (#259)
1 parent 51e92df commit 45f8c22

File tree

6 files changed

+295
-0
lines changed

6 files changed

+295
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ To keep the code simple, we only officially support the two latest releases of N
3333
- netbox_device_bay
3434
- netbox_device_bay_template
3535
- netbox_device_interface
36+
- netbox_device_interface_template
3637
- netbox_device_role
3738
- netbox_device_type
3839
- netbox_device

plugins/module_utils/netbox_dcim.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
NB_FRONT_PORTS = "front_ports"
3131
NB_FRONT_PORT_TEMPLATES = "front_port_templates"
3232
NB_INTERFACES = "interfaces"
33+
NB_INTERFACE_TEMPLATES = "interface_templates"
3334
NB_INVENTORY_ITEMS = "inventory_items"
3435
NB_MANUFACTURERS = "manufacturers"
3536
NB_PLATFORMS = "platforms"
@@ -71,6 +72,7 @@ def run(self):
7172
- front_ports
7273
- front_port_templates
7374
- interfaces
75+
- interface_templates
7476
- inventory_items
7577
- manufacturers
7678
- platforms

plugins/module_utils/netbox_utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"front_ports",
5050
"front_port_templates",
5151
"interfaces",
52+
"interface_templates",
5253
"inventory_items",
5354
"manufacturers",
5455
"platforms",
@@ -150,6 +151,7 @@
150151
"group": "tenant_groups",
151152
"installed_device": "devices",
152153
"interface": "interfaces",
154+
"interface_template": "interface_templates",
153155
"ip_addresses": "ip_addresses",
154156
"ipaddresses": "ip_addresses",
155157
"lag": "interfaces",
@@ -210,6 +212,7 @@
210212
"front_ports": "front_port",
211213
"front_port_templates": "front_port_template",
212214
"interfaces": "interface",
215+
"interface_templates": "interface_template",
213216
"inventory_items": "inventory_item",
214217
"ip_addresses": "ip_address",
215218
"manufacturers": "manufacturer",
@@ -271,6 +274,7 @@
271274
"front_port_template": set(["name", "device_type", "rear_port"]),
272275
"installed_device": set(["name"]),
273276
"interface": set(["name", "device", "virtual_machine"]),
277+
"interface_template": set(["name", "device_type"]),
274278
"inventory_item": set(["name", "device"]),
275279
"ip_address": set(["address", "vrf", "interface"]),
276280
"ip_addresses": set(["address", "vrf", "device", "interface"]),
@@ -342,6 +346,7 @@
342346
"front_ports": set(["type"]),
343347
"front_port_templates": set(["type"]),
344348
"interfaces": set(["form_factor", "mode", "type"]),
349+
"interface_templates": set(["type"]),
345350
"ip_addresses": set(["status", "role"]),
346351
"prefixes": set(["status"]),
347352
"power_feeds": set(["status", "type", "supply", "phase"]),
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
# © 2020 Nokia
4+
# Licensed under the GNU General Public License v3.0 only
5+
# SPDX-License-Identifier: GPL-3.0-only
6+
7+
from __future__ import absolute_import, division, print_function
8+
9+
__metaclass__ = type
10+
11+
ANSIBLE_METADATA = {
12+
"metadata_version": "1.1",
13+
"status": ["preview"],
14+
"supported_by": "community",
15+
}
16+
17+
DOCUMENTATION = r"""
18+
---
19+
module: netbox_device_interface_template
20+
short_description: Creates or removes interfaces on devices from Netbox
21+
description:
22+
- Creates or removes interfaces from Netbox
23+
notes:
24+
- Tags should be defined as a YAML list
25+
- This should be ran with connection C(local) and hosts C(localhost)
26+
author:
27+
- Tobias Groß (@toerb)
28+
requirements:
29+
- pynetbox
30+
version_added: "0.2.4"
31+
options:
32+
netbox_url:
33+
description:
34+
- URL of the Netbox instance resolvable by Ansible control host
35+
required: true
36+
type: str
37+
netbox_token:
38+
description:
39+
- The token created within Netbox to authorize API access
40+
required: true
41+
type: str
42+
data:
43+
description:
44+
- Defines the prefix configuration
45+
suboptions:
46+
device_type:
47+
description:
48+
- Name of the device the interface template will be associated with (case-sensitive)
49+
required: true
50+
type: raw
51+
name:
52+
description:
53+
- Name of the interface template to be created
54+
required: true
55+
type: str
56+
type:
57+
description:
58+
- |
59+
Form factor of the interface:
60+
ex. 1000Base-T (1GE), Virtual, 10GBASE-T (10GE)
61+
This has to be specified exactly as what is found within UI
62+
required: true
63+
type: str
64+
mgmt_only:
65+
description:
66+
- This interface template is used only for out-of-band management
67+
required: false
68+
type: bool
69+
required: true
70+
type: dict
71+
state:
72+
description:
73+
- Use C(present) or C(absent) for adding or removing.
74+
choices: [ absent, present ]
75+
default: present
76+
type: str
77+
query_params:
78+
description:
79+
- This can be used to override the specified values in ALLOWED_QUERY_PARAMS that is defined
80+
- in plugins/module_utils/netbox_utils.py and provides control to users on what may make
81+
- an object unique in their environment.
82+
required: false
83+
type: list
84+
validate_certs:
85+
description:
86+
- |
87+
If C(no), SSL certificates will not be validated.
88+
This should only be used on personally controlled sites using self-signed certificates.
89+
default: true
90+
type: raw
91+
"""
92+
93+
EXAMPLES = r"""
94+
- name: "Test Netbox interface template module"
95+
connection: local
96+
hosts: localhost
97+
gather_facts: False
98+
tasks:
99+
- name: Create interface template within Netbox with only required information
100+
netbox_device_interface_template:
101+
netbox_url: http://netbox.local
102+
netbox_token: thisIsMyToken
103+
data:
104+
device_type: Arista Test
105+
name: 10GBASE-T (10GE)
106+
type: 10gbase-t
107+
state: present
108+
- name: Delete interface template within netbox
109+
netbox_device_interface_template:
110+
netbox_url: http://netbox.local
111+
netbox_token: thisIsMyToken
112+
data:
113+
device_type: Arista Test
114+
name: 10GBASE-T (10GE)
115+
type: 10gbase-t
116+
state: absent
117+
"""
118+
119+
RETURN = r"""
120+
interface_template:
121+
description: Serialized object as created or already existent within Netbox
122+
returned: on creation
123+
type: dict
124+
msg:
125+
description: Message indicating failure or info about what has been achieved
126+
returned: always
127+
type: str
128+
"""
129+
130+
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_utils import (
131+
NetboxAnsibleModule,
132+
NETBOX_ARG_SPEC,
133+
)
134+
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_dcim import (
135+
NetboxDcimModule,
136+
NB_INTERFACE_TEMPLATES,
137+
)
138+
from copy import deepcopy
139+
140+
141+
def main():
142+
"""
143+
Main entry point for module execution
144+
"""
145+
argument_spec = deepcopy(NETBOX_ARG_SPEC)
146+
argument_spec.update(
147+
dict(
148+
data=dict(
149+
type="dict",
150+
required=True,
151+
options=dict(
152+
device_type=dict(required=True, type="raw"),
153+
name=dict(required=True, type="str"),
154+
type=dict(required=True, type="str",),
155+
mgmt_only=dict(required=False, type="bool"),
156+
),
157+
),
158+
)
159+
)
160+
161+
required_if = [
162+
("state", "present", ["device_type", "name", "type"]),
163+
("state", "absent", ["device_type", "name", "type"]),
164+
]
165+
166+
module = NetboxAnsibleModule(
167+
argument_spec=argument_spec, supports_check_mode=True, required_if=required_if
168+
)
169+
170+
netbox_device_interface_template = NetboxDcimModule(module, NB_INTERFACE_TEMPLATES)
171+
netbox_device_interface_template.run()
172+
173+
174+
if __name__ == "__main__": # pragma: no cover
175+
main()

tests/integration/targets/latest/tasks/main.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
- name: "NETBOX_DEVICE_INTERFACE TESTS"
66
include_tasks: "netbox_device_interface.yml"
77

8+
- name: "NETBOX_DEVICE_INTERFACE_TEMPLATE TESTS"
9+
include_tasks: "netbox_device_interface_template.yml"
10+
811
- name: "NETBOX_IP_ADDRESS TESTS"
912
include_tasks: "netbox_ip_address.yml"
1013

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
##
3+
##
4+
### NETBOX_DEVICE_INTERFACE_TEMPLATE
5+
##
6+
##
7+
- name: "1 - Interface with required information"
8+
netbox.netbox.netbox_device_interface_template:
9+
netbox_url: "http://localhost:32768"
10+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
11+
data:
12+
device_type: Arista Test
13+
name: 10GBASE-T (10GE)
14+
type: 10gbase-t
15+
register: test_one
16+
17+
- name: "1 - ASSERT"
18+
assert:
19+
that:
20+
- test_one is changed
21+
- test_one['msg'] == "interface_template 10GBASE-T (10GE) created"
22+
- test_one['diff']['before']['state'] == 'absent'
23+
- test_one['diff']['after']['state'] == 'present'
24+
- test_one['interface_template']['name'] == "10GBASE-T (10GE)"
25+
- test_one['interface_template']['device_type'] == 2
26+
- test_one['interface_template']['type'] == '10gbase-t'
27+
28+
- name: "2 - Update 10GBASE-T (10GE)"
29+
netbox.netbox.netbox_device_interface_template:
30+
netbox_url: "http://localhost:32768"
31+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
32+
data:
33+
device_type: Arista Test
34+
name: 10GBASE-T (10GE)
35+
type: 10gbase-t
36+
mgmt_only: true
37+
register: test_two
38+
39+
- name: "2 - ASSERT"
40+
assert:
41+
that:
42+
- test_two is changed
43+
- test_two['msg'] == "interface_template 10GBASE-T (10GE) updated"
44+
- test_two['diff']['after']['mgmt_only'] == true
45+
- test_two['interface_template']['name'] == "10GBASE-T (10GE)"
46+
- test_two['interface_template']['device_type'] == 2
47+
- test_two['interface_template']['mgmt_only'] == true
48+
49+
- name: "3 - Delete interface template 10GBASE-T (10GE)"
50+
netbox.netbox.netbox_device_interface_template:
51+
netbox_url: "http://localhost:32768"
52+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
53+
data:
54+
device_type: Arista Test
55+
name: 10GBASE-T (10GE)
56+
type: 10gbase-t
57+
state: absent
58+
register: test_three
59+
60+
- name: "3 - ASSERT"
61+
assert:
62+
that:
63+
- test_three is changed
64+
- test_three['msg'] == "interface_template 10GBASE-T (10GE) deleted"
65+
- test_three['diff']['before']['state'] == "present"
66+
- test_three['diff']['after']['state'] == "absent"
67+
68+
- name: "4 - Create LAG with several specified options"
69+
netbox.netbox.netbox_device_interface_template:
70+
netbox_url: "http://localhost:32768"
71+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
72+
data:
73+
device_type: Arista Test
74+
name: port channel template
75+
type: lag
76+
mgmt_only: false
77+
state: present
78+
register: test_four
79+
80+
- name: "4 - ASSERT"
81+
assert:
82+
that:
83+
- test_four is changed
84+
- test_four['msg'] == "interface_template port channel template created"
85+
- test_four['diff']['before']['state'] == 'absent'
86+
- test_four['diff']['after']['state'] == 'present'
87+
- test_four['interface_template']['name'] == "port channel template"
88+
- test_four['interface_template']['device_type'] == 2
89+
- test_four['interface_template']['type'] == "lag"
90+
- test_four['interface_template']['mgmt_only'] == false
91+
92+
- name: "5 - Duplicate Interface Template port channel template"
93+
netbox.netbox.netbox_device_interface_template:
94+
netbox_url: "http://localhost:32768"
95+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
96+
data:
97+
device_type: Arista Test
98+
name: port channel template
99+
type: lag
100+
register: test_five
101+
102+
- name: "5 - ASSERT"
103+
assert:
104+
that:
105+
- not test_five['changed']
106+
- test_five['msg'] == "interface_template port channel template already exists"
107+
- test_five['interface_template']['name'] == "port channel template"
108+
- test_five['interface_template']['device_type'] == 2
109+
- test_five['interface_template']['type'] == "lag"

0 commit comments

Comments
 (0)