Add molecule testing

Depends-On: https://review.opendev.org/c/openstack/openstack-ansible/+/938571
Change-Id: I1310915186dc286e592aa0db8127b172800fc96c
This commit is contained in:
Jonathan Rosser 2022-02-28 17:38:18 +00:00 committed by Dmitriy Rabotyagov
parent 30b72fcdd9
commit 112a5367c9
9 changed files with 353 additions and 7 deletions

View File

@ -1,6 +1,8 @@
---
- name: Install PKI
hosts: localhost
user: root
roles:
- role: "pki"
hosts: all
tasks:
- name: "Include pki role"
ansible.builtin.include_role:
name: "{{ playbook_dir | dirname | basename }}"

View File

@ -4,6 +4,8 @@ galaxy_info:
company: City Networks, BBC
license: Apache2
min_ansible_version: 2.10
namespace: openstack
role_name: pki
platforms:
- name: Ubuntu
versions:

View File

@ -0,0 +1,188 @@
---
molecule_packages:
debian:
- ca-certificates
- python3-cryptography
- gnutls-bin
- iproute2
redhat:
- ca-certificates
- python3-cryptography
- gnutls-utils
- iproute
pki_setup_host: "{{ inventory_hostname }}"
functional_ca_name_1: "ExampleCorpRoot"
# Example self-signed certificate authority
# Using the default variable
pki_authorities:
- name: "{{ functional_ca_name_1 }}"
provider: selfsigned
basic_constraints: "CA:TRUE"
cn: "Example Corp Root CA"
email_address: "pki@example.com"
country_name: "GB"
state_or_province_name: "England"
organization_name: "Example Corporation"
organizational_unit_name: "IT Security"
key_usage:
- digitalSignature
- cRLSign
- keyCertSign
not_after: "+3650d"
- name: "ExampleCorpIntermediate"
provider: ownca
basic_constraints: "CA:TRUE,pathlen:0"
cn: "Example Corp Openstack Infrastructure Intermediate CA"
email_address: "pki@example.com"
country_name: "GB"
state_or_province_name: "England"
organization_name: "Example Corporation"
organizational_unit_name: "IT Security"
key_usage:
- digitalSignature
- cRLSign
- keyCertSign
not_after: "+3650d"
signed_by: "ExampleCorpRoot"
# Custom CA generation search pattern
pki_search_authorities_pattern: "foo_authorities_"
# Certificate authority to cerate from a custom variable
functional_ca_name_2: "FooAuthorityNotInstalled"
functional_ca_name_3: "FooAuthorityInstalled"
foo_authorities_variable:
- name: "{{ functional_ca_name_2 }}"
country: "GB"
state_or_province_name: "England"
organization_name: "Example Corporation"
organizational_unit_name: "IT Security"
cn: "FooAutorityNotInstalled"
provider: selfsigned
basic_constraints: "CA:TRUE"
key_usage:
- digitalSignature
- keyCertSign
not_after: "+3650d"
condition: false
- name: "{{ functional_ca_name_3 }}"
country: "GB"
state_or_province_name: "England"
organization_name: "Example Corporation"
organizational_unit_name: "IT Security"
cn: "FooAutorityInstalled"
provider: selfsigned
basic_constraints: "CA:TRUE"
key_usage:
- digitalSignature
- keyCertSign
not_after: "+3650d"
condition: true
# install the root CA certificate
pki_install_ca:
- name: "ExampleCorpRoot"
# Custom CA install search pattern
pki_search_install_ca_pattern: "foo_install_ca_"
# CA to install from a custom variable
foo_install_ca_variable:
- name: "FooAuthorityInstalled"
# Certificates to create from the default variable
pki_certificates:
- name: "{{ ansible_facts['hostname'] }}_1"
provider: ownca
cn: "{{ ansible_facts['hostname'] }}"
san: "{{ 'DNS:' ~ ansible_facts['hostname'] }}"
signed_by: "ExampleCorpIntermediate"
# Custom certificate generation search pattern
pki_search_certificates_pattern: "foo_certificates_"
# Certificates to create from a custom variable, with conditionals
foo_certificates_variable:
- name: "{{ ansible_facts['hostname'] }}_2"
provider: ownca
cn: "{{ ansible_facts['hostname'] }}"
san: "{{ 'DNS:' ~ ansible_facts['hostname'] }}"
signed_by: "ExampleCorpIntermediate"
condition: true
- name: "{{ ansible_facts['hostname'] }}_3"
provider: ownca
cn: "{{ ansible_facts['hostname'] }}"
san: "{{ 'DNS:' ~ ansible_facts['hostname'] }}"
signed_by: "ExampleCorpIntermediate"
condition: false
# Certificates to install from the default variable
functional_install_cert_1_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_1.crt' }}"
functional_install_chain_1_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_1-chain.crt' }}"
functional_install_key_1_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_1.key.pem' }}"
pki_install_certificates:
- src: "{{ pki_dir ~ '/certs/certs/' ~ ansible_facts['hostname'] ~ '_1.crt' }}"
dest: "{{ functional_install_cert_1_dest }}"
owner: "root"
group: "root"
mode: "0644"
- src: "{{ pki_dir ~ '/certs/certs/' ~ ansible_facts['hostname'] ~ '_1-chain.crt' }}"
dest: "{{ functional_install_chain_1_dest }}"
owner: "root"
group: "root"
mode: "0644"
- src: "{{ pki_dir ~ '/certs/private/' ~ ansible_facts['hostname'] ~ '_1.key.pem' }}"
dest: "{{ functional_install_key_1_dest }}"
owner: "root"
group: "root"
mode: "0640"
# Custom certificate installation search pattern
pki_search_install_certificates_pattern: "foo_install_certificates_"
# Certificates to isntall from a custom variable, with conditionals
functional_install_cert_2_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_2.crt' }}"
functional_install_chain_2_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_2-chain.crt' }}"
functional_install_key_2_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_2.key.pem' }}"
functional_install_cert_3_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_3.crt' }}"
functional_install_chain_3_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_3-chain.crt' }}"
functional_install_key_3_dest: "{{ '/root/' ~ ansible_facts['hostname'] ~ '_3.key.pem' }}"
foo_install_certificates_variable:
- src: "{{ pki_dir ~ '/certs/certs/' ~ ansible_facts['hostname'] ~ '_2.crt' }}"
dest: "{{ functional_install_cert_2_dest }}"
owner: "root"
group: "root"
mode: "0644"
condition: true
- src: "{{ pki_dir ~ '/certs/certs/' ~ ansible_facts['hostname'] ~ '_2-chain.crt' }}"
dest: "{{ functional_install_chain_2_dest }}"
owner: "root"
group: "root"
mode: "0644"
condition: true
- src: "{{ pki_dir ~ '/certs/private/' ~ ansible_facts['hostname'] ~ '_2.key.pem' }}"
dest: "{{ functional_install_key_2_dest }}"
owner: "root"
group: "root"
mode: "0640"
condition: true
- src: "{{ pki_dir ~ '/certs/certs/' ~ ansible_facts['hostname'] ~ '_3.crt' }}"
dest: "{{ functional_install_cert_3_dest }}"
owner: "root"
group: "root"
mode: "0644"
condition: false
- src: "{{ pki_dir ~ '/certs/private/' ~ ansible_facts['hostname'] ~ '_3.key.pem' }}"
dest: "{{ functional_install_key_3_dest }}"
owner: "root"
group: "root"
mode: "0640"
condition: false

