Add molecule testing to the role

Depends-On: https://review.opendev.org/c/openstack/openstack-ansible/+/939824
Change-Id: Iba67d3e321c6ebc256bb63de27ce61c26db10ab0
This commit is contained in:
Dmitriy Rabotyagov
2025-01-22 19:13:22 +01:00
parent b09ac39cbc
commit 45f6078fe5
22 changed files with 196 additions and 434 deletions

46
Vagrantfile vendored
View File

@ -1,46 +0,0 @@
# Note:
# This file is maintained in the openstack-ansible-tests repository.
# https://opendev.org/openstack/openstack-ansible-tests/src/Vagrantfile
#
# If you need to perform any change on it, you should modify the central file,
# then, an OpenStack CI job will propagate your changes to every OSA repository
# since every repo uses the same Vagrantfile
# Verify whether required plugins are installed.
required_plugins = [ "vagrant-disksize" ]
required_plugins.each do |plugin|
if not Vagrant.has_plugin?(plugin)
raise "The vagrant plugin #{plugin} is required. Please run `vagrant plugin install #{plugin}`"
end
end
Vagrant.configure(2) do |config|
config.vm.provider "virtualbox" do |v|
v.memory = 6144
v.cpus = 2
# https://github.com/hashicorp/vagrant/issues/9524
v.customize ["modifyvm", :id, "--audio", "none"]
end
config.vm.synced_folder ".", "/vagrant", type: "rsync"
config.vm.provision "shell",
privileged: false,
inline: <<-SHELL
cd /vagrant
./run_tests.sh
SHELL
config.vm.define "centos8" do |centos8|
centos8.vm.box = "centos/8"
end
config.vm.define "debian10" do |debian10|
debian10.vm.box = "debian/buster64"
end
config.vm.define "ubuntu2004" do |focal|
focal.disksize.size = "40GB"
focal.vm.box = "ubuntu/focal64"
end
end

View File

@ -1,47 +0,0 @@
# This file facilitates OpenStack-CI package installation
# before the execution of any tests.
#
# See the following for details:
# - https://docs.openstack.org/infra/bindep/
# - https://opendev.org/openstack-infra/bindep
#
# Even if the role does not make use of this facility, it
# is better to have this file empty, otherwise OpenStack-CI
# will fall back to installing its default packages which
# will potentially be detrimental to the tests executed.
#
# Note:
# This file is maintained in the openstack-ansible-tests repository.
# https://opendev.org/openstack/openstack-ansible-tests/src/bindep.txt
# If you need to remove or add extra dependencies, you should modify
# the central file instead and once your change is accepted then update
# this file as well. The purpose of this file is to ensure that Python and
# Ansible have all their necessary binary requirements on the test host before
# tox executes. Any binary requirements needed by services/roles should be
# installed by those roles in their applicable package install tasks, not through
# using this file.
#
# The gcc compiler
gcc
# Base requirements for Ubuntu
git-core [platform:dpkg]
libssl-dev [platform:dpkg]
libffi-dev [platform:dpkg]
python3 [platform:dpkg]
python3-apt [platform:dpkg]
python3-dev [platform:dpkg]
# Base requirements for RPM distros
gcc-c++ [platform:rpm]
git [platform:rpm]
libffi-devel [platform:rpm]
openssl-devel [platform:rpm]
python3-dnf [platform:fedora]
python3-devel [platform:rpm]
# For SELinux
libselinux-python3 [platform:redhat]
libsemanage-python3 [platform:redhat]
iptables [platform:redhat]

View File

@ -1,6 +1,9 @@
- name: Install RabbitMQ server
hosts: rabbitmq_all
user: root
serial:
- 1
- 100%
roles:
- role: rabbitmq_server
tags:

View File

