Skip to content

Commit 9391280

Browse files
authored
#644 Add contact modules (#671)
* Add modules netbox_contact_role, netbox_contact, netbox_contact_group
1 parent a71767f commit 9391280

File tree

8 files changed

+687
-3
lines changed

8 files changed

+687
-3
lines changed

plugins/module_utils/netbox_tenancy.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
NB_TENANTS = "tenants"
1616
NB_TENANT_GROUPS = "tenant_groups"
17+
NB_CONTACTS = "contacts"
18+
NB_CONTACT_GROUPS = "contact_groups"
19+
NB_CONTACT_ROLES = "contact_roles"
1720

1821

1922
class NetboxTenancyModule(NetboxModule):
@@ -25,8 +28,10 @@ def run(self):
2528
This function should have all necessary code for endpoints within the application
2629
to create/update/delete the endpoint objects
2730
Supported endpoints:
28-
tenants
29-
tenant groups
31+
- tenants
32+
- tenant groups
33+
- contacts
34+
- contact groups
3035
"""
3136
# Used to dynamically set key when returning results
3237
endpoint_name = ENDPOINT_NAME_MAPPING[self.endpoint]

plugins/module_utils/netbox_utils.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
"services",
9090
],
9191
secrets=[],
92-
tenancy=["tenants", "tenant_groups"],
92+
tenancy=["tenants", "tenant_groups", "contacts", "contact_groups", "contact_roles"],
9393
virtualization=["cluster_groups", "cluster_types", "clusters", "virtual_machines"],
9494
)
9595

@@ -102,6 +102,8 @@
102102
cluster_group="slug",
103103
cluster_type="slug",
104104
config_context="name",
105+
contact_group="name",
106+
contact_role="name",
105107
device="name",
106108
device_role="slug",
107109
device_type="slug",
@@ -113,6 +115,7 @@
113115
manufacturer="slug",
114116
nat_inside="address",
115117
nat_outside="address",
118+
parent_contact_group="name",
116119
parent_location="slug",
117120
parent_region="slug",
118121
parent_site_group="slug",
@@ -162,6 +165,7 @@
162165
"cluster_groups": "cluster_groups",
163166
"cluster_type": "cluster_types",
164167
"config_context": "config_contexts",
168+
"contact_groups": "contact_groups",
165169
"dcim.consoleport": "console_ports",
166170
"dcim.consoleserverport": "console_server_ports",
167171
"dcim.frontport": "front_ports",
@@ -189,6 +193,7 @@
189193
"nat_inside": "ip_addresses",
190194
"nat_outside": "ip_addresses",
191195
"platform": "platforms",
196+
"parent_contact_group": "contact_groups",
192197
"parent_location": "locations",
193198
"parent_interface": "interfaces",
194199
"parent_vm_interface": "interfaces",
@@ -253,6 +258,9 @@
253258
"console_port_templates": "console_port_template",
254259
"console_server_ports": "console_server_port",
255260
"console_server_port_templates": "console_server_port_template",
261+
"contacts": "contact",
262+
"contact_groups": "contact_group",
263+
"contact_roles": "contact_role",
256264
"device_bays": "device_bay",
257265
"device_bay_templates": "device_bay_template",
258266
"devices": "device",
@@ -327,6 +335,9 @@
327335
"console_port_template": set(["name", "device_type"]),
328336
"console_server_port": set(["name", "device"]),
329337
"console_server_port_template": set(["name", "device_type"]),
338+
"contact": set(["name", "group"]),
339+
"contact_group": set(["name"]),
340+
"contact_role": set(["name"]),
330341
"dcim.consoleport": set(["name", "device"]),
331342
"dcim.consoleserverport": set(["name", "device"]),
332343
"dcim.frontport": set(["name", "device", "rear_port"]),
@@ -354,6 +365,7 @@
354365
"manufacturer": set(["slug"]),
355366
"master": set(["name"]),
356367
"nat_inside": set(["vrf", "address"]),
368+
"parent_contact_group": set(["name"]),
357369
"parent_location": set(["slug"]),
358370
"parent_interface": set(["name"]),
359371
"parent_vm_interface": set(["name"]),
@@ -452,6 +464,8 @@
452464
"circuit_type": "type",
453465
"cluster_type": "type",
454466
"cluster_group": "group",
467+
"contact_group": "group",
468+
"parent_contact_group": "parent",
455469
"parent_location": "parent",
456470
"parent_interface": "parent",
457471
"parent_vm_interface": "parent",
@@ -478,6 +492,8 @@
478492
"circuit_types",
479493
"cluster_groups",
480494
"cluster_types",
495+
"contact_groups",
496+
"contact_roles",
481497
"device_roles",
482498
"device_types",
483499
"ipam_roles",
@@ -989,6 +1005,7 @@ def _find_ids(self, data, user_query_params):
9891005
"platforms",
9901006
"cluster_groups",
9911007
"clusters",
1008+
"contact_groups",
9921009
"tenant_groups",
9931010
"tenants",
9941011
"tags",

plugins/modules/netbox_contact.py

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
# Copyright: (c) 2021, Martin Rødvand (@rodvand)
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_contact
13+
short_description: Creates or removes contacts from NetBox
14+
description:
15+
- Creates or removes contacts 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+
- Martin Rødvand (@rodvand)
21+
requirements:
22+
- pynetbox
23+
version_added: "3.5.0"
24+
extends_documentation_fragment:
25+
- netbox.netbox.common
26+
options:
27+
data:
28+
type: dict
29+
description:
30+
- Defines the contact configuration
31+
suboptions:
32+
name:
33+
description:
34+
- Name of the contact to be created
35+
required: true
36+
type: str
37+
title:
38+
description:
39+
- The title of the contact
40+
required: false
41+
type: str
42+
phone:
43+
description:
44+
- The phone number of the contact
45+
required: false
46+
type: str
47+
email:
48+
description:
49+
- The email of the contact
50+
required: false
51+
type: str
52+
address:
53+
description:
54+
- The address of the contact
55+
required: false
56+
type: str
57+
comments:
58+
description:
59+
- Comments on the contact
60+
required: false
61+
type: str
62+
contact_group:
63+
description:
64+
- Group assignment for the contact
65+
required: false
66+
type: raw
67+
tags:
68+
description:
69+
- Any tags that the contact may need to be associated with
70+
required: false
71+
type: list
72+
elements: raw
73+
custom_fields:
74+
description:
75+
- must exist in NetBox
76+
required: false
77+
type: dict
78+
required: true
79+
"""
80+
81+
EXAMPLES = r"""
82+
- name: "Test NetBox module"
83+
connection: local
84+
hosts: localhost
85+
gather_facts: False
86+
tasks:
87+
- name: Create contact within NetBox with only required information
88+
netbox_contact:
89+
netbox_url: http://netbox.local
90+
netbox_token: thisIsMyToken
91+
data:
92+
name: Contact One
93+
state: present
94+
95+
- name: Delete contact within netbox
96+
netbox_contact:
97+
netbox_url: http://netbox.local
98+
netbox_token: thisIsMyToken
99+
data:
100+
name: Contact One
101+
state: absent
102+
103+
- name: Create contact with all parameters
104+
netbox_contact:
105+
netbox_url: http://netbox.local
106+
netbox_token: thisIsMyToken
107+
data:
108+
name: contact ABC
109+
title: Mr Contact
110+
phone: 123456789
111+
email: contac@contact.com
112+
tags:
113+
- tagA
114+
- tagB
115+
- tagC
116+
state: present
117+
"""
118+
119+
RETURN = r"""
120+
contact:
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_tenancy import (
135+
NetboxTenancyModule,
136+
NB_CONTACTS,
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+
name=dict(required=True, type="str"),
153+
title=dict(required=False, type="str"),
154+
phone=dict(required=False, type="str"),
155+
email=dict(required=False, type="str"),
156+
address=dict(required=False, type="str"),
157+
comments=dict(required=False, type="str"),
158+
contact_group=dict(required=False, type="raw"),
159+
tags=dict(required=False, type="list", elements="raw"),
160+
custom_fields=dict(required=False, type="dict"),
161+
),
162+
),
163+
)
164+
)
165+
166+
required_if = [("state", "present", ["name"]), ("state", "absent", ["name"])]
167+
168+
module = NetboxAnsibleModule(
169+
argument_spec=argument_spec, supports_check_mode=True, required_if=required_if
170+
)
171+
172+
netbox_contact = NetboxTenancyModule(module, NB_CONTACTS)
173+
netbox_contact.run()
174+
175+
176+
if __name__ == "__main__": # pragma: no cover
177+
main()

0 commit comments

Comments
 (0)