Skip to content

Commit 670cb0c

Browse files
committed
Fix same subnet in different sections bug (#33)
The lookup for subnets now respect the provided section. Now a subnet can be used in different sections. To test more complex situations we refactored the test data and test scripts to be more common for all test cases. The condition in the `run` method for deleting children has not workded properly. We fix these condition to use the correct method to resolve parent. Add changelog fragment.
1 parent 3b3a4e4 commit 670cb0c

File tree

8 files changed

+128
-48
lines changed

8 files changed

+128
-48
lines changed

plugins/module_utils/phpipam_helper.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,23 +127,25 @@ def find_entity(self, controller, path, params=None):
127127
return None
128128

129129
if type(result) == list:
130-
if len(result) == 1:
131-
result = result[0]
130+
if len(result) >= 1:
131+
result = result
132132
else:
133-
if len(result) > 1:
134-
error_msg = "too many ({0})".format(len(result))
135-
else:
136-
error_msg = "no"
137-
self.fail_json(msg="Found {0} results while searching for {1} at {2}".format(error_msg, controller, path))
133+
self.fail_json(msg="Found no results while searching for {0} at {1}".format(controller, path))
138134

139135
return result
140136

141-
def find_subnet(self, subnet, mask):
137+
def find_subnet(self, subnet, mask, section):
142138
# lookups for subnets need a separate find method
143139
# We only support cidr format to simplify the task.
144140
# CIDR is valid for ipv4 and ipv6 too.
145141
path = 'cidr/{0}/{1}'.format(subnet, mask)
146-
return self.find_entity('subnets', path)
142+
143+
lookup_params = {
144+
'filter_by': 'section',
145+
'filter_value': section,
146+
}
147+
148+
return self.find_entity('subnets', path, params=lookup_params)
147149

148150
def find_address(self, address):
149151
path = 'search/{0}'.format(address)
@@ -181,7 +183,7 @@ def find_by_key(self, controller, value, key='name'):
181183

182184
def find_current_entity(self):
183185
if self.controller_name == 'subnet':
184-
entity = self.find_subnet(self.phpipam_params['subnet'], self.phpipam_params['mask'])
186+
entity = self.find_subnet(self.phpipam_params['subnet'], self.phpipam_params['mask'], self.phpipam_params['section'])
185187
elif self.controller_name == 'address':
186188
entity = self.find_address(self.phpipam_params['ipaddress'])
187189
elif self.controller_name == 'device':
@@ -209,7 +211,7 @@ def _resolve_entity(self, key):
209211
result = None
210212
if controller == 'subnets':
211213
subnet, mask = self.phpipam_params[key].split('/')
212-
result = self.find_subnet(subnet, mask)
214+
result = self.find_subnet(subnet, mask, self.phpipam_params['section'])
213215
elif controller == 'tools/device_types':
214216
result = self.find_device_type(self.phpipam_params[key])
215217
elif 'tools' in controller or controller in ['vlan', 'l2domains', 'vrf']:
@@ -507,7 +509,7 @@ def run(self, **kwargs):
507509
Manage entities. Lookup, ensure, sanitize and manage parameters.
508510
"""
509511
if ('parent' in self.phpipam_spec and self.phpipam_spec['parent'].get('type') == 'entity'
510-
and self.desired_absent and 'parent' in self.phpipam_params and self.loopup_entity('parent') is None):
512+
and self.desired_absent and 'parent' in self.phpipam_params and self._resolve_entity('parent') is None):
511513
return None
512514

513515
desired_entity = self._auto_resolve_entities()
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
- hosts: localhost
3+
collections:
4+
- codeaffen.phpipam
5+
gather_facts: false
6+
vars_files:
7+
- vars/server.yml
8+
- vars/section.yml
9+
- vars/subnet.yml
10+
tasks:
11+
- name: setup data
12+
block:
13+
- name: create sections
14+
include: tasks/section.yml
15+
vars:
16+
name: "{{ section.name }}"
17+
loop: "{{ sections }}"
18+
loop_control:
19+
loop_var: section
20+
21+
- name: create subnets
22+
include: tasks/subnet.yml
23+
vars:
24+
name: "{{ subnet.cidr }}"
25+
loop: "{{ subnets }}"
26+
loop_control:
27+
loop_var: subnet
28+
when: cleanup is not defined
29+
30+
- name: cleanup data
31+
block:
32+
- name: remove subnets
33+
include: tasks/subnet.yml
34+
vars:
35+
name: "{{ subnet_loop.cidr }}"
36+
override:
37+
state: absent
38+
subnet: "{{ subnet_loop | combine(override) }}"
39+
loop: "{{ subnets | reverse | list }}"
40+
loop_control:
41+
loop_var: subnet_loop
42+
43+
- name: remove sections
44+
include: tasks/section.yml
45+
vars:
46+
name: "{{ section_loop.name }}"
47+
override:
48+
state: absent
49+
section: "{{ section_loop | combine(override) }}"
50+
loop: "{{ sections | reverse | list }}"
51+
loop_control:
52+
loop_var: section_loop
53+
when: cleanup is defined

tests/test_playbooks/section.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,26 @@
1111
include: tasks/section.yml
1212
vars:
1313
name: create section
14+
section: "{{ base_section_data }}"
1415

1516
- name: create section again, no change
1617
include: tasks/section.yml
1718
vars:
1819
name: create section again, no change
20+
section: "{{ base_section_data }}"
1921

2022
- name: update section
2123
include: tasks/section.yml
2224
vars:
2325
name: update section
24-
section_description: section updated
26+
override:
27+
description: section updated
28+
section: "{{ base_section_data | combine(override) }}"
2529

2630
- name: delete section
2731
include: tasks/section.yml
2832
vars:
2933
name: delete section
30-
section_state: absent
34+
override:
35+
state: absent
36+
section: "{{ base_section_data | combine(override) }}"

tests/test_playbooks/subnet.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@
1111
include: tasks/subnet.yml
1212
vars:
1313
name: create subnet
14+
subnet: "{{ base_subnet_data }}"
1415

1516
- name: create subnet again, no change
1617
include: tasks/subnet.yml
1718
vars:
1819
name: create subnet again, no change
20+
subnet: "{{ base_subnet_data }}"
1921

2022
- name: delete subnet
2123
include: tasks/subnet.yml
2224
vars:
2325
name: delete subnet
24-
subnet_state: absent
26+
override:
27+
state: absent
28+
subnet: "{{ base_subnet_data | combine(override) }}"

tests/test_playbooks/tasks/section.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
username: "{{ phpipam_username }}"
77
password: "{{ phpipam_password }}"
88
name: "{{ section.name }}"
9-
description: "{{ section_description | default(omit) }}"
10-
parent: "{{ section_parent | default(omit) }}"
11-
permissions: "{{ section_permissions | default(omit) }}"
12-
strict_mode: "{{ section_strict_mode | default(omit) }}"
13-
subnet_ordering: "{{ section_subnet_ordering | default(omit) }}"
14-
list_order: "{{ section_list_order | default(omit) }}"
15-
show_vlan: "{{ section_show_vlan | default(omit) }}"
16-
show_vrf: "{{ section_show_vrf | default(omit) }}"
17-
show_supernets_only: "{{ section_show_supernets_only | default(omit) }}"
18-
dns_resolver: "{{ section_dns_resolver | default(omit) }}"
19-
validate_certs: "{{ section_validate_certs | default('no') }}"
20-
state: "{{ section_state | default('present') }}"
9+
description: "{{ section.description | default(omit) }}"
10+
parent: "{{ section.parent | default(omit) }}"
11+
permissions: "{{ section.permissions | default(omit) }}"
12+
strict_mode: "{{ section.strict_mode | default(omit) }}"
13+
subnet_ordering: "{{ section.subnet_ordering | default(omit) }}"
14+
list_order: "{{ section.list_order | default(omit) }}"
15+
show_vlan: "{{ section.show_vlan | default(omit) }}"
16+
show_vrf: "{{ section.show_vrf | default(omit) }}"
17+
show_supernets_only: "{{ section.show_supernets_only | default(omit) }}"
18+
dns_resolver: "{{ section.dns_resolver | default(omit) }}"
19+
validate_certs: "{{ section.validate_certs | default('no') }}"
20+
state: "{{ section.state | default('present') }}"

tests/test_playbooks/tasks/subnet.yml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@
1010
mask: "{{ subnet.mask | default(omit) }}"
1111
description: "{{ subnet.description | default(omit) }}"
1212
section: "{{ subnet.section | default(omit) }}"
13-
linked_subnet: "{{ subnet_linked_subnet | default(omit) }}"
14-
vlan_id: "{{ subnet_vlan_id | default(omit) }}"
15-
vrf_id: "{{ subnet_vrf_id | default(omit) }}"
16-
master_subnet_cidr: "{{ subnet_master_subnet_cidr | default(omit) }}"
17-
nameserver: "{{ subnet_nameserver | default(omit) }}"
18-
show_as_name: "{{ subnet_show_as_name | default(omit) }}"
19-
permissions: "{{ subnet_permissions | default(omit) }}"
20-
dns_recursive: "{{ subnet_dns_recursive | default(omit) }}"
21-
dns_records: "{{ subnet_dns_records | default(omit) }}"
22-
allow_requests: "{{ subnet_allow_requests | default(omit) }}"
23-
scan_agent: "{{ subnet_scan_agent | default(omit) }}"
24-
ping_subnet: "{{ subnet_ping_subnet | default(omit) }}"
25-
discover_subnet: "{{ subnet_discover_subnet | default(omit) }}"
26-
is_folder: "{{ subnet_is_folder | default(omit) }}"
27-
is_full: "{{ subnet_is_full | default(omit) }}"
28-
subnet_state: "{{ subnet_subnet_state | default(omit) }}"
29-
threshold: "{{ subnet_threshold | default(omit) }}"
30-
location: "{{ subnet_location | default(omit) }}"
31-
state: "{{ subnet_state | default('present') }}"
13+
linked_subnet: "{{ subnet.linked_subnet | default(omit) }}"
14+
vlan_id: "{{ subnet.vlan_id | default(omit) }}"
15+
vrf_id: "{{ subnet.vrf_id | default(omit) }}"
16+
master_subnet.cidr: "{{ subnet.master_subnet.cidr | default(omit) }}"
17+
nameserver: "{{ subnet.nameserver | default(omit) }}"
18+
show_as_name: "{{ subnet.show_as_name | default(omit) }}"
19+
permissions: "{{ subnet.permissions | default(omit) }}"
20+
dns_recursive: "{{ subnet.dns_recursive | default(omit) }}"
21+
dns_records: "{{ subnet.dns_records | default(omit) }}"
22+
allow_requests: "{{ subnet.allow_requests | default(omit) }}"
23+
scan_agent: "{{ subnet.scan_agent | default(omit) }}"
24+
ping_subnet: "{{ subnet.ping_subnet | default(omit) }}"
25+
discover_subnet: "{{ subnet.discover_subnet | default(omit) }}"
26+
is_folder: "{{ subnet.is_folder | default(omit) }}"
27+
is_full: "{{ subnet.is_full | default(omit) }}"
28+
subnet.state: "{{ subnet.subnet.state | default(omit) }}"
29+
threshold: "{{ subnet.threshold | default(omit) }}"
30+
location: "{{ subnet.location | default(omit) }}"
31+
state: "{{ subnet.state | default('present') }}"
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
---
2-
section:
2+
base_section_data:
33
name: "Example Inc."
4+
5+
sections:
6+
- name: "ACME Inc."
7+
- name: "DevOps Department"
8+
parent: "ACME Inc."
9+
- name: "Infrastructure Department"
10+
parent: "ACME Inc."
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
---
2-
subnet:
2+
base_subnet_data:
33
cidr: 10.0.0.0/24
44
section: "Customers"
5+
6+
subnets:
7+
- cidr: 192.0.2.0/24
8+
section: "ACME Inc."
9+
- cidr: 192.0.2.0/25
10+
section: "DevOps Department"
11+
- cidr: 192.0.2.0/25
12+
section: "Infrastructure Department"

0 commit comments

Comments
 (0)