Skip to content
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

[WIP] upstream CI: Add support for multihost testing. #1010

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ansible-lint
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ exclude_paths:
- meta/runtime.yml
- requirements-docker.yml
- requirements-podman.yml
- tests/multihost/vagrant-inventory.yml

kinds:
- playbook: '**/tests/**/test_*.yml'
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ansible-test.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: ansible-test sanity
on:
- push
- pull_request
on: []
# - push
# - pull_request
jobs:
ansible_test:
name: Verify ansible-test sanity
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: Verify Ansible documentation.
on:
- push
- pull_request
on: []
# - push
# - pull_request
jobs:
check_docs_oldest_supported:
name: Check Ansible Documentation with ansible-core 2.12.
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: Run Linters
on:
- push
- pull_request
on: []
# - push
# - pull_request
jobs:
ansible_lint:
name: Verify ansible-lint
Expand Down
105 changes: 105 additions & 0 deletions .github/workflows/multihost.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Multihost Testing

on:
- push
- pull_request

jobs:
multihost-testing:
name: "Multihost tests"
# Only macos provides Vagrant.
runs-on: macos-12
defaults:
run:
working-directory: tests/multihost

steps:
- uses: actions/[email protected]
with:
fetch-depth: 0

- uses: actions/[email protected]
with:
python-version: "3.x"

- name: Install Ansible
run: pip install ansible-core

- name: Ansible version
run: ansible --version

- name: Prepare ansible-freeipa environment
working-directory: .
run: |
rm -rf ~/.ansible
mkdir ~/.ansible
ln -s $(pwd)/roles ~/.ansible/
ln -s $(pwd)/plugins ~/.ansible/
ls -l ~/.ansible/*

- name: Show Vagrant version
run: |
vagrant --version

- name: Run vagrant up
run: vagrant up

- name: Get vagrant ssh config
run: |
vagrant ssh-config | tee "vagrant-ssh"

- name: Get nodes IP addresses
run: |
./get_ip.sh server replica client | tee "inventory/group_vars/all.yml"

- name: Test host connection
run: |
ansible -i inventory --ssh-extra-args "-F vagrant-ssh" -m ping all

- name: Log scenario configuration
run: ansible -i inventory --ssh-extra-args "-F vagrant-ssh" -m debug -a var=hostvars localhost | tee 'scenario.log'

# Here is where you add tests...
- name: Test IPA server deploy
run: ansible-playbook -i inventory --ssh-extra-args "-F vagrant-ssh" playbooks/install-server.yml

- name: Test IPA client deploy
run: ansible-playbook -i inventory --ssh-extra-args "-F vagrant-ssh" playbooks/install-client.yml

#- name: Ensure server PTR records are available
# run: ansible-playbook -i inventory --ssh-extra-args "-F vagrant-ssh" ensure-reverse-dns.yaml

- name: Test IPA replica deploy
run: ansible-playbook -i inventory --ssh-extra-args "-F vagrant-ssh" playbooks/install-replica.yml

- name: Retrieve logs in case of ANY deploy failure
if: failure()
working-directory: .
run: |
ssh -F tests/multihost/vagrant-ssh server "sudo chmod a+r /var/log/*.log"
mkdir -p logs/server-logs
scp -F tests/multihost/vagrant-ssh vagrant@server:/var/log/{ipaserver,ipaclient}-install.log logs/server-logs || true
ssh -F tests/multihost/vagrant-ssh replica "sudo chmod a+r /var/log/*.log"
mkdir -p logs/replica-logs
scp -F tests/multihost/vagrant-ssh vagrant@replica:/var/log/{ipareplica,ipaclient}-install.log logs/replica-logs || true
ssh -F tests/multihost/vagrant-ssh clente.ipa.test "sudo chmod a+r /var/log/*.log"
mkdir -p logs/client-logs
scp -F tests/multihost/vagrant-ssh vagrant@client:/var/log/ipaclient-install.log logs/client-logs || true
# tar czvf multihost-logs.tar.gz logs

- name: Save artifacts
if: failure()
uses: actions/upload-artifact@v3
with:
name: test-results
# path: multihost-logs.tar.gz
path: |
logs/
tests/multihost/inventory/
tests/multihost/vagrant-ssh
tests/multihost/scenario.log
if-no-files-found: "ignore"

# Cleanup
- name: Stop vagrant
run: vagrant destroy -f
6 changes: 3 additions & 3 deletions .github/workflows/readme.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: readme test
on:
- push
- pull_request
on: []
# - push
# - pull_request
jobs:
ansible_test:
name: Verify readme
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@
/.tox/
/.venv/

# ignore Vagrant data
/.vagrant/
/tests/multihost/vagrant-ssh

tests/logs/
2 changes: 2 additions & 0 deletions tests/multihost/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.vagrant/

93 changes: 93 additions & 0 deletions tests/multihost/README-vagrant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Multihost testing with Vagrant
==============================

To test ipaserver role and ipabackup restore options, it is required that a target node without IPA installed is provided. To test ipareplica and ipaclient roles, it is required that a multihost environvent is available, and at least one target node does not have IPA installed. This environment must have proper networking configuration and some isolation for the tarkget nodes that is not provided by containers.

By using Vagrant along with Github Workflows we can have nested virtualization, allowing the creation of virtual machine nodes that will play the roles of primary server, replicas and clients. The use of Vagrant also allows the use of a similar environment to run the tests in a developer's local machine, if desired.

Github workflows only allows nested vintualization within _macOS_ runners \[[1]\]\[[2]\]. A nice side effect of using macOS runners is that there is some more available memory for the VMs \[[3]\], which might allow the use of a Windows node, or more replicas/clients in the future.

The Ansible controller is the runner, a macOS host with the latest `ansible-core` version, installed through `pip`. Connection to the hosts is done through Vagrant `ssh-config` setup.

To execute a playbook, use `ansible-playbook -i vagrant-inventory.yml --ssh-extra-args "-F vagrant-ssh" <path/to/playbook>`. The current directory is `<repo_root>/tests/multihost`.


VM Configuration
----------------

Currently, only three VMs are used, and the hostnames and memory sizes cannot be changed.

* Server:
* hostname: server.ipa.test
* RAM: 2500 MB
* Replica:
* hostname: rep-01.ipa.test
* private network ip: 192.168.56.102
* RAM: 2500 MB
* Client:
* hostname: cli-01.ipa.test
* private network ip: 192.168.56.110
* RAM: 768 MB


BASE Variables
----------------

| Name | Description | Type | Default
| `ipadm_password` | The password for the Directory Manager.| str | SomeDMpassword |
| `ipaadmin_password` | The password for the IPA admin user.| str | SomeADMINpassword |


Server Variables
----------------

| Name | Description | Type | Default
| `ipaserver_setup_kra`| Install and configure a KRA on this server. | bool | false |
| `ipaserver_setup_adtrust` | Configure AD Trust capability. | bool | false |
| `ipaserver_netbios_name` | The NetBIOS name for the IPA domain. | str | None |
| `ipaserver_setup_dns` | Configure an integrated DNS server, create DNS zone specified by domain. | bool | true |
| `ipaserver_auto_forwarders` | Add DNS forwarders configured in /etc/resolv.conf to the list of forwarders used by IPA DNS. | bool | true |
| `ipaserver_no_forwarders` | Do not add any DNS forwarders. Root DNS servers will be used instead. | bool | false |
| `ipaserver_forwarders` | Add DNS forwarders to the DNS configuration. | list of strings | \[\] |
| `ipaserver_auto_reverse` | Try to resolve reverse records and reverse zones for server IP addresses. | bool | true |
| `ipaserver_random_serial_numbers` | Enable use of random serial numbers for certificates. | bool | true |

Also the following variables are always set:
```yaml
ipaserver_allow_zone_overlap: true
ipaserver_no_dnssec_validation: true
ipaserver_no_hbac_allow: true
```


Replica Variables
----------------

| Name | Description | Type | Default
| `ipareplica_setup_kra`| Install and configure a KRA on this server. | bool | false |
| `ipareplica_setup_adtrust` | Configure AD Trust capability. | bool | false |
| `ipareplica_netbios_name` | The NetBIOS name for the IPA domain. | str | None |
| `ipareplica_setup_dns` | Configure an integrated DNS server, create DNS zone specified by domain. | bool | false |
| `ipareplica_auto_forwarders` | Add DNS forwarders configured in /etc/resolv.conf to the list of forwarders used by IPA DNS. | bool | true |
| `ipareplica_no_forwarders` | Do not add any DNS forwarders. Root DNS servers will be used instead. | bool | false |
| `ipareplica_forwarders` | Add DNS forwarders to the DNS configuration. | list of strings | \[\] |
| `ipareplica_auto_reverse` | Try to resolve reverse records and reverse zones for server IP addresses. | bool | true |
| `ipareplica_random_serial_numbers` | Enable use of random serial numbers for certificates. | bool | true |


Client Variables
----------------

Currently, no variables can be configured for the `ipaclient` role.


Caveats
-------

As of this writing, there were some issues running Vagrant on `macos-latest`, and as it is transitioning from `macos-11` to `macos-12`, it was decided that the runner used will be pinned to `macos-12`.


<!-- References -->
[1]: https://github.com/actions/runner-images/issues/183
[2]: https://github.com/actions/runner-images/issues/433
[3]: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
55 changes: 55 additions & 0 deletions tests/multihost/Vagrantfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
config.vm.box = "fedora/38-cloud-base"

config.vm.provider :libvirt do |libvirt|
libvirt.qemu_use_session = false
libvirt.memory = 2500
end
config.vm.provider :virtualbox do |virtualbox|
virtualbox.memory = 2500
end

# Prevent SharedFoldersEnableSymlinksCreate errors
config.vm.synced_folder ".", "/vagrant", disabled: true
# boot timeout (in seconds).
config.vm.boot_timeout = 25 * 60

config.vm.define "server" do |server|
server.vm.hostname = "server.ipa.test"
server.vm.provision "shell",
inline: "hostnamectl set-hostname server.ipa.test"
server.vm.provision "shell",
inline: "echo $(hostname -I) server.ipa.test >> /etc/hosts"
server.vm.provision "shell",
inline: "dnf install --downloadonly -y freeipa-server python3-libselinux freeipa-server-dns freeipa-server-trust-ad firewalld"
end

config.vm.define "replica" do |replica|
replica.vm.hostname="replica"
replica.vm.provision "shell",
inline: "hostnamectl set-hostname rep-01.ipa.test"
replica.vm.provision "shell",
inline: "echo $(hostname -I) rep-01.ipa.test >> /etc/hosts"
replica.vm.provision "shell",
inline: "dnf install --downloadonly -y freeipa-server python3-libselinux freeipa-server-dns freeipa-server-trust-ad firewalld"
end

config.vm.define "client" do |client|
client.vm.hostname="client"
client.vm.provision "shell",
inline: "hostnamectl set-hostname cli-01.ipa.test"
client.vm.provision "shell",
inline: "dnf install --downloadonly -y freeipa-client python3-libselinux"
client.vm.provider :libvirt do |cmv|
cmv.memory = 768
end
client.vm.provider :virtualbox do |cmv|
cmv.memory = 768
end
end

end

18 changes: 18 additions & 0 deletions tests/multihost/ensure-reverse-dns.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
- name: Ensure IPA server has domain reverse zone and server PTR record.
hosts: ipaserver
become: no
gather_facts: no

tasks:
- name: Ensure reverse zone is present.
ipadnszone:
ipaadmin_password: "{{ ipa_admin_password }}"
name_from_ip: "{{ server_ip }}"

- name: Ensure server PTR record is set.
ipadnsrecord:
ipaadmin_password: "{{ ipa_admin_password }}"
zone_name: '{{ server_ip.split(".")[:-1][::-1] | join(".") }}.in-addr.arpa.'
name: '{{ server_ip.split(".")[-1] }}'
ptr_hostname: server.ipa.test.
9 changes: 9 additions & 0 deletions tests/multihost/get_ip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

echo "---"

while [ -n "${1}" ]
do
echo "${1}_ip: $(vagrant ssh -c "hostname -I" "${1}")"
shift
done
2 changes: 2 additions & 0 deletions tests/multihost/inventory/group_vars/all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
# This file will be replaced during test execution.
Loading