Skip to content

Commit d2ad8ef

Browse files
authored
Merge pull request #689 from stackhpc/upstream/master-2025-03-03
Synchronise master with upstream
2 parents 4cbf2ee + b952deb commit d2ad8ef

File tree

11 files changed

+194
-22
lines changed

11 files changed

+194
-22
lines changed

ansible/gather-facts.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
batch_size: "{{ ansible_play_batch | length }}"
4545
# Use a python list slice to divide the group up.
4646
# Syntax: [<start index>:<end index>:<step size>]
47-
delegate_hosts: "{{ groups['all'][batch_index | int::batch_size | int] }}"
47+
delegate_hosts: "{{ kolla_ansible_delegate_facts_hosts[batch_index | int::batch_size | int] }}"
4848
tasks:
4949
- name: Gather facts
5050
setup:

ansible/group_vars/all.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ kolla_ansible_setup_filter: "{{ omit }}"
3636
# By default, we do not provide a gather subset.
3737
kolla_ansible_setup_gather_subset: "{{ omit }}"
3838

39+
# This variable determines which hosts require facts when using --limit. Facts
40+
# will be gathered using delegation for hosts in this list that are not
41+
# included in the limit.
42+
# By default, this list includes all hosts.
43+
kolla_ansible_delegate_facts_hosts: "{{ groups['all'] }}"
44+
3945
###################
4046
# Kolla options
4147
###################

ansible/roles/prometheus/templates/prometheus.yml.j2

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ scrape_configs:
2424
static_configs:
2525
{% for host in groups['prometheus'] %}
2626
- targets:
27-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ prometheus_port }}'
27+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ prometheus_port }}'
2828
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
2929
labels:
3030
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -36,7 +36,7 @@ scrape_configs:
3636
static_configs:
3737
{% for host in groups['prometheus-node-exporter'] %}
3838
- targets:
39-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_node_exporter_port'] }}'
39+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_node_exporter_port'] }}'
4040
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
4141
labels:
4242
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -56,7 +56,7 @@ scrape_configs:
5656
static_configs:
5757
{% for host in groups['prometheus-mysqld-exporter'] %}
5858
- targets:
59-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_mysqld_exporter_port'] }}'
59+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_mysqld_exporter_port'] }}'
6060
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
6161
labels:
6262
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -69,7 +69,7 @@ scrape_configs:
6969
static_configs:
7070
{% for host in groups['loadbalancer'] %}
7171
- targets:
72-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ prometheus_haproxy_exporter_port }}'
72+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ prometheus_haproxy_exporter_port }}'
7373
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
7474
labels:
7575
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -82,7 +82,7 @@ scrape_configs:
8282
static_configs:
8383
{% for host in groups['rabbitmq'] %}
8484
- targets:
85-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_rabbitmq_exporter_port'] }}'
85+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_rabbitmq_exporter_port'] }}'
8686
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
8787
labels:
8888
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -95,7 +95,7 @@ scrape_configs:
9595
static_configs:
9696
{% for host in groups['prometheus-memcached-exporter'] %}
9797
- targets:
98-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_memcached_exporter_port'] }}'
98+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_memcached_exporter_port'] }}'
9999
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
100100
labels:
101101
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -108,7 +108,7 @@ scrape_configs:
108108
static_configs:
109109
{% for host in groups["prometheus-cadvisor"] %}
110110
- targets:
111-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_cadvisor_port'] }}'
111+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_cadvisor_port'] }}'
112112
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
113113
labels:
114114
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -121,7 +121,7 @@ scrape_configs:
121121
static_configs:
122122
{% for host in groups['fluentd'] %}
123123
- targets:
124-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_fluentd_integration_port'] }}'
124+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_fluentd_integration_port'] }}'
125125
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
126126
labels:
127127
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -159,7 +159,7 @@ scrape_configs:
159159
static_configs:
160160
{% for host in groups["prometheus-elasticsearch-exporter"] %}
161161
- targets:
162-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_elasticsearch_exporter_port'] }}'
162+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_elasticsearch_exporter_port'] }}'
163163
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
164164
labels:
165165
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -204,7 +204,7 @@ scrape_configs:
204204
static_configs:
205205
{% for host in groups["prometheus-libvirt-exporter"] %}
206206
- targets:
207-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_libvirt_exporter_port'] }}'
207+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_libvirt_exporter_port'] }}'
208208
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
209209
labels:
210210
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -220,7 +220,7 @@ scrape_configs:
220220
static_configs:
221221
{% for host in groups["etcd"] %}
222222
- targets:
223-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_etcd_integration_port'] }}'
223+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_etcd_integration_port'] }}'
224224
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
225225
labels:
226226
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -232,7 +232,8 @@ scrape_configs:
232232
- job_name: ironic_prometheus_exporter
233233
static_configs:
234234
{% for host in groups['ironic-conductor'] %}
235-
- targets: ["{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['ironic_prometheus_exporter_port'] }}"]
235+
- targets:
236+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['ironic_prometheus_exporter_port'] }}'
236237
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
237238
labels:
238239
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -245,7 +246,7 @@ scrape_configs:
245246
static_configs:
246247
{% for host in groups['prometheus-alertmanager'] %}
247248
- targets:
248-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_alertmanager_port'] }}'
249+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_alertmanager_port'] }}'
249250
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
250251
labels:
251252
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -257,7 +258,7 @@ scrape_configs:
257258
static_configs:
258259
{% for host in groups["loadbalancer"] %}
259260
- targets:
260-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['proxysql_prometheus_exporter_port'] }}'
261+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['proxysql_prometheus_exporter_port'] }}'
261262
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
262263
labels:
263264
instance: "{{ hostvars[host].prometheus_instance_label }}"
@@ -270,7 +271,7 @@ alerting:
270271
- static_configs:
271272
{% for host in groups["prometheus-alertmanager"] %}
272273
- targets:
273-
- '{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_alertmanager_port'] }}'
274+
- '{{ 'api' | kolla_address(host, override_var='prometheus_target_address') | put_address_in_context('url') }}:{{ hostvars[host]['prometheus_alertmanager_port'] }}'
274275
{% if hostvars[host].prometheus_instance_label | default(false, true) %}
275276
labels:
276277
instance: "{{ hostvars[host].prometheus_instance_label }}"

