diff --git a/README.md b/README.md index 393054f..c85c2a6 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,8 @@ This code package is currently undergoing active and intensive development. It m By using this package, you acknowledge and understand the potential risks and agree that you are using it at your own discretion and risk. Should any issues or damage arise from its use, the responsibility rests solely with the user. We strongly advise regularly backing up any data or systems that interact with this package and frequently checking for updates. -Your feedback and reports on any bugs or inconsistencies are greatly appreciated, but please proceed with caution. \ No newline at end of file +Your feedback and reports on any bugs or inconsistencies are greatly appreciated, but please proceed with caution. + +#TODO: Storage role +#TODO: Storage-ZFS tasks (Params: /sys/module/zfs/parameters/zfs_arc_max, Modprobe: /etc/modprobe.d/zfs.conf) +#TODO: Proxmox role -> Sysctl VM swappiness \ No newline at end of file diff --git a/roles/auth/vars/main.yml b/roles/auth/vars/main.yml index e22c0cd..53bb0e0 100644 --- a/roles/auth/vars/main.yml +++ b/roles/auth/vars/main.yml @@ -1,5 +1,5 @@ --- -auth__all: "{{ auth__host + auth__group + auth__default + (auth__external | default([])) }}" +auth__all: "{{ auth__host + auth__group + auth__default }}" __auth__config: authorized_keys: diff --git a/roles/network/vars/main.yml b/roles/network/vars/main.yml index 56ca2dc..ebf0de7 100644 --- a/roles/network/vars/main.yml +++ b/roles/network/vars/main.yml @@ -39,9 +39,12 @@ __network__interfaces_configs: >- {%- endfor -%} {{ __configs_prepared }} +# Sort interfaces by name to avoid unneccessary changes network__interfaces_all: "{{ __network__interfaces_configs | community.general.lists_mergeby('name', recursive=true, list_merge='prepend') | - aybarsm.helper.unique_recursive(attributes='name', recurse='inet') | aybarsm.helper.unique_recursive(attributes='name', recurse='inet6') }}" + aybarsm.helper.unique_recursive(attributes='name', recurse='inet') | + aybarsm.helper.unique_recursive(attributes='name', recurse='inet6') | + sort(attribute='name') }}" ##### BEGIN: network sysctl vars network__sysctl_all: "{{ (network__host + network__group + network__default) | diff --git a/roles/package_manager/defaults/main.yml b/roles/package_manager/defaults/main.yml index 7cacfa7..fda9446 100644 --- a/roles/package_manager/defaults/main.yml +++ b/roles/package_manager/defaults/main.yml @@ -1,6 +1,10 @@ --- package_manager__role_enabled: false +package_manager__manage_repo_keys: false +package_manager__manage_repos: false +package_manager__manage_packages: false + # Package Manager Strategy: # Change the package manager strategy to use for the system i.e. ansible.builtin.apt vs ansible.builtin.package # Available options: specific, common diff --git a/roles/package_manager/tasks/deb_packages.yml b/roles/package_manager/tasks/deb_packages.yml index d5a38bb..8276e75 100644 --- a/roles/package_manager/tasks/deb_packages.yml +++ b/roles/package_manager/tasks/deb_packages.yml @@ -29,5 +29,6 @@ loop: "{{ package_manager__packages_all }}" register: package_manager__packages_deb_apply when: + - package_manager__manage_packages | default(false) | bool - package_manager__packages_all | type_debug == 'list' - package_manager__packages_all | length > 0 diff --git a/roles/package_manager/tasks/deb_repo_keys.yml b/roles/package_manager/tasks/deb_repo_keys.yml new file mode 100644 index 0000000..94934b5 --- /dev/null +++ b/roles/package_manager/tasks/deb_repo_keys.yml @@ -0,0 +1,15 @@ +--- +- name: Manage DEB repository keys via APT + become: true + ansible.builtin.apt_key: + state: "{{ item.state | default(omit) }}" + data: "{{ item.data | default(omit) }}" + file: "{{ item.file | default(omit) }}" + keyring: "{{ item.keyring | default(omit) }}" + url: "{{ item.url | default(omit) }}" + validate_certs: "{{ item.validate_certs | default(omit) | bool }}" + loop: "{{ package_manager__repo_keys_all }}" + register: package_manager__repo_keys_deb_apply + when: + - package_manager__repo_keys_all | type_debug == 'list' + - package_manager__repo_keys_all | length > 0 diff --git a/roles/package_manager/tasks/deb_repo.yml b/roles/package_manager/tasks/deb_repos.yml similarity index 60% rename from roles/package_manager/tasks/deb_repo.yml rename to roles/package_manager/tasks/deb_repos.yml index 751d6db..3c4e737 100644 --- a/roles/package_manager/tasks/deb_repo.yml +++ b/roles/package_manager/tasks/deb_repos.yml @@ -1,19 +1,4 @@ --- -- name: Manage DEB repository keys via APT - become: true - ansible.builtin.apt_key: - state: "{{ item.state | default(omit) }}" - data: "{{ item.data | default(omit) }}" - file: "{{ item.file | default(omit) }}" - keyring: "{{ item.keyring | default(omit) }}" - url: "{{ item.url | default(omit) }}" - validate_certs: "{{ item.validate_certs | default(omit) | bool }}" - loop: "{{ package_manager__repo_keys_all }}" - register: package_manager__repo_keys_deb_apply - when: - - package_manager__repo_keys_all | type_debug == 'list' - - package_manager__repo_keys_all | length > 0 - - name: Manage DEB repositories via APT become: true ansible.builtin.apt_repository: diff --git a/roles/package_manager/tasks/main.yml b/roles/package_manager/tasks/main.yml index 546edf3..579b164 100644 --- a/roles/package_manager/tasks/main.yml +++ b/roles/package_manager/tasks/main.yml @@ -9,11 +9,20 @@ - name: Load common variables structured on OS related variables ansible.builtin.include_vars: common.yml -- name: Include DEB repository key and repository tasks (APT) +- name: Include DEB repository key tasks (APT) ansible.builtin.include_tasks: - file: deb_repo.yml + file: deb_repo_keys.yml when: - package_manager__role_enabled | default(false) | bool + - package_manager__manage_repo_keys | default(false) | bool + - ansible_os_family | default('') | lower == 'debian' + +- name: Include DEB repository tasks (APT) + ansible.builtin.include_tasks: + file: deb_repos.yml + when: + - package_manager__role_enabled | default(false) | bool + - package_manager__manage_repos | default(false) | bool - ansible_os_family | default('') | lower == 'debian' # TODO: Implement RPM repository tasks @@ -24,22 +33,12 @@ # - package_manager__role_enabled | default(false) | bool # - ansible_os_family | default('') | lower == 'redhat' -- name: Include upgrade tasks - ansible.builtin.include_tasks: - file: upgrade.yml - when: - - package_manager__role_enabled | default(false) | bool - - __package_manager__upgrade_execute.decision - vars: - ansible_callback_diy_runner_on_skipped_msg: | - skipping: [{{ inventory_hostname }}] - msg: {{ __package_manager__upgrade_execute.reason }} - - name: Include DEB package tasks (APT) ansible.builtin.include_tasks: file: deb_packages.yml when: - package_manager__role_enabled | default(false) | bool + - package_manager__manage_packages | default(false) | bool - package_manager__package_strategy | lower == 'specific' - ansible_os_family | default('') | lower == 'debian' @@ -48,12 +47,29 @@ file: rpm_packages.yml when: - package_manager__role_enabled | default(false) | bool + - package_manager__manage_packages | default(false) | bool - package_manager__package_strategy | lower == 'specific' - ansible_os_family | default('') | lower == 'redhat' +- name: Include upgrade tasks + ansible.builtin.include_tasks: + file: upgrade.yml + when: + - package_manager__role_enabled | default(false) | bool + - __package_manager__upgrade_execute.decision + +- name: Inform when upgrade skipped + ansible.builtin.debug: + msg: "{{ __package_manager__upgrade_execute.reason }}" + when: + - package_manager__role_enabled | default(false) | bool + - not __package_manager__upgrade_execute.decision + delegate_to: localhost + - name: Include common package manager tasks ansible.builtin.include_tasks: file: common_packages.yml when: - package_manager__role_enabled | default(false) | bool + - package_manager__manage_packages | default(false) | bool - package_manager__package_strategy | lower == 'common' diff --git a/roles/package_manager/vars/common-pre.yml b/roles/package_manager/vars/common-pre.yml new file mode 100644 index 0000000..1defb99 --- /dev/null +++ b/roles/package_manager/vars/common-pre.yml @@ -0,0 +1,51 @@ +package_manager__repo_keys_all: "{{ package_manager__all | + selectattr('type', 'defined') | selectattr('type', 'equalto', 'repo_key') | + default([]) }}" + +package_manager__repos_all: "{{ package_manager__all | + selectattr('type', 'defined') | selectattr('type', 'equalto', 'repo') | + default([]) }}" + +package_manager__repo_lists_all: "{{ package_manager__all | + selectattr('type', 'defined') | selectattr('type', 'equalto', 'repo_list') | + selectattr('dest', 'defined') | selectattr('src', 'defined') | + selectattr('source_module', 'defined') | selectattr('source_module', 'in', ['copy', 'template']) | + unique(attribute='dest') | default([]) }}" + +package_manager__packages_all: "{{ package_manager__all | + selectattr('type', 'defined') | selectattr('type', 'equalto', 'package') | + default([]) }}" + +__package_manager__clean_upgrade_modes: "{{ ['clean_'] | product(__package_manager__upgrade_modes) | map('join') }}" + +__package_manager__repo_list_defaults: "{{ package_manager__repo_lists_all | selectattr('category', 'defined') | selectattr('category', 'equalto', 'default') | default([]) }}" +__package_manager__repo_list_defaults_copy: "{{ __package_manager__repo_list_defaults | selectattr('source_module', 'equalto', 'copy') | default([]) }}" +__package_manager__repo_list_defaults_template: "{{ __package_manager__repo_list_defaults | selectattr('source_module', 'equalto', 'template') | default([]) }}" + +__package_manager__upgrade_clean: "{{ package_manager__upgrade_mode in __package_manager__clean_upgrade_modes }}" +__package_manager__upgrade_mode: "{{ package_manager__upgrade_mode | regex_replace('clean_', '') }}" +__package_manager__upgrade_clean_eligible: "{{ __package_manager__upgrade_clean and __package_manager__repo_list_defaults | length > 0 }}" + +__package_manager__upgrade_once: "{{ package_manager__upgrade_strategy == 'once' }}" +__package_manager__upgrade_always: "{{ package_manager__upgrade_strategy == 'always' }}" +__package_manager__upgrade_never: "{{ package_manager__upgrade_strategy == 'never' }}" +__package_manager__upgrade_execute: >- + {%- set exec_upgrade = {'decision': true, 'reason': ''} -%} + {%- if not package_manager__role_enabled -%} + {%- set exec_upgrade = {'decision': false, 'reason': 'Upgrade requires aybarsm.linux.package_manager role enabled. (package_manager__role_enabled: true)'} -%} + {%- elif __package_manager__upgrade_never -%} + {%- set exec_upgrade = {'decision': false, 'reason': 'Upgrade strategy is set to never.'} -%} + {%- elif __package_manager__upgrade_clean and not __package_manager__upgrade_clean_eligible -%} + {%- set exec_upgrade = {'decision': false, 'reason': 'Upgrade strategy is set to clean, but no default repo list configuration found.'} -%} + {%- elif __package_manager__upgrade_once -%} + {%- if ansible__local_fact_name is undefined -%} + {%- set exec_upgrade = {'decision': false, 'reason': 'Upgrade strategy once requires aybarsm.linux.ansible role imported.'} -%} + {%- elif ansible__role_enabled is undefined or not ansible__role_enabled -%} + {%- set exec_upgrade = {'decision': false, 'reason': 'Upgrade strategy once requires aybarsm.linux.ansible role enabled. (ansible__role_enabled: true)'} -%} + {%- elif not ansible__manage_local_facts -%} + {%- set exec_upgrade = {'decision': false, 'reason': 'Upgrade strategy once requires aybarsm.linux.ansible role local fact management enabled. (ansible__manage_local_facts: true)'} -%} + {%- elif ansible_local[ansible__local_fact_name].package_manager.upgrade is defined -%} + {%- set exec_upgrade = {'decision': false, 'reason': 'Host already upgraded.'} -%} + {%- endif -%} + {%- endif -%} + {{ exec_upgrade }} diff --git a/roles/proxmox/defaults/main.yml b/roles/proxmox/defaults/main.yml index b609544..f055425 100644 --- a/roles/proxmox/defaults/main.yml +++ b/roles/proxmox/defaults/main.yml @@ -1,34 +1,53 @@ proxmox__role_enabled: false -proxmox__manage_cluster: false -proxmox__manage_cluster_hosts: false -proxmox__manage_cluster_ssh_config: false +# TODO: Implement managing the purpose package setup for repos and package versioning. +# proxmox__manage_repo_keys: false +# proxmox__manage_repos: false +# proxmox__manage_packages: false +# proxmox__manage_grub: false +# proxmox__manage_hostname: false +# proxmox__manage_hosts: false +# proxmox__manage_sshd_config: false +# proxmox__manage_ssh_config: false +# proxmox__manage_cluster: false # Cluster configuration # For target inventory specs, consult https://docs.ansible.com/ansible/latest/inventory_guide/intro_patterns.html for more information +# If init node not provided, the init node will be designated as the first node regarding ascending sorted of inventory_hostname # proxmox__clusters: # - name: 'pve-london01' # target: 'proxmox:&london' # - name: 'pve-atlanta01' # target: 'proxmox:&atlanta' +# init: 'pve01-atlanta01' proxmox__clusters: [] -# Ip addresses for the cluster links for the host (will be automatically prioritized regarding the posisiton in the list) +# Ip addresses for the cluster links for the host proxmox__cluster_links: [] -# If set to any integer higher than 0, cluster links will be prioritized automatically regarding the step. -# i.e. proxmox__cluster_links: ['10.0.0.2', 'fd00::2'] and proxmox__cluster_links_auto_priority_step: 10 will be prioritized as 10.0.0.2 = 20 and fd00::2 = 10 -proxmox__cluster_links_auto_priority_step: 0 +# If set as a dict, with integer keys, keys will be used as link priority. Consult: https://pve.proxmox.com/pve-docs/pvecm.1.html +# i.e. proxmox__cluster_links: {'10': '10.0.0.2', '20': 'fd00::2'} proxmox__ssh_port: 22 proxmox__repo_url_enterprise: https://enterprise.proxmox.com/debian proxmox__repo_url_no_subscription: http://download.proxmox.com/debian +proxmox__repo_keys: + bookworm: + url: https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg + keyring: /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg + bullseye: + url: https://enterprise.proxmox.com/debian/proxmox-release-bullseye.gpg + keyring: /etc/apt/trusted.gpg.d/proxmox-release-bullseye.gpg -proxmox__purpose_names: ['pve', 'pbs', 'pmg', 'ceph_pacific', 'ceph_quincy', 'ceph_reef'] +proxmox__purpose_names: ['pve', 'pbs', 'pmg', 'ceph_pacific', 'ceph_quincy', 'ceph_reef', 'zfs'] proxmox__purpose_types: ['enterprise', 'no-subscription'] proxmox__purpose_packages: - pve: pve-manager - pbs: proxmox-backup-server - pmg: proxmox-mailgateway + pve: ['pve-manager'] + pbs: ['proxmox-backup-server'] + pmg: ['proxmox-mailgateway'] + ceph_pacific: ['ceph', 'ceph-common', 'ceph-mds', 'ceph-fuse'] + ceph_quincy: ['ceph', 'ceph-common', 'ceph-mds', 'ceph-fuse'] + ceph_reef: ['ceph', 'ceph-common', 'ceph-mds', 'ceph-fuse'] + zfs: ['zfsutils-linux', 'zfs-initramfs', 'zfs-zed'] # If enabled, the role will manage the purpose package setup for repos and package versioning. proxmox__manage_purpose_package_setup: true diff --git a/roles/proxmox/tasks/main.yml b/roles/proxmox/tasks/main.yml index 8e010ac..d306bb2 100644 --- a/roles/proxmox/tasks/main.yml +++ b/roles/proxmox/tasks/main.yml @@ -7,6 +7,34 @@ ansible.builtin.include_tasks: file: set_facts.yml +- name: Import aybarsm package_manager role + ansible.builtin.import_role: + name: aybarsm.linux.package_manager + when: + - proxmox__role_enabled + - __proxmox__use_package_manager + +- name: Import aybarsm grub role + ansible.builtin.import_role: + name: aybarsm.linux.grub + when: + - proxmox__role_enabled + - proxmox__manage_grub + +# - name: Import aybarsm network role +# ansible.builtin.import_role: +# name: aybarsm.linux.network +# when: proxmox__role_enabled + +# - name: Reboot node and wait if upgraded, grub or network-systemd changed +# ansible.builtin.reboot: +# test_command: "uptime" +# vars: +# is_upgraded: "{{ package_manager__upgrade_deb is defined and package_manager__upgrade_deb is changed }}" +# is_grub: "{{ grub__deploy is defined and grub__deploy is changed }}" +# is_systemd: "{{ network__systemd_deploy is defined and network__systemd_deploy is changed }}" +# when: is_upgraded or is_grub or is_systemd + # - name: Proxmox Query # become: true # proxmox_query: diff --git a/roles/proxmox/tasks/network.yml b/roles/proxmox/tasks/network.yml new file mode 100644 index 0000000..7caf0a1 --- /dev/null +++ b/roles/proxmox/tasks/network.yml @@ -0,0 +1,15 @@ +--- +- name: Import aybarsm package_manager role + ansible.builtin.include_role: + name: aybarsm.linux.package_manager + vars: + package_manager__role_enabled: true + package_manager__manage_repo_keys: "{{ proxmox__manage_repo_keys }}" + package_manager__manage_repos: "{{ proxmox__manage_repos }}" + package_manager__manage_packages: "{{ proxmox__manage_packages }}" + node_repo_keys: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'repo_key') if proxmox__manage_repo_keys else [] }}" + node_repos: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'repo') if proxmox__manage_repos else [] }}" + node_packages: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'package') if proxmox__manage_packages else [] }}" + package_manager__host: "{{ node_repo_keys + node_repos + node_packages + (package_manager__host | default([])) }}" + + when: proxmox__role_enabled \ No newline at end of file diff --git a/roles/proxmox/tasks/package_manager.yml b/roles/proxmox/tasks/package_manager.yml new file mode 100644 index 0000000..12db457 --- /dev/null +++ b/roles/proxmox/tasks/package_manager.yml @@ -0,0 +1,14 @@ +--- +- name: Include aybarsm package_manager role + ansible.builtin.include_role: + name: aybarsm.linux.package_manager + vars: + package_manager__role_enabled: true + package_manager__package_strategy: specific + package_manager__manage_repo_keys: "{{ proxmox__manage_repo_keys }}" + package_manager__manage_repos: "{{ proxmox__manage_repos }}" + package_manager__manage_packages: "{{ proxmox__manage_packages }}" + node_repo_keys: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'repo_key') if proxmox__manage_repo_keys else [] }}" + node_repos: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'repo') if proxmox__manage_repos else [] }}" + node_packages: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'package') if proxmox__manage_packages else [] }}" + package_manager__host: "{{ node_repo_keys + node_repos + node_packages + (package_manager__host | default([])) }}" \ No newline at end of file diff --git a/roles/proxmox/tasks/set_facts.yml b/roles/proxmox/tasks/set_facts.yml index 7c6c9b2..f120994 100644 --- a/roles/proxmox/tasks/set_facts.yml +++ b/roles/proxmox/tasks/set_facts.yml @@ -1,12 +1,14 @@ --- - name: Set fact for main proxmox cluster configuration ansible.builtin.set_fact: - __proxmox__clusters: "{{ __proxmox__clusters | default([]) + cluster_config }}" + __proxmox__cluster_configs: "{{ (__proxmox__cluster_configs | default([]) + cluster_config) | sort(attribute='name,host') }}" vars: - cluster_inventory: "{{ lookup('ansible.builtin.inventory_hostnames', item) | split(',') }}" + cluster_inventory: "{{ lookup('ansible.builtin.inventory_hostnames', item.target) | split(',') }}" cluster_query: "{{ __proxmox__cluster_query | replace('__MEMBERS__', ('[`' + (cluster_inventory | join('`,`')) + '`]')) }}" - cluster_config: "{{ dict(hostvars) | community.general.json_query(cluster_query) | map('combine', proxmox__clusters[config_index]) }}" - loop: "{{ proxmox__clusters | map(attribute='target') }}" + cluster_node_config: "{{ dict(hostvars) | community.general.json_query(cluster_query) | sort(attribute='host') }}" + cluster_default_init: "{{ cluster_node_config | map(attribute='host') | first }}" + cluster_config: "{{ cluster_node_config | map('combine', ({'init': cluster_default_init} | combine(item))) }}" + loop: "{{ proxmox__clusters }}" loop_control: index_var: config_index delegate_to: localhost @@ -18,9 +20,50 @@ - name: Set facts for proxmox cluster configuration ansible.builtin.set_fact: - __proxmox__clusters: "{{ __proxmox__clusters | default([]) + cluster_config }}" + __proxmox__cluster: "{{ {'members': cluster_members} | combine(cluster_play) if cluster_play else None }}" + __proxmox__cluster_eligible: "{{ cluster_eligible }}" + + __proxmox__use_package_manager: "{{ use_package_manager }}" + package_manager__role_enabled: "{{ use_package_manager if use_package_manager else omit }}" + package_manager__host: "{{ node_repo_keys + node_repos + node_packages + (package_manager__host | default([])) if use_package_manager else omit }}" + + grub__role_enabled: "{{ proxmox__manage_grub if proxmox__manage_grub else omit }}" + grub__change_strategy: "{{ __proxmox__grub_change_strategy if proxmox__manage_grub else omit }}" + + network__hosts_auto_discovery: False + network__hostname: "{{ cluster_play.fqdn | default(cluster_play.hostname) if cluster_play and proxmox__manage_hostname else omit }}" + network__host: "{{ node_hosts + (network__host | default([])) }}" + auth__host: "{{ [(node_auth_default | combine(node_auth))] + (auth__host | default([])) if cluster_eligible else (auth__host | default([])) }}" vars: - __proxmox__play: "{{ __proxmox__clusters | selectattr('host', 'equalto', inventory_hostname) | default(None) | first }}" + cluster_play: "{{ __proxmox__cluster_configs | + selectattr('host', 'eq', inventory_hostname) | first | default(None) }}" + cluster_members: "{{ __proxmox__cluster_configs | + selectattr('name', 'eq', cluster_play.name) | + rejectattr('host', 'eq', inventory_hostname) | + aybarsm.helper.only_with(['host', 'fqdn', 'hostname', 'links']) if cluster_play else None }}" + cluster_required: "{{ [inventory_hostname] + (cluster_members | map(attribute='host') | list) if cluster_play else None }}" + cluster_eligible: "{{ ansible_play_batch | intersect(cluster_required) | length == cluster_required | length if cluster_play else False }}" + + use_package_manager: "{{ proxmox__manage_repo_keys or proxmox__manage_repos or proxmox__manage_packages }}" + use_grub: "{{ proxmox__manage_grub }}" + + node_repo_keys: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'repo_key') if proxmox__manage_repo_keys else [] }}" + node_repos: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'repo') if proxmox__manage_repos else [] }}" + node_packages: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'package') if proxmox__manage_packages else [] }}" + + cluster_hosts: "{{ [cluster_play | aybarsm.helper.only_with(['hostname', 'fqdn', 'links'])] + cluster_members if cluster_play else None }}" + node_hosts: "{{ { + 'ip': (cluster_hosts | map(attribute='links') | map('first')), + 'hostname': (cluster_hosts | map(attribute='hostname')), + 'fqdn': (cluster_hosts | map(attribute='fqdn')) + } | aybarsm.helper.to_list_of_dicts({'type': 'host'}) if cluster_play and proxmox__manage_hosts else [] }}" + node_auth_all: "{{ (auth__host | default([])) + (auth__group | default([])) + (auth__default | default([])) }}" + node_auth_default: "{{ node_auth_all | aybarsm.helper.selectattr(__proxmox__auth_selectattr) | first if cluster_play else {} }}" + node_auth: + type: user + name: root + generate_ssh_key: true + ssh_key_comment: "{{ node_auth_default.ssh_key_comment | default('root@' + inventory_hostname_short) }}" + distribute_ssh_key: "{{ cluster_required | difference([inventory_hostname]) if cluster_play else [] }}" when: - - __proxmox__clusters | length > 0 - - __proxmox__play is not None \ No newline at end of file + - __proxmox__cluster_configs | length > 0 diff --git a/roles/proxmox/vars/main.yml b/roles/proxmox/vars/main.yml index 393db39..239bfcb 100644 --- a/roles/proxmox/vars/main.yml +++ b/roles/proxmox/vars/main.yml @@ -2,48 +2,58 @@ # proxmox__host > proxmox__group > proxmox__default proxmox__all: "{{ proxmox__default | combine(proxmox__group, proxmox__host, recursive=true, list_merge='replace') }}" +__proxmox__grub_change_strategy: + module: command + cmd: 'proxmox-boot-tool refresh' + immediate: true + __proxmox__purpose_packages: >- + {%- set proxmox_repo_keys = [proxmox__repo_keys[ansible_distribution_release] | combine({'type': 'repo_key', 'state': 'present'})] -%} {%- set proxmox_repos = [] -%} {%- set proxmox_packages = [] -%} - {%- set purpose_packages = [] -%} + {%- set purpose_packages_done = [] -%} {%- if proxmox__manage_purpose_package_setup is defined and proxmox__manage_purpose_package_setup and proxmox__all.purposes is defined -%} {%- for purpose in proxmox__purpose_names -%} {%- for purpose_type in proxmox__purpose_types -%} {%- set host_config = proxmox__all.purposes[purpose] if purpose in proxmox__all.purposes else none -%} {%- set is_host_purpose = true if host_config else false -%} {%- set is_host_purpose_type = true if host_config and host_config.type is defined and host_config.type == purpose_type else false -%} - {%- set host_purpose_version = host_config.version if host_config and host_config.version is defined else none -%} + {%- set purpose_package_version = host_config.version if host_config and host_config.version is defined else none -%} {%- set purpose_repo_state = 'present' if is_host_purpose and is_host_purpose_type else 'absent' -%} {%- set purpose_repo = proxmox__repo_url_enterprise if purpose_type == 'enterprise' else proxmox__repo_url_no_subscription -%} {%- if purpose in ['pve', 'pbs', 'pmg'] -%} {%- set proxmox_repos = proxmox_repos.append({ 'type': 'repo', 'repo': 'deb ' + purpose_repo + '/' + purpose + ' ' + ansible_distribution_release + ' ' + purpose + '-' + purpose_type, - 'filename': purpose + '-' + purpose_type, - 'state': purpose_repo_state - }) -%} - {%- if host_purpose_version and proxmox__purpose_packages[purpose] is defined and not purpose in purpose_packages -%} - {%- set purpose_packages = purpose_packages.append(purpose) -%} - {%- set package_name = proxmox__purpose_packages[purpose] if host_purpose_version == 'latest' else proxmox__purpose_packages[purpose] + '=' + host_purpose_version -%} - {%- set package_state = 'latest' if host_purpose_version == 'latest' else 'present' -%} - {%- set proxmox_packages = proxmox_packages.append({ - 'type': 'package', - 'name': package_name, - 'state': package_state + 'filename': purpose + '-' + (purpose_type | replace('_', '-')), + 'state': purpose_repo_state, + 'update_cache': true }) -%} - {%- endif -%} {%- elif purpose.startswith('ceph-') or purpose.startswith('ceph_') -%} {%- set proxmox_repos = proxmox_repos.append({ 'type': 'repo', 'repo': 'deb ' + purpose_repo + '/' + (purpose | replace('_', '-')) + ' ' + ansible_distribution_release + ' ' + purpose_type, 'filename': 'ceph', - 'state': purpose_repo_state + 'state': purpose_repo_state, + 'update_cache': true }) -%} {%- endif -%} + {%- if is_host_purpose and proxmox__purpose_packages[purpose] is defined and not purpose in purpose_packages_done -%} + {%- set purpose_packages_done = purpose_packages_done.append(purpose) -%} + {%- for purpose_package in proxmox__purpose_packages[purpose] -%} + {%- set package_name = purpose_package + '=' + purpose_package_version if purpose_package_version else purpose_package -%} + {%- set proxmox_packages = proxmox_packages.append({ + 'type': 'package', + 'name': package_name, + 'state': 'present', + 'update_cache': true + }) -%} + {%- endfor -%} + {%- endif -%} {%- endfor -%} {%- endfor -%} {%- endif -%} - {{ proxmox_repos + proxmox_packages }} + {{ proxmox_repo_keys + proxmox_repos + proxmox_packages }} __proxmox_cluster_links: >- {%- set proxmox_links = [] -%} @@ -51,4 +61,11 @@ __proxmox_cluster_links: >- {%- endif -%} __proxmox__cluster_query: '*.{host: inventory_hostname, fqdn: ansible_facts.fqdn, hostname: ansible_facts.hostname, links: proxmox__cluster_links} | - [?not_null(links) && contains(__MEMBERS__, host)]' \ No newline at end of file + [?not_null(links) && contains(__MEMBERS__, host)]' + +__proxmox__auth_selectattr: + - when: + - ['type', 'defined'] + - ['type', 'equalto', 'user'] + - ['name', 'defined'] + - ['name', 'equalto', 'root'] \ No newline at end of file