View File

@ -0,0 +1,35 @@
---
dependency:
name: galaxy
options:
requirements-file: requirements.yml
force: ${GALAXY_FORCE:-false}
driver:
name: docker
platforms:
- name: "pki-${MOLECULE_SCENARIO_NAME}"
image: "${DOCKER_REGISTRY:-quay.io/gotmax23}/${DOCKER_IMAGE_TAG:-debian-systemd:bookworm}"
command: ${DOCKER_COMMAND:-""}
pre_build_image: true
privileged: true
systemd: true
provisioner:
name: ansible
lint:
name: ansible-lint
playbooks:
prepare: prepare.yml
converge: ../../examples/playbook.yml
verify: verify.yml
inventory:
links:
group_vars: ./group_vars/
config_options:
defaults:
inject_facts_as_vars: false
scenario:
name: default

View File

@ -0,0 +1,14 @@
---
- name: Prepare
hosts: all
tasks:
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
when:
- ansible_facts['os_family'] | lower == 'debian'
- name: Install packages
ansible.builtin.package:
name: "{{ molecule_packages[ansible_facts['os_family'] | lower] }}"

View File

@ -0,0 +1,84 @@
---
- name: Verify
hosts: all
vars:
pki_trust_store_location:
apt: /usr/local/share/ca-certificates/
dnf: /etc/pki/ca-trust/source/anchors/
tasks:
# Check that certificate authorities are installed (or absent) at the correct path
- stat:
path: "{{ pki_trust_store_location[ansible_facts['pkg_mgr']] }}/{{ functional_ca_name_1 }}.crt"
register: ca_1_stat
- stat:
path: "{{ pki_trust_store_location[ansible_facts['pkg_mgr']] }}/{{ functional_ca_name_2 }}.crt"
register: ca_2_stat
- stat:
path: "{{ pki_trust_store_location[ansible_facts['pkg_mgr']] }}/{{ functional_ca_name_3 }}.crt"
register: ca_3_stat
- assert:
that:
- ca_1_stat.stat.exists
- not ca_2_stat.stat.exists
- ca_3_stat.stat.exists
# Check that certificates are installed (or absent) at the correct path
- stat:
path: "{{ functional_install_cert_1_dest }}"
register: cert_1_stat
- stat:
path: "{{ functional_install_chain_1_dest }}"
register: chain_1_stat
- stat:
path: "{{ functional_install_key_1_dest }}"
register: key_1_stat
- stat:
path: "{{ functional_install_cert_2_dest }}"
register: cert_2_stat
- stat:
path: "{{ functional_install_chain_2_dest }}"
register: chain_2_stat
- stat:
path: "{{ functional_install_key_2_dest }}"
register: key_2_stat
- stat:
path: "{{ functional_install_cert_3_dest }}"
register: cert_3_stat
- stat:
path: "{{ functional_install_chain_3_dest }}"
register: chain_3_stat
- stat:
path: "{{ functional_install_key_3_dest }}"
register: key_3_stat
- assert:
that:
- cert_1_stat.stat.exists
- chain_1_stat.stat.exists
- key_1_stat.stat.exists
- cert_2_stat.stat.exists
- key_2_stat.stat.exists
- not cert_3_stat.stat.exists
- not chain_3_stat.stat.exists
- not key_3_stat.stat.exists
# Check that certificates can validate against the installed CA
- name: Validate server certificate against system trust store
command: certtool --verify --infile "{{ functional_install_chain_1_dest }}"
changed_when: false
- name: Validate server certificate against system trust store
command: certtool --verify --infile "{{ functional_install_chain_2_dest }}"
changed_when: false