doc/source/reference/logging-and-monitoring/prometheus-guide.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,16 @@ For example:
243243
labels:
244244
instance: host1
245245
246+
Target address
247+
~~~~~~~~~~~~~~
248+
249+
By default, Prometheus server uses the IP of the API interface of scrape
250+
targets when collecting metrics. This may be overridden by setting
251+
``prometheus_target_address`` as a host variable. The value of this host
252+
variable must be a valid IPv4 or IPv6 address.
253+
254+
Prometheus server is one of the few instances where we need to know IP
255+
addresses of all other hosts in the cloud. Being able to specify these via
256+
``prometheus_target_address`` allows us to operate when facts are not available
257+
for all hosts. This could be due to some hosts being unreachable or having
258+
previously failed.

doc/source/reference/storage/cinder-guide-pure.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ If you wish to use any of these parameters then refer to the
7171
`Service Configuration <https://docs.openstack.org/kolla-ansible/latest/admin/advanced-configuration.html#openstack-service-configuration-in-kolla>`_
7272
documentation for instructions using the INI update strategy.
7373

74-
The use of this backend requires that the ``purestorage`` SDK package is
75-
installed in the ``cinder-volume`` container. To do this follow the steps
74+
The use of this backend requires that an additional Python SDK package is
75+
installed in the ``cinder-volume`` container.
76+
77+
Prior to 2024.2 (Dalmatian) the ``purestorage`` SDK is required. From
78+
2024.2 (Dalmatian) the SDK to install is called ``py-pure-client``.
79+
80+
To install the appropriate SDK follow the steps
7681
outlined in the `kolla image building guide <https://docs.openstack.org/kolla/latest/admin/image-building.html>`_
7782
particularly the ``Package Customisation`` and ``Custom Repos`` sections.

