snapshot
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
**/bak.yml
|
||||
**/vault.yml
|
||||
@@ -0,0 +1,76 @@
|
||||
# AIM --- Ansible Inventory Manager
|
||||
|
||||
AIM is an operator-focused Python application for managing Ansible
|
||||
customer inventories, access configuration, Vaults and curated playbook
|
||||
execution.
|
||||
|
||||
## Source layout
|
||||
|
||||
``` text
|
||||
/etc/ansible/scripts/
|
||||
├── README.md
|
||||
├── install.md
|
||||
├── CHANGELOG.md
|
||||
├── docs/
|
||||
├── pyproject.toml
|
||||
└── src/
|
||||
└── aim/
|
||||
```
|
||||
|
||||
AIM uses `/etc/ansible/inventories/<customer>/hosts.yml` as the
|
||||
inventory source of truth.
|
||||
|
||||
## Supported platform groups
|
||||
|
||||
- `linux`
|
||||
- `windows`
|
||||
- `sophosxgs`
|
||||
- `pfsense`
|
||||
|
||||
A host can belong to multiple groups/subgroups. Platform groups remain
|
||||
the top-level groups because they define Ansible connection semantics.
|
||||
|
||||
## Quick start
|
||||
|
||||
See [install.md](install.md) for installation, virtual-environment
|
||||
setup, authorization-group configuration and recovery of Git-ignored
|
||||
runtime data.
|
||||
|
||||
Start AIM with:
|
||||
|
||||
``` bash
|
||||
aim
|
||||
```
|
||||
|
||||
Useful UI troubleshooting modes:
|
||||
|
||||
``` bash
|
||||
aim --no-clear
|
||||
aim --plain
|
||||
aim --live-output
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Installation](install.md)
|
||||
- [Operations](docs/OPERATIONS.md)
|
||||
- [Inventory](docs/INVENTORY.md)
|
||||
- [Windows / WinRM / AD](docs/WINDOWS.md)
|
||||
- [Recovery](docs/RECOVERY.md)
|
||||
- [Security and sensitive data](docs/SECURITY.md)
|
||||
- [Development](docs/DEVELOPMENT.md)
|
||||
- [Changelog](CHANGELOG.md)
|
||||
|
||||
## Important operational rules
|
||||
|
||||
AIM does not use `.hosts.tsv` as inventory state. `hosts.yml` is
|
||||
authoritative.
|
||||
|
||||
Routine host changes use local YAML validation and do not unnecessarily
|
||||
prompt for the Vault password. Explicit inventory validation may invoke
|
||||
`ansible-inventory` and request the customer Vault password when a Vault
|
||||
exists.
|
||||
|
||||
Existing customer-specific values and arbitrary valid YAML structures
|
||||
should be preserved unless an operator explicitly requests an operation
|
||||
that changes them.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
root_dir: /etc/ansible
|
||||
service_user: svc_ansible
|
||||
required_group: root
|
||||
platform_groups:
|
||||
- linux
|
||||
- windows
|
||||
- sophosxgs
|
||||
- pfsense
|
||||
ui:
|
||||
clear_screen: true
|
||||
ascii: false
|
||||
output: compact
|
||||
@@ -0,0 +1,5 @@
|
||||
domain_suffix: desq-gaming.lan
|
||||
network_address: 192.168.20.0
|
||||
netmask: 255.255.255.0
|
||||
ad_dns_domain: ''
|
||||
ad_netbios_domain: ''
|
||||
@@ -0,0 +1 @@
|
||||
# group_vars/all/main.yml for desq_gaming
|
||||
@@ -0,0 +1,8 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCzzsHfog
|
||||
Wv9erYAv5gNSMrAAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIFEjnIIVsyXXaoqd
|
||||
VGOGwSPXthf8vzZ7L//SZP3OuJjxAAAAoPoC23Ps5HmvCpJrlOsubdcAjq0Ol65xhOb8VQ
|
||||
OolhyCPFPj/eH1z21w/PvXhL1S8tDsBut27qW8+5dSwT2gqjtt/x2SiOQYMHt6EjGGAISu
|
||||
NNy9L+vRcOFIB4Lo1IE/BMeZRUpgW2GXRFcQH9KgZXh/IWMDqcS5q8GbIT69OUxVUeBg3x
|
||||
Wa5f3MyCUMEmIMkBcdbJrebWXLjDvVYDI3myE=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFEjnIIVsyXXaoqdVGOGwSPXthf8vzZ7L//SZP3OuJjx svc_ansible@desq_gaming
|
||||
@@ -0,0 +1,7 @@
|
||||
# Linux / SSH variables
|
||||
ansible_connection: ssh
|
||||
ansible_user: svc_ansible
|
||||
ansible_private_key_file:
|
||||
/etc/ansible/inventories/desq_gaming/group_vars/linux/.ssh/svc_ansible
|
||||
ansible_ssh_pass: '{{ ansible_vault_linux_ssh_pass }}'
|
||||
ansible_become_method: sudo
|
||||
@@ -0,0 +1,2 @@
|
||||
# pfSense-specific variables
|
||||
{}
|
||||
@@ -0,0 +1,7 @@
|
||||
# SophosXGS-specific variables
|
||||
#ansible_password: "{{ ansible_password }}" # Passwort wird aus --ask-pass übernommen
|
||||
ansible_user: admin
|
||||
ansible_connection: ansible.netcommon.httpapi
|
||||
ansible_httpapi_validate_certs: false
|
||||
ansible_httpapi_port: 4444
|
||||
ansible_network_os: sophos.sophos_firewall.sfos
|
||||
@@ -0,0 +1,7 @@
|
||||
# Windows / WinRM variables
|
||||
ansible_connection: winrm
|
||||
ansible_port: 5986
|
||||
ansible_winrm_transport: ntlm
|
||||
ansible_winrm_server_cert_validation: ignore
|
||||
ansible_user: svc_ansible
|
||||
ansible_password: '{{ vault_windows_ansible_password }}'
|
||||
@@ -0,0 +1,4 @@
|
||||
all:
|
||||
children:
|
||||
desq_gaming:
|
||||
children: {}
|
||||
@@ -0,0 +1,99 @@
|
||||
all:
|
||||
children:
|
||||
desq_gaming:
|
||||
children:
|
||||
linux:
|
||||
children:
|
||||
networking:
|
||||
hosts:
|
||||
dewenpm01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.3
|
||||
dewedns02.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.2
|
||||
dewesrv-unifi02.desq-gaming.lan:
|
||||
ansible_host: 192.168.99.5
|
||||
|
||||
backup:
|
||||
hosts:
|
||||
dewepbs01.desq-gaming.lan:
|
||||
ansible_host: 192.168.99.32
|
||||
|
||||
proxmox:
|
||||
hosts:
|
||||
dewepbs01.desq-gaming.lan:
|
||||
ansible_host: 192.168.99.32
|
||||
dewepve01.desq-gaming.lan:
|
||||
ansible_host: 192.168.99.31
|
||||
|
||||
hosting:
|
||||
hosts:
|
||||
dewepve01.desq-gaming.lan:
|
||||
ansible_host: 192.168.99.31
|
||||
|
||||
management:
|
||||
hosts:
|
||||
dewesrv-ansible01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.46
|
||||
dewesrv-patch01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.45
|
||||
|
||||
applications:
|
||||
hosts:
|
||||
dewesrv-budget02.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.44
|
||||
dewesrv-cache02.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.24
|
||||
dewesrv-cloud01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.14
|
||||
dewesrv-crafty02.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.19
|
||||
dewesrv-db01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.21
|
||||
dewesrv-db02.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.23
|
||||
dewesrv-docker02.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.30
|
||||
dewesrv-git01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.38
|
||||
dewesrv-grafana01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.22
|
||||
dewesrv-ha01.desq-gaming.lan:
|
||||
ansible_host: 192.168.30.10
|
||||
dewesrv-homarr01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.35
|
||||
dewesrv-mail01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.40
|
||||
dewesrv-nodejs01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.20
|
||||
dewesrv-omv01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.15
|
||||
dewesrv-overseerr01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.18
|
||||
dewesrv-plex02.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.39
|
||||
dewesrv-puppet01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.25
|
||||
dewesrv-recipe01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.37
|
||||
dewesrv-rust02.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.27
|
||||
dewesrv-speed01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.16
|
||||
dewesrv-steam01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.12
|
||||
dewesrv-support01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.28
|
||||
dewesrv-tautulli01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.17
|
||||
dewesrv-tv01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.43
|
||||
dewesrv-uptime01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.11
|
||||
dewesrv-vault01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.34
|
||||
dewesrv-wallos01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.29
|
||||
dewesrv-wazuh01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.13
|
||||
dewesrv-wiki01.desq-gaming.lan:
|
||||
ansible_host: 192.168.20.36
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
- name: "Checkmk | Cleanup agent"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
tasks:
|
||||
- name: "Windows | Remove installed Checkmk agent"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$Ansible.Changed = $false
|
||||
$uninstallRoots = @(
|
||||
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
|
||||
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
|
||||
)
|
||||
|
||||
$products = foreach ($root in $uninstallRoots) {
|
||||
if (Test-Path -LiteralPath $root) {
|
||||
Get-ChildItem -LiteralPath $root -ErrorAction SilentlyContinue |
|
||||
ForEach-Object {
|
||||
$product = Get-ItemProperty -LiteralPath $_.PSPath -ErrorAction SilentlyContinue
|
||||
if ($product.DisplayName -like 'Check MK Agent*' -or
|
||||
$product.DisplayName -like 'Checkmk Agent*') {
|
||||
[PSCustomObject]@{
|
||||
ProductCode = $_.PSChildName
|
||||
DisplayName = $product.DisplayName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($product in $products) {
|
||||
if ($product.ProductCode -match '^\{[0-9A-Fa-f-]+\}$') {
|
||||
$process = Start-Process -FilePath 'msiexec.exe' `
|
||||
-ArgumentList "/x $($product.ProductCode) /qn /norestart" `
|
||||
-Wait -PassThru
|
||||
|
||||
if ($process.ExitCode -notin @(0, 1605, 1614, 3010)) {
|
||||
throw "Failed to uninstall $($product.DisplayName). MSI exit code: $($process.ExitCode)"
|
||||
}
|
||||
|
||||
if ($process.ExitCode -in @(0, 3010)) {
|
||||
$Ansible.Changed = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Ansible.Result = @{
|
||||
removed_products = @($products.DisplayName)
|
||||
}
|
||||
|
||||
- name: "Debian | Remove Checkmk agent"
|
||||
when: ansible_facts['os_family'] == 'Debian'
|
||||
ansible.builtin.apt:
|
||||
name: check-mk-agent
|
||||
state: absent
|
||||
purge: true
|
||||
|
||||
- name: "RedHat | Remove Checkmk agent"
|
||||
when: ansible_facts['os_family'] == 'RedHat'
|
||||
ansible.builtin.dnf:
|
||||
name: check-mk-agent
|
||||
state: absent
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: "Checkmk | Deploy agent, scripts and configuration"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- checkmk_agent
|
||||
- server_role_selection
|
||||
- checkmk_scripts
|
||||
- checkmk_agent_config
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: "Checkmk | Update agent configuration"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- server_role_selection
|
||||
- checkmk_agent_config
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: "Checkmk | Update monitoring scripts"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- server_role_selection
|
||||
- checkmk_scripts
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
- name: "Debug | Disk usage"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
tasks:
|
||||
- name: "Linux | Collect filesystem usage"
|
||||
when: ansible_facts['os_family'] != 'Windows'
|
||||
ansible.builtin.command:
|
||||
cmd: df -hP -x tmpfs -x devtmpfs
|
||||
register: disk_usage_linux
|
||||
changed_when: false
|
||||
|
||||
- name: "Linux | Show filesystem usage"
|
||||
when: ansible_facts['os_family'] != 'Windows'
|
||||
ansible.builtin.debug:
|
||||
var: disk_usage_linux.stdout_lines
|
||||
|
||||
- name: "Windows | Collect filesystem drive usage"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
|
||||
Select-Object DeviceID,
|
||||
@{Name='SizeGB';Expression={[math]::Round($_.Size / 1GB, 2)}},
|
||||
@{Name='FreeGB';Expression={[math]::Round($_.FreeSpace / 1GB, 2)}},
|
||||
@{Name='UsedPercent';Expression={
|
||||
if ($_.Size -gt 0) {
|
||||
[math]::Round((($_.Size - $_.FreeSpace) / $_.Size) * 100, 1)
|
||||
} else { 0 }
|
||||
}}
|
||||
register: disk_usage_windows
|
||||
changed_when: false
|
||||
|
||||
- name: "Windows | Show filesystem drive usage"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.builtin.debug:
|
||||
var: disk_usage_windows.output
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: "Debug | Ping hosts"
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: "Windows | WinRM ping"
|
||||
when: ansible_connection | default('') == 'winrm'
|
||||
ansible.windows.win_ping:
|
||||
|
||||
- name: "Linux | Ansible ping"
|
||||
when: ansible_connection | default('ssh') != 'winrm'
|
||||
ansible.builtin.ping:
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
- name: "Debug | Server Role Selection"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- server_role_selection
|
||||
|
||||
tasks:
|
||||
- name: "Debug | Display detected server roles"
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
host: "{{ inventory_hostname }}"
|
||||
os_family: "{{ ansible_facts['os_family'] | default('unknown') }}"
|
||||
|
||||
windows_roles:
|
||||
domain_controller: "{{ is_dc | default(false) | bool }}"
|
||||
dhcp_server: "{{ is_dhcp_server | default(false) | bool }}"
|
||||
hyperv_host: "{{ is_hyperv_host | default(false) | bool }}"
|
||||
|
||||
veeam:
|
||||
vbr: "{{ has_veeam_vbr | default(false) | bool }}"
|
||||
vbo: "{{ has_veeam_vbo | default(false) | bool }}"
|
||||
enterprise_manager: "{{ has_veeam_em | default(false) | bool }}"
|
||||
|
||||
linux_roles:
|
||||
unifi_controller: "{{ is_unifi_controller | default(false) | bool }}"
|
||||
|
||||
optional_features:
|
||||
linux_certificate_check: "{{ want_linux_check_certificate | default(false) | bool }}"
|
||||
windows_citrix: "{{ want_windows_citrix | default(false) | bool }}"
|
||||
windows_surebackup: "{{ want_windows_surebackup | default(false) | bool }}"
|
||||
windows_backup: "{{ want_windows_backup | default(false) | bool }}"
|
||||
|
||||
- name: "Debug | Display Checkmk script deployment decisions"
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
linux:
|
||||
unifi_controller:
|
||||
deploy: "{{ is_unifi_controller | default(false) | bool }}"
|
||||
reason: "UniFi Controller detected"
|
||||
scripts:
|
||||
- "check_unifi-controller.sh"
|
||||
- "unifi.cfg"
|
||||
|
||||
certificate_directory:
|
||||
deploy: "{{ want_linux_check_certificate | default(false) | bool }}"
|
||||
reason: "Certificate directory monitoring explicitly enabled"
|
||||
scripts:
|
||||
- "check_certificate_directory.sh"
|
||||
|
||||
windows:
|
||||
check_ping:
|
||||
deploy: "{{ is_dc | default(false) | bool }}"
|
||||
reason: "Domain Controller"
|
||||
scripts:
|
||||
- "check-ping.ps1"
|
||||
|
||||
veeam_config_backup:
|
||||
deploy: "{{ has_veeam_vbr | default(false) | bool }}"
|
||||
reason: "Veeam Backup & Replication detected"
|
||||
scripts:
|
||||
- "veeam_config_backup_status.ps1"
|
||||
|
||||
veeam_o365:
|
||||
deploy: "{{ has_veeam_vbo | default(false) | bool }}"
|
||||
reason: "Veeam Backup for Microsoft 365 detected"
|
||||
scripts:
|
||||
- "veeam_o365_status.ps1"
|
||||
|
||||
citrix_sessions:
|
||||
deploy: "{{ want_windows_citrix | default(false) | bool }}"
|
||||
reason: "Citrix monitoring explicitly enabled"
|
||||
scripts:
|
||||
- "citrix_sessions_customized.ps1"
|
||||
|
||||
veeam_surebackup:
|
||||
deploy: "{{ want_windows_surebackup | default(false) | bool }}"
|
||||
reason: "Veeam SureBackup monitoring explicitly enabled"
|
||||
scripts:
|
||||
- "veeam_surebackup_status.ps1"
|
||||
|
||||
windows_backup:
|
||||
deploy: "{{ want_windows_backup | default(false) | bool }}"
|
||||
reason: "Windows Backup monitoring explicitly enabled"
|
||||
scripts:
|
||||
- "windows-backup.ps1"
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
- name: "Maintenance | Backup system logs"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
vars:
|
||||
windows_event_log_backup_dir: 'C:\\Windows\\Temp\\EventLogBackup'
|
||||
windows_event_logs_to_backup:
|
||||
- Application
|
||||
- System
|
||||
- Security
|
||||
|
||||
linux_log_backup_dir: /var/backups/system-logs
|
||||
linux_journal_since: "-24h"
|
||||
|
||||
tasks:
|
||||
- name: "Windows | Ensure event log backup directory exists"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.windows.win_file:
|
||||
path: "{{ windows_event_log_backup_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: "Windows | Export event logs"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.windows.win_command: >-
|
||||
wevtutil epl {{ item }} "{{ windows_event_log_backup_dir }}\\{{ item }}.evtx" /ow:true
|
||||
loop: "{{ windows_event_logs_to_backup }}"
|
||||
changed_when: true
|
||||
|
||||
- name: "Linux | Ensure system log backup directory exists"
|
||||
when: ansible_facts['os_family'] != 'Windows'
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ linux_log_backup_dir }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0750"
|
||||
|
||||
- name: "Linux | Check whether systemd journal is available"
|
||||
when: ansible_facts['os_family'] != 'Windows'
|
||||
ansible.builtin.command:
|
||||
cmd: journalctl --version
|
||||
register: journalctl_available
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: "Linux | Export systemd journal"
|
||||
when:
|
||||
- ansible_facts['os_family'] != 'Windows'
|
||||
- journalctl_available.rc == 0
|
||||
become: true
|
||||
ansible.builtin.shell: >-
|
||||
journalctl --since {{ linux_journal_since | quote }} --no-pager
|
||||
> {{ (linux_log_backup_dir ~ '/journal.log') | quote }}
|
||||
args:
|
||||
executable: /bin/sh
|
||||
changed_when: true
|
||||
|
||||
- name: "Linux | Backup traditional system logs"
|
||||
when:
|
||||
- ansible_facts['os_family'] != 'Windows'
|
||||
- journalctl_available.rc != 0
|
||||
become: true
|
||||
ansible.builtin.shell: |
|
||||
set -e
|
||||
for file in /var/log/syslog /var/log/messages /var/log/auth.log /var/log/secure; do
|
||||
if [ -f "$file" ]; then
|
||||
cp -p "$file" "{{ linux_log_backup_dir }}/$(basename "$file")"
|
||||
fi
|
||||
done
|
||||
args:
|
||||
executable: /bin/sh
|
||||
changed_when: true
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
- name: "Maintenance | Patch operating system"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
tasks:
|
||||
- name: "Debian | Update package cache and upgrade packages"
|
||||
when: ansible_facts['os_family'] == 'Debian'
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
upgrade: dist
|
||||
|
||||
- name: "RedHat | Upgrade installed packages"
|
||||
when: ansible_facts['os_family'] == 'RedHat'
|
||||
ansible.builtin.dnf:
|
||||
name: '*'
|
||||
state: latest
|
||||
|
||||
- name: "Windows | Install available updates"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.windows.win_updates:
|
||||
category_names:
|
||||
- CriticalUpdates
|
||||
- SecurityUpdates
|
||||
- UpdateRollups
|
||||
- Updates
|
||||
reboot: false
|
||||
register: windows_updates
|
||||
|
||||
- name: "Windows | Report reboot requirement"
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'Windows'
|
||||
- windows_updates.reboot_required | default(false)
|
||||
ansible.builtin.debug:
|
||||
msg: "Windows updates were installed and a reboot is required. No reboot was performed."
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: "Maintenance | Reboot systems"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
tasks:
|
||||
- name: "Windows | Reboot system"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.windows.win_reboot:
|
||||
reboot_timeout: 1800
|
||||
|
||||
- name: "Linux | Reboot system"
|
||||
when: ansible_facts['os_family'] != 'Windows'
|
||||
ansible.builtin.reboot:
|
||||
reboot_timeout: 1800
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
- name: "Maintenance | Start stopped automatic services"
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
tasks:
|
||||
- name: "Windows | Start stopped automatic services"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$Ansible.Changed = $false
|
||||
$started = @()
|
||||
|
||||
Get-CimInstance Win32_Service |
|
||||
Where-Object {
|
||||
$_.StartMode -eq 'Auto' -and
|
||||
$_.State -ne 'Running'
|
||||
} |
|
||||
ForEach-Object {
|
||||
try {
|
||||
Start-Service -Name $_.Name -ErrorAction Stop
|
||||
$started += $_.Name
|
||||
$Ansible.Changed = $true
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Could not start service $($_.Name): $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
$Ansible.Result = @{
|
||||
started_services = $started
|
||||
}
|
||||
register: started_services_windows
|
||||
|
||||
- name: "Windows | Show started services"
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.builtin.debug:
|
||||
var: started_services_windows.result.started_services
|
||||
|
||||
- name: "Linux | Collect service facts"
|
||||
when: ansible_facts['os_family'] != 'Windows'
|
||||
ansible.builtin.service_facts:
|
||||
|
||||
- name: "Linux | Start stopped enabled systemd services"
|
||||
when:
|
||||
- ansible_facts['os_family'] != 'Windows'
|
||||
- ansible_facts['service_mgr'] == 'systemd'
|
||||
- item.value.status | default('') == 'enabled'
|
||||
- item.value.state | default('') != 'running'
|
||||
become: true
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ item.key }}"
|
||||
state: started
|
||||
loop: "{{ ansible_facts.services | dict2items }}"
|
||||
loop_control:
|
||||
label: "{{ item.key }}"
|
||||
register: started_services_linux
|
||||
failed_when: false
|
||||
|
||||
- name: "Linux | Show services that were started"
|
||||
when:
|
||||
- ansible_facts['os_family'] != 'Windows'
|
||||
- ansible_facts['service_mgr'] == 'systemd'
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{
|
||||
started_services_linux.results
|
||||
| default([])
|
||||
| selectattr('changed', 'defined')
|
||||
| selectattr('changed')
|
||||
| map(attribute='item.key')
|
||||
| list
|
||||
}}
|
||||
|
||||
- name: "Linux | Report unsupported service manager"
|
||||
when:
|
||||
- ansible_facts['os_family'] != 'Windows'
|
||||
- ansible_facts['service_mgr'] != 'systemd'
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Automatic stopped-service recovery currently supports systemd hosts only.
|
||||
Detected service manager: {{ ansible_facts['service_mgr'] }}
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
checkmk_linux_tmp_path: "/tmp"
|
||||
checkmk_windows_tmp_path: "C:\\Windows\\Temp"
|
||||
checkmk_deb_filename: "check-mk-agent.deb"
|
||||
checkmk_rpm_filename: "check-mk-agent.rpm"
|
||||
checkmk_msi_filename: "check_mk_agent.msi"
|
||||
checkmk_linux_socket_name: "check-mk-agent.socket"
|
||||
checkmk_linux_service_name: "check-mk-agent"
|
||||
checkmk_windows_service_name: "CheckMkService"
|
||||
@@ -0,0 +1,5 @@
|
||||
Place the Checkmk agent packages here:
|
||||
|
||||
- `check-mk-agent.deb`
|
||||
- `check-mk-agent.rpm`
|
||||
- `check_mk_agent.msi`
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,55 @@
|
||||
---
|
||||
- name: "Enable & start Checkmk socket (if present)"
|
||||
listen: "checkmk | linux | agent-ensure-running"
|
||||
when: ansible_facts['os_family'] != "Windows"
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ checkmk_linux_socket_name }}"
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: true
|
||||
failed_when: false
|
||||
|
||||
- name: "Enable & start Checkmk service (fallback/if present)"
|
||||
listen: "checkmk | linux | agent-ensure-running"
|
||||
when: ansible_facts['os_family'] != "Windows"
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ checkmk_linux_service_name }}"
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: true
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Detect Checkmk service name"
|
||||
listen: "checkmk | windows | agent-ensure-running"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$candidates = @('CheckMkService','Check_MK_Agent')
|
||||
foreach ($n in $candidates) {
|
||||
$svc = Get-Service -Name $n -ErrorAction SilentlyContinue
|
||||
if ($svc) { $svc.Name; break }
|
||||
}
|
||||
register: cmk_detect
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Set detected service name"
|
||||
listen: "checkmk | windows | agent-ensure-running"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.builtin.set_fact:
|
||||
cmk_service_name: >-
|
||||
{{
|
||||
(cmk_detect.output[0] | default('') | trim)
|
||||
if (cmk_detect.output | default([]) | length > 0)
|
||||
else (checkmk_windows_service_name | default('CheckMkService'))
|
||||
}}
|
||||
|
||||
- name: "Windows | Ensure Checkmk agent service running"
|
||||
listen: "checkmk | windows | agent-ensure-running"
|
||||
when:
|
||||
- ansible_facts['os_family'] == "Windows"
|
||||
- (cmk_service_name | default('')) | length > 0
|
||||
ansible.windows.win_service:
|
||||
name: "{{ cmk_service_name }}"
|
||||
start_mode: auto
|
||||
state: started
|
||||
failed_when: false
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: checkmk_agent
|
||||
description: Install Checkmk agent from local packages
|
||||
min_ansible_version: "2.18"
|
||||
dependencies: []
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: "Debian | Copy Checkmk agent package"
|
||||
ansible.builtin.copy:
|
||||
src: "{{ checkmk_deb_filename }}"
|
||||
dest: "{{ checkmk_linux_tmp_path }}/{{ checkmk_deb_filename }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: "Debian | Install Checkmk agent"
|
||||
ansible.builtin.apt:
|
||||
deb: "{{ checkmk_linux_tmp_path }}/{{ checkmk_deb_filename }}"
|
||||
notify: "checkmk | linux | agent-ensure-running"
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Include Debian installation
|
||||
ansible.builtin.include_tasks: debian.yml
|
||||
when: ansible_facts['os_family'] == 'Debian'
|
||||
|
||||
- name: Include RedHat installation
|
||||
ansible.builtin.include_tasks: redhat.yml
|
||||
when: ansible_facts['os_family'] == 'RedHat'
|
||||
|
||||
- name: Include Windows installation
|
||||
ansible.builtin.include_tasks: windows.yml
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: "RedHat | Copy Checkmk agent package"
|
||||
ansible.builtin.copy:
|
||||
src: "{{ checkmk_rpm_filename }}"
|
||||
dest: "{{ checkmk_linux_tmp_path }}/{{ checkmk_rpm_filename }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: "RedHat | Install Checkmk agent"
|
||||
ansible.builtin.package:
|
||||
name: "{{ checkmk_linux_tmp_path }}/{{ checkmk_rpm_filename }}"
|
||||
state: present
|
||||
notify: "checkmk | linux | agent-ensure-running"
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: "Windows | Copy Checkmk agent MSI"
|
||||
ansible.windows.win_copy:
|
||||
src: "{{ checkmk_msi_filename }}"
|
||||
dest: "{{ checkmk_windows_tmp_path }}\\{{ checkmk_msi_filename }}"
|
||||
|
||||
- name: "Windows | Install Checkmk agent from local MSI"
|
||||
ansible.windows.win_package:
|
||||
path: "{{ checkmk_windows_tmp_path }}\\{{ checkmk_msi_filename }}"
|
||||
state: present
|
||||
notify: "checkmk | windows | agent-ensure-running"
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
checkmk_windows_user_cfg: "C:\\ProgramData\\checkmk\\agent\\check_mk.user.yml"
|
||||
checkmk_windows_updates_timeout: 3600
|
||||
checkmk_windows_updates_cache: 43200
|
||||
checkmk_mk_inventory_timeout: 120
|
||||
checkmk_plugins_default_timeout: 120
|
||||
checkmk_plugins_default_cache: 600
|
||||
checkmk_extra_plugin_patterns: []
|
||||
checkmk_extra_local_patterns: []
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: checkmk_agent_config
|
||||
description: Render Windows Checkmk agent configuration from detected server roles
|
||||
min_ansible_version: "2.18"
|
||||
dependencies: []
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: "Debug detected role flags"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
dc: "{{ is_dc | default(false) }}"
|
||||
dhcp: "{{ is_dhcp_server | default(false) }}"
|
||||
vbr: "{{ has_veeam_vbr | default(false) }}"
|
||||
vbo: "{{ has_veeam_vbo | default(false) }}"
|
||||
em: "{{ has_veeam_em | default(false) }}"
|
||||
hv: "{{ is_hyperv_host | default(false) }}"
|
||||
timeout_updates: "{{ checkmk_windows_updates_timeout }}"
|
||||
|
||||
- name: "Windows | Render check_mk.user.yml"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_template:
|
||||
src: "windows_check_mk.user.yml.j2"
|
||||
dest: "{{ checkmk_windows_user_cfg }}"
|
||||
backup: true
|
||||
notify: "checkmk | windows | agent-ensure-running"
|
||||
@@ -0,0 +1,130 @@
|
||||
# Managed by Ansible (checkmk_agent_config)
|
||||
# Windows Checkmk Agent user configuration built from detected roles.
|
||||
|
||||
# $CUSTOM_PLUGINS_PATH$ -> ProgramData\checkmk\agent\plugins
|
||||
# $BUILTIN_PLUGINS_PATH$ -> Program Files (x86)\checkmk\service\plugins
|
||||
# $CUSTOM_AGENT_PATH$ -> ProgramData\checkmk\agent
|
||||
# $CUSTOM_LOCAL_PATH$ -> ProgramData\checkmk\agent\local
|
||||
|
||||
global:
|
||||
_only_from:
|
||||
_realtime:
|
||||
enabled: yes
|
||||
timeout: 90
|
||||
port: 6559
|
||||
encrypted: no
|
||||
passphrase: this is my password
|
||||
run:
|
||||
- mem
|
||||
- df
|
||||
- winperf_processor
|
||||
|
||||
winperf:
|
||||
counters:
|
||||
- MSExchangeTransport Queues: msx_queues
|
||||
|
||||
_logfiles:
|
||||
enabled: no
|
||||
|
||||
fileinfo:
|
||||
path: []
|
||||
|
||||
logwatch:
|
||||
logfile: []
|
||||
|
||||
plugins:
|
||||
execution:
|
||||
# --- Built-in defaults ---
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\windows_updates.vbs'
|
||||
run: yes
|
||||
async: yes
|
||||
timeout: {{ checkmk_windows_updates_timeout }}
|
||||
cache_age: {{ checkmk_windows_updates_cache }}
|
||||
retry_count: 0
|
||||
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\mk_inventory.vbs'
|
||||
run: yes
|
||||
async: yes
|
||||
timeout: {{ checkmk_mk_inventory_timeout }}
|
||||
cache_age: 3600
|
||||
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\mssql.vbs'
|
||||
run: yes
|
||||
timeout: {{ checkmk_plugins_default_timeout }}
|
||||
|
||||
{% if has_veeam_vbr | default(false) %}
|
||||
# --- Veeam Backup & Replication ---
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\veeam_backup_status.ps1'
|
||||
run: yes
|
||||
async: yes
|
||||
timeout: {{ checkmk_plugins_default_timeout }}
|
||||
cache_age: {{ checkmk_plugins_default_cache }}
|
||||
{% endif %}
|
||||
|
||||
{% if is_dc | default(false) %}
|
||||
# --- Domain Controller ---
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\ad_replication.bat'
|
||||
run: yes
|
||||
timeout: {{ checkmk_plugins_default_timeout }}
|
||||
{% endif %}
|
||||
|
||||
{% if is_dhcp_server | default(false) %}
|
||||
# --- DHCP Server ---
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\win_dhcp_pools.bat'
|
||||
run: yes
|
||||
timeout: {{ checkmk_plugins_default_timeout }}
|
||||
{% endif %}
|
||||
|
||||
# --- Generic patterns / precedence ---
|
||||
- pattern: '$CUSTOM_PLUGINS_PATH$\*.ps1'
|
||||
run: yes
|
||||
async: yes
|
||||
timeout: {{ checkmk_plugins_default_timeout }}
|
||||
cache_age: {{ checkmk_plugins_default_cache }}
|
||||
|
||||
- pattern: '$CUSTOM_PLUGINS_PATH$\*.*'
|
||||
run: yes
|
||||
timeout: {{ checkmk_plugins_default_timeout }}
|
||||
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\*.*'
|
||||
run: no
|
||||
timeout: {{ checkmk_plugins_default_timeout }}
|
||||
|
||||
- pattern: '*'
|
||||
run: no
|
||||
|
||||
{% for p in (checkmk_extra_plugin_patterns | default([])) %}
|
||||
- pattern: '{{ p.pattern }}'
|
||||
{% if p.run is defined %}
|
||||
run: {{ p.run | bool }}
|
||||
{% endif %}
|
||||
{% if p.async is defined %}
|
||||
async: {{ p.async | bool }}
|
||||
{% endif %}
|
||||
{% if p.timeout is defined %}
|
||||
timeout: {{ p.timeout }}
|
||||
{% endif %}
|
||||
{% if p.cache_age is defined %}
|
||||
cache_age: {{ p.cache_age }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
local:
|
||||
_execution:
|
||||
- pattern: '*.*'
|
||||
run: yes
|
||||
{% for l in (checkmk_extra_local_patterns | default([])) %}
|
||||
- pattern: '{{ l.pattern }}'
|
||||
{% if l.run is defined %}
|
||||
run: {{ l.run | bool }}
|
||||
{% endif %}
|
||||
{% if l.async is defined %}
|
||||
async: {{ l.async | bool }}
|
||||
{% endif %}
|
||||
{% if l.timeout is defined %}
|
||||
timeout: {{ l.timeout }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
mrpe:
|
||||
config: []
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
checkmk_linux_local_dir: "/usr/lib/check_mk_agent/local"
|
||||
checkmk_linux_config_dir: "/etc/check_mk"
|
||||
checkmk_windows_local_dir: "C:\\ProgramData\\checkmk\\agent\\local"
|
||||
checkmk_linux_scripts_dir: "Linux/local"
|
||||
checkmk_windows_scripts_dir: "Windows/local"
|
||||
|
||||
# Optional checks, disabled until explicitly requested
|
||||
want_linux_check_certificate: false
|
||||
want_windows_citrix: false
|
||||
want_windows_surebackup: false
|
||||
want_windows_backup: false
|
||||
@@ -0,0 +1,16 @@
|
||||
Place the actual monitoring scripts in these directories.
|
||||
|
||||
Linux/local/
|
||||
- check_certificate_directory.sh
|
||||
- check_unifi-controller.sh
|
||||
- unifi.cfg
|
||||
|
||||
Windows/local/
|
||||
- check-ping.ps1
|
||||
- citrix_sessions_customized.ps1
|
||||
- veeam_config_backup_status.ps1
|
||||
- veeam_o365_status.ps1
|
||||
- veeam_surebackup_status.ps1
|
||||
- windows-backup.ps1
|
||||
|
||||
The ZIP intentionally does not invent script contents that were not provided.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: checkmk_scripts
|
||||
description: Deploy role-specific Checkmk local monitoring scripts
|
||||
min_ansible_version: "2.18"
|
||||
dependencies: []
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
- name: "Linux | Ensure local dir exists"
|
||||
ansible.builtin.file:
|
||||
path: "{{ checkmk_linux_local_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: "Linux | Ensure config dir exists"
|
||||
ansible.builtin.file:
|
||||
path: "{{ checkmk_linux_config_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: "Linux | Deploy UniFi local check"
|
||||
when: is_unifi_controller | default(false) | bool
|
||||
ansible.builtin.copy:
|
||||
src: "{{ checkmk_linux_scripts_dir }}/check_unifi-controller.sh"
|
||||
dest: "{{ checkmk_linux_local_dir }}/check_unifi-controller.sh"
|
||||
mode: "0755"
|
||||
notify: "checkmk | linux | agent-ensure-running"
|
||||
|
||||
- name: "Linux | Deploy unifi.cfg"
|
||||
when: is_unifi_controller | default(false) | bool
|
||||
ansible.builtin.copy:
|
||||
src: "{{ checkmk_linux_scripts_dir }}/unifi.cfg"
|
||||
dest: "{{ checkmk_linux_config_dir }}/unifi.cfg"
|
||||
mode: "0644"
|
||||
notify: "checkmk | linux | agent-ensure-running"
|
||||
|
||||
- name: "Linux | Deploy certificate directory check"
|
||||
when: want_linux_check_certificate | default(false) | bool
|
||||
ansible.builtin.copy:
|
||||
src: "{{ checkmk_linux_scripts_dir }}/check_certificate_directory.sh"
|
||||
dest: "{{ checkmk_linux_local_dir }}/check_certificate_directory.sh"
|
||||
mode: "0755"
|
||||
notify: "checkmk | linux | agent-ensure-running"
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Include Linux monitoring scripts
|
||||
ansible.builtin.include_tasks: linux.yml
|
||||
when: ansible_facts['os_family'] != 'Windows'
|
||||
|
||||
- name: Include Windows monitoring scripts
|
||||
ansible.builtin.include_tasks: windows.yml
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
- name: "Windows | Ensure local dir exists"
|
||||
ansible.windows.win_file:
|
||||
path: "{{ checkmk_windows_local_dir }}"
|
||||
state: directory
|
||||
|
||||
- name: "Windows | Deploy check-ping.ps1 (DC only)"
|
||||
when: is_dc | default(false) | bool
|
||||
ansible.windows.win_copy:
|
||||
src: "{{ checkmk_windows_scripts_dir }}/check-ping.ps1"
|
||||
dest: "{{ checkmk_windows_local_dir }}\\check-ping.ps1"
|
||||
notify: "checkmk | windows | agent-ensure-running"
|
||||
|
||||
- name: "Windows | Deploy Veeam configuration backup status check (VBR only)"
|
||||
when: has_veeam_vbr | default(false) | bool
|
||||
ansible.windows.win_copy:
|
||||
src: "{{ checkmk_windows_scripts_dir }}/veeam_config_backup_status.ps1"
|
||||
dest: "{{ checkmk_windows_local_dir }}\\veeam_config_backup_status.ps1"
|
||||
notify: "checkmk | windows | agent-ensure-running"
|
||||
|
||||
- name: "Windows | Deploy veeam_o365_status.ps1 (VBO only)"
|
||||
when: has_veeam_vbo | default(false) | bool
|
||||
ansible.windows.win_copy:
|
||||
src: "{{ checkmk_windows_scripts_dir }}/veeam_o365_status.ps1"
|
||||
dest: "{{ checkmk_windows_local_dir }}\\veeam_o365_status.ps1"
|
||||
notify: "checkmk | windows | agent-ensure-running"
|
||||
|
||||
- name: "Windows | Deploy Citrix sessions check"
|
||||
when: want_windows_citrix | default(false) | bool
|
||||
ansible.windows.win_copy:
|
||||
src: "{{ checkmk_windows_scripts_dir }}/citrix_sessions_customized.ps1"
|
||||
dest: "{{ checkmk_windows_local_dir }}\\citrix_sessions_customized.ps1"
|
||||
notify: "checkmk | windows | agent-ensure-running"
|
||||
|
||||
- name: "Windows | Deploy Veeam SureBackup check"
|
||||
when: want_windows_surebackup | default(false) | bool
|
||||
ansible.windows.win_copy:
|
||||
src: "{{ checkmk_windows_scripts_dir }}/veeam_surebackup_status.ps1"
|
||||
dest: "{{ checkmk_windows_local_dir }}\\veeam_surebackup_status.ps1"
|
||||
notify: "checkmk | windows | agent-ensure-running"
|
||||
|
||||
- name: "Windows | Deploy Windows Backup check"
|
||||
when: want_windows_backup | default(false) | bool
|
||||
ansible.windows.win_copy:
|
||||
src: "{{ checkmk_windows_scripts_dir }}/windows-backup.ps1"
|
||||
dest: "{{ checkmk_windows_local_dir }}\\windows-backup.ps1"
|
||||
notify: "checkmk | windows | agent-ensure-running"
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
ad_ds_feature_name: "AD-Domain-Services"
|
||||
dhcp_windows_service_name: "DHCPServer"
|
||||
veeam_services:
|
||||
vbr: "VeeamBackupSvc"
|
||||
vbo: "Veeam.Archiver.Service"
|
||||
em: "VeeamEnterpriseManagerSvc"
|
||||
unifi_linux_services:
|
||||
- unifi
|
||||
- unifi.service
|
||||
unifi_linux_packages:
|
||||
- unifi
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: server_role_selection
|
||||
description: Detect server roles used for Checkmk deployment decisions
|
||||
min_ansible_version: "2.18"
|
||||
dependencies: []
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
# ==========================
|
||||
# WINDOWS DETECTION
|
||||
# ==========================
|
||||
- name: "Windows | Detect AD DS feature (DC)"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_feature_info:
|
||||
name: "{{ ad_ds_feature_name }}"
|
||||
register: _win_dc_feature
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Fallback: check NTDS service (DC)"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_service_info:
|
||||
name: "NTDS"
|
||||
register: _win_ntds_svc
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Check DHCP service"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_service_info:
|
||||
name: "{{ dhcp_windows_service_name }}"
|
||||
register: _win_dhcp_svc
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Check Veeam VBR service"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_service_info:
|
||||
name: "{{ veeam_services.vbr }}"
|
||||
register: _veeam_vbr
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Check Veeam VBO service"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_service_info:
|
||||
name: "{{ veeam_services.vbo }}"
|
||||
register: _veeam_vbo
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Check Veeam Enterprise Manager service"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_service_info:
|
||||
name: "{{ veeam_services.em }}"
|
||||
register: _veeam_em
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Check Hyper-V service"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.windows.win_service_info:
|
||||
name: "vmms"
|
||||
register: _win_hyperv_svc
|
||||
failed_when: false
|
||||
|
||||
- name: "Windows | Set detection booleans"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.builtin.set_fact:
|
||||
is_dc: >-
|
||||
{{
|
||||
(((_win_dc_feature.features | default([])) | selectattr('installed') | list | length) > 0)
|
||||
or (_win_ntds_svc.exists | default(false))
|
||||
}}
|
||||
is_dhcp_server: "{{ _win_dhcp_svc.exists | default(false) }}"
|
||||
has_veeam_vbr: "{{ _veeam_vbr.exists | default(false) }}"
|
||||
has_veeam_vbo: "{{ _veeam_vbo.exists | default(false) }}"
|
||||
has_veeam_em: "{{ _veeam_em.exists | default(false) }}"
|
||||
is_hyperv_host: "{{ _win_hyperv_svc.exists | default(false) }}"
|
||||
|
||||
- name: "Windows | Debug summary"
|
||||
when: ansible_facts['os_family'] == "Windows"
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
is_dc: "{{ is_dc }}"
|
||||
is_dhcp_server: "{{ is_dhcp_server }}"
|
||||
has_veeam_vbr: "{{ has_veeam_vbr }}"
|
||||
has_veeam_vbo: "{{ has_veeam_vbo }}"
|
||||
has_veeam_em: "{{ has_veeam_em }}"
|
||||
is_hyperv_host: "{{ is_hyperv_host }}"
|
||||
|
||||
# ==========================
|
||||
# LINUX DETECTION
|
||||
# ==========================
|
||||
- name: "Linux | Collect service facts"
|
||||
when: ansible_facts['os_family'] != "Windows"
|
||||
ansible.builtin.service_facts:
|
||||
|
||||
- name: "Linux | Collect package facts"
|
||||
when: ansible_facts['os_family'] != "Windows"
|
||||
ansible.builtin.package_facts:
|
||||
manager: auto
|
||||
|
||||
- name: "Linux | Set UniFi flag"
|
||||
when: ansible_facts['os_family'] != "Windows"
|
||||
vars:
|
||||
svcs: "{{ ansible_facts.services | default({}) }}"
|
||||
pkgs: "{{ ansible_facts.packages | default({}) | list }}"
|
||||
ansible.builtin.set_fact:
|
||||
is_unifi_controller: >-
|
||||
{{
|
||||
(unifi_linux_services | select('in', svcs.keys()) | list | length > 0)
|
||||
or (pkgs | intersect(unifi_linux_packages) | length > 0)
|
||||
}}
|
||||
|
||||
- name: "Normalize detection booleans"
|
||||
ansible.builtin.set_fact:
|
||||
is_dc: "{{ is_dc | default(false) }}"
|
||||
is_dhcp_server: "{{ is_dhcp_server | default(false) }}"
|
||||
has_veeam_vbr: "{{ has_veeam_vbr | default(false) }}"
|
||||
has_veeam_vbo: "{{ has_veeam_vbo | default(false) }}"
|
||||
has_veeam_em: "{{ has_veeam_em | default(false) }}"
|
||||
is_hyperv_host: "{{ is_hyperv_host | default(false) }}"
|
||||
is_unifi_controller: "{{ is_unifi_controller | default(false) }}"
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "aim-inventory-manager"
|
||||
version = "2.1.2"
|
||||
version = "2.2.2"
|
||||
description = "AIM - Ansible Inventory Manager"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "2.1.2"
|
||||
__version__ = "2.2.2"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -25,6 +25,11 @@ class Config:
|
||||
ui_ascii: bool = False
|
||||
ui_output: str = "compact"
|
||||
|
||||
checkmk_agent_base_url: str = ""
|
||||
checkmk_agent_version: str = ""
|
||||
checkmk_agent_role_files_dir: Path = Path("/etc/ansible/roles/checkmk_agent/files")
|
||||
checkmk_monitoring_scripts_dir: Path = Path("/etc/checkmk_monitoring_scripts")
|
||||
|
||||
@property
|
||||
def inventory_dir(self) -> Path:
|
||||
return self.root_dir / "inventories"
|
||||
@@ -64,8 +69,19 @@ class Config:
|
||||
for setting in ("clear_screen", "ascii"):
|
||||
if setting in ui and not isinstance(ui[setting], bool):
|
||||
raise ValueError(f"ui.{setting} must be true or false")
|
||||
return cls(root, service_user, required_group, platform_groups,
|
||||
ui.get("clear_screen", True), ui.get("ascii", False), output)
|
||||
maintenance = data.get("maintenance", {}) or {}
|
||||
if not isinstance(maintenance, dict):
|
||||
raise ValueError("maintenance must be a mapping")
|
||||
return cls(
|
||||
root_dir=root, service_user=service_user, required_group=required_group,
|
||||
platform_groups=platform_groups,
|
||||
ui_clear_screen=ui.get("clear_screen", True),
|
||||
ui_ascii=ui.get("ascii", False), ui_output=output,
|
||||
checkmk_agent_base_url=str(maintenance.get("checkmk_agent_base_url", "")).strip(),
|
||||
checkmk_agent_version=str(maintenance.get("checkmk_agent_version", "")).strip(),
|
||||
checkmk_agent_role_files_dir=Path(str(maintenance.get("checkmk_agent_role_files_dir", "/etc/ansible/roles/checkmk_agent/files"))),
|
||||
checkmk_monitoring_scripts_dir=Path(str(maintenance.get("checkmk_monitoring_scripts_dir", "/etc/checkmk_monitoring_scripts"))),
|
||||
)
|
||||
except Exception as exc:
|
||||
raise ConfigurationError(f"Could not load {path}: {exc}") from exc
|
||||
|
||||
@@ -86,6 +102,15 @@ class Config:
|
||||
if not isinstance(ui, dict):
|
||||
raise ConfigurationError("Existing ui configuration is not a mapping")
|
||||
ui.update(clear_screen=self.ui_clear_screen, ascii=self.ui_ascii, output=self.ui_output)
|
||||
maintenance = data.setdefault("maintenance", {})
|
||||
if not isinstance(maintenance, dict):
|
||||
raise ConfigurationError("Existing maintenance configuration is not a mapping")
|
||||
maintenance.update(
|
||||
checkmk_agent_base_url=self.checkmk_agent_base_url,
|
||||
checkmk_agent_version=self.checkmk_agent_version,
|
||||
checkmk_agent_role_files_dir=str(self.checkmk_agent_role_files_dir),
|
||||
checkmk_monitoring_scripts_dir=str(self.checkmk_monitoring_scripts_dir),
|
||||
)
|
||||
fd, name = tempfile.mkstemp(prefix=".aim-config-", dir=self.root_dir)
|
||||
tmp = Path(name)
|
||||
try:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
"""Controller-local maintenance helpers."""
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,116 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import tempfile
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
from aim.exceptions import AIMError
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PackageResult:
|
||||
label: str
|
||||
filename: str
|
||||
source_url: str
|
||||
size: int
|
||||
old_sha256: str | None
|
||||
new_sha256: str
|
||||
|
||||
|
||||
class CheckmkAgentUpdater:
|
||||
"""Download and atomically stage Checkmk agent packages on the controller."""
|
||||
|
||||
def __init__(self, target_dir: Path):
|
||||
self.target_dir = target_dir
|
||||
|
||||
@staticmethod
|
||||
def _sha256(path: Path) -> str:
|
||||
digest = hashlib.sha256()
|
||||
with path.open('rb') as stream:
|
||||
for chunk in iter(lambda: stream.read(1024 * 1024), b''):
|
||||
digest.update(chunk)
|
||||
return digest.hexdigest()
|
||||
|
||||
@staticmethod
|
||||
def _specs(base_url: str, version: str) -> list[tuple[str, str, str]]:
|
||||
base = base_url.rstrip('/')
|
||||
return [
|
||||
('Windows MSI', f'{base}/windows/check_mk_agent.msi', 'check_mk_agent.msi'),
|
||||
('Debian / Ubuntu DEB', f'{base}/check-mk-agent_{version}_all.deb', 'check-mk-agent.deb'),
|
||||
('RHEL / Alma / Rocky RPM', f'{base}/check-mk-agent-{version}.noarch.rpm', 'check-mk-agent.rpm'),
|
||||
]
|
||||
|
||||
def update(self, base_url: str, version: str) -> list[PackageResult]:
|
||||
base_url = base_url.strip().rstrip('/')
|
||||
version = version.strip()
|
||||
if not base_url:
|
||||
raise AIMError('Checkmk agent base URL is required.')
|
||||
if not version:
|
||||
raise AIMError('Checkmk agent version is required.')
|
||||
if not re.fullmatch(r'\d+\.\d+\.\d+p\d+-\d+', version):
|
||||
raise AIMError(
|
||||
'Checkmk agent version must use the package format <major>.<minor>.<patch>p<patchlevel>-<revision> '
|
||||
'(example: 2.4.0p21-1).'
|
||||
)
|
||||
if not base_url.startswith(('https://', 'http://')):
|
||||
raise AIMError('Checkmk agent base URL must start with https:// or http://.')
|
||||
if not base_url.endswith('/check_mk/agents'):
|
||||
raise AIMError('Checkmk agent base URL must end with /check_mk/agents.')
|
||||
|
||||
specs = self._specs(base_url, version)
|
||||
downloaded: list[tuple[str, str, str, Path, int, str]] = []
|
||||
with tempfile.TemporaryDirectory(prefix='aim-checkmk-agent-') as tmp_name:
|
||||
tmp = Path(tmp_name)
|
||||
for label, url, filename in specs:
|
||||
destination = tmp / filename
|
||||
try:
|
||||
request = Request(url, headers={'User-Agent': 'bitformer-AIM/CheckmkAgentUpdater'})
|
||||
with urlopen(request, timeout=60) as response, destination.open('wb') as output:
|
||||
shutil.copyfileobj(response, output)
|
||||
except (HTTPError, URLError, TimeoutError, OSError) as exc:
|
||||
raise AIMError(f'Could not download {label} from {url}: {exc}') from exc
|
||||
size = destination.stat().st_size
|
||||
if size <= 0:
|
||||
raise AIMError(f'Downloaded {label} is empty: {url}')
|
||||
downloaded.append((label, url, filename, destination, size, self._sha256(destination)))
|
||||
|
||||
try:
|
||||
self.target_dir.mkdir(parents=True, exist_ok=True)
|
||||
except OSError as exc:
|
||||
raise AIMError(f'Could not create Checkmk role files directory {self.target_dir}: {exc}') from exc
|
||||
|
||||
staged: list[tuple[str, str, str, Path, Path, int, str, str | None]] = []
|
||||
try:
|
||||
# Stage every file in the destination filesystem before replacing anything.
|
||||
for label, url, filename, source, size, new_hash in downloaded:
|
||||
target = self.target_dir / filename
|
||||
old_hash = self._sha256(target) if target.exists() else None
|
||||
fd, stage_name = tempfile.mkstemp(prefix=f'.{filename}.aim-', dir=self.target_dir)
|
||||
stage = Path(stage_name)
|
||||
try:
|
||||
with os.fdopen(fd, 'wb') as output, source.open('rb') as input_stream:
|
||||
shutil.copyfileobj(input_stream, output)
|
||||
output.flush()
|
||||
os.fsync(output.fileno())
|
||||
stage.chmod(0o644)
|
||||
except Exception:
|
||||
stage.unlink(missing_ok=True)
|
||||
raise
|
||||
staged.append((label, url, filename, stage, target, size, new_hash, old_hash))
|
||||
|
||||
results: list[PackageResult] = []
|
||||
for label, url, filename, stage, target, size, new_hash, old_hash in staged:
|
||||
os.replace(stage, target)
|
||||
results.append(PackageResult(label, filename, url, size, old_hash, new_hash))
|
||||
return results
|
||||
except OSError as exc:
|
||||
raise AIMError(f'Could not stage Checkmk agent packages in {self.target_dir}: {exc}') from exc
|
||||
finally:
|
||||
for _label, _url, _filename, stage, _target, _size, _new_hash, _old_hash in staged:
|
||||
stage.unlink(missing_ok=True)
|
||||
@@ -0,0 +1,75 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
from aim.exceptions import AIMError
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RepositoryState:
|
||||
path: Path
|
||||
branch: str
|
||||
upstream: str
|
||||
head: str
|
||||
tracked_dirty: bool
|
||||
untracked_count: int
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SyncResult:
|
||||
before: str
|
||||
after: str
|
||||
upstream: str
|
||||
changed: bool
|
||||
stat: str
|
||||
|
||||
|
||||
class ShadowRepository:
|
||||
"""Manage a checkout that intentionally mirrors its configured upstream."""
|
||||
|
||||
def __init__(self, path: Path):
|
||||
self.path = path
|
||||
|
||||
def _git(self, *args: str, check: bool = True) -> str:
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
['git', '-C', str(self.path), *args],
|
||||
text=True, capture_output=True, check=False,
|
||||
)
|
||||
except OSError as exc:
|
||||
raise AIMError(f'Could not execute git: {exc}') from exc
|
||||
output = (proc.stdout or '').strip()
|
||||
error = (proc.stderr or '').strip()
|
||||
if check and proc.returncode != 0:
|
||||
detail = error or output or f'exit code {proc.returncode}'
|
||||
raise AIMError(f'git {" ".join(args)} failed: {detail}')
|
||||
return output
|
||||
|
||||
def inspect(self) -> RepositoryState:
|
||||
if not self.path.is_dir():
|
||||
raise AIMError(f'Monitoring scripts directory does not exist: {self.path}')
|
||||
if self._git('rev-parse', '--is-inside-work-tree') != 'true':
|
||||
raise AIMError(f'Not a Git working tree: {self.path}')
|
||||
branch = self._git('branch', '--show-current') or '(detached HEAD)'
|
||||
if branch == '(detached HEAD)':
|
||||
raise AIMError('The monitoring scripts shadow repository is in detached HEAD state.')
|
||||
upstream = self._git('rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}')
|
||||
head = self._git('rev-parse', 'HEAD')
|
||||
tracked = self._git('status', '--porcelain', '--untracked-files=no')
|
||||
untracked = self._git('ls-files', '--others', '--exclude-standard')
|
||||
return RepositoryState(self.path, branch, upstream, head, bool(tracked.strip()),
|
||||
len([line for line in untracked.splitlines() if line.strip()]))
|
||||
|
||||
def sync(self) -> SyncResult:
|
||||
before = self._git('rev-parse', 'HEAD')
|
||||
upstream = self._git('rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}')
|
||||
self._git('fetch', '--prune')
|
||||
remote_head = self._git('rev-parse', '@{u}')
|
||||
stat = '' if before == remote_head else self._git('diff', '--stat', f'{before}..{remote_head}', check=False)
|
||||
self._git('reset', '--hard', '@{u}')
|
||||
after = self._git('rev-parse', 'HEAD')
|
||||
if after != remote_head:
|
||||
raise AIMError(f'Repository reset did not reach upstream {upstream}. Expected {remote_head}, got {after}.')
|
||||
return SyncResult(before, after, upstream, before != after, stat)
|
||||
Binary file not shown.
Binary file not shown.
@@ -21,22 +21,114 @@ class PlaybookSpec:
|
||||
|
||||
|
||||
PLAYBOOKS: tuple[PlaybookSpec, ...] = (
|
||||
PlaybookSpec("checkmk_cleanup", "Cleanup CheckMK", "checkmk_cleanup.yml", "CheckMK", ("linux", "windows"), ("checkmk_cleanup_enabled=true",)),
|
||||
PlaybookSpec("checkmk_install_agent", "Install CheckMK Agent", "checkmk_install_agent.yml", "CheckMK", ("linux", "windows")),
|
||||
PlaybookSpec("checkmk_update_config", "Update CheckMK Config", "checkmk_update_config.yml", "CheckMK", ("linux", "windows")),
|
||||
PlaybookSpec("debug_ping", "Ping", "debug_ping.yml", "Debug", ("linux", "windows")),
|
||||
PlaybookSpec("debug_server_role_selection", "Server Role Selection", "debug_server_role_selection.yml", "Debug", ("linux", "windows")),
|
||||
PlaybookSpec("debug_disk_usage", "Disk Usage", "debug_disk_usage.yml", "Debug", ("windows",)),
|
||||
PlaybookSpec("patch_os", "Patch OS", "patch_os.yml", "Maintenance", ("linux", "windows")),
|
||||
PlaybookSpec("reboot_system", "Reboot System", "reboot_system.yml", "Maintenance", ("linux", "windows")),
|
||||
PlaybookSpec("backup_eventlog", "Backup Event Log", "backup_eventlog.yml", "Maintenance", ("windows",)),
|
||||
PlaybookSpec("start_stopped_services", "Start Stopped Services", "start_stopped_services.yml", "Maintenance", ("windows",)),
|
||||
PlaybookSpec("configure_sophos_initial", "Initial Bitformer Config", "configure_sophos_initial_bitformer_config.yml", "Sophos XGS", ("sophosxgs",), ask_pass=True, require_vault=True),
|
||||
PlaybookSpec("configure_sophosxgs", "Configure Sophos XGS", "configure_sophosxgs.yml", "Sophos XGS", ("sophosxgs",), customer_specific=True, ask_pass=True, require_vault=True),
|
||||
# CheckMK
|
||||
PlaybookSpec(
|
||||
"checkmk_cleanup",
|
||||
"Cleanup CheckMK",
|
||||
"checkmk_cleanup.yml",
|
||||
"CheckMK",
|
||||
("linux", "windows"),
|
||||
("checkmk_cleanup_enabled=true",),
|
||||
),
|
||||
PlaybookSpec(
|
||||
"checkmk_deploy",
|
||||
"Deploy CheckMK",
|
||||
"checkmk_deploy.yml",
|
||||
"CheckMK",
|
||||
("linux", "windows"),
|
||||
),
|
||||
PlaybookSpec(
|
||||
"checkmk_update_config",
|
||||
"Update CheckMK Config",
|
||||
"checkmk_update_config.yml",
|
||||
"CheckMK",
|
||||
("windows",),
|
||||
),
|
||||
PlaybookSpec(
|
||||
"checkmk_update_scripts",
|
||||
"Update CheckMK Scripts",
|
||||
"checkmk_update_scripts.yml",
|
||||
"CheckMK",
|
||||
("linux", "windows"),
|
||||
),
|
||||
|
||||
# Debug
|
||||
PlaybookSpec(
|
||||
"debug_ping",
|
||||
"Ping",
|
||||
"debug_ping.yml",
|
||||
"Debug",
|
||||
("linux", "windows"),
|
||||
),
|
||||
PlaybookSpec(
|
||||
"debug_server_role_selection",
|
||||
"Server Role Selection",
|
||||
"debug_server_role_selection.yml",
|
||||
"Debug",
|
||||
("linux", "windows"),
|
||||
),
|
||||
PlaybookSpec(
|
||||
"debug_disk_usage",
|
||||
"Disk Usage",
|
||||
"debug_disk_usage.yml",
|
||||
"Debug",
|
||||
("linux", "windows"),
|
||||
),
|
||||
|
||||
# Maintenance
|
||||
PlaybookSpec(
|
||||
"maintenance_patch_os",
|
||||
"Patch OS",
|
||||
"maintenance_patch_os.yml",
|
||||
"Maintenance",
|
||||
("linux", "windows"),
|
||||
),
|
||||
PlaybookSpec(
|
||||
"maintenance_reboot",
|
||||
"Reboot System",
|
||||
"maintenance_reboot.yml",
|
||||
"Maintenance",
|
||||
("linux", "windows"),
|
||||
),
|
||||
PlaybookSpec(
|
||||
"maintenance_backup_event_log",
|
||||
"Backup System Logs",
|
||||
"maintenance_backup_event_log.yml",
|
||||
"Maintenance",
|
||||
("linux", "windows"),
|
||||
),
|
||||
PlaybookSpec(
|
||||
"maintenance_start_stopped_services",
|
||||
"Start Stopped Services",
|
||||
"maintenance_start_stopped_services.yml",
|
||||
"Maintenance",
|
||||
("linux", "windows"),
|
||||
),
|
||||
|
||||
# Sophos XGS
|
||||
# PlaybookSpec(
|
||||
# "configure_sophos_initial",
|
||||
# "Initial Bitformer Config",
|
||||
# "configure_sophos_initial_bitformer_config.yml",
|
||||
# "Sophos XGS",
|
||||
# ("sophosxgs",),
|
||||
# ask_pass=True,
|
||||
# require_vault=True,
|
||||
# ),
|
||||
# PlaybookSpec(
|
||||
# "configure_sophosxgs",
|
||||
# "Configure Sophos XGS",
|
||||
# "configure_sophosxgs.yml",
|
||||
# "Sophos XGS",
|
||||
# ("sophosxgs",),
|
||||
# customer_specific=True,
|
||||
# ask_pass=True,
|
||||
# require_vault=True,
|
||||
# ),
|
||||
)
|
||||
|
||||
CATEGORY_ORDER = ("CheckMK", "Debug", "Maintenance", "Sophos XGS")
|
||||
|
||||
# CATEGORY_ORDER = ("CheckMK", "Debug", "Maintenance", "Sophos XGS")
|
||||
CATEGORY_ORDER = ("CheckMK", "Debug", "Maintenance")
|
||||
|
||||
class PlaybookManager:
|
||||
def __init__(self, customers, config):
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user