diff --git a/.circleci/config.yml b/.circleci/config.yml index 70ffe0a2..313259e2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - collection-testing: maxhoesel-ansible/ansible-collection-testing@0.4.0 + collection-testing: maxhoesel-ansible/ansible-collection-testing@0.5.3 filters: &semver-tagged tags: @@ -10,28 +10,69 @@ filters: &semver-tagged branches: ignore: /.*/ +executors: + pytest: + machine: + image: ubuntu-2204:current + resource_class: large + +jobs: + test: + parameters: + parallelism: + description: Number of parallel runners + type: integer + ansible-version: + description: Version of Ansible to use for testing + type: string + step-version: + type: enum + enum: + - latest + - compat + description: Version of smallstep to test + node-python-version: + description: Version of python to use for module tests + type: string + executor: pytest + parallelism: << parameters.parallelism >> + steps: + - when: + condition: + equal: ["<< parameters.step-version >>", "latest"] + steps: + - collection-testing/pytest: + pytest-args: > + --ansible-version << parameters.ansible-version >> + --step-cli-version "latest" + --step-ca-version "latest" + --node-python-version << parameters.node-python-version >> + - when: + condition: + equal: ["<< parameters.step-version >>", "compat"] + steps: + - collection-testing/pytest: + pytest-args: > + --ansible-version << parameters.ansible-version >> + --step-cli-version "0.24.0" + --step-ca-version "0.24.0" + --node-python-version << parameters.node-python-version >> + workflows: ci: jobs: + - test: + name: Test (ansible-<< matrix.ansible-version >>, step-<< matrix.step-version >>) + parallelism: 3 + matrix: + parameters: + ansible-version: ["2.15", "2.14"] + step-version: ["latest", "compat"] + node-python-version: ["3.6"] - collection-testing/pre-commit-lint: name: Lint - collection-testing/antsibull-docs: name: Generate Docs - - collection-testing/run-tox-environments: - name: Test Modules - match-environments: \-test\- - parallelism: 3 - resource-class: medium - retries: 1 - retry-delay: 60 - - collection-testing/run-tox-environments: - name: Test Roles - match-environments: roles - # number of scenarios * ansible versions to test - parallelism: 12 - resource-class: large - retries: 1 - retry-delay: 60 - collection-testing/publish-github: name: Publish Release to GitHub context: collection-publishing diff --git a/.config/molecule/config.yml b/.config/molecule/config.yml index 746d631c..6349fa54 100644 --- a/.config/molecule/config.yml +++ b/.config/molecule/config.yml @@ -3,20 +3,18 @@ dependency: name: galaxy driver: - name: podman + name: docker provisioner: name: ansible - env: {} - # Cannot enable pipelining for podman at this time: - # https://github.com/ansible-community/molecule-podman/issues/2 - #ANSIBLE_PIPELINING: false + env: + ANSIBLE_PIPELINING: true inventory: group_vars: all: - # Versions to use, passed in from Tox - step_cli_version: ${STEP_CLI_VERSION} - step_ca_version: ${STEP_CA_VERSION} + # Versions to use, can be passed in from Nox + step_cli_version: ${STEP_CLI_VERSION:-latest} + step_ca_version: ${STEP_CA_VERSION:-latest} scenario: test_sequence: diff --git a/.gitignore b/.gitignore index d5c4587b..4737a371 100644 --- a/.gitignore +++ b/.gitignore @@ -150,3 +150,8 @@ docs/ansible_collections/ # Don't commit ephermal integration config tests/integration/integration_config.yml +collections + +# CI files +results +split-tests diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a924b4fa..47105415 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,9 +9,8 @@ Note that by contributing to this collection, you agree with the code of conduct Prerequisites: -- A recent version of Python supported by `ansible-core` (see [here](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#control-node-requirements)) -- For role tests: `podman` 4 or newer set up as shown [below](#setting-up-podman) (note that Docker will *not* work for role tests!) -- For plugin tests: A recent version of Docker +- A recent version of Python supported by the current release of `ansible-core` (see [here](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#control-node-requirements)) +- Docker (for running Tests) Steps: @@ -50,78 +49,54 @@ Some general guidelines: - Keep the configuration for the user simple and try to provide sensible defaults where possible - Try to avoid using complex data structures as role variables/parameters, use simple values that can be composed easily instead. - Make sure to document any role variables in both the `README.md` and in the `meta/argument_specs.yml` file. - Te latter is used to generate role documentation programmatically. + The latter is used to generate role documentation programmatically. ## Testing Changes -We aim to test all of the components in this collection as thoroughly as possible. -We currently test all components using the following testing matrix: +We aim to test every part of this collection as thoroughly as reasonable to ensure correct behavior. +We use `pytest` to run all of our tests, both for plugins and roles. +If you set up the test environment as described in [the Getting Started guide](#getting-started), you should be able to see all available tests: -- Ansible version: The three most recent major releases (such as 6,7,8), with a compatible host Python -- Node Python: The minimum supported Python version (see `tox.ini`) -- Step-CLI/CA version: The most recent minor release corresponding to the collections version (e.g. collection version `0.24.X` is teated with `step-cli/ca` `0.24.y`) -- For each entry in this matrix, we test all roles on all of their supported platforms, as well as all modules/plugins +`pytest --co` -To make testing all these permutations easier, we use `tox`to manage test scenarios. -If you set up the test environment as described in [the Getting Started guide](#getting-started), you should be able to run `tox -l` from the collection root: +You can run these tests using `pytest` and limit execution to specific test with `pytest -k 'test_pattern'` (or just use your editors testing plugin). +Please note that running the full test suite executes all molecule scenarios and may take **up to an hour** to complete. -This should print a list of test environments (scenarios) that you can run. -To run a specific environment, just use `tox -e {environment}`. -You can also use substitution syntax to run multiple environments at once: +### Testing different App Versions -```bash -# Will run the py3-ansible7-roles-step_cli environment -tox -e py3-ansible7-roles-step_cli +When you run the collection tests using `ptytest`, they are executed with the current stable Ansible version in `requirements.txt` and the latest smallstep tools. +To ensure that this collection remains backwards-compatible, we also test against older versions of both ansible and the smallstep tools. +Our testing Matrix currently looks like this: -# Will run XXX-roles-step_cli environment with ansible versions 6,7 and 8 -# Note the single quotes around the string! -tox -e 'py3-ansible{6,7,8}-roles-step_cli' -``` - -### Plugins (and Modules) +| Component | Module Tests | Role Tests | Versions | +|-----------|--------------|------------|----------| +| `ansible-core` | ✅ | ✅ | Three most recent releases (e.g. `2.13`, `2.14`, `2.15`) | +| Node Python Version | ✅ | ❌ | Collection-supported Python version (see [README](./README.md)) +| `step-ca`, `step-cli` | ✅ | ✅ | `latest` and the minimum collection-supported version (see [README](./README.md)) -Modules (and plugins in general) are verified using `ansible-test`, specifically sanity, unit (TBD) and integration tests, all run from tox. -Since many plugins in this collection need access to a step-ca server, the `tox` environments spin up additional docker containers as needed - -see [`tox.ini`](./tox.ini) and the `docker-compose.yml` files in `tests/{integration/sanity}` for details. +All possible permutations are automatically tested in CI. +You can change the tested versions locally by supplying additional arguments to `pytest`: -You should always run the plugin tests after making changes to one (sanity, unit (TBD), integration): - -```bash -tox -e 'py3-ansible215-test-{sanity,integration,#add other environments here}' ``` - -### Roles - -We use the `tox-ansible` plugin (v1) to integrate molecule scenarios into tox. -You can run these scenarios using `tox -e`, just like for module tests. - -Molecule itself runs the subject role against several containers to verify its functionality across target systems. -Since some roles involve the management of systemd services, we need a container runtime with good systemd support, -something which `docker` sadly doesn't offer on [modern linux distros](https://gist.github.com/pinkeen/bba0a6790fec96d6c8de84bd824ad933). - -Instead, we use `podman`, a daemonless, rootless container runtime developed by RedHat to be (mostly) compatible to docker, but with better support for certain features such as systemd. -See below for setup instructions. -Once podman is installed and running, you can use `tox` to run the molecule scenarios. - -#### Setting up Podman - -1. Ensure that you have the following packages installed: - - `podman` version 4+ (as it comes with the new netvark networking stack) - - `aardvark-dns`, a plugin for netvark which provides DNS between containers in the same network - - **NOTE:** If you previously used an older (`<=3.x`) version of `podman`, you will have to migrate to the new networking stack fist. This can be done with `podman system reset` -2. Ensure that your user has a subuid/subguid configuration associated with them so that you can run rootless containers - - Check the `/etc/subuid` and `/etc/subgid` files for entries corresponding to your username. - - If there is nothing, you can add them like so: `sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 ` (make sure that the range is not already taken by another user in `/etc/subuid`/`/etc/subgid`). -3. Once you have applied your changes, run `podman system migrate` to force `podman` to pick up the new configuration. - -That's it! Podman should now be working! To test it, you can run a container just like with docker: `podman run --rm -it ubuntu bash` +$ pytest --help +# truncated output +Custom options: + --ansible-version=ANSIBLE_VERSION + Version of ansible to use for tests, in the format '2.xx'. Default: see requirements.txt + --step-cli-version=STEP_CLI_VERSION + Version of step-cli to use for tests, either 'latest' (default) or a version ('0.24.0') + --step-ca-version=STEP_CA_VERSION + Version of step-ca to use for tests, either 'latest' (default) or a version ('0.24.0') + --node-python-version=NODE_PYTHON_VERSION + Python version to test Ansible modules with, in the format '3.x'. Default: '3.6' +``` ## Writing Tests Any new new component or change to an existing one should be covered by tests to ensure that the code works, and that it keeps working into the future. This section will help you in adding your own tests to this collection. -#### Plugins +### Plugins Unit tests are currently not used in this collection, this section will be filled once the need for them arises. @@ -136,30 +111,28 @@ tasks/ main.yml ``` -Since many plugins need to connect to a CA to verify functionality, you can set up your target to connect to either a remote (network) or a local CA: +Since many plugins need to connect to a CA to verify functionality, `pytest` will automatically start a CA container that you can connect to. +You can configure your target to use this CA like so: ```yaml # in meta/main.yml: dependencies: - # Setup the target role for accessing a CA over the network, this is the default - setup_remote_ca - # Setup the target role for accessing a CA that is installed locally. - # This is needed for certain plugins/modules such as step_ca_provisioner. - # Mutually exclusive with setup_remote_ca - #- setup_local_ca ``` +Check out the [`integration_config_remote.yml` template](./tests/integration/integration_config_remote.yml.j2) for all available variables. -Your target will then be set up for accessing the selected CA. -For more details, see the integration config templates for the [remote]() and the [local]() CA. +--- -```yaml -# in tasks/main.yml: -- name: Get a certificate from the remote CA - maxhoesel.smallstep.step_ca_certificate: - # parameters go here -``` +**Note on local-ca tests** + +A few plugins (such as `step_ca_provisioner`) need to be run on the same host as the CA. +For this purpose, a second test case (`integration_local`) is run on a separate container prepared to run both `step-ca` and Ansible (see the Dockerfile [here](./tests/integration/docker/local-ca/)). +Only tasks tagged with `local-ca` are run on this test container. +See the [`step_ca_provisioner`](./tests/integration/targets/step_ca_provisioner/) target for more details -#### Roles +--- + +### Roles There are tons of good guides online for how to write tests using molecule. Alternatively, you can always look at the existing molecule scenarios in this collection @@ -175,7 +148,6 @@ some_role/ converge.yml molecule.yml prepare.yml - requirements.txt # --> symlink to /tests/roles/requirements.txt verify.yml another-scenario/ ... @@ -183,9 +155,6 @@ some_role/ ... ``` -The `requirements.txt` symlink is used by `tox-ansible` when running tests via `tox` to install a specific, known-good version of `molecule` and the `molecule-podman` driver. -That way, all roles and scenarios in this collection can use the same version of `molecule`. - The [root molecule config](./.config/molecule/config.yml) contains the basic settings for molecule, such as driver setup and the step utility versions. In addition, your roles molecule scenario must define a set of platforms to test on, as well as any inventory configuration that you may need. To get started you can copy the `molecule.yml` configuration from an existing role, then adjust it to suit your needs. @@ -199,21 +168,20 @@ The CI also builds the docs to ensure they don't break silently. ## Maintainer information -### Updating Tested Versions +### Raising minimum supported step versions + +1. Change the versions in [`plugins/module_utils/constants.py`](./plugins/module_utils/constants.py) +2. Update the versions in the [CI config](./.circleci/config.yml) +3. Update the table in `README.md` + +### Bumping supported ansible-core versions -- Smallstep CLI/CA and Node Python: Bump the values in `tox.ini` (`consts` section) -- ansible-core (for plugins): Add the new core version to the following places in `tox.ini`: - - The `envlist` in `tox.ini` - - each `testenv:xxx` section header that deals with plugin tests - - Set the correct environment variable in the main `testenv` section -- ansible (for roles): Change the version string in the `ansible` section in `tox.ini` +1. Update the versions in the [CI config](./.circleci/config.yml) ### Versioning and Releases -- This project uses sematic versioning. the collection version stays in sync with the `step-cli`` utility version to ensure compatibility. - This means that any breaking changes can only be shipped when updates to the `step-cli` utility are released. - Version numbers and releases/changelogs are automatically generated using [release-drafter](https://github.com/release-drafter/release-drafter), utilizing pull request labels. +- Releases are automatically drafted by `release-drafter`, with a changelog generated from PR labels - When merging a pull request, make sure to select an appropriate label (pr-bugfix, pr-feature, etc.). - Release-drafter will automatically update the draft release changelog and the galaxy.yml version will be bumped if needed. -- Once a draft release is actually published, collection packages will be added to the release and ansible-galaxy automatically. -- If you need to manually bump the collection version, run the `update-version` script and adjust the test versions if required. + Release-drafter will automatically update the draft release changelog and a PR will be opened with bumped collection versions. +- Once a draft release is actually published, collection packages will be published to the release and ansible-galaxy automatically. +- If you need to manually bump the collection version, run the `update-version` script diff --git a/README.md b/README.md index 096e746c..e18c9ca6 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ and the [CLI tool](https://github.com/smallstep/cli). Possible uses for this col ### Dependencies -- A recent release of Ansible. This collection is tested against the 3 most recent Ansible releases. +- A recent release of Ansible. This collection is tested against the 2 most recent Ansible releases. Older versions might still work, but are not supported - Python 3.6 or newer on the target nodes diff --git a/TODO b/TODO new file mode 100644 index 00000000..c24015b5 --- /dev/null +++ b/TODO @@ -0,0 +1,10 @@ +pytest-ansible, get familiar with test syntax +1. fixture to set up a dev container with step installed (can be dockerfiled) +2. fixture to set up a ca (per-test maybe?) +3. test uses ansible inventory with container +4. cleanup? + +CI, get nox scenarios (or pytest? circleci integration? coverage?) + +ansible-test local-ca, ensure python version matches +actually check node python in general diff --git a/galaxy.yml b/galaxy.yml index 76255f44..5d0de528 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -18,7 +18,6 @@ build_ignore: - .readthedocs.yaml - pyproject.toml - requirements.txt -- tox.ini - '**/requirements.txt' dependencies: community.general: '>=1.0.0' diff --git a/pyproject.toml b/pyproject.toml index 7e33c326..5d0f9273 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,20 +4,24 @@ ignore = "E402" # Pylint settings [tool.pylint.'NESSAGES CONTROL'] -disable=[ +disable = [ "logging-fstring-interpolation", # See https://github.com/PyCQA/pylint/issues/2354 "missing-module-docstring", "missing-class-docstring", - "missing-function-docstring", # also triggers on abstract functions - "consider-using-enumerate", # not for simple loops + "missing-function-docstring", # also triggers on abstract functions + "consider-using-enumerate", # not for simple loops "consider-using-dict-items", "no-else-return", "invalid-name", "too-many-boolean-expressions", "too-few-public-methods", - 'wrong-import-position', # Ansible module best practices + 'wrong-import-position', # Ansible module best practices "I", ] [tool.pylint.'FORMAT'] -max-line-length=120 +max-line-length = 120 + +[tool.pytest.ini_options] +testpaths = ["tests"] +filterwarnings = ['ignore:AnsibleCollectionFinder has already been configured'] diff --git a/requirements.txt b/requirements.txt index 2af2757c..0152ebe5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,14 +7,15 @@ pylint==3.0.1 autopep8==2.0.4 pre-commit==3.4.0 -# Test scenario runner -tox==3.28.0 +# Testing libraries +pytest==7.4.2 +pytest-virtualenv==1.7.0 +docker==6.1.3 # Utility packages used in scripts pyyaml==6.0.1 packaging==23.2 -# Also include a version of ansible-core for IDE hints and such. -# Note that this version is independent of the one used in tests, see tox.ini -# and /tests +# Also include a version of ansible-core for IDE hints +# and as the default version used in tests ansible-core==2.15.5 diff --git a/roles/step_acme_cert/molecule/default/molecule.yml b/roles/step_acme_cert/molecule/default/molecule.yml index 816b849c..5ad29f75 100644 --- a/roles/step_acme_cert/molecule/default/molecule.yml +++ b/roles/step_acme_cert/molecule/default/molecule.yml @@ -10,87 +10,120 @@ platforms: env: DOCKER_STEPCA_INIT_NAME: "Molecule_Bootstrap_CA" DOCKER_STEPCA_INIT_DNS_NAMES: "step-ca,localhost" - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-ubuntu-22 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu2204-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-ubuntu-20 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu2004-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-ubuntu-18 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu1804-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-debian-11 groups: - clients - debian image: "docker.io/geerlingguy/docker-debian11-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-debian-10 groups: - clients - debian image: "docker.io/geerlingguy/docker-debian10-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-rockylinux-9 groups: - clients - rockylinux image: "docker.io/geerlingguy/docker-rockylinux9-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-rockylinux-8 groups: - clients - rockylinux image: "docker.io/geerlingguy/docker-rockylinux8-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-fedora-36 groups: - clients - fedora image: "docker.io/geerlingguy/docker-fedora36-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert provisioner: playbooks: diff --git a/roles/step_acme_cert/molecule/default/prepare.yml b/roles/step_acme_cert/molecule/default/prepare.yml index 3fb33f59..2975a769 100644 --- a/roles/step_acme_cert/molecule/default/prepare.yml +++ b/roles/step_acme_cert/molecule/default/prepare.yml @@ -15,18 +15,18 @@ tasks: # Somewhat hacky way to customize the container image, but we make do with what we have - name: Add ACME provisioner # noqa no-changed-when - ansible.builtin.command: "podman exec step-ca step ca provisioner add {{ step_acme_cert_ca_provisioner }} --type=ACME" + ansible.builtin.command: "docker exec step-ca step ca provisioner add {{ step_acme_cert_ca_provisioner }} --type=ACME" - name: Get CA PID - ansible.builtin.command: podman exec step-ca pgrep -f step-ca + ansible.builtin.command: docker exec step-ca pgrep -f step-ca register: _step_ca_pid changed_when: false - name: Reload step-ca # noqa no-changed-when - ansible.builtin.command: "podman exec step-ca kill -1 {{ _step_ca_pid.stdout }}" + ansible.builtin.command: "docker exec step-ca kill -1 {{ _step_ca_pid.stdout }}" - hosts: clients tasks: - name: Get CA fingerprint - ansible.builtin.command: podman exec step-ca step certificate fingerprint certs/root_ca.crt + ansible.builtin.command: docker exec step-ca step certificate fingerprint certs/root_ca.crt register: _ca_fingerprint changed_when: false check_mode: false diff --git a/roles/step_acme_cert/molecule/default/requirements.txt b/roles/step_acme_cert/molecule/default/requirements.txt deleted file mode 120000 index 0bd8d018..00000000 --- a/roles/step_acme_cert/molecule/default/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../tests/roles/requirements.txt \ No newline at end of file diff --git a/roles/step_acme_cert/molecule/non_root/molecule.yml b/roles/step_acme_cert/molecule/non_root/molecule.yml index 36a8335d..5223f4f8 100644 --- a/roles/step_acme_cert/molecule/non_root/molecule.yml +++ b/roles/step_acme_cert/molecule/non_root/molecule.yml @@ -10,87 +10,120 @@ platforms: env: DOCKER_STEPCA_INIT_NAME: "Molecule_Bootstrap_CA" DOCKER_STEPCA_INIT_DNS_NAMES: "step-ca,localhost" - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-ubuntu-22 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu2204-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-ubuntu-20 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu2004-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-ubuntu-18 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu1804-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-debian-11 groups: - clients - debian image: "docker.io/geerlingguy/docker-debian11-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-debian-10 groups: - clients - debian image: "docker.io/geerlingguy/docker-debian10-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-rockylinux-9 groups: - clients - rockylinux image: "docker.io/geerlingguy/docker-rockylinux9-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-rockylinux-8 groups: - clients - rockylinux image: "docker.io/geerlingguy/docker-rockylinux8-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert - name: step-host-fedora-36 groups: - clients - fedora image: "docker.io/geerlingguy/docker-fedora36-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-acme-cert + networks: + - name: molecule-step-acme-cert provisioner: playbooks: diff --git a/roles/step_acme_cert/molecule/non_root/prepare.yml b/roles/step_acme_cert/molecule/non_root/prepare.yml index 62342a30..00046e14 100644 --- a/roles/step_acme_cert/molecule/non_root/prepare.yml +++ b/roles/step_acme_cert/molecule/non_root/prepare.yml @@ -15,13 +15,13 @@ tasks: # Somewhat hacky way to customize the container image, but we make do with what we have - name: Add ACME provisioner # noqa no-changed-when - ansible.builtin.command: "podman exec step-ca step ca provisioner add {{ step_acme_cert_ca_provisioner }} --type=ACME" + ansible.builtin.command: "docker exec step-ca step ca provisioner add {{ step_acme_cert_ca_provisioner }} --type=ACME" - name: Get CA PID - ansible.builtin.command: podman exec step-ca pgrep -f step-ca + ansible.builtin.command: docker exec step-ca pgrep -f step-ca register: _step_ca_pid changed_when: false - name: Reload step-ca # noqa no-changed-when - ansible.builtin.command: "podman exec step-ca kill -1 {{ _step_ca_pid.stdout }}" + ansible.builtin.command: "docker exec step-ca kill -1 {{ _step_ca_pid.stdout }}" - hosts: clients vars: @@ -51,7 +51,7 @@ mode: "750" - name: Get CA fingerprint - ansible.builtin.command: podman exec step-ca step certificate fingerprint certs/root_ca.crt + ansible.builtin.command: docker exec step-ca step certificate fingerprint certs/root_ca.crt register: _ca_fingerprint changed_when: false check_mode: false diff --git a/roles/step_acme_cert/molecule/non_root/requirements.txt b/roles/step_acme_cert/molecule/non_root/requirements.txt deleted file mode 120000 index 0bd8d018..00000000 --- a/roles/step_acme_cert/molecule/non_root/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../tests/roles/requirements.txt \ No newline at end of file diff --git a/roles/step_bootstrap_host/molecule/converge.yml b/roles/step_bootstrap_host/molecule/converge.yml index 5c2ce5b2..32c9759d 100644 --- a/roles/step_bootstrap_host/molecule/converge.yml +++ b/roles/step_bootstrap_host/molecule/converge.yml @@ -4,7 +4,7 @@ tasks: # Slightly hacky way to get the CA fingerprint. We could also look at logs but i prefer this method - name: Get CA fingerprint - ansible.builtin.command: podman exec step-ca step certificate fingerprint certs/root_ca.crt + ansible.builtin.command: docker exec step-ca step certificate fingerprint certs/root_ca.crt register: _ca_fingerprint changed_when: false check_mode: false diff --git a/roles/step_bootstrap_host/molecule/default/molecule.yml b/roles/step_bootstrap_host/molecule/default/molecule.yml index 765077d4..5c10f979 100644 --- a/roles/step_bootstrap_host/molecule/default/molecule.yml +++ b/roles/step_bootstrap_host/molecule/default/molecule.yml @@ -11,87 +11,120 @@ platforms: env: DOCKER_STEPCA_INIT_NAME: "Molecule_Bootstrap_CA" DOCKER_STEPCA_INIT_DNS_NAMES: "step-ca,localhost" - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-ubuntu-22 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu2204-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-ubuntu-20 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu2004-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-ubuntu-18 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu1804-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-debian-11 groups: - clients - debian image: "docker.io/geerlingguy/docker-debian11-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-debian-10 groups: - clients - debian image: "docker.io/geerlingguy/docker-debian10-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-rockylinux-9 groups: - clients - rockylinux image: "docker.io/geerlingguy/docker-rockylinux9-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-rockylinux-8 groups: - clients - rockylinux image: "docker.io/geerlingguy/docker-rockylinux8-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-fedora-36 groups: - clients - fedora image: "docker.io/geerlingguy/docker-fedora36-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host provisioner: playbooks: diff --git a/roles/step_bootstrap_host/molecule/default/requirements.txt b/roles/step_bootstrap_host/molecule/default/requirements.txt deleted file mode 120000 index 0bd8d018..00000000 --- a/roles/step_bootstrap_host/molecule/default/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../tests/roles/requirements.txt \ No newline at end of file diff --git a/roles/step_bootstrap_host/molecule/multi_user/molecule.yml b/roles/step_bootstrap_host/molecule/multi_user/molecule.yml index 0b5c4cdd..a31b76f0 100644 --- a/roles/step_bootstrap_host/molecule/multi_user/molecule.yml +++ b/roles/step_bootstrap_host/molecule/multi_user/molecule.yml @@ -11,87 +11,120 @@ platforms: env: DOCKER_STEPCA_INIT_NAME: "Molecule_Bootstrap_CA" DOCKER_STEPCA_INIT_DNS_NAMES: "step-ca,localhost" - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-ubuntu-22 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu2204-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-ubuntu-20 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu2004-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-ubuntu-18 groups: - clients - ubuntu image: "docker.io/geerlingguy/docker-ubuntu1804-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-debian-11 groups: - clients - debian image: "docker.io/geerlingguy/docker-debian11-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-debian-10 groups: - clients - debian image: "docker.io/geerlingguy/docker-debian10-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-rockylinux-9 groups: - clients - rockylinux image: "docker.io/geerlingguy/docker-rockylinux9-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-rockylinux-8 groups: - clients - rockylinux image: "docker.io/geerlingguy/docker-rockylinux8-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host - name: step-host-fedora-36 groups: - clients - fedora image: "docker.io/geerlingguy/docker-fedora36-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true - network: molecule-step-bootstrap-host + networks: + - name: molecule-step-bootstrap-host provisioner: playbooks: diff --git a/roles/step_bootstrap_host/molecule/multi_user/requirements.txt b/roles/step_bootstrap_host/molecule/multi_user/requirements.txt deleted file mode 120000 index 0bd8d018..00000000 --- a/roles/step_bootstrap_host/molecule/multi_user/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../tests/roles/requirements.txt \ No newline at end of file diff --git a/roles/step_ca/molecule/default/molecule.yml b/roles/step_ca/molecule/default/molecule.yml index fba82461..8c8a143e 100644 --- a/roles/step_ca/molecule/default/molecule.yml +++ b/roles/step_ca/molecule/default/molecule.yml @@ -4,7 +4,10 @@ platforms: - ubuntu - ca image: "docker.io/geerlingguy/docker-ubuntu2204-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true @@ -13,7 +16,10 @@ platforms: - ubuntu - ca image: "docker.io/geerlingguy/docker-ubuntu2004-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true @@ -22,7 +28,10 @@ platforms: - ubuntu - ca image: "docker.io/geerlingguy/docker-ubuntu1804-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true @@ -31,7 +40,10 @@ platforms: - debian - ca image: "docker.io/geerlingguy/docker-debian11-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true @@ -40,7 +52,10 @@ platforms: - debian - ca image: "docker.io/geerlingguy/docker-debian10-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true @@ -49,7 +64,10 @@ platforms: - rockylinux - ca image: "docker.io/geerlingguy/docker-rockylinux9-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true @@ -58,7 +76,10 @@ platforms: - rockylinux - ca image: "docker.io/geerlingguy/docker-rockylinux8-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true @@ -67,7 +88,10 @@ platforms: - fedora - ca image: "docker.io/geerlingguy/docker-fedora36-ansible" - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true override_command: false pre_build_image: true diff --git a/roles/step_ca/molecule/default/requirements.txt b/roles/step_ca/molecule/default/requirements.txt deleted file mode 120000 index 0bd8d018..00000000 --- a/roles/step_ca/molecule/default/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../tests/roles/requirements.txt \ No newline at end of file diff --git a/roles/step_cli/README.md b/roles/step_cli/README.md index c484ad64..fd1709ba 100644 --- a/roles/step_cli/README.md +++ b/roles/step_cli/README.md @@ -9,7 +9,7 @@ This role is used by `step_bootstrap_host` and `step_ca`, but can also be used s - The following distributions are currently supported: - Ubuntu 18.04 LTS or newer - Debian 10 or newer - - Fedora 36 or newer + - Fedora 38 or newer - A CentOS-compatible distribution like RockyLinux/AlmaLinux 8 or newer. RockyLinux is used for testing - Supported architectures: amd64, arm64 - This role requires root access. Make sure to run this role with `become: yes` or equivalent diff --git a/roles/step_cli/molecule/default/molecule.yml b/roles/step_cli/molecule/default/molecule.yml index 48192f59..adde61c1 100644 --- a/roles/step_cli/molecule/default/molecule.yml +++ b/roles/step_cli/molecule/default/molecule.yml @@ -5,7 +5,10 @@ platforms: - ubuntu override_command: false pre_build_image: true - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true - name: step-cli-ubuntu-20 image: "docker.io/geerlingguy/docker-ubuntu2004-ansible" @@ -13,7 +16,10 @@ platforms: - ubuntu override_command: false pre_build_image: true - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true - name: step-cli-ubuntu-18 image: "docker.io/geerlingguy/docker-ubuntu1804-ansible" @@ -21,7 +27,10 @@ platforms: - ubuntu override_command: false pre_build_image: true - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true - name: step-cli-debian-11 image: "docker.io/geerlingguy/docker-debian11-ansible" @@ -29,7 +38,10 @@ platforms: - debian override_command: false pre_build_image: true - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true - name: step-cli-debian-10 image: "docker.io/geerlingguy/docker-debian10-ansible" @@ -37,7 +49,10 @@ platforms: - debian override_command: false pre_build_image: true - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true - name: step-cli-rockylinux-9 image: "docker.io/geerlingguy/docker-rockylinux9-ansible" @@ -45,7 +60,10 @@ platforms: - rockylinux override_command: false pre_build_image: true - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true - name: step-cli-rockylinux-8 image: "docker.io/geerlingguy/docker-rockylinux8-ansible" @@ -53,7 +71,10 @@ platforms: - rockylinux override_command: false pre_build_image: true - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true - name: step-cli-fedora-36 image: "docker.io/geerlingguy/docker-fedora36-ansible" @@ -61,7 +82,10 @@ platforms: - fedora override_command: false pre_build_image: true - systemd: always + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true provisioner: inventory: diff --git a/roles/step_cli/molecule/default/requirements.txt b/roles/step_cli/molecule/default/requirements.txt deleted file mode 120000 index 0bd8d018..00000000 --- a/roles/step_cli/molecule/default/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../tests/roles/requirements.txt \ No newline at end of file diff --git a/scripts/setup.sh b/scripts/setup.sh index a1b3cd15..bc12a9df 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -11,7 +11,7 @@ source .venv/bin/activate printf "Installing development requirements..." python3 -m pip install --upgrade pip --quiet python3 -m pip install --quiet -r requirements.txt --upgrade -# Also install molecule if we need to debug something manually +# Also install the scenario requirements so we can run them directly python3 -m pip install --quiet -r tests/roles/requirements.txt --upgrade printf "OK\n" @@ -19,10 +19,6 @@ printf "Installing pre-commit hook..." pre-commit install > /dev/null printf "OK\n" -printf "Initializing tox..." -tox -l > /dev/null -printf "OK\n" - printf "Development venv initialized!\n" printf "To activate it, run:\n\n" printf "source .venv/bin/activate\n" diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..fe4ffa72 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,83 @@ +from dataclasses import dataclass +import os +from pathlib import Path +import subprocess + +from packaging import version +import pkg_resources +import pytest +from pytest_virtualenv import VirtualEnv +import yaml + +with open("galaxy.yml", encoding="utf-8") as f: + GALAXY_YML = yaml.safe_load(f) + + +class TestEnv(): + def __init__(self, virtualenv: VirtualEnv) -> None: + self.virtualenv = virtualenv + + def run(self, *args, **kwargs): + # Combine any passed in env with the virtualenv to ensure proper PATH + if "env" in kwargs: + kwargs["env"] = {**kwargs["env"], **self.virtualenv.env} + self.virtualenv.run(*args, **kwargs) + + +def get_ansible_version(): + base_version = version.parse(pkg_resources.get_distribution("ansible-core").version) + return f"{base_version.major}.{base_version.minor}" + + +def pytest_addoption(parser): + parser.addoption("--ansible-version", action="store", default=get_ansible_version(), + help="Version of ansible to use for tests, in the format '2.xx'. Default: see requirements.txt") + parser.addoption("--step-cli-version", action="store", default="latest", + help="Version of step-cli to use for tests, either 'latest' (default) or a version ('0.24.0')") + parser.addoption("--step-ca-version", action="store", default="latest", + help="Version of step-ca to use for tests, either 'latest' (default) or a version ('0.24.0')") + parser.addoption("--node-python-version", action="store", default="3.6", + help="Python version to test Ansible modules with, in the format '3.x'. Default: '3.6'") + + +@pytest.fixture(scope="session") +def collection_path(tmp_path_factory) -> Path: + build_path: Path = tmp_path_factory.mktemp("build") + collection_file = build_path / f"{GALAXY_YML['namespace']}-{GALAXY_YML['name']}-{GALAXY_YML['version']}.tar.gz" + subprocess.run( + ["ansible-galaxy", "collection", "build", "--output-path", build_path], + check=True, + ) + + install_path: Path = tmp_path_factory.mktemp("collections") + env = os.environ.copy() + env["ANSIBLE_COLLECTIONS_PATH"] = install_path.resolve().as_posix() + subprocess.run( + ["ansible-galaxy", "collection", "install", collection_file], + env=env, check=True, + ) + return install_path + + +@dataclass +class TestVersions: + ansible_version: str + step_cli_version: str + step_ca_version: str + node_python_version: str + + @property + def ansible_version_pip(self): + major, minor = self.ansible_version.split(".") + next_minor = int(minor) + 1 + return f"ansible-core>={self.ansible_version},<{major}.{next_minor}" + + +@pytest.fixture(scope="session") +def test_versions(request) -> TestVersions: + return TestVersions( + request.config.getoption("--ansible-version"), + request.config.getoption("--step-cli-version"), + request.config.getoption("--step-ca-version"), + request.config.getoption("--node-python-version") + ) diff --git a/tests/integration/docker-compose-local.yml b/tests/integration/docker-compose-local.yml deleted file mode 100644 index 49f57c25..00000000 --- a/tests/integration/docker-compose-local.yml +++ /dev/null @@ -1,36 +0,0 @@ -version: "3" - -services: - # Test modules that require a ca configured on the executing node (local) - test-runner-local: - image: quay.io/maxhoesel-ansible/ansible-test-collection-runner:${ANSIBLE_VERSION} - volumes: - # Pass through the docker socket - - /var/run/docker.sock:/var/run/docker.sock - # and our collection - - ../../:/collection - environment: - # versions - STEP_CA_VERSION: ${STEP_CA_VERSION} - STEP_CLI_VERSION: ${STEP_CLI_VERSION} - # local-ca settings - STEP_LOCAL_CA_USER: step - STEP_LOCAL_CLI_BINARY: step - STEP_LOCAL_STEPPATH: /home/step # hardcoded in the local-ca Dockerfile - # render the integration config template - PRE_COMMANDS: "/collection/scripts/render_template.sh \ - /collection/tests/integration/integration_config.yml.template-local > /collection/tests/integration/integration_config.yml" - ANSIBLE_TEST_ARGS: "integration --color -v \ - --controller docker:default --target docker:step-ansible-local-ca:ca${STEP_CA_VERSION},python=${NODE_PYTHON_VERSION}@/usr/bin/python${NODE_PYTHON_VERSION} \ - --tags local-ca" - - # build local-ca container so that we can use it for tests. - # We don't actually use the started container, we just need the built image in the local cache - local-ca: - build: - context: ./docker/local-ca - tags: - - step-ansible-local-ca:ca${STEP_CA_VERSION} - args: - STEP_CA_VERSION: ${STEP_CA_VERSION} - ANSIBLE_VERSION: ${ANSIBLE_VERSION} diff --git a/tests/integration/docker-compose-remote.yml b/tests/integration/docker-compose-remote.yml deleted file mode 100644 index dd5166b0..00000000 --- a/tests/integration/docker-compose-remote.yml +++ /dev/null @@ -1,44 +0,0 @@ -version: "3" - -services: - # Test modules that do not require a ca configured on the executing node (remote) - test-runner-remote: - image: quay.io/maxhoesel-ansible/ansible-test-collection-runner:${ANSIBLE_VERSION} - volumes: - # Pass through the docker socket - - /var/run/docker.sock:/var/run/docker.sock - # and our collection - - ../../:/collection - environment: - # versions - STEP_CA_VERSION: ${STEP_CA_VERSION} - STEP_CLI_VERSION: ${STEP_CLI_VERSION} - # remote ca settings - STEP_REMOTE_CA_URL: https://remote-ca:9000 - STEP_REMOTE_CA_PROVISIONER_NAME: ansible - STEP_REMOTE_CA_PROVISIONER_PASSWORD: ansible-module-tests-pw - # render the integration config template - PRE_COMMANDS: "/collection/scripts/render_template.sh \ - /collection/tests/integration/integration_config.yml.template-remote > /collection/tests/integration/integration_config.yml" - ANSIBLE_TEST_ARGS: "integration --color -v \ - --controller docker:default --target docker:default,python=${NODE_PYTHON_VERSION} \ - --docker-network ansible-collection-smallstep-integration-ca \ - --skip-tags local-ca" - depends_on: - remote-ca: - condition: service_healthy - - remote-ca: - image: docker.io/smallstep/step-ca:${STEP_CA_VERSION} - environment: - DOCKER_STEPCA_INIT_NAME: Ansible-Test - DOCKER_STEPCA_INIT_DNS_NAMES: localhost,remote-ca - DOCKER_STEPCA_INIT_PROVISIONER_NAME: ansible - DOCKER_STEPCA_INIT_PASSWORD: ansible-module-tests-pw - networks: - - ca - -networks: - ca: - name: ansible-collection-smallstep-integration-ca - driver: bridge diff --git a/tests/integration/docker/local-ca/Dockerfile b/tests/integration/docker/local-ca/Dockerfile index 702dad05..3bd32352 100644 --- a/tests/integration/docker/local-ca/Dockerfile +++ b/tests/integration/docker/local-ca/Dockerfile @@ -3,9 +3,9 @@ ARG ANSIBLE_VERSION FROM docker.io/smallstep/step-ca:${STEP_CA_VERSION} as ca -# This is only a target, the exact ansible version does not matter -# as long as that image has our required python lib -FROM quay.io/ansible/default-test-container:stable-2.15 +# The stable test containers already come with all required python versions preinstalled +# in /usr/local/bin/ (pyython3.6, 3.7, etc) +FROM quay.io/ansible/default-test-container:stable-${ANSIBLE_VERSION} # Get binaries from step-ca container COPY --from=ca /usr/local/bin/step /usr/local/bin/step diff --git a/tests/integration/docker/local-ca/README.md b/tests/integration/docker/local-ca/README.md index 96da76bb..bed76671 100644 --- a/tests/integration/docker/local-ca/README.md +++ b/tests/integration/docker/local-ca/README.md @@ -1,7 +1,4 @@ -To test module functionality, we need a ready-to-go docker image serving the smallstep CA to our target container in a docker network. -For most tests, we can simply use the upstream image for this (see the test-modules-integration script). +Some modules, such as `step_ca_provisioner` need to be run on the same host as the `step-ca` server. +To enable this in ansible integration tests, we use a custom Docker image based on the official ansible test image that also runs `step-ca`. -However, there are modules that need direct access to the CA resources (like, on the same host) and the upstream image does not work as an ansible target by default (big surprise). - -The Dockerfile in this directory modifies the upstream image to support Ansible connections made from ansible-test, so that our local-only targets can be run on the container directly. -Note that this container is launched by ansible-test, so a lot of typical `docker run` options aren't available, hence the hardcoded values in the Dockerfile. +This dockerfile is built automatically by pytest when module tests are executed diff --git a/tests/integration/integration_config.yml.template-local b/tests/integration/integration_config.yml.template-local deleted file mode 100644 index 9941c48a..00000000 --- a/tests/integration/integration_config.yml.template-local +++ /dev/null @@ -1,14 +0,0 @@ ---- -# Configuration for the smallstep module tests. -# This template is rendered by render_config.sh, called from tox -# You can use these variable names in your module integration tests. - -# Currently tested versions -ca_version: ${STEP_CA_VERSION} -cli_version: ${STEP_CLI_VERSION} - -# Locally reachable CA settings - this is needed by modules like step_ca_provisioner that need FS access -# Don't use these unless your target is tagged with "local-ca" and you use "setup_local_ca" -ca_user: ${STEP_LOCAL_CA_USER} -ca_path: ${STEP_LOCAL_STEPPATH} -cli_binary: ${STEP_LOCAL_CLI_BINARY} diff --git a/tests/integration/integration_config.yml.template-remote b/tests/integration/integration_config.yml.template-remote deleted file mode 100644 index 25d6664c..00000000 --- a/tests/integration/integration_config.yml.template-remote +++ /dev/null @@ -1,16 +0,0 @@ ---- -# Configuration for the smallstep module tests. -# This template is rendered by render_config.sh, called from tox -# You can use these variable names in your module integration tests. - -# Remote CA access options - this could be a VM somewhere or a local container -# Use these variables for normal module integration tests -ca_url: ${STEP_REMOTE_CA_URL} -# Use this provisioner to create certs/tokens/etc. The password file is already present after calling "setup_remote_provisioner" -ca_provisioner: ${STEP_REMOTE_CA_PROVISIONER_NAME} -ca_provisioner_password: ${STEP_REMOTE_CA_PROVISIONER_PASSWORD} -ca_provisioner_password_file: /tmp/provisioner_passfile - -# Currently tested versions -ca_version: ${STEP_CA_VERSION} -cli_version: ${STEP_CLI_VERSION} diff --git a/tests/integration/integration_config_local.yml.j2 b/tests/integration/integration_config_local.yml.j2 new file mode 100644 index 00000000..882c028a --- /dev/null +++ b/tests/integration/integration_config_local.yml.j2 @@ -0,0 +1,15 @@ +--- +# Configuration for the smallstep module integration tests. +# This template is rendered from pytest at the beginning of the integration tests +# You can use these variable names in your module integration tests. + +# Currently tested versions +ca_version: "{{ step_ca_version }}" +cli_version: "{{ step_cli_version }}" + +# Locally reachable CA settings - this is needed by modules like step_ca_provisioner that need FS access +# Don't use these unless your target is tagged with "local-ca" and you use "setup_local_ca" +# these values are hardcoded in the local-ca dockerfile +ca_user: "step" +ca_path: "/home/step" +cli_binary: "step" diff --git a/tests/integration/integration_config_remote.yml.j2 b/tests/integration/integration_config_remote.yml.j2 new file mode 100644 index 00000000..d183a849 --- /dev/null +++ b/tests/integration/integration_config_remote.yml.j2 @@ -0,0 +1,17 @@ +--- +# Configuration for the smallstep module integration tests. +# This template is rendered from pytest at the beginning of the integration tests +# You can use these variable names in your module integration tests. + +# Currently tested versions +ca_version: "{{ step_ca_version }}" +cli_version: "{{ step_cli_version }}" + +# Remote CA access options - this could be a VM somewhere or a local container +# Use these variables for normal module integration tests +ca_url: "{{ step_remote_ca_url }}" +ca_fp: "{{ step_remote_ca_fingerprint }}" +# Use this provisioner to create certs/tokens/etc. The password file is already present after calling "setup_remote_provisioner" +ca_provisioner: "{{ step_remote_ca_provisioner_name }}" +ca_provisioner_password: "{{ step_remote_ca_provisioner_password }}" +ca_provisioner_password_file: "/tmp/remote-ca-password" diff --git a/tests/integration/targets/setup_remote_ca/tasks/main.yml b/tests/integration/targets/setup_remote_ca/tasks/main.yml index bad10ec4..64e5a471 100644 --- a/tests/integration/targets/setup_remote_ca/tasks/main.yml +++ b/tests/integration/targets/setup_remote_ca/tasks/main.yml @@ -1,29 +1,32 @@ -- name: Install JQ - ansible.builtin.apt: - name: jq # needed to get root certificate - retries: 3 - delay: 5 - register: _task - until: _task is not failed -- name: Install step-cli +- name: Install step-cli (specific version) ansible.builtin.apt: deb: "https://github.com/smallstep/cli/releases/download/v{{ cli_version }}/step-cli_{{ cli_version }}_amd64.deb" retries: 3 delay: 5 register: _task until: _task is not failed - -# the stuff of itsec nightmares -# the step-ca container genreates its root CA dynamically when started, but we retrieve its CA fingerprint to bootstrap from it. -# since there is no way to pre-seed the fingerprint and root CA cert, we instead use the internal step-ca API to retrieve all root certificates, -# then generate the fingerprint from that. -# This hack may stop working if smallstep decides to change their ca API structure in the future. but it works for now -- name: Get remote fingerprint - ansible.builtin.shell: "curl -k {{ ca_url }}/roots | jq -rj '.crts[0]' > /tmp/root_cert && step-cli certificate fingerprint /tmp/root_cert" - register: _ca_fp -- name: Set fingerprint - set_fact: - ca_fp: "{{ _ca_fp.stdout }}" + when: cli_version != "latest" +- block: + - name: Get latest step-cli release information + ansible.builtin.uri: + url: https://api.github.com/repos/smallstep/cli/releases/latest + body_format: json + return_content: yes + register: step_cli_latest_release + no_log: true # super noisy + delegate_to: localhost + become: no + run_once: yes + retries: 3 + delay: 5 + - name: Install step-cli (latest) + ansible.builtin.apt: + deb: "https://github.com/smallstep/cli/releases/download/v{{ (step_cli_latest_release.json.tag_name)[1:] }}/step-cli_{{ (step_cli_latest_release.json.tag_name)[1:] }}_amd64.deb" + retries: 3 + delay: 5 + register: _task + until: _task is not failed + when: cli_version == "latest" - name: Bootstrap host maxhoesel.smallstep.step_ca_bootstrap: diff --git a/tests/integration/targets/step_ca_bootstrap/tasks/main.yml b/tests/integration/targets/step_ca_bootstrap/tasks/main.yml index ea5ea46d..e4a4e994 100644 --- a/tests/integration/targets/step_ca_bootstrap/tasks/main.yml +++ b/tests/integration/targets/step_ca_bootstrap/tasks/main.yml @@ -1,15 +1,3 @@ -# the stuff of itsec nightmares -# the step-ca container genreates its root CA dynamically when started, but we retrieve its CA fingerprint to bootstrap from it. -# since there is no way to pre-seed the fingerprint and root CA cert, we instead use the internal step-ca API to retrieve all root certificates, -# then generate the fingerprint from that. -# This hack may stop working if smallstep decides to change their ca API structure in the future. but it works for now -- name: Get remote fingerprint - ansible.builtin.shell: "curl -k {{ ca_url }}/roots | jq -rj '.crts[0]' > /tmp/root_cert && step-cli certificate fingerprint /tmp/root_cert" - register: _ca_fp -- name: Set fingerprint - set_fact: - ca_fp: "{{ _ca_fp.stdout }}" - - name: Bootstrap Host maxhoesel.smallstep.step_ca_bootstrap: ca_url: "{{ ca_url }}" diff --git a/tests/plugins/conftest.py b/tests/plugins/conftest.py new file mode 100644 index 00000000..5f86f813 --- /dev/null +++ b/tests/plugins/conftest.py @@ -0,0 +1,125 @@ +# pylint: disable=redefined-outer-name +from dataclasses import dataclass +from pathlib import Path +import random +import string +from typing import cast, Generator, Optional + +import docker +from docker.models.containers import Container +from docker.models.images import Image +from docker.models.networks import Network +from docker.errors import NotFound +import pytest + +from tests.conftest import TestEnv, GALAXY_YML + +REMOTE_CA_NETWORK = "ansible-collection-smallstep-test-remote-ca" +REMOTE_CA_HOSTNAME = "ca" +REMOTE_CA_PROVISIONER_NAME = "ansible" +REMOTE_CA_PROVISIONER_PASSWORD = "secret-secret-secret" + +LOCAL_CA_DOCKERFILE_DIR = Path("tests/integration/docker/local-ca").resolve() +LOCAL_CA_TAG = "ansible-collection-smallstep-local-ca" + + +class AnsibleTestEnv(TestEnv): + # pylint: disable=redefined-outer-name + def __init__(self, virtualenv, collection_path, test_versions) -> None: + self.cwd = collection_path / "ansible_collections" / GALAXY_YML["namespace"] / GALAXY_YML["name"] + super().__init__(virtualenv) + + self.run(["pip", "install", test_versions.ansible_version_pip]) + + def run(self, *args, **kwargs): + kwargs["cwd"] = self.cwd + return super().run(*args, **kwargs) + + +ANSIBLE_TEST_ENV: Optional[AnsibleTestEnv] = None + + +@pytest.fixture() +# This fixture should be session-scoped, but cannot be since it requires the function-scoped virtualenv fixture +# Use memoization for now. +# pylint: disable=redefined-outer-name +def ansible_test_env(virtualenv, collection_path, test_versions) -> AnsibleTestEnv: + global ANSIBLE_TEST_ENV # pylint: disable=global-statement + if ANSIBLE_TEST_ENV is not None: + return ANSIBLE_TEST_ENV + + ANSIBLE_TEST_ENV = AnsibleTestEnv(virtualenv, collection_path, test_versions) + return ANSIBLE_TEST_ENV + + +@pytest.fixture(scope="session") +def remote_ca_network() -> Generator[Network, None, None]: + client = docker.from_env() + try: + net = client.networks.get(REMOTE_CA_NETWORK) + except NotFound: + net = client.networks.create(REMOTE_CA_NETWORK) + net = cast(Network, net) + yield net + + net.remove() + + +@dataclass +class RemoteCaContainerConfig: + ct: Container + ct_hostname: str + ct_network: str + ca_url: str + ca_fingerprint: str + ca_provisioner_name: str + ca_provisioner_password: str + + +@pytest.fixture(scope="session") +def remote_ca_container(remote_ca_network, test_versions) -> Generator[RemoteCaContainerConfig, None, None]: + client = docker.from_env() + ct = cast(Container, client.containers.run( + f"docker.io/smallstep/step-ca:{test_versions.step_ca_version}", detach=True, remove=True, + hostname=REMOTE_CA_HOSTNAME, network=remote_ca_network.name, + environment={ + "DOCKER_STEPCA_INIT_NAME": "smallstep-test-remote", + "DOCKER_STEPCA_INIT_DNS_NAMES": f"localhost,{REMOTE_CA_HOSTNAME}", + "DOCKER_STEPCA_INIT_PROVISIONER_NAME": REMOTE_CA_PROVISIONER_NAME, + "DOCKER_STEPCA_INIT_PASSWORD": REMOTE_CA_PROVISIONER_PASSWORD + }, + )) + # Wait for the CA to come online + rc = ct.exec_run("bash -c 'for i in {1..10}; do step ca health && exit 0 || sleep 1; done && exit 1'")[0] + assert rc == 0 + # Read the CA fingerprint, tty required due to this: https://github.com/docker/docker-py/issues/2044 + rc, _fp = ct.exec_run("step certificate fingerprint certs/root_ca.crt", stdout=True, stderr=False, tty=True) + assert rc == 0 + fingerprint = bytes(_fp).decode().strip() # type: ignore + + yield RemoteCaContainerConfig( + ct, ct_hostname=REMOTE_CA_HOSTNAME, ct_network=REMOTE_CA_NETWORK, + ca_url=f"https://{REMOTE_CA_HOSTNAME}:9000", ca_fingerprint=fingerprint, + ca_provisioner_name=REMOTE_CA_PROVISIONER_NAME, ca_provisioner_password=REMOTE_CA_PROVISIONER_PASSWORD + ) + + ct.remove(force=True) + + +@pytest.fixture(scope="session") +def local_ca_image(test_versions) -> Generator[Image, None, None]: + image_suffix = ''.join(random.choice(string.ascii_lowercase) for i in range(8)) + client = docker.from_env() + + img = client.images.build( + path=LOCAL_CA_DOCKERFILE_DIR.as_posix(), + tag=f"{LOCAL_CA_TAG}-{image_suffix}:latest", + buildargs={ + "STEP_CA_VERSION": test_versions.step_ca_version, + "ANSIBLE_VERSION": test_versions.ansible_version + })[0] # type: ignore + img = cast(Image, img) + + yield img + + img.remove(force=True) diff --git a/tests/plugins/test_plugins.py b/tests/plugins/test_plugins.py new file mode 100644 index 00000000..1fa9593e --- /dev/null +++ b/tests/plugins/test_plugins.py @@ -0,0 +1,67 @@ +# pylint: disable=redefined-outer-name + +from pathlib import Path + +from jinja2 import Environment, FileSystemLoader + +LOCAL_CA_TAG = "local-ca" + +INTEGRATION_CONFIG_DIR = Path("tests/integration/") +INTEGRATION_CONFIG_TEMPLATE_REMOTE = "integration_config_remote.yml.j2" +INTEGRATION_CONFIG_TEMPLATE_LOCAL = "integration_config_local.yml.j2" +INTEGRATION_CONFIG_FILE = "integration_config.yml" + + +def render_integration_config(template, dest: Path, **kwargs): + env = Environment(loader=FileSystemLoader(INTEGRATION_CONFIG_DIR)) + template = env.get_template(template) + content = template.render(**kwargs) + with open(dest, "w", encoding="utf-8") as f: + f.write(f"{content}\n") + + +def test_plugins_integration_remote(test_versions, remote_ca_container, ansible_test_env): + render_integration_config( + INTEGRATION_CONFIG_TEMPLATE_REMOTE, + ansible_test_env.cwd / "tests" / "integration" / INTEGRATION_CONFIG_FILE, + step_ca_version=test_versions.step_ca_version, + step_cli_version=test_versions.step_cli_version, + step_remote_ca_url=remote_ca_container.ca_url, + step_remote_ca_fingerprint=remote_ca_container.ca_fingerprint, + step_remote_ca_provisioner_name=remote_ca_container.ca_provisioner_name, + step_remote_ca_provisioner_password=remote_ca_container.ca_provisioner_password + ) + + ansible_test_env.run([ + "ansible-test", "integration", "--color", "-v", + "--controller", "docker:default", + "--target", f"docker:default,python={test_versions.node_python_version}", + "--docker-network", remote_ca_container.ct_network, + "--skip-tags", LOCAL_CA_TAG + ]) + + +def test_plugins_integration_local(test_versions, local_ca_image, ansible_test_env): + render_integration_config( + INTEGRATION_CONFIG_TEMPLATE_LOCAL, + ansible_test_env.cwd / "tests" / "integration" / INTEGRATION_CONFIG_FILE, + step_ca_version=test_versions.step_ca_version, + step_cli_version=test_versions.step_cli_version, + ) + + ansible_test_env.run([ + "ansible-test", "integration", "--color", "-v", + "--controller", "docker:default", + "--target", f"docker:{local_ca_image.tags[0]},python={test_versions.node_python_version}", + "--tags", LOCAL_CA_TAG + ]) + + +def test_plugins_sanity(ansible_test_env, test_versions): + ansible_test_env.run([ + "ansible-test", + "sanity", "--docker", "--color", "-v", + "--python", test_versions.node_python_version, + "--skip-test", "metaclass-boilerplate", + "--skip-test", "future-import-boilerplate", + ]) diff --git a/tests/roles/conftest.py b/tests/roles/conftest.py new file mode 100644 index 00000000..77756f9e --- /dev/null +++ b/tests/roles/conftest.py @@ -0,0 +1,45 @@ +import os +from pathlib import Path +from typing import Optional + +import pytest + +from tests.conftest import TestEnv + +MOLECULE_REQUIREMENTS_PIP = Path("tests/roles/requirements.txt").resolve() +MOLECULE_REQUIREMENTS_ANSIBLE = Path("tests/roles/requirements.yml").resolve() + + +class MoleculeTestEnv(TestEnv): + # pylint: disable=redefined-outer-name + def __init__(self, virtualenv, test_versions, collection_path) -> None: + self.env = {**os.environ.copy(), **{ + "ANSIBLE_COLLECTIONS_PATH": collection_path, + "STEP_CLI_VERSION": test_versions.step_cli_version, + "STEP_CA_VERSION": test_versions.step_ca_version, + }} + super().__init__(virtualenv) + + self.run(["pip", "install", test_versions.ansible_version_pip]) + self.run(["pip", "install", "-r", MOLECULE_REQUIREMENTS_PIP]) + self.run(["ansible-galaxy", "collection", "install", "-r", MOLECULE_REQUIREMENTS_ANSIBLE]) + + def run(self, *args, **kwargs): + kwargs["env"] = self.env + return super().run(*args, **kwargs) + + +MOLECULE_ENV: Optional[MoleculeTestEnv] = None + + +@pytest.fixture() +# This fixture should be session-scoped, but cannot be since it requires the function-scoped virtualenv fixture. +# Use memoization for now. +# pylint: disable=redefined-outer-name +def molecule_env(virtualenv, test_versions, collection_path) -> MoleculeTestEnv: + global MOLECULE_ENV # pylint: disable=global-statement + if MOLECULE_ENV is not None: + return MOLECULE_ENV + + MOLECULE_ENV = MoleculeTestEnv(virtualenv, test_versions, collection_path) + return MOLECULE_ENV diff --git a/tests/roles/requirements.txt b/tests/roles/requirements.txt index a7e1c0be..578fa5bf 100644 --- a/tests/roles/requirements.txt +++ b/tests/roles/requirements.txt @@ -1,4 +1,3 @@ # Dependencies for executing the role scenarios. -# We pin molecule to prevent issues with breaking changes molecule==6.0.2 -molecule-plugins[podman]==23.4.1 +molecule-plugins[docker]==23.4.1 diff --git a/tests/roles/requirements.yml b/tests/roles/requirements.yml new file mode 100644 index 00000000..f93a9feb --- /dev/null +++ b/tests/roles/requirements.yml @@ -0,0 +1,5 @@ +# Requirements for running molecule scenarios +# These are not the collection runtime requirements, see galaxy.yml for those +collections: + - name: community.docker + version: "==3.4.8" diff --git a/tests/roles/test_molecule.py b/tests/roles/test_molecule.py new file mode 100644 index 00000000..c4d51114 --- /dev/null +++ b/tests/roles/test_molecule.py @@ -0,0 +1,23 @@ +from pathlib import Path + +import pytest + +# List of molecule scenario directories +MOLECULE_SCENARIOS = [ + subdir + for role in Path("./roles").iterdir() + for subdir in Path(role, 'molecule').glob('*') + if subdir.is_dir() and (subdir / "molecule.yml").exists() +] + + +def scenario_id(path: Path) -> str: + return f"{path.parent.parent.name}-{path.name}" + + +@pytest.mark.parametrize("scenario", MOLECULE_SCENARIOS, ids=scenario_id) +def test_scenario(scenario: Path, molecule_env) -> None: + molecule_env.run( + ["molecule", "test", "-s", scenario.name], + cwd=scenario.parent.parent.resolve() + ) diff --git a/tests/sanity/docker-compose.yml b/tests/sanity/docker-compose.yml deleted file mode 100644 index d5fbec94..00000000 --- a/tests/sanity/docker-compose.yml +++ /dev/null @@ -1,15 +0,0 @@ -version: "3" - -services: - test-runner: - image: quay.io/maxhoesel-ansible/ansible-test-collection-runner:${ANSIBLE_VERSION} - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ../../:/collection:ro - # As we only support py36+, pyupgrade is set to remove the py27 boilerplate. - # Don't check for that as we don't need it. - environment: - ANSIBLE_TEST_ARGS: "sanity --docker --color -v \ - --python ${NODE_PYTHON_VERSION} \ - --skip-test metaclass-boilerplate \ - --skip-test future-import-boilerplate" diff --git a/tox.ini b/tox.ini deleted file mode 100644 index ad002f04..00000000 --- a/tox.ini +++ /dev/null @@ -1,74 +0,0 @@ -[consts] -node_min_python = 3.6 -step_ca_version = 0.24.1 -step_cli_version = 0.24.3 - -[tox] -# plugin tests: run plugin tests with these ansible versions -envlist = py3-ansible{213,214,215}-test-{sanity,integration} -requires = - tox-ansible>=1.8,<2 - tox<4 -skipsdist = True - -[ansible] -# Role tests config: we test roles with these ansible/py versions -ansible = 6,7,8 -python = 3 -scenario_format = $path-$parent-$nondefault_name - -[testenv] -passenv = - HOME -setenv = - # Set the ansible version for plugin tests - ansible213: ANSIBLE_VERSION = 2.13 - ansible214: ANSIBLE_VERSION = 2.14 - ansible215: ANSIBLE_VERSION = 2.15 - # Make testing versions available to everyone - STEP_CLI_VERSION = {[consts]step_cli_version} - STEP_CA_VERSION = {[consts]step_ca_version} - NODE_PYTHON_VERSION = {[consts]node_min_python} - # Visualization - PY_COLORS = 1 - ANSIBLE_FORCE_COLOR = 1 - -[testenv:py3-ansible{213,214,215}-test-sanity] -whitelist_externals = - docker -changedir = tests/sanity -commands_pre = - docker compose down -commands = - docker compose run --no-TTY --rm test-runner -commands_post = - # cleanup networks - docker compose down --remove-orphans - -#[testenv:py3-ansible{213,214,215}-test-units] -#whitelist_externals = -# docker -#changedir = tests/unit -#commands_pre = -# docker compose down -#commands = -# docker compose run --no-TTY --rm test-runner -#commands_post = -# # cleanup networks -# docker compose down --remove-orphans - -[testenv:py3-ansible{213,214,215}-test-integration] -whitelist_externals = - docker -changedir = tests/integration -commands_pre = - docker compose -f docker-compose-local.yml down - docker compose -f docker-compose-remote.yml down -commands = - docker compose -f docker-compose-local.yml build - docker compose -f docker-compose-local.yml run --no-TTY --rm test-runner-local - docker compose -f docker-compose-remote.yml run --no-TTY --rm test-runner-remote -commands_post = - # cleanup networks - docker compose -f docker-compose-local.yml down --remove-orphans - docker compose -f docker-compose-remote.yml down --remove-orphans