From fedd89eea09529f4e10ebe0e6088dddeea6a7cab Mon Sep 17 00:00:00 2001 From: Rafael Guterres Jeffman Date: Fri, 8 Mar 2024 23:31:22 -0300 Subject: [PATCH] upstream ci: Add support for testing ipaserver deployment This patch provides the base for testing ipaserver role using Azure's infrastructure. By using containers prepared to thave FreeIPA installed, but unconfigured, allows the use of a test matrix to test the behavior of modules in differnt IPA configurations. It also improves tests by allowing the creation of a test matrix of FreeIPA deployment. A new pipeline script is provided, which can be used as a standalone pipeline, os as part of an existing pipeline. The script 'tests/server_role/inventory.py' is used to create inventory files for the tests, which should be executed using the existing 'install-server.yml' playbook. More information on how to generate different inventories can be found in the accompanying README file 'tests/server_role/README.md'. --- tests/azure/deployment.yml | 53 ++++++++++ tests/azure/templates/deployment_tests.yml | 70 +++++++++++++ tests/server_role/README.md | 1 + tests/server_role/inventory.py | 111 +++++++++++++++++++++ tests/server_role/ipv6config.yml | 22 ++++ 5 files changed, 257 insertions(+) create mode 100644 tests/azure/deployment.yml create mode 100644 tests/azure/templates/deployment_tests.yml create mode 100644 tests/server_role/README.md create mode 100755 tests/server_role/inventory.py create mode 100644 tests/server_role/ipv6config.yml diff --git a/tests/azure/deployment.yml b/tests/azure/deployment.yml new file mode 100644 index 000000000..bc9000013 --- /dev/null +++ b/tests/azure/deployment.yml @@ -0,0 +1,53 @@ +--- +schedules: +- cron: "0 19 * * *" + displayName: Nightly Builds + branches: + include: + - master + always: true + +trigger: none + +pool: + vmImage: 'ubuntu-22.04' + +stages: + +# Fedora + +- stage: FedoraLatest_Ansible_Core_2_15 + dependsOn: [] + jobs: + - template: templates/deployment_tests.yml + parameters: + build_number: $(Build.BuildNumber) + scenario: fedora-latest + ansible_version: "-core >=2.15,<2.16" + +- stage: FedoraLatest_Ansible_Core_2_16 + dependsOn: [] + jobs: + - template: templates/deployment_tests.yml + parameters: + build_number: $(Build.BuildNumber) + scenario: fedora-latest + ansible_version: "-core >=2.16,<2.17" + +#- stage: FedoraLatest_Ansible_Core_2_17 +# dependsOn: [] +# jobs: +# - template: templates/deployment_tests.yml +# parameters: +# build_number: $(Build.BuildNumber) +# scenario: fedora-latest +# ansible_version: "-core >=2.17,<2.18" + +- stage: FedoraLatest_Ansible_latest + dependsOn: [] + jobs: + - template: templates/deployment_tests.yml + parameters: + build_number: $(Build.BuildNumber) + scenario: fedora-latest + ansible_version: "" diff --git a/tests/azure/templates/deployment_tests.yml b/tests/azure/templates/deployment_tests.yml new file mode 100644 index 000000000..06db0b27b --- /dev/null +++ b/tests/azure/templates/deployment_tests.yml @@ -0,0 +1,70 @@ +--- +parameters: + - name: scenario + type: string + default: fedora-latest + - name: ansible_version + type: string + default: "" + - name: python_version + type: string + default: 3.x + - name: build_number + type: string + +jobs: +- job: Test_Deployment + displayName: Run deployment tests ${{ parameters.scenario }} + timeoutInMinutes: 240 + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '${{ parameters.python_version }}' + + - script: | + pip install "ansible${{ parameters.ansible_version }}" + retryCountOnTaskFailure: 5 + displayName: Install Ansible + + - script: ansible-galaxy collection install community.docker ansible.posix + retryCountOnTaskFailure: 5 + displayName: Install Ansible collections + + - script: pip install -r requirements-tests.txt + retryCountOnTaskFailure: 5 + displayName: Install dependencies + + - script: | + rm -rf ~/.ansible/plugins ~/.ansible/roles + ln -snf "$(realpath plugins)" ~/.ansible/plugins + ln -snf "$(realpath roles)" ~/.ansible/roles + ls -l ~/.ansible + docker pull ${SCENARIO_IMAGE} + env: + SCENARIO_IMAGE: quay.io/ansible-freeipa/upstream-tests:raw-${{ parameters.scenario }} + retryCountOnTaskFailure: 5 + displayName: Setup test environment + + - script: tests/server_role/inventory.py | tee inventory.yml + displayName: Create inventory files + + - script: | + # remove stray container + docker rm --force ${{ parameters.scenario }} >&2 2>/dev/null + # run test + docker run -d --privileged --name ${IPA_CONTAINER} --hostname ${IPA_HOSTNAME} ${SCENARIO_IMAGE} + ansible-playbook -i inventory.yml tests/server_role/ipv6config.yml + ansible-playbook -i inventory.yml playbooks/install-server.yml + # Run tests to verify installation + ansible-playbook -i inventory.yml tests/user/test_user.yml + displayName: Run deployment tests + env: + SCENARIO_IMAGE: quay.io/ansible-freeipa/upstream-tests:raw-${{ parameters.scenario }} + IPA_CONTAINER: ipaserver_test_container + IPA_HOSTNAME: ipaserver.test.local + + - task: PublishTestResults@2 + inputs: + mergeTestResults: true + testRunTitle: DeploymentTests-Build${{ parameters.build_number }} + condition: succeededOrFailed() diff --git a/tests/server_role/README.md b/tests/server_role/README.md new file mode 100644 index 000000000..1355eb1c4 --- /dev/null +++ b/tests/server_role/README.md @@ -0,0 +1 @@ +This file should include how to test ipaserver. diff --git a/tests/server_role/inventory.py b/tests/server_role/inventory.py new file mode 100755 index 000000000..2158a6be4 --- /dev/null +++ b/tests/server_role/inventory.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +"""Dynamic inventory to test ipaserver role.""" + +import os +import sys +from collections import namedtuple + +try: + import yaml + + inventory_to_string = yaml.dump +except ImportError: + import json + + inventory_to_string = json.dumps + +Config = namedtuple( + "Config", + """ + engine + container + hostname + ipa_domain + ipa_realm + setup_kra + setup_dns + dns_no_forwarders + dns_auto_reverse + setup_adtrust + ipa_netbios_name +""", +) + + +def to_boolean(value): + return value.lower() == "true" + + +def get_inventory_data(config): + """Generate inventory based on given configuration.""" + return { + "all": { + "children": { + "ipaserver": { + "hosts": { + "ipa_server": { + "ansible_connection": config.engine, + "ansible_host": config.container, + }, + }, + "vars": { + # KRA + "ipaserver_setup_kra": config.setup_kra, + # DNS + "ipaserver_setup_dns": config.setup_dns, + "ipaserver_no_forwarders": config.dns_no_forwarders, + "ipaserver_auto_reverse": config.dns_auto_reverse, + # AD Trust + "ipaserver_setup_adtrust": config.setup_adtrust, + "ipaserver_netbios_name": config.ipa_netbios_name, + # adjtimex fails on container, so do not set ntp + "ipaclient_no_ntp": True, + # server configuration + "ipaserver_hostname": config.hostname, + }, + }, + }, + "vars": { + # server/realm + "ipaserver_domain": config.ipa_domain, + "ipaserver_realm": config.ipa_realm, + # passwords + "ipaadmin_password": "SomeADMINpassword", + "ipadm_password": "SomeDMpassword", + }, + }, + } + + +def gen_default_inventory(): + default_hostname = "ipaserver.test.local" + ipa_hostname = os.environ.get("IPA_HOSTNAME", default_hostname).split(".") + + setup_dns = to_boolean(os.environ.get("SETUP_DNS", "False")) + + config = Config( + engine=( + "containers.podman.podman" + if "--podman" in sys.argv + else "community.docker.docker" + ), + container=os.environ.get("IPA_CONTAINER", "ipaserver_test_container"), + hostname=".".join(ipa_hostname), + ipa_domain=os.environ.get("IPA_DOMAIN", ".".join(ipa_hostname[1:])), + ipa_realm=os.environ.get( + "IPA_REALM", ".".join(ipa_hostname[1:]).upper() + ), + setup_kra=to_boolean(os.environ.get("SETUP_KRA", "False")), + setup_dns=setup_dns, + dns_no_forwarders=os.environ.get("DNS_NO_FORWARDERS", setup_dns), + dns_auto_reverse=os.environ.get("DNS_AUTO_REVERSE", setup_dns), + setup_adtrust=to_boolean(os.environ.get("SETUP_ADTRUST", "False")), + ipa_netbios_name=os.environ.get("IPA_NETBIOS_NAME", "IPA"), + ) + print(inventory_to_string(get_inventory_data(config))) + + +if "--matrix" in sys.argv: # pylint: disable=no-else-raise + raise NotImplementedError("Test matrix not implemented yet.") +else: + gen_default_inventory() diff --git a/tests/server_role/ipv6config.yml b/tests/server_role/ipv6config.yml new file mode 100644 index 000000000..169b27ead --- /dev/null +++ b/tests/server_role/ipv6config.yml @@ -0,0 +1,22 @@ +--- +- name: Configure IPv6 + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # IPA depends on IPv6 and without it dirsrv service won't start. + - name: Ensure IPv6 is ENABLED + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" + sysctl_set: yes + state: present + reload: yes + with_items: + - name: net.ipv6.conf.all.disable_ipv6 + value: 0 + - name: net.ipv6.conf.lo.disable_ipv6 + value: 0 + - name: net.ipv6.conf.eth0.disable_ipv6 + value: 1