4
requirements.yml Normal file
View File

@ -0,0 +1,4 @@
collections:
- name: community.crypto
version: 2.0.2
source: https://galaxy.ansible.com

22
tox.ini
View File

@ -1,7 +1,7 @@
[tox]
minversion = 3.1
minversion = 4.0
skipsdist = True
envlist = docs,releasenotes
envlist = docs,releasenotes,molecule
ignore_basepython_conflict = True
@ -27,7 +27,6 @@ allowlist_externals =
setenv =
PYTHONUNBUFFERED=1
ROLE_NAME=pki
TEST_IDEMPOTENCE=false
VIRTUAL_ENV={envdir}
WORKING_DIR={toxinidir}
@ -56,3 +55,20 @@ commands =
[testenv:venv]
commands =
{posargs}
[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}
-rhttps://opendev.org/openstack/openstack-ansible/raw/branch/{env:TEST_BRANCH:master}/test-requirements.txt
commands =
molecule test
passenv =
{[testenv]passenv}
DOCKER_REGISTRY
DOCKER_IMAGE_TAG
DOCKER_COMMAND

View File

@ -18,5 +18,6 @@
- check-requirements
- openstack-ansible-deploy-infra_lxc-jobs
- openstack-ansible-linters-jobs
- openstack-ansible-molecule
- publish-openstack-docs-pti
- build-release-notes-jobs-python3