From 1c70988310d65e3b7d9ed4f78ed2bc8615242de9 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 16 Jul 2025 09:34:54 +0000 Subject: [PATCH] Add v2 of cloud facts playbook --- etc/kayobe/ansible.cfg | 2 + etc/kayobe/ansible/filter_plugins/filters.py | 57 ++++++++++++ etc/kayobe/ansible/get-cloud-facts.yml | 98 +++++++++++++------- 3 files changed, 122 insertions(+), 35 deletions(-) create mode 100644 etc/kayobe/ansible/filter_plugins/filters.py diff --git a/etc/kayobe/ansible.cfg b/etc/kayobe/ansible.cfg index e6c3e9c12d..c4bf7a0dda 100644 --- a/etc/kayobe/ansible.cfg +++ b/etc/kayobe/ansible.cfg @@ -10,6 +10,8 @@ inject_facts_as_vars = False callbacks_enabled = ansible.posix.profile_tasks # Silence warning about invalid characters found in group names force_valid_group_names = ignore +# Default value plus custom filter plugins path +filter_plugins = $ANSIBLE_HOME/plugins/filter:/usr/share/ansible/plugins/filter:$KAYOBE_CONFIG_PATH/ansible/filter_plugins/ [inventory] # Fail when any inventory source cannot be parsed. diff --git a/etc/kayobe/ansible/filter_plugins/filters.py b/etc/kayobe/ansible/filter_plugins/filters.py new file mode 100644 index 0000000000..253ca339ef --- /dev/null +++ b/etc/kayobe/ansible/filter_plugins/filters.py @@ -0,0 +1,57 @@ +#!usr/bin/env python3 + +from ansible.errors import AnsibleFilterError +# from ansible.plugins.filter.core imprt FilterModule + +class FilterModule(object): + def filters(self): + return { + 'group_hostvars_by_var': + self.group_hostvars_by_var, + 'group_hostvars_by_host': + self.group_hostvars_by_host + } + + def group_hostvars_by_var(self, hostvars, var, stdout=None): + result = {} + + for host in hostvars.keys(): + try: + indiv_host_all = hostvars[host] + indiv_host_var = indiv_host_all[var] + if stdout is not None: + indiv_host_var = indiv_host_var[stdout] + if indiv_host_var not in result.keys(): + result[indiv_host_var] = [host] + else: + result[indiv_host_var].append(host) + except KeyError as e: + raise AnsibleFilterError(f"Variable {var} not found in hostvars: {e}") + + return result + + def group_hostvars_by_host(self, hostvars, var, stdout=None, hosts=None): + result = {} + + ### Currently returns blank dict, try block doesn't appear to be working + + if not hosts: + hosts = hostvars.keys() + + for host in hosts: + try: + indiv_host_vars = hostvars[host][var] + if stdout is not None: + indiv_host_vars = indiv_host_vars['stdout_lines'] + if indiv_host_vars: + result[host] = indiv_host_vars + else: + result[host] = [] + + except KeyError as e: + AnsibleFilterError(f"Host {host} not found in hostvars.keys(): {e}") + + + return result + + diff --git a/etc/kayobe/ansible/get-cloud-facts.yml b/etc/kayobe/ansible/get-cloud-facts.yml index e966f8acce..be20100f42 100644 --- a/etc/kayobe/ansible/get-cloud-facts.yml +++ b/etc/kayobe/ansible/get-cloud-facts.yml @@ -1,4 +1,55 @@ --- +- name: Can the control host reach the internet? + hosts: localhost + gather_facts: true + tasks: + - name: Check internet connectivity + ansible.builtin.command: "ping stackhpc.com -c 3" + register: internet_connectivity + timeout: 5 + ignore_errors: true + + - name: Set internet connectivity fact + ansible.builtin.set_fact: + internet_connectivity: "{{ not internet_connectivity.failed }}" + +- name: Get facts for seed node + hosts: seed + gather_facts: true + tasks: + - name: Is there a dedicated seed node? + ansible.builtin.set_fact: + seed_node_is_vm: "{{ ansible_facts.virtualization_role == 'guest' }}" + +- name: Get facts + hosts: all + gather_facts: true + tasks: + - name: Get OS distribution + ansible.builtin.set_fact: + distribution: "{{ ansible_facts.distribution }}" + + - name: Get OS distribution release + ansible.builtin.set_fact: + distribution_release: "{{ ansible_facts.distribution_release }}" + + - name: Get kernel version + ansible.builtin.command: "uname -r" + register: kernel_version + + - name: Get running contianers + ansible.builtin.command: "docker ps --format {% raw %}'{{.Names}}'{% endraw %}" + become: true + register: containers_list + +- name: Get facts for computes + hosts: compute + gather_facts: true + tasks: + - name: Check if hugepages enabled + ansible.builtin.set_fact: + hugepages_enabled: "{{ ansible_facts.cmdline }}" + - name: Gather Cloud Facts hosts: localhost gather_facts: true @@ -6,8 +57,12 @@ - name: Write facts to file vars: cloud_facts: - ansible_control_host_distribution: "{{ ansible_facts.distribution }}" - ansible_control_host_distribution_release: "{{ ansible_facts.distribution_release }}" + internet_connectivity: "{{ internet_connectivity }}" + seed_node_is_vm: "{{ hostvars[groups['seed'][0]]['seed_node_is_vm'] | default('N/A') }}" + distributions: "{{ hostvars | group_hostvars_by_var('distribution') }}" + dist_releases: "{{ hostvars | group_hostvars_by_var('distribution_release') }}" + kernel_versions: "{{ hostvars | group_hostvars_by_var('kernel_version','stdout') }}" + deployed_containers: "{{ hostvars | group_hostvars_by_host('containers_list', 'stdout') }}" openstack_release: "{{ openstack_release }}" openstack_release_name: "{{ openstack_release_codename }}" ansible_control_host_is_vm: "{{ ansible_facts.virtualization_role == 'guest' }}" @@ -22,41 +77,11 @@ ceph_release: "{{ cephadm_ceph_release }}" storage_hyperconverged: "{{ groups['controllers'] | intersect(groups['osds']) | length > 0 | bool }}" wazuh_enabled: "{{ groups['wazuh-agent'] | length > 0 | bool }}" + # ngs_enabled_: "{{ 'genericswitch' in (kolla_neutron_ml2_mechanism_drivers | default([])) | bool }}" + # # ABOVE LEADS TO ERROR: argument of type ''NoneType'' is not iterable. argument of type ''NoneType'' is not iterable' kayobe_managed_switches: "{{ groups['switches'] | length > 0 | bool }}" proxy_configured: "{{ http_proxy | bool or https_proxy | bool }}" bifrost_version: "{{ kolla_bifrost_source_version }}" - barbican_enabled: "{{ kolla_enable_barbican }}" - nova_enabled: "{{ kolla_enable_nova }}" - neutron_enabled: "{{ kolla_enable_neutron }}" - ovs_enabled: "{{ kolla_enable_openvswitch }}" - ovn_enabled: "{{ kolla_enable_ovn }}" - glance_enabled: "{{ kolla_enable_glance }}" - cinder_enabled: "{{ kolla_enable_cinder }}" - keystone_enabled: "{{ kolla_enable_keystone }}" - horizon_enabled: "{{ kolla_enable_horizon }}" - fluentd_enabled: "{{ kolla_enable_fluentd }}" - rabbitmq_enabled: "{{ kolla_enable_rabbitmq }}" - mariadb_enabled: "{{ kolla_enable_mariadb }}" - mariabackup_enabled: "{{ kolla_enable_mariabackup }}" - memcached_enabled: "{{ kolla_enable_memcached }}" - haproxy_enabled: "{{ kolla_enable_haproxy }}" - keepalived_enabled: "{{ kolla_enable_keepalived }}" - octavia_enabled: "{{ kolla_enable_octavia }}" - designate_enabled: "{{ kolla_enable_designate }}" - manila_enabled: "{{ kolla_enable_manila }}" - magnum_enabled: "{{ kolla_enable_magnum }}" - heat_enabled: "{{ kolla_enable_heat }}" - ironic_enabled: "{{ kolla_enable_ironic }}" - skyline_enabled: "{{ kolla_enable_skyline }}" - blazar_enabled: "{{ kolla_enable_blazar }}" - pulp_enabled: "{{ seed_pulp_container_enabled }}" - opensearch_enabled: "{{ kolla_enable_opensearch }}" - opensearch_dashboards_enabled: "{{ kolla_enable_opensearch_dashboards }}" - influxdb_enabled: "{{ kolla_enable_influxdb }}" - grafana_enabled: "{{ kolla_enable_grafana }}" - prometheus_enabled: "{{ kolla_enable_prometheus }}" - cloudkitty_enabled: "{{ kolla_enable_cloudkitty }}" - telegraf_enabled: "{{ kolla_enable_telegraf }}" internal_tls_enabled: "{{ kolla_enable_tls_internal }}" external_tls_enabled: "{{ kolla_enable_tls_external }}" firewalld_enabled_all: >- @@ -82,6 +107,9 @@ stackhpc_package_repos_enabled: "{{ stackhpc_repos_enabled }}" pulp_tls_enabled: "{{ pulp_enable_tls }}" kolla_image_tags: "{{ kolla_image_tags }}" + gpu_passthrough_enabled: "{{ gpu_group_map | length > 0 | bool }}" + vGPU_enabled: "{{ groups['vgpu'] | length > 0 | bool }}" + hugepages_enabled: "{{ hostvars | group_hostvars_by_host('hugepages_enabled', hosts=['compute']) }}" ansible.builtin.copy: content: "{{ cloud_facts | to_nice_json(sort_keys=false) }}" - dest: ~/cloud-facts.json + dest: ~/cloud-facts_2.json