Compare commits

..

4 Commits

Author SHA1 Message Date
991b8c635c chore: bump version to 0.4.0
- Adds the role `ldap_user_backend` for managing ldap authentication backends in nextcloud
- Allow checking integrity of nextcloud apps
- Allow specifying type for server settings, avoid leaking secrets in ansible task names
2021-11-26 07:57:16 +01:00
63f45dc193 chore(server): do not leak secrets in ansible task names 2021-11-26 07:55:46 +01:00
c56b82121b chore(server): do not check mode when retrieving current config setting 2021-11-26 07:54:54 +01:00
e46c687b89 feat(ldap-user-backend): add role for managing ldap user backend in nextcloud 2021-11-21 12:39:33 +01:00
8 changed files with 119 additions and 78 deletions

View File

@ -13,6 +13,8 @@ and managing nextcloud installations
- [`roles/apps`](roles/apps/README.md): - [`roles/apps`](roles/apps/README.md):
For managing nextcloud apps in an already installed nextcloud For managing nextcloud apps in an already installed nextcloud
server instance. Can install, remove, enable/disable and update apps. server instance. Can install, remove, enable/disable and update apps.
- [`roles/ldap-user-backend`](roles/ldap-user-backend/README.md):
Manages LDAP authentication sources in installed nextcloud instances.
## License ## License

View File

@ -1,6 +1,6 @@
namespace: finallycoffee namespace: finallycoffee
name: nextcloud name: nextcloud
version: 0.3.0 version: 0.4.0
readme: README.md readme: README.md
authors: authors:
- Johanna Dorothea Reichmann <transcaffeine@finallycoffee.eu> - Johanna Dorothea Reichmann <transcaffeine@finallycoffee.eu>

View File

