-
Notifications
You must be signed in to change notification settings - Fork 23
Gather cloud factsv2 #1869
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: stackhpc/2025.1
Are you sure you want to change the base?
Gather cloud factsv2 #1869
Conversation
97bc20e
to
d199d9a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears to have picked up some stray changes from another PR. You might need another rebase
#!usr/bin/env python3 | ||
|
||
from ansible.errors import AnsibleFilterError | ||
# from ansible.plugins.filter.core imprt FilterModule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this required?
# 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 }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd guess it's only defined if it's used, so could you add a check to first ensure kolla_neutron_ml2_mechanism_drivers
is defined, and if it is, check the values it contains?
- 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 }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two things to note here:
- it's probably useful to know this fact for all the hosts, not just localhost, so I'd move it to the "All" section later.
- It's not just checking internet connectivity, it's also resolving the DNS entry for stackhpc.com, and it's ICMP (ping) in particular. Could it be rephrased, so it's more specific about what it's doing? i.e. "pinging stackhpc.com"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to extend it further, you could also add a curl
command in, to check other protocols, ping an IP address (to sidestep DNS), or ping something that isn't stackhpc.com
register: kernel_version | ||
|
||
- name: Get running contianers | ||
ansible.builtin.command: "docker ps --format {% raw %}'{{.Names}}'{% endraw %}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could fail if it runs on a host that doesn't have docker installed, so needs to account for that
ansible.builtin.copy: | ||
content: "{{ cloud_facts | to_nice_json(sort_keys=false) }}" | ||
dest: ~/cloud-facts.json | ||
dest: ~/cloud-facts_2.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets just keep this as cloud-facts.json
self.group_hostvars_by_host | ||
} | ||
|
||
def group_hostvars_by_var(self, hostvars, var, stdout=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add docstrings for these filters?
/gemini review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a new playbook to gather more detailed facts about the cloud environment, supported by a new custom Ansible filter. While the overall direction is good, the new filter plugin in filters.py
contains several issues, including a critical bug that silences errors, leftover debugging comments, and inconsistencies. The get-cloud-facts.yml
playbook also has some potential problems, such as a misleading fact name and unsafe variable access that could lead to playbook failures. I have provided specific comments and code suggestions to address these issues and improve the robustness and clarity of the new code.
result[host] = [] | ||
|
||
except KeyError as e: | ||
AnsibleFilterError(f"Host {host} not found in hostvars.keys(): {e}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The AnsibleFilterError
is instantiated but not raised, which means any KeyError
is silently ignored. This is a critical bug and is likely the cause of the problem mentioned in the comment on line 36. The exception must be raised to signal an error. I've also improved the error message to be more specific.
raise AnsibleFilterError(f"Variable '{var}' not found for host '{host}': {e}")
try: | ||
indiv_host_vars = hostvars[host][var] | ||
if stdout is not None: | ||
indiv_host_vars = indiv_host_vars['stdout_lines'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stdout
parameter is used as a flag to access the hardcoded key 'stdout_lines'
. This is inconsistent with group_hostvars_by_var
, where stdout
is used as the key itself. To improve consistency and flexibility, this function should also use the value of the stdout
parameter as the key. You will need to update the call in get-cloud-facts.yml
to pass 'stdout_lines'
instead of 'stdout'
.
indiv_host_vars = indiv_host_vars[stdout]
tasks: | ||
- name: Check if hugepages enabled | ||
ansible.builtin.set_fact: | ||
hugepages_enabled: "{{ ansible_facts.cmdline }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact hugepages_enabled
is set to the value of ansible_facts.cmdline
, which is a dictionary of all kernel command-line parameters. This is misleading, as the name suggests a boolean value. It would be clearer and less error-prone to set this fact to a boolean indicating whether hugepages are actually configured.
hugepages_enabled: "{{ 'hugepages' in ansible_facts.cmdline }}"
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') }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessing groups['seed'][0]
directly will cause the playbook to fail if the seed
group is empty. It's safer to check for the group's existence before trying to access an element from it.
seed_node_is_vm: "{{ hostvars[groups['seed'][0]]['seed_node_is_vm'] | default('N/A') if groups['seed'] else 'N/A' }}"
@@ -0,0 +1,57 @@ | |||
#!usr/bin/env python3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#!usr/bin/env python3 | ||
|
||
from ansible.errors import AnsibleFilterError | ||
# from ansible.plugins.filter.core imprt FilterModule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if indiv_host_var not in result.keys(): | ||
result[indiv_host_var] = [host] | ||
else: | ||
result[indiv_host_var].append(host) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ansible.builtin.copy: | ||
content: "{{ cloud_facts | to_nice_json(sort_keys=false) }}" | ||
dest: ~/cloud-facts.json | ||
dest: ~/cloud-facts_2.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
d199d9a
to
1c70988
Compare
Adds playbook to gather more advanced facts about a multinode cloud