2021-03-21 11:30:16 +01:00
|
|
|
#!/usr/bin/python
|
|
|
|
# -*- coding: utf-8 -*-
|
2022-08-05 13:17:19 +02:00
|
|
|
# Copyright (c) 2021, Florian Dambrine <android.florian@gmail.com>
|
|
|
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2021-03-21 11:30:16 +01:00
|
|
|
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
|
|
DOCUMENTATION = """
|
|
|
|
---
|
|
|
|
module: pritunl_user
|
|
|
|
author: "Florian Dambrine (@Lowess)"
|
|
|
|
version_added: 2.3.0
|
|
|
|
short_description: Manage Pritunl Users using the Pritunl API
|
|
|
|
description:
|
|
|
|
- A module to manage Pritunl users using the Pritunl API.
|
|
|
|
extends_documentation_fragment:
|
|
|
|
- community.general.pritunl
|
|
|
|
options:
|
|
|
|
organization:
|
|
|
|
type: str
|
|
|
|
required: true
|
|
|
|
aliases:
|
|
|
|
- org
|
|
|
|
description:
|
|
|
|
- The name of the organization the user is part of.
|
|
|
|
|
|
|
|
state:
|
|
|
|
type: str
|
|
|
|
default: 'present'
|
|
|
|
choices:
|
|
|
|
- present
|
|
|
|
- absent
|
|
|
|
description:
|
|
|
|
- If C(present), the module adds user I(user_name) to
|
|
|
|
the Pritunl I(organization). If C(absent), removes the user
|
|
|
|
I(user_name) from the Pritunl I(organization).
|
|
|
|
|
|
|
|
user_name:
|
|
|
|
type: str
|
|
|
|
required: true
|
|
|
|
default: null
|
|
|
|
description:
|
|
|
|
- Name of the user to create or delete from Pritunl.
|
|
|
|
|
|
|
|
user_email:
|
|
|
|
type: str
|
|
|
|
required: false
|
|
|
|
default: null
|
|
|
|
description:
|
|
|
|
- Email address associated with the user I(user_name).
|
|
|
|
|
|
|
|
user_type:
|
|
|
|
type: str
|
|
|
|
required: false
|
|
|
|
default: client
|
|
|
|
choices:
|
|
|
|
- client
|
|
|
|
- server
|
|
|
|
description:
|
|
|
|
- Type of the user I(user_name).
|
|
|
|
|
|
|
|
user_groups:
|
|
|
|
type: list
|
|
|
|
elements: str
|
|
|
|
required: false
|
|
|
|
default: null
|
|
|
|
description:
|
|
|
|
- List of groups associated with the user I(user_name).
|
|
|
|
|
|
|
|
user_disabled:
|
|
|
|
type: bool
|
|
|
|
required: false
|
|
|
|
default: null
|
|
|
|
description:
|
|
|
|
- Enable/Disable the user I(user_name).
|
|
|
|
|
|
|
|
user_gravatar:
|
|
|
|
type: bool
|
|
|
|
required: false
|
|
|
|
default: null
|
|
|
|
description:
|
|
|
|
- Enable/Disable Gravatar usage for the user I(user_name).
|
2022-05-09 07:38:10 +02:00
|
|
|
|
|
|
|
user_mac_addresses:
|
|
|
|
type: list
|
|
|
|
elements: str
|
|
|
|
description:
|
|
|
|
- Allowed MAC addresses for the user I(user_name).
|
|
|
|
version_added: 5.0.0
|
2021-03-21 11:30:16 +01:00
|
|
|
"""
|
|
|
|
|
|
|
|
EXAMPLES = """
|
|
|
|
- name: Create the user Foo with email address foo@bar.com in MyOrg
|
|
|
|
community.general.pritunl_user:
|
|
|
|
state: present
|
2022-05-09 07:38:10 +02:00
|
|
|
organization: MyOrg
|
2021-03-21 11:30:16 +01:00
|
|
|
user_name: Foo
|
|
|
|
user_email: foo@bar.com
|
2022-05-09 07:38:10 +02:00
|
|
|
user_mac_addresses:
|
|
|
|
- "00:00:00:00:00:99"
|
2021-03-21 11:30:16 +01:00
|
|
|
|
|
|
|
- name: Disable the user Foo but keep it in Pritunl
|
|
|
|
community.general.pritunl_user:
|
|
|
|
state: present
|
2022-05-09 07:38:10 +02:00
|
|
|
organization: MyOrg
|
2021-03-21 11:30:16 +01:00
|
|
|
user_name: Foo
|
|
|
|
user_email: foo@bar.com
|
|
|
|
user_disabled: yes
|
|
|
|
|
|
|
|
- name: Make sure the user Foo is not part of MyOrg anymore
|
|
|
|
community.general.pritunl_user:
|
|
|
|
state: absent
|
2022-05-09 07:38:10 +02:00
|
|
|
organization: MyOrg
|
2021-03-21 11:30:16 +01:00
|
|
|
user_name: Foo
|
|
|
|
"""
|
|
|
|
|
|
|
|
RETURN = """
|
|
|
|
response:
|
|
|
|
description: JSON representation of Pritunl Users.
|
|
|
|
returned: success
|
|
|
|
type: dict
|
|
|
|
sample:
|
|
|
|
{
|
|
|
|
"audit": false,
|
|
|
|
"auth_type": "google",
|
|
|
|
"bypass_secondary": false,
|
|
|
|
"client_to_client": false,
|
|
|
|
"disabled": false,
|
|
|
|
"dns_mapping": null,
|
|
|
|
"dns_servers": null,
|
|
|
|
"dns_suffix": null,
|
|
|
|
"email": "foo@bar.com",
|
|
|
|
"gravatar": true,
|
|
|
|
"groups": [
|
|
|
|
"foo", "bar"
|
|
|
|
],
|
|
|
|
"id": "5d070dafe63q3b2e6s472c3b",
|
|
|
|
"name": "foo@acme.com",
|
|
|
|
"network_links": [],
|
|
|
|
"organization": "58070daee6sf342e6e4s2c36",
|
|
|
|
"organization_name": "Acme",
|
|
|
|
"otp_auth": true,
|
|
|
|
"otp_secret": "35H5EJA3XB2$4CWG",
|
|
|
|
"pin": false,
|
|
|
|
"port_forwarding": [],
|
|
|
|
"servers": [],
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
2021-06-26 23:59:11 +02:00
|
|
|
from ansible.module_utils.common.text.converters import to_native
|
2021-03-21 11:30:16 +01:00
|
|
|
from ansible.module_utils.common.dict_transformations import dict_merge
|
|
|
|
from ansible_collections.community.general.plugins.module_utils.net_tools.pritunl.api import (
|
|
|
|
PritunlException,
|
|
|
|
delete_pritunl_user,
|
|
|
|
get_pritunl_settings,
|
|
|
|
list_pritunl_organizations,
|
|
|
|
list_pritunl_users,
|
|
|
|
post_pritunl_user,
|
|
|
|
pritunl_argument_spec,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def add_or_update_pritunl_user(module):
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
org_name = module.params.get("organization")
|
|
|
|
user_name = module.params.get("user_name")
|
|
|
|
|
|
|
|
user_params = {
|
|
|
|
"name": user_name,
|
|
|
|
"email": module.params.get("user_email"),
|
|
|
|
"groups": module.params.get("user_groups"),
|
|
|
|
"disabled": module.params.get("user_disabled"),
|
|
|
|
"gravatar": module.params.get("user_gravatar"),
|
2022-05-09 07:38:10 +02:00
|
|
|
"mac_addresses": module.params.get("user_mac_addresses"),
|
2021-03-21 11:30:16 +01:00
|
|
|
"type": module.params.get("user_type"),
|
|
|
|
}
|
|
|
|
|
|
|
|
org_obj_list = list_pritunl_organizations(
|
|
|
|
**dict_merge(
|
|
|
|
get_pritunl_settings(module),
|
|
|
|
{"filters": {"name": org_name}},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
if len(org_obj_list) == 0:
|
|
|
|
module.fail_json(
|
|
|
|
msg="Can not add user to organization '%s' which does not exist" % org_name
|
|
|
|
)
|
|
|
|
|
|
|
|
org_id = org_obj_list[0]["id"]
|
|
|
|
|
|
|
|
# Grab existing users from this org
|
|
|
|
users = list_pritunl_users(
|
|
|
|
**dict_merge(
|
|
|
|
get_pritunl_settings(module),
|
|
|
|
{
|
|
|
|
"organization_id": org_id,
|
|
|
|
"filters": {"name": user_name},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Check if the pritunl user already exists
|
|
|
|
if len(users) > 0:
|
|
|
|
# Compare remote user params with local user_params and trigger update if needed
|
|
|
|
user_params_changed = False
|
|
|
|
for key in user_params.keys():
|
|
|
|
# When a param is not specified grab existing ones to prevent from changing it with the PUT request
|
|
|
|
if user_params[key] is None:
|
|
|
|
user_params[key] = users[0][key]
|
|
|
|
|
2022-05-09 07:38:10 +02:00
|
|
|
# 'groups' and 'mac_addresses' are list comparison
|
|
|
|
if key == "groups" or key == "mac_addresses":
|
2021-03-21 11:30:16 +01:00
|
|
|
if set(users[0][key]) != set(user_params[key]):
|
|
|
|
user_params_changed = True
|
|
|
|
|
|
|
|
# otherwise it is either a boolean or a string
|
|
|
|
else:
|
|
|
|
if users[0][key] != user_params[key]:
|
|
|
|
user_params_changed = True
|
|
|
|
|
|
|
|
# Trigger a PUT on the API to update the current user if settings have changed
|
|
|
|
if user_params_changed:
|
|
|
|
response = post_pritunl_user(
|
|
|
|
**dict_merge(
|
|
|
|
get_pritunl_settings(module),
|
|
|
|
{
|
|
|
|
"organization_id": org_id,
|
|
|
|
"user_id": users[0]["id"],
|
|
|
|
"user_data": user_params,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
result["changed"] = True
|
|
|
|
result["response"] = response
|
|
|
|
else:
|
|
|
|
result["changed"] = False
|
|
|
|
result["response"] = users
|
|
|
|
else:
|
|
|
|
response = post_pritunl_user(
|
|
|
|
**dict_merge(
|
|
|
|
get_pritunl_settings(module),
|
|
|
|
{
|
|
|
|
"organization_id": org_id,
|
|
|
|
"user_data": user_params,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
result["changed"] = True
|
|
|
|
result["response"] = response
|
|
|
|
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
|
|
|
|
|
|
|
def remove_pritunl_user(module):
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
org_name = module.params.get("organization")
|
|
|
|
user_name = module.params.get("user_name")
|
|
|
|
|
|
|
|
org_obj_list = []
|
|
|
|
|
|
|
|
org_obj_list = list_pritunl_organizations(
|
|
|
|
**dict_merge(
|
|
|
|
get_pritunl_settings(module),
|
|
|
|
{
|
|
|
|
"filters": {"name": org_name},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
if len(org_obj_list) == 0:
|
|
|
|
module.fail_json(
|
|
|
|
msg="Can not remove user '%s' from a non existing organization '%s'"
|
|
|
|
% (user_name, org_name)
|
|
|
|
)
|
|
|
|
|
|
|
|
org_id = org_obj_list[0]["id"]
|
|
|
|
|
|
|
|
# Grab existing users from this org
|
|
|
|
users = list_pritunl_users(
|
|
|
|
**dict_merge(
|
|
|
|
get_pritunl_settings(module),
|
|
|
|
{
|
|
|
|
"organization_id": org_id,
|
|
|
|
"filters": {"name": user_name},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Check if the pritunl user exists, if not, do nothing
|
|
|
|
if len(users) == 0:
|
|
|
|
result["changed"] = False
|
|
|
|
result["response"] = {}
|
|
|
|
|
|
|
|
# Otherwise remove the org from Pritunl
|
|
|
|
else:
|
|
|
|
response = delete_pritunl_user(
|
|
|
|
**dict_merge(
|
|
|
|
get_pritunl_settings(module),
|
|
|
|
{
|
|
|
|
"organization_id": org_id,
|
|
|
|
"user_id": users[0]["id"],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
result["changed"] = True
|
|
|
|
result["response"] = response
|
|
|
|
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
argument_spec = pritunl_argument_spec()
|
|
|
|
|
|
|
|
argument_spec.update(
|
|
|
|
dict(
|
|
|
|
organization=dict(required=True, type="str", aliases=["org"]),
|
|
|
|
state=dict(
|
|
|
|
required=False, choices=["present", "absent"], default="present"
|
|
|
|
),
|
|
|
|
user_name=dict(required=True, type="str"),
|
|
|
|
user_type=dict(
|
|
|
|
required=False, choices=["client", "server"], default="client"
|
|
|
|
),
|
|
|
|
user_email=dict(required=False, type="str", default=None),
|
|
|
|
user_groups=dict(required=False, type="list", elements="str", default=None),
|
|
|
|
user_disabled=dict(required=False, type="bool", default=None),
|
|
|
|
user_gravatar=dict(required=False, type="bool", default=None),
|
2022-05-09 07:38:10 +02:00
|
|
|
user_mac_addresses=dict(required=False, type="list", elements="str", default=None),
|
2021-03-21 11:30:16 +01:00
|
|
|
)
|
|
|
|
),
|
|
|
|
|
|
|
|
module = AnsibleModule(argument_spec=argument_spec)
|
|
|
|
|
|
|
|
state = module.params.get("state")
|
|
|
|
|
|
|
|
try:
|
|
|
|
if state == "present":
|
|
|
|
add_or_update_pritunl_user(module)
|
|
|
|
elif state == "absent":
|
|
|
|
remove_pritunl_user(module)
|
|
|
|
except PritunlException as e:
|
|
|
|
module.fail_json(msg=to_native(e))
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|