You've already forked ansible-netbird
mirror of
https://github.com/netbirdio/ansible-netbird.git
synced 2026-05-22 18:43:36 -07:00
5d85c3afef
- Add (items or []) to all find_*_by_* functions across 12 modules.
The NetBird API returns null for empty collections, causing TypeError
when iterating. Affects find_group_by_name, find_policy_by_name,
find_setup_key_by_name, find_user_by_email, find_user_by_name,
find_network_by_name, find_route_by_network_id, find_nsgroup_by_name,
find_zone_by_name, find_posture_check_by_name, find_idp_by_name,
find_invite_by_email, find_token_by_name.
- Add (or []) to sync_routers and sync_resources in netbird_network
for the same reason (new networks have null router/resource lists).
- Fix export role network enrichment: .get('json', []) does not work
on Ansible uri module results. Changed to .json | default([]).
- Fix set_fact parsing in export and configure roles: {{ result | to_json }}
produces a JSON string, not a list. Added | from_json so downstream
loop directives receive proper lists (3 occurrences in configure,
1 in export).
- Use urllib.parse.urlencode for query parameter encoding instead of
raw f-string interpolation to prevent URL breakage with special chars.
212 lines
5.6 KiB
Python
212 lines
5.6 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 personal access tokens."""
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = r'''
|
|
---
|
|
module: netbird_token
|
|
short_description: Manage NetBird personal access tokens
|
|
description:
|
|
- Create and delete personal access tokens in NetBird.
|
|
- Tokens are used for API authentication.
|
|
version_added: "1.0.0"
|
|
author:
|
|
- Community
|
|
options:
|
|
state:
|
|
description:
|
|
- The desired state of the token.
|
|
type: str
|
|
choices: ['present', 'absent']
|
|
default: present
|
|
user_id:
|
|
description:
|
|
- The unique identifier of the user to manage tokens for.
|
|
type: str
|
|
required: true
|
|
token_id:
|
|
description:
|
|
- The unique identifier of the token.
|
|
- Required when state is absent.
|
|
type: str
|
|
name:
|
|
description:
|
|
- Name of the token.
|
|
- Required when creating a new token.
|
|
type: str
|
|
expires_in:
|
|
description:
|
|
- Token expiration time in days.
|
|
- If not specified, uses the default expiration.
|
|
type: int
|
|
extends_documentation_fragment:
|
|
- community.ansible_netbird.netbird
|
|
requirements:
|
|
- python >= 3.6
|
|
'''
|
|
|
|
EXAMPLES = r'''
|
|
- name: Create a personal access token
|
|
community.ansible_netbird.netbird_token:
|
|
api_url: "https://netbird.example.com"
|
|
api_token: "{{ netbird_token }}"
|
|
user_id: "user-id-123"
|
|
name: "automation-token"
|
|
expires_in: 365
|
|
state: present
|
|
register: new_token
|
|
|
|
- name: Display the token value (only available on creation)
|
|
ansible.builtin.debug:
|
|
msg: "Token: {{ new_token.token.plain_token }}"
|
|
|
|
- name: Delete a token
|
|
community.ansible_netbird.netbird_token:
|
|
api_url: "https://netbird.example.com"
|
|
api_token: "{{ netbird_token }}"
|
|
user_id: "user-id-123"
|
|
token_id: "token-id-456"
|
|
state: absent
|
|
'''
|
|
|
|
RETURN = r'''
|
|
token:
|
|
description: The token object.
|
|
returned: success
|
|
type: dict
|
|
contains:
|
|
id:
|
|
description: Token ID.
|
|
type: str
|
|
name:
|
|
description: Token name.
|
|
type: str
|
|
expiration_date:
|
|
description: Token expiration date.
|
|
type: str
|
|
created_by:
|
|
description: User ID who created the token.
|
|
type: str
|
|
created_at:
|
|
description: Token creation timestamp.
|
|
type: str
|
|
last_used:
|
|
description: Last used timestamp.
|
|
type: str
|
|
plain_token:
|
|
description: The actual token value (only returned on creation).
|
|
type: str
|
|
'''
|
|
|
|
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_token_by_name(api, user_id, name):
|
|
"""Find a token by name for a specific user."""
|
|
tokens, _ = api.list_tokens(user_id)
|
|
for token in (tokens or []):
|
|
if token.get('name') == name:
|
|
return token
|
|
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'),
|
|
user_id=dict(type='str', required=True),
|
|
token_id=dict(type='str'),
|
|
name=dict(type='str'),
|
|
expires_in=dict(type='int')
|
|
)
|
|
|
|
module = AnsibleModule(
|
|
argument_spec=argument_spec,
|
|
supports_check_mode=True,
|
|
required_if=[
|
|
('state', 'absent', ['token_id'], True),
|
|
('state', 'present', ['name'], True),
|
|
]
|
|
)
|
|
|
|
api = NetBirdAPI(
|
|
module,
|
|
module.params['api_url'],
|
|
module.params['api_token'],
|
|
module.params['validate_certs']
|
|
)
|
|
|
|
state = module.params['state']
|
|
user_id = module.params['user_id']
|
|
token_id = module.params['token_id']
|
|
name = module.params['name']
|
|
expires_in = module.params['expires_in']
|
|
|
|
result = dict(
|
|
changed=False,
|
|
token={}
|
|
)
|
|
|
|
try:
|
|
if state == 'absent':
|
|
if token_id:
|
|
if not module.check_mode:
|
|
api.delete_token(user_id, token_id)
|
|
result['changed'] = True
|
|
result['msg'] = 'Token deleted successfully'
|
|
elif name:
|
|
# Find token by name to delete
|
|
existing_token = find_token_by_name(api, user_id, name)
|
|
if existing_token:
|
|
if not module.check_mode:
|
|
api.delete_token(user_id, existing_token['id'])
|
|
result['changed'] = True
|
|
result['msg'] = 'Token deleted successfully'
|
|
module.exit_json(**result)
|
|
|
|
# state == 'present'
|
|
# Check if token with this name already exists
|
|
existing_token = find_token_by_name(api, user_id, name)
|
|
|
|
if existing_token:
|
|
# Token exists, return it (we can't update tokens)
|
|
result['token'] = existing_token
|
|
result['msg'] = 'Token already exists'
|
|
else:
|
|
# Create new token
|
|
if not module.check_mode:
|
|
token, _ = api.create_token(
|
|
user_id,
|
|
name=name,
|
|
expires_in=expires_in
|
|
)
|
|
result['token'] = token
|
|
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()
|
|
|
|
|