summaryrefslogtreecommitdiff
path: root/roles
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2024-08-27 23:34:37 +0200
committerChristian Pointner <equinox@spreadspace.org>2024-08-27 23:34:47 +0200
commitc704534f80d7b724472f8b940e23fb8d00c44ef8 (patch)
tree374e16844188ce89188bbb243276064e66739c75 /roles
parentdisable playbook for sk-tomnext-nc (diff)
onlyoffice: migrate app to generic storage and new publish framework
Diffstat (limited to 'roles')
-rw-r--r--roles/apps/onlyoffice/defaults/main.yml25
-rw-r--r--roles/apps/onlyoffice/instance/tasks/main.yml88
-rw-r--r--roles/apps/onlyoffice/instance/templates/pod-spec.yml.j275
-rw-r--r--roles/apps/onlyoffice/tasks/main.yml152
-rw-r--r--roles/apps/onlyoffice/templates/pod-spec.yml.j2102
5 files changed, 174 insertions, 268 deletions
diff --git a/roles/apps/onlyoffice/defaults/main.yml b/roles/apps/onlyoffice/defaults/main.yml
index 1ea4773a..7e33368d 100644
--- a/roles/apps/onlyoffice/defaults/main.yml
+++ b/roles/apps/onlyoffice/defaults/main.yml
@@ -1,30 +1,21 @@
---
-# onlyoffice_app_uid: "960"
-# onlyoffice_app_gid: "960"
-
-onlyoffice_db_uid: "961"
-onlyoffice_db_gid: "961"
-
-# onlyoffice_amqp_uid: "962"
-# onlyoffice_amqp_gid: "962"
-
-# onlyoffice_base_path: /srv/onlyoffice
-
-# onlyoffice_zfs:
-# pool: storage
-# name: onlyoffice
-# properties:
-# compression: lz4
-
# onlyoffice_instances:
# example:
# version: 6.2.1.24
# port: 8600
# hostname: office.example.com
# jwt_secret: very-secure-password
+# storage:
+# type: ...
# database:
# version: 9.5.25
# password: secret
# amqp:
# version: 3.8.14
# password: secret
+# publish:
+# zone: "{{ apps_publish_zone__foo }}"
+# hostnames:
+# - office.example.com
+# tls:
+# certificate_provider: ...
diff --git a/roles/apps/onlyoffice/instance/tasks/main.yml b/roles/apps/onlyoffice/instance/tasks/main.yml
new file mode 100644
index 00000000..2ca6026d
--- /dev/null
+++ b/roles/apps/onlyoffice/instance/tasks/main.yml
@@ -0,0 +1,88 @@
+---
+- name: prepare storage volume
+ vars:
+ storage_volume: "{{ onlyoffice_instances[onlyoffice_instance].storage }}"
+ include_role:
+ name: "storage/{{ onlyoffice_instances[onlyoffice_instance].storage.type }}/volume"
+
+- set_fact:
+ onlyoffice_instance_basepath: "{{ storage_volume_mountpoint }}"
+
+- name: create onlyoffice database subdirectory
+ file:
+ path: "{{ onlyoffice_instance_basepath }}/postgres"
+ state: directory
+
+- name: create onlyoffice tls subdirectory
+ file:
+ path: "{{ onlyoffice_instance_basepath }}/tls"
+ state: directory
+ mode: 0700
+
+- name: generate/install TLS certificates for publishment
+ vars:
+ x509_certificate_name: "onlyoffice-{{ onlyoffice_instance }}_publish"
+ x509_certificate_hostnames: []
+ x509_certificate_config:
+ ca: "{{ onlyoffice_instances[onlyoffice_instance].publish.zone.certificate_ca_config }}"
+ cert:
+ common_name: "onlyoffice-{{ onlyoffice_instance }}.{{ inventory_hostname }}"
+ extended_key_usage:
+ - serverAuth
+ extended_key_usage_critical: yes
+ create_subject_key_identifier: yes
+ not_after: +100w
+ x509_certificate_renewal:
+ install:
+ - dest: "{{ onlyoffice_instance_basepath }}/tls/onlyoffice.crt"
+ src:
+ - cert
+ mode: "0400"
+ - dest: "{{ onlyoffice_instance_basepath }}/tls/onlyoffice.key"
+ src:
+ - key
+ mode: "0400"
+ include_role:
+ name: "x509/{{ onlyoffice_instances[onlyoffice_instance].publish.zone.certificate_provider }}/cert"
+
+- name: install pod manifest
+ vars:
+ kubernetes_standalone_pod:
+ name: "onlyoffice-{{ onlyoffice_instance }}"
+ spec: "{{ lookup('template', 'pod-spec.yml.j2') }}"
+ mode: "0600"
+ include_role:
+ name: kubernetes/standalone/pod
+
+- name: configure nginx vhost for publishment
+ vars:
+ nginx_vhost__yaml: |
+ name: "onlyoffice-{{ onlyoffice_instance }}.{{ inventory_hostname }}"
+ template: generic
+ {% if 'tls' in onlyoffice_instances[onlyoffice_instance].publish %}
+ tls:
+ {{ onlyoffice_instances[onlyoffice_instance].publish.tls | to_nice_yaml(indent=2) | indent(2) }}
+ {% endif %}
+ hostnames:
+ {% for hostname in onlyoffice_instances[onlyoffice_instance].publish.hostnames %}
+ - {{ hostname }}
+ {% endfor %}
+ locations:
+ '/':
+ {% if onlyoffice_instances[onlyoffice_instance].publish.zone.publisher == inventory_hostname %}
+ proxy_pass: "https://127.0.0.1:{{ onlyoffice_instances[onlyoffice_instance].port }}"
+ {% else %}
+ proxy_pass: "https://{{ ansible_default_ipv4.address }}:{{ onlyoffice_instances[onlyoffice_instance].port }}"
+ {% endif %}
+ proxy_ssl:
+ trusted_certificate: "/etc/ssl/apps-publish-{{ onlyoffice_instances[onlyoffice_instance].publish.zone.name }}/apps-publish-{{ onlyoffice_instances[onlyoffice_instance].publish.zone.name }}-ca-crt.pem"
+ verify: "on"
+ name: "onlyoffice-{{ onlyoffice_instance }}.{{ inventory_hostname }}"
+ protocols: "TLSv1.2 TLSv1.3"
+ extra_directives: |-
+ client_max_body_size 0;
+ nginx_vhost: "{{ nginx_vhost__yaml | from_yaml }}"
+ include_role:
+ name: nginx/vhost
+ apply:
+ delegate_to: "{{ onlyoffice_instances[onlyoffice_instance].publish.zone.publisher }}"
diff --git a/roles/apps/onlyoffice/instance/templates/pod-spec.yml.j2 b/roles/apps/onlyoffice/instance/templates/pod-spec.yml.j2
new file mode 100644
index 00000000..ec70f8c1
--- /dev/null
+++ b/roles/apps/onlyoffice/instance/templates/pod-spec.yml.j2
@@ -0,0 +1,75 @@
+terminationGracePeriodSeconds: 120
+containers:
+- name: documentserver
+ image: "onlyoffice/documentserver:{{ onlyoffice_instances[onlyoffice_instance].version }}"
+ resources:
+ limits:
+ memory: "4Gi"
+ env:
+ - name: "DB_TYPE"
+ value: "postgres"
+ - name: "DB_HOST"
+ value: "127.0.0.1"
+ - name: "DB_PORT"
+ value: "5432"
+ - name: "DB_NAME"
+ value: "onlyoffice"
+ - name: "DB_USER"
+ value: "onlyoffice"
+ - name: "DB_PWD"
+ value: "{{ onlyoffice_instances[onlyoffice_instance].database.password }}"
+ - name: "AMQP_TYPE"
+ value: "rabbitmq"
+ - name: "AMQP_URI"
+ value: "amqp://onlyoffice:{{ onlyoffice_instances[onlyoffice_instance].amqp.password }}@127.0.0.1:5672"
+ - name: "JWT_ENABLED"
+ value: "true"
+ - name: "JWT_SECRET"
+ value: "{{ onlyoffice_instances[onlyoffice_instance].jwt_secret }}"
+ volumeMounts:
+ - name: tls
+ mountPath: /var/www/onlyoffice/Data/certs/
+ readOnly: true
+ ports:
+ - containerPort: 443
+ hostPort: {{ onlyoffice_instances[onlyoffice_instance].port }}
+ hostIP: 127.0.0.1
+
+- name: postgresql
+ image: "postgres:{{ onlyoffice_instances[onlyoffice_instance].database.version }}"
+ args:
+ - postgres
+ - -c
+ - listen_addresses=127.0.0.1
+ env:
+ - name: "POSTGRES_DB"
+ value: "onlyoffice"
+ - name: "POSTGRES_USER"
+ value: "onlyoffice"
+ - name: "POSTGRES_PASSWORD"
+ value: "{{ onlyoffice_instances[onlyoffice_instance].database.password }}"
+ volumeMounts:
+ - name: postgres
+ mountPath: /var/lib/postgresql/data
+
+- name: rabbitmq
+ image: "rabbitmq:{{ onlyoffice_instances[onlyoffice_instance].amqp.version }}"
+ env:
+ - name: "RABBITMQ_NODENAME"
+ value: "rabbit@localhost"
+ - name: "RABBITMQ_NODE_IP_ADDRESS"
+ value: "127.0.0.1"
+ - name: "RABBITMQ_DEFAULT_USER"
+ value: "onlyoffice"
+ - name: "RABBITMQ_DEFAULT_PASS"
+ value: "{{ onlyoffice_instances[onlyoffice_instance].amqp.password }}"
+
+volumes:
+- name: tls
+ hostPath:
+ path: "{{ onlyoffice_instance_basepath }}/tls"
+ type: Directory
+- name: postgres
+ hostPath:
+ path: "{{ onlyoffice_instance_basepath }}/postgres"
+ type: Directory
diff --git a/roles/apps/onlyoffice/tasks/main.yml b/roles/apps/onlyoffice/tasks/main.yml
index 960e811b..a42ee589 100644
--- a/roles/apps/onlyoffice/tasks/main.yml
+++ b/roles/apps/onlyoffice/tasks/main.yml
@@ -1,153 +1,7 @@
---
-- name: create zfs datasets
- when: onlyoffice_zfs is defined
- block:
- - name: create zfs base dataset
- zfs:
- name: "{{ onlyoffice_zfs.pool }}/{{ onlyoffice_zfs.name }}"
- state: present
- extra_zfs_properties: "{{ onlyoffice_zfs.properties | dehumanize_zfs_properties | default(omit) }}"
-
- - name: create zfs volumes for instances
- loop: "{{ onlyoffice_instances | dict2items }}"
- loop_control:
- label: "{{ item.key }} ({{ (item.value.zfs_properties | default({})).items() | map('join', '=') | join(', ') }})"
- zfs:
- name: "{{ onlyoffice_zfs.pool }}/{{ onlyoffice_zfs.name }}/{{ item.key }}"
- state: present
- extra_zfs_properties: "{{ item.value.zfs_properties | dehumanize_zfs_properties | default(omit) }}"
-
- - name: configure onlyoffice base bath
- set_fact:
- onlyoffice_base_path: "{{ (zfs_pools[onlyoffice_zfs.pool].mountpoint, onlyoffice_zfs.name) | path_join }}"
-
-
-- name: create instance subdirectories
- when: onlyoffice_zfs is not defined
+- name: instance specific tasks
loop: "{{ onlyoffice_instances | list }}"
- file:
- path: "{{ onlyoffice_base_path }}/{{ item }}"
- state: directory
-
-
-# TODO: run documentserver components as non-root
-# - name: add group for onlyoffice app
-# group:
-# name: oo-app
-# gid: "{{ onlyoffice_app_gid }}"
-
-# - name: add user for onlyoffice app
-# user:
-# name: oo-app
-# uid: "{{ onlyoffice_app_uid }}"
-# group: oo-app
-# password: "!"
-
-# - name: create onlyoffice app subdirectory
-# loop: "{{ onlyoffice_instances | list }}"
-# file:
-# path: "{{ onlyoffice_base_path }}/{{ item }}/onlyoffice"
-# owner: "{{ onlyoffice_app_uid }}"
-# group: "{{ onlyoffice_app_gid }}"
-# state: directory
-
-
-- name: add group for onlyoffice db
- group:
- name: oo-db
- gid: "{{ onlyoffice_db_gid }}"
-
-- name: add user for onlyoffice db
- user:
- name: oo-db
- uid: "{{ onlyoffice_db_uid }}"
- group: oo-db
- password: "!"
-
-- name: create onlyoffice database subdirectory
- loop: "{{ onlyoffice_instances | dict2items}}"
loop_control:
- label: "{{ item.key }}"
- file:
- path: "{{ onlyoffice_base_path }}/{{ item.key }}/postgres"
- owner: "{{ onlyoffice_db_uid }}"
- group: "{{ onlyoffice_db_gid }}"
- state: directory
-
-
-# TODO: run documentserver components as non-root
-# - name: add group for onlyoffice aqmp
-# group:
-# name: oo-aqmp
-# gid: "{{ onlyoffice_aqmp_gid }}"
-
-# - name: add user for onlyoffice aqmp
-# user:
-# name: oo-aqmp
-# uid: "{{ onlyoffice_aqmp_uid }}"
-# group: oo-aqmp
-# password: "!"
-
-# - name: create onlyoffice aqmp subdirectory
-# loop: "{{ onlyoffice_instances | list }}"
-# file:
-# path: "{{ onlyoffice_base_path }}/{{ item }}/onlyoffice"
-# owner: "{{ onlyoffice_aqmp_uid }}"
-# group: "{{ onlyoffice_aqmp_gid }}"
-# state: directory
-
-# TODO: AQMP config?
-# - name: create onlyoffice rabbitmq subdirectory
-# loop: "{{ onlyoffice_instances | dict2items}}"
-# loop_control:
-# label: "{{ item.key }}"
-# file:
-# path: "{{ onlyoffice_base_path }}/{{ item.key }}/rabbitmq"
-# state: directory
-
-# - name: install rabbitmq config snipped
-# loop: "{{ onlyoffice_instances | dict2items}}"
-# loop_control:
-# label: "{{ item.key }}"
-# copy:
-# dest: "{{ onlyoffice_base_path }}/{{ item.key }}/rabbitmq/config"
-# content: |
-# management.tcp.ip = 127.0.0.1
-
-
-- name: install pod manifest
- loop: "{{ onlyoffice_instances | dict2items }}"
- loop_control:
- label: "{{ item.key }}"
- vars:
- kubernetes_standalone_pod:
- name: "onlyoffice-{{ item.key }}"
- spec: "{{ lookup('template', 'pod-spec.yml.j2') }}"
- mode: "0600"
-# TODO: AQMP config?
-# config_hash_items:
-# - path: "{{ onlyoffice_base_path }}/{{ item.key }}/rabbitmq/config"
-# properties:
-# - checksum
- include_role:
- name: kubernetes/standalone/pod
-
-- name: configure nginx vhost
- loop: "{{ onlyoffice_instances | dict2items }}"
- loop_control:
- label: "{{ item.key }}"
- vars:
- nginx_vhost:
- name: "onlyoffice-{{ item.key }}"
- template: generic
- tls:
- certificate_provider: "{{ acme_client }}"
- hostnames:
- - "{{ item.value.hostname }}"
- locations:
- '/':
- proxy_pass: "http://127.0.0.1:{{ item.value.port }}"
- extra_directives: |-
- client_max_body_size 0;
+ loop_var: onlyoffice_instance
include_role:
- name: nginx/vhost
+ name: apps/onlyoffice/instance
diff --git a/roles/apps/onlyoffice/templates/pod-spec.yml.j2 b/roles/apps/onlyoffice/templates/pod-spec.yml.j2
deleted file mode 100644
index 620e0d18..00000000
--- a/roles/apps/onlyoffice/templates/pod-spec.yml.j2
+++ /dev/null
@@ -1,102 +0,0 @@
-{# TODO:
-securityContext:
- allowPrivilegeEscalation: false
-#}
-terminationGracePeriodSeconds: 120
-containers:
-{# TODO: only listen to localhost #}
-- name: documentserver
- image: "onlyoffice/documentserver:{{ item.value.version }}"
- resources:
- limits:
- memory: "4Gi"
-{# TODO:
- securityContext:
- allowPrivilegeEscalation: false
- runAsUser: {{ onlyoffice_amqp_uid }}
- runAsGroup: {{ onlyoffice_amqp_gid }}
-#}
- env:
- - name: "DB_TYPE"
- value: "postgres"
- - name: "DB_HOST"
- value: "127.0.0.1"
- - name: "DB_PORT"
- value: "5432"
- - name: "DB_NAME"
- value: "onlyoffice"
- - name: "DB_USER"
- value: "onlyoffice"
- - name: "DB_PWD"
- value: "{{ item.value.database.password }}"
- - name: "AMQP_TYPE"
- value: "rabbitmq"
- - name: "AMQP_URI"
- value: "amqp://onlyoffice:{{ item.value.amqp.password }}@127.0.0.1:5672"
- - name: "JWT_ENABLED"
- value: "true"
- - name: "JWT_SECRET"
- value: "{{ item.value.jwt_secret }}"
- ports:
- - containerPort: 80
- hostPort: {{ item.value.port }}
- hostIP: 127.0.0.1
-
-- name: postgresql
- image: "postgres:{{ item.value.database.version }}"
- args:
- - postgres
- - -c
- - listen_addresses=127.0.0.1
- securityContext:
- allowPrivilegeEscalation: false
- runAsUser: {{ onlyoffice_db_uid }}
- runAsGroup: {{ onlyoffice_db_gid }}
- env:
- - name: "POSTGRES_DB"
- value: "onlyoffice"
- - name: "POSTGRES_USER"
- value: "onlyoffice"
- - name: "POSTGRES_PASSWORD"
- value: "{{ item.value.database.password }}"
- volumeMounts:
- - name: postgres
- mountPath: /var/lib/postgresql/data
-
-{# TODO: only listen to localhost #}
-- name: rabbitmq
- image: "rabbitmq:{{ item.value.amqp.version }}"
-{# TODO:
- securityContext:
- allowPrivilegeEscalation: false
- runAsUser: {{ onlyoffice_amqp_uid }}
- runAsGroup: {{ onlyoffice_amqp_gid }}
-#}
- env:
- - name: "RABBITMQ_NODENAME"
- value: "rabbit@localhost"
- - name: "RABBITMQ_NODE_IP_ADDRESS"
- value: "127.0.0.1"
- - name: "RABBITMQ_DEFAULT_USER"
- value: "onlyoffice"
- - name: "RABBITMQ_DEFAULT_PASS"
- value: "{{ item.value.amqp.password }}"
-{# TODO: AQMP config?
- volumeMounts:
- - name: rabbitmq
- mountPath: /etc/rabbitmq/conf.d/k8s.conf
- subPath: config
- readOnly: true
-#}
-
-volumes:
-- name: postgres
- hostPath:
- path: "{{ onlyoffice_base_path }}/{{ item.key }}/postgres"
- type: Directory
-{# TODO: AQMP config?
-- name: rabbitmq
- hostPath:
- path: "{{ onlyoffice_base_path }}/{{ item.key }}/rabbitmq"
- type: Directory
-#}