Skip to content

Commit 3398d82

Browse files
authored
Merge pull request #35 from cmeissner/issue/33
Add possibility to manage same subnet in different sections
2 parents 3023118 + d0c0a8d commit 3398d82

File tree

10 files changed

+130
-46
lines changed

10 files changed

+130
-46
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bugfixes:
2+
- Fixing `Creating same subnet in different sections isn't possible` bug (https://github.com/codeaffen/phpipam-ansible-modules/issues/33)

plugins/module_utils/phpipam_helper.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,20 +130,22 @@ def find_entity(self, controller, path, params=None):
130130
if len(result) == 1:
131131
result = result[0]
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': 'sectionId',
145+
'filter_value': self.find_entity('sections', section)['id'],
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':
@@ -206,9 +208,10 @@ def _resolve_entity(self, key):
206208

207209
controller = entity_spec['controller'] or self.controller_uri
208210

211+
result = None
209212
if controller == 'subnets':
210213
subnet, mask = self.phpipam_params[key].split('/')
211-
result = self.find_subnet(subnet, mask)
214+
result = self.find_subnet(subnet, mask, self.phpipam_params['section'])
212215
elif controller == 'tools/device_types':
213216
result = self.find_device_type(self.phpipam_params[key])
214217
elif 'tools' in controller or controller in ['vlan', 'l2domains', 'vrf']:
@@ -496,7 +499,7 @@ def run(self, **kwargs):
496499
Manage entities. Lookup, ensure, sanitize and manage parameters.
497500
"""
498501
if ('parent' in self.phpipam_spec and self.phpipam_spec['parent'].get('type') == 'entity'
499-
and self.desired_absent and 'parent' in self.phpipam_params and self.loopup_entity('parent') is None):
502+
and self.desired_absent and 'parent' in self.phpipam_params and self._resolve_entity('parent') is None):
500503
return None
501504

502505
desired_entity = self._auto_resolve_entities()

plugins/modules/subnet.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ def main():
231231
if '/' not in module_params['cidr']:
232232
module.fail_json(msg='missing prefix lenght in "cidr". Need <ipaddr>/<prefix_lenght>.')
233233
else:
234+
IPNetwork = None
234235
if '.' in module_params['cidr'] and ':' not in module_params['cidr']:
235236
IPNetwork = ipaddress.IPv4Network
236237
module_params['mask'] = str(IPNetwork(u'%s' % (module_params['cidr'])).prefixlen)
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)