From 0a73bc63b394545e8c372fd334aeb555e14f9ad6 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 1 Oct 2024 14:14:51 +0200 Subject: [PATCH] refs #8025 #7892 roles debian-once & debian-host, sysctl, README, environment --- .gitignore | 3 +- README.md | 13 +- ansible.cfg | 2 +- collections/requirements.yml | 6 - context/Dockerfile | 83 ++++++++++++ execution-environment.yml | 4 + inventories/group_vars/all.yml | 4 +- playbooks/debian-once.yml | 5 + playbooks/debian.yml | 4 + playbooks/passbolt.yml | 6 +- requirements.txt | 1 - roles/debian-base/tasks/defuser.yaml | 5 + roles/debian-base/tasks/main.yml | 2 + roles/debian-base/tasks/root.yaml | 9 -- roles/debian-host/files/sysctl/30-basic.conf | 4 + .../debian-host/files/sysctl/40-network.conf | 7 + roles/debian-host/files/sysctl/42-noipv6.conf | 3 + roles/debian-host/handlers/main.yml | 4 + roles/debian-host/tasks/hostname.yml | 12 ++ roles/debian-host/tasks/main.yml | 4 + roles/debian-host/tasks/resolv.yml | 9 ++ roles/debian-host/tasks/sysctl.yml | 8 ++ .../templates/resolv.conf} | 4 +- roles/debian-once/defaults/main.yaml | 1 + roles/debian-once/tasks/main.yml | 4 + roles/debian-once/tasks/root.yml | 14 ++ roles/debian-once/tasks/ssh.yml | 10 ++ roles/linux-hostname/tasks/main.yml | 23 ---- roles/linux-hostname/templates/hosts.j2 | 5 - roles/pve/files/nrpe/check_chrony | 127 ++++++++++++++++++ roles/pve/files/nrpe/check_smartdisk.sh | 22 +++ roles/pve/files/nrpe/check_zfs.pl | 120 +++++++++++++++++ roles/pve/tasks/main.yml | 9 ++ .../handlers/main.yml | 0 .../tasks/main.yml | 0 .../vars/main.yaml | 0 vault-playbook.sh | 1 + 37 files changed, 482 insertions(+), 56 deletions(-) create mode 100644 context/Dockerfile create mode 100644 execution-environment.yml create mode 100644 playbooks/debian-once.yml create mode 100644 roles/debian-base/tasks/defuser.yaml delete mode 100644 roles/debian-base/tasks/root.yaml create mode 100644 roles/debian-host/files/sysctl/30-basic.conf create mode 100644 roles/debian-host/files/sysctl/40-network.conf create mode 100644 roles/debian-host/files/sysctl/42-noipv6.conf create mode 100644 roles/debian-host/handlers/main.yml create mode 100644 roles/debian-host/tasks/hostname.yml create mode 100644 roles/debian-host/tasks/main.yml create mode 100644 roles/debian-host/tasks/resolv.yml create mode 100644 roles/debian-host/tasks/sysctl.yml rename roles/{linux-hostname/templates/resolv.j2 => debian-host/templates/resolv.conf} (60%) create mode 100644 roles/debian-once/defaults/main.yaml create mode 100644 roles/debian-once/tasks/main.yml create mode 100644 roles/debian-once/tasks/root.yml create mode 100644 roles/debian-once/tasks/ssh.yml delete mode 100644 roles/linux-hostname/tasks/main.yml delete mode 100644 roles/linux-hostname/templates/hosts.j2 create mode 100755 roles/pve/files/nrpe/check_chrony create mode 100755 roles/pve/files/nrpe/check_smartdisk.sh create mode 100755 roles/pve/files/nrpe/check_zfs.pl rename roles/{linux-secure-grub => secure-grub}/handlers/main.yml (100%) rename roles/{linux-secure-grub => secure-grub}/tasks/main.yml (100%) rename roles/{linux-secure-grub => secure-grub}/vars/main.yaml (100%) diff --git a/.gitignore b/.gitignore index 644b295..6bea6c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vscode/ .vaultpass -.pyenv +venv +context/_build diff --git a/README.md b/README.md index 5040b75..86bb730 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,9 @@ ansible-galaxy collection install -r collections/requirements.yml Create Python virtual environment. ``` -python3 -m venv .pyenv -source .pyenv/bin/activate +python3 -m venv venv +source venv/bin/activate +pip install --upgrade pip ansible==10.1.0 ansible-builder==3.1.0 pip install -r requirements.txt ``` @@ -45,6 +46,13 @@ ansible-vault {view,edit} --vault-pass-file .vaultpass vault.yml When running playbooks that use the vault the *vault-playbook.sh* script can be used, it is ovelay over the original *ansible-playbook* command. +## Create execution environment + +Create an image with *ansible-builder* and upload it to registry. +``` +ansible-builder build --tag ansible-runner:vn1 +``` + ## Common playbooks * **facts.yml**: Collect and display facts from a host @@ -59,3 +67,4 @@ be used, it is ovelay over the original *ansible-playbook* command. * https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_vars_facts.html * https://www.passbolt.com/blog/managing-secrets-in-ansible-using-passbolt * https://galaxy.ansible.com/ui/repo/published/anatomicjc/passbolt/ +* https://www.ansible.com/blog/introduction-to-ansible-builder/ diff --git a/ansible.cfg b/ansible.cfg index 8dd7b9f..c4aa65a 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -2,7 +2,7 @@ remote_user = root host_key_checking = False roles_path = ./roles -inventory = ./inventories/servers +inventory = ./inventories/lab gathering = smart interpreter_python = auto_silent diff --git a/collections/requirements.yml b/collections/requirements.yml index ec5156f..a97df8d 100644 --- a/collections/requirements.yml +++ b/collections/requirements.yml @@ -1,10 +1,4 @@ collections: -- name: community.general - version: '>=9.0.0' - type: galaxy -- name: ansible.posix - version: '>=1.5.4' - type: galaxy - name: ansible.utils version: '>=4.1.0' type: galaxy diff --git a/context/Dockerfile b/context/Dockerfile new file mode 100644 index 0000000..c94e222 --- /dev/null +++ b/context/Dockerfile @@ -0,0 +1,83 @@ +ARG EE_BASE_IMAGE="quay.io/ansible/ansible-runner:latest" +ARG PYCMD="/usr/bin/python3" +ARG PKGMGR_PRESERVE_CACHE="" +ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS="" +ARG ANSIBLE_GALAXY_CLI_ROLE_OPTS="" +ARG PKGMGR="/usr/bin/dnf" + +# Base build stage +FROM $EE_BASE_IMAGE as base +USER root +ENV PIP_BREAK_SYSTEM_PACKAGES=1 +ARG EE_BASE_IMAGE +ARG PYCMD +ARG PKGMGR_PRESERVE_CACHE +ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS +ARG ANSIBLE_GALAXY_CLI_ROLE_OPTS +ARG PKGMGR + +COPY _build/scripts/ /output/scripts/ +COPY _build/scripts/entrypoint /opt/builder/bin/entrypoint +RUN /output/scripts/pip_install $PYCMD + +# Galaxy build stage +FROM base as galaxy +ARG EE_BASE_IMAGE +ARG PYCMD +ARG PKGMGR_PRESERVE_CACHE +ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS +ARG ANSIBLE_GALAXY_CLI_ROLE_OPTS +ARG PKGMGR + +RUN /output/scripts/check_galaxy +COPY _build /build +WORKDIR /build + +RUN mkdir -p /usr/share/ansible +RUN ansible-galaxy role install $ANSIBLE_GALAXY_CLI_ROLE_OPTS -r requirements.yml --roles-path "/usr/share/ansible/roles" +RUN ANSIBLE_GALAXY_DISABLE_GPG_VERIFY=1 ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path "/usr/share/ansible/collections" + +# Builder build stage +FROM base as builder +ENV PIP_BREAK_SYSTEM_PACKAGES=1 +WORKDIR /build +ARG EE_BASE_IMAGE +ARG PYCMD +ARG PKGMGR_PRESERVE_CACHE +ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS +ARG ANSIBLE_GALAXY_CLI_ROLE_OPTS +ARG PKGMGR + +RUN $PYCMD -m pip install --no-cache-dir bindep pyyaml packaging + +COPY --from=galaxy /usr/share/ansible /usr/share/ansible + +COPY _build/requirements.txt requirements.txt +RUN $PYCMD /output/scripts/introspect.py introspect --user-pip=requirements.txt --write-bindep=/tmp/src/bindep.txt --write-pip=/tmp/src/requirements.txt +RUN /output/scripts/assemble + +# Final build stage +FROM base as final +ENV PIP_BREAK_SYSTEM_PACKAGES=1 +ARG EE_BASE_IMAGE +ARG PYCMD +ARG PKGMGR_PRESERVE_CACHE +ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS +ARG ANSIBLE_GALAXY_CLI_ROLE_OPTS +ARG PKGMGR + +RUN /output/scripts/check_ansible $PYCMD + +COPY --from=galaxy /usr/share/ansible /usr/share/ansible + +COPY --from=builder /output/ /output/ +RUN /output/scripts/install-from-bindep && rm -rf /output/wheels +RUN chmod ug+rw /etc/passwd +RUN mkdir -p /runner && chgrp 0 /runner && chmod -R ug+rwx /runner +WORKDIR /runner +RUN $PYCMD -m pip install --no-cache-dir 'dumb-init==1.2.5' +RUN rm -rf /output +LABEL ansible-execution-environment=true +USER 1000 +ENTRYPOINT ["/opt/builder/bin/entrypoint", "dumb-init"] +CMD ["bash"] diff --git a/execution-environment.yml b/execution-environment.yml new file mode 100644 index 0000000..f6977c8 --- /dev/null +++ b/execution-environment.yml @@ -0,0 +1,4 @@ +version: 3 +dependencies: + galaxy: collections/requirements.yml + python: requirements.txt diff --git a/inventories/group_vars/all.yml b/inventories/group_vars/all.yml index 22824da..c53863f 100644 --- a/inventories/group_vars/all.yml +++ b/inventories/group_vars/all.yml @@ -9,9 +9,7 @@ main_dns_server: ns1.verdnatura.es ldap_uri: ldap://ldap.verdnatura.es ldap_base: dc=verdnatura,dc=es dc_net: "10.0.0.0/16" -resolv: - domain: verdnatura.es - search: verdnatura.es +resolv_domain: verdnatura.es resolvers: - '10.0.0.4' - '10.0.0.5' diff --git a/playbooks/debian-once.yml b/playbooks/debian-once.yml new file mode 100644 index 0000000..1a59ea0 --- /dev/null +++ b/playbooks/debian-once.yml @@ -0,0 +1,5 @@ +- name: First time host configuration + hosts: all + tasks: + - import_role: + name: debian-once diff --git a/playbooks/debian.yml b/playbooks/debian.yml index 4888a35..3531330 100644 --- a/playbooks/debian.yml +++ b/playbooks/debian.yml @@ -13,3 +13,7 @@ import_role: name: debian-qemu when: ansible_virtualization_role == 'guest' and ansible_virtualization_type == 'kvm' + - name: Configure virtual machine or host + import_role: + name: debian-host + when: ansible_virtualization_role == 'host' or ansible_virtualization_type == 'kvm' diff --git a/playbooks/passbolt.yml b/playbooks/passbolt.yml index 20ec1cc..792e858 100644 --- a/playbooks/passbolt.yml +++ b/playbooks/passbolt.yml @@ -1,10 +1,10 @@ - name: Fetch passbolt password hosts: all gather_facts: no + vars: + passbolt: 'anatomicjc.passbolt.passbolt' + passbolt_inventory: 'anatomicjc.passbolt.passbolt_inventory' tasks: - name: Print password debug: msg: "Variable: {{ lookup(passbolt, 'test') }}" - vars: - passbolt: 'anatomicjc.passbolt.passbolt' - passbolt_inventory: 'anatomicjc.passbolt.passbolt_inventory' diff --git a/requirements.txt b/requirements.txt index 7915399..c0ee91b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ py-passbolt==0.0.18 cryptography==3.3.2 -ansible==2.1.0 diff --git a/roles/debian-base/tasks/defuser.yaml b/roles/debian-base/tasks/defuser.yaml new file mode 100644 index 0000000..b41897b --- /dev/null +++ b/roles/debian-base/tasks/defuser.yaml @@ -0,0 +1,5 @@ +- name: Delete default user + user: + name: "{{ default_user }}" + state: absent + remove: yes diff --git a/roles/debian-base/tasks/main.yml b/roles/debian-base/tasks/main.yml index 0e3ba90..405ee97 100644 --- a/roles/debian-base/tasks/main.yml +++ b/roles/debian-base/tasks/main.yml @@ -1,3 +1,5 @@ +- import_tasks: defuser.yml + tags: defuser - import_tasks: install.yml tags: install - import_tasks: locale.yml diff --git a/roles/debian-base/tasks/root.yaml b/roles/debian-base/tasks/root.yaml deleted file mode 100644 index 0bb8a91..0000000 --- a/roles/debian-base/tasks/root.yaml +++ /dev/null @@ -1,9 +0,0 @@ -- name: Delete default user - user: - name: "{{ default_user }}" - state: absent - remove: yes -- name: Change root password - user: - name: root - password: "{{ root_password | password_hash('sha512') }}" diff --git a/roles/debian-host/files/sysctl/30-basic.conf b/roles/debian-host/files/sysctl/30-basic.conf new file mode 100644 index 0000000..3c6f393 --- /dev/null +++ b/roles/debian-host/files/sysctl/30-basic.conf @@ -0,0 +1,4 @@ +vm.swappiness=10 +vm.dirty_ratio=30 +vm.dirty_background_ratio=5 +net.core.somaxconn=65536 diff --git a/roles/debian-host/files/sysctl/40-network.conf b/roles/debian-host/files/sysctl/40-network.conf new file mode 100644 index 0000000..46a4e09 --- /dev/null +++ b/roles/debian-host/files/sysctl/40-network.conf @@ -0,0 +1,7 @@ +net.core.rmem_max=134217728 +net.core.wmem_max=134217728 +net.core.netdev_max_backlog=250000 +net.ipv4.tcp_rmem=4096 87380 67108864 +net.ipv4.tcp_wmem=4096 65536 67108864 +net.ipv4.tcp_congestion_control=htcp +net.ipv4.tcp_mtu_probing=1 diff --git a/roles/debian-host/files/sysctl/42-noipv6.conf b/roles/debian-host/files/sysctl/42-noipv6.conf new file mode 100644 index 0000000..81073be --- /dev/null +++ b/roles/debian-host/files/sysctl/42-noipv6.conf @@ -0,0 +1,3 @@ +net.ipv6.conf.all.disable_ipv6=1 +net.ipv6.conf.default.disable_ipv6=1 +net.ipv6.conf.lo.disable_ipv6=1 \ No newline at end of file diff --git a/roles/debian-host/handlers/main.yml b/roles/debian-host/handlers/main.yml new file mode 100644 index 0000000..35f2de4 --- /dev/null +++ b/roles/debian-host/handlers/main.yml @@ -0,0 +1,4 @@ +- name: restart-sysctl + service: + name: systemd-sysctl + state: restarted diff --git a/roles/debian-host/tasks/hostname.yml b/roles/debian-host/tasks/hostname.yml new file mode 100644 index 0000000..71c9e4a --- /dev/null +++ b/roles/debian-host/tasks/hostname.yml @@ -0,0 +1,12 @@ +- name: Set the hostname in /etc/hostname + hostname: + name: "{{ inventory_hostname_short }}" + use: debian +- name: Configure hostname in hosts + blockinfile: + path: /etc/hosts + marker_begin: '--- BEGIN VN ---' + marker_end: '--- END VN ---' + marker: "# {mark}" + block: | + {{ ansible_default_ipv4.address }} {{ ansible_host }} {{ inventory_hostname_short }} diff --git a/roles/debian-host/tasks/main.yml b/roles/debian-host/tasks/main.yml new file mode 100644 index 0000000..7f49737 --- /dev/null +++ b/roles/debian-host/tasks/main.yml @@ -0,0 +1,4 @@ +- import_tasks: hostname.yml + tags: hostname +- import_tasks: sysctl.yml + tags: sysctl diff --git a/roles/debian-host/tasks/resolv.yml b/roles/debian-host/tasks/resolv.yml new file mode 100644 index 0000000..9aeb5a4 --- /dev/null +++ b/roles/debian-host/tasks/resolv.yml @@ -0,0 +1,9 @@ +- name: Replace /etc/resolv.conf + template: + src: resolv.conf + dest: /etc/ + owner: root + group: root + mode: '0644' + backup: true + when: resolv_enabled diff --git a/roles/debian-host/tasks/sysctl.yml b/roles/debian-host/tasks/sysctl.yml new file mode 100644 index 0000000..be8eaf7 --- /dev/null +++ b/roles/debian-host/tasks/sysctl.yml @@ -0,0 +1,8 @@ +- name: Set systctl configuration + copy: + src: sysctl/ + dest: /etc/sysctl.d/ + owner: root + group: root + mode: u=rw,g=r,o=r + notify: restart-sysctl diff --git a/roles/linux-hostname/templates/resolv.j2 b/roles/debian-host/templates/resolv.conf similarity index 60% rename from roles/linux-hostname/templates/resolv.j2 rename to roles/debian-host/templates/resolv.conf index b137dc2..cce81b4 100644 --- a/roles/linux-hostname/templates/resolv.j2 +++ b/roles/debian-host/templates/resolv.conf @@ -1,5 +1,5 @@ -domain {{ resolv.domain }} -search {{ resolv.search }} +domain {{ resolv_domain }} +search {{ resolv_domain }} {% if resolvers is defined %} {% for resolver in resolvers %} nameserver {{resolver}} diff --git a/roles/debian-once/defaults/main.yaml b/roles/debian-once/defaults/main.yaml new file mode 100644 index 0000000..a0671ab --- /dev/null +++ b/roles/debian-once/defaults/main.yaml @@ -0,0 +1 @@ +root_password: Pa$$w0rd diff --git a/roles/debian-once/tasks/main.yml b/roles/debian-once/tasks/main.yml new file mode 100644 index 0000000..b77c6fc --- /dev/null +++ b/roles/debian-once/tasks/main.yml @@ -0,0 +1,4 @@ +- import_tasks: ssh.yml + tags: ssh +- import_tasks: root.yml + tags: root diff --git a/roles/debian-once/tasks/root.yml b/roles/debian-once/tasks/root.yml new file mode 100644 index 0000000..654b2b4 --- /dev/null +++ b/roles/debian-once/tasks/root.yml @@ -0,0 +1,14 @@ +- name: Generate a random root password + set_fact: + root_password: "{{ lookup('password', '/dev/null length=18 chars=ascii_letters,digits') }}" +- name: Save the root password to a file + copy: + content: "{{ root_password }}\n" + dest: /root/root_password.txt + owner: root + group: root + mode: '0600' +- name: Change root password + user: + name: root + password: "{{ root_password | password_hash('sha512') }}" diff --git a/roles/debian-once/tasks/ssh.yml b/roles/debian-once/tasks/ssh.yml new file mode 100644 index 0000000..84877cc --- /dev/null +++ b/roles/debian-once/tasks/ssh.yml @@ -0,0 +1,10 @@ +- name: Delete old host SSH keys + file: + path: "{{ item }}" + state: absent + with_items: + - /etc/ssh/ssh_host_ecdsa_key + - /etc/ssh/ssh_host_ed25519_key + - /etc/ssh/ssh_host_rsa_key +- name: Regenerate host SSH keys + command: dpkg-reconfigure openssh-server diff --git a/roles/linux-hostname/tasks/main.yml b/roles/linux-hostname/tasks/main.yml deleted file mode 100644 index e052922..0000000 --- a/roles/linux-hostname/tasks/main.yml +++ /dev/null @@ -1,23 +0,0 @@ -# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/hostname_module.html#ansible-collections-ansible-builtin-hostname-module - -- name: Set the hostname in /etc/hostname - ansible.builtin.hostname: - name: "{{ hostname }}" - use: debian -- name: Replace /etc/hosts - template: - src: hosts.j2 - dest: /etc/hosts - owner: root - group: root - mode: '0644' - backup: true -- name: Replace /etc/resolv.conf - template: - src: resolv.j2 - dest: /etc/resolv.conf - owner: root - group: root - mode: '0644' - backup: true - when: resolv_enabled diff --git a/roles/linux-hostname/templates/hosts.j2 b/roles/linux-hostname/templates/hosts.j2 deleted file mode 100644 index d071be4..0000000 --- a/roles/linux-hostname/templates/hosts.j2 +++ /dev/null @@ -1,5 +0,0 @@ -{% if hosts is defined %} -{% for host in hosts %} -{{host.ip}} {{hostname}} -{% endfor %} -{% endif %} \ No newline at end of file diff --git a/roles/pve/files/nrpe/check_chrony b/roles/pve/files/nrpe/check_chrony new file mode 100755 index 0000000..bd8cd5d --- /dev/null +++ b/roles/pve/files/nrpe/check_chrony @@ -0,0 +1,127 @@ +#!/usr/bin/env perl +#=============================================================================== +# DESCRIPTION: Icinga2 / Nagios Check for chrony time sync status and offset +# +# OPTIONS: -h : Help +# -w [warning threshold in seconds] +# -c [critical threshold in seconds] +# +# REQUIREMENTS: Chrony, perl version 5.10.1+ +# +# AUTHOR: Dennis Ullrich (request@decstasy.de) +# +# BUGS ETC: https://github.com/Decstasy/check_chrony +# +# LICENSE: GPL v3 (GNU General Public License, Version 3) +# see https://www.gnu.org/licenses/gpl-3.0.txt +#=============================================================================== + +use 5.10.1; +use strict; +use warnings; +use utf8; +use Getopt::Std; + +# +# Variables +# +my $chronyDaemonName = "chronyd"; +my $leapOk = "Normal"; + +my $rc = 3; +my $msg= ""; +my $perfdata = ""; + +# +# Subroutines +# + +sub help { + print "check_chrony [options] + -w [warning threshold in seconds] + -c [critical threshold in seconds] + e.g.: check_chrony -w 0.6 -c 2\n"; + exit(3); +} + +# Script exit with Nagios / Icinga typical output +sub _exit { + my ( $return, $line ) = @_; + my @state = ( "OK", "WARNING", "CRITICAL", "UNKNOWN" ); + print "$state[$return]: $line\n"; + exit( $return ); +} + +# Checks if a process with $_[0] as name exists +sub proc_exists { + my $PID = `ps -C $_[0] -o pid=`; + if ( ${^CHILD_ERROR_NATIVE} == 0 ){ + return 1; + } + return 0; +} + +# +# Options +# + +my %options=(); +getopts( "hw:c:", \%options ); + +# Check input +if ( keys %options == 0 || defined $options{h} ){ + &help; +} + +for my $key ( keys %options ){ + if ( $options{$key} !~ /^[\d\.]+$/ ){ + &_exit( 3, "Value of option -$key is not a valid number!" ); + } +} + +# +# Check chrony process +# + +&_exit( 2, "$chronyDaemonName is not running!" ) if not &proc_exists( $chronyDaemonName ); + +# +# Get tracking data +# + +my $chronyOutput = `chronyc tracking`; +&_exit( 3, "Chronyc tracking command failed!" ) if ${^CHILD_ERROR_NATIVE} != 0; + +my ( $offset, $dir ) = $chronyOutput =~ /(?:System\stime)[^\d]+([\d\.]+)(?:.*?)(fast|slow)/; +my ( $leap ) = $chronyOutput =~ /(?:Leap)[^\:]+(?::\s+)([\w\h]+)/; + +# +# Check stuff +# + +# Check offset +if ( $offset >= $options{"c"} ){ + $rc = 2; # Critical +} +elsif ( $offset >= $options{"w"} ){ + $rc = 1; # Warning +} +else { + $rc = 0; # Ok +} + +# Prepare offset performace data +$offset = $dir =~ "slow" ? "-$offset" : "+$offset"; +$msg = sprintf( "Time offset of %+.9f seconds to reference.", $offset); +$perfdata = sprintf( "|offset=%.9fs;%.9f;%.9f", ${offset}, $options{'w'}, $options{'c'}); + +# Check leap +if( $leap !~ $leapOk ){ + &_exit( 2, "Chrony leap status \"$leap\" is not equal to \"$leapOk\"! $msg $perfdata" ); +} + +# +# Return stuff +# + +&_exit($rc, "$msg $perfdata"); diff --git a/roles/pve/files/nrpe/check_smartdisk.sh b/roles/pve/files/nrpe/check_smartdisk.sh new file mode 100755 index 0000000..605ea12 --- /dev/null +++ b/roles/pve/files/nrpe/check_smartdisk.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Checks status of disks SMART + +STATUS_LABEL="SMART Health Status:" +STATUS_OK="$STATUS_LABEL OK" + +if [[ "$#" == "0" ]]; then + echo "Usage: $0 [ ... ]" + exit +fi + +for DISK in "$@" +do + STATUS=$(sudo /usr/sbin/smartctl -H -d scsi "$DISK" | grep "$STATUS_LABEL") + + if [ "$STATUS" != "$STATUS_OK" ]; then + echo "CRITICAL: $DISK: $STATUS" + exit 2 + fi +done + +echo "OK: $STATUS_OK" diff --git a/roles/pve/files/nrpe/check_zfs.pl b/roles/pve/files/nrpe/check_zfs.pl new file mode 100755 index 0000000..88dc1d9 --- /dev/null +++ b/roles/pve/files/nrpe/check_zfs.pl @@ -0,0 +1,120 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use English; + +$ENV{'PATH'} = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; + +use constant N_OK => 0; +use constant N_WARNING => 1; +use constant N_CRITICAL => 2; +use constant N_MSG => [ "OK", "WARNING", "CRITICAL" ]; + +my @zpool = (); + +sub get_pools() { + local *P; + my $zpool_cmd = $EUID == 0 ? "zpool" : "sudo zpool"; + open(P, $zpool_cmd . " list -H 2>&1 |") or &nagios_response("Could not find zpool command", N_CRITICAL); + while (

) { + chomp; + my @ret = split(/\s+/, $_); + push(@zpool, { + 'name' => $ret[0], + 'health' => $ret[-2], + 'size' => $ret[1], + 'alloc' => $ret[2], + 'free' => $ret[3] + }); + } + close(P); + my $rc = $?; + if ($rc != 0) { + &nagios_response("zpool list command failed (rc=$rc)", N_CRITICAL); + } +} + +sub get_status() +{ + my $storage = shift || "unknown"; + my $cat = 0; + my $res = {}; + local *P; + my $zpool_cmd = $EUID == 0 ? "zpool" : "sudo zpool"; + open(P, $zpool_cmd . " status $storage 2>&1 |") or &nagios_response("Could not find zpool command", N_CRITICAL); + while (

) { + chomp; + if ($_ =~ /^\s*([^\s]+):\s*(.*)$/) { + $cat = $1; + $res->{"$cat"} = (); + if ($2) { + push(@{$res->{"$cat"}}, $2); + } + } elsif ($cat && $_ =~ /^\s+(.+)$/) { + push(@{$res->{"$cat"}}, $1); + } + } + close(P); + my $rc = $?; + if ($rc != 0) { + &nagios_response("zpool status command failed (rc=$rc)", N_CRITICAL); + } + return $res; +} + +sub nagios_response() +{ + my $msg = shift || "Unknown"; + my $exit_status = shift; + if (!defined($exit_status)) { + $exit_status = N_CRITICAL; + } + printf("%s %s\n", N_MSG->[$exit_status], $msg); + exit($exit_status); +} + +sub main() { + + &get_pools(); + my $exit_status = N_OK; + my @out = (); + foreach my $pool (@zpool) { + if ($pool->{'health'} eq 'DEGRADED') { + $exit_status = N_WARNING; + my $extinfo = &get_status($pool->{'name'}); + my $scanned = 0; + my $total = 0; + my $speed = 0; + my $left = 0; + my $percent = 0; + my $resilvered = 0; + if (defined($extinfo->{'scan'})) { + foreach my $line (@{$extinfo->{'scan'}}) { + if ($line =~ /^\s*([^\s]+)\s+scanned out of\s+([^\s]+)\s+at\s+([^\s]+),\s*([^\s]+)\s+to go/) { + $scanned = $1; + $total = $2; + $speed = $3; + $left = $4; + } elsif ($line =~ /^\s*([^\s]+)\s+resilvered,\s*([^\s]+)\s+done/) { + $resilvered = $1; + $percent = $2; + } + } + } + if ($scanned && length($scanned) > 2) { + push(@out, sprintf("%s(RESILVER %s,%s,%s)", $pool->{'name'}, $percent, $speed, $left)); + } else { + push(@out, sprintf("%s(%s %s/%s)", $pool->{'name'}, $pool->{'health'}, $pool->{'alloc'}, $pool->{'size'})); + } + } elsif ($pool->{'health'} ne 'ONLINE') { + $exit_status = N_WARNING; + push(@out, sprintf("%s(%s %s/%s)", $pool->{'name'}, $pool->{'health'}, $pool->{'alloc'}, $pool->{'size'})); + } else { + push(@out, sprintf("%s(%s %s/%s)", $pool->{'name'}, $pool->{'health'}, $pool->{'alloc'}, $pool->{'size'})); + } + } + &nagios_response(join(",", @out), $exit_status); +} + +&main(); diff --git a/roles/pve/tasks/main.yml b/roles/pve/tasks/main.yml index 101abcf..67fbc3a 100644 --- a/roles/pve/tasks/main.yml +++ b/roles/pve/tasks/main.yml @@ -6,6 +6,14 @@ group: root mode: u=rw,g=r,o=r notify: restart-nrpe +- name: Copy PVE NRPE plugins + copy: + src: nrpe/ + dest: /etc/nagios/plugins/ + owner: root + group: root + mode: u=rwx,g=rx,o=rx + notify: restart-nrpe - name: Add nagios to sudoers copy: src: sudoers @@ -13,6 +21,7 @@ mode: u=rw,g=r,o= owner: root group: root + notify: restart-nrpe - name: Configure memory regions copy: src: vhost.conf diff --git a/roles/linux-secure-grub/handlers/main.yml b/roles/secure-grub/handlers/main.yml similarity index 100% rename from roles/linux-secure-grub/handlers/main.yml rename to roles/secure-grub/handlers/main.yml diff --git a/roles/linux-secure-grub/tasks/main.yml b/roles/secure-grub/tasks/main.yml similarity index 100% rename from roles/linux-secure-grub/tasks/main.yml rename to roles/secure-grub/tasks/main.yml diff --git a/roles/linux-secure-grub/vars/main.yaml b/roles/secure-grub/vars/main.yaml similarity index 100% rename from roles/linux-secure-grub/vars/main.yaml rename to roles/secure-grub/vars/main.yaml diff --git a/vault-playbook.sh b/vault-playbook.sh index 0a1398a..d7e1c89 100755 --- a/vault-playbook.sh +++ b/vault-playbook.sh @@ -1,2 +1,3 @@ #!/bin/bash +export PYTHONPATH=./venv/lib/python3.12/site-packages/ ansible-playbook --vault-password-file .vaultpass $@