@ -25,3 +25,13 @@ nextcloud app installed. For starting a nextcloud instance, see the
the URL to the nextcloud server, including protocol (and port, if the URL to the nextcloud server, including protocol (and port, if
non-standard), and `nc_ldap_api_basic_auth_[user|password]` contain the non-standard), and `nc_ldap_api_basic_auth_[user|password]` contain the
credentials of an admin user with the rights to edit the LDAP settings. credentials of an admin user with the rights to edit the LDAP settings.
- Set `nc_ldap_test_configuration` to `true`/`false` to have the role issue a
nextcloud-provided test of the configured LDAP configuration, this corresponds
to a `occ ldap:test-config <id>`.
For most of the options, see the
[nextcloud manual on configuration keys](https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_auth_ldap_api.html#configuration-keys),
the config keys are mapped 1:1 with a prefix of `nc_ldap_config_` and
the so-called "snake-case" (`ldap_backup_host`), so `ldapUserFilterMode` becomes
`nc_ldap_config_ldap_user_filter_mode`.

View File

@ -1,6 +1,7 @@
--- ---
nc_ldap_api_method: occ nc_ldap_api_method: occ
nc_ldap_test_configuration: true
nc_ldap_api_instance_url: http://localhost nc_ldap_api_instance_url: http://localhost
nc_ldap_api_basic_auth_user: nc_ldap_api_basic_auth_user:

View File

@ -0,0 +1,49 @@
---
- name: Set default api parameters for HTTP
meta: noop
vars: &api_defaults
http_agent: "{{ nc_ldap_meta_http_agent }}"
headers: "{{ nc_ldap_api_headers }}"
url_username: "{{ nc_ldap_api_basic_auth_user }}"
url_password: "{{ nc_ldap_api_basic_auth_password }}"
force_basic_auth: yes
force: yes
- name: Check if configuration with given config ID already exists
uri:
<<: *api_defaults
url: "{{ nc_ldap_api_path }}/{{ nc_ldap_config_id }}{{ query_params }}"
method: GET
vars:
query_params: "?showPassword={{ '1' if nc_ldap_config_agent_password else '0' }}&format={{nc_ldap_api_parameter_format }}"
register: nc_ldap_existing_config_api
# TODO: Can we force an ID on POST?
- name: Create ldap configuration with id={{ nc_ldap_config_id }}
uri:
<<: *api_defaults
url: "{{ nc_ldap_api_path }}"
method: POST
when: nc_ldap_existing_config_api.status != 200
- name: Parse output of query command to dict
set_fact:
nc_ldap_existing_config: "{{ nc_ldap_existing_config_api.stdout | from_json }}"
changed_when: false
- name: Create changeset
set_fact:
nc_ldap_config_changeset: "{{ nc_ldap_config_changeset | combine(changed_entry) }}"
vars:
changed_entry: "{{ { item : nc_ldap_config_keys[item] } }}"
loop: "{{ nc_ldap_config_keys.keys() }}"
when: nc_ldap_config_keys[item] is defined and nc_ldap_config_keys[item] and nc_ldap_config_keys[item] != nc_ldap_existing_config[nc_ldap_config_id][item]
- name: Ensure ldap configuration is in sync (http)
uri:
<<: *api_defaults
url: "{{ nc_lap_api_path }}/{{ nc_ldap_config_id }}"
method: PUT
body: "{{ { 'configData': nc_ldap_config_changeset } }}"
body_format: "form-urlencoded"

View File

@ -0,0 +1,49 @@
---
- name: Check if configuration with given config ID already exists
docker_container_exec:
container: "{{ nc_ldap_container }}"
command: "{{ nc_ldap_occ_command }} ldap:show-config --output json {{ '--show-password' if nc_ldap_config_agent_password else '' }} {{ nc_ldap_config_id }}"
user: "{{ nc_ldap_occ_user }}"
tty: yes
changed_when: false
check_mode: false
register: nc_ldap_existing_config_occ
- name: Create ldap configuration with id={{ nc_ldap_config_id }}
docker_container_exec:
container: "{{ nc_ldap_container }}"
command: "{{ nc_ldap_occ_command }} ldap:create-empty-config --output json {{ nc_ldap_config_id }}"
user: "{{ nc_ldap_occ_user }}"
tty: yes
when: nc_ldap_existing_config_occ.rc != 0 and nc_ldap_config_id not in (nc_ldap_existing_config_occ.stdout | from_json).keys()
- name: Parse output of query command to dict
set_fact:
nc_ldap_existing_config: "{{ nc_ldap_existing_config_occ.stdout | from_json }}"
changed_when: false
- name: Create changeset
set_fact:
nc_ldap_config_changeset: "{{ nc_ldap_config_changeset | combine(changed_entry) }}"
vars:
changed_entry: "{{ { item : nc_ldap_config_keys[item] } }}"
loop: "{{ nc_ldap_config_keys.keys() }}"
when: nc_ldap_config_keys[item] is defined and nc_ldap_config_keys[item] and nc_ldap_config_keys[item] != nc_ldap_existing_config[nc_ldap_config_id][item]
- name: Ensure ldap configuration is in sync
docker_container_exec:
container: "{{ nc_ldap_container }}"
command: "{{ nc_ldap_occ_command }} ldap:set-config \"{{ nc_ldap_config_id }}\" \"{{ item.key }}\" \"{{ item.value }}\""
user: "{{ nc_ldap_occ_user }}"
tty: yes
loop: "{{ nc_ldap_config_changeset | dict2items }}"
- name: Ensure ldap configuration is working
docker_container_exec:
container: "{{ nc_ldap_container }}"
command: "{{ nc_ldap_occ_command }} ldap:test-config {{ nc_ldap_config_id }}"
user: "{{ nc_ldap_occ_user }}"
tty: yes
changed_when: false
when: nc_ldap_test_configuration

View File

@ -1,81 +1,10 @@
--- ---
- name: Set default api parameters for HTTP - name: Load config {{ nc_ldap_config_id }} (and create if not exists) when running mode is http
meta: noop include_tasks: load_config_http.yml
vars: &api_defaults
http_agent: "{{ nc_ldap_meta_http_agent }}"
headers: "{{ nc_ldap_api_headers }}"
url_username: "{{ nc_ldap_api_basic_auth_user }}"
url_password: "{{ nc_ldap_api_basic_auth_password }}"
force_basic_auth: yes
force: yes
when: nc_ldap_api_method == 'http' when: nc_ldap_api_method == 'http'
- name: Check if configuration with given config ID already exists (occ) - name: Load config {{ nc_ldap_config_id }} (and create if not exists) when running mode is occ
docker_container_exec: include_tasks: load_config_occ.yml
container: "{{ nc_ldap_container }}"
command: "{{ nc_ldap_occ_command }} ldap:show-config --output json {{ '--show-password' if nc_ldap_config_agent_password else '' }} {{ nc_ldap_config_id }}"
user: "{{ nc_ldap_occ_user }}"
tty: yes
when: nc_ldap_api_method == 'occ' when: nc_ldap_api_method == 'occ'
changed_when: false
check_mode: false
register: nc_ldap_existing_config_occ
- name: Check if configuration with given config ID already exists (http)
uri:
<<: *api_defaults
url: "{{ nc_ldap_api_path }}/{{ nc_ldap_config_id }}{{ query_params }}"
method: GET
vars:
query_params: "?showPassword={{ '1' if nc_ldap_config_agent_password else '0' }}&format={{nc_ldap_api_parameter_format }}"
when: nc_ldap_api_method == 'http'
register: nc_ldap_existing_config_api
# TODO: Can we force an ID on POST?
- name: Create ldap configuration with id={{ nc_ldap_config_id }} (http)
uri:
<<: *api_defaults
url: "{{ nc_ldap_api_path }}"
method: POST
when: nc_ldap_api_method == 'http' and nc_ldap_existing_config_api.status != 200
- name: Create ldap configuration with id={{ nc_ldap_config_id }} (occ)
docker_container_exec:
container: "{{ nc_ldap_container }}"
command: "{{ nc_ldap_occ_command }} ldap:create-empty-config --output json {{ nc_ldap_config_id }}"
user: "{{ nc_ldap_occ_user }}"
tty: yes
when: nc_ldap_api_method == 'occ' and nc_ldap_existing_config_occ.rc != 0 and nc_ldap_config_id not in (nc_ldap_existing_config_occ.stdout | from_json).keys()
- name: Parse output of query command to dict
set_fact:
nc_ldap_existing_config: "{{ nc_ldap_existing_config_occ.stdout | from_json }}"
changed_when: false
- name: Create changeset
set_fact:
nc_ldap_config_changeset: "{{ nc_ldap_config_changeset | combine(changed_entry) }}"
vars:
changed_entry: "{{ { item : nc_ldap_config_keys[item] } }}"
loop: "{{ nc_ldap_config_keys.keys() }}"
when: nc_ldap_config_keys[item] is defined and nc_ldap_config_keys[item] and nc_ldap_config_keys[item] != nc_ldap_existing_config[nc_ldap_config_id][item]
- name: Ensure ldap configuration is in sync (http)
uri:
<<: *api_defaults
url:
method: PUT
body:
body_format: "form-urlencoded"
loop: "{{ nc_ldap_config_changeset | dict2items }}"
when: nc_ldap_api_method == 'http'
- name: Ensure ldap configuration is in sync (occ)
docker_container_exec:
container: "{{ nc_ldap_container }}"
command: "{{ nc_ldap_occ_command }} ldap:set-config \"{{ nc_ldap_config_id }}\" \"{{ item.key }}\" \"{{ item.value }}\""
user: "{{ nc_ldap_occ_user }}"
tty: yes
loop: "{{ nc_ldap_config_changeset | dict2items }}"
when: nc_ldap_api_method == 'occ'

View File

@ -1,6 +1,6 @@
--- ---
- name: Ensure {{ key }} is set to {{ value }} - name: Ensure {{ key }} is set to {{ '***' if ['pass', 'secret', 'key']|select('in', key) else value }}
block: block:
- name: Check value of {{ key }} - name: Check value of {{ key }}
community.docker.docker_container_exec: community.docker.docker_container_exec:
@ -9,9 +9,10 @@
user: "{{ nextcloud_user_info.uid }}" user: "{{ nextcloud_user_info.uid }}"
tty: yes tty: yes
register: nextcloud_current_config_entry register: nextcloud_current_config_entry
check_mode: false
changed_when: false changed_when: false
- name: Set {{ key }} to {{ value }} - name: Set {{ key }} to {{ '***' if (['pass', 'secret', 'key']|select('in', key)) else value }}
community.docker.docker_container_exec: community.docker.docker_container_exec:
container: "{{ nextcloud_container_name }}" container: "{{ nextcloud_container_name }}"
command: "{{ nextcloud_occ_command }} config:{{ type }}:set {{ scope }} {{ entry }} --type={{ value_type }} --value={{ value }} -n" command: "{{ nextcloud_occ_command }} config:{{ type }}:set {{ scope }} {{ entry }} --type={{ value_type }} --value={{ value }} -n"