207 lines
9.5 KiB
YAML
207 lines
9.5 KiB
YAML
---
|
|
- name: Развернуть Windows/RDP collector'ы AWatch-rus
|
|
hosts: aw_windows
|
|
gather_facts: false
|
|
|
|
vars:
|
|
aw_windows_repo_root: "{{ playbook_dir | dirname }}"
|
|
aw_windows_deploy_root: "C:\\Program Files\\AWatch-rus"
|
|
aw_windows_server_scheme: "http"
|
|
aw_windows_server_host: "10.10.10.13"
|
|
aw_windows_server_port: 5600
|
|
aw_windows_package_version: "v0.13.2"
|
|
aw_windows_package_url: "https://github.com/ActivityWatch/activitywatch/releases/download/v0.13.2/activitywatch-v0.13.2-windows-x86_64.zip"
|
|
aw_windows_package_zip_path: ""
|
|
aw_windows_domain: "SHARKON2025"
|
|
aw_windows_users:
|
|
- user1
|
|
- user2
|
|
- user3
|
|
- user4
|
|
- user5
|
|
aw_windows_extra_users: []
|
|
aw_windows_users_effective: "{{ (aw_windows_users + aw_windows_extra_users) | unique }}"
|
|
aw_windows_install_root: "C:\\Program Files\\AWatch-rus\\bin"
|
|
aw_windows_state_root: "C:\\ProgramData\\AWatch-rus"
|
|
aw_windows_afk_enabled: true
|
|
aw_windows_window_enabled: true
|
|
aw_windows_local_agent_logs_enabled: false
|
|
aw_windows_incident_capture_enabled: true
|
|
aw_windows_incident_screenshot_enabled: true
|
|
aw_windows_incident_artifacts_root: "{{ aw_windows_state_root }}\\incident-artifacts"
|
|
aw_windows_logon_marker_enabled: true
|
|
aw_windows_skip_hardening: false
|
|
aw_windows_rules_path: "{{ aw_windows_deploy_root }}\\windows\\web-category-rules.example.json"
|
|
aw_windows_policy_path: "{{ aw_windows_deploy_root }}\\windows\\dlp-policy.example.json"
|
|
aw_windows_validation_remote_path: "{{ aw_windows_state_root }}\\aw_validate_ansible.json"
|
|
aw_windows_validation_local_dir: "/tmp/aw-rus-validation"
|
|
aw_windows_launch_task_pattern: "ActivityWatch Launch *"
|
|
aw_windows_recovery_task_name: "ActivityWatch Recovery"
|
|
aw_windows_force_task_restart: true
|
|
aw_windows_api_smoke_check_enabled: true
|
|
aw_windows_api_smoke_check_bucket: ""
|
|
aw_windows_api_smoke_check_limit: 10
|
|
aw_windows_fail_on_validation_error: true
|
|
|
|
tasks:
|
|
- name: Проверить обязательные переменные
|
|
ansible.builtin.assert:
|
|
that:
|
|
- aw_windows_server_host is defined
|
|
- aw_windows_server_port is defined
|
|
- aw_windows_server_scheme is defined
|
|
- aw_windows_domain is defined
|
|
- aw_windows_users_effective | length > 0
|
|
- aw_windows_install_root is defined
|
|
- aw_windows_state_root is defined
|
|
fail_msg: "Не заданы обязательные переменные Windows-развёртывания."
|
|
|
|
- name: Создать каталоги развёртывания
|
|
ansible.windows.win_file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
loop:
|
|
- "{{ aw_windows_deploy_root }}"
|
|
- "{{ aw_windows_deploy_root }}\\windows"
|
|
|
|
- name: Загрузить Windows toolkit развёртывания
|
|
ansible.windows.win_copy:
|
|
src: "{{ aw_windows_repo_root }}/windows/{{ item }}"
|
|
dest: "{{ aw_windows_deploy_root }}\\windows\\{{ item }}"
|
|
loop:
|
|
- ActivityWatch.Windows.Common.psd1
|
|
- ActivityWatch.Windows.Common.psm1
|
|
- browser-domains-native-collector.ps1
|
|
- dlp-endpoint-signals-collector.ps1
|
|
- worktime-session-collector.ps1
|
|
- deploy-domain-users.ps1
|
|
- deploy-ensemble.ps1
|
|
- hardening-recovery.ps1
|
|
- validate-deployment.ps1
|
|
- web-category-rules.example.json
|
|
- dlp-policy.example.json
|
|
|
|
- name: Загрузить список пользователей для доменного развёртывания
|
|
ansible.windows.win_copy:
|
|
dest: "{{ aw_windows_deploy_root }}\\windows\\users.txt"
|
|
content: |
|
|
{% for user in aw_windows_users_effective -%}
|
|
{{ user }}
|
|
{% endfor -%}
|
|
|
|
- name: Запустить Windows/RDP ensemble развёртывание
|
|
ansible.windows.win_powershell:
|
|
script: |
|
|
$ErrorActionPreference = 'Stop'
|
|
$params = @{
|
|
ServerScheme = "{{ aw_windows_server_scheme }}"
|
|
ServerHost = "{{ aw_windows_server_host }}"
|
|
ServerPort = {{ aw_windows_server_port }}
|
|
Version = "{{ aw_windows_package_version }}"
|
|
Domain = "{{ aw_windows_domain }}"
|
|
UserListPath = "{{ aw_windows_deploy_root }}\windows\users.txt"
|
|
InstallRoot = "{{ aw_windows_install_root }}"
|
|
StateRoot = "{{ aw_windows_state_root }}"
|
|
AfkEnabled = {{ '$true' if (aw_windows_afk_enabled | bool) else '$false' }}
|
|
WindowEnabled = {{ '$true' if (aw_windows_window_enabled | bool) else '$false' }}
|
|
LocalAgentLogsEnabled = {{ '$true' if (aw_windows_local_agent_logs_enabled | bool) else '$false' }}
|
|
IncidentCaptureEnabled = {{ '$true' if (aw_windows_incident_capture_enabled | bool) else '$false' }}
|
|
IncidentScreenshotEnabled = {{ '$true' if (aw_windows_incident_screenshot_enabled | bool) else '$false' }}
|
|
IncidentArtifactsRoot = "{{ aw_windows_incident_artifacts_root }}"
|
|
LogonMarkerEnabled = {{ '$true' if (aw_windows_logon_marker_enabled | bool) else '$false' }}
|
|
CustomRulesPath = "{{ aw_windows_rules_path }}"
|
|
CustomPolicyPath = "{{ aw_windows_policy_path }}"
|
|
}
|
|
{% if (aw_windows_package_url | default('') | string | length) > 0 %}
|
|
$params.PackageUrl = "{{ aw_windows_package_url }}"
|
|
{% endif %}
|
|
{% if (aw_windows_package_zip_path | default('') | string | length) > 0 %}
|
|
$params.PackageZipPath = "{{ aw_windows_package_zip_path }}"
|
|
{% endif %}
|
|
{% if aw_windows_skip_hardening | bool %}
|
|
$params.SkipHardening = $true
|
|
{% endif %}
|
|
& "{{ aw_windows_deploy_root }}\windows\deploy-ensemble.ps1" @params
|
|
|
|
- name: Принудительно запустить ActivityWatch recovery и launch tasks
|
|
when: aw_windows_force_task_restart | bool
|
|
ansible.windows.win_powershell:
|
|
script: |
|
|
$ErrorActionPreference = 'Stop'
|
|
Start-ScheduledTask -TaskName "{{ aw_windows_recovery_task_name }}"
|
|
Get-ScheduledTask |
|
|
Where-Object TaskName -like "{{ aw_windows_launch_task_pattern }}" |
|
|
ForEach-Object { Start-ScheduledTask -TaskName $_.TaskName }
|
|
|
|
- name: Получить Windows hostname для AW smoke-check bucket
|
|
when:
|
|
- aw_windows_api_smoke_check_enabled | bool
|
|
- aw_windows_afk_enabled | bool
|
|
ansible.windows.win_command: powershell.exe -NoProfile -Command "$env:COMPUTERNAME"
|
|
register: aw_windows_hostname_result
|
|
changed_when: false
|
|
|
|
- name: Вычислить AW AFK smoke-check bucket
|
|
when:
|
|
- aw_windows_api_smoke_check_enabled | bool
|
|
- aw_windows_afk_enabled | bool
|
|
ansible.builtin.set_fact:
|
|
aw_windows_api_smoke_check_bucket_effective: >-
|
|
{{
|
|
aw_windows_api_smoke_check_bucket
|
|
if (aw_windows_api_smoke_check_bucket | default('') | string | length) > 0
|
|
else 'aw-watcher-afk_' ~ (aw_windows_hostname_result.stdout | trim)
|
|
}}
|
|
|
|
- name: Дождаться свежих AFK событий на AW server
|
|
when:
|
|
- aw_windows_api_smoke_check_enabled | bool
|
|
- aw_windows_afk_enabled | bool
|
|
delegate_to: localhost
|
|
ansible.builtin.uri:
|
|
url: "{{ aw_windows_server_scheme }}://{{ aw_windows_server_host }}:{{ aw_windows_server_port }}/api/0/buckets/{{ aw_windows_api_smoke_check_bucket_effective }}/events?limit={{ aw_windows_api_smoke_check_limit }}"
|
|
method: GET
|
|
return_content: true
|
|
register: aw_windows_api_smoke
|
|
until: >
|
|
aw_windows_api_smoke.status == 200 and
|
|
(aw_windows_api_smoke.json | length) > 0 and
|
|
(
|
|
aw_windows_api_smoke.json
|
|
| selectattr('data.status', 'equalto', 'not-afk')
|
|
| list
|
|
| length
|
|
) > 0
|
|
retries: 10
|
|
delay: 6
|
|
|
|
- name: Выполнить валидацию и сохранить отчёт на целевом Windows host
|
|
ansible.windows.win_powershell:
|
|
script: |
|
|
$ErrorActionPreference = 'Stop'
|
|
$report = & "{{ aw_windows_deploy_root }}\windows\validate-deployment.ps1" `
|
|
-ConfigPath "{{ aw_windows_state_root }}\deployment-config.json"
|
|
$report | ConvertTo-Json -Depth 12 | Out-File -FilePath "{{ aw_windows_validation_remote_path }}" -Encoding utf8
|
|
if ({{ '$true' if (aw_windows_fail_on_validation_error | bool) else '$false' }} -and -not [bool]$report.overallOk) {
|
|
throw "Проверка развёртывания ActivityWatch завершилась ошибкой. Отчёт: {{ aw_windows_validation_remote_path }}"
|
|
}
|
|
|
|
- name: Создать локальный каталог для validation reports
|
|
ansible.builtin.file:
|
|
path: "{{ aw_windows_validation_local_dir }}"
|
|
state: directory
|
|
mode: "0755"
|
|
delegate_to: localhost
|
|
|
|
- name: Забрать validation report
|
|
ansible.builtin.fetch:
|
|
src: "{{ aw_windows_validation_remote_path }}"
|
|
dest: "{{ aw_windows_validation_local_dir }}/{{ inventory_hostname }}-aw_validate_ansible.json"
|
|
flat: true
|
|
|
|
- name: Показать путь к отчёту
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "Windows/RDP развёртывание завершено на {{ inventory_hostname }}."
|
|
- "Отчёт проверки: {{ aw_windows_validation_local_dir }}/{{ inventory_hostname }}-aw_validate_ansible.json"
|