- Updated `bf-wireguard-restart.yml` to include dynamic host targeting based on `operation_wave`. - Added pre-tasks to assert that the operation wave is approved and confirmed, ensuring proper execution context. - Modified the service restart task to use a more structured command format. - Adjusted `operations.py` and `ui_gui.py` to reflect changes in operation scope from "simple" to "wave" for relevant operations. - Improved UI handling in `ui_gui.py` and `ui_surfaces.py` for better output management and user interaction. - Updated log rotation configuration to target specific log files. - Enhanced systemd service configurations for WireGuard to improve restart behavior. - Refined firstboot scripts to ensure proper handling of dealer ID and state management. - Improved error handling and rollback mechanisms in identity and installation scripts.
80 lines
No EOL
3.3 KiB
YAML
80 lines
No EOL
3.3 KiB
YAML
---
|
|
# Run an approved script already present on a confirmed maintenance wave.
|
|
- name: Run operator script
|
|
hosts: "{{ operation_wave | default('invalid-wave', true) }}"
|
|
gather_facts: false
|
|
become: true
|
|
vars:
|
|
approved_operation_waves: [lab, pilot_1, pilot_2, wave_1, wave_2, production]
|
|
production_override: false
|
|
script_path: ""
|
|
script_args: ""
|
|
script_allowed_dirs:
|
|
- /opt/blueforce/bin
|
|
- /usr/local/sbin
|
|
script_allowlist: []
|
|
pre_tasks:
|
|
- name: Require confirmed approved operation wave scope
|
|
ansible.builtin.assert:
|
|
that:
|
|
- operation_wave in approved_operation_waves
|
|
- operation_confirmed | bool
|
|
- operation_wave in groups
|
|
- ansible_play_hosts_all | length > 0
|
|
- ansible_play_hosts_all | difference(groups[operation_wave]) | length == 0
|
|
fail_msg: "Set operation_wave to one inventory wave and operation_confirmed=true; full-fleet scope is refused."
|
|
run_once: true
|
|
|
|
- name: Require separate production override
|
|
ansible.builtin.assert:
|
|
that:
|
|
- operation_wave != 'production' or production_override | bool
|
|
fail_msg: "Production operation requires production_override=true in addition to operation_confirmed=true."
|
|
run_once: true
|
|
tasks:
|
|
- name: Canonicalize requested script path
|
|
ansible.builtin.command:
|
|
argv: [readlink, -f, --, "{{ script_path }}"]
|
|
register: canonical_script
|
|
changed_when: false
|
|
failed_when: canonical_script.rc != 0
|
|
|
|
- name: Canonicalize approved directory prefixes
|
|
ansible.builtin.command:
|
|
argv: [readlink, -f, --, "{{ item }}"]
|
|
loop: "{{ script_allowed_dirs }}"
|
|
register: canonical_dirs
|
|
changed_when: false
|
|
|
|
- name: Validate exact approved path boundary or explicit allowlist
|
|
ansible.builtin.assert:
|
|
that:
|
|
- canonical_script.stdout is match('^/.+')
|
|
- canonical_script.stdout in script_allowlist or (canonical_dirs.results | map(attribute='stdout') | select('match', '^/.+') | map('regex_replace', '$', '/') | select('in', canonical_script.stdout + '/') | list | length > 0)
|
|
fail_msg: "Refused root execution of '{{ script_path }}': canonical path '{{ canonical_script.stdout }}' is not in an approved directory or explicit allowlist."
|
|
|
|
- name: Check canonical script is a regular executable file
|
|
ansible.builtin.stat:
|
|
path: "{{ canonical_script.stdout }}"
|
|
register: script_stat
|
|
|
|
- name: Validate canonical script metadata
|
|
ansible.builtin.assert:
|
|
that:
|
|
- script_stat.stat.exists
|
|
- script_stat.stat.isreg
|
|
- script_stat.stat.executable
|
|
|
|
- name: Execute approved canonical script
|
|
# NOTE: script_args is split on whitespace; quoted arguments are NOT
|
|
# preserved. The plain split is the safe default (no shell involved),
|
|
# so multi-word input must be passed as separate words.
|
|
ansible.builtin.command:
|
|
argv: "{{ [canonical_script.stdout] + (script_args | default('') | split()) }}"
|
|
register: script_out
|
|
changed_when: true
|
|
|
|
- name: Show script output
|
|
# Intentional: script output stays operator-visible; do NOT add no_log here.
|
|
ansible.builtin.debug:
|
|
msg: "{{ inventory_hostname }} exit={{ script_out.rc }}\n{{ script_out.stdout | default('') }}{{ script_out.stderr | default('') }}" |