initial commit

This commit is contained in:
Ansible Servercow
2024-11-19 16:04:17 +01:00
commit 67c5aae913
26 changed files with 438 additions and 0 deletions

1
README.md Normal file
View File

@@ -0,0 +1 @@
This Repository contains all important playbooks/roles used for system operation automation such as updates and cleanups.

0
collections/.gitkeep Normal file
View File

View File

@@ -0,0 +1,17 @@
- name: Run Docker Cleanup (full)
hosts: all
tasks:
- include_role:
name: managed-mailcow
tasks_from: find-mailcow-composedir.yml
- include_role:
name: docker
tasks_from: get-containerstatus.yml
vars:
docker_compose_path: "{{ mailcow_dir_result.files[0].path }}"
- include_role:
name: docker
tasks_from: cleanup-all.yml
when: not 'false' in container_status.values()

View File

@@ -0,0 +1,12 @@
- name: Clean Docker Images on Host
hosts: all
tasks:
- include_role:
name: docker
tasks_from: get-containerstatus.yml
vars:
docker_compose_path: /opt/mailcow-dockerized
- include_role:
name: docker
tasks_from: cleanup-images.yml

View File

@@ -0,0 +1,8 @@
---
- name: Deploy Haveged to VMs
hosts: all
tasks:
- name: Install Haveged
apt:
name: haveged
state: present

View File

@@ -0,0 +1,26 @@
---
- name: Garbage Cleaner ändern
hosts: all
tasks:
- name: "Prüfe ob mailcow.conf exists"
ansible.builtin.stat:
path: /opt/mailcow-dockerized/mailcow.conf
register: mailcow_conf
- name: "Setze Garbage Cleaner auf 7 Tage"
ansible.builtin.replace:
path: "/opt/mailcow-dockerized/mailcow.conf"
regexp: "^MAILDIR_GC_TIME=.*"
replace: "MAILDIR_GC_TIME=10080"
backup: yes
register: gc
when: mailcow_conf.stat.exists
- name: "Starte mailcow Container neu"
ansible.builtin.shell: |
cd /opt/mailcow-dockerized
docker compose up -d
when: gc.changed

View File

@@ -0,0 +1,62 @@
- name: Fetch webpages and check response
hosts: localhost
gather_facts: false
vars:
hosts:
- "mail.ps.develcow.de"
- "mail.np.develcow.de"
tasks:
- name: Fetch webpage
uri:
url: "https://{{ item }}"
return_content: yes
register: webpage_response
loop: "{{ hosts }}"
- name: Fail if mailcow UI is not working - Skipping = OK
fail:
msg: "UI not OK"
loop: "{{ webpage_response.results }}"
when: "'showVersionModal' not in item.content"
no_log: true
ignore_errors: yes
- name: Check SMTP Port 25 connection
wait_for:
host: "{{ item }}"
port: 25
state: started
delay: 0
timeout: 3
loop: "{{ hosts }}"
ignore_errors: yes
- name: Check SUBMISSION Port 587 connection
wait_for:
host: "{{ item }}"
port: 587
state: started
delay: 0
timeout: 3
loop: "{{ hosts }}"
ignore_errors: yes
- name: Check IMAP Port 143 connection
wait_for:
host: "{{ item }}"
port: 143
state: started
delay: 0
timeout: 3
loop: "{{ hosts }}"
ignore_errors: yes
- name: Check IMAPS Port 993 connection
wait_for:
host: "{{ item }}"
port: 993
state: started
delay: 0
timeout: 3
loop: "{{ hosts }}"
ignore_errors: yes

View File

@@ -0,0 +1,33 @@
---
- name: ClamAV Server auf neuen shared ClamAV setzen
hosts: all
tasks:
- name: "Setze ClamAV Server in rspamd Config auf managed mailcows"
ansible.builtin.replace:
path: "/opt/mailcow-dockerized/data/conf/rspamd/local.d/antivirus.conf"
regexp: "^ servers = \".*\";$"
replace: " servers = \"[2a07:6fc0:c:2809::23]:3310\";"
backup: yes
register: rspamd
- name: "Setze lokalen ClamAV auf n (falls noch nicht geschehen)"
ansible.builtin.replace:
path: "/opt/mailcow-dockerized/mailcow.conf"
regexp: "^SKIP_CLAMD=.*"
replace: "SKIP_CLAMD=y"
backup: yes
register: clamd
- name: "Starte mailcow Container neu (wenn ClamAV noch nicht deaktiviert lokal)"
ansible.builtin.shell: |
cd /opt/mailcow-dockerized
docker compose up -d
when: clamd.changed
- name: "Restart Rspamd Container"
shell: |
cd /opt/mailcow-dockerized
docker compose restart rspamd-mailcow
when: rspamd.changed

