Skip to content

Commit ac1ece8

Browse files
authored
Add Export Template module (#727)
1 parent 73add49 commit ac1ece8

File tree

5 files changed

+290
-2
lines changed

5 files changed

+290
-2
lines changed

plugins/module_utils/netbox_extras.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
NB_TAGS = "tags"
1616
NB_CUSTOM_FIELDS = "custom_fields"
1717
NB_CUSTOM_LINKS = "custom_links"
18+
NB_EXPORT_TEMPLATES = "export_templates"
1819

1920

2021
class NetboxExtrasModule(NetboxModule):

plugins/module_utils/netbox_utils.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,13 @@
7474
"site_groups",
7575
"virtual_chassis",
7676
],
77-
extras=["config_contexts", "tags", "custom_fields", "custom_links"],
77+
extras=[
78+
"config_contexts",
79+
"tags",
80+
"custom_fields",
81+
"custom_links",
82+
"export_templates",
83+
],
7884
ipam=[
7985
"aggregates",
8086
"ip_addresses",
@@ -115,6 +121,7 @@
115121
device_role="slug",
116122
device_type="slug",
117123
export_targets="name",
124+
export_template="name",
118125
group="slug",
119126
installed_device="name",
120127
import_targets="name",
@@ -288,6 +295,7 @@
288295
"devices": "device",
289296
"device_roles": "device_role",
290297
"device_types": "device_type",
298+
"export_templates": "export_template",
291299
"front_ports": "front_port",
292300
"front_port_templates": "front_port_template",
293301
"interfaces": "interface",
@@ -379,6 +387,7 @@
379387
"device": set(["name"]),
380388
"device_role": set(["slug"]),
381389
"device_type": set(["slug"]),
390+
"export_template": set(["name"]),
382391
"front_port": set(["name", "device", "rear_port"]),
383392
"front_port_template": set(["name", "device_type", "rear_port"]),
384393
"installed_device": set(["name"]),
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
# Copyright: (c) 2022, Martin Rødvand (@rodvand) <p@tristero.se>
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_export_template
13+
short_description: Creates, updates or deletes export templates within NetBox
14+
description:
15+
- Creates, updates or removes export templates from NetBox
16+
notes:
17+
- This should be ran with connection C(local) and hosts C(localhost)
18+
- Use the C(!unsafe) data type if you want jinja2 code in template_code
19+
author:
20+
- Martin Rødvand (@rodvand)
21+
requirements:
22+
- pynetbox
23+
version_added: "3.6.0"
24+
extends_documentation_fragment:
25+
- netbox.netbox.common
26+
options:
27+
data:
28+
type: dict
29+
description:
30+
- Defines the custom field
31+
suboptions:
32+
content_type:
33+
description:
34+
- The content type to apply this export template to
35+
required: false
36+
type: raw
37+
name:
38+
description:
39+
- The name of the export template
40+
required: true
41+
type: str
42+
description:
43+
description:
44+
- Description of the export template
45+
required: false
46+
type: str
47+
template_code:
48+
description:
49+
- Template code of the export template
50+
required: true
51+
type: raw
52+
mime_type:
53+
description:
54+
- MIME type of the export template
55+
required: false
56+
type: str
57+
file_extension:
58+
description:
59+
- The file extension of the export template
60+
required: false
61+
type: str
62+
as_attachment:
63+
description:
64+
- Download file as attachment
65+
required: false
66+
type: bool
67+
required: true
68+
"""
69+
70+
EXAMPLES = r"""
71+
- name: "Test NetBox custom_link module"
72+
connection: local
73+
hosts: localhost
74+
tasks:
75+
- name: Create a custom link on device
76+
netbox_custom_link:
77+
netbox_url: http://netbox.local
78+
netbox_token: thisIsMyToken
79+
data:
80+
content_type: "dcim.device"
81+
name: Custom Link
82+
link_text: "Open Web Management"
83+
link_url: !unsafe https://{{ obj.name }}.domain.local
84+
85+
- name: Delete the custom link
86+
netbox_custom_field:
87+
netbox_url: http://netbox.local
88+
netbox_token: thisIsMyToken
89+
data:
90+
content_type: "dcim.device"
91+
name: Custom Link
92+
link_text: "Open Web Management"
93+
link_url: !unsafe https://{{ obj.name }}.domain.local
94+
state: absent
95+
"""
96+
97+
RETURN = r"""
98+
custom_link:
99+
description: Serialized object as created/existent/updated/deleted within NetBox
100+
returned: always
101+
type: dict
102+
msg:
103+
description: Message indicating failure or info about what has been achieved
104+
returned: always
105+
type: str
106+
"""
107+
108+
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_utils import (
109+
NetboxAnsibleModule,
110+
NETBOX_ARG_SPEC,
111+
)
112+
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_extras import (
113+
NetboxExtrasModule,
114+
NB_EXPORT_TEMPLATES,
115+
)
116+
from copy import deepcopy
117+
118+
119+
def main():
120+
"""
121+
Main entry point for module execution
122+
"""
123+
argument_spec = deepcopy(NETBOX_ARG_SPEC)
124+
argument_spec.update(
125+
dict(
126+
data=dict(
127+
type="dict",
128+
required=True,
129+
options=dict(
130+
content_type=dict(required=False, type="raw"),
131+
name=dict(required=True, type="str"),
132+
description=dict(required=False, type="str"),
133+
template_code=dict(required=True, type="raw"),
134+
mime_type=dict(required=False, type="str"),
135+
file_extension=dict(required=False, type="str"),
136+
as_attachment=dict(required=False, type="bool"),
137+
),
138+
)
139+
)
140+
)
141+
142+
required_if = [
143+
("state", "present", ["content_type", "name", "template_code"]),
144+
("state", "absent", ["name"]),
145+
]
146+
147+
module = NetboxAnsibleModule(
148+
argument_spec=argument_spec, supports_check_mode=True, required_if=required_if
149+
)
150+
151+
netbox_export_template = NetboxExtrasModule(module, NB_EXPORT_TEMPLATES)
152+
netbox_export_template.run()
153+
154+
155+
if __name__ == "__main__":
156+
main()

tests/integration/targets/v3.1/tasks/main.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,13 @@
216216
tags:
217217
- netbox_custom_link
218218
tags:
219-
- netbox_custom_link
219+
- netbox_custom_link
220+
221+
- name: "NETBOX_EXPORT_TEMPLATE TESTS"
222+
include_tasks:
223+
file: "netbox_export_template.yml"
224+
apply:
225+
tags:
226+
- netbox_export_template
227+
tags:
228+
- netbox_export_template
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
##
3+
##
4+
### NETBOX_EXPORT_TEMPLATE
5+
##
6+
##
7+
- name: "EXPORT_TEMPLATE 1: Necessary info creation"
8+
netbox.netbox.netbox_export_template:
9+
netbox_url: http://localhost:32768
10+
netbox_token: 0123456789abcdef0123456789abcdef01234567
11+
data:
12+
content_type: "dcim.device"
13+
name: Example Export Template
14+
description: Export Devices
15+
template_code: !unsafe >-
16+
{% for obj in queryset %}{{ obj.name }}{% endfor %}
17+
state: present
18+
register: test_one
19+
20+
- name: "EXPORT_TEMPLATE 1: ASSERT - Necessary info creation"
21+
assert:
22+
that:
23+
- test_one is changed
24+
- test_one['diff']['before']['state'] == "absent"
25+
- test_one['diff']['after']['state'] == "present"
26+
- test_one['export_template']['name'] == "Example Export Template"
27+
- test_one['export_template']['content_type'] == "dcim.device"
28+
- test_one['export_template']['description'] == "Export Devices"
29+
- test_one['msg'] == "export_template Example Export Template created"
30+
31+
- name: "EXPORT_TEMPLATE 2: Create duplicate"
32+
netbox.netbox.netbox_export_template:
33+
netbox_url: http://localhost:32768
34+
netbox_token: 0123456789abcdef0123456789abcdef01234567
35+
data:
36+
content_type: "dcim.device"
37+
name: Example Export Template
38+
description: Export Devices
39+
template_code: !unsafe >-
40+
{% for obj in queryset %}{{ obj.name }}{% endfor %}
41+
state: present
42+
register: test_two
43+
44+
- name: "EXPORT_TEMPLATE 2: ASSERT - Create duplicate"
45+
assert:
46+
that:
47+
- not test_two['changed']
48+
- test_two['export_template']['name'] == "Example Export Template"
49+
- test_two['msg'] == "export_template Example Export Template already exists"
50+
51+
- name: "CUSTOM_FIELD 3: Update data and remove as_attachment"
52+
netbox.netbox.netbox_export_template:
53+
netbox_url: http://localhost:32768
54+
netbox_token: 0123456789abcdef0123456789abcdef01234567
55+
data:
56+
content_type: "dcim.device"
57+
name: Example Export Template
58+
description: Export Devices
59+
template_code: !unsafe >-
60+
{% for obj in queryset %}{{ obj.name }}{% endfor %}
61+
as_attachment: no
62+
state: present
63+
register: test_three
64+
65+
- name: "CUSTOM_FIELD 3: ASSERT - Updated"
66+
assert:
67+
that:
68+
- test_three is changed
69+
- test_three['diff']['after']['as_attachment'] == false
70+
- test_three['export_template']['name'] == "Example Export Template"
71+
- test_three['msg'] == "export_template Example Export Template updated"
72+
73+
- name: "EXPORT_TEMPLATE 4: Change content type"
74+
netbox.netbox.netbox_export_template:
75+
netbox_url: http://localhost:32768
76+
netbox_token: 0123456789abcdef0123456789abcdef01234567
77+
data:
78+
content_type: "virtualization.virtualmachine"
79+
name: Example Export Template
80+
description: Export Devices
81+
template_code: !unsafe >-
82+
{% for obj in queryset %}{{ obj.name }}{% endfor %}
83+
state: present
84+
register: test_four
85+
86+
- name: "EXPORT_TEMPLATE 4: ASSERT - Change content type"
87+
assert:
88+
that:
89+
- test_four is changed
90+
- test_four['diff']['after']['content_type'] == "virtualization.virtualmachine"
91+
- test_four['export_template']['name'] == "Example Export Template"
92+
- test_four['msg'] == "export_template Example Export Template updated"
93+
94+
- name: "EXPORT_TEMPLATE 5: Delete"
95+
netbox.netbox.netbox_export_template:
96+
netbox_url: http://localhost:32768
97+
netbox_token: 0123456789abcdef0123456789abcdef01234567
98+
data:
99+
content_type: "virtualization.virtualmachine"
100+
name: Example Export Template
101+
description: Export Devices
102+
template_code: !unsafe >-
103+
{% for obj in queryset %}{{ obj.name }}{% endfor %}
104+
state: absent
105+
register: test_five
106+
107+
- name: "EXPORT_TEMPLATE 5: ASSERT - Deleted"
108+
assert:
109+
that:
110+
- test_five is changed
111+
- test_five['diff']['after']['state'] == "absent"
112+
- test_five['export_template']['name'] == "Example Export Template"
113+
- test_five['msg'] == "export_template Example Export Template deleted"

0 commit comments

Comments
 (0)