Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement checking for nested alias content #141

Open
wants to merge 1 commit into
base: latest
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 45 additions & 20 deletions plugins/module_utils/helper/alias.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,38 @@
from re import match as regex_match
from typing import Callable
from ipaddress import ip_network, ip_address

from ansible.module_utils.basic import AnsibleModule

from ansible_collections.ansibleguy.opnsense.plugins.module_utils.defaults.main import \
BUILTIN_ALIASES, BUILTIN_INTERFACE_ALIASES_REG
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.helper.validate import \
is_valid_mac_address, is_valid_url
is_valid_mac_address, is_valid_url, is_valid_domain
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.helper.main import \
get_selected


def validate_values(cnf: dict, error_func: Callable) -> None:
def validate_values(cnf: dict, error_func: Callable, existing_entries: dict) -> None:
v_type = cnf['type']

if isinstance(existing_entries, dict):
existing_entries = {
a['name']: get_selected(a['type'])
for a in existing_entries.values()
}
else:
existing_entries = {
a['name']: a['type']
for a in existing_entries
}

for value in cnf['content']:
error = f"Value '{value}' is invalid for type '{v_type}'!"

if v_type == 'port':
if value in existing_entries and existing_entries[value] == 'port':
continue

if str(value).find(':') != -1:
to_check = value.split(':')

Expand All @@ -39,24 +56,32 @@ def validate_values(cnf: dict, error_func: Callable) -> None:
if not is_valid_url(value):
error_func(error)

# unable to check because of alias-nesting support
# if v_type == 'network':
# value = value[1:] if value.startswith('!') else value
#
# try:
# ip_network(value)
#
# except ValueError:
# error_func(error)

# unable to check because of alias-nesting support and ip-ranges
# if v_type == 'host':
# try:
# ip_address(value)
#
# except ValueError:
# if not is_valid_domain(value):
# error_func(error)
elif v_type == 'network':
if value in existing_entries and existing_entries[value] in ['network', 'host']:
continue

value = value[1:] if value.startswith('!') else value

try:
ip_network(value)

except ValueError:
error_func(error)

elif v_type == 'host':
if value in existing_entries and existing_entries[value] in ['network', 'host']:
continue

if is_valid_domain(value):
continue

for _value in value.split('-', 1):
_value = _value[1:] if _value.startswith('!') else _value
try:
ip_address(_value)

except ValueError:
error_func(error)


def check_purge_filter(module: AnsibleModule, existing_rule: dict) -> bool:
Expand Down
6 changes: 3 additions & 3 deletions plugins/module_utils/main/alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ def check(self) -> None:
f"must be shorter than {self.MAX_ALIAS_LEN} characters",
)

if self.p['state'] == 'present':
validate_values(error_func=self._error, cnf=self.p)

self.b.find(match_fields=[self.FIELD_ID])

if self.p['state'] == 'present':
validate_values(error_func=self._error, cnf=self.p, existing_entries=self.existing_entries)

if self.p['state'] == 'present':
self.r['diff']['after'] = self.b.build_diff(data=self.p)

Expand Down
85 changes: 64 additions & 21 deletions tests/alias.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,30 @@
name: 'ANSIBLE_TEST_1_2_HOST3'
type: 'host'
content: ['ANSIBLE_TEST_1_2_HOST2', 'ANSIBLE_TEST_1_2_HOST1']
register: opnhost2
failed_when: opnhost2.failed != ansible_check_mode

- name: Adding ip range
ansibleguy.opnsense.alias:
name: 'ANSIBLE_TEST_1_2_HOST4'
type: 'host'
content: '1.1.1.1-1.1.1.4'

# NOTE: cannot fail as validation was disabled because of alias-nesting and ip-range support
# - name: Adding invalid host
# ansibleguy.opnsense.alias:
# name: 'ANSIBLE_TEST_1_2_HOST3'
# type: 'host'
# content: "{{ item }}"
# register: opnhost1
# failed_when: not opnhost1.failed
# loop:
# - ['1.1.1.n']
- name: Adding exclusion
ansibleguy.opnsense.alias:
name: 'ANSIBLE_TEST_1_2_HOST5'
type: 'host'
content: '!1.1.1.1'

- name: Adding invalid host
ansibleguy.opnsense.alias:
name: 'ANSIBLE_TEST_1_2_HOST3'
type: 'host'
content: "{{ item }}"
register: opnhost1
failed_when: not opnhost1.failed
loop:
- ['1.1.1.n']

# networks

Expand All @@ -170,16 +177,23 @@
type: 'network'
content: ['192.168.0.0/24', '192.168.1.0/24']