@ -1,33 +0,0 @@
export VIRTUAL_ENV=$(pwd)
export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_SSH_CONTROL_PATH=/tmp/%%h-%%r
# TODO (odyssey4me) These are only here as they are non-standard folder
# names for Ansible 1.9.x. We are using the standard folder names for
# Ansible v2.x. We can remove this when we move to Ansible 2.x.
export ANSIBLE_ACTION_PLUGINS=${HOME}/.ansible/plugins/action
export ANSIBLE_CALLBACK_PLUGINS=${HOME}/.ansible/plugins/callback
export ANSIBLE_FILTER_PLUGINS=${HOME}/.ansible/plugins/filter
export ANSIBLE_LOOKUP_PLUGINS=${HOME}/.ansible/plugins/lookup
# This is required as the default is the current path or a path specified
# in ansible.cfg
export ANSIBLE_LIBRARY=${HOME}/.ansible/plugins/library
# This is required as the default is '/etc/ansible/roles' or a path
# specified in ansible.cfg
export ANSIBLE_ROLES_PATH=${HOME}/.ansible/roles:$(pwd)/..
export ANSIBLE_SSH_ARGS="-o ControlMaster=no \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-o ServerAliveInterval=64 \
-o ServerAliveCountMax=1024 \
-o Compression=no \
-o TCPKeepAlive=yes \
-o VerifyHostKeyDNS=no \
-o ForwardX11=no \
-o ForwardAgent=yes"
echo "Run manual functional tests by executing the following:"
echo "# ./.tox/functional/bin/ansible-playbook -i tests/inventory tests/test.yml"

View File

@ -0,0 +1,8 @@
---
- name: Prepare
hosts: localhost
tasks:
- name: Delete generated certs, if any
ansible.builtin.file:
path: /tmp/pki/rabbitmq-ca
state: absent

View File

@ -0,0 +1,78 @@
---
dependency:
name: galaxy
options:
requirements-file: requirements.yml
driver:
name: docker
platforms:
- name: rabbitmq01
groups:
- rabbitmq_all
image: "${DOCKER_REGISTRY:-quay.io/gotmax23}/${DOCKER_IMAGE_TAG:-debian-systemd:bookworm}"
command: ${DOCKER_COMMAND:-""}
privileged: true
pre_build_image: true
docker_networks:
- name: 'rabbitmq'
ipam_config:
- subnet: '10.1.0.0/24'
networks:
- name: "rabbitmq"
ipv4_address: '10.1.0.2'
- name: rabbitmq02
groups:
- rabbitmq_all
image: "${DOCKER_REGISTRY:-quay.io/gotmax23}/${DOCKER_IMAGE_TAG:-debian-systemd:bookworm}"
command: ${DOCKER_COMMAND:-""}
privileged: true
pre_build_image: true
docker_networks:
- name: 'rabbitmq'
ipam_config:
- subnet: '10.1.0.0/24'
networks:
- name: "rabbitmq"
ipv4_address: '10.1.0.3'
- name: rabbitmq03
groups:
- rabbitmq_all
image: "${DOCKER_REGISTRY:-quay.io/gotmax23}/${DOCKER_IMAGE_TAG:-debian-systemd:bookworm}"
command: ${DOCKER_COMMAND:-""}
privileged: true
pre_build_image: true
docker_networks:
- name: 'rabbitmq'
ipam_config:
- subnet: '10.1.0.0/24'
networks:
- name: "rabbitmq"
ipv4_address: '10.1.0.4'
provisioner:
name: ansible
inventory:
group_vars:
rabbitmq_all:
rabbitmq_apply_openstack_policies: True
rabbitmq_cookie_token: secrete
rabbitmq_manage_hosts_entries: False
rabbitmq_pki_dir: /tmp/pki/rabbitmq-ca
host_vars:
rabbitmq01:
rabbitmq_node_address: 10.1.0.2
rabbitmq02:
rabbitmq_node_address: 10.1.0.3
rabbitmq03:
rabbitmq_node_address: 10.1.0.4
lint:
name: ansible-lint
playbooks:
prepare: prepare.yml
converge: ../../tests/test.yml
verify: ../../tests/test-rabbitmq-functional.yml
cleanup: cleanup.yml
config_options:
defaults:
inject_facts_as_vars: false
scenario:
name: default

View File

@ -0,0 +1,21 @@
---
- name: Prepare
hosts: all
vars:
procps_package:
debian: procps
redhat: procps-ng
tasks:
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
when:
- ansible_facts['os_family'] | lower == 'debian'
- name: Install python3-cryptography
ansible.builtin.package:
name:
- python3-cryptography
- "{{ procps_package[ansible_facts['os_family'] | lower] }}"
state: present

30
requirements.yml Normal file
View File

@ -0,0 +1,30 @@
---
collections:
- name: https://opendev.org/openstack/ansible-config_template
version: master
type: git
- name: community.crypto
source: https://github.com/ansible-collections/community.crypto
type: git
version: 2.22.3
- name: community.general
source: https://github.com/ansible-collections/community.general
type: git
version: 10.0.1
- name: community.rabbitmq
source: https://github.com/ansible-collections/community.rabbitmq
type: git
version: 1.3.0
roles:
- name: apt_package_pinning
src: https://opendev.org/openstack/openstack-ansible-apt_package_pinning
scm: git
version: master
- name: systemd_service
src: https://opendev.org/openstack/ansible-role-systemd_service
scm: git
version: master
- name: pki
src: https://opendev.org/openstack/ansible-role-pki
scm: git
version: master