doc/source/user/ansible-tuning.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,44 @@ A max fail percentage may be set for specific services using
160160
161161
kolla_max_fail_percentage: 50
162162
nova_max_fail_percentage: 25
163+
164+
Delegated fact gathering
165+
------------------------
166+
167+
When Kolla Ansible is executed with a ``--limit`` argument, the scope of an
168+
operation is limited to the hosts in the limit. For example:
169+
170+
.. code-block:: console
171+
172+
kolla-ansible deploy --limit control
173+
174+
Due to the nature of configuring clustered software services, there are cases
175+
where we need to know information about other hosts. Most often this is related
176+
to their hostname or network addresses. To make this work, Kolla Ansible
177+
gathers facts for hosts outside of the limit using `delegated fact gathering
178+
<https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_delegation.html#delegating-facts>`__.
179+
180+
By default, Kolla Ansible gathers facts for all hosts. Because delegated facts
181+
are gathered serially in batches by the active hosts, this can take a long time
182+
when there are not many hosts in the limit. If you know that facts are not
183+
required for all hosts, it is possible to reduce the set of hosts eligible for
184+
delegated fact gathering by setting ``kolla_ansible_delegate_facts_hosts`` to a
185+
list of hosts. This may be done permanently in ``globals.yml`` or temporarily
186+
for the duration of a command using the ``-e`` argument.
187+
188+
The exact requirements will depend upon configuration and inventory, but here
189+
are some rules of thumb:
190+
191+
* Facts are typically required for all controllers, regardless of which hosts
192+
are in the limit. This is due to references to RabbitMQ and Memcache
193+
connection strings etc.
194+
* Prometheus server requires facts for all other hosts to generate scrape
195+
configs for node exporter, cAdvisor, etc. Specifically it uses the IP address
196+
of the API interface. This may be avoided by hard-coding
197+
``prometheus_target_address`` in the inventory for each host.
198+
* Configuration of ``/etc/hosts`` during the ``bootstrap-servers`` command
199+
requires facts for all other hosts. Specifically it uses the IP address of
200+
the API interface, and the ``hostname`` and ``nodename`` facts.
201+
* Noting the above exceptions, compute nodes are fairly independent. Other
202+
hosts do not need to know their facts, and they do not need to know other
203+
hosts' facts.

etc/kolla/globals.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
# commented parameters are shown here, To override the default value uncomment
66
# the parameter and change its value.
77

8+
# Dummy variable to allow Ansible to accept this file.
9+
workaround_ansible_issue_8743: yes
10+
811
###################
912
# Ansible options
1013
###################
@@ -21,15 +24,18 @@
2124
# By default, we do not provide a gather subset.
2225
#kolla_ansible_setup_gather_subset: "{{ omit }}"
2326

24-
# Dummy variable to allow Ansible to accept this file.
25-
workaround_ansible_issue_8743: yes
26-
2727
# This variable may be used to set the maximum failure percentage for all
2828
# plays. More fine-grained control is possible via per-service variables, e.g.
2929
# nova_max_fail_percentage. The default behaviour is to set a max fail
3030
# percentage of 100, which is equivalent to not setting it.
3131
#kolla_max_fail_percentage:
3232

33+
# This variable determines which hosts require facts when using --limit. Facts
34+
# will be gathered using delegation for hosts in this list that are not
35+
# included in the limit.
36+
# By default, this list includes all hosts.
37+
#kolla_ansible_delegate_facts_hosts: "{{ groups['all'] }}"
38+
3339
###############
3440
# Kolla options
3541
###############

kolla_ansible/kolla_address.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
import ipaddress
18+
1719
from jinja2.filters import pass_context
1820
from jinja2.runtime import Undefined
1921

@@ -22,7 +24,7 @@
2224

2325

