Browse Source

Merge branch 'wip-wordpress' into 'master'

wordpress: first implementation

Closes #233

See merge request main/infrastructure!272
keep-around/3d89174795e23a606210eea4b4bd05b2a520598a
Loïc Dachary 12 months ago
parent
commit
3d89174795
  1. 2
      docs/services/index.rst
  2. 2
      docs/services/pad.rst
  3. 16
      docs/services/wordpress.rst
  4. 3
      docs/user-guide.rst
  5. 3
      enough-playbook.yml
  6. 1
      inventory/all.yml
  7. 2
      inventory/host_vars/openedx-host/provision.yml
  8. 17
      inventory/services.yml
  9. 84
      playbooks/openedx/openedx-playbook.yml
  10. 10
      playbooks/openedx/playbook.yml
  11. 6
      playbooks/openedx/roles/openedx/defaults/main.yml
  12. 2
      playbooks/openedx/roles/openedx/tasks/main.yml
  13. 58
      playbooks/openedx/roles/openedx/tasks/openedx.yml
  14. 5
      playbooks/openedx/roles/openedx/templates/crontab
  15. 48
      playbooks/openedx/roles/openedx/templates/docker-compose-infrastructure.yml
  16. 4
      playbooks/wordpress/conftest.py
  17. 4
      playbooks/wordpress/inventory/services.yml
  18. 4
      playbooks/wordpress/inventory/test-hosts.yml
  19. 10
      playbooks/wordpress/playbook.yml
  20. 35
      playbooks/wordpress/roles/wordpress/defaults/main.yml
  21. 2
      playbooks/wordpress/roles/wordpress/tasks/main.yml
  22. 62
      playbooks/wordpress/roles/wordpress/tasks/wordpress.yml
  23. 32
      playbooks/wordpress/roles/wordpress/templates/docker-compose.yml.j2
  24. 3
      playbooks/wordpress/roles/wordpress/templates/uploads.ini.j2
  25. 6
      playbooks/wordpress/tests/test_icinga.py
  26. 8
      playbooks/wordpress/tests/test_wordpress.py
  27. 59
      playbooks/wordpress/wordpress-playbook.yml
  28. 3
      tox.ini

2
docs/services/index.rst

@ -20,3 +20,5 @@ Services
monitoring
backup
jitsi
wordpress

2
docs/services/pad.rst

@ -13,4 +13,4 @@ The service is created on the host specified by the `--host` argument:
.. code::
$ enough --domain example.com service create --host website-host pad
$ enough --domain example.com service create --host pad-host pad

16
docs/services/wordpress.rst

@ -0,0 +1,16 @@
WordPress
=========
`WordPress <https://wordpress.org/>`__ is available at
`wordpress.example.com`. The user with administrative rights and the
contact email are defined as documented in `this file
<https://lab.enough.community/main/infrastructure/blob/master/playbooks/weblate/roles/wordpress/defaults/main.yml>`__
and can be modified in the
`~/.enough/example.com/inventory/group_vars/wordpress-service-group.yml`
file.
The service is created on the host specified by the `--host` argument:
.. code::
$ enough --domain example.com service create --host wordpress-host wordpress

3
docs/user-guide.rst

@ -128,7 +128,8 @@ The following services are available:
* ``forum``, for `discussions and mailing lists <https://www.discourse.org/>`__ at ``forum.example.com``
* ``packages``, a `static web service <https://www.nginx.com/>`__ at ``packages.example.com``
* ``pad``, for `collaborative note taking <https://etherpad.org/>`__ at ``pad.example.com``
* :doc:`weblate <services/weblate>`, for `online translations <https://weblate.org/>`__ at ``weblate.example.com``
* :doc:`Weblate <services/weblate>`, for `online translations <https://weblate.org/>`__ at ``weblate.example.com``
* :doc:`WordPress <services/wordpress>`, for `CMS <https://wordpress.org/>`__ at ``wordpress.example.com``
* ``website``, for `static websites <https://gohugo.io/>`__ at ``website.example.com``
* ``wekan``, for `kanban <https://wekan.github.io/>`__ at ``wekan.example.com``
* :doc:`gitlab <services/gitlab>`, for `software development <https://gitlab.com/>`__ at ``lab.example.com``