View File

@ -1,88 +0,0 @@
#!/usr/bin/env bash
# Copyright 2015, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# PURPOSE:
# This script clones the openstack-ansible-tests repository to the
# tests/common folder in order to be able to re-use test components
# for role testing. This is intended to be the thinnest possible
# shim for test execution outside of OpenStack CI.
# WARNING:
# This file is maintained in the openstack-ansible-tests repository.
# https://opendev.org/openstack/openstack-ansible-tests/src/run_tests.sh
# If you need to modify this file, update the one in the openstack-ansible-tests
# repository and then update this file as well. The purpose of this file is to
# prepare the host and then execute all the tox tests.
#
## Shell Opts ----------------------------------------------------------------
set -xeu
## Vars ----------------------------------------------------------------------
WORKING_DIR="$(readlink -f $(dirname $0))"
OSA_PROJECT_NAME="$(sed -n 's|^project=openstack/\(.*\).git$|\1|p' $(pwd)/.gitreview)"
COMMON_TESTS_PATH="${WORKING_DIR}/tests/common"
TESTING_HOME=${TESTING_HOME:-$HOME}
ZUUL_TESTS_CLONE_LOCATION="/home/zuul/src/opendev.org/openstack/openstack-ansible-tests"
# Use .gitreview as the key to determine the appropriate
# branch to clone for tests.
TESTING_BRANCH=$(awk -F'=' '/defaultbranch/ {print $2}' "${WORKING_DIR}/.gitreview")
if [[ "${TESTING_BRANCH}" == "" ]]; then
TESTING_BRANCH="master"
fi
## Main ----------------------------------------------------------------------
# Source distribution information
source /etc/os-release || source /usr/lib/os-release
# Figure out the appropriate package install command
case ${ID,,} in
centos|rhel|fedora|rocky) pkg_mgr_cmd="dnf install -y" ;;
ubuntu|debian) pkg_mgr_cmd="apt-get install -y" ;;
*) echo "unsupported distribution: ${ID,,}"; exit 1 ;;
esac
# Install git so that we can clone the tests repo if git is not available
which git &>/dev/null || eval sudo "${pkg_mgr_cmd}" git
# Clone the tests repo for access to the common test script
if [[ ! -d "${COMMON_TESTS_PATH}" ]]; then
# The tests repo doesn't need a clone, we can just
# symlink it.
if [[ "${OSA_PROJECT_NAME}" == "openstack-ansible-tests" ]]; then
ln -s "${WORKING_DIR}" "${COMMON_TESTS_PATH}"
# In zuul v3 any dependent repository is placed into
# /home/zuul/src/opendev.org, so we check to see
# if there is a tests checkout there already. If so, we
# symlink that and use it.
elif [[ -d "${ZUUL_TESTS_CLONE_LOCATION}" ]]; then
ln -s "${ZUUL_TESTS_CLONE_LOCATION}" "${COMMON_TESTS_PATH}"
# Otherwise we're clearly not in zuul or using a previously setup
# repo in some way, so just clone it from upstream.
else
git clone -b "${TESTING_BRANCH}" \
https://opendev.org/openstack/openstack-ansible-tests \
"${COMMON_TESTS_PATH}"
fi
fi
# Execute the common test script
source tests/common/run_tests_common.sh

View File

@ -79,8 +79,8 @@
file:
path: "/etc/rabbitmq/"
state: "directory"
group: "{{ rabbit_system_user_name }}"
owner: "{{ rabbit_system_group_name }}"
owner: "root"
group: "{{ rabbit_system_group_name }}"
mode: "0755"
tags:
- rabbitmq-config

View File

@ -1,21 +0,0 @@
---
- name: apt_package_pinning
src: https://opendev.org/openstack/openstack-ansible-apt_package_pinning
scm: git
version: master
- name: pip_install
src: https://opendev.org/openstack/openstack-ansible-pip_install
scm: git
version: master
- name: openstack_hosts
src: https://opendev.org/openstack/openstack-ansible-openstack_hosts
scm: git
version: master
- name: lxc_hosts
src: https://opendev.org/openstack/openstack-ansible-lxc_hosts
scm: git
version: master
- name: lxc_container_create
src: https://opendev.org/openstack/openstack-ansible-lxc_container_create
scm: git
version: master

