From b4b621e760055126341d45a44df138ee46dd03ba Mon Sep 17 00:00:00 2001 From: Daniel Berteaud Date: Fri, 17 Mar 2023 16:00:08 +0100 Subject: [PATCH] Update to 2023-03-17 16:00 --- roles/offen/defaults/main.yml | 38 ++++++++++++++++ roles/offen/handlers/main.yml | 4 ++ roles/offen/meta/main.yml | 6 +++ roles/offen/tasks/archive_post.yml | 13 ++++++ roles/offen/tasks/archive_pre.yml | 22 ++++++++++ roles/offen/tasks/cleanup.yml | 7 +++ roles/offen/tasks/conf.yml | 13 ++++++ roles/offen/tasks/directories.yml | 21 +++++++++ roles/offen/tasks/facts.yml | 42 ++++++++++++++++++ roles/offen/tasks/install.yml | 60 ++++++++++++++++++++++++++ roles/offen/tasks/iptables.yml | 8 ++++ roles/offen/tasks/main.yml | 38 ++++++++++++++++ roles/offen/tasks/service.yml | 7 +++ roles/offen/tasks/user.yml | 5 +++ roles/offen/tasks/write_version.yml | 5 +++ roles/offen/templates/offen.conf.j2 | 14 ++++++ roles/offen/templates/offen.service.j2 | 38 ++++++++++++++++ roles/offen/templates/post-backup.j2 | 5 +++ roles/offen/templates/pre-backup.j2 | 11 +++++ roles/offen/vars/RedHat-8.yml | 5 +++ 20 files changed, 362 insertions(+) create mode 100644 roles/offen/defaults/main.yml create mode 100644 roles/offen/handlers/main.yml create mode 100644 roles/offen/meta/main.yml create mode 100644 roles/offen/tasks/archive_post.yml create mode 100644 roles/offen/tasks/archive_pre.yml create mode 100644 roles/offen/tasks/cleanup.yml create mode 100644 roles/offen/tasks/conf.yml create mode 100644 roles/offen/tasks/directories.yml create mode 100644 roles/offen/tasks/facts.yml create mode 100644 roles/offen/tasks/install.yml create mode 100644 roles/offen/tasks/iptables.yml create mode 100644 roles/offen/tasks/main.yml create mode 100644 roles/offen/tasks/service.yml create mode 100644 roles/offen/tasks/user.yml create mode 100644 roles/offen/tasks/write_version.yml create mode 100644 roles/offen/templates/offen.conf.j2 create mode 100644 roles/offen/templates/offen.service.j2 create mode 100644 roles/offen/templates/post-backup.j2 create mode 100644 roles/offen/templates/pre-backup.j2 create mode 100644 roles/offen/vars/RedHat-8.yml diff --git a/roles/offen/defaults/main.yml b/roles/offen/defaults/main.yml new file mode 100644 index 0000000..66ddade --- /dev/null +++ b/roles/offen/defaults/main.yml @@ -0,0 +1,38 @@ +--- + +offen_version: 1.3.4 +offen_archive_url: https://github.com/offen/offen/releases/download/v{{ offen_version }}/offen-v{{ offen_version }}.tar.gz +offen_archive_sha256: f0997f8cc57d8f935c6745beaa506526da639ad6c7b691b2bf40f95ba425283c +offen_manage_upgrade: True + +offen_root_dir: /opt/offen +offen_user: offen + +# DB settings +offen_db_engine: mysql +offen_db_server: "{{ mysql_server | default('localhost') }}" +offen_db_port: 3306 +offen_db_user: offen +offen_db_name: offen +# A random one will be created if not defined +# offen_db_pass: S3cr3t. + +# Port on which offen will listen +offen_port: 3003 +# List of IP/CIDR for which the offen port will be accessible +offen_src_ip: [] + +offen_smtp_server: localhost +offen_smtp_port: 25 +# offen_smtp_user: foo +# offen_smtp_pass: bar +offen_smtp_from: offen-no-reply@{{ ansible_domain }} + +# secret used to sign cookies. A random one is created if missing +# offen_secret: p@ssw0rd + +# Default lang +offen_locale: fr + +# Data retention +offen_retention: 6months diff --git a/roles/offen/handlers/main.yml b/roles/offen/handlers/main.yml new file mode 100644 index 0000000..6964c0b --- /dev/null +++ b/roles/offen/handlers/main.yml @@ -0,0 +1,4 @@ +--- + +- name: restart offen + service: name=offen state=restarted diff --git a/roles/offen/meta/main.yml b/roles/offen/meta/main.yml new file mode 100644 index 0000000..5278c0c --- /dev/null +++ b/roles/offen/meta/main.yml @@ -0,0 +1,6 @@ +--- + +dependencies: + - role: mysql_server + when: offen_db_engine == 'mysql' and offen_db_server in ['localhost', '127.0.0.1'] + diff --git a/roles/offen/tasks/archive_post.yml b/roles/offen/tasks/archive_post.yml new file mode 100644 index 0000000..9a2662e --- /dev/null +++ b/roles/offen/tasks/archive_post.yml @@ -0,0 +1,13 @@ +--- + +- name: Compress previous version + command: tar cf {{ offen_root_dir }}/archives/{{ offen_current_version }}.tar.zst --use-compress-program=zstd ./ + args: + chdir: "{{ offen_root_dir }}/archives/{{ offen_current_version }}" + environment: + ZSTD_CLEVEL: 10 + tags: offen + +- name: Remove uncompressed previous version + file: path={{ offen_root_dir }}/archives/{{ offen_current_version }} state=absent + tags: offen diff --git a/roles/offen/tasks/archive_pre.yml b/roles/offen/tasks/archive_pre.yml new file mode 100644 index 0000000..1af79bc --- /dev/null +++ b/roles/offen/tasks/archive_pre.yml @@ -0,0 +1,22 @@ +--- +- name: Create archive directory + file: path={{ offen_root_dir }}/archives/{{ offen_current_version }} state=directory mode=700 + tags: offen + +- name: Archive previous version + copy: src={{ offen_root_dir }}/bin/offen dest={{ offen_root_dir }}/archives/{{ offen_current_version }} remote_src=True + tags: offen + +- name: Archive the database + mysql_db: + state: dump + name: "{{ offen_db_name }}" + target: "{{ offen_root_dir }}/archives/{{ offen_current_version }}/{{ offen_db_name }}.sql.xz" + login_host: "{{ offen_db_server | default(mysql_server) }}" + login_user: sqladmin + login_password: "{{ mysql_admin_pass }}" + quick: True + single_transaction: True + environment: + XZ_OPT: -T0 + tags: offen diff --git a/roles/offen/tasks/cleanup.yml b/roles/offen/tasks/cleanup.yml new file mode 100644 index 0000000..b9ae764 --- /dev/null +++ b/roles/offen/tasks/cleanup.yml @@ -0,0 +1,7 @@ +--- + +- name: Remove tmp and obsolete files + file: path={{ item }} state=absent + loop: + - "{{ offen_root_dir }}/tmp/{{ offen_version }}" + tags: offen diff --git a/roles/offen/tasks/conf.yml b/roles/offen/tasks/conf.yml new file mode 100644 index 0000000..098988a --- /dev/null +++ b/roles/offen/tasks/conf.yml @@ -0,0 +1,13 @@ +--- + +- name: Deploy configuration + template: src=offen.conf.j2 dest={{ offen_root_dir }}/etc/offen.conf group={{ offen_user }} mode=640 + notify: + - restart offen + tags: offen + +- name: Init database + command: | + {{ offen_root_dir }}/bin/offen setup -email admin@{{ ansible_domain }} -password password -name admin -envfile {{ offen_root_dir }}/etc/offen.conf + when: offen_install_mode == 'install' + tags: offen diff --git a/roles/offen/tasks/directories.yml b/roles/offen/tasks/directories.yml new file mode 100644 index 0000000..a0f4a4a --- /dev/null +++ b/roles/offen/tasks/directories.yml @@ -0,0 +1,21 @@ +--- + +- name: Create required directories + file: path={{ item.dir }} state=directory owner={{ item.owner | default(omit) }} group={{ item.group | default(omit) }} mode={{ item.mode | default(omit) }} + loop: + - dir: "{{ offen_root_dir }}" + - dir: "{{ offen_root_dir }}/meta" + mode: 700 + - dir: "{{ offen_root_dir }}/backup" + mode: 700 + - dir: "{{ offen_root_dir }}/archives" + mode: 700 + - dir: "{{ offen_root_dir }}/bin" + - dir: "{{ offen_root_dir }}/etc" + group: "{{ offen_user }}" + mode: 750 + - dir: "{{ offen_root_dir }}/tmp" + group: "{{ offen_user }}" + mode: 770 + tags: offen + diff --git a/roles/offen/tasks/facts.yml b/roles/offen/tasks/facts.yml new file mode 100644 index 0000000..2a216dc --- /dev/null +++ b/roles/offen/tasks/facts.yml @@ -0,0 +1,42 @@ +--- + +# Load distribution specific variables +- include_vars: "{{ item }}" + with_first_found: + - "{{ role_path }}/vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" + - "{{ role_path }}/vars/{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml" + - "{{ role_path }}/vars/{{ ansible_distribution }}.yml" + - "{{ role_path }}/vars/{{ ansible_os_family }}.yml" + tags: offen + +# Detect installed version (if any) +- block: + - import_tasks: ../includes/webapps_set_install_mode.yml + vars: + - root_dir: "{{ offen_root_dir }}" + - version: "{{ offen_version }}" + - set_fact: offen_install_mode={{ (install_mode == 'upgrade' and not offen_manage_upgrade) | ternary('none',install_mode) }} + - set_fact: offen_current_version={{ current_version | default('') }} + tags: offen + +# Create a random pass for the DB if needed +- block: + - import_tasks: ../includes/get_rand_pass.yml + vars: + - pass_file: "{{ offen_root_dir }}/meta/ansible_dbpass" + - complex: False + - set_fact: offen_db_pass={{ rand_pass }} + when: offen_db_pass is not defined + tags: offen + +# Create a random secret if needed +- block: + - import_tasks: ../includes/get_rand_pass.yml + vars: + - pass_file: "{{ offen_root_dir }}/meta/ansible_secret" + - complex: False + - pass_size: 16 + - set_fact: offen_secret={{ rand_pass }} + when: offen_secret is not defined + tags: offen + diff --git a/roles/offen/tasks/install.yml b/roles/offen/tasks/install.yml new file mode 100644 index 0000000..fd52d7d --- /dev/null +++ b/roles/offen/tasks/install.yml @@ -0,0 +1,60 @@ +--- +- name: Install packages + yum: name={{ offen_packages }} + tags: offen + +- when: offen_install_mode != 'none' + block: + + - name: Download offen + get_url: + url: "{{ offen_archive_url }}" + dest: "{{ offen_root_dir }}/tmp" + checksum: "sha256:{{ offen_archive_sha256 }}" + + - name: Create temporary dir + file: path={{ offen_root_dir }}/tmp/{{ offen_version }} state=directory + + - name: Unarchive offen + unarchive: + src: "{{ offen_root_dir }}/tmp/offen-v{{ offen_version }}.tar.gz" + dest: "{{ offen_root_dir }}/tmp/{{ offen_version }}" + remote_src: True + + - name: Install offen binary + copy: + src: "{{ offen_root_dir }}/tmp/{{ offen_version }}/offen-linux-amd64" + dest: "{{ offen_root_dir }}/bin/offen" + mode: 755 + remote_src: True + notify: restart offen + + tags: offen + +- name: Deploy offen service unit + template: src=offen.service.j2 dest=/etc/systemd/system/offen.service + register: offen_unit + notify: restart offen + tags: offen + +- name: Reload systemd + systemd: daemon_reload=True + when: offen_unit.changed + tags: offen + + # Create MySQL database +- import_tasks: ../includes/webapps_create_mysql_db.yml + vars: + - db_name: "{{ offen_db_name }}" + - db_user: "{{ offen_db_user }}" + - db_server: "{{ offen_db_server }}" + - db_pass: "{{ offen_db_pass }}" + tags: offen + +- name: Deploy pre/post backup scripts + template: src={{ item }}-backup.j2 dest=/etc/backup/{{ item }}.d/offen mode=0750 + with_items: + - pre + - post + tags: offen + diff --git a/roles/offen/tasks/iptables.yml b/roles/offen/tasks/iptables.yml new file mode 100644 index 0000000..be4bed2 --- /dev/null +++ b/roles/offen/tasks/iptables.yml @@ -0,0 +1,8 @@ +--- + +- name: Handle offen port in the firewall + iptables_raw: + name: offen_port + state: "{{ (offen_src_ip | length > 0) | ternary('present','absent') }}" + rules: "-A INPUT -m state --state NEW -p tcp --dport {{ offen_port }} -s {{ offen_src_ip | join(',') }} -j ACCEPT" + tags: firewall,offen diff --git a/roles/offen/tasks/main.yml b/roles/offen/tasks/main.yml new file mode 100644 index 0000000..0cb1fce --- /dev/null +++ b/roles/offen/tasks/main.yml @@ -0,0 +1,38 @@ +--- + +- include_tasks: user.yml + tags: always + +- include_tasks: directories.yml + tags: always + +- include_tasks: facts.yml + tags: always + +- include_tasks: archive_pre.yml + when: offen_install_mode | default('none') == 'upgrade' + tags: always + +- include_tasks: install.yml + tags: always + +- include_tasks: conf.yml + tags: always + +- include_tasks: iptables.yml + when: iptables_manage | default(True) + tags: always + +- include_tasks: service.yml + tags: always + +- include_tasks: archive_post.yml + when: offen_install_mode | default('none') == 'upgrade' + tags: always + +- include_tasks: write_version.yml + tags: always + +- include_tasks: cleanup.yml + tags: always + diff --git a/roles/offen/tasks/service.yml b/roles/offen/tasks/service.yml new file mode 100644 index 0000000..574ac72 --- /dev/null +++ b/roles/offen/tasks/service.yml @@ -0,0 +1,7 @@ +--- + +- name: Start and enable the service + service: name=offen state=started enabled=True + register: offen_started + tags: offen + diff --git a/roles/offen/tasks/user.yml b/roles/offen/tasks/user.yml new file mode 100644 index 0000000..c7905c2 --- /dev/null +++ b/roles/offen/tasks/user.yml @@ -0,0 +1,5 @@ +--- + +- name: Create user account + user: name={{ offen_user }} system=True shell=/sbin/nologin home={{ offen_root_dir }} + tags: offen diff --git a/roles/offen/tasks/write_version.yml b/roles/offen/tasks/write_version.yml new file mode 100644 index 0000000..cfb8fa4 --- /dev/null +++ b/roles/offen/tasks/write_version.yml @@ -0,0 +1,5 @@ +--- + +- name: Write installed version + copy: content={{ offen_version }} dest={{ offen_root_dir }}/meta/ansible_version + tags: offen diff --git a/roles/offen/templates/offen.conf.j2 b/roles/offen/templates/offen.conf.j2 new file mode 100644 index 0000000..d6b75e0 --- /dev/null +++ b/roles/offen/templates/offen.conf.j2 @@ -0,0 +1,14 @@ +OFFEN_SERVER_PORT={{ offen_port }} +OFFEN_SERVER_REVERSEPROXY=true +OFFEN_DATABASE_DIALECT=mysql +OFFEN_DATABASE_CONNECTIONSTRING={{ offen_db_user }}:{{ offen_db_pass }}@tcp({{ offen_db_server }}:{{ offen_db_port }})/{{ offen_db_name }}?parseTime=true +OFFEN_SMTP_HOST={{ offen_smtp_server }} +OFFEN_SMTP_PORT={{ offen_smtp_port }} +OFFEN_SMTP_SENDER={{ offen_smtp_from }} +{% if offen_smtp_user is defined and offen_smtp_pass is defined %} +OFFEN_SMTP_USER={{ offen_smtp_user }} +OFFEN_SMTP_PASSWORD={{ offen_smtp_pass }} +{% endif %} +OFFEN_SECRET={{ offen_secret }} +OFFEN_APP_LOCALE={{ offen_locale }} +OFFEN_APP_RETENTION={{ offen_retention }} diff --git a/roles/offen/templates/offen.service.j2 b/roles/offen/templates/offen.service.j2 new file mode 100644 index 0000000..e32308d --- /dev/null +++ b/roles/offen/templates/offen.service.j2 @@ -0,0 +1,38 @@ +[Unit] +Description=Offen Fair Web Analytics +After=network.target postgresql.service mariadb.service + +[Service] +Type=simple +EnvironmentFile={{ offen_root_dir }}/etc/offen.conf +User={{ offen_user }} +ExecStart={{ offen_root_dir }}/bin/offen +RuntimeDirectory=offen +Restart=always +RestartSec=5 +Restart=always +NoNewPrivileges=true +PrivateDevices=true +ProtectControlGroups=true +ProtectHome=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectSystem=strict +ProtectHostname=yes +ProtectKernelLogs=yes +ProtectClock=yes +RestrictRealtime=true +RestrictNamespaces=yes +ReadWritePaths=/run +PrivateTmp=true +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=~@privileged +SystemCallFilter=~@resources +SystemCallErrorNumber=EPERM +LockPersonality=yes +MemoryDenyWriteExecute=yes + +[Install] +WantedBy=multi-user.target + diff --git a/roles/offen/templates/post-backup.j2 b/roles/offen/templates/post-backup.j2 new file mode 100644 index 0000000..3398bbf --- /dev/null +++ b/roles/offen/templates/post-backup.j2 @@ -0,0 +1,5 @@ +#!/bin/sh + +set -e + +rm -f {{ offen_root_dir }}/backup/* diff --git a/roles/offen/templates/pre-backup.j2 b/roles/offen/templates/pre-backup.j2 new file mode 100644 index 0000000..63160c5 --- /dev/null +++ b/roles/offen/templates/pre-backup.j2 @@ -0,0 +1,11 @@ +#!/bin/sh + +set -eo pipefail + +/usr/bin/mysqldump --user={{ offen_db_user | quote }} \ + --password={{ offen_db_pass | quote }} \ + --host={{ offen_db_server }} \ + --quick --single-transaction \ + --add-drop-table {{ offen_db_name }} | \ + zstd -c > {{ offen_root_dir }}/backup/{{ offen_db_name }}.sql.zst + diff --git a/roles/offen/vars/RedHat-8.yml b/roles/offen/vars/RedHat-8.yml new file mode 100644 index 0000000..ae38a35 --- /dev/null +++ b/roles/offen/vars/RedHat-8.yml @@ -0,0 +1,5 @@ +--- + +offen_packages: + - tar + - zstd