# NOTE: cannot fail as validation was disabled because of alias-nesting support
# - name: Adding invalid network
# ansibleguy.opnsense.alias:
# name: 'ANSIBLE_TEST_1_2_NET3'
# type: 'network'
# content: "{{ item }}"
# register: opnnet1
# failed_when: not opnnet1.failed
# loop:
# - ['192.168.0.0/240']
- name: Adding invalid network
ansibleguy.opnsense.alias:
name: 'ANSIBLE_TEST_1_2_NET3'
type: 'network'
content: "{{ item }}"
register: opnnet1
failed_when: not opnnet1.failed
loop:
- ['192.168.0.0/240']

- name: Adding nested network
ansibleguy.opnsense.alias:
name: 'ANSIBLE_TEST_1_2_NET3'
type: 'network'
content: ['ANSIBLE_TEST_1_2_NET1', 'ANSIBLE_TEST_1_2_NET2']
register: opnnet2
failed_when: opnnet2.failed != ansible_check_mode

# ports

Expand Down Expand Up @@ -211,6 +225,30 @@
type: 'port'
content: '9000:9500'

- name: Adding nested ports
ansibleguy.opnsense.alias:
name: 'ANSIBLE_TEST_1_2_PORT5'
type: 'port'
content:
- 'ANSIBLE_TEST_1_2_PORT1'
- 'ANSIBLE_TEST_1_2_PORT2'
register: opnport2
failed_when: opnport2.failed != ansible_check_mode

# mac

- name: Adding mac
ansibleguy.opnsense.alias:
name: 'ANSIBLE_TEST_1_2_MAC1'
type: 'mac'
content: f4:90:ea:00:00:01

- name: Adding multiple macs
ansibleguy.opnsense.alias:
name: 'ANSIBLE_TEST_1_2_MAC2'
type: 'mac'
content: ['f4:90:ea:00:00:01', 'f4:90:ea:00:00:02']

# urls

- name: Adding url
Expand Down Expand Up @@ -336,13 +374,18 @@
- 'ANSIBLE_TEST_1_2_URL1'
- 'ANSIBLE_TEST_1_2_URL2'
- 'ANSIBLE_TEST_1_2_URL3'
- 'ANSIBLE_TEST_1_2_PORT5'
- 'ANSIBLE_TEST_1_2_PORT1'
- 'ANSIBLE_TEST_1_2_PORT2'
- 'ANSIBLE_TEST_1_2_PORT3'
- 'ANSIBLE_TEST_1_2_PORT4'
- 'ANSIBLE_TEST_1_2_MAC1'
- 'ANSIBLE_TEST_1_2_MAC2'
- 'ANSIBLE_TEST_1_2_NET3'
- 'ANSIBLE_TEST_1_2_NET1'
- 'ANSIBLE_TEST_1_2_NET2'
- 'ANSIBLE_TEST_1_2_NET3'
- 'ANSIBLE_TEST_1_2_NET4'
- 'ANSIBLE_TEST_1_2_HOST5'
- 'ANSIBLE_TEST_1_2_HOST4'
- 'ANSIBLE_TEST_1_2_HOST3'
- 'ANSIBLE_TEST_1_2_HOST2'
Expand Down
40 changes: 39 additions & 1 deletion tests/alias_multi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
ANSIBLE_TEST_2_8:
ANSIBLE_TEST_2_9:
ANSIBLE_TEST_2_10:
ANSIBLE_TEST_2_11:
ANSIBLE_TEST_2_12:
ANSIBLE_TEST_2_13:
ANSIBLE_TEST_2_14:
state: 'absent'
register: opn1
failed_when: >
Expand Down Expand Up @@ -157,12 +161,46 @@
opn6.changed
when: not ansible_check_mode

- name: Adding nested aliases
ansibleguy.opnsense.alias_multi:
aliases:
# hosts
ANSIBLE_TEST_2_12:
content: ['ANSIBLE_TEST_2_1', 'ANSIBLE_TEST_2_2']

# networks
ANSIBLE_TEST_2_13:
type: 'network'
content: ['ANSIBLE_TEST_2_3', 'ANSIBLE_TEST_2_4']

# ports
ANSIBLE_TEST_2_14:
type: 'port'
content: ['ANSIBLE_TEST_2_5', 'ANSIBLE_TEST_2_6']

reload: false # geoip and urltable take LONG time

register: opn7
failed_when: >
opn7.failed or
not opn7.changed
when: not ansible_check_mode

- name: Listing aliases
ansibleguy.opnsense.list:
register: opn4
failed_when: >
'data' not in opn4 or
opn4.data | length != 11
opn4.data | length != 14
when: not ansible_check_mode

- name: Removing nesting
ansibleguy.opnsense.alias_multi:
aliases:
ANSIBLE_TEST_2_12:
ANSIBLE_TEST_2_13:
ANSIBLE_TEST_2_14:
state: 'absent'
when: not ansible_check_mode

- name: Removing
Expand Down
Loading