mirror of
https://github.com/netbirdio/ansible-netbird.git
synced 2026-05-22 18:43:36 -07:00
255 lines
6.5 KiB
Python
255 lines
6.5 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
# Copyright: (c) 2024, Community
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
"""Ansible module for managing NetBird groups."""
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = r'''
|
|
---
|
|
module: netbird_group
|
|
short_description: Manage NetBird groups
|
|
description:
|
|
- Create, update, and delete groups in NetBird.
|
|
- Groups are used to organize peers and define access policies.
|
|
version_added: "1.0.0"
|
|
author:
|
|
- Community
|
|
options:
|
|
state:
|
|
description:
|
|
- The desired state of the group.
|
|
type: str
|
|
choices: ['present', 'absent']
|
|
default: present
|
|
group_id:
|
|
description:
|
|
- The unique identifier of the group.
|
|
- Required when state is absent or when updating by ID.
|
|
type: str
|
|
name:
|
|
description:
|
|
- Name of the group.
|
|
- Required when creating a new group.
|
|
type: str
|
|
peers:
|
|
description:
|
|
- List of peer IDs to include in the group.
|
|
type: list
|
|
elements: str
|
|
default: []
|
|
resources:
|
|
description:
|
|
- List of resource objects for the group.
|
|
type: list
|
|
elements: dict
|
|
extends_documentation_fragment:
|
|
- community.ansible_netbird.netbird
|
|
requirements:
|
|
- python >= 3.6
|
|
'''
|
|
|
|
EXAMPLES = r'''
|
|
- name: Create a group
|
|
community.ansible_netbird.netbird_group:
|
|
api_url: "https://netbird.example.com"
|
|
api_token: "{{ netbird_token }}"
|
|
name: "developers"
|
|
state: present
|
|
|
|
- name: Create a group with peers
|
|
community.ansible_netbird.netbird_group:
|
|
api_url: "https://netbird.example.com"
|
|
api_token: "{{ netbird_token }}"
|
|
name: "production-servers"
|
|
peers:
|
|
- "peer-id-1"
|
|
- "peer-id-2"
|
|
state: present
|
|
|
|
- name: Update group peers
|
|
community.ansible_netbird.netbird_group:
|
|
api_url: "https://netbird.example.com"
|
|
api_token: "{{ netbird_token }}"
|
|
group_id: "group-id-123"
|
|
peers:
|
|
- "peer-id-1"
|
|
- "peer-id-2"
|
|
- "peer-id-3"
|
|
state: present
|
|
|
|
- name: Delete a group
|
|
community.ansible_netbird.netbird_group:
|
|
api_url: "https://netbird.example.com"
|
|
api_token: "{{ netbird_token }}"
|
|
group_id: "group-id-123"
|
|
state: absent
|
|
'''
|
|
|
|
RETURN = r'''
|
|
group:
|
|
description: The group object.
|
|
returned: success
|
|
type: dict
|
|
contains:
|
|
id:
|
|
description: Group ID.
|
|
type: str
|
|
name:
|
|
description: Group name.
|
|
type: str
|
|
peers_count:
|
|
description: Number of peers in the group.
|
|
type: int
|
|
peers:
|
|
description: List of peer IDs.
|
|
type: list
|
|
resources:
|
|
description: List of resources.
|
|
type: list
|
|
'''
|
|
|
|
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
|
|
)
|
|
|
|
|
|
def find_group_by_name(api, name):
|
|
"""Find a group by name."""
|
|
groups, _ = api.list_groups()
|
|
for group in groups:
|
|
if group.get('name') == name:
|
|
return group
|
|
return None
|
|
|
|
|
|
def group_needs_update(current, desired):
|
|
"""Check if group needs to be updated."""
|
|
if 'name' in desired and desired['name'] is not None:
|
|
if current.get('name') != desired['name']:
|
|
return True
|
|
|
|
if 'peers' in desired and desired['peers'] is not None:
|
|
current_peers = set(extract_ids(current.get('peers') or []))
|
|
desired_peers = set(extract_ids(desired['peers'] or []))
|
|
if current_peers != desired_peers:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def run_module():
|
|
"""Main module execution."""
|
|
argument_spec = netbird_argument_spec()
|
|
argument_spec.update(
|
|
state=dict(type='str', choices=['present', 'absent'], default='present'),
|
|
group_id=dict(type='str'),
|
|
name=dict(type='str'),
|
|
peers=dict(type='list', elements='str', default=[]),
|
|
resources=dict(type='list', elements='dict')
|
|
)
|
|
|
|
module = AnsibleModule(
|
|
argument_spec=argument_spec,
|
|
supports_check_mode=True,
|
|
required_one_of=[
|
|
('group_id', 'name'),
|
|
]
|
|
)
|
|
|
|
api = NetBirdAPI(
|
|
module,
|
|
module.params['api_url'],
|
|
module.params['api_token'],
|
|
module.params['validate_certs']
|
|
)
|
|
|
|
state = module.params['state']
|
|
group_id = module.params['group_id']
|
|
name = module.params['name']
|
|
peers = module.params['peers']
|
|
resources = module.params['resources']
|
|
|
|
result = dict(
|
|
changed=False,
|
|
group={}
|
|
)
|
|
|
|
try:
|
|
# Find existing group
|
|
existing_group = None
|
|
if group_id:
|
|
try:
|
|
existing_group, _ = api.get_group(group_id)
|
|
except NetBirdAPIError as e:
|
|
if e.status_code != 404:
|
|
raise
|
|
elif name:
|
|
existing_group = find_group_by_name(api, name)
|
|
|
|
if state == 'absent':
|
|
if existing_group:
|
|
if not module.check_mode:
|
|
api.delete_group(existing_group['id'])
|
|
result['changed'] = True
|
|
result['msg'] = 'Group deleted successfully'
|
|
module.exit_json(**result)
|
|
|
|
# state == 'present'
|
|
if existing_group:
|
|
# Check if update is needed
|
|
desired = {
|
|
'name': name,
|
|
'peers': peers
|
|
}
|
|
|
|
if group_needs_update(existing_group, desired):
|
|
if not module.check_mode:
|
|
group, _ = api.update_group(
|
|
existing_group['id'],
|
|
name=name,
|
|
peers=peers,
|
|
resources=resources
|
|
)
|
|
result['group'] = group
|
|
else:
|
|
result['group'] = existing_group
|
|
result['changed'] = True
|
|
else:
|
|
result['group'] = existing_group
|
|
else:
|
|
# Create new group
|
|
if not name:
|
|
module.fail_json(msg="name is required when creating a new group")
|
|
|
|
if not module.check_mode:
|
|
group, _ = api.create_group(
|
|
name=name,
|
|
peers=peers,
|
|
resources=resources
|
|
)
|
|
result['group'] = group
|
|
result['changed'] = True
|
|
|
|
module.exit_json(**result)
|
|
|
|
except NetBirdAPIError as e:
|
|
module.fail_json(msg=str(e), status_code=e.status_code, response=e.response)
|
|
|
|
|
|
def main():
|
|
run_module()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|
|
|