diff --git a/roles/global_defaults/defaults/main.yml b/roles/global_defaults/defaults/main.yml index f75f7b5..fa817c6 100644 --- a/roles/global_defaults/defaults/main.yml +++ b/roles/global_defaults/defaults/main.yml @@ -1,5 +1,4 @@ --- -# OS family lists - single source of truth for platform detection and validation os_family_rhel: - almalinux - fedora @@ -10,8 +9,7 @@ os_family_debian: - ubuntu - ubuntu-lts -# OS -> family mapping - aligns with the main project's ansible_os_family pattern. -# Enables platform_config dict lookups per role instead of inline when: is_rhel chains. +# OS -> family, so roles do platform_config lookups instead of is_rhel when-chains. os_family_map: almalinux: RedHat archlinux: Archlinux @@ -40,6 +38,8 @@ hypervisor_defaults: url: "" username: "" password: "" + token_id: "" + token_secret: "" node: "" storage: "" datacenter: "" @@ -78,9 +78,8 @@ system_defaults: timezone: "Europe/Vienna" locale: "en_US.UTF-8" keymap: "us" - # Uniform content source, family-resolved. source: dvd|mirror|satellite|none - # ('' -> family default: EL=dvd, debian/ubuntu/arch=mirror). satellite values - # come from inventory/vault only, never committed code. + # source: dvd|mirror|satellite|none ('' -> family default: EL=dvd, else mirror). + # satellite values come from inventory/vault only, never committed code. content: source: "" url: "" @@ -119,9 +118,7 @@ system_defaults: bits: 512 pbkdf: "argon2id" features: - # Bake cloud-init for the deterministic clone-deploy golden path; off by - # default (ansible-direct everywhere, smaller image). Package name is - # uniform across families. + # On only for the clone-deploy golden path; off keeps ansible-direct + smaller image. cloud_init: false cis: enabled: false @@ -172,10 +169,8 @@ system_defaults: displaylink: false hardware: profile: {} # full override: non-empty SKIPS detection (golden image) - # Declarative hardware group: a per-device profile that MERGES over - # auto-detect (auto-detect = base; these supplement/override it). Vendor - # lists union with detection, booleans OR with detection, packages append, - # disable[] force-off (applied last), kernel_params append to the cmdline. + # The keys below MERGE over detection: lists union, booleans OR, packages + # and kernel_params append, disable[] force-off applied last. cpu: "" # pin a CPU vendor (intel|amd); empty = use detection gpus: [] # extra GPU vendor codes to force wireless: [] # extra wireless vendor codes to force @@ -187,11 +182,10 @@ system_defaults: disable: [] # feature/vendor names to force-off (audio|bluetooth|camera|fingerprint|displaylink|) kernel_params: [] # extra kernel cmdline params (quirks), e.g. ["i915.enable_psr=0"] -# Per-hypervisor required fields - drives data-driven validation. -# All virtual types additionally require network bridge or interfaces. +# Drives data-driven validation. Virtual types also require a network bridge or interfaces. hypervisor_required_fields: proxmox: - hypervisor: [url, username, password, node, storage] + hypervisor: [url, username, node, storage] system: [id] vmware: hypervisor: [url, username, password, datacenter, storage] @@ -203,14 +197,13 @@ hypervisor_required_fields: hypervisor: [] system: [] -# Family default content mirror URLs, used when content.url is empty. +# Used when content.url is empty. content_mirror_defaults: debian: "https://deb.debian.org/debian/" ubuntu: "http://archive.ubuntu.com/ubuntu/" ubuntu-lts: "http://archive.ubuntu.com/ubuntu/" -# Hypervisor-to-disk device prefix mapping for virtual machines. -# Physical installs must set system.disks[].device explicitly. +# Virtual-only; physical installs must set system.disks[].device explicitly. hypervisor_disk_device_map: libvirt: "/dev/vd" xen: "/dev/xvd" diff --git a/roles/global_defaults/tasks/main.yml b/roles/global_defaults/tasks/main.yml index f14b10d..03e5133 100644 --- a/roles/global_defaults/tasks/main.yml +++ b/roles/global_defaults/tasks/main.yml @@ -1,8 +1,6 @@ --- -# Centralized normalization - all input dicts (system, hypervisor, disks) -# are normalized here into system_cfg, hypervisor_cfg, etc. -# Downstream roles consume these computed facts directly and do NOT need -# per-role _normalize.yml (except CIS, which has its own input dict). +# Normalizes all input dicts into system_cfg/hypervisor_cfg/etc. here, so downstream +# roles consume the computed facts directly with no per-role _normalize (except CIS). - name: Global defaults loaded ansible.builtin.debug: msg: Global defaults loaded. @@ -27,11 +25,15 @@ _proxmox_auth: api_host: "{{ hypervisor_cfg.url }}" api_user: "{{ hypervisor_cfg.username }}" - api_password: "{{ hypervisor_cfg.password }}" + api_password: "{{ hypervisor_cfg.password | default(omit, true) }}" + api_token_id: "{{ hypervisor_cfg.token_id | default(omit, true) }}" + api_token_secret: "{{ hypervisor_cfg.token_secret | default(omit, true) }}" _proxmox_auth_node: api_host: "{{ hypervisor_cfg.url }}" api_user: "{{ hypervisor_cfg.username }}" - api_password: "{{ hypervisor_cfg.password }}" + api_password: "{{ hypervisor_cfg.password | default(omit, true) }}" + api_token_id: "{{ hypervisor_cfg.token_id | default(omit, true) }}" + api_token_secret: "{{ hypervisor_cfg.token_secret | default(omit, true) }}" node: "{{ hypervisor_cfg.node }}" no_log: true diff --git a/roles/global_defaults/tasks/validation.yml b/roles/global_defaults/tasks/validation.yml index 2861c3a..62ee2d2 100644 --- a/roles/global_defaults/tasks/validation.yml +++ b/roles/global_defaults/tasks/validation.yml @@ -166,6 +166,21 @@ label: "hypervisor.{{ item }}" no_log: true +- name: Validate Proxmox authentication (password or API token) + when: + - system_cfg.type == "virtual" + - hypervisor_type == "proxmox" + ansible.builtin.assert: + that: + - >- + (hypervisor_cfg.password | default('') | string | length > 0) + or (hypervisor_cfg.token_id | default('') | string | length > 0 + and hypervisor_cfg.token_secret | default('') | string | length > 0) + fail_msg: >- + Proxmox requires either hypervisor.password or + hypervisor.token_id + hypervisor.token_secret (API token). + quiet: true + - name: Validate VMware placement (cluster or node required, mutually exclusive) when: - system_cfg.type == "virtual" diff --git a/roles/system_check/tasks/main.yml b/roles/system_check/tasks/main.yml index b55b107..303eb75 100644 --- a/roles/system_check/tasks/main.yml +++ b/roles/system_check/tasks/main.yml @@ -41,7 +41,9 @@ community.proxmox.proxmox_vm_info: api_host: "{{ hypervisor_cfg.url }}" api_user: "{{ hypervisor_cfg.username }}" - api_password: "{{ hypervisor_cfg.password }}" + api_password: "{{ hypervisor_cfg.password | default(omit, true) }}" + api_token_id: "{{ hypervisor_cfg.token_id | default(omit, true) }}" + api_token_secret: "{{ hypervisor_cfg.token_secret | default(omit, true) }}" block: - name: Query Proxmox for existing VM community.proxmox.proxmox_vm_info: diff --git a/roles/virtualization/tasks/delete.yml b/roles/virtualization/tasks/delete.yml index 5a02cc8..0c11ff2 100644 --- a/roles/virtualization/tasks/delete.yml +++ b/roles/virtualization/tasks/delete.yml @@ -20,7 +20,9 @@ community.proxmox.proxmox_kvm: api_host: "{{ hypervisor_cfg.url }}" api_user: "{{ hypervisor_cfg.username }}" - api_password: "{{ hypervisor_cfg.password }}" + api_password: "{{ hypervisor_cfg.password | default(omit, true) }}" + api_token_id: "{{ hypervisor_cfg.token_id | default(omit, true) }}" + api_token_secret: "{{ hypervisor_cfg.token_secret | default(omit, true) }}" node: "{{ hypervisor_cfg.node }}" vmid: "{{ system_cfg.id | default(omit, true) }}" name: "{{ hostname }}"