View File

@ -1,25 +0,0 @@
---
# Copyright 2016, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
container_networks:
management_address:
address: "{{ ansible_host }}"
bridge: "br-mgmt"
interface: "eth1"
netmask: "255.255.255.0"
type: "veth"
physical_host: localhost
properties:
service_name: "{{ inventory_hostname }}"

View File

@ -1,19 +0,0 @@
---
# Copyright 2017, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
ansible_host: 10.1.0.2
ansible_become: True
ansible_user: root
container_name: container1

View File

@ -1,19 +0,0 @@
---
# Copyright 2017, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
ansible_host: 10.1.0.3
ansible_become: True
ansible_user: root
container_name: container2

View File

@ -1,19 +0,0 @@
---
# Copyright 2017, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
ansible_host: 10.1.0.4
ansible_become: True
ansible_user: root
container_name: container3

View File

@ -1,18 +0,0 @@
---
# Copyright 2016, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
bridges:
- "br-mgmt"

View File

@ -1,13 +0,0 @@
[all]
localhost
container1
container2
container3
[rabbitmq_all]
container1
container2
container3
[all_containers:children]
rabbitmq_all

View File

@ -1,5 +0,0 @@
rabbitmq_cookie_token: secrete
rabbitmq_ssl_cert: /etc/rabbitmq/rabbitmq.pem
rabbitmq_ssl_key: /etc/rabbitmq/rabbitmq.key
rabbitmq_apply_openstack_policies: True

View File

@ -18,76 +18,67 @@
any_errors_fatal: true
user: root
gather_facts: true
become: true
tasks:
- name: Check rabbitmq is running
command: "pgrep -f rabbit"
delegate_to: "{{ item }}"
when: ansible_host == item
with_items:
- 10.1.0.2
- 10.1.0.3
- 10.1.0.4
- name: Open rabbitmq.config
slurp:
src: "/etc/rabbitmq/rabbitmq.config"
src: "/etc/rabbitmq/rabbitmq.conf"
register: rabbitmq_config
- name: Open enabled_plugins
slurp:
src: "/etc/rabbitmq/enabled_plugins"
register: enabled_plugins
- name: Read rabbitmq_ssl_cert
stat:
path: "{{ rabbitmq_ssl_cert }}"
community.crypto.x509_certificate_info:
path: "/etc/rabbitmq/rabbitmq.pem"
register: rabbitmq_ssl_cert_stat
- name: Read rabbitmq_ssl_key
stat:
path: "{{ rabbitmq_ssl_key }}"
register: rabbitmq_ssl_key_stat
- name: Read rabbit files
set_fact:
enabled_plugins_contents: "{{ enabled_plugins.content | b64decode }}"
rabbitmq_config_contents: "{{ rabbitmq_config.content | b64decode }}"
rabbitmq_ssl_cert_checksum: "{{ rabbitmq_ssl_cert_stat.stat.checksum }}"
rabbitmq_ssl_key_checksum: "{{ rabbitmq_ssl_key_stat.stat.checksum }}"
- name: Check files contents
assert:
that:
- "'rabbitmq_management' in enabled_plugins_contents"
- "'ssl_options.certfile = /etc/rabbitmq/rabbitmq.pem' in rabbitmq_config_contents"
- "'ssl_options.keyfile = /etc/rabbitmq/rabbitmq.key' in rabbitmq_config_contents"
- not rabbitmq_ssl_cert_stat['expired']
- rabbitmq_ssl_cert_stat['issuer']['commonName'] == 'RabbitMQ Intermediate CA'
- rabbitmq_ssl_cert_stat['subject']['commonName'] == inventory_hostname
- "'IP:' ~ rabbitmq_node_address in rabbitmq_ssl_cert_stat['subject_alt_name']"
- name: Get status of rabbitmq
command: rabbitmqctl status
command: rabbitmqctl status --formatter json
register: rabbitmqctl_status
changed_when: false
- name: Print rabbitmqctl status
debug:
var: rabbitmqctl_status
- name: Get cluster status of rabbitmq
command: rabbitmqctl cluster_status --formatter json
register: rabbitmqctl_cluster_status
changed_when: false
- name: Ensure SSL cert/key checksums are identical across cluster
- name: Ensure proper resulting state of deployment
vars:
cluster_status: "{{ rabbitmqctl_cluster_status.stdout | from_json }}"
node_status: "{{ rabbitmqctl_status.stdout | from_json }}"
cluster_rabbit_versions: "{{ cluster_status['versions'].values() | map(attribute='rabbitmq_version') | unique }}"
cluster_erlang_versions: "{{ cluster_status['versions'].values() | map(attribute='erlang_version') | unique }}"
assert:
that:
- hostvars['container1']['rabbitmq_ssl_cert_checksum'] == hostvars['container2']['rabbitmq_ssl_cert_checksum']
- hostvars['container2']['rabbitmq_ssl_cert_checksum'] == hostvars['container3']['rabbitmq_ssl_cert_checksum']
- hostvars['container1']['rabbitmq_ssl_key_checksum'] == hostvars['container2']['rabbitmq_ssl_key_checksum']
- hostvars['container2']['rabbitmq_ssl_key_checksum'] == hostvars['container3']['rabbitmq_ssl_key_checksum']
- not node_status['is_under_maintenance']
- node_status['alarms'] | length == 0
- "'rabbitmq_management' in node_status['active_plugins']"
- cluster_rabbit_versions | length == 1
- cluster_erlang_versions | length == 1
- cluster_status['running_nodes'] | length == 3
- cluster_status['disk_nodes'] | length == 3
- name: Get the policy list
command: rabbitmqctl -q list_policies
command: rabbitmqctl -q list_policies --formatter json
register: rabbitmq_policies_output
changed_when: false
- name: Show the policies
debug:
var: rabbitmq_policies.stdout
# Expected policy: "/ HA all ^(?!amq\\.).* {"ha-mode":"all"} 0"
# Expected policy: "/ CQv2 .* all {"queue-version":2} 0"
- name: Validate that the expected policies are present
assert:
that: rabbitmq_policies_output.stdout is search("amq")
that: rabbitmq_policies_output.stdout | from_json | selectattr('name', 'eq', 'CQv2') | length > 0

