aim-web2.1.0rc9
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# checkmk_configure_agent
|
||||
|
||||
On Windows, AIM owns only the top-level `plugins:` section of `check_mk.user.yml`.
|
||||
The role preserves all other top-level sections and comments, including `global`,
|
||||
`winperf`, `fileinfo`, `logwatch`, `local`, and `mrpe`.
|
||||
|
||||
The first line is an AIM ownership notice. The managed `plugins:` section also gets
|
||||
its own ownership comment so operators can see the exact management boundary.
|
||||
|
||||
Operator defaults are intentionally low-precedence; inventory and explicit run options may override them.
|
||||
|
||||
```yaml
|
||||
---
|
||||
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_plugin_patterns` entries are inserted before AIM's standard plugin
|
||||
rules. AIM does not manage `local:` or `mrpe:` from this role; existing host-specific
|
||||
configuration in those sections is left intact.
|
||||
|
||||
## Structured result integration
|
||||
|
||||
Current reporting behavior and field semantics are specified in
|
||||
[scripts/docs/OPERATION_RESULTS.md](../../scripts/docs/OPERATION_RESULTS.md).
|
||||
The calling catalog playbook owns publication; helper roles do not implicitly export
|
||||
arbitrary facts, module results or debug data. Existing defaults above retain their
|
||||
precedence. See the current validation/sanity documents before using the new candidate.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
# AIM owns only the top-level plugins section in the Windows user configuration.
|
||||
# All other sections and comments must remain untouched.
|
||||
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: []
|
||||
@@ -0,0 +1,196 @@
|
||||
---
|
||||
|
||||
- name: Checkmk | Validate Windows plugin execution settings
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- checkmk_extra_plugin_patterns is sequence
|
||||
- checkmk_extra_plugin_patterns is not string
|
||||
- checkmk_windows_updates_timeout | int >= 0
|
||||
- checkmk_windows_updates_cache | int >= 0
|
||||
- checkmk_mk_inventory_timeout | int >= 0
|
||||
- checkmk_plugins_default_timeout | int >= 0
|
||||
- checkmk_plugins_default_cache | int >= 0
|
||||
fail_msg: Invalid Checkmk plugin execution setting type or negative timeout.
|
||||
quiet: true
|
||||
when: ansible_facts.os_family == 'Windows'
|
||||
|
||||
- name: Checkmk | Validate custom plugin rule fields
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- item is mapping
|
||||
- item.pattern is defined
|
||||
- item.pattern is string
|
||||
- item.run is not defined or item.run is boolean
|
||||
- item['async'] is not defined or item['async'] is boolean
|
||||
- item.timeout is not defined or item.timeout | int >= 0
|
||||
- item.cache_age is not defined or item.cache_age | int >= 0
|
||||
- item.keys() | difference(['pattern','run','async','timeout','cache_age','retry_count']) | length == 0
|
||||
fail_msg: Custom plugin rules require pattern and supported execution fields.
|
||||
quiet: true
|
||||
loop: '{{ checkmk_extra_plugin_patterns }}'
|
||||
loop_control:
|
||||
label: custom plugin execution rule
|
||||
no_log: true
|
||||
when: ansible_facts.os_family == 'Windows'
|
||||
|
||||
- name: Windows | Render AIM-managed Checkmk plugins section
|
||||
ansible.windows.win_template:
|
||||
src: windows_plugins_section.yml.j2
|
||||
dest: '{{ checkmk_windows_user_cfg }}.aim-plugins.tmp'
|
||||
when: ansible_facts.os_family == 'Windows'
|
||||
diff: false
|
||||
changed_when: false
|
||||
|
||||
- name: Windows | Replace only Checkmk plugins section
|
||||
ansible.windows.win_shell: |
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$configPath = '{{ checkmk_windows_user_cfg }}'
|
||||
$fragmentPath = '{{ checkmk_windows_user_cfg }}.aim-plugins.tmp'
|
||||
$header = '# Managed by Ansible (checkmk_configure_agent). Only AIM-marked sections are modified; all other content is preserved.'
|
||||
$legacyHeader = '# Managed by Ansible (checkmk_configure_agent).'
|
||||
$managedMarkerPrefix = '# AIM managed section: plugins (checkmk_configure_agent).'
|
||||
|
||||
if (-not (Test-Path -LiteralPath $fragmentPath)) {
|
||||
throw "AIM Checkmk plugins fragment is missing: $fragmentPath"
|
||||
}
|
||||
|
||||
$fragment = [System.IO.File]::ReadAllText($fragmentPath)
|
||||
$fragment = $fragment.TrimEnd([char[]]"`r`n")
|
||||
|
||||
if (Test-Path -LiteralPath $configPath) {
|
||||
$original = [System.IO.File]::ReadAllText($configPath)
|
||||
}
|
||||
else {
|
||||
$original = ''
|
||||
}
|
||||
|
||||
if ($original.Contains("`r`n")) {
|
||||
$newline = "`r`n"
|
||||
}
|
||||
else {
|
||||
$newline = "`n"
|
||||
}
|
||||
|
||||
$hadFinalNewline = $original.EndsWith("`r`n") -or $original.EndsWith("`n") -or $original.EndsWith("`r")
|
||||
$lines = @()
|
||||
if ($original.Length -gt 0) {
|
||||
$lines = @([regex]::Split($original, "`r`n|`n|`r"))
|
||||
if ($hadFinalNewline -and $lines.Count -gt 0 -and $lines[$lines.Count - 1] -eq '') {
|
||||
if ($lines.Count -eq 1) {
|
||||
$lines = @()
|
||||
}
|
||||
else {
|
||||
$lines = @($lines[0..($lines.Count - 2)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Keep the AIM ownership notice as line 1 without discarding the previous first line.
|
||||
if ($lines.Count -eq 0) {
|
||||
$lines = @($header)
|
||||
}
|
||||
elseif ($lines[0] -eq $legacyHeader -or $lines[0].StartsWith('# Managed by Ansible (checkmk_configure_agent).')) {
|
||||
$lines[0] = $header
|
||||
}
|
||||
else {
|
||||
$lines = @($header) + $lines
|
||||
}
|
||||
|
||||
$pluginIndex = -1
|
||||
for ($i = 0; $i -lt $lines.Count; $i++) {
|
||||
if ($lines[$i] -match '^plugins\s*:\s*(?:#.*)?$') {
|
||||
$pluginIndex = $i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
$fragmentLines = @([regex]::Split($fragment, "`r`n|`n|`r"))
|
||||
|
||||
if ($pluginIndex -ge 0) {
|
||||
$replaceStart = $pluginIndex
|
||||
if ($pluginIndex -gt 0 -and $lines[$pluginIndex - 1].StartsWith($managedMarkerPrefix)) {
|
||||
$replaceStart = $pluginIndex - 1
|
||||
}
|
||||
|
||||
$nextTopLevelKey = $lines.Count
|
||||
for ($i = $pluginIndex + 1; $i -lt $lines.Count; $i++) {
|
||||
if ($lines[$i] -match '^[A-Za-z_][A-Za-z0-9_.-]*\s*:') {
|
||||
$nextTopLevelKey = $i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# Preserve blank lines and top-level comments immediately before the next untouched section.
|
||||
$replaceEnd = $nextTopLevelKey
|
||||
while ($replaceEnd -gt ($pluginIndex + 1)) {
|
||||
$candidate = $lines[$replaceEnd - 1]
|
||||
if ([string]::IsNullOrWhiteSpace($candidate) -or $candidate.StartsWith('#')) {
|
||||
$replaceEnd--
|
||||
}
|
||||
else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
$before = @()
|
||||
if ($replaceStart -gt 0) {
|
||||
$before = @($lines[0..($replaceStart - 1)])
|
||||
}
|
||||
$after = @()
|
||||
if ($replaceEnd -lt $lines.Count) {
|
||||
$after = @($lines[$replaceEnd..($lines.Count - 1)])
|
||||
}
|
||||
$lines = @($before + $fragmentLines + $after)
|
||||
}
|
||||
else {
|
||||
if ($lines.Count -gt 0 -and -not [string]::IsNullOrWhiteSpace($lines[$lines.Count - 1])) {
|
||||
$lines += ''
|
||||
}
|
||||
$lines += $fragmentLines
|
||||
}
|
||||
|
||||
$updated = [string]::Join($newline, $lines)
|
||||
if ($hadFinalNewline -or $original.Length -eq 0) {
|
||||
$updated += $newline
|
||||
}
|
||||
|
||||
if ($updated -ne $original) {
|
||||
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
|
||||
[System.IO.File]::WriteAllText($configPath, $updated, $utf8NoBom)
|
||||
Write-Output 'AIM_CHANGED=true'
|
||||
}
|
||||
else {
|
||||
Write-Output 'AIM_CHANGED=false'
|
||||
}
|
||||
register: _checkmk_plugins_update
|
||||
changed_when: "'AIM_CHANGED=true' in _checkmk_plugins_update.stdout"
|
||||
when: ansible_facts.os_family == 'Windows'
|
||||
notify: checkmk | windows | configuration-changed
|
||||
diff: false
|
||||
|
||||
- name: Windows | Normalize ACL on Checkmk user configuration
|
||||
ansible.builtin.include_role:
|
||||
name: checkmk_windows_acl
|
||||
vars:
|
||||
checkmk_windows_acl_paths:
|
||||
- '{{ checkmk_windows_user_cfg }}'
|
||||
when: ansible_facts.os_family == 'Windows'
|
||||
|
||||
- name: Windows | Remove temporary Checkmk plugins fragment
|
||||
ansible.windows.win_file:
|
||||
path: '{{ checkmk_windows_user_cfg }}.aim-plugins.tmp'
|
||||
state: absent
|
||||
when: ansible_facts.os_family == 'Windows'
|
||||
changed_when: false
|
||||
|
||||
- name: Checkmk | Configuration summary
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
destination: '{{ checkmk_windows_user_cfg }}'
|
||||
managed_section: plugins
|
||||
extra_plugin_rules: '{{ checkmk_extra_plugin_patterns | length }}'
|
||||
other_sections: preserved
|
||||
when:
|
||||
- ansible_facts.os_family == 'Windows'
|
||||
- aim_debug | default(false) | bool
|
||||
@@ -0,0 +1,72 @@
|
||||
# AIM managed section: plugins (checkmk_configure_agent). Content under plugins: may be replaced by AIM.
|
||||
plugins:
|
||||
execution:
|
||||
{% if checkmk_extra_plugin_patterns | length %}
|
||||
{{ checkmk_extra_plugin_patterns | to_nice_yaml(indent=2, sort_keys=false) | indent(4, true) }}
|
||||
{% endif %}
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\windows_updates.vbs'
|
||||
run: true
|
||||
async: true
|
||||
timeout: {{ checkmk_windows_updates_timeout | int }}
|
||||
cache_age: {{ checkmk_windows_updates_cache | int }}
|
||||
retry_count: 0
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\mk_inventory.vbs'
|
||||
run: true
|
||||
async: true
|
||||
timeout: {{ checkmk_mk_inventory_timeout | int }}
|
||||
cache_age: 3600
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\mssql.vbs'
|
||||
run: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
{% if has_veeam_vbo | default(false) %}
|
||||
- pattern: '$CUSTOM_PLUGINS_PATH$\veeam_o365_status.ps1'
|
||||
run: true
|
||||
async: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
cache_age: {{ checkmk_plugins_default_cache | int }}
|
||||
{% endif %}
|
||||
{% if want_windows_citrix | default(false) %}
|
||||
- pattern: '$CUSTOM_PLUGINS_PATH$\citrix_sessions_customized.ps1'
|
||||
run: true
|
||||
async: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
cache_age: {{ checkmk_plugins_default_cache | int }}
|
||||
{% endif %}
|
||||
{% if want_windows_veeam_backup | default(false) %}
|
||||
- pattern: '$CUSTOM_PLUGINS_PATH$\veeam_backup_status.ps1'
|
||||
run: true
|
||||
async: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
cache_age: {{ checkmk_plugins_default_cache | int }}
|
||||
{% endif %}
|
||||
{% if is_dc | default(false) %}
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\ad_replication.bat'
|
||||
run: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
{% endif %}
|
||||
{% if is_dhcp_server | default(false) %}
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\win_dhcp_pools.bat'
|
||||
run: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
{% endif %}
|
||||
{% if is_hyperv_host | default(false) %}
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\hyperv_vms.ps1'
|
||||
run: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\hyperv_vms_guestinfos.ps1'
|
||||
run: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
{% endif %}
|
||||
- pattern: '$CUSTOM_PLUGINS_PATH$\*.ps1'
|
||||
run: true
|
||||
async: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
cache_age: {{ checkmk_plugins_default_cache | int }}
|
||||
- pattern: '$CUSTOM_PLUGINS_PATH$\*.*'
|
||||
run: true
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
- pattern: '$BUILTIN_PLUGINS_PATH$\*.*'
|
||||
run: false
|
||||
timeout: {{ checkmk_plugins_default_timeout | int }}
|
||||
- pattern: '*'
|
||||
run: false
|
||||
Reference in New Issue
Block a user