Compare commits
1 Commits
e8e3bc8859
...
021028d238
Author | SHA1 | Date | |
---|---|---|---|
021028d238 |
@ -4,10 +4,6 @@
|
|||||||
|
|
||||||
Roles for deploying matrix infrastructure using ansible.
|
Roles for deploying matrix infrastructure using ansible.
|
||||||
|
|
||||||
## Modules
|
|
||||||
|
|
||||||
- [`synapse_signing_key`](plugins/modules/synapse_signing_key.md): Module for managing / generating synapse signing keys
|
|
||||||
|
|
||||||
## Roles
|
## Roles
|
||||||
|
|
||||||
- [`cinny`](roles/cinny/README.md): [Cinny](https://cinny.in/) Web Client
|
- [`cinny`](roles/cinny/README.md): [Cinny](https://cinny.in/) Web Client
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
# `finallycoffee.matrix.synapse_signing_key` module
|
|
||||||
|
|
||||||
Module to generate and manage synapse signing keys.
|
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
> Supports `check mode` and `diff` rendering
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
- `python >= 3.9`
|
|
||||||
- `signed_json >= 1.1.4`
|
|
||||||
|
|
||||||
|
|
||||||
## Usage examples
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Generate a key
|
|
||||||
- finallycoffee.matrix.synapse_signing_key:
|
|
||||||
path: "/not/there/yet/signing.key"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# Read a key from the filesystem or generate one
|
|
||||||
- finallycoffee.matrix.synapse_signing_key:
|
|
||||||
path: "/maybe/existing/signing/key"
|
|
||||||
register: key_result
|
|
||||||
- debug:
|
|
||||||
msg: "Signing key is '{{ key_result.signing_key }}'"
|
|
||||||
|
|
||||||
# Delete an existing signing key file
|
|
||||||
- finallycoffee.matrix.synapse_signing_key:
|
|
||||||
path: "/path/to/key/to/delete.key"
|
|
||||||
state: absent
|
|
||||||
```
|
|
@ -1,139 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import os
|
|
||||||
import traceback
|
|
||||||
import random, string
|
|
||||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
|
||||||
|
|
||||||
from dataclasses import asdict
|
|
||||||
|
|
||||||
LIB_IMPORT_ERR = None
|
|
||||||
try:
|
|
||||||
from signedjson.key import *
|
|
||||||
HAS_LIB = True
|
|
||||||
except:
|
|
||||||
HAS_LIB = False
|
|
||||||
LIB_IMPORT_ERR = traceback.format_exc()
|
|
||||||
|
|
||||||
DOCUMENTION = r"""
|
|
||||||
---
|
|
||||||
module: synapse_signing_key
|
|
||||||
author:
|
|
||||||
- transcaffeine (transcaffeine@finally.coffee)
|
|
||||||
requirements:
|
|
||||||
- python >= 3.9
|
|
||||||
- signed_json >= 1.1.4
|
|
||||||
short_description: Generate and persist a synapse signing key
|
|
||||||
description:
|
|
||||||
- "Allows to generate, save and manipulate synapse signing keys"
|
|
||||||
options:
|
|
||||||
path:
|
|
||||||
description: "Where the signing key is saved or read from"
|
|
||||||
type: str
|
|
||||||
required: false
|
|
||||||
state:
|
|
||||||
description: "State of the key to enforce, can be used to remove keys or generate them"
|
|
||||||
type: str
|
|
||||||
choices: [present, absent]
|
|
||||||
default: present
|
|
||||||
required: false
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = r"""
|
|
||||||
- name: Read existing signing key from filesystem
|
|
||||||
finallycoffee.matrix.synapse_signing_key:
|
|
||||||
path: "/path/to/existing-synapse.signing.key"
|
|
||||||
- name: Delete existing signing key
|
|
||||||
finallycoffee.matrix.synapse.signing_key:
|
|
||||||
path: "/this/signing/key/will/be/deleted.signing.key"
|
|
||||||
state: absent
|
|
||||||
"""
|
|
||||||
|
|
||||||
RETURN = r"""
|
|
||||||
signing_key:
|
|
||||||
description: Complete synapse signing key
|
|
||||||
returned: always
|
|
||||||
type: str
|
|
||||||
"""
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
_ = dict
|
|
||||||
module = AnsibleModule(
|
|
||||||
argument_spec=_(
|
|
||||||
path=_(required=False, type="str"),
|
|
||||||
state=_(
|
|
||||||
required=False,
|
|
||||||
type="str",
|
|
||||||
default="present",
|
|
||||||
choices=["present", "absent"],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
supports_check_mode=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
result = _(changed=False, diff={}, msg="")
|
|
||||||
failed = False
|
|
||||||
|
|
||||||
if not HAS_LIB:
|
|
||||||
module.fail_json(msg=missing_required_lib("signed_json"), exception=LIB_IMPORT_ERR)
|
|
||||||
|
|
||||||
path = module.params['path']
|
|
||||||
state = module.params['state']
|
|
||||||
existing_key_found = False
|
|
||||||
if path:
|
|
||||||
try:
|
|
||||||
keys = _read_signing_keys(module.params['path'])
|
|
||||||
existing_key_found = True
|
|
||||||
except FileNotFoundError:
|
|
||||||
existing_key_found = False
|
|
||||||
if not existing_key_found:
|
|
||||||
keys = _generate_signing_key()
|
|
||||||
result['changed'] = True
|
|
||||||
|
|
||||||
if not module.check_mode:
|
|
||||||
if state == 'present' and not existing_key_found and path:
|
|
||||||
_save_signing_keys(path, keys)
|
|
||||||
if state == 'absent' and existing_key_found:
|
|
||||||
os.remove(path)
|
|
||||||
result['changed'] = True
|
|
||||||
|
|
||||||
result['diff'] = {
|
|
||||||
"before_header": path,
|
|
||||||
"after_header": path,
|
|
||||||
"before": _render_signing_keys(keys) if existing_key_found else "",
|
|
||||||
"after": "" if state == 'absent' else _render_signing_keys(keys),
|
|
||||||
}
|
|
||||||
result['signing_key'] = _render_signing_keys(keys)
|
|
||||||
|
|
||||||
if failed:
|
|
||||||
module.fail_json(**result)
|
|
||||||
else:
|
|
||||||
module.exit_json(**result)
|
|
||||||
|
|
||||||
def _render_signing_keys(keys) -> str:
|
|
||||||
return "\n".join(_render_signing_key(k) for k in keys)
|
|
||||||
|
|
||||||
def _render_signing_key(key) -> str:
|
|
||||||
key_b64 = encode_signing_key_base64(key)
|
|
||||||
return f"{key.alg} {key.version} {key_b64}"
|
|
||||||
|
|
||||||
def _read_signing_keys(file):
|
|
||||||
with open(file, "r", opener=lambda path, f: os.open(path, f)) as stream:
|
|
||||||
return read_signing_keys(stream)
|
|
||||||
|
|
||||||
def _write_signing_keys(file, keys) -> None:
|
|
||||||
with open(file, "w", opener=lambda path, f: op.open(path, f, mode=0o640)) as stream:
|
|
||||||
write_signing_keys(strea, keys)
|
|
||||||
|
|
||||||
def _generate_signing_key():
|
|
||||||
id = ''
|
|
||||||
for i in range(0, 4):
|
|
||||||
id += random.choice(string.ascii_letters)
|
|
||||||
key_id = "a_" + id
|
|
||||||
key = generate_signing_key(key_id)
|
|
||||||
return [key]
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -18,5 +18,3 @@ synapse_logging_config_file: >-
|
|||||||
{{ synapse_config_path }}/{{ synapse_domain }}.log.config
|
{{ synapse_config_path }}/{{ synapse_domain }}.log.config
|
||||||
synapse_pid_file: "{{ synapse_data_path }}/homeserver.pid"
|
synapse_pid_file: "{{ synapse_data_path }}/homeserver.pid"
|
||||||
synapse_sqlite_database_file: "{{ synapse_data_path }}/homeserver.db"
|
synapse_sqlite_database_file: "{{ synapse_data_path }}/homeserver.db"
|
||||||
|
|
||||||
synapse_role_generate_signing_key: false
|
|
||||||
|
@ -19,14 +19,3 @@
|
|||||||
when: >-2
|
when: >-2
|
||||||
item not in hostvars[ansible_host]
|
item not in hostvars[ansible_host]
|
||||||
or hostvars[ansible_host][item] | length == 0
|
or hostvars[ansible_host][item] | length == 0
|
||||||
|
|
||||||
- name: Ensure conditionally required variables are given
|
|
||||||
fail:
|
|
||||||
msg: "Required variable '{{ item.name }}' is undefined!"
|
|
||||||
loop: "{{ synapse_conditionally_required_variables }}"
|
|
||||||
loop_control:
|
|
||||||
label: "{{ item.name }}"
|
|
||||||
when: >-2
|
|
||||||
item.when
|
|
||||||
and (item.name not in hostvars[ansible_host]
|
|
||||||
or hostvars[ansible_host][item.name] | length == 0)
|
|
||||||
|
@ -25,12 +25,6 @@
|
|||||||
loop_control:
|
loop_control:
|
||||||
label: "{{ item.path }}"
|
label: "{{ item.path }}"
|
||||||
|
|
||||||
- name: Ensure synapse signing key is generated
|
|
||||||
finallycoffee.matrix.synapse_signing_key:
|
|
||||||
path: "{{ synapse_signing_key_file }}"
|
|
||||||
state: "{{ synapse_state }}"
|
|
||||||
when: synapse_role_generate_signing_key
|
|
||||||
|
|
||||||
- name: Ensure configuration files are templated
|
- name: Ensure configuration files are templated
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
dest: "{{ config_file.path }}"
|
dest: "{{ config_file.path }}"
|
||||||
@ -39,9 +33,7 @@
|
|||||||
owner: "{{ config_file.owner | default(synapse_user_info.uid | default(synapse_user)) }}"
|
owner: "{{ config_file.owner | default(synapse_user_info.uid | default(synapse_user)) }}"
|
||||||
group: "{{ config_file.group | default(synapse_user_info.group | default(synapse_user)) }}"
|
group: "{{ config_file.group | default(synapse_user_info.group | default(synapse_user)) }}"
|
||||||
loop: >-
|
loop: >-
|
||||||
{{ synapse_configs_to_write
|
{{ synapse_configs_to_write + synapse_configs | default([]) }}
|
||||||
+ (synapse_keys_to_write if not synapse_role_generate_signing_key else [])
|
|
||||||
+ synapse_configs | default([]) }}
|
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: config_file
|
loop_var: config_file
|
||||||
label: "{{ config_file.path }}"
|
label: "{{ config_file.path }}"
|
||||||
@ -51,7 +43,6 @@
|
|||||||
path: "{{ synapse_homeserver_config_file }}"
|
path: "{{ synapse_homeserver_config_file }}"
|
||||||
- content: "{{ synapse_log_config | to_nice_yaml(width=1000) }}"
|
- content: "{{ synapse_log_config | to_nice_yaml(width=1000) }}"
|
||||||
path: "{{ synapse_logging_config_file }}"
|
path: "{{ synapse_logging_config_file }}"
|
||||||
synapse_keys_to_write:
|
|
||||||
- content: "{{ synapse_signing_key }}"
|
- content: "{{ synapse_signing_key }}"
|
||||||
path: "{{ synapse_signing_key_file }}"
|
path: "{{ synapse_signing_key_file }}"
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
|
@ -8,7 +8,4 @@ synapse_deployment_methods:
|
|||||||
|
|
||||||
synapse_required_variables:
|
synapse_required_variables:
|
||||||
- synapse_domain
|
- synapse_domain
|
||||||
|
- synapse_signing_key
|
||||||
synapse_conditionally_required_variables:
|
|
||||||
- name: synapse_signing_key
|
|
||||||
when: "{{ not synapse_role_generate_signing_key | bool }}"
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user