diff --git a/.ansible-lint b/.ansible-lint index 9008dfa9..a96bb516 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -27,3 +27,4 @@ exclude_paths: - roles/ansible_role_gitea - roles/ansible-role-postgresql - .woodpecker/ + - .gitea/ diff --git a/.gitea/workflows/ansible-lint.yaml b/.gitea/workflows/ansible-lint.yaml new file mode 100644 index 00000000..dc303896 --- /dev/null +++ b/.gitea/workflows/ansible-lint.yaml @@ -0,0 +1,21 @@ +name: ansible-lint +on: + push: + branches: [ master ] + pull_request: + +jobs: + ansible-lint: + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: write vault-pass + run: echo ${{ secrets.VAULTPASS }} > ./vault-pass + + - name: run ansible-lint + uses: docker://registry.mgrote.net/ansible-devspace:latest + with: + args: ansible-lint --force-color --format pep8 --show-relpath + +# VAULTPASS ist als Secrets auf Repo-Ebene angelegt diff --git a/.gitea/workflows/gitleaks.yaml b/.gitea/workflows/gitleaks.yaml new file mode 100644 index 00000000..7009367a --- /dev/null +++ b/.gitea/workflows/gitleaks.yaml @@ -0,0 +1,16 @@ +name: gitleaks +on: + push: + branches: [ master ] + pull_request: + +jobs: + gitleaks: + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Run Gitleaks + uses: docker://zricethezav/gitleaks:v8.18.4 + with: + args: detect --no-git --verbose --source ${{ github.workspace }} diff --git a/.woodpecker/ansible-lint.yml b/.woodpecker/ansible-lint.yml deleted file mode 100644 index ea875b35..00000000 --- a/.woodpecker/ansible-lint.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -depends_on: - - gitleaks - -steps: - ansible-lint: - image: registry.mgrote.net/ansible-devspace:latest - commands: - # Secrets - - echo $${SSHKEY} | base64 -d > ./id_ed25519 # woodpecker verschluckt linebreaks, daher mit base64 -w0 "kodiert" - - echo $${VAULTPASS} | base64 -d > ./vault-pass # Name des Secrets in Großschreibung - - chmod 0400 ./id_ed25519 - # Doing - - ansible-lint --force-color --format pep8 --show-relpath - # https://woodpecker-ci.org/docs/usage/secrets#use-secrets-in-commands - secrets: [vaultpass] - when: - - event: [push, pull_request, cron, pull_request_closed, tag, release, manual] - evaluate: 'CI_COMMIT_AUTHOR_EMAIL != "renovate@mgrote.net"' -... diff --git a/.woodpecker/gitleaks.yml b/.woodpecker/gitleaks.yml deleted file mode 100644 index afb2b029..00000000 --- a/.woodpecker/gitleaks.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -steps: - gitleaks: - image: zricethezav/gitleaks:v8.18.4 - commands: - - gitleaks detect --no-git --verbose --source $CI_WORKSPACE - when: - - event: [push, pull_request, cron, pull_request_closed, tag, release, manual] - evaluate: 'CI_COMMIT_AUTHOR_EMAIL != "renovate@mgrote.net"' -... diff --git a/README.md b/README.md index 345b549a..273c5fba 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ # ansible_heimserver -[![status-badge](https://ci.mgrote.net/api/badges/2/status.svg)](https://ci.mgrote.net/repos/2) - ## ansible-devspace - Repository: https://git.mgrote.net/container-images/ansible-devspace - - dort mit Woodpecker-CI gebaut und in eigene Registry gepushed + - dort mit CI gebaut und in eigene Registry gepushed - ``devspace.sh`` pulled Image, prüft ob SSH-Key und ``vault-pass`` vorhanden sind - mountet git-Secrets - startet Container diff --git a/docker-compose/act-runner/docker-compose.yml.j2 b/docker-compose/act-runner/docker-compose.yml.j2 new file mode 100644 index 00000000..675c9318 --- /dev/null +++ b/docker-compose/act-runner/docker-compose.yml.j2 @@ -0,0 +1,18 @@ +--- +# https://gitea.com/gitea/act_runner/src/branch/main/examples/docker-compose +version: "3.7" +services: + runner: + container_name: act-runner + image: gitea/act_runner + restart: always + volumes: + - act_runner_data:/data + - /var/run/docker.sock:/var/run/docker.sock + environment: + GITEA_INSTANCE_URL: https://git.mgrote.net + GITEA_RUNNER_REGISTRATION_TOKEN: "{{ lookup('viczem.keepass.keepass', 'gitea_act_runner_token', 'password') }}" # only used on first start, https://git.mgrote.net/admin/actions/runners + GITEA_RUNNER_NAME: "docker10-act-runner" + +volumes: + act_runner_data: diff --git a/docker-compose/nextcloud/docker-compose.yml.j2 b/docker-compose/nextcloud/docker-compose.yml.j2 index 48234006..2f53eeb5 100644 --- a/docker-compose/nextcloud/docker-compose.yml.j2 +++ b/docker-compose/nextcloud/docker-compose.yml.j2 @@ -2,7 +2,7 @@ version: '3.3' services: ######## Datenbank ######## nextcloud-db: - image: "mariadb:11.5.2" + image: "mariadb:11.4.3" container_name: nextcloud-db command: --transaction-isolation=READ-COMMITTED --log-bin=ROW --innodb_read_only_compressed=OFF restart: unless-stopped @@ -67,7 +67,7 @@ services: ######## Nextcloud ######## nextcloud-app: - image: "nextcloud:29.0.4" + image: "nextcloud:29.0.5" container_name: nextcloud-app restart: unless-stopped depends_on: diff --git a/group_vars/blocky.yml b/group_vars/blocky.yml index fec986e0..b5ed8c83 100644 --- a/group_vars/blocky.yml +++ b/group_vars/blocky.yml @@ -92,7 +92,7 @@ blocky_custom_lookups: # optional - name: ldap.mgrote.net ip: 192.168.2.47 - name: munin.mgrote.net - ip: 192.168.2.41 + ip: 192.168.2.40 ### mgrote_munin_node # kann git.mgrote.net nicht auflösen, deshalb hiermit IP diff --git a/group_vars/git.yml b/group_vars/git.yml index 87090b04..9093f25c 100644 --- a/group_vars/git.yml +++ b/group_vars/git.yml @@ -55,7 +55,7 @@ ufw_rules: ### ansible_role_gitea gitea_fork: "forgejo" # gitea update -gitea_version: "1.21.7-0" # alt zum renovate testen +gitea_version: "1.21.11-2" # TODO renovate, wird das erkannt? gitea_version_check: true gitea_backup_on_upgrade: false # gitea in the linux world @@ -127,7 +127,7 @@ gitea_federation_enabled: false # Packages gitea_packages_enabled: false # actions -gitea_actions_enabled: false +gitea_actions_enabled: true gitea_extra_config: | ; webhook: wird für drone benötigt, sonst wird der Webhook nicht "gesendet" [webhook] diff --git a/group_vars/munin.yml b/group_vars/munin.yml index 25b109ae..6fbfc29d 100644 --- a/group_vars/munin.yml +++ b/group_vars/munin.yml @@ -42,6 +42,7 @@ munin_node_bind_port: "4949" munin_node_allowed_cidrs: [127.0.0.1] ### mgrote_munin_master +munin_mode: cgi # or cron munin_mail_user: munin@mgrote.net munin_mail_server: "{{ postfix_smtp_server }}" munin_mail_port: "{{ 1025 }}" diff --git a/host_vars/docker10.mgrote.net.yml b/host_vars/docker10.mgrote.net.yml index a614829e..97d8de94 100644 --- a/host_vars/docker10.mgrote.net.yml +++ b/host_vars/docker10.mgrote.net.yml @@ -67,6 +67,8 @@ compose_files: network: traefik - name: gramps state: present + - name: act-runner + state: present ### oefenweb.ufw ufw_rules: diff --git a/host_vars/pbs.mgrote.net.yml b/host_vars/pbs.mgrote.net.yml index 85e84a22..f9315299 100644 --- a/host_vars/pbs.mgrote.net.yml +++ b/host_vars/pbs.mgrote.net.yml @@ -68,6 +68,7 @@ zfs_extra_zfs_pools: ### mgrote_zfs_sanoid sanoid_snaps_enable: true + ## syncoid sanoid_syncoid_destination_host: true sanoid_syncoid_ssh_privkey: "{{ lookup('viczem.keepass.keepass', 'sanoid_syncoid_private_key', 'notes') }}" diff --git a/keepass_db.kdbx b/keepass_db.kdbx index ce6855d3..0c13e0fd 100644 Binary files a/keepass_db.kdbx and b/keepass_db.kdbx differ diff --git a/roles/mgrote_munin_server/defaults/main.yml b/roles/mgrote_munin_server/defaults/main.yml index 13509f1e..aea18e28 100644 --- a/roles/mgrote_munin_server/defaults/main.yml +++ b/roles/mgrote_munin_server/defaults/main.yml @@ -6,20 +6,14 @@ munin_packages: - wget - libapache2-mod-fcgid - libcgi-fast-perl - - ssmtp - perl - mailutils - curl - tzdata - munin-node + - s-nail - libfile-readbackwards-perl munin_servername: "{{ ansible_fqdn }}.mgrote.net" -munin_dirs: - - /var/run/munin - - /etc/munin/plugins - - /var/cache/munin/www - - /var/lib/munin - - /var/cache/munin munin_server_plugins: - munin_stats - munin_update @@ -27,10 +21,6 @@ munin_cron_job: present munin_dbdir: "/var/lib/munin" munin_enable_alerts: false -munin_mail_server: mail.server.com -munin_mail_port: 25 -munin_mail_tls: false -munin_alerts_to: nobody@nowhere.com munin_mode: cgi # or cron diff --git a/roles/mgrote_munin_server/tasks/main.yml b/roles/mgrote_munin_server/tasks/main.yml index 7f605c54..ecce6fdc 100644 --- a/roles/mgrote_munin_server/tasks/main.yml +++ b/roles/mgrote_munin_server/tasks/main.yml @@ -7,21 +7,48 @@ - name: Ensure needed dirs exists ansible.builtin.file: - path: "{{ item }}" + path: "{{ item.name }}" state: directory - mode: '0755' - owner: munin - group: munin - loop: "{{ munin_dirs }}" - -- name: Ensure permissions are set - ansible.builtin.file: - path: /var/lib/munin/cgi-tmp - mode: 'ugo+rw' - state: directory - owner: munin - group: munin - recurse: true + mode: "{{ item.mode }}" + owner: "{{ item.owner }}" + group: "{{ item.group }}" + recurse: "{{ item.recurse }}" + loop: + - name: /var/run/munin + mode: '0755' + owner: munin + group: munin + recurse: false + - name: /var/lib/munin-node/plugin-state + mode: '0775' + owner: munin + group: munin + recurse: false + - name: /etc/munin/plugins + mode: '0755' + owner: munin + group: munin + recurse: false + - name: /var/cache/munin/www + mode: '0755' + owner: munin + group: root + recurse: false + - name: /var/lib/munin + mode: '0755' + owner: munin + group: munin + recurse: false + - name: /var/cache/munin + mode: '0755' + owner: root + group: root + recurse: false + - name: /var/lib/munin/cgi-tmp # TODO, ist immer changed + mode: "0775" + owner: munin + group: www-data + recurse: true - name: Template apache config ansible.builtin.template: @@ -32,10 +59,17 @@ group: root notify: "restart apache2" -- name: Enable fgcid +- name: "apache2: enable rewrite" + community.general.apache2_module: + state: present + name: rewrite + notify: "restart apache2" + +- name: "apache2: enable rewrite" community.general.apache2_module: state: present name: fcgid + notify: "restart apache2" - name: Template munin-server plugins ansible.builtin.template: @@ -61,6 +95,7 @@ line: "*/5 * * * * munin if [ -x /usr/bin/munin-cron ]; then /usr/bin/munin-cron; fi" create: true mode: '0644' + notify: "restart munin" - name: check if munin has been run ansible.builtin.stat: @@ -75,12 +110,4 @@ owner: munin group: munin when: not placeholder.stat.exists - -- name: Template ssmtp config - ansible.builtin.template: - src: ssmtp.conf - dest: /etc/ssmtp/ssmtp.conf - mode: '0644' - owner: root - group: root ... diff --git a/roles/mgrote_munin_server/templates/apache.conf b/roles/mgrote_munin_server/templates/apache.conf index 4d21bc08..c883f2c0 100644 --- a/roles/mgrote_munin_server/templates/apache.conf +++ b/roles/mgrote_munin_server/templates/apache.conf @@ -1,24 +1,37 @@ ServerName {{ munin_servername }} - # Redirect requests without /munin to /munin - RedirectMatch ^/$ /munin/ + DocumentRoot /var/www - # Existing configuration for serving /munin - Alias /munin /var/cache/munin/www - - Require all granted - Options None + # Rewrite rules to serve traffic from the root instead of /munin-cgi + RewriteEngine On + # Static files + RewriteRule ^/favicon.ico /var/cache/munin/www/static/favicon.ico [L] + RewriteRule ^/static/(.*) /var/cache/munin/www/static/$1 [L] + # HTML + RewriteRule ^(/.*\.html)?$ /munin-cgi/munin-cgi-html/$1 [PT] + # Images + RewriteRule ^/munin-cgi/munin-cgi-graph/(.*) /$1 + RewriteCond %{REQUEST_URI} !^/static + RewriteRule ^/(.*.png)$ /munin-cgi/munin-cgi-graph/$1 [L,PT] + ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph + ScriptAlias /munin-cgi/munin-cgi-html /usr/lib/munin/cgi/munin-cgi-html + + + Require all granted - ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph - - Require all granted - - SetHandler fcgid-script - - - SetHandler cgi-script - - + + Require all granted + + + + Require all granted + + SetHandler fcgid-script + + + SetHandler cgi-script + + diff --git a/roles/mgrote_munin_server/templates/munin.conf b/roles/mgrote_munin_server/templates/munin.conf index 1d8effa0..5924073b 100644 --- a/roles/mgrote_munin_server/templates/munin.conf +++ b/roles/mgrote_munin_server/templates/munin.conf @@ -91,7 +91,7 @@ html_strategy {{ munin_mode }} # something changes (OK -> WARNING, CRITICAL -> OK, etc) # test with: sudo -u munin /usr/share/munin/munin-limits --contact someuser --force {% if munin_enable_alerts is sameas true %} -contact.someuser.command mail -aFROM:munin@mgrote.net -s "Munin ${var:worst}: ${var:group}::${var:host}::${var:plugin}" {{ munin_alerts_to }} +contact.someuser.command s-nail --set=from='munin@mgrote.net' -s "Munin ${var:worst}: ${var:group}::${var:host}::${var:plugin}" {{ munin_alerts_to }} {% endif %} #contact.anotheruser.command mail -s "Munin ${var:worst}: ${var:group}::${var:host}::${var:plugin}" anotheruser@blibb.comm # diff --git a/roles/mgrote_munin_server/templates/ssmtp.conf b/roles/mgrote_munin_server/templates/ssmtp.conf deleted file mode 100644 index 27a5b091..00000000 --- a/roles/mgrote_munin_server/templates/ssmtp.conf +++ /dev/null @@ -1,12 +0,0 @@ -# The user that gets all the mails (UID < 1000, usually the admin) -root={{ munin_alerts_to }} - -# The mail server (where the mail is sent to), both port 465 or 587 should be acceptable -# See also https://support.google.com/mail/answer/78799 -mailhub={{ munin_mail_server }}:{{ munin_mail_port }} - -# The full hostname. Must be correctly formed, fully qualified domain name or GMail will reject connection. -hostname={{ munin_servername }} - -# Use implicit TLS (port 465). When using port 587, change UseSTARTTLS=Yes -UseTLS={{ munin_mail_tls }} diff --git a/roles/mgrote_users/tasks/main.yml b/roles/mgrote_users/tasks/main.yml index 28c0d77a..e7a76f47 100644 --- a/roles/mgrote_users/tasks/main.yml +++ b/roles/mgrote_users/tasks/main.yml @@ -1,7 +1,7 @@ --- - name: set groups as list ansible.builtin.set_fact: - groups_as_list: "{{ (groups_as_list | default([]) + item.groups.split(',')) | map('trim') | list | sort | unique }}" + groups_as_list: "{{ (((((groups_as_list | default([]) + item.groups.split(','))) | map('trim')) | list) | sort) | unique }}" loop: '{{ users }}' when: item.groups is defined diff --git a/roles/mgrote_zfs_sanoid/defaults/main.yml b/roles/mgrote_zfs_sanoid/defaults/main.yml index 73f17eda..78cf8310 100644 --- a/roles/mgrote_zfs_sanoid/defaults/main.yml +++ b/roles/mgrote_zfs_sanoid/defaults/main.yml @@ -3,8 +3,6 @@ sanoid_timer: '*-*-* *:00/5' ### when should syncoid be run sanoid_syncoid_timer: '*-*-* *:00:00' -### where to download the package -sanoid_deb_url: http://docker10.mgrote.net:3344/sanoid_3.0.0.deb # ### "Default" Datasets # sanoid_datasets: # dictionary @@ -31,7 +29,6 @@ sanoid_deb_url: http://docker10.mgrote.net:3344/sanoid_3.0.0.deb sanoid_user: sanoid sanoid_user_group: sanoid - ### enable/disable features ## enable snapshotting # sanoid_snaps_enable: true diff --git a/roles/mgrote_zfs_sanoid/tasks/main.yml b/roles/mgrote_zfs_sanoid/tasks/main.yml index 32fce206..30e0bbd1 100644 --- a/roles/mgrote_zfs_sanoid/tasks/main.yml +++ b/roles/mgrote_zfs_sanoid/tasks/main.yml @@ -11,13 +11,18 @@ - libcapture-tiny-perl - pv - libconfig-ini-perl + - sanoid state: present -- name: install packages from self-build +- name: Overwrite syncoid script from package become: true - ansible.builtin.apt: - deb: "{{ sanoid_deb_url }}" - state: present + ansible.builtin.get_url: + url: https://raw.githubusercontent.com/jimsalterjrs/sanoid/master/syncoid + dest: /usr/bin/syncoid + mode: '0755' + owner: root + group: root + force: true - name: create sanoid directories become: true diff --git a/roles/mgrote_zfs_sanoid/templates/syncoid.sh.j2 b/roles/mgrote_zfs_sanoid/templates/syncoid.sh.j2 index 6394ffae..68b2f752 100644 --- a/roles/mgrote_zfs_sanoid/templates/syncoid.sh.j2 +++ b/roles/mgrote_zfs_sanoid/templates/syncoid.sh.j2 @@ -8,5 +8,5 @@ # check if source host is reachable ping -c1 -W1 {{ item.source_host }} > /dev/null || {{ item.source_host }} not reachable! # syncoid -export HOME=/root ; /usr/bin/syncoid --compress=zstd-fast --sshoption=StrictHostKeyChecking=no --delete-target-snapshots --use-hold --preserve-recordsize --sshkey "/etc/sanoid/.ssh/id_sanoid" --source-bwlimit {{ sanoid_syncoid_bwlimit }} {{ sanoid_user }}@{{ item.source_host }}:{{ item.source_dataset }} {{ item.destination_dataset }} 2> /dev/null +export HOME=/root ; /usr/bin/syncoid --compress=zstd-fast --sshoption=StrictHostKeyChecking=no --delete-target-snapshots --use-hold --preserve-recordsize --sshkey "/etc/sanoid/.ssh/id_sanoid" --source-bwlimit {{ sanoid_syncoid_bwlimit }} {{ sanoid_user }}@{{ item.source_host }}:{{ item.source_dataset }} {{ item.destination_dataset }} {% endfor %}