2021-04-10 10:59:25 +00:00
|
|
|
# coding: utf-8
|
|
|
|
|
2022-04-11 18:56:42 +00:00
|
|
|
# (c) 2021-2022, Famedly GmbH
|
2021-04-10 10:59:25 +00:00
|
|
|
# GNU Affero General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/agpl-3.0.txt)
|
|
|
|
|
|
|
|
from __future__ import (absolute_import, division, print_function)
|
2022-07-29 08:47:49 +00:00
|
|
|
|
2021-04-10 10:59:25 +00:00
|
|
|
__metaclass__ = type
|
|
|
|
|
|
|
|
import traceback
|
|
|
|
|
2022-07-29 08:47:49 +00:00
|
|
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
|
|
|
|
|
|
|
# Check if all required libs can load
|
2021-04-10 10:59:25 +00:00
|
|
|
LIB_IMP_ERR = None
|
|
|
|
try:
|
2022-07-29 08:47:49 +00:00
|
|
|
from nio import AsyncClient, AsyncClientConfig, \
|
|
|
|
Api, \
|
|
|
|
LoginResponse, LoginError, \
|
|
|
|
LogoutResponse, LogoutError, \
|
|
|
|
RoomGetStateResponse, RoomGetStateError, \
|
|
|
|
RoomBanResponse, RoomBanError, \
|
|
|
|
RoomUnbanResponse, RoomUnbanError, \
|
|
|
|
RoomKickResponse, RoomKickError, \
|
|
|
|
RoomInviteResponse, RoomInviteError, \
|
|
|
|
RoomResolveAliasResponse, RoomResolveAliasError, \
|
|
|
|
JoinedRoomsResponse, JoinedRoomsError
|
|
|
|
HAS_LIB = True
|
2021-04-10 10:59:25 +00:00
|
|
|
except ImportError:
|
2022-07-29 08:47:49 +00:00
|
|
|
LIB_IMP_ERR = traceback.format_exc()
|
|
|
|
HAS_LIB = False
|
2021-04-10 10:59:25 +00:00
|
|
|
|
2022-07-29 08:47:49 +00:00
|
|
|
|
|
|
|
class AnsibleNioModule:
|
|
|
|
def __init__(self,
|
|
|
|
custom_spec=None,
|
2021-04-10 10:59:25 +00:00
|
|
|
bypass_checks=False,
|
|
|
|
no_log=False,
|
2022-07-29 08:47:49 +00:00
|
|
|
mutually_exclusive=None,
|
2022-04-11 18:56:42 +00:00
|
|
|
required_together=None,
|
2022-07-29 08:47:49 +00:00
|
|
|
required_one_of=None,
|
|
|
|
required_by=None,
|
2021-04-10 10:59:25 +00:00
|
|
|
add_file_common_args=False,
|
|
|
|
supports_check_mode=True,
|
|
|
|
required_if=None,
|
|
|
|
user_logout=True):
|
|
|
|
|
2022-07-29 08:47:49 +00:00
|
|
|
if required_by is None:
|
|
|
|
required_by = {'password': 'user_id'}
|
|
|
|
|
|
|
|
if required_one_of is None:
|
|
|
|
required_one_of = [['password', 'token']]
|
|
|
|
|
|
|
|
if mutually_exclusive is None:
|
|
|
|
mutually_exclusive = [['password', 'token']]
|
|
|
|
|
|
|
|
if custom_spec is None:
|
|
|
|
custom_spec = {}
|
|
|
|
|
|
|
|
# If a user/password login is provided, should we logout when exiting?
|
|
|
|
self.user_logout = user_logout
|
|
|
|
|
|
|
|
# Create the Ansible module
|
2021-04-10 10:59:25 +00:00
|
|
|
self.module = AnsibleModule(
|
2022-07-29 08:47:49 +00:00
|
|
|
argument_spec=AnsibleNioModule.__common_argument_spec(custom_spec),
|
2021-04-10 10:59:25 +00:00
|
|
|
bypass_checks=bypass_checks,
|
|
|
|
no_log=no_log,
|
|
|
|
mutually_exclusive=mutually_exclusive,
|
|
|
|
required_together=required_together,
|
|
|
|
required_one_of=required_one_of,
|
|
|
|
add_file_common_args=add_file_common_args,
|
2022-07-29 08:47:49 +00:00
|
|
|
supports_check_mode=supports_check_mode,
|
2021-04-10 10:59:25 +00:00
|
|
|
required_if=required_if,
|
|
|
|
required_by=required_by
|
|
|
|
)
|
2022-07-29 08:47:49 +00:00
|
|
|
|
|
|
|
# Make some values from the module easly accessible
|
2021-04-10 10:59:25 +00:00
|
|
|
self.check_mode = self.module.check_mode
|
2022-07-29 08:47:49 +00:00
|
|
|
self.params = self.module.params
|
2021-04-10 10:59:25 +00:00
|
|
|
|
2022-07-29 08:47:49 +00:00
|
|
|
# Fail when matix-nio is not installed
|
|
|
|
# WARNING: We don't perform a version check!
|
2021-04-10 10:59:25 +00:00
|
|
|
if not HAS_LIB:
|
|
|
|
self.module.fail_json(msg=missing_required_lib("matrix-nio"))
|
|
|
|
|
|
|
|
async def matrix_login(self):
|
2022-07-29 08:47:49 +00:00
|
|
|
# Login with token or supplied user account
|
2021-04-10 10:59:25 +00:00
|
|
|
if self.module.params['token'] is None:
|
|
|
|
self.client = AsyncClient(self.module.params['hs_url'], self.module.params['user_id'])
|
2022-07-29 08:47:49 +00:00
|
|
|
login_response = await self.client.login(password=self.module.params['password'])
|
2021-04-10 10:59:25 +00:00
|
|
|
else:
|
|
|
|
self.client = AsyncClient(self.module.params['hs_url'])
|
2022-07-29 08:47:49 +00:00
|
|
|
login_response = await self.client.login(token=self.module.params['token'])
|
|
|
|
if isinstance(login_response, LoginResponse):
|
|
|
|
self.access_token = login_response.access_token
|
|
|
|
self.device_id = login_response.device_id
|
|
|
|
else:
|
|
|
|
result = {
|
|
|
|
'msg': login_response.message,
|
|
|
|
'http_status_code': login_response.status_code
|
|
|
|
}
|
|
|
|
self.module.fail_json(**result)
|
2021-04-10 10:59:25 +00:00
|
|
|
|
|
|
|
async def matrix_logout(self):
|
|
|
|
if self.client.logged_in:
|
2022-07-29 08:47:49 +00:00
|
|
|
request = await self.client.logout()
|
|
|
|
if isinstance(request, LogoutError):
|
|
|
|
result = {'msg': request.message}
|
|
|
|
self.module.fail_json(**result)
|
2021-04-10 10:59:25 +00:00
|
|
|
|
|
|
|
async def exit_json(self, **result):
|
2022-07-29 08:47:49 +00:00
|
|
|
if self.module.params['token'] is None and self.user_logout is True:
|
2021-04-10 10:59:25 +00:00
|
|
|
await self.matrix_logout()
|
|
|
|
await self.client.close()
|
|
|
|
self.module.exit_json(**result)
|
|
|
|
|
2021-04-28 09:22:42 +00:00
|
|
|
async def fail_json(self, **result):
|
2022-07-29 08:47:49 +00:00
|
|
|
if self.module.params['token'] is None and self.user_logout is True:
|
2021-04-10 10:59:25 +00:00
|
|
|
await self.matrix_logout()
|
|
|
|
await self.client.close()
|
2021-04-28 09:22:42 +00:00
|
|
|
self.module.fail_json(**result)
|
2021-04-10 10:59:25 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def __common_argument_spec(custom_spec: dict):
|
|
|
|
argument_spec = dict(
|
|
|
|
hs_url=dict(type='str', required=True),
|
|
|
|
user_id=dict(type='str', required=False),
|
|
|
|
password=dict(type='str', required=False, no_log=True),
|
|
|
|
token=dict(type='str', required=False, no_log=True)
|
|
|
|
)
|
|
|
|
return {**argument_spec, **custom_spec}
|