Skip to content

Commit 1980f50

Browse files
authored
Netbox service (#70)
1 parent 6955406 commit 1980f50

File tree

5 files changed

+277
-0
lines changed

5 files changed

+277
-0
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,4 +271,5 @@ Copying an existing module that has close to the same options is typically the p
271271
272272
- Please add or update an existing play to test the new Netbox module for integration testing within `tests/integration/integration-tests.yml`. Make sure to test creation, duplicate, update (if possible), and deletion along with any other conditions that may want to be tested.
273273
- Run `black .` within the base directory for black formatting as it's required for tests to pass
274+
- Run `ansible-lint integration-tests.yml` it's required for tests to pass
274275
- Check necessary dependencies defined within `.travis.yml` for now if you're wanting to test locally

plugins/module_utils/netbox_ipam.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
NB_VLANS = "vlans"
3333
NB_VLAN_GROUPS = "vlan_groups"
3434
NB_VRFS = "vrfs"
35+
NB_SERVICES = "services"
3536

3637

3738
class NetboxIpamModule(NetboxModule):

plugins/module_utils/netbox_utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"vlans",
5454
"vlan_groups",
5555
"vrfs",
56+
"services",
5657
],
5758
secrets=[],
5859
tenancy=["tenants", "tenant_groups"],
@@ -392,6 +393,7 @@
392393
"vlan_groups",
393394
}
394395

396+
395397
NETBOX_ARG_SPEC = dict(
396398
netbox_url=dict(type="str", required=True),
397399
netbox_token=dict(type="str", required=True, no_log=True),

plugins/modules/netbox_service.py

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
# Copyright: (c) 2019, Kulakov Ilya (@TawR1024)
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+
ANSIBLE_METADATA = {
11+
"metadata_version": "1.1",
12+
"status": ["preview"],
13+
"supported_by": "community",
14+
}
15+
16+
DOCUMENTATION = r"""
17+
---
18+
module: netbox_service
19+
short_description: Creates or removes service from Netbox
20+
description:
21+
- Creates or removes service from Netbox
22+
notes:
23+
- This should be ran with connection C(local) and hosts C(localhost)
24+
author:
25+
- Kulakov Ilya (@TawR1024)
26+
requirements:
27+
- pynetbox
28+
version_added: '0.1.5'
29+
options:
30+
netbox_url:
31+
description:
32+
- URL of the Netbox instance resolvable by Ansible control host
33+
required: true
34+
type: str
35+
netbox_token:
36+
description:
37+
- The token created within Netbox to authorize API access
38+
required: true
39+
type: str
40+
data:
41+
description:
42+
- Defines the service configuration
43+
suboptions:
44+
device:
45+
description:
46+
- Specifies on which device the service is running
47+
type: raw
48+
virtual_machine:
49+
description:
50+
type: raw
51+
port:
52+
description:
53+
- Specifies which port used by service
54+
type: int
55+
protocol:
56+
description:
57+
- Specifies which protocol used by service
58+
type: int
59+
choices:
60+
- 6 TCP
61+
- 17 UDP
62+
ipaddress:
63+
description:
64+
- VRF that prefix is associated with
65+
type: str
66+
description:
67+
description:
68+
- Service description
69+
type: str
70+
custom_fields:
71+
description:
72+
- Must exist in Netbox and in key/value format
73+
type: dict
74+
required: true
75+
state:
76+
description:
77+
- Use C(present) or C(absent) for adding or removing.
78+
choices: [ absent, present ]
79+
default: present
80+
validate_certs:
81+
description:
82+
- If C(no), SSL certificates will not be validated. This should only be used on personally controlled sites using self-signed certificates.
83+
default: "yes"
84+
type: bool
85+
"""
86+
87+
EXAMPLES = r"""
88+
- name: "Create netbox service"
89+
connection: local
90+
hosts: all
91+
gather_facts: False
92+
93+
tasks:
94+
- name: Create service
95+
netbox_service:
96+
netbox_url: netbox_url
97+
netbox_token: netbox_token
98+
data:
99+
device: Test666
100+
name: node-exporter
101+
port: 9100
102+
protocol: 6
103+
state: present
104+
105+
- name: "Delete netbox service"
106+
connection: local
107+
hosts: all
108+
gather_facts: False
109+
110+
tasks:
111+
- name: Delete service
112+
netbox_service:
113+
netbox_url: netbox_url
114+
netbox_token: netbox_token
115+
data:
116+
device: Test666
117+
name: node-exporter
118+
port: 9100
119+
protocol: 6
120+
state: absent
121+
"""
122+
123+
from ansible_collections.netbox_community.ansible_modules.plugins.module_utils.netbox_utils import (
124+
NetboxAnsibleModule,
125+
NETBOX_ARG_SPEC,
126+
)
127+
from ansible_collections.netbox_community.ansible_modules.plugins.module_utils.netbox_ipam import (
128+
NetboxIpamModule,
129+
NB_SERVICES,
130+
)
131+
132+
133+
def main():
134+
"""
135+
Main entry point for module execution
136+
"""
137+
argument_spec = NETBOX_ARG_SPEC
138+
argument_spec.update(
139+
dict(
140+
data=dict(
141+
type="dict",
142+
required=True,
143+
options=dict(
144+
device=dict(required=True, type="raw"),
145+
virtual_machine=dict(required=False, type="raw"),
146+
name=dict(required=True, type="str"),
147+
port=dict(required=True, type="int"),
148+
protocol=dict(required=True, type="raw"),
149+
ipaddresses=dict(required=False, type="raw"),
150+
description=dict(required=False, type="str"),
151+
custom_fields=dict(required=False, type=dict),
152+
),
153+
),
154+
)
155+
)
156+
157+
required_if = [("state", "present", ["name"]), ("state", "absent", ["name"])]
158+
159+
module = NetboxAnsibleModule(
160+
argument_spec=argument_spec, supports_check_mode=True, required_if=required_if
161+
)
162+
163+
netbox_service = NetboxIpamModule(module, NB_SERVICES)
164+
netbox_service.run()
165+
166+
167+
if __name__ == "__main__":
168+
main()

tests/integration/integration-tests.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4079,6 +4079,108 @@
40794079
- test_five['circuit_termination']['pp_info'] == "PP10-24"
40804080
- test_five['circuit_termination']['description'] == "Test description"
40814081
- test_five['msg'] == "circuit_termination test_circuit_a deleted"
4082+
-
4083+
4084+
##
4085+
##
4086+
### NETBOX_SERVICE
4087+
##
4088+
##
4089+
- name: "1 - Device with required information needs to add new service"
4090+
netbox_device:
4091+
netbox_url: "http://localhost:32768"
4092+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
4093+
data:
4094+
name: "FOR_SERVICE"
4095+
device_type: "Cisco Test"
4096+
device_role: "Core Switch"
4097+
site: "Test Site"
4098+
status: "Staged"
4099+
state: present
4100+
4101+
- name: "NETBOX_SERVICE: Create new service"
4102+
netbox_service:
4103+
netbox_url: "http://localhost:32768"
4104+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
4105+
data:
4106+
device: "FOR_SERVICE"
4107+
name: "node-exporter"
4108+
port: 9100
4109+
protocol: TCP
4110+
state: present
4111+
register: test_service_create
4112+
4113+
- name: "NETBOX_SERVICE ASSERT - Create"
4114+
assert:
4115+
that:
4116+
- test_service_create is changed
4117+
- test_service_create['services']['name'] == "node-exporter"
4118+
- test_service_create['services']['port'] == 9100
4119+
- test_service_create['services']['protocol'] == 6
4120+
- test_service_create['diff']['after']['state'] == "present"
4121+
- test_service_create['diff']['before']['state'] == "absent"
4122+
- test_service_create['msg'] == "services node-exporter created"
4123+
4124+
- name: "NETBOX_SERVICE: Test idempotence"
4125+
netbox_service:
4126+
netbox_url: "http://localhost:32768"
4127+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
4128+
data:
4129+
device: "FOR_SERVICE"
4130+
name: "node-exporter"
4131+
port: 9100
4132+
protocol: TCP
4133+
state: present
4134+
register: test_service_idempotence
4135+
4136+
- name: "NETBOX_SERVICE ASSERT - Not changed"
4137+
assert:
4138+
that:
4139+
- test_service_idempotence['services']['name'] == "node-exporter"
4140+
- test_service_idempotence['services']['port'] == 9100
4141+
- test_service_idempotence['services']['protocol'] == 6
4142+
- test_service_idempotence['msg'] == "services node-exporter already exists"
4143+
- name: "NETBOX_SERVICE: Test update"
4144+
netbox_service:
4145+
netbox_url: "http://localhost:32768"
4146+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
4147+
data:
4148+
device: "FOR_SERVICE"
4149+
name: "node-exporter"
4150+
port: 9100
4151+
protocol: UDP
4152+
state: present
4153+
register: test_service_update
4154+
4155+
- name: "NETBOX_SERVICE ASSERT - Service has been updated"
4156+
assert:
4157+
that:
4158+
- test_service_update is changed
4159+
- test_service_update['diff']['before']['protocol'] == 6
4160+
- test_service_update['diff']['after']['protocol'] == 17
4161+
- test_service_update['msg'] == "services node-exporter updated"
4162+
4163+
4164+
- name: "NETBOX_SERVICE: Test service deletion"
4165+
netbox_service:
4166+
netbox_url: "http://localhost:32768"
4167+
netbox_token: "0123456789abcdef0123456789abcdef01234567"
4168+
data:
4169+
device: "FOR_SERVICE"
4170+
name: "node-exporter"
4171+
port: 9100
4172+
protocol: UDP
4173+
state: absent
4174+
register: test_service_delete
4175+
4176+
- name: "NETBOX_SERVICE ASSERT - Service has been deleted"
4177+
assert:
4178+
that:
4179+
- test_service_delete is changed
4180+
- test_service_delete['diff']['after']['state'] == "absent"
4181+
- test_service_delete['diff']['before']['state'] == "present"
4182+
- test_service_delete['msg'] == "services node-exporter deleted"
4183+
40824184

40834185
##
40844186
##
@@ -4148,3 +4250,6 @@
41484250
that: "{{ query_result|json_query('[?value.display_name==`L2`]')|count }} == 1"
41494251
vars:
41504252
query_result: "{{ query('netbox_community.ansible_modules.netbox', 'devices', api_filter='role=core-switch tag=lookup', api_endpoint='http://localhost:32768', token='0123456789abcdef0123456789abcdef01234567') }}"
4253+
4254+
4255+

0 commit comments

Comments
 (0)