Files
2026-03-24 16:34:41 +01:00

267 lines
7.3 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 user invites."""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''
---
module: netbird_invite
short_description: Manage NetBird user invites
description:
- Create, delete, and regenerate user invites in NetBird.
- Invites are used to onboard new users to a NetBird account.
- Invites cannot be updated, only created, deleted, or regenerated.
version_added: "1.0.0"
author:
- Community
options:
state:
description:
- The desired state of the user invite.
type: str
choices: ['present', 'absent']
default: present
invite_id:
description:
- The unique identifier of the user invite.
- Can be used to delete a specific invite when state is absent.
type: str
email:
description:
- Email address for the invite.
- Required when state is present.
type: str
name:
description:
- Name of the invited user.
type: str
role:
description:
- Role to assign to the invited user.
type: str
choices: ['admin', 'user']
default: user
auto_groups:
description:
- List of group IDs to auto-assign to the invited user.
type: list
elements: str
default: []
expires_in:
description:
- Expiration time for the invite in seconds.
type: int
regenerate:
description:
- If true and an invite already exists for the email, regenerate the invite token.
type: bool
default: false
extends_documentation_fragment:
- community.ansible_netbird.netbird
requirements:
- python >= 3.6
'''
EXAMPLES = r'''
- name: Create a user invite
community.ansible_netbird.netbird_invite:
api_url: "https://netbird.example.com"
api_token: "{{ netbird_token }}"
email: "newuser@example.com"
name: "New User"
role: "user"
auto_groups:
- "group-id-1"
expires_in: 604800
state: present
- name: Create an admin invite
community.ansible_netbird.netbird_invite:
api_url: "https://netbird.example.com"
api_token: "{{ netbird_token }}"
email: "admin@example.com"
name: "Admin User"
role: "admin"
state: present
- name: Regenerate an existing invite
community.ansible_netbird.netbird_invite:
api_url: "https://netbird.example.com"
api_token: "{{ netbird_token }}"
email: "newuser@example.com"
regenerate: true
state: present
- name: Delete an invite by email
community.ansible_netbird.netbird_invite:
api_url: "https://netbird.example.com"
api_token: "{{ netbird_token }}"
email: "newuser@example.com"
state: absent
- name: Delete an invite by ID
community.ansible_netbird.netbird_invite:
api_url: "https://netbird.example.com"
api_token: "{{ netbird_token }}"
invite_id: "invite-id-123"
state: absent
'''
RETURN = r'''
invite:
description: The user invite object.
returned: success
type: dict
contains:
id:
description: Invite ID.
type: str
email:
description: Invited user email.
type: str
name:
description: Invited user name.
type: str
role:
description: Assigned role.
type: str
auto_groups:
description: Auto-assigned group IDs.
type: list
expires_at:
description: Invite expiration timestamp.
type: str
created_at:
description: Invite creation timestamp.
type: str
expired:
description: Whether the invite has expired.
type: bool
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.ansible_netbird.plugins.module_utils.netbird_api import (
NetBirdAPI,
NetBirdAPIError,
netbird_argument_spec
)
def find_invite_by_email(api, email):
"""Find a user invite by email address."""
invites, _ = api.list_user_invites()
for invite in invites:
if invite.get('email') == email:
return invite
return None
def run_module():
"""Main module execution."""
argument_spec = netbird_argument_spec()
argument_spec.update(
state=dict(type='str', choices=['present', 'absent'], default='present'),
invite_id=dict(type='str'),
email=dict(type='str'),
name=dict(type='str'),
role=dict(type='str', choices=['admin', 'user'], default='user'),
auto_groups=dict(type='list', elements='str', default=[]),
expires_in=dict(type='int'),
regenerate=dict(type='bool', default=False)
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_if=[
('state', 'present', ['email']),
]
)
api = NetBirdAPI(
module,
module.params['api_url'],
module.params['api_token'],
module.params['validate_certs']
)
state = module.params['state']
invite_id = module.params['invite_id']
email = module.params['email']
name = module.params['name']
role = module.params['role']
auto_groups = module.params['auto_groups']
expires_in = module.params['expires_in']
regenerate = module.params['regenerate']
result = dict(
changed=False,
invite={}
)
try:
if state == 'absent':
if invite_id:
if not module.check_mode:
api.delete_user_invite(invite_id)
result['changed'] = True
result['msg'] = 'User invite deleted successfully'
elif email:
existing_invite = find_invite_by_email(api, email)
if existing_invite:
if not module.check_mode:
api.delete_user_invite(existing_invite['id'])
result['changed'] = True
result['msg'] = 'User invite deleted successfully'
module.exit_json(**result)
# state == 'present'
existing_invite = find_invite_by_email(api, email)
if existing_invite:
if regenerate:
# Regenerate the invite token
if not module.check_mode:
invite, _ = api.regenerate_user_invite(
existing_invite['id'],
expires_in=expires_in
)
result['invite'] = invite
else:
result['invite'] = existing_invite
result['changed'] = True
else:
# Invite already exists, return it
result['invite'] = existing_invite
result['msg'] = 'User invite already exists'
else:
# Create new invite
if not module.check_mode:
invite, _ = api.create_user_invite(
email=email,
name=name,
role=role,
auto_groups=auto_groups,
expires_in=expires_in
)
result['invite'] = invite
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()