View File

@@ -0,0 +1,23 @@
- name: Start/Stop mailcow
hosts: all
tasks:
- import_role:
name: managed-mailcow
tasks_from: find-mailcow-composedir.yml
- import_role:
name: managed-mailcow
tasks_from: stop-mailcow.yml
vars:
docker_compose_path: "{{ mailcow_dir_result.files[0].path }}"
verbose: true # Or False if you dont' wanna see docker's outputs
- import_role:
name: managed-mailcow
tasks_from: start-mailcow.yml
vars:
docker_compose_path: "{{ mailcow_dir_result.files[0].path }}"
verbose: true # Or False if you dont' wanna see docker's outputs

View File

@@ -0,0 +1,14 @@
- name: Update mailcow (update.sh)
hosts: all
tasks:
- import_role:
name: roles/managed-mailcow
tasks_from: find-mailcow-composedir.yml
- import_role:
name: roles/managed-mailcow
tasks_from: update-mailcow.yml
vars:
github_mailcow_ver: "2024-11b" # GitHub Version Tag | Value to compare the current running mailcow version to.
disk_space_percent_max: "97" # Number in percent | Defines the max allowed disk utilization until ansible is not updating mailcow automatically
debug: true # Or False if you dont' wanna see verbose outputs of role outputs

View File

@@ -0,0 +1,41 @@
---
- name: Update mailcow stacks
hosts: all
vars:
github_mailcow_ver: "2024-08a"
mailcow_search_paths:
- /opt
- /data
- /root
tasks:
- name: Find mailcow-dockerized directory
ansible.builtin.find:
file_type: directory
paths: "{{ mailcow_search_paths }}"
patterns: mailcow-dockerized
recurse: yes
register: mailcow_dir_result
ignore_errors: true
- name: 'DEBUG: Show file paths'
debug:
msg: "{{ mailcow_dir_result.files[0].path }}"
when: mailcow_dir_result is defined
- name: Check if mailcow.conf exists
ansible.builtin.stat:
path: "{{ mailcow_dir_result.files[0].path }}/mailcow.conf"
register: mailcow_conf
when: mailcow_dir_result is defined
- name: Check mailcow Version
ansible.builtin.shell: |
cd {{ mailcow_dir_result.files[0].path }}/data/web/inc
grep -oP '\$MAILCOW_GIT_VERSION="\K[^"]+' app_info.inc.php
register: local_mailcow_version
when: mailcow_conf.stat.exists
- name: Update mailcow
shell: "cd {{ mailcow_dir_result.files[0].path }} && git fetch && git checkout origin/master update.sh && ./update.sh --force"
when: local_mailcow_version.stdout != github_mailcow_ver and mailcow_conf.stat.exists

View File

@@ -0,0 +1,63 @@
---
- name: Update Docker Daemon configuration to use Syslog Server
hosts: all
become: yes
tasks:
- name: Read current Docker daemon.json
ansible.builtin.slurp:
src: /etc/docker/daemon.json
register: current_daemon_json
- name: Parse current Docker daemon.json
set_fact:
current_daemon_config: "{{ current_daemon_json['content'] | b64decode | from_json }}"
- name: Check current log-driver setting
set_fact:
log_driver_current: "{{ current_daemon_config['log-driver'] | default('not_set') }}"
- name: Update Docker daemon.json with syslog configuration if log-driver is local
ansible.builtin.copy:
dest: /etc/docker/daemon.json
content: "{{ updated_daemon_json | to_nice_json }}"
vars:
syslog_config: {
"log-driver": "syslog",
"log-opts": {
"syslog-address": "udp://[2a0e:b680:80::91]:5514",
"syslog-format": "rfc5424",
"tag": "{{ '{{.Name}}' }}"
}
}
updated_daemon_json: "{{ current_daemon_config | combine(syslog_config) }}"
when: log_driver_current == 'local' or log is undefined
register: daemon_update
- name: Restart Docker to apply changes
ansible.builtin.systemd:
name: docker
state: restarted
when: daemon_update.changed
- include_role:
name: managed-mailcow
tasks_from: find-mailcow-composedir.yml
when: daemon_update.changed
- name: Stop mailcow stack
import_role:
name: managed-mailcow
tasks_from: stop-mailcow.yml
vars:
docker_compose_path: "{{ mailcow_dir_result.files[0].path }}"
verbose: False
when: daemon_update.changed and mailcow_dir_result.matched > 0
- name: Start mailcow stack
import_role:
name: managed-mailcow
tasks_from: start-mailcow.yml
vars:
docker_compose_path: "{{ mailcow_dir_result.files[0].path }}"
verbose: False
when: daemon_update.changed and mailcow_dir_result.matched > 0

