Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions etc/kayobe/ansible.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
87 changes: 87 additions & 0 deletions etc/kayobe/ansible/filter_plugins/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python3

from ansible.errors import AnsibleFilterError

class FilterModule(object):
def filters(self):
return {
'group_hostvars_by_var':
self.group_hostvars_by_var,
'get_hostvars_by_host':
self.get_hostvars_by_host
}

def group_hostvars_by_var(self, hostvars, var, subkey=None):
"""
Returns a dictionary where the keys are values for the
specified var in hostvars, and the values are the hosts
that match that value.

For example, a grouping of hosts by OS release might look like:
distribution_release:
noble:
- node1
- node2
jammy:
- node3
- node4
- node5

Some Ansible commands, such as ansible.builtin.command, return a
dict rather than a single value. So 'subkey' is used for these cases
to access the desired value.
"""
result = {}

for host in hostvars.keys():
try:
indiv_host_var = hostvars[host][var]
if subkey is not None:
indiv_host_var = indiv_host_var[subkey]
result.setdefault(indiv_host_var, []).append(host)
except KeyError as e:
raise AnsibleFilterError(f"Variable {var} not found for host {host} in hostvars: {e}")

return result

def get_hostvars_by_host(self, hostvars, var, subkey=None):
"""
Returns a dictionary where the keys are hosts and the values
are the values for the specified var in hostvars.

For example, the deployed containers by host might look like:
deployed_containers:
node1:
- grafana
- glance
- nova
- prometheus
node2:
- designate
- neutron
- nova

Some Ansible commands, such as ansible.builtin.command, return a
dict rather than a single value. So 'subkey' is used for these cases
to access the desired value.
"""
result = {}
for host in hostvars.keys():
try:
indiv_host_var = hostvars[host][var]
for key in indiv_host_var.keys():
# Check if task to assign value was skipped
if key == "skipped":
result[host] = "No data"
continue
if subkey is not None:
indiv_host_var = indiv_host_var[subkey]
if indiv_host_var:
result[host] = indiv_host_var
else:
result[host] = []

except KeyError as e:
raise AnsibleFilterError(f"Variable {var} not found for host {host} in hostvars: {e}")

return result
105 changes: 71 additions & 34 deletions etc/kayobe/ansible/get-cloud-facts.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,78 @@
---
- name: Get facts for control host
hosts: localhost
gather_facts: true
tasks:
- name: Check if ngs enabled
ansible.builtin.set_fact:
ngs_enabled: >-
{{ 'genericswitch' in kolla_neutron_ml2_mechanism_drivers | default(false) }}
when: kolla_neutron_ml2_mechanism_drivers

- 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: Pinging stackhpc.com to check internet connectivity
ansible.builtin.command: "ping stackhpc.com -c 3"
register: successful_ping
timeout: 5
ignore_errors: true

- name: Set internet connectivity fact
ansible.builtin.set_fact:
internet_connectivity: "{{ not successful_ping.failed }}"
- 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: Check if docker is installed
ansible.builtin.command: "which docker"
register: docker_check
failed_when: docker_check.rc not in [0]
ignore_errors: true

- name: Get running contianers
ansible.builtin.command: "docker ps --format {% raw %}'{{.Names}}'{% endraw %}"
become: true
register: containers_list
when: not docker_check.failed

- name: Check if hugepages enabled
ansible.builtin.set_fact:
hugepages_enabled: "{{ 'hugepages' in ansible_facts.cmdline }}"

- name: Gather Cloud Facts
hosts: localhost
gather_facts: true
tasks:
- 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: "{{ hostvars | group_hostvars_by_var('internet_connectivity') }}"
seed_node_is_vm: "{{ hostvars[groups['seed'][0]]['seed_node_is_vm'] | default('N/A') if groups ['seed'] else '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 | get_hostvars_by_host('containers_list', 'stdout_lines') | default({}) }}"
openstack_release: "{{ openstack_release }}"
openstack_release_name: "{{ openstack_release_codename }}"
ansible_control_host_is_vm: "{{ ansible_facts.virtualization_role == 'guest' }}"
Expand All @@ -22,41 +87,10 @@
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: "{{ ngs_enabled | default(false) }}"
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: >-
Expand All @@ -82,6 +116,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_var('hugepages_enabled') }}"
ansible.builtin.copy:
content: "{{ cloud_facts | to_nice_json(sort_keys=false) }}"
dest: ~/cloud-facts.json