View File

@ -13,11 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# Setup the host
- import_playbook: common/test-setup-host.yml
# Install RabbitMQ server
- import_playbook: common/test-install-rabbitmq.yml
# Run functional tests
- import_playbook: test-rabbitmq-functional.yml
- name: Install RabbitMQ server
hosts: rabbitmq_all
user: root
roles:
- "{{ playbook_dir | dirname | basename }}"

48
tox.ini
View File

@ -1,7 +1,7 @@
[tox]
minversion = 3.1
minversion = 4.0
skipsdist = True
envlist = docs,linters,functional
envlist = docs,molecule
ignore_basepython_conflict = True
[testenv]
@ -61,36 +61,22 @@ commands =
commands =
{posargs}
[testenv:pep8]
commands =
bash -c "{toxinidir}/tests/common/test-pep8.sh"
[flake8]
# Ignores the following rules due to how ansible modules work in general
# F403 'from ansible.module_utils.basic import *' used;
# unable to detect undefined names
ignore=F403
[testenv:molecule]
# You can use DOCKER_REGISTRY and DOCKER_IMAGE_TAG to switch between
# tested distros. I.e:
# DOCKER_IMAGE_TAG=ubuntu-systemd:jammy tox -e molecule
deps =
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{env:OSA_TEST_REQUIREMENTS_FILE:https://opendev.org/openstack/openstack-ansible/raw/branch/{env:TEST_BRANCH:master}/test-requirements.txt}
jmespath
setuptools
[testenv:bashate]
commands =
bash -c "{toxinidir}/tests/common/test-bashate.sh"
molecule test
[testenv:ansible-syntax]
commands =
bash -c "{toxinidir}/tests/common/test-ansible-syntax.sh"
[testenv:ansible-lint]
commands =
bash -c "{toxinidir}/tests/common/test-ansible-lint.sh"
[testenv:functional]
commands =
bash -c "{toxinidir}/tests/common/test-ansible-functional.sh"
[testenv:linters]
commands =
bash -c "{toxinidir}/tests/common/test-ansible-env-prep.sh"
{[testenv:pep8]commands}
{[testenv:bashate]commands}
{[testenv:ansible-lint]commands}
{[testenv:ansible-syntax]commands}
passenv =
{[testenv]passenv}
DOCKER_REGISTRY
DOCKER_IMAGE_TAG
DOCKER_COMMAND

View File

@ -16,6 +16,7 @@
- project:
templates:
- openstack-ansible-linters-jobs
- openstack-ansible-molecule
- openstack-ansible-deploy-infra_lxc-jobs
- openstack-ansible-deploy-aio_metal-jobs
- openstack-ansible-deploy-infra_distro_lxc-jobs