View File

@@ -0,0 +1,9 @@
- name: Prune everything
community.docker.docker_prune:
containers: true
images: true
networks: true
volumes: true
builder_cache: true
register: result

View File

@@ -0,0 +1,4 @@
- name: Prune images only
community.docker.docker_prune:
images: true
register: result

View File

@@ -0,0 +1,12 @@
---
- name: Ensure Docker Compose project is up
community.docker.docker_compose_v2:
project_src: "{{ docker_compose_path }}"
state: present
register: compose_status
- name: Set fact for container status
set_fact:
container_status: "{{ container_status | default({}) | combine({item.Name: (item.State == 'running')}) }}"
verbosity: 0
with_items: "{{ compose_status.containers }}"

View File

@@ -0,0 +1,5 @@
---
- name: Restart Docker Daemon
ansible.builtin.systemd:
name: docker
state: restarted

View File

@@ -0,0 +1,14 @@
---
- name: Find mailcow-dockerized directory
vars:
mailcow_search_paths:
- /opt
- /data
- /root
ansible.builtin.find:
file_type: directory
paths: "{{ mailcow_search_paths }}"
patterns: mailcow-dockerized
recurse: yes
register: mailcow_dir_result
ignore_errors: true

View File

@@ -0,0 +1,12 @@
---
- name: Start mailcow stack
community.docker.docker_compose_v2:
project_src: "{{ docker_compose_path }}"
state: present
register: output
- name: Print Replay
debug:
var: output
when: verbose | bool

View File

@@ -0,0 +1,11 @@
---
- name: Stop mailcow stack
community.docker.docker_compose_v2:
project_src: "{{ docker_compose_path }}"
state: absent
register: output
- name: Print Replay
debug:
var: output
when: verbose | bool

View File

@@ -0,0 +1,22 @@
---
- name: Check if mailcow.conf exists
ansible.builtin.stat:
path: "{{ mailcow_dir_result.files[0].path }}/mailcow.conf"
register: mailcow_conf
when: mailcow_dir_result.files[0].path is defined
- name: Check mailcow Version
ansible.builtin.shell: |
cd {{ mailcow_dir_result.files[0].path }}/data/web/inc
grep -oP '\$MAILCOW_GIT_VERSION="\K[^"]+' app_info.inc.php
register: local_mailcow_version
when: mailcow_conf.stat.exists
- name: Check Disk Utilization
import_role:
name: roles/system
tasks_from: check-disk-utilization.yaml
- name: Update mailcow
shell: "cd {{ mailcow_dir_result.files[0].path }} && git fetch && git checkout origin/master update.sh && ./update.sh --force"
when: local_mailcow_version.stdout != github_mailcow_ver and mailcow_conf.stat.exists and disk_space_output | bool

4
roles/requirements.yml Normal file
View File

@@ -0,0 +1,4 @@
---
collections:
- name: community.docker
version: 3.11.0

View File

@@ -0,0 +1,9 @@
- name: Run disk space command
ansible.builtin.shell: "df --output=used,avail / | awk 'NR==2 {used=$1; available=$2; total=used+available; percentage=used*100/total; if (percentage < {{ disk_space_percent_max }} ) printf \"true\"; else printf \"false\"}'"
# System uses the disk_space_percent_max variable to determine condition this check is getting. Over the amount defined in the var causes the check to fail!
register: disk_space_output
- name: "**DEBUG**: Server disk Utilization condition"
ansible.builtin.debug:
var: disk_space_output.stdout
when: debug | bool

View File

@@ -0,0 +1,8 @@
- name: Run apk update
ansible.builtin.apk:
update_cache: yes
register: apk_result
- name: Run Package Upgrade (apk)
ansible.builtin.apk:
upgrade: yes

View File

@@ -0,0 +1,10 @@
- name: Run Cache refresh (apt)
ansible.builtin.apt:
update_cache: yes
register: apt_result
- name: Run Package Upgrade (apt)
ansible.builtin.apt:
upgrade: dist
force: true
autoclean: true

View File

@@ -0,0 +1,15 @@
- name: APT run autoremove with purge
ansible.builtin.apt:
autoremove: yes
purge: yes
when: purge_autoremove | bool
- name: APT run autoremove without purge
ansible.builtin.apt:
autoremove: yes
purge: no
when: not purge_autoremove
- name: APT run autoclean
ansible.builtin.apt:
autoclean: yes

View File

@@ -0,0 +1,3 @@
- name: Upgrade Debian Repos to newest Major Version
task:
a