diff --git a/roles/lemonldap_ng/defaults/main.yml b/roles/lemonldap_ng/defaults/main.yml index ea2a90b..e4e8de7 100644 --- a/roles/lemonldap_ng/defaults/main.yml +++ b/roles/lemonldap_ng/defaults/main.yml @@ -62,3 +62,5 @@ llng_handler_db_user: lemonldapnghandler # llng_db_pass: s3cr3t. # llng_handler_db_pass +# Number of llng-fastcgi-server workers. The upstream default is 7 which is often too much +llng_fcgi_workers: 5 diff --git a/roles/lemonldap_ng/files/logos/metabase.png b/roles/lemonldap_ng/files/logos/metabase.png new file mode 100644 index 0000000..aa76ff2 Binary files /dev/null and b/roles/lemonldap_ng/files/logos/metabase.png differ diff --git a/roles/lemonldap_ng/tasks/main.yml b/roles/lemonldap_ng/tasks/main.yml index 3401ed6..3230376 100644 --- a/roles/lemonldap_ng/tasks/main.yml +++ b/roles/lemonldap_ng/tasks/main.yml @@ -119,15 +119,19 @@ when: llng_portal == True tags: web -- name: Deploy custom llng-fastcgi-server unit - template: src=llng-fastcgi-server.service.j2 dest=/etc/systemd/system/llng-fastcgi-server.service - notify: restart llng-fastcgi-server - register: llng_fastcgi_unit - tags: web - -- name: Reload systemd - systemd: daemon_reload=True - when: llng_fastcgi_unit.changed +- when: llng_server == 'nginx' + block: + - name: Deploy custom llng-fastcgi-server unit + template: src=llng-fastcgi-server.service.j2 dest=/etc/systemd/system/llng-fastcgi-server.service + notify: restart llng-fastcgi-server + register: llng_fastcgi_unit + + - name: Reload systemd + systemd: daemon_reload=True + + - name: Deploy llng-fastcgi-server config + template: src=llng-fastcgi-server.j2 dest=/etc/default/llng-fastcgi-server + notify: restart llng-fastcgi-server tags: web - name: Handle Fast CGI server diff --git a/roles/lemonldap_ng/templates/lemonldap-ng.ini.j2 b/roles/lemonldap_ng/templates/lemonldap-ng.ini.j2 index deb30c6..3fbb511 100644 --- a/roles/lemonldap_ng/templates/lemonldap-ng.ini.j2 +++ b/roles/lemonldap_ng/templates/lemonldap-ng.ini.j2 @@ -2,6 +2,7 @@ [all] logLevel = info +logger = Lemonldap::NG::Common::Logger::Syslog {% if llng_conf_backend == 'file' %} globalStorage = Apache::Session::File globalStorageOptions = { \ diff --git a/roles/lemonldap_ng/templates/llng-fastcgi-server.j2 b/roles/lemonldap_ng/templates/llng-fastcgi-server.j2 new file mode 100644 index 0000000..bc24046 --- /dev/null +++ b/roles/lemonldap_ng/templates/llng-fastcgi-server.j2 @@ -0,0 +1,9 @@ +USER=apache +GROUP=apache +NPROC={{ llng_fcgi_workers }} +SOCKET=/run/llng-fastcgi-server/llng-fastcgi.sock +PID=/run/llng-fastcgi-server/llng-fastcgi-server.pid +PERL_LWP_ENV_PROXY={{ llng_reload_use_proxy | ternary('1','0') }} +PM_MAX_REQUESTS=500 +PM_SIZECHECK_NUM_REQUESTS=100 +PM_MAX_SIZE=800000 diff --git a/roles/lemonldap_ng/templates/llng-fastcgi-server.service.j2 b/roles/lemonldap_ng/templates/llng-fastcgi-server.service.j2 index e08a753..d569f16 100644 --- a/roles/lemonldap_ng/templates/llng-fastcgi-server.service.j2 +++ b/roles/lemonldap_ng/templates/llng-fastcgi-server.service.j2 @@ -4,17 +4,10 @@ After=network.target [Service] Type=simple -PIDFile=/var/run/llng-fastcgi-server/llng-fastcgi-server.pid +EnvironmentFile=/etc/default/llng-fastcgi-server +PIDFile=/run/llng-fastcgi-server/llng-fastcgi-server.pid User=apache Group=apache -{% if ansible_os_family == 'RedHat' and ansible_distribution_major_version is version('8','<') %} -Environment=PM_MAX_REQUESTS=5000 -Environment=PM_SIZECHECK_NUM_REQUESTS=100 -Environment=PM_MAX_SIZE=800000 -{% endif %} -Environment=SOCKET=/var/run/llng-fastcgi-server/llng-fastcgi.sock -Environment=PID=/var/run/llng-fastcgi-server/llng-fastcgi-server.pid -Environment=PERL_LWP_ENV_PROXY={{ llng_reload_use_proxy | ternary('1','0') }} ExecStart=/usr/libexec/lemonldap-ng/sbin/llng-fastcgi-server \ --foreground PrivateTmp=yes @@ -22,7 +15,7 @@ PrivateDevices=yes ProtectSystem=full ProtectHome=yes NoNewPrivileges=yes -MemoryLimit=3072M +MemoryLimit={{ llng_fcgi_workers * 250 }}M Restart=on-failure StartLimitInterval=0 RestartSec=1 diff --git a/roles/metabase/defaults/.main.yml.swp b/roles/metabase/defaults/.main.yml.swp new file mode 100644 index 0000000..52be59a Binary files /dev/null and b/roles/metabase/defaults/.main.yml.swp differ diff --git a/roles/metabase/defaults/main.yml b/roles/metabase/defaults/main.yml new file mode 100644 index 0000000..def684a --- /dev/null +++ b/roles/metabase/defaults/main.yml @@ -0,0 +1,65 @@ +--- + +# Version to deploy +metabase_version: 0.38.0 +# URL to fetch the jar +metabase_jar_url: https://downloads.metabase.com/v{{ metabase_version }}/metabase.jar +# Expected sha1 of the jar +metabase_jar_sha1: 2d2333deff92c18784c4a0e0d23288b29d2c8a87 +# Should ansible handle upgrades ? If set to false, only the initial install (and the config) will be handled +metabase_manage_upgrade: True + +# User account under which metabase will run +# Will be created +metabase_user: metabase +# Path under which metabase will be installed +metabase_root_dir: /opt/metabase + +# Port on which metabase will listen +metabase_port: 3002 +# List of IP or CIDR allowed to reach metabase_port +metabase_src_ip: [] + +# MySQL database +metabase_db_server: "{{ mysql_server | default('localhost') }}" +metabase_db_port: 3306 +metabase_db_name: metabase +metabase_db_user: metabase +# A random pass will be generated and stored in the meta dir if not defined +# metabase_db_pass: S3cr3t. + +# Email of the admins +metabase_admin_email: "{{ system_admin_email }}" +# From email for emails sent by metabase +metabase_from_email: metabase-noreply@{{ ansible_domain }} +# Settings for sending emails +metabase_smtp_server: localhost +metabase_smtp_port: 25 +# metabase_smtp_user: metabase@example.org +# metabase_smtp_pass: S3cr3t. +metabase_smtp_starttls: False + +# Encryption key to protect credentials stored in the DB +# If not set, a random one will be created and store in the mata directory +# metabase_encryption_key: SuperS3cr3t. + +# Default language for notifications +metabase_lang: fr + +# Public URL to reach metabase. +# Will most likely need to be adjusted, because you'll put it behind a reverse proxy don't you ? +metabase_public_url: http://{{ inventory_hostname }}:{{ metabase_port }}/ + +# LDAP Auth settings +metabase_ldap: "{{ (ad_auth | default(False) or ldap_auth | default(False)) | ternary(True,False) }}" +metabase_ldap_attr_email: mail +metabase_ldap_attr_firstname: givenName +metabase_ldap_attr_lastname: sn +metabase_ldap_server: "{{ (ldap_uri is defined) | ternary(ldap_uri | urlsplit('hostname'), ad_auth | default(False) | ternary(ad_realm | default(samba_realm) | default(ansible_domain) | lower, ansible_domain)) }}" +metabase_ldap_port: "{{ (ldap_auth is defined and ldap_auth | urlsplit('port') is search('\\d+')) | ternary(ldap_auth | urlsplit('port'), '389') }}" +# metabase_ldap_user: CN=Metabase,OU=Apps,DC=example,DC=org +# metabase_ldap_pass: S3cr3t. +metabase_ldap_user_base: "{{ (ad_ldap_user_search_base is defined and ad_auth) | ternary(ad_ldap_user_search_base, ad_auth | default(False) | ternary('DC=' + ad_realm | default(samba_realm) | default(ansible_domain) | regex_replace('\\.',',DC='), 'ou=Users,' + ldap_base)) }}" +metabase_ldap_user_filter: (&{{ ad_auth | default(False) | ternary('(objectClass=user)(objectCategory=person)(primaryGroupId=513)','(objectClass=inetOrgPerson)') }}(|(uid={login})(mail={login})) +metabase_ldap_group_base: "{{ (ad_ldap_group_search_base is defined and ad_auth) | ternary(ad_ldap_group_search_base, ad_auth | default(False) | ternary('DC=' + ad_realm | default(samba_realm) | default(ansible_domain) | regex_replace('\\.',',DC='), 'ou=Groups,' + ldap_base)) }}" + diff --git a/roles/metabase/handlers/main.yml b/roles/metabase/handlers/main.yml new file mode 100644 index 0000000..f81ef91 --- /dev/null +++ b/roles/metabase/handlers/main.yml @@ -0,0 +1,4 @@ +--- + +- name: restart metabase + service: name=metabase state=restarted diff --git a/roles/metabase/meta/main.yml b/roles/metabase/meta/main.yml new file mode 100644 index 0000000..91d91ca --- /dev/null +++ b/roles/metabase/meta/main.yml @@ -0,0 +1,5 @@ +--- + +dependencies: + - role: mysql_server + when: metabase_db_server in ['localhost','127.0.0.1'] diff --git a/roles/metabase/tasks/archive_post.yml b/roles/metabase/tasks/archive_post.yml new file mode 100644 index 0000000..dd24d66 --- /dev/null +++ b/roles/metabase/tasks/archive_post.yml @@ -0,0 +1,10 @@ +--- + +- name: Compress previous version + command: tar cf {{ metabase_root_dir }}/archives/{{ metabase_current_version }}.tar.zst --use-compress-program=zstd ./ + environment: + ZSTD_CLEVEL: 10 + args: + chdir: "{{ metabase_root_dir }}/archives/{{ metabase_current_version }}" + warn: False + tags: metabase diff --git a/roles/metabase/tasks/archive_pre.yml b/roles/metabase/tasks/archive_pre.yml new file mode 100644 index 0000000..0b1a7c9 --- /dev/null +++ b/roles/metabase/tasks/archive_pre.yml @@ -0,0 +1,36 @@ +--- + +- name: Create the archive dir + file: + path: "{{ metabase_root_dir }}/archives/{{ metabase_current_version }}" + state: directory + tags: metabase + +- name: Archive previous version + synchronize: + src: "{{ metabase_root_dir }}/{{ item }}" + dest: "{{ metabase_root_dir }}/archives/{{ metabase_current_version }}" + recursive: True + delete: True + loop: + - app + - plugins + - data + - etc + delegate_to: "{{ inventory_hostname }}" + tags: metabase + +- name: Dump the database + mysql_db: + state: dump + name: "{{ metabase_db_name }}" + target: "{{ metabase_root_dir }}/archives/{{ metabase_current_version }}/{{ metabase_db_name }}.sql.xz" + login_host: "{{ metabase_db_server }}" + login_port: "{{ metabase_db_port }}" + login_user: "{{ metabase_db_user }}" + login_password: "{{ metabase_db_pass }}" + quick: True + single_transaction: True + environment: + XZ_OPT: -T0 + tags: metabase diff --git a/roles/metabase/tasks/cleanup.yml b/roles/metabase/tasks/cleanup.yml new file mode 100644 index 0000000..f6756ba --- /dev/null +++ b/roles/metabase/tasks/cleanup.yml @@ -0,0 +1,8 @@ +--- + +- name: Remove tmp and unused files + file: path={{ item }} state=absent + loop: + - "{{ metabase_root_dir }}/archives/{{ metabase_current_version }}" + - "{{ metabase_root_dir }}/tmp/metabase.jar" + tags: metabase diff --git a/roles/metabase/tasks/conf.yml b/roles/metabase/tasks/conf.yml new file mode 100644 index 0000000..4a5bede --- /dev/null +++ b/roles/metabase/tasks/conf.yml @@ -0,0 +1,6 @@ +--- + +- name: Deploy configuration + template: src=env.j2 dest={{ metabase_root_dir }}/etc/env group={{ metabase_user }} mode=640 + notify: restart metabase + tags: metabase diff --git a/roles/metabase/tasks/directories.yml b/roles/metabase/tasks/directories.yml new file mode 100644 index 0000000..89bb87d --- /dev/null +++ b/roles/metabase/tasks/directories.yml @@ -0,0 +1,23 @@ +--- + +- name: Create needed directories + file: path={{ item.dir }} state=directory owner={{ item.owner | default(omit) }} group={{ item.group | default(omit) }} mode={{ item.mode | default(omit) }} + loop: + - dir: "{{ metabase_root_dir }}/app" + - dir: "{{ metabase_root_dir }}/tmp" + - dir: "{{ metabase_root_dir }}/data" + owner: "{{ metabase_user }}" + mode: 700 + - dir: "{{ metabase_root_dir }}/etc" + group: "{{ metabase_user }}" + mode: 750 + - dir: "{{ metabase_root_dir }}/plugins" + owner: "{{ metabase_user }}" + - dir: "{{ metabase_root_dir }}/archives" + mode: 700 + - dir: "{{ metabase_root_dir }}/meta" + mode: 700 + - dir: "{{ metabase_root_dir }}/backup" + mode: 700 + tags: metabase + diff --git a/roles/metabase/tasks/facts.yml b/roles/metabase/tasks/facts.yml new file mode 100644 index 0000000..bea274e --- /dev/null +++ b/roles/metabase/tasks/facts.yml @@ -0,0 +1,29 @@ +--- + +# Detect installed version (if any) +- block: + - import_tasks: ../includes/webapps_set_install_mode.yml + vars: + - root_dir: "{{ metabase_root_dir }}" + - version: "{{ metabase_version }}" + - set_fact: metabase_install_mode={{ (install_mode == 'upgrade' and not metabase_manage_upgrade) | ternary('none',install_mode) }} + - set_fact: metabase_current_version={{ current_version | default('') }} + tags: metabase + +# Create a random pass for the DB if needed +- block: + - import_tasks: ../includes/get_rand_pass.yml + vars: + - pass_file: "{{ metabase_root_dir }}/meta/ansible_dbpass" + - set_fact: metabase_db_pass={{ rand_pass }} + when: metabase_db_pass is not defined + tags: metabase + +# Create a random encryption key +- block: + - import_tasks: ../includes/get_rand_pass.yml + vars: + - pass_file: "{{ metabase_root_dir }}/meta/ansible_encryption_key" + - set_fact: metabase_encryption_key={{ rand_pass }} + when: metabase_encryption_key is not defined + tags: metabase diff --git a/roles/metabase/tasks/install.yml b/roles/metabase/tasks/install.yml new file mode 100644 index 0000000..c44d423 --- /dev/null +++ b/roles/metabase/tasks/install.yml @@ -0,0 +1,46 @@ +--- + +- name: Install dependencies + yum: + name: + - java-11-openjdk + tags: metabase + +- name: Stop the service during upgrades + service: name=metabase state=stopped + when: metabase_install_mode == 'upgrade' + tags: metabase + +- when: metabase_install_mode != 'none' + block: + - name: Download metabase JAR file + get_url: + url: "{{ metabase_jar_url }}" + dest: "{{ metabase_root_dir }}/tmp/" + checksum: sha1:{{ metabase_jar_sha1 }} + + - name: Move the JAR to the app dir + copy: src={{ metabase_root_dir }}/tmp/metabase.jar dest={{ metabase_root_dir }}/app/ mode=644 remote_src=True + notify: restart metabase + + tags: metabase + +- name: Deploy systemd unit + template: src=metabase.service.j2 dest=/etc/systemd/system/metabase.service + register: metabase_unit + notify: restart metabase + tags: metabase + +- name: Reload systemd + systemd: daemon_reload=True + when: metabase_unit.changed + tags: metabase + +# Create the database +- import_tasks: ../includes/webapps_create_mysql_db.yml + vars: + - db_name: "{{ metabase_db_name }}" + - db_user: "{{ metabase_db_user }}" + - db_server: "{{ metabase_db_server }}" + - db_pass: "{{ metabase_db_pass }}" + tags: metabase diff --git a/roles/metabase/tasks/iptables.yml b/roles/metabase/tasks/iptables.yml new file mode 100644 index 0000000..96af576 --- /dev/null +++ b/roles/metabase/tasks/iptables.yml @@ -0,0 +1,8 @@ +--- + +- name: Handle metabase port in the firewall + iptables_raw: + name: metabase_port + state: "{{ (metabase_src_ip | length > 0) | ternary('present','absent') }}" + rules: "-A INPUT -m state --state NEW -p tcp --dport {{ metabase_port }} -s {{ metabase_src_ip | join(',') }} -j ACCEPT" + tags: firewall,metabase diff --git a/roles/metabase/tasks/main.yml b/roles/metabase/tasks/main.yml new file mode 100644 index 0000000..a6c6732 --- /dev/null +++ b/roles/metabase/tasks/main.yml @@ -0,0 +1,16 @@ +--- + +- include: user.yml +- include: directories.yml +- include: facts.yml +- include: archive_pre.yml + when: metabase_install_mode == 'upgrade' +- include: install.yml +- include: conf.yml +- include: iptables.yml + when: iptables_manage | default(True) +- include: services.yml +- include: write_version.yml +- include: archive_post.yml + when: metabase_install_mode == 'upgrade' +- include: cleanup.yml diff --git a/roles/metabase/tasks/services.yml b/roles/metabase/tasks/services.yml new file mode 100644 index 0000000..bbcc30b --- /dev/null +++ b/roles/metabase/tasks/services.yml @@ -0,0 +1,5 @@ +--- + +- name: Start and enable the service + service: name=metabase state=started enabled=True + tags: metabase diff --git a/roles/metabase/tasks/user.yml b/roles/metabase/tasks/user.yml new file mode 100644 index 0000000..c19344d --- /dev/null +++ b/roles/metabase/tasks/user.yml @@ -0,0 +1,5 @@ +--- + +- name: Create metabase user account + user: name={{ metabase_user }} home={{ metabase_root_dir }} system=True + tags: metabase diff --git a/roles/metabase/tasks/write_version.yml b/roles/metabase/tasks/write_version.yml new file mode 100644 index 0000000..44f1aa6 --- /dev/null +++ b/roles/metabase/tasks/write_version.yml @@ -0,0 +1,5 @@ +--- + +- name: Write installed version + copy: content={{ metabase_version }} dest={{ metabase_root_dir }}/meta/ansible_version + tags: metabase diff --git a/roles/metabase/templates/env.j2 b/roles/metabase/templates/env.j2 new file mode 100644 index 0000000..28f6d7d --- /dev/null +++ b/roles/metabase/templates/env.j2 @@ -0,0 +1,43 @@ +MB_ADMIN_EMAIL={{ metabase_admin_email }} +MB_EMAIL_FROM_ADDRESS={{ metabase_from_email }} +MB_EMAIL_SMTP_HOST={{metabase_smtp_server }} +MB_EMAIL_SMTP_PORT={{ metabase_smtp_port }} +{% if metabase_smtp_user is defined and metabase_smtp_pass is defined %} +MB_EMAIL_SMTP_USERNAME={{ metabase_smtp_user }} +MB_EMAIL_SMTP_PASSWORD={{ metabase_smtp_pass }} +{% endif %} +MB_EMAIL_SMTP_SECURITY={{ metabase_smtp_starttls | ternary('starttls','none') }} +MB_ANON_TRACKING_ENABLED=false +MB_DB_FILE={{ metabase_root_dir }}/data/metabase.db +MB_DB_DBNAME={{ metabase_db_name }} +MB_DB_HOST={{ metabase_db_server }} +MB_DB_USER={{ metabase_db_user }} +MB_DB_PASS={{ metabase_db_pass | quote }} +MB_DB_PORT={{ metabase_db_port }} +MB_DB_TYPE=mysql +MB_ENABLE_QUERY_CACHING=true +MB_ENABLE_PUBLIC_SHARING=true +MB_ENABLE_EMBEDDING=true +MB_ENCRYPTION_SECRET_KEY={{ metabase_encryption_key | quote }} +MB_JETTY_HOST=0.0.0.0 +MB_JETTY_PORT={{ metabase_port }} +MB_PLUGINS_DIR={{ metabase_root_dir }}/plugins +MB_SITE_LOCALE={{ metabase_lang }} +MB_SITE_URL={{ metabase_public_url }} +{% if metabase_ldap %} +MB_LDAP_ENABLED=true +MB_LDAP_HOST={{ metabase_ldap_server }} +MB_LDAP_PORT={{ metabase_ldap_port }} +MB_LDAP_SECURITY=tls +{% if metabase_ldap_user is defined and metabase_ldap_pass is defined %} +MB_LDAP_BIND_DN={{ metabase_ldap_user | quote }} +MB_LDAP_PASSWORD={{ metabase_ldap_pass | quote }} +{% endif %} +MB_LDAP_ATTRIBUTE_EMAIL={{ metabase_ldap_attr_email }} +MB_LDAP_ATTRIBUTE_FIRSTNAME={{ metabase_ldap_attr_firstname }} +MB_LDAP_ATTRIBUTE_LASTNAME={{ metabase_ldap_attr_lastname }} +MB_LDAP_USER_BASE={{ metabase_ldap_user_base }} +MB_LDAP_USER_FILTER={{ metabase_ldap_user_filter | quote }} +MB_LDAP_GROUP_SYNC=true +MB_LDAP_GROUP_BASE={{ metabase_ldap_group_base }} +{% endif %} diff --git a/roles/metabase/templates/metabase.service.j2 b/roles/metabase/templates/metabase.service.j2 new file mode 100644 index 0000000..f78f310 --- /dev/null +++ b/roles/metabase/templates/metabase.service.j2 @@ -0,0 +1,25 @@ +[Unit] +Description=Metabase opensource BI +After=syslog.target network.target + +[Service] +Type=simple +User={{ metabase_user }} +WorkingDirectory={{ metabase_root_dir }}/app +EnvironmentFile={{ metabase_root_dir }}/etc/env +ExecStart=/usr/bin/java -Djava.net.preferIPv4Stack=true \ +{% if system_proxy is defined and system_proxy != '' %} + -Dhttp.proxyHost={{ system_proxy | urlsplit('hostname') }} -Dhttp.proxyPort={{ system_proxy | urlsplit('port') }} \ + -Dhttps.proxyHost={{ system_proxy | urlsplit('hostname') }} -Dhttps.proxyPort={{ system_proxy | urlsplit('port') }} \ +{% endif %} + -jar {{ metabase_root_dir }}/app/metabase.jar +PrivateTmp=yes +PrivateDevices=yes +ProtectSystem=full +ProtectHome=yes +NoNewPrivileges=yes +Restart=on-failure + +[Install] +WantedBy=multi-user.target + diff --git a/roles/squid/files/acl/software_various.domains b/roles/squid/files/acl/software_various.domains index 74a73f3..31e25a7 100644 --- a/roles/squid/files/acl/software_various.domains +++ b/roles/squid/files/acl/software_various.domains @@ -347,3 +347,4 @@ store.itophub.io # Crowdsec crowdsec-statics-assets.s3-eu-west-1.amazonaws.com api.crowdsec.com +www.cloudflare.com