3
enough-playbook.yml

@ -9,7 +9,10 @@
- import_playbook: "{{ '$SHARE_DIR/playbooks/cloud/cloud-playbook.yml' | expandvars }}"
- import_playbook: "{{ '$SHARE_DIR/playbooks/enough/enough-playbook.yml' | expandvars }}"
- import_playbook: "{{ '$SHARE_DIR/playbooks/website/website-playbook.yml' | expandvars }}"
when: (groups['website-service-group'] | length) > 0
- import_playbook: "{{ '$SHARE_DIR/playbooks/forum/forum-playbook.yml' | expandvars }}"
- import_playbook: "{{ '$SHARE_DIR/playbooks/wordpress/wordpress-playbook.yml' | expandvars }}"
when: (groups['wordpress-service-group'] | length) > 0
- import_playbook: "{{ '$SHARE_DIR/playbooks/jitsi/jitsi-playbook.yml' | expandvars }}"
when: (groups['jitsi-service-group'] | length) > 0
- import_playbook: "{{ '$SHARE_DIR/playbooks/pad/pad-playbook.yml' | expandvars }}"

1
inventory/all.yml

@ -9,7 +9,6 @@ all-hosts:
gitlab-host:
icinga-host:
jitsi-host:
openedx-host:
packages-host:
postfix-host:
runner-host:

2
inventory/host_vars/openedx-host/provision.yml

@ -1,2 +0,0 @@
---
openstack_flavor: s1-8

17
inventory/services.yml

@ -138,15 +138,6 @@ wekan-service-hosts:
wekan-service-group:
essential-service-group:
openedx-service-group:
hosts:
openedx-host:
openedx-service-hosts:
children:
openedx-service-group:
essential-service-group:
pad-service-group:
hosts: {}
@ -187,3 +178,11 @@ jitsi-service-hosts:
children:
jitsi-service-group:
essential-service-group:
wordpress-service-group:
hosts: {}
wordpress-service-hosts:
children:
wordpress-service-group:
essential-service-group:

84
playbooks/openedx/openedx-playbook.yml

@ -1,84 +0,0 @@
---
- name: firewall for web
hosts: localhost
gather_facts: false
tasks:
- include_role:
name: firewall
vars:
firewall_server: "{{ item }}"
firewall_clients: [ 0.0.0.0/0 ]
firewall_protocols: [ tcp ]
firewall_ports: [ 80, 443 ]
when: hostvars[item].ansible_host is defined
with_items: "{{ groups['openedx-service-group'] | default([]) }}"
- name: setup openedx DNS
hosts: openedx-service-group
become: true
pre_tasks:
- name: set CNAME
nsupdate:
server: "{{ hostvars['bind-host']['ansible_host'] }}"
zone: "{{ domain }}"
record: "openedx.{{ domain }}."
ttl: 1800
type: CNAME
value: "{{ groups['openedx-service-group'][0] }}.{{ domain }}."
delegate_to: bind-host
- name: set CNAME
nsupdate:
server: "{{ hostvars['bind-host']['ansible_host'] }}"
zone: "{{ domain }}"
record: "studio.openedx.{{ domain }}."
ttl: 1800
type: CNAME
value: "{{ groups['openedx-service-group'][0] }}.{{ domain }}."
delegate_to: bind-host
- name: install openedX
hosts: openedx-service-group
become: true
roles:
- role: ansible-role-docker
docker_install_compose: true
- role: docker
- role: openedx
- role: enough-nginx
vars:
enough_nginx_reverse_proxy: 127.0.0.1:{{ openedx_port }}
enough_nginx_fqdn: "openedx.{{ domain }}"
- role: certificate
vars:
certificate_fqdn: "openedx.{{ domain }}"
certificate_installer: nginx
- role: monitor_http_vhost
http_vhost_https: true
http_vhost_name: openedX
http_vhost_fqdn: "openedx.{{ domain }}"
http_vhost_uri: "/"
http_vhost_string: "openedX"
- name: reverse proxy for openedX studio
hosts: openedx-service-group
become: true
roles:
- role: enough-nginx
vars:
enough_nginx_reverse_proxy: 127.0.0.1:8501
enough_nginx_fqdn: "studio.{{ domain }}"
- role: certificate
vars:
certificate_fqdn: "studio.{{ domain }}"
certificate_installer: nginx

