mirror of
https://github.com/netbirdio/ansible-netbird.git
synced 2026-05-22 18:43:36 -07:00
@@ -14,6 +14,19 @@ from ansible.module_utils.basic import env_fallback
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
|
||||
|
||||
|
||||
def extract_ids(items):
|
||||
"""Extract IDs from a list that may contain dicts or plain strings.
|
||||
|
||||
The NetBird API returns related objects as dicts (e.g.
|
||||
``[{"id": "abc", "name": "..."}]``) while module parameters are plain
|
||||
ID strings. This helper normalises both forms to a flat list of ID
|
||||
strings so they can be safely compared with ``set()``.
|
||||
"""
|
||||
if not items:
|
||||
return []
|
||||
return [item['id'] if isinstance(item, dict) else item for item in items]
|
||||
|
||||
|
||||
class NetBirdAPIError(Exception):
|
||||
"""Exception raised for NetBird API errors."""
|
||||
def __init__(self, message, status_code=None, response=None):
|
||||
|
||||
@@ -213,6 +213,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
|
||||
NetBirdAPI,
|
||||
NetBirdAPIError,
|
||||
extract_ids,
|
||||
netbird_argument_spec
|
||||
)
|
||||
|
||||
@@ -239,8 +240,8 @@ def nsgroup_needs_update(current, params):
|
||||
|
||||
# Check groups
|
||||
if params.get('groups') is not None:
|
||||
current_groups = set(current.get('groups', []))
|
||||
desired_groups = set(params['groups'])
|
||||
current_groups = set(extract_ids(current.get('groups') or []))
|
||||
desired_groups = set(extract_ids(params['groups'] or []))
|
||||
if current_groups != desired_groups:
|
||||
return True
|
||||
|
||||
@@ -299,8 +300,8 @@ def run_module():
|
||||
if state == 'present':
|
||||
disabled_groups = module.params['disabled_management_groups']
|
||||
if disabled_groups is not None:
|
||||
current_disabled = set(current_settings.get('disabled_management_groups', []))
|
||||
desired_disabled = set(disabled_groups)
|
||||
current_disabled = set(extract_ids(current_settings.get('disabled_management_groups') or []))
|
||||
desired_disabled = set(extract_ids(disabled_groups or []))
|
||||
|
||||
if current_disabled != desired_disabled:
|
||||
if not module.check_mode:
|
||||
|
||||
@@ -168,6 +168,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
|
||||
NetBirdAPI,
|
||||
NetBirdAPIError,
|
||||
extract_ids,
|
||||
netbird_argument_spec
|
||||
)
|
||||
|
||||
@@ -192,8 +193,8 @@ def zone_needs_update(current, params):
|
||||
if params.get('enable_search_domain') is not None and current.get('enable_search_domain') != params['enable_search_domain']:
|
||||
return True
|
||||
if params.get('distribution_groups') is not None:
|
||||
current_groups = set(current.get('distribution_groups', []) or [])
|
||||
desired_groups = set(params['distribution_groups'] or [])
|
||||
current_groups = set(extract_ids(current.get('distribution_groups') or []))
|
||||
desired_groups = set(extract_ids(params['distribution_groups'] or []))
|
||||
if current_groups != desired_groups:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -116,6 +116,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
|
||||
NetBirdAPI,
|
||||
NetBirdAPIError,
|
||||
extract_ids,
|
||||
netbird_argument_spec
|
||||
)
|
||||
|
||||
@@ -136,14 +137,8 @@ def group_needs_update(current, desired):
|
||||
return True
|
||||
|
||||
if 'peers' in desired and desired['peers'] is not None:
|
||||
# API returns peers as dicts [{"id": "...", "name": "..."}] or null;
|
||||
# desired peers are plain ID strings from the module parameter.
|
||||
raw_peers = current.get('peers') or []
|
||||
if raw_peers and isinstance(raw_peers[0], dict):
|
||||
current_peers = set(p['id'] for p in raw_peers)
|
||||
else:
|
||||
current_peers = set(raw_peers)
|
||||
desired_peers = set(desired['peers'])
|
||||
current_peers = set(extract_ids(current.get('peers') or []))
|
||||
desired_peers = set(extract_ids(desired['peers'] or []))
|
||||
if current_peers != desired_peers:
|
||||
return True
|
||||
|
||||
|
||||
@@ -318,6 +318,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
|
||||
NetBirdAPI,
|
||||
NetBirdAPIError,
|
||||
extract_ids,
|
||||
netbird_argument_spec
|
||||
)
|
||||
|
||||
@@ -343,7 +344,7 @@ def network_needs_update(current, params):
|
||||
def get_router_key(router):
|
||||
"""Generate a unique key for a router based on peer/peer_groups."""
|
||||
peer = router.get('peer', '')
|
||||
peer_groups = tuple(sorted(router.get('peer_groups', []) or []))
|
||||
peer_groups = tuple(sorted(extract_ids(router.get('peer_groups') or [])))
|
||||
return (peer, peer_groups)
|
||||
|
||||
|
||||
@@ -366,8 +367,8 @@ def resource_needs_update(current, desired):
|
||||
return True
|
||||
if current.get('enabled', True) != desired.get('enabled', True):
|
||||
return True
|
||||
current_groups = set(current.get('groups', []) or [])
|
||||
desired_groups = set(desired.get('groups', []) or [])
|
||||
current_groups = set(extract_ids(current.get('groups') or []))
|
||||
desired_groups = set(extract_ids(desired.get('groups') or []))
|
||||
if current_groups != desired_groups:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -233,6 +233,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
|
||||
NetBirdAPI,
|
||||
NetBirdAPIError,
|
||||
extract_ids,
|
||||
netbird_argument_spec
|
||||
)
|
||||
|
||||
@@ -283,6 +284,36 @@ def build_rules_data(rules):
|
||||
return [build_rule_data(rule) for rule in rules]
|
||||
|
||||
|
||||
def normalize_rule(rule):
|
||||
"""Normalize a rule for comparison, extracting IDs from any dict references."""
|
||||
return {
|
||||
'name': rule.get('name', ''),
|
||||
'description': rule.get('description', ''),
|
||||
'enabled': rule.get('enabled', True),
|
||||
'sources': sorted(extract_ids(rule.get('sources') or [])),
|
||||
'destinations': sorted(extract_ids(rule.get('destinations') or [])),
|
||||
'bidirectional': rule.get('bidirectional', True),
|
||||
'protocol': rule.get('protocol', 'all'),
|
||||
'ports': sorted(rule.get('ports') or []),
|
||||
'action': rule.get('action', 'accept'),
|
||||
}
|
||||
|
||||
|
||||
def rules_need_update(current_rules, desired_rules):
|
||||
"""Check if rules need to be updated by comparing normalized representations."""
|
||||
current_rules = current_rules or []
|
||||
desired_rules = desired_rules or []
|
||||
if len(current_rules) != len(desired_rules):
|
||||
return True
|
||||
for current, desired in zip(
|
||||
sorted(current_rules, key=lambda r: r.get('name', '')),
|
||||
sorted(desired_rules, key=lambda r: r.get('name', ''))
|
||||
):
|
||||
if normalize_rule(current) != normalize_rule(desired):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def policy_needs_update(current, params):
|
||||
"""Check if policy needs to be updated."""
|
||||
if params.get('name') is not None and current.get('name') != params['name']:
|
||||
@@ -291,11 +322,14 @@ def policy_needs_update(current, params):
|
||||
return True
|
||||
if params.get('enabled') is not None and current.get('enabled') != params['enabled']:
|
||||
return True
|
||||
if params.get('source_posture_checks') is not None and current.get('source_posture_checks') != params['source_posture_checks']:
|
||||
return True
|
||||
# For rules, always update if provided to ensure they match exactly
|
||||
if params.get('source_posture_checks') is not None:
|
||||
current_checks = set(extract_ids(current.get('source_posture_checks') or []))
|
||||
desired_checks = set(extract_ids(params['source_posture_checks'] or []))
|
||||
if current_checks != desired_checks:
|
||||
return True
|
||||
if params.get('rules') is not None:
|
||||
return True
|
||||
if rules_need_update(current.get('rules'), params['rules']):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
@@ -181,6 +181,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
|
||||
NetBirdAPI,
|
||||
NetBirdAPIError,
|
||||
extract_ids,
|
||||
netbird_argument_spec
|
||||
)
|
||||
|
||||
@@ -207,15 +208,15 @@ def route_needs_update(current, params):
|
||||
|
||||
# Check peer_groups
|
||||
if params.get('peer_groups') is not None:
|
||||
current_groups = set(current.get('peer_groups', []))
|
||||
desired_groups = set(params['peer_groups'])
|
||||
current_groups = set(extract_ids(current.get('peer_groups') or []))
|
||||
desired_groups = set(extract_ids(params['peer_groups'] or []))
|
||||
if current_groups != desired_groups:
|
||||
return True
|
||||
|
||||
|
||||
# Check groups
|
||||
if params.get('groups') is not None:
|
||||
current_groups = set(current.get('groups', []))
|
||||
desired_groups = set(params['groups'])
|
||||
current_groups = set(extract_ids(current.get('groups') or []))
|
||||
desired_groups = set(extract_ids(params['groups'] or []))
|
||||
if current_groups != desired_groups:
|
||||
return True
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
|
||||
NetBirdAPI,
|
||||
NetBirdAPIError,
|
||||
extract_ids,
|
||||
netbird_argument_spec
|
||||
)
|
||||
|
||||
@@ -198,8 +199,8 @@ def setup_key_needs_update(current, params):
|
||||
if params.get('revoked') is not None and current.get('revoked') != params['revoked']:
|
||||
return True
|
||||
if params.get('auto_groups') is not None:
|
||||
current_groups = set(current.get('auto_groups', []))
|
||||
desired_groups = set(params['auto_groups'])
|
||||
current_groups = set(extract_ids(current.get('auto_groups') or []))
|
||||
desired_groups = set(extract_ids(params['auto_groups'] or []))
|
||||
if current_groups != desired_groups:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -158,6 +158,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
|
||||
NetBirdAPI,
|
||||
NetBirdAPIError,
|
||||
extract_ids,
|
||||
netbird_argument_spec
|
||||
)
|
||||
|
||||
@@ -188,8 +189,8 @@ def user_needs_update(current, desired):
|
||||
return True
|
||||
|
||||
if 'auto_groups' in desired and desired['auto_groups'] is not None:
|
||||
current_groups = set(current.get('auto_groups', []))
|
||||
desired_groups = set(desired['auto_groups'])
|
||||
current_groups = set(extract_ids(current.get('auto_groups') or []))
|
||||
desired_groups = set(extract_ids(desired['auto_groups'] or []))
|
||||
if current_groups != desired_groups:
|
||||
return True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user