2426
@pass_context
25-
def kolla_address(context, network_name, hostname=None):
27+
def kolla_address(context, network_name, hostname=None, override_var=None):
2628
"""returns IP address on the requested network
2729
2830
The output is affected by '<network_name>_*' variables:
@@ -33,6 +35,8 @@ def kolla_address(context, network_name, hostname=None):
3335
:param network_name: string denoting the name of the network to get IP
3436
address for, e.g. 'api'
3537
:param hostname: to override host which address is retrieved for
38+
:param override_var: optional name of a host variable that can be used
39+
to override the IP address
3640
:returns: string with IP address
3741
"""
3842

@@ -58,6 +62,25 @@ def kolla_address(context, network_name, hostname=None):
5862

5963
del hostvars # remove for clarity (no need for other hosts)
6064

65+
if override_var is not None:
66+
if override_var in host:
67+
try:
68+
# Use ipaddress to test IPv4/6 validity of
69+
# the string returned from override_var and
70+
# return the string-formatted, valid IP address
71+
ip = ipaddress.ip_address(host[override_var])
72+
return format(ip)
73+
except ValueError:
74+
# Catch ValueError from ipaddress and make the
75+
# output more useful for operators
76+
raise FilterError("variable '{override_var}' for "
77+
"host '{hostname}' is set to "
78+
"'{value}', which is not a valid "
79+
"IPv4 or IPv6 address"
80+
.format(override_var=override_var,
81+
hostname=hostname,
82+
value=host[override_var]))
83+
6184
# NOTE(yoctozepto): variable "host" will *not* return Undefined
6285
# same applies to all its children (act like plain dictionary)
6386

kolla_ansible/tests/unit/test_address_filters.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,71 @@ def test_valid_ipv6_config_do_not_ignore_any_vip_address(self):
325325
})
326326
self.assertEqual(addr, kolla_address(context, 'api'))
327327

328+
def test_override_var_valid_ipv4(self):
329+
addr = '192.0.2.1'
330+
override_var = 'my_ip_address'
331+
context = self._make_context({
332+
'inventory_hostname': 'primary',
333+
'hostvars': {
334+
'primary': {
335+
override_var: addr,
336+
},
337+
},
338+
})
339+
self.assertEqual(
340+
addr, kolla_address(context, 'api', override_var=override_var))
341+
342+
def test_override_var_valid_ipv6(self):
343+
addr = 'fd::'
344+
override_var = 'my_ip_address'
345+
context = self._make_context({
346+
'inventory_hostname': 'primary',
347+
'hostvars': {
348+
'primary': {
349+
override_var: addr,
350+
},
351+
},
352+
})
353+
self.assertEqual(
354+
addr, kolla_address(context, 'api', override_var=override_var))
355+
356+
def test_override_var_invalid(self):
357+
addr = 'this-is-an-fqdn.example.com'
358+
override_var = 'my_ip_address'
359+
context = self._make_context({
360+
'inventory_hostname': 'primary',
361+
'hostvars': {
362+
'primary': {
363+
override_var: addr,
364+
},
365+
},
366+
})
367+
self.assertRaises(
368+
FilterError, kolla_address, context, 'api',
369+
override_var=override_var)
370+
371+
def test_override_var_missing(self):
372+
addr = '192.0.2.1'
373+
override_var = 'my_ip_address'
374+
context = self._make_context({
375+
'inventory_hostname': 'primary',
376+
'hostvars': {
377+
'primary': {
378+
'api_address_family': 'ipv4',
379+
'api_interface': 'fake-interface',
380+
'ansible_facts': {
381+
'fake_interface': {
382+
'ipv4': {
383+
'address': addr,
384+
},
385+
},
386+
},
387+
},
388+
},
389+
})
390+
self.assertEqual(
391+
addr, kolla_address(context, 'api', None, override_var))
392+
328393

329394
class TestKollaUrlFilter(unittest.TestCase):
330395

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
Adds a new variable, ``kolla_ansible_delegate_facts_hosts``, that may be
5+
used to control which hosts require facts when using ``--limit``. Its
6+
default value is ``groups['all']``.

0 commit comments

Comments
 (0)