10
playbooks/openedx/playbook.yml

@ -1,10 +0,0 @@
---
# - import_playbook: ../infrastructure/buster-playbook.yml
# - import_playbook: ../infrastructure/network-playbook.yml
# - import_playbook: ../firewall/firewall-playbook.yml
# - import_playbook: ../icinga/test-icinga-playbook.yml
# - import_playbook: ../bind/bind-playbook.yml
# - import_playbook: ../bind/bind-client-playbook.yml
# - import_playbook: ../icinga/icinga-playbook.yml
# - import_playbook: ../postfix/postfix-playbook.yml
- import_playbook: openedx-playbook.yml

6
playbooks/openedx/roles/openedx/defaults/main.yml

@ -1,6 +0,0 @@
---
openedx_port: 8500
openedx_root: /srv/openedx
openedx_contact: admin@{{ domain }}
openedx_language: en
openedx_platform_name: Enough

2
playbooks/openedx/roles/openedx/tasks/main.yml

@ -1,2 +0,0 @@
---
- import_tasks: openedx.yml

58
playbooks/openedx/roles/openedx/tasks/openedx.yml

@ -1,58 +0,0 @@
---
- name: apt-get install python3 python3-pip libyaml-dev
apt:
name: [ python3, python3-pip, libyaml-dev ]
state: present
- name: pip install tutor-openedx
pip:
executable: pip3
name: tutor-openedx
- name: "mkdir -p {{ openedx_root }}"
file:
path: "{{ openedx_root }}"
state: directory
owner: debian
group: debian
- name: (re)create openedX
shell: |
tutor local quickstart
- name: configure openedX
shell: |
tutor config save --set ACTIVATE_HTTPS=false \
--set CMS_HOST=studio.{{ domain }} \
--set CONTACT_EMAIL='{{ openedx_contact }}' \
--set LANGUAGE_CODE={{ openedx_language }} \
--set LMS_HOST=openedx.{{ domain }} \
--set PLATFORM_NAME='{{ openedx_platform_name }}' \
--set NGINX_HTTP_PORT={{ openedx_port }} \
--set NGINX_HTTPS_PORT=8543 \
--set SMTP_HOST=openedx-host.{{ domain }} \
--set SMTP_PORt=25
- name: git clone https://github.com/overhangio/indigo
git:
repo: https://github.com/overhangio/indigo
force: yes
dest: "{{ openedx_root }}/indigo"
become: False
- name: install indigo theme
shell: |
set -ex
tutor config render --extra-config ./indigo/config.yml ./indigo/theme "$(tutor config printroot)/env/build/openedx/themes/indigo"
tutor images build openedx
args:
chdir: "{{ openedx_root }}"
- name: (re)create openedX
shell: |
tutor local start -d
- name: activate indigo theme
shell: |
tutor local settheme indigo localhost studio.localhost \
$(tutor config printvalue LMS_HOST) $(tutor config printvalue CMS_HOST)

5
playbooks/openedx/roles/openedx/templates/crontab

@ -1,5 +0,0 @@
MAILTO=""
*/5 * * * * cd {{ weblate_root }}/weblate; flock --timeout 600 /tmp/weblate sudo docker-compose -f docker-compose-infrastructure.yml run --rm weblate update_index
@daily cd {{ weblate_root }}/weblate; flock --timeout 600 /tmp/weblate sudo docker-compose -f docker-compose-infrastructure.yml run --rm weblate cleanuptrans
@hourly cd {{ weblate_root }}/weblate; flock --timeout 600 /tmp/weblate sudo docker-compose -f docker-compose-infrastructure.yml run --rm weblate commit_pending --all --age=1

48
playbooks/openedx/roles/openedx/templates/docker-compose-infrastructure.yml

@ -1,48 +0,0 @@
version: '2'
services:
weblate:
image: weblate/weblate:{{ weblate_version }}
links:
- database
- cache
volumes:
- weblate-data:/app/data
ports:
- '8000:8080'
env_file:
- ./environment
restart: always
depends_on:
- database
- cache
environment:
- WEBLATE_EMAIL_HOST={{ hostvars["postfix-host"]["ansible_host"] }}
- WEBLATE_EMAIL_PORT=465
- WEBLATE_EMAIL_USE_TLS=0
- WEBLATE_EMAIL_USE_SSL=1
- WEBLATE_SERVER_EMAIL={{ weblate_server_email }}
- WEBLATE_DEFAULT_FROM_EMAIL={{ weblate_default_from_email }}
- WEBLATE_ADMIN_NAME=admin
- WEBLATE_ADMIN_EMAIL={{ weblate_admin_email }}
- WEBLATE_ADMIN_PASSWORD={{ weblate_admin_password }}
- WEBLATE_DEBUG=0
- WEBLATE_ENABLE_HTTPS=1
- WEBLATE_ALLOWED_HOSTS=weblate.{{ domain }},{{ hostvars[groups["weblate-service-group"][0]]["ansible_host"] }}
- WEBLATE_REGISTRATION_OPEN=1
database:
image: postgres:9.6-alpine
env_file:
- ./environment
volumes:
- postgres-data:/var/lib/postgresql/data
restart: always
cache:
image: redis:5-alpine
restart: always
command: [ "redis-server", "--appendonly", "yes" ]
volumes:
- redis-data:/data
volumes:
weblate-data: { }
postgres-data: { }
redis-data: { }

4
playbooks/openedx/conftest.py → playbooks/wordpress/conftest.py

@ -3,12 +3,12 @@ def pytest_addoption(parser):
"--enough-hosts",
action="store",
default="bind-host,postfix-host,openedx-host",
default="bind-host,postfix-host,wordpress-host",
help="list of hosts"
)
parser.addoption(
"--enough-service",
action="store",
default="openedx",
default="wordpress",
help="service"
)

4
playbooks/openedx/inventory/services.yml → playbooks/wordpress/inventory/services.yml

@ -6,3 +6,7 @@ icinga-service-group:
postfix-service-group:
hosts:
postfix-host:
wordpress-service-group:
hosts:
wordpress-host:

4
playbooks/wordpress/inventory/test-hosts.yml

@ -0,0 +1,4 @@
---
all-hosts:
hosts:
wordpress-host:

10
playbooks/wordpress/playbook.yml

@ -0,0 +1,10 @@
---
- import_playbook: ../infrastructure/buster-playbook.yml
- import_playbook: ../infrastructure/network-playbook.yml
- import_playbook: ../firewall/firewall-playbook.yml
- import_playbook: ../icinga/test-icinga-playbook.yml
- import_playbook: ../bind/bind-playbook.yml
- import_playbook: ../bind/bind-client-playbook.yml
- import_playbook: ../icinga/icinga-playbook.yml
- import_playbook: ../postfix/postfix-playbook.yml
- import_playbook: wordpress-playbook.yml

35
playbooks/wordpress/roles/wordpress/defaults/main.yml

@ -0,0 +1,35 @@
---
#
######################################
#
# Name of the user with administrative rights
#
wordpress_admin_user: "admin"
#
######################################
#
# email of the user with administrative rights
#
wordpress_admin_email: "admin@{{ domain }}"
#
######################################
#
# password of the user with administrative rights
#
wordpress_admin_password: "6l#s4kcHQprVqc1w*m"
#
######################################
#
# password of the database user
#
wordpress_db_password: Jask0ovCaing
#
######################################
#
# DO NOT MODIFY VARIABLES BELOW
#
######################################
#
wordpress_port: 8300
wordpress_version: 5.5.0-php7.4-apache
wordpress_root: /srv/wordpress

2
playbooks/wordpress/roles/wordpress/tasks/main.yml

@ -0,0 +1,2 @@
---
- import_tasks: wordpress.yml

62
playbooks/wordpress/roles/wordpress/tasks/wordpress.yml

@ -0,0 +1,62 @@
---
- name: apt-get install git virtualenv python-pip and python-setuptools python-backports.ssl-match-hostname
apt:
name: [ git, virtualenv, python-pip, python-setuptools, python-backports.ssl-match-hostname ]
state: present
- name: "mkdir {{ wordpress_root }}"
file:
path: "{{ wordpress_root }}"
state: directory
owner: debian
group: debian
- name: Copy docker-compose.yml
template:
src: docker-compose.yml.j2
dest: "{{ wordpress_root }}/docker-compose.yml"
owner: debian
mode: "0600"
- name: Copy uploads.ini
template:
src: uploads.ini.j2
dest: "{{ wordpress_root }}/uploads.ini"
owner: debian
mode: "0600"
- name: (re)create wordpress
shell: |
docker-compose up -d
args:
chdir: "{{ wordpress_root }}"
- name: wait for wordpress.{{ domain }} to be ready
shell: |
set $(curl -k -s --head https://wordpress.{{ domain }} | grep HTTP | tail -1)
if test "$2" = 200 -o "$2" = 302 ; then
exit 0
else
exit 1
fi
register: wordpress_get
until: wordpress_get is success
retries: 20
delay: 5
- name: set_fact wp_cli
set_fact:
wp_cli: "docker run -it --rm --volumes-from wordpress_wordpress_1 --network container:wordpress_wordpress_1 wordpress:cli"
- name: is WordPress installed already ?
shell: |
{{ wp_cli }} core is-installed
register: wordpress_installed
ignore_errors: True
- when: wordpress_installed.rc == 1
block:
- name: install WordPress
shell: |
{{ wp_cli }} core install --url=wordpress.{{ domain }} --title="Enough" --admin_name={{ wordpress_admin_user }} --admin_password='{{ wordpress_admin_password }}' --admin_email='{{ wordpress_admin_email }}'

32
playbooks/wordpress/roles/wordpress/templates/docker-compose.yml.j2

@ -0,0 +1,32 @@
---
version: '3.1'
services:
wordpress:
image: wordpress:{{ wordpress_version }}
depends_on:
- db
ports:
- "{{ wordpress_port }}:80"
volumes:
- ./wp-content:/var/www/html/wp-content
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
restart: always
environment:
WORDPRESS_DEBUG: 1
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: dbuser
WORDPRESS_DB_PASSWORD: {{ wordpress_db_password }}
WORDPRESS_DB_NAME: namedb
db:
image: mysql:5.7
volumes:
- ./db_data:/var/lib/mysql
restart: always
environment:
MYSQL_DATABASE: namedb
MYSQL_USER: dbuser
MYSQL_PASSWORD: {{ wordpress_db_password }}
MYSQL_RANDOM_ROOT_PASSWORD: '1'

3
playbooks/wordpress/roles/wordpress/templates/uploads.ini.j2

@ -0,0 +1,3 @@
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 600

6
playbooks/openedx/tests/test_icinga.py → playbooks/wordpress/tests/test_icinga.py

@ -8,8 +8,8 @@ IcingaHelper.icinga_host = 'bind-host'
class TestChecks(IcingaHelper):
def test_host(self):
r = self.get_client().objects.get('Host', 'openedx-host')
assert r['attrs']['name'] == 'openedx-host'
r = self.get_client().objects.get('Host', 'wordpress-host')
assert r['attrs']['name'] == 'wordpress-host'
def test_service(self, host):
assert self.is_service_ok('openedx-host!openedX')
assert self.is_service_ok('wordpress-host!WordPress')

8
playbooks/openedx/tests/test_openedx.py → playbooks/wordpress/tests/test_wordpress.py

@ -5,16 +5,16 @@ import yaml
def get_address(inventory):
vars_dir = f'{inventory}/group_vars/all'
return 'https://openedx.' + yaml.load(
return 'https://wordpress.' + yaml.load(
open(vars_dir + '/domain.yml'))['domain']
def test_openedx(pytestconfig):
# openedx freshly recreated may take few mins to be operationnal
def test_wordpress(pytestconfig):
# wordpress freshly recreated may take few mins to be operationnal
url = get_address(pytestconfig.getoption("--ansible-inventory"))
for i in range(60, 0, -1):
r = requests.get(url, timeout=5, verify='certs')
if r.status_code == requests.codes.ok:
break
time.sleep(5)
assert 'openedX' in r.text
assert 'WordPress' in r.text

59
playbooks/wordpress/wordpress-playbook.yml

@ -0,0 +1,59 @@
---
- name: firewall for web
hosts: localhost
gather_facts: false
tasks:
- include_role:
name: firewall
vars:
firewall_server: "{{ item }}"
firewall_clients: [ 0.0.0.0/0 ]
firewall_protocols: [ tcp ]
firewall_ports: [ 80, 443 ]
when: hostvars[item].ansible_host is defined
with_items: "{{ groups['wordpress-service-group'] | default([]) }}"
- name: setup wordpress DNS
hosts: wordpress-service-group
become: true
pre_tasks:
- name: set CNAME
nsupdate:
server: "{{ hostvars['bind-host']['ansible_host'] }}"
zone: "{{ domain }}"
record: "wordpress.{{ domain }}."
ttl: 1800
type: CNAME
value: "{{ groups['wordpress-service-group'][0] }}.{{ domain }}."
delegate_to: bind-host
- name: install wordpress
hosts: wordpress-service-group
become: true
roles:
- role: ansible-role-docker
docker_install_compose: true
- role: docker
- role: wordpress
- role: enough-nginx
vars:
enough_nginx_reverse_proxy: "127.0.0.1:{{ wordpress_port }}"
enough_nginx_fqdn: "wordpress.{{ domain }}"
- role: certificate
vars:
certificate_fqdn: "wordpress.{{ domain }}"
certificate_installer: nginx
- role: monitor_http_vhost
http_vhost_https: true
http_vhost_name: WordPress
http_vhost_fqdn: "wordpress.{{ domain }}"
http_vhost_uri: "/"
http_vhost_string: "WordPress"

3
tox.ini

@ -10,6 +10,7 @@ passenv =
SKIP_NETWORK_OPENSTACK_INTEGRATION_TESTS
PYTEST_ADDOPTS
HOME
allowlist_externals = env
usedevelop = True
install_command = pip install {opts} {packages}
deps =
@ -23,7 +24,7 @@ commands = flake8 {posargs}
#
# Integration tests
#
[testenv:{infrastructure,bind,authorized_keys,backup,certificate,postfix,icinga,openvpn,wekan,misc,pad,firewall,gitlab,api,wazuh,weblate,website,chat,cloud,enough,forum,packages,securedrop,jitsi,openedx}]
[testenv:{infrastructure,bind,authorized_keys,backup,certificate,postfix,icinga,openvpn,wekan,misc,pad,firewall,gitlab,api,wazuh,weblate,website,chat,cloud,enough,forum,packages,securedrop,jitsi,wordpress}]
passenv =
ENOUGH_API_TOKEN
PYTEST_ADDOPTS

Loading…
Cancel
Save