mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 11:03:59 +00:00
- Ensure k3s mode uses the k3s registry endpoint and avoid localhost/k3d image prefixes. - Make ArgoCD repo-server cmp symlink creation idempotent. - Normalize common-core provisioning to knoe-system and add repair-time dedupe of stray default-namespace installs. - Add k3s MariaDB datastore/refresh playbooks and regression tests.
196 lines
6.7 KiB
YAML
196 lines
6.7 KiB
YAML
---
|
|
|
|
- name: Guard - require explicit confirmation for k3s server refresh
|
|
ansible.builtin.assert:
|
|
that:
|
|
- k3s_role == 'server'
|
|
- k3s_state == 'present'
|
|
- (k3s_refresh_confirm | default('')) == 'YES'
|
|
fail_msg: >-
|
|
Refusing to refresh k3s server without explicit confirmation.
|
|
Set k3s_refresh_confirm=YES and re-run (this is destructive: it wipes k3s state).
|
|
|
|
- name: Read current k3s config (to detect current data-dir)
|
|
ansible.builtin.stat:
|
|
path: /etc/rancher/k3s/config.yaml
|
|
register: _k3s_refresh_config_stat
|
|
|
|
- name: Slurp current k3s config
|
|
ansible.builtin.slurp:
|
|
src: /etc/rancher/k3s/config.yaml
|
|
register: _k3s_refresh_config_slurp
|
|
when: _k3s_refresh_config_stat.stat.exists
|
|
|
|
- name: Set refresh source/target data-dir
|
|
ansible.builtin.set_fact:
|
|
_k3s_refresh_cfg: >-
|
|
{{
|
|
(_k3s_refresh_config_slurp.content | b64decode | from_yaml)
|
|
if (_k3s_refresh_config_stat.stat.exists | bool)
|
|
else {}
|
|
}}
|
|
k3s_refresh_source_data_dir: >-
|
|
{{
|
|
_k3s_refresh_cfg.get('data-dir')
|
|
| default((k3s_data_dir | default('/var/lib/rancher/k3s')), true)
|
|
}}
|
|
k3s_refresh_target_data_dir: "{{ k3s_data_dir | default('/var/lib/rancher/k3s') }}"
|
|
|
|
- name: Preflight - check external datastore TCP reachability (best-effort)
|
|
ansible.builtin.wait_for:
|
|
host: "{{ k3s_datastore_mariadb_host }}"
|
|
port: "{{ k3s_datastore_mariadb_port | default(3306) }}"
|
|
connect_timeout: 2
|
|
timeout: 5
|
|
state: started
|
|
when:
|
|
- (k3s_datastore_endpoint | default('') | length) > 0
|
|
- k3s_datastore_mariadb_host is defined
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Create refresh backup directory
|
|
ansible.builtin.file:
|
|
path: "{{ k3s_refresh_backup_root }}/{{ inventory_hostname }}/{{ ansible_date_time.iso8601_basic_short }}"
|
|
state: directory
|
|
mode: "0700"
|
|
register: _k3s_refresh_backup_dir
|
|
|
|
- name: Stat k3s token/tls artifacts (source data-dir)
|
|
ansible.builtin.stat:
|
|
path: "{{ item }}"
|
|
loop:
|
|
- "{{ k3s_refresh_source_data_dir }}/server/token"
|
|
- "{{ k3s_refresh_source_data_dir }}/server/node-token"
|
|
# Minimal TLS set to preserve agent trust (CA hash) while allowing k3s to
|
|
# regenerate component creds and `server/cred/*.kubeconfig`.
|
|
- "{{ k3s_refresh_source_data_dir }}/server/tls/server-ca.crt"
|
|
- "{{ k3s_refresh_source_data_dir }}/server/tls/server-ca.key"
|
|
- "{{ k3s_refresh_source_data_dir }}/server/tls/client-ca.crt"
|
|
- "{{ k3s_refresh_source_data_dir }}/server/tls/client-ca.key"
|
|
- "{{ k3s_refresh_source_data_dir }}/server/tls/request-header-ca.crt"
|
|
- "{{ k3s_refresh_source_data_dir }}/server/tls/request-header-ca.key"
|
|
- "{{ k3s_refresh_source_data_dir }}/server/tls/service.key"
|
|
- "{{ k3s_refresh_source_data_dir }}/server/tls/service.current.key"
|
|
register: _k3s_refresh_artifacts
|
|
|
|
- name: Back up k3s token/tls artifacts (remote->remote)
|
|
ansible.builtin.copy:
|
|
remote_src: true
|
|
src: "{{ item.item }}"
|
|
dest: "{{ _k3s_refresh_backup_dir.path }}/"
|
|
mode: preserve
|
|
loop: "{{ _k3s_refresh_artifacts.results }}"
|
|
when: item.stat.exists
|
|
|
|
- name: Read preserved server token (source data-dir)
|
|
ansible.builtin.slurp:
|
|
src: "{{ k3s_refresh_source_data_dir }}/server/token"
|
|
register: _k3s_refresh_token_slurp
|
|
when: >-
|
|
{{
|
|
(
|
|
_k3s_refresh_artifacts.results
|
|
| selectattr('item', 'equalto', (k3s_refresh_source_data_dir ~ '/server/token'))
|
|
| map(attribute='stat.exists')
|
|
| first
|
|
)
|
|
| default(false)
|
|
}}
|
|
no_log: true
|
|
|
|
- name: Ensure we have a token to preserve
|
|
ansible.builtin.assert:
|
|
that:
|
|
- (k3s_token | default('') | length) > 0 or (_k3s_refresh_token_slurp is defined)
|
|
fail_msg: >-
|
|
No existing token file was found under {{ k3s_refresh_source_data_dir }}/server/token,
|
|
and k3s_token is empty. Refusing to proceed because this would change the join token.
|
|
|
|
- name: Force k3s_token to preserved token (so rendered config matches what we restore)
|
|
ansible.builtin.set_fact:
|
|
k3s_token: "{{ (_k3s_refresh_token_slurp.content | b64decode | trim) if (_k3s_refresh_token_slurp is defined) else k3s_token }}"
|
|
no_log: true
|
|
|
|
- name: Stop k3s services before refresh
|
|
ansible.builtin.service:
|
|
name: "{{ item }}"
|
|
state: stopped
|
|
enabled: false
|
|
loop:
|
|
- k3s
|
|
- k3s-agent
|
|
failed_when: false
|
|
|
|
- name: Uninstall and wipe k3s state (blank slate)
|
|
ansible.builtin.import_tasks: cleanup.yml
|
|
|
|
- name: Wipe target k3s data-dir (blank slate except restored token/CA)
|
|
ansible.builtin.file:
|
|
path: "{{ k3s_refresh_target_data_dir }}"
|
|
state: absent
|
|
|
|
- name: Recreate target server directory
|
|
ansible.builtin.file:
|
|
path: "{{ k3s_refresh_target_data_dir }}/server"
|
|
state: directory
|
|
mode: "0700"
|
|
|
|
- name: Recreate target tls directory
|
|
ansible.builtin.file:
|
|
path: "{{ k3s_refresh_target_data_dir }}/server/tls"
|
|
state: directory
|
|
mode: "0700"
|
|
|
|
- name: Restore preserved minimal tls artifacts into target data-dir
|
|
ansible.builtin.copy:
|
|
remote_src: true
|
|
src: "{{ item }}"
|
|
dest: "{{ k3s_refresh_target_data_dir }}/server/tls/"
|
|
mode: preserve
|
|
loop:
|
|
- "{{ _k3s_refresh_backup_dir.path }}/server-ca.crt"
|
|
- "{{ _k3s_refresh_backup_dir.path }}/server-ca.key"
|
|
- "{{ _k3s_refresh_backup_dir.path }}/client-ca.crt"
|
|
- "{{ _k3s_refresh_backup_dir.path }}/client-ca.key"
|
|
- "{{ _k3s_refresh_backup_dir.path }}/request-header-ca.crt"
|
|
- "{{ _k3s_refresh_backup_dir.path }}/request-header-ca.key"
|
|
- "{{ _k3s_refresh_backup_dir.path }}/service.key"
|
|
- "{{ _k3s_refresh_backup_dir.path }}/service.current.key"
|
|
failed_when: false
|
|
|
|
- name: Install and start k3s
|
|
ansible.builtin.import_tasks: install.yml
|
|
|
|
- name: Configure k3s add-ons
|
|
ansible.builtin.import_tasks: configure.yml
|
|
when: k3s_refresh_run_configure | bool
|
|
|
|
- name: Verify k3s API is responsive after refresh
|
|
ansible.builtin.command: k3s kubectl get nodes
|
|
register: _k3s_refresh_nodes
|
|
changed_when: false
|
|
until: _k3s_refresh_nodes.rc == 0
|
|
retries: 18
|
|
delay: 10
|
|
|
|
- name: Read k3s node-token after refresh
|
|
ansible.builtin.slurp:
|
|
src: "{{ k3s_refresh_target_data_dir }}/server/node-token"
|
|
register: _k3s_refresh_node_token
|
|
changed_when: false
|
|
until: _k3s_refresh_node_token is succeeded
|
|
retries: 18
|
|
delay: 10
|
|
no_log: true
|
|
|
|
- name: Assert node-token is preserved (when token is in node-token format)
|
|
ansible.builtin.assert:
|
|
that:
|
|
- (k3s_token | default('')) == (_k3s_refresh_node_token.content | b64decode | trim)
|
|
fail_msg: >-
|
|
Refusing to continue: expected regenerated node-token to match preserved k3s_token,
|
|
but it differs. This indicates the join token changed.
|
|
when:
|
|
- (k3s_token | default('')) is match('^K10[0-9a-f]+::server:.+')
|