Skip to content

Commit 9eef2df

Browse files
authored
Feature: Added module for FHRP group assignments (#974)
* Added fhrp_group_assignment module * Added fhrp groups creation to netbox-deploy * Added tests for fhrp_group_assignment module * Added netbox_fhrp_group_assignment to runtime.yml
1 parent de5e7c2 commit 9eef2df

File tree

11 files changed

+474
-0
lines changed

11 files changed

+474
-0
lines changed

meta/runtime.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ action_groups:
3838
- netbox_device_type
3939
- netbox_export_template
4040
- netbox_fhrp_group
41+
- netbox_fhrp_group_assignment
4142
- netbox_front_port
4243
- netbox_front_port_template
4344
- netbox_inventory_item

plugins/module_utils/netbox_ipam.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
NB_AGGREGATES = "aggregates"
2222
NB_ASNS = "asns"
2323
NB_FHRP_GROUPS = "fhrp_groups"
24+
NB_FHRP_GROUP_ASSIGNMENTS = "fhrp_group_assignments"
2425
NB_IP_ADDRESSES = "ip_addresses"
2526
NB_PREFIXES = "prefixes"
2627
NB_IPAM_ROLES = "roles"
@@ -152,6 +153,7 @@ def run(self):
152153
- aggregates
153154
- asns
154155
- fhrp_groups
156+
- fhrp_group_assignments
155157
- ipam_roles
156158
- ip_addresses
157159
- l2vpns
@@ -190,6 +192,12 @@ def run(self):
190192
name = data.get("asn")
191193
elif self.endpoint == "fhrp_groups":
192194
name = data.get("group_id")
195+
elif self.endpoint == "fhrp_group_assignments":
196+
name = "fhrp_group %s > %s %s" % (
197+
data.get("group"),
198+
data.get("interface_type"),
199+
data.get("interface_id"),
200+
)
193201
else:
194202
name = data.get("name")
195203

plugins/module_utils/netbox_utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"aggregates",
9090
"asns",
9191
"fhrp_groups",
92+
"fhrp_group_assignments",
9293
"ip_addresses",
9394
"l2vpns",
9495
"l2vpn_terminations",
@@ -133,6 +134,7 @@
133134
export_targets="name",
134135
export_template="name",
135136
fhrp_groups="group_id",
137+
fhrp_group_assignments="id",
136138
group="slug",
137139
installed_device="name",
138140
inventory_item_role="name",
@@ -317,6 +319,7 @@
317319
"device_types": "device_type",
318320
"export_templates": "export_template",
319321
"fhrp_groups": "fhrp_group",
322+
"fhrp_group_assignments": "fhrp_group_assignment",
320323
"front_ports": "front_port",
321324
"front_port_templates": "front_port_template",
322325
"journal_entries": "journal_entry",
@@ -421,6 +424,7 @@
421424
"fhrp_group": set(
422425
["id", "group_id", "interface_type", "device", "virtual_machine"]
423426
),
427+
"fhrp_group_assignment": set(["group", "interface_type", "interface_id"]),
424428
"front_port": set(["name", "device", "rear_port"]),
425429
"front_port_template": set(["name", "device_type", "rear_port"]),
426430
"installed_device": set(["name"]),
@@ -550,6 +554,7 @@
550554
"cluster_type": "type",
551555
"cluster_group": "group",
552556
"contact_group": "group",
557+
"fhrp_group": "group",
553558
"parent_contact_group": "parent",
554559
"parent_location": "parent",
555560
"parent_interface": "parent",
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
# Copyright: (c) 2023, Andrii Konts (@andrii-konts) <andrew.konts@uk2group.com>
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_fhrp_group_assignment
13+
short_description: Create, update or delete FHRP group assignments within NetBox
14+
description:
15+
- Creates, updates or removes FHRP group assignments 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+
- Andrii Konts (@andrii-konts)
21+
requirements:
22+
- pynetbox
23+
seealso:
24+
- name: FHRP Group Model reference
25+
description: NetBox Documentation for FHRP Group Model.
26+
link: https://docs.netbox.dev/en/stable/models/ipam/fhrpgroupassignment/
27+
extends_documentation_fragment:
28+
- netbox.netbox.common
29+
options:
30+
data:
31+
type: dict
32+
description:
33+
- Defines the FHRP group assignment configuration
34+
suboptions:
35+
fhrp_group:
36+
description:
37+
- FHRP Group ID
38+
required: True
39+
type: int
40+
interface_type:
41+
description:
42+
- Interface type
43+
required: True
44+
choices:
45+
- dcim.interface
46+
- virtualization.vminterface
47+
type: str
48+
interface_id:
49+
description:
50+
- Interface ID
51+
type: int
52+
required: True
53+
priority:
54+
description:
55+
- Priority (0 .. 255)
56+
type: int
57+
required: True
58+
"""
59+
60+
EXAMPLES = r"""
61+
- hosts: localhost
62+
connection: local
63+
module_defaults:
64+
group/netbox.netbox.netbox:
65+
netbox_url: "http://netbox.local"
66+
netbox_token: "thisIsMyToken"
67+
68+
tasks:
69+
- name: "Create FHRP group assignment within netbox"
70+
netbox.netbox.netbox_fhrp_group_assignment:
71+
data:
72+
fhrp_group: 3
73+
interface_type: dcim.interface
74+
interface_id: 5
75+
priority: 1
76+
state: present
77+
78+
- name: Delete FHRP group assignment within netbox
79+
netbox.netbox.netbox_fhrp_group_assignment:
80+
data:
81+
fhrp_group: 3
82+
interface_type: dcim.interface
83+
interface_id: 5
84+
state: absent
85+
86+
"""
87+
88+
RETURN = r"""
89+
fhrp_group:
90+
description: Serialized object as created or already existent within NetBox
91+
returned: success (when I(state=present))
92+
type: dict
93+
msg:
94+
description: Message indicating failure or info about what has been achieved
95+
returned: always
96+
type: str
97+
"""
98+
99+
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_utils import (
100+
NetboxAnsibleModule,
101+
NETBOX_ARG_SPEC,
102+
)
103+
from ansible_collections.netbox.netbox.plugins.module_utils.netbox_ipam import (
104+
NetboxIpamModule,
105+
NB_FHRP_GROUP_ASSIGNMENTS,
106+
)
107+
108+
from copy import deepcopy
109+
110+
111+
def main():
112+
"""
113+
Main entry point for module execution
114+
"""
115+
argument_spec = deepcopy(NETBOX_ARG_SPEC)
116+
argument_spec.update(
117+
dict(
118+
data=dict(
119+
type="dict",
120+
required=True,
121+
options=dict(
122+
fhrp_group=dict(required=True, type="int"),
123+
interface_type=dict(
124+
required=True,
125+
type="str",
126+
choices=["dcim.interface", "virtualization.vminterface"],
127+
),
128+
interface_id=dict(required=True, type="int"),
129+
priority=dict(type="int"),
130+
),
131+
),
132+
)
133+
)
134+
required_if = [("state", "present", ["priority"])]
135+
136+
module = NetboxAnsibleModule(argument_spec=argument_spec, required_if=required_if)
137+
138+
netbox_fhrp_group = NetboxIpamModule(module, NB_FHRP_GROUP_ASSIGNMENTS)
139+
netbox_fhrp_group.run()
140+
141+
142+
if __name__ == "__main__":
143+
main()

tests/integration/netbox-deploy.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,20 @@ def make_netbox_calls(endpoint, payload):
173173
]
174174
created_vlans = make_netbox_calls(nb.ipam.vlans, vlans)
175175

176+
## Create FHRP GROUPS
177+
fhrp_groups = [
178+
{
179+
"protocol": "other",
180+
"group_id": 1,
181+
"description": "Test FHRP Group 1",
182+
},
183+
{
184+
"protocol": "glbp",
185+
"group_id": 2,
186+
"description": "Test FHRP Group 2",
187+
},
188+
]
189+
created_fhrp_groups = make_netbox_calls(nb.ipam.fhrp_groups, fhrp_groups)
176190

177191
## Create IPAM Roles
178192
ipam_roles = [{"name": "Network of care", "slug": "network-of-care"}]

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,12 @@
241241

242242
- name: "NETBOX_FHRP_GROUP TESTS"
243243
include_tasks: "netbox_fhrp_group.yml"
244+
245+
- name: "NETBOX_FHRP_GROUP_ASSIGNMENT TESTS"
246+
include_tasks:
247+
file: "netbox_fhrp_group_assignment.yml"
248+
apply:
249+
tags:
250+
- netbox_fhrp_group_assignmen
251+
tags:
252+
- netbox_fhrp_group_assignmen
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
##
3+
##
4+
### NETBOX_FHRP_GROUP_ASSIGNMENT
5+
##
6+
##
7+
- name: "FHRP group assignment 1: Test FHRP group assignment creation"
8+
netbox.netbox.netbox_fhrp_group_assignment:
9+
netbox_url: http://localhost:32768
10+
netbox_token: 0123456789abcdef0123456789abcdef01234567
11+
data:
12+
fhrp_group: 1
13+
interface_type: dcim.interface
14+
interface_id: 1
15+
priority: 1
16+
state: present
17+
register: test_one
18+
19+
- name: "FHRP group assignment: ASSERT - Necessary info creation"
20+
ansible.builtin.assert:
21+
that:
22+
- test_one is changed
23+
- test_one['diff']['before']['state'] == "absent"
24+
- test_one['diff']['after']['state'] == "present"
25+
- test_one['fhrp_group_assignment']['group'] == 1
26+
- test_one['fhrp_group_assignment']['interface_type'] == "dcim.interface"
27+
- test_one['fhrp_group_assignment']['interface_id'] == 1
28+
- test_one['fhrp_group_assignment']['priority'] == 1
29+
- test_one['msg'] == "fhrp_group_assignment fhrp_group 1 > dcim.interface 1 created"
30+
31+
- name: "FHRP group assignment 2: Create duplicate"
32+
netbox.netbox.netbox_fhrp_group_assignment:
33+
netbox_url: http://localhost:32768
34+
netbox_token: 0123456789abcdef0123456789abcdef01234567
35+
data:
36+
fhrp_group: 1
37+
interface_type: dcim.interface
38+
interface_id: 1
39+
priority: 1
40+
state: present
41+
register: test_two
42+
43+
- name: "FHRP group assignment 2: ASSERT - Create duplicate"
44+
ansible.builtin.assert:
45+
that:
46+
- not test_two['changed']
47+
- test_two['fhrp_group_assignment']['group'] == 1
48+
- test_two['fhrp_group_assignment']['interface_type'] == "dcim.interface"
49+
- test_two['fhrp_group_assignment']['interface_id'] == 1
50+
- test_two['fhrp_group_assignment']['priority'] == 1
51+
- test_two['msg'] == "fhrp_group_assignment fhrp_group 1 > dcim.interface 1 already exists"
52+
53+
- name: "FHRP group assignment 3: Update FHRP group assignment"
54+
netbox.netbox.netbox_fhrp_group_assignment:
55+
netbox_url: http://localhost:32768
56+
netbox_token: 0123456789abcdef0123456789abcdef01234567
57+
data:
58+
fhrp_group: 1
59+
interface_type: dcim.interface
60+
interface_id: 1
61+
priority: 2
62+
state: present
63+
register: test_three
64+
65+
- name: "FHRP group assignment 3: ASSERT - Update FHRP group assignment"
66+
ansible.builtin.assert:
67+
that:
68+
- test_three is changed
69+
- test_three['fhrp_group_assignment']['group'] == 1
70+
- test_three['fhrp_group_assignment']['interface_type'] == "dcim.interface"
71+
- test_three['fhrp_group_assignment']['interface_id'] == 1
72+
- test_three['fhrp_group_assignment']['priority'] == 2
73+
- test_three['msg'] == "fhrp_group_assignment fhrp_group 1 > dcim.interface 1 updated"
74+
75+
- name: "FHRP group assignment 4: Delete FHRP group assignment"
76+
netbox.netbox.netbox_fhrp_group_assignment:
77+
netbox_url: http://localhost:32768
78+
netbox_token: 0123456789abcdef0123456789abcdef01234567
79+
data:
80+
fhrp_group: 1
81+
interface_type: dcim.interface
82+
interface_id: 1
83+
state: absent
84+
register: test_four
85+
86+
- name: "FHRP group assignment 3: ASSERT - Delete FHRP group assignment"
87+
ansible.builtin.assert:
88+
that:
89+
- test_four is changed
90+
- test_four['diff']['before']['state'] == "present"
91+
- test_four['diff']['after']['state'] == "absent"
92+
- test_four['msg'] == "fhrp_group_assignment fhrp_group 1 > dcim.interface 1 deleted"

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,12 @@
270270

271271
- name: "NETBOX_FHRP_GROUP TESTS"
272272
include_tasks: "netbox_fhrp_group.yml"
273+
274+
- name: "NETBOX_FHRP_GROUP_ASSIGNMENT TESTS"
275+
include_tasks:
276+
file: "netbox_fhrp_group_assignment.yml"
277+
apply:
278+
tags:
279+
- netbox_fhrp_group_assignmen
280+
tags:
281+
- netbox_fhrp_group_assignmen

0 commit comments

Comments
 (0)