diff options
Diffstat (limited to 'ansible_collections/cyberark/conjur')
136 files changed, 5660 insertions, 0 deletions
diff --git a/ansible_collections/cyberark/conjur/.codeclimate.yml b/ansible_collections/cyberark/conjur/.codeclimate.yml new file mode 100644 index 000000000..40b46a5fd --- /dev/null +++ b/ansible_collections/cyberark/conjur/.codeclimate.yml @@ -0,0 +1,162 @@ +# This is our default .CodeClimate.yml, broken out by language. Uncomment the +# sections at the bottom that apply to your project. ACTION comments indicate +# places where config might need to be tweaked. + +version: "2" + +plugins: + +# --------------- +# Cross-language plugins. Should always be on. + + duplication: # Looks for similar and identical code blocks + enabled: true + config: + languages: + go: + java: + javascript: + php: + python: + python_version: 3 # ACTION Comment this out if using Python 2 + ruby: + swift: + typescript: + + fixme: # Flags any FIXME, TODO, BUG, XXX, HACK comments so they can be fixed + enabled: true + config: + strings: + - FIXME + - TODO + - HACK + - XXX + - BUG + +# --------------- +# Commonly-used languages - run time is minimal and all of these will work +# whether files of that language are found or not. In general, leave uncommented + + # Markdown + markdownlint: + enabled: true + + # Go + gofmt: + enabled: true + golint: + enabled: true + govet: + enabled: true + + # Ruby + flog: + enabled: true + reek: + enabled: true + rubocop: + enabled: true + channel: rubocop-0-79 # As of March 10, 2020, rubocop 0.80.1 is the latest + # However, it does not work with CodeClimate - throws + # an Invalid JSON error. + # ACTION uncomment bundler-audit below if using Gemfile/Gemfile.lock + # ACTION uncomment brakeman below if using Rails + + # Shell scripts + shellcheck: + enabled: true + +# --------------- +# Other languages - will work with or without language files present. Again, +# runtime is minimal, so OK to leave uncommented. + + # CoffeeScript + coffeelint: + enabled: true + + # CSS + csslint: + enabled: true + + # Groovy + codenarc: + enabled: true + + # Java + pmd: + enabled: true + sonar-java: + enabled: true + config: + sonar.java.source: "7" # ACTION set this to the major version of Java used + # ACTION uncomment checkstyle below if Java code exists in repo + + # Node.js + nodesecurity: + enabled: true + # ACTION uncomment eslint below if JavaScript already exists and .eslintrc + # file exists in repo + + # PHP + phan: + enabled: true + config: + file_extensions: "php" + phpcodesniffer: + enabled: true + config: + file_extensions: "php,inc,lib" + # Using Wordpress standards as our one PHP repo is a Wordpress theme + standards: "PSR1,PSR2,WordPress,WordPress-Core,WordPress-Extra" + phpmd: + enabled: true + config: + file_extensions: "php,inc,lib" + rulesets: "cleancode,codesize,controversial,naming,unusedcode" + sonar-php: + enabled: true + + # Python + bandit: + enabled: true + pep8: + enabled: true + radon: + enabled: true + # config: + # python_version: 2 # ACTION Uncomment these 2 lines if using Python 2 + sonar-python: + enabled: true + +# --------------- +# Configuration Required Language specific - these will error and abort the +# codeclimate run if they are turned on and certain files or configuration are +# missing. Should be commented out unless the project already includes the +# necessary files that the linter looks at + + # Ruby - requires presence of Gemfile and Gemfile.lock + # bundler-audit: + # enabled: true + + # Rails - requires detecting a Rails application + # brakeman: + # enabled: true + + # Chef - requires detecting a cookbook + # foodcritic: + # enabled: true + + # Java - might require Java code? Errored when run without + # checkstyle: + # enabled: true + + # JavaScript - requires an eslintrc to be created and added to project + # eslint: + # enabled: true + # channel: "eslint-6" + +# --------------- +# List any files/folders to exclude from checking. Wildcards accepted. Leave +# commented if no files to exclude as an empty array will error +exclude_patterns: + - ".gitignore" diff --git a/ansible_collections/cyberark/conjur/.github/CODEOWNERS b/ansible_collections/cyberark/conjur/.github/CODEOWNERS new file mode 100644 index 000000000..7e099ff54 --- /dev/null +++ b/ansible_collections/cyberark/conjur/.github/CODEOWNERS @@ -0,0 +1,10 @@ +* @cyberark/community-and-integrations-team @conjurinc/community-and-integrations-team @conjurdemos/community-and-integrations-team + +# Changes to .trivyignore require Security Architect approval +.trivyignore @cyberark/security-architects @conjurinc/security-architects @conjurdemos/security-architects + +# Changes to .codeclimate.yml require Quality Architect approval +.codeclimate.yml @cyberark/quality-architects @conjurinc/quality-architects @conjurdemos/quality-architects + +# Changes to SECURITY.md require Security Architect approval +SECURITY.md @cyberark/security-architects @conjurinc/security-architects @conjurdemos/security-architects diff --git a/ansible_collections/cyberark/conjur/.github/workflows/ansible-test.yml b/ansible_collections/cyberark/conjur/.github/workflows/ansible-test.yml new file mode 100644 index 000000000..27d352352 --- /dev/null +++ b/ansible_collections/cyberark/conjur/.github/workflows/ansible-test.yml @@ -0,0 +1,91 @@ +# This file implements a Github action to run Ansible collection sanity tests +# on the Conjur Ansible Collection. The Ansible collection sanity tests are +# run across the following matrices: +# +#Ansible versions: +# - stable-2.10 +# - stable-2.11 +# - stable-2.12 +# - devel +# +#Python versions: +# - Python 3.9 + +name: CI +on: +# Run CI against all pushes (direct commits) and Pull Requests +- push +- pull_request + +jobs: + +### +# Sanity tests (REQUIRED) +# +# https://docs.ansible.com/ansible/latest/dev_guide/testing_sanity.html + + sanity: + name: Sanity (${{ matrix.ansible }}+py${{ matrix.python }}) + strategy: + matrix: + ansible: + # It's important that Sanity is tested against all stable-X.Y branches + # Testing against `devel` may fail as new tests are added. + - stable-2.10 + - stable-2.11 + - stable-2.12 + - devel + python: + - 3.9 + runs-on: ubuntu-latest + steps: + + # ansible-test requires the collection to be in a directory in the form + # .../ansible_collections/cyberark/conjur/ + + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/cyberark/conjur + + - name: Set up Python ${{ matrix.ansible }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + + # Install the head of the given branch (devel, stable-2.10) + - name: Install ansible-base (${{ matrix.ansible }}) + run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check + + # run ansible-test sanity inside of Docker. + # The docker container has all the pinned dependencies that are required. + # Explicity specify the version of Python we want to test + - name: Run sanity tests + run: ansible-test sanity --docker -v --color --python ${{ matrix.python }} + working-directory: ./ansible_collections/cyberark/conjur + +# Unit tests (OPTIONAL) + +# https://docs.ansible.com/ansible/latest/dev_guide/testing_units.html + + units: + name: Units (â’¶${{ matrix.ansible }}+py${{ matrix.python }}) + strategy: + matrix: + ansible: + - stable-2.10 + - stable-2.11 + - stable-2.12 + - devel + python: + - 3.9 + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/cyberark/conjur + + - name: Run unit tests + run: ./dev/test_unit.sh -a ${{ matrix.ansible }} -p ${{ matrix.python }} + working-directory: ./ansible_collections/cyberark/conjur diff --git a/ansible_collections/cyberark/conjur/.gitignore b/ansible_collections/cyberark/conjur/.gitignore new file mode 100644 index 000000000..2be2e7467 --- /dev/null +++ b/ansible_collections/cyberark/conjur/.gitignore @@ -0,0 +1,39 @@ +# System directories files +.DS_Store +.idea/ + +# Test output +tests/*/bot/ +tests/*/coverage/ +tests/*/junit/ +tests/*/reports/ + +tests/*/conjur.pem +tests/*/conjur-enterprise.pem +tests/*/access_token +**/test-files/output +**/conjur-intro/ +bot +coverage +junit +reports + +*.js +*.html +output/ + +# Pycache directories and files +**/__pycache__/ +.pytest_cache +*.pyc + +# Distributable directories files +*.tar.gz +vendor/ + +# Temporary files +*.log +.cache +*.retry +*.tmp +conjur.pem diff --git a/ansible_collections/cyberark/conjur/CHANGELOG.md b/ansible_collections/cyberark/conjur/CHANGELOG.md new file mode 100644 index 000000000..8fa9162e4 --- /dev/null +++ b/ansible_collections/cyberark/conjur/CHANGELOG.md @@ -0,0 +1,84 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.2.0] - 2020-09-01 + +### Added +- Add `state` variable to Conjur Ansible role, which can be used to cleanup + configuration and identity artifacts created on managed nodes. + [cyberark/ansible-conjur-collection#176](https://github.com/cyberark/ansible-conjur-collection/pull/176) + +### Changed +- Lookup plugin now retries variable retrieval 5 times before accepting a + failure response. + [cyberark/ansible-conjur-collection#60](https://github.com/cyberark/ansible-conjur-collection/pull/60) + +### Removed +- End support for Python 2. + [cyberark/ansible-conjur-collection#69](https://github.com/cyberark/ansible-conjur-collection/pull/69) + +## [1.1.0] - 2020-12-29 + +### Added +- The [Conjur Ansible role](https://galaxy.ansible.com/cyberark/conjur-host-identity) has been + migrated to this collection, where it will be maintained moving forward. + At current, the role in the collection is aligned with the v0.3.2 release of + the standalone role. + [cyberark/ansible-conjur-host-identity#30](https://github.com/cyberark/ansible-conjur-host-identity/issues/30) +- Add `as_file` boolean option to the lookup plugin which stores the secret as + a temporary file and returns its path. This enables users to use the + `ansible_ssh_private_key_file` parameter to define an SSH private key using a + variable stored in Conjur; previously, users couldn't set this parameter via + a direct call to the lookup plugin because the parameter does not accept + inline SSH keys, and the lookup plugin could only return a string. + [cyberark/ansible-conjur-collection#52](https://github.com/cyberark/ansible-conjur-collection/issues/52), + [Cyberark Commons post #1070](https://discuss.cyberarkcommons.org/t/conjur-ansible-lookup-plugin-and-ssh-key-file/1070) + +## [1.0.7] - 2020-08-20 + +### Changed +- Various improvements to code quality, documentation, and adherence to Ansible standards + in preparation for including this collection in the release of Ansible 2.10. + [cyberark/ansible-conjur-collection#30](https://github.com/cyberark/ansible-conjur-collection/issues/30) + +## [1.0.6] - 2020-07-01 + +### Added +- Plugin supports authenticating with Conjur access token (for example, if provided by authn-k8s). + [cyberark/ansible-conjur-collection#23](https://github.com/cyberark/ansible-conjur-collection/issues/23) + +## [1.0.5] - 2020-06-18 + +### Added +- Plugin supports validation of self-signed certificates provided in `CONJUR_CERT_FILE` + or Conjur config file + ([cyberark/ansible-conjur-collection#4](https://github.com/cyberark/ansible-conjur-collection/issues/4)) + +### Fixed +- Encode spaces to "%20" instead of "+". This encoding fixes an issue where Conjur + variables that have spaces were not encoded correctly + ([cyberark/ansible-conjur-collection#12](https://github.com/cyberark/ansible-conjur-collection/issues/12)) +- Allow users to set `validate_certs` to `false` without setting a value to `cert_file` + ([cyberark/ansible-conjur-collection#13](https://github.com/cyberark/ansible-conjur-collection/issues/13)) + +## [1.0.3] - 2020-04-18 +### Changed +- Updated documentation section to comply with sanity checks + +## [1.0.2] - 2020-04-01 +### Added +- Migrated code from Ansible conjur_variable lookup plugin +- Added support to configure the use of the plugin via environment variables + +[Unreleased]: https://github.com/cyberark/ansible-conjur-collection/compare/v1.2.0...HEAD +[1.2.0]: https://github.com/cyberark/ansible-conjur-collection/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/cyberark/ansible-conjur-collection/compare/v1.0.7...v1.1.0 +[1.0.7]: https://github.com/cyberark/ansible-conjur-collection/compare/v1.0.6...v1.0.7 +[1.0.6]: https://github.com/cyberark/ansible-conjur-collection/compare/v1.0.5...v1.0.6 +[1.0.5]: https://github.com/cyberark/ansible-conjur-collection/compare/v1.0.3...v1.0.5 +[1.0.3]: https://github.com/cyberark/ansible-conjur-collection/compare/v1.0.2...v1.0.3 diff --git a/ansible_collections/cyberark/conjur/CONTRIBUTING.md b/ansible_collections/cyberark/conjur/CONTRIBUTING.md new file mode 100644 index 000000000..82319a287 --- /dev/null +++ b/ansible_collections/cyberark/conjur/CONTRIBUTING.md @@ -0,0 +1,251 @@ +# Contributing to the Ansible Conjur Collection + +Thanks for your interest in Conjur. Before contributing, please take a moment to +read and sign our <a href="https://github.com/cyberark/community/blob/master/documents/CyberArk_Open_Source_Contributor_Agreement.pdf" download="conjur_contributor_agreement">Contributor Agreement</a>. +This provides patent protection for all Conjur users and allows CyberArk to enforce +its license terms. Please email a signed copy to <a href="oss@cyberark.com">oss@cyberark.com</a>. +For general contribution and community guidelines, please see the [community repo](https://github.com/cyberark/community). + +- [Contributing to the Ansible Conjur Collection](#contributing-to-the-ansible-conjur-collection) + * [Prerequisites](#prerequisites) + * [Set up a development environment](#set-up-a-development-environment) + + [Verification](#verification) + + [Useful links](#useful-links) + * [Testing](#testing) + + [Unit tests](#unit-tests) + + [Integration tests](#integration-tests) + * [Releasing](#releasing) +- [Ansible Conjur Collection Quick Start](#ansible-conjur-collection-quick-start) + * [Setup a conjur OSS Environment](#setup-a-conjur-oss-environment) + * [Load policy to set up Conjur Ansible integration](#load-policy-to-set-up-conjur-ansible-integration) + * [Create Ansible managed nodes](#create-ansible-managed-nodes) + * [Use Conjur Ansible Role to set up identity on managed nodes](#use-conjur-ansible-role-to-set-up-identity-on-managed-nodes) + * [Use Conjur Lookup Plugin to provide secrets to Ansible Playbooks](#use-conjur-lookup-plugin-to-provide-secrets-to-ansible-playbooks) + +<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small> + +## Prerequisites + +Before getting started, the following tools need to be installed: + +1. [Git][get-git] to manage source code +2. [Docker][get-docker] to manage dependencies and runtime environments +3. [Docker Compose][get-docker-compose] to orchestrate Docker environments + +[get-docker]: https://docs.docker.com/engine/installation +[get-docker-compose]: https://docs.docker.com/compose/install +[get-git]: https://git-scm.com/downloads + +## Set up a development environment + +The `dev` directory contains a `docker-compose` file which creates a development +environment : +- A Conjur Open Source instance +- An Ansible control node +- Managed nodes to push tasks to + +To use it: + +1. Install dependencies (as above) + +1. To use the dev environment, clone the + [Collection repository](https://github.com/cyberark/ansible-conjur-collection) + and run the setup script: + + ```sh-session + $ git clone https://github.com/cyberark/ansible-conjur-collection.git + $ cd ansible-conjur-collection/dev + $ ./start.sh + ``` + +### Verification + +When the Conjur and Ansible containers have been successfully setup, the +terminal prints the following: + +```sh-session + ... + PLAY RECAP ********************************************************************* + ansibleplugingtestingconjurhostidentity-test_app_centos-1 : ok=17 ... + ansibleplugingtestingconjurhostidentity-test_app_centos-2 : ok=17 ... + ansibleplugingtestingconjurhostidentity-test_app_ubuntu-1 : ok=16 ... + ansibleplugingtestingconjurhostidentity-test_app_ubuntu-2 : ok=16 ... + ``` + +Your Conjur instance will be configured with the following: +* Account: `cucumber` +* User: `admin` +* Password: Run `conjurctl role retrieve-key cucumber:user:admin` inside the + Conjur container shell to retrieve the admin user API key + +### Useful links + +- [Official documentation for Conjur's Ansible integration](https://docs.conjur.org/Latest/en/Content/Integrations/ansible.html) +- [Conjur Collection on Ansible Galaxy](https://galaxy.ansible.com/cyberark/conjur) +- [Ansible documentation for the Conjur collection](https://docs.ansible.com/ansible/latest/collections/cyberark/conjur/index.html) + +## Testing + +### Unit tests + +Unit tests are only available for the Conjur Variable Lookup plugin. To run +these tests: +``` +./dev/test_unit.sh +``` + +### Integration tests + +The collection has integration tests for both the Variable Lookup plugin and the +Host Identity role that will validate each against live Conjur and Ansible +containers. + +To run all tests: +``` +./ci/test.sh -a +``` + +To run the tests for a particular module: +``` +./ci/test.sh -d <role or plugin name> +``` + +Integration tests can be run against Conjur Enterprise by adding the `-e` flag: +``` +./ci/test/sh -e -a +``` + +## Releasing + +From a clean instance of main, perform the following actions to release a new version +of this plugin: + +- Update the version number in [`galaxy.yml`](galaxy.yml) and [`CHANGELOG.md`](CHANGELOG.md) + - Verify that all changes for this version in `CHANGELOG.md` are clear and accurate, + and are followed by a link to their respective issue + - Create a PR with these changes + +- Create an annotated tag with the new version, formatted as `v##.##.##` + - This will kick off an automated script which publish the release to + [Ansible Galaxy](https://galaxy.ansible.com/cyberark/conjur) + +- Create the release on GitHub for that tag + - Build the release package with `./ci/build_release` + - Attach package to Github Release + + +# Ansible Conjur Collection Quick Start + +## Setup a conjur OSS Environment + +Generate the master key, which will be used to encrypt Conjur's database. Store +this value as an environment variable. + +```sh-session +docker-compose run --no-deps --rm conjur data-key generate > data_key +export CONJUR_DATA_KEY="$(< data_key)" +``` + +Start the Conjur OSS environment. An account, named `cucumber`, will be +automatically created. + +```sh-session +docker-compose up -d conjur +``` + +Retrieve the admin user's API key, and store the value in an environment variable. + +```sh-session +export CLI_CONJUR_AUTHN_API_KEY="$(docker-compose exec conjur conjurctl role retrieve-key cucumber:user:admin)" +``` + +Start the Conjur CLI container. The CLI will be automatically authenticated as +the user `cucumber:user:admin`. + +```sh-session +docker-compose up -d conjur_cli +``` + +## Load policy to set up Conjur Ansible integration + +Policy defines Conjur entities and the relationships between them. An entity can +be a policy, a host, a user, a layer, a group, or a variable. + +Check out the policy file, and load it into Conjur: + +```sh-session +docker-compose exec conjur_cli cat /policy/root.yml +docker-compose exec conjur_cli conjur policy load root /policy/root.yml +``` + +Also, load a dummy secret value into the `ansible/target-password` variable. +This is a variable required by remote nodes in order to complete their workloads. + +```sh-session +docker-compose exec conjur_cli conjur variable values add ansible/target-password S3cretV@lue +``` + +## Create Ansible managed nodes + +The Ansible environment will include a control node and a number of managed +nodes. First, retrieve the API key for the Conjur host representing the control +node, then create it: + +```sh-session +export ANSIBLE_CONJUR_AUTHN_API_KEY="$(docker-compose exec conjur conjurctl role retrieve-key cucumber:host:ansible/ansible-master)" +docker-compose up -d ansible +``` + +Next, create two instances of each managed node: + +```sh-session +docker-compose up -d --scale test_app_ubuntu=2 test_app_ubuntu +docker-compose up -d --scale test_app_centos=2 test_app_centos +``` + +## Use Conjur Ansible Role to set up identity on managed nodes + +To grant your Ansible host a Conjur identity, first install the Conjur +Collection on your Ansible control node: + +```sh-session +docker-compose exec ansible ansible-galaxy collection install cyberark.conjur +``` + +Set up the host factory token in the HFTOKEN env var + +```sh-session +export HFTOKEN="$(docker-compose exec conjur_cli conjur hostfactory tokens create ansible/ansible-factory | jq -r '.[0].token')" +``` + +Once you've done this, you can configure each Ansible node with a Conjur +identity by including a section like the example below in your Ansible playbook: + +```yaml +--- +- hosts: testapp + roles: + - role: cyberark.conjur.conjur_host_identity + conjur_appliance_url: 'https://conjur.myorg.com', + conjur_account: 'cucumber', + conjur_host_factory_token: "{{lookup('env', 'HFTOKEN')}}", + conjur_host_name: "{{inventory_hostname}}" +``` + +First we register the host with Conjur, adding it into the layer specific to the +provided host factory token, and then install Summon with the Summon Conjur +provider for secret retrieval from Conjur. + +## Use Conjur Lookup Plugin to provide secrets to Ansible Playbooks + +The Conjur lookup plugin can inject secret data directly into an Ansible +playbook, like it the following example: + +```yaml +--- +- hosts: testapp + tasks: + - name: Provide secret with Lookup plugin + debug: + msg: "{{ lookup('cyberark.conjur.conjur_variable', '/ansible/target-password') }}" +``` diff --git a/ansible_collections/cyberark/conjur/FILES.json b/ansible_collections/cyberark/conjur/FILES.json new file mode 100644 index 000000000..75f988f2c --- /dev/null +++ b/ansible_collections/cyberark/conjur/FILES.json @@ -0,0 +1,1419 @@ +{ + "files": [ + { + "name": ".", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4f950d62ff31f5dd42adccedf87aee3526c4d297843eef14db49452c802a9445", + "format": 1 + }, + { + "name": ".github", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".github/workflows", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".github/workflows/ansible-test.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3ea436b9dad8d9ea9ec8a5d07d60187cc85cabcbf455feaa1f3a21db10aa9fa1", + "format": 1 + }, + { + "name": ".github/CODEOWNERS", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f1dee7b6ae693cebe88547d034b17710489e515c3def06dad75252c8b19bfc51", + "format": 1 + }, + { + "name": "secrets.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "de372b010bf7a57b35af4bc901681a75cabe48b2e182d0691ff48d95a9d2b96f", + "format": 1 + }, + { + "name": "ci", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "ci/publish_to_galaxy", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "901e3836a10feba6a35d1c3b16e64a53e9069f87fed951edc2f292acc0fc1438", + "format": 1 + }, + { + "name": "ci/parse-changelog.sh", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "21337ea8fac801781f8299af7e0cb7818fbc851bab26cbfff6224a0e5cf8dbb8", + "format": 1 + }, + { + "name": "ci/test.sh", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "29d385e809a0a8c5e56a245244e1787d201c0c685182972ed39a5d3d07d5be0e", + "format": 1 + }, + { + "name": "ci/build_release", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9fd1048e1e1af19e2eb301a04c18fe207cc9fff663abc6485352aad2ed2225ef", + "format": 1 + }, + { + "name": ".codeclimate.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6e0a09af4e5f5f6fe2b16a8a49230170d53f0a495c6405d962be66a15a9774bd", + "format": 1 + }, + { + "name": "plugins", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/lookup", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/lookup/conjur_variable.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "fb3d6620f57c577a966cbbeb1f01d234cf43cafb81dc3edb44f0e3cd5b6d9679", + "format": 1 + }, + { + "name": "roles", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a712c1e5c56fb9a3917ebfd4a55109801da9e57dff304d1941aaf2cf2ab471ca", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/defaults", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/defaults/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c7f30d049a541e0fd98faeb5dcd8d83839e00db1f68ece8b14431630fb779e13", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tasks/uninstall.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d40f3bd7fdddbd8eddeb983e28ba959685e086d7382789b717e54a7f469d1f77", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tasks/identity.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e4a249b32c8b6d90b37e9787c6a22f6683820cf03af4f1038b8d73dbabf3fd1b", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tasks/install.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "723de78f2785f8cb7737c2e0e0801d674eba41636a7b1c5915dd41cec7083fed", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5f2195992211d603a73dead76e8e60e511ae0da2293a8a3167836d129ffe9bbf", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tasks/summon.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "40ad1a387e7f7a0a7c342614d9cdd5cd7ad4334634f4da733929e8e3b0a7ab4f", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tasks/identity_check.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "681aa9e68a95921df2701bd96baf8c9335845863d75395293a3002b037ce2b94", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tasks/summon-conjur.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b75ef3c1b8db527e7469e50d3b1f4f13ce09cc17ccec05ec598273f2afb79f34", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/templates", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/templates/conjur.conf.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a658eba375110e14ba752f82ccbcca9012351ca1c51a18419d870917bd807202", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/templates/conjur.identity.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b53dbe8b97fc87d0c0c168799a14d91862a010bc0472f982587a47326a2312", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0103f8e65603e7da7511224456dacf19c6a0e92c6e6f1fbf152f171d33741f80", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/inventory.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f1474fb6e66c0fbcdd6129332de95feab1e1222f64f1be45325f4eac5101614f", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.dockerignore", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1a0dc73ccd02fc377cf4cb1d99237e42335beeaf8c0bdb012dd4ecfb54790d57", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/ansible.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "73a428e3f22914440bb8072e66b3e36b3f930e513623a0a46a23bbd644995776", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/junit", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/junit/configure-conjur-identity", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c8c91315bc4679968e1f14101ae2ecc8606b82b32ab19e6aca4fb4905ee1e998", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/junit/cleanup-conjur-identity", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "24ac5dadeb28955ca2b4766e57bf27268a2fb10a186f425f06ff94200fc9e270", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_app_centos", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_app_centos/Dockerfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0de86cd21721bcf47192e1cb659d6edf4b20ac7ebf8ce1b667fc2dec14b4fbdf", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_app_ubuntu", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_app_ubuntu/Dockerfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2f381951ae812a2521539c06206945f2105f02beef04ab55ae76c5cf7e86406c", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/inventory-v2.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2e1c0d5018358dbe5bce37280e9d8c8fd6fc9f0ff85f4b8fefbfa4aa04defb37", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/inventory-playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "af542c07e6677cb819d35eb71e56587d3b4d97721578bed0775df4100695c79b", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/policy", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/policy/root.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2cf74b90f4eabbb9a9be67afeb2cf63c35b447579cef5b70f6daf270509d4309", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/Dockerfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d3e9a9f4bfff5c34b2078aa879faf017a494613a1ca5be5791ad4a8a08694c2e", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/configure-conjur-identity", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e5608c4f7fbc040647b99f2137e58df82807f8054fabbcc10bd4c830df64e80c", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b23eaacaae61ccdaf6d79e911606c8b964301cb2e1d661a1328171c1ea080bdf", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c1d3a10ce6d52166877a318bee957e9f394a87f29b5732652c9b2ea9f3d456b4", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9425b40cb335c7dc2d2d2cce0f9f1bfd64ce6c3833032b38522f8f709a157953", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/misconfig-conjur-identity", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test_cases/misconfig-conjur-identity/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b6af952b247d510012d4d2ed2bd067f2f989345d391c28a83c0d865da10a2a2d", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/docker-compose.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "dec4fc80511912594c6c7dd0b0d0721de13c66a0bfe4fbf92ba7bc9a5ff6cb85", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/test.sh", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e6d2aadcf5611e12181425d176b67fbe95740d374565535ece1be9181b78aabe", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.pytest_cache", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.pytest_cache/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "73fd6fccdd802c419a6b2d983d6c3173b7da97558ac4b589edec2dfe443db9ad", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.pytest_cache/.gitignore", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3ed731b65d06150c138e2dadb0be0697550888a6b47eb8c45ecc9adba8b8e9bd", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.pytest_cache/CACHEDIR.TAG", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "37dc88ef9a0abeddbe81053a6dd8fdfb13afb613045ea1eb4a5c815a74a3bde4", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.pytest_cache/v", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.pytest_cache/v/cache", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.pytest_cache/v/cache/nodeids", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "49897170c9d77d5454d0f6550ba0c931b1dc295434317ac0ca3544c67dc53dfc", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/.pytest_cache/v/cache/stepwise", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/inventory-playbook-v2.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6045114154ca1faa2de0fa327a5524d44a76354023bd461a5b0f69c889bf1fe7", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/Dockerfile_nginx", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "513be93943c1c05ff4ea2df90d9e439f41d51059ec4513ce0098f463f0c96822", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/proxy", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/proxy/ssl.conf", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0a4a35d53f3dc60c2c4931e50136c580ed1eeb8850c93eea12e0965248990e41", + "format": 1 + }, + { + "name": "roles/conjur_host_identity/tests/proxy/default.conf", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2bf362d9b43aac8f3271e92af5d180ab2e5e9621a91bb49d9819f458e89c8e74", + "format": 1 + }, + { + "name": "dev", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "dev/ansible.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a9af189b8c8d89c9abbde117964844485f11a1f39a571c4222054e28a289aac6", + "format": 1 + }, + { + "name": "dev/test_app_centos", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "dev/test_app_centos/Dockerfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0de86cd21721bcf47192e1cb659d6edf4b20ac7ebf8ce1b667fc2dec14b4fbdf", + "format": 1 + }, + { + "name": "dev/test_unit.sh", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2d7fd0d7f339f326c47c3bf29fb371e6f90748de5904cce4ef93a5c2868b31b7", + "format": 1 + }, + { + "name": "dev/test_app_ubuntu", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "dev/test_app_ubuntu/Dockerfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a589a57581799c71a9a0179d20cafac119423bf476b1283ffe64dee0dbb1327d", + "format": 1 + }, + { + "name": "dev/start.sh", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "65c0f0415e06b601b8bce9f41b4ef1b50bfc5f6e88f24eb91ee1fe2cd9665bf3", + "format": 1 + }, + { + "name": "dev/policy", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "dev/policy/root.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2cf74b90f4eabbb9a9be67afeb2cf63c35b447579cef5b70f6daf270509d4309", + "format": 1 + }, + { + "name": "dev/Dockerfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "04decc424cd79115cd13f014ed57bb9c053b97132cdb1983dce73d20dfb20e86", + "format": 1 + }, + { + "name": "dev/docker-compose.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ca35276332fda1a0029c08c4993856c65db0aac39b23f171c9cbed99fa1f7c48", + "format": 1 + }, + { + "name": "dev/playbooks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "dev/playbooks/inventory-setup", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "dev/playbooks/inventory-setup/inventory.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f1474fb6e66c0fbcdd6129332de95feab1e1222f64f1be45325f4eac5101614f", + "format": 1 + }, + { + "name": "dev/playbooks/inventory-setup/inventory-v2.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2e1c0d5018358dbe5bce37280e9d8c8fd6fc9f0ff85f4b8fefbfa4aa04defb37", + "format": 1 + }, + { + "name": "dev/playbooks/inventory-setup/inventory-playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5889c8007cb9273c2415a399b4099cc49ed12e41599409e79ee11183a66c6d33", + "format": 1 + }, + { + "name": "dev/playbooks/inventory-setup/inventory-playbook-v2.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4acbd2fe2d992b72af5085c1f74f1154b5843c679d723662529cd6f9b365ce5e", + "format": 1 + }, + { + "name": "dev/playbooks/conjur-identity-setup", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "dev/playbooks/conjur-identity-setup/conjur_role_playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bcd9272359c7694b8c02240ed1596f47d237b099bf00ee3b64d08295d0c7478c", + "format": 1 + }, + { + "name": "dev/Dockerfile_nginx", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "513be93943c1c05ff4ea2df90d9e439f41d51059ec4513ce0098f463f0c96822", + "format": 1 + }, + { + "name": "dev/proxy", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "dev/proxy/ssl.conf", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0a4a35d53f3dc60c2c4931e50136c580ed1eeb8850c93eea12e0965248990e41", + "format": 1 + }, + { + "name": "dev/proxy/default.conf", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2bf362d9b43aac8f3271e92af5d180ab2e5e9621a91bb49d9819f458e89c8e74", + "format": 1 + }, + { + "name": "CONTRIBUTING.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "51665e44857e861e04b64120a17ea6f6960a1ca496d9ef6e2fec24bc01f585b6", + "format": 1 + }, + { + "name": ".gitignore", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b38eece6dfedd018ef0a4a5aafc02ec38b1fd2c26b6046876238b814b5ac6a13", + "format": 1 + }, + { + "name": "SECURITY.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1e913fcef04d2f2652839b896dd875dd3268b67d4669105e0e4b1a0249ef843a", + "format": 1 + }, + { + "name": "requirements.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0a2f8c8f38472c11f47c93fe7ac69bb6e08b2d09dcc5a2b9fdd7054366822a21", + "format": 1 + }, + { + "name": "examples", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "examples/test.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "94fcc880e144e39d06fb0fd4957ca4aac77578627b509a110f4ec5b2ffc7f9ff", + "format": 1 + }, + { + "name": "Jenkinsfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "86a001994fd11e82fb1065a0448e4aca1ce8f3bb4d92b86d3b91285c97bd98c7", + "format": 1 + }, + { + "name": "meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "meta/runtime.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5d87483c5cc5fa8efe932acb8b6d203610070eaecf3eaf89244828331affdc59", + "format": 1 + }, + { + "name": "tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit/plugins", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit/plugins/lookup", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit/plugins/lookup/test_conjur_variable.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1094276de30412849f76efef2aa091a3b40f9491bb581a4190070ca33e65d7c1", + "format": 1 + }, + { + "name": "tests/unit/plugins/lookup/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "tests/unit/Dockerfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f3ddc9e66be63de38a509c3de747685d82f0ddf4d921260bcb9afe4a33c8f25b", + "format": 1 + }, + { + "name": "tests/unit/requirements.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d77bc26186f3301ae88c08e272549546ce9b746b881b9cc18873b71592ef9c39", + "format": 1 + }, + { + "name": "tests/sanity", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.10.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ae307769453795ad4a44b902d7b12b4c8fbaf0e14860dde658cd78a0dc4ae851", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.12.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "afec9c66a2cb034dbdbde017b83c2396fbd5522ca70176fe3bdb7c9890fffcaa", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.9.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b08ae705c45bd09b8e38926a50ba7f41b099bcd7eb954b9275398932fb5ef3af", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.13.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "afec9c66a2cb034dbdbde017b83c2396fbd5522ca70176fe3bdb7c9890fffcaa", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.14.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "15187a140306a1008f16190fbd19869ae04780436f3c424de932fc9e727e6c8c", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.11.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f14e70571eaed048c38d12d5d3ece414d8bd8b21ab2036b26dc5515e6ebf0b17", + "format": 1 + }, + { + "name": "tests/conjur_variable", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/.dockerignore", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1a0dc73ccd02fc377cf4cb1d99237e42335beeaf8c0bdb012dd4ecfb54790d57", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable-with-spaces-secret", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "450814057d9ff23fe172d1ab4261370e8c49e93429dea0ec5a5e54a90402044b", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable-with-authn-token-bad-cert", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "22ee749d5bbcc57247124f120ff952c4b120a8fb31b383c57c8d237f9dce6756", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable-bad-cert-path", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8aaab3b0c4135a32feb6e27b25c0a56c07e210554e52c8b7d5b0ff96e96f382a", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable-no-cert-provided", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "02fe519032146f888ee4917ab2e4e4634430e3228eb5e1b7e1b8d4a0cd1c72c9", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "da21a70004df7d5ede5b6de8f22309be77a2a2e2d63edeb87a9f8c788d3f0055", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable-into-file", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ff27dbeb102cd3c925f79f5783cacf6e461586af768c2cc6a051252d90eb8bd7", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable-with-authn-token", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2b78a9aeaaf0226879ccb95a40995425c212789dcd6ed8effb1e99e8442776ee", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable-bad-certs", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "78f002c0d5330875c83f68fa51aed9ad489351031f146093f83576a7434d11bd", + "format": 1 + }, + { + "name": "tests/conjur_variable/junit/retrieve-variable-disable-verify-certs", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "cff63e56362085e36639c36c9e4d5cb8717051b4b8f201be203b10d6a6d4875b", + "format": 1 + }, + { + "name": "tests/conjur_variable/policy", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/policy/root.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a14765439458912cff269b174d8d1630abbc8ff3ce634fb84ef3a3050d36e6dc", + "format": 1 + }, + { + "name": "tests/conjur_variable/Dockerfile", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "55f203234d81c41d08b6e13bca720243846b06ce1ab971da6b3535bcbef6623b", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/env", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e4e591758bdfdbe673f40afd9e81b4ccdd749a484d843b46f63e77d1e33c8108", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e1a6f8f4cded9369fbf9c6bc55f725cd0aa8da7ff1fba59e91b338511ed20736", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "afd74fa0ebdb6d7cbb79e10760b644c33850a03daaf9b5960f0b6a7030c666c0", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/env", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4d4140d2408d4370136030335f326ae051bbff50998d45f7ec5db6b6249d1168", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/bad-cert.pem", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7529afc89345f5dde282fb51014d158769d3fb22ddf20744d093eb8fa820b8d3", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "09328157b6fca097da34a7f2deec84b639c46476d8d9deefc445c55097603d58", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6f82d730f6f13a368ee69640beb3907fdddfb243e5b6e600c127b6154e7d67b5", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/env", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9f5febf65f45e537c0666df07ea12f0568f1ee5afa7bc9eef5a36370e6b5dfa4", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bb4764e18fcc10f83c16d10cbc4b7eac8c0abd2668f1b158649fc1a0d47df2c8", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7aacd0b2b04e7b1850906a76dbda5df814c59a78f8b5290eed154cac9655ed68", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bb4764e18fcc10f83c16d10cbc4b7eac8c0abd2668f1b158649fc1a0d47df2c8", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7aacd0b2b04e7b1850906a76dbda5df814c59a78f8b5290eed154cac9655ed68", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable/env", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e4e591758bdfdbe673f40afd9e81b4ccdd749a484d843b46f63e77d1e33c8108", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6bce626301d8259174bfa57b2bc7ff543b267f2f93be4a1a77df69b8cf515801", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "af47f2a134c9a33e2682f66cefe03002704c71557350674d5b5a58963251f6e3", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-into-file", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-into-file/env", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e4e591758bdfdbe673f40afd9e81b4ccdd749a484d843b46f63e77d1e33c8108", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-into-file/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b35ead7d25b79bf07011729173d288accd5a997296f4760373bd51cfeb3e6873", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-into-file/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-into-file/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8040a8b67b23b63706f3b4f79e6c080f26fbb1472906cab4a7146373b6dfd1b7", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/env", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8fa8ee6b4fb30d49d52e64a5fb70167ac0bdc7d968f18fe53219e1db475fcff9", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a57510d743d358c0405b3de73cbae3e5945c492fb8ca64be0d3777f1e4de811e", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "af47f2a134c9a33e2682f66cefe03002704c71557350674d5b5a58963251f6e3", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-certs", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-certs/env", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e1d90dec2be9f840d4f27dcfd2bf1c67be44c5d801ee57ea45c94ff6895ddf62", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-certs/bad-cert.pem", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7529afc89345f5dde282fb51014d158769d3fb22ddf20744d093eb8fa820b8d3", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-certs/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bb4764e18fcc10f83c16d10cbc4b7eac8c0abd2668f1b158649fc1a0d47df2c8", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-certs/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-bad-certs/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7aacd0b2b04e7b1850906a76dbda5df814c59a78f8b5290eed154cac9655ed68", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d94bc0b090fc07e738c0bfc05b3b6747850b8f06e5e290771d200efeb3044e35", + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "af47f2a134c9a33e2682f66cefe03002704c71557350674d5b5a58963251f6e3", + "format": 1 + }, + { + "name": "tests/conjur_variable/docker-compose.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c433a8af1060d174e8c03e99fa26da51092a24c007e5486a83de9e507854df9c", + "format": 1 + }, + { + "name": "tests/conjur_variable/pytest.ini", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4b8dce177a1820e68b4a821d858669035b849f9c5fbc4cfd6d4718325a7e69c8", + "format": 1 + }, + { + "name": "tests/conjur_variable/test.sh", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "40af14dc3993251c72b4a0d11075e999a1b8ef9076e41b15614e762e6dd94879", + "format": 1 + }, + { + "name": "tests/conjur_variable/.pytest_cache", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/.pytest_cache/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "73fd6fccdd802c419a6b2d983d6c3173b7da97558ac4b589edec2dfe443db9ad", + "format": 1 + }, + { + "name": "tests/conjur_variable/.pytest_cache/.gitignore", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3ed731b65d06150c138e2dadb0be0697550888a6b47eb8c45ecc9adba8b8e9bd", + "format": 1 + }, + { + "name": "tests/conjur_variable/.pytest_cache/CACHEDIR.TAG", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "37dc88ef9a0abeddbe81053a6dd8fdfb13afb613045ea1eb4a5c815a74a3bde4", + "format": 1 + }, + { + "name": "tests/conjur_variable/.pytest_cache/v", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/.pytest_cache/v/cache", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/.pytest_cache/v/cache/nodeids", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d58a2892e1f89b35c10fd58d24d7811dd7537e762c65d3b32decd33681206cee", + "format": 1 + }, + { + "name": "tests/conjur_variable/.pytest_cache/v/cache/stepwise", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", + "format": 1 + }, + { + "name": "tests/conjur_variable/Dockerfile_nginx", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "53cbc9253079dd1a19afb896e3839d9bd8b812d9473d769438c44eb10e03858c", + "format": 1 + }, + { + "name": "tests/conjur_variable/proxy", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/conjur_variable/proxy/ssl.conf", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "11bd8688bb233d0d366f16673a9892bf14aea34aa0d2fe40811ad5ca5028b490", + "format": 1 + }, + { + "name": "tests/conjur_variable/proxy/default.conf", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ffa77f3f6db4da0916c4c666fc6e5582a3584dc302a4852048a0b84c889ab7ea", + "format": 1 + }, + { + "name": "LICENSE", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e092618211b1d864e3caf325abbd567f997e6ffb98d9fb97188d4fa280334bbe", + "format": 1 + }, + { + "name": "CHANGELOG.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "cfc80a8bef07ed8c3f72a7c27774095d8033d59077a165f688efae49fb8ada77", + "format": 1 + } + ], + "format": 1 +}
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/Jenkinsfile b/ansible_collections/cyberark/conjur/Jenkinsfile new file mode 100644 index 000000000..01242da42 --- /dev/null +++ b/ansible_collections/cyberark/conjur/Jenkinsfile @@ -0,0 +1,127 @@ +#!/usr/bin/env groovy + +pipeline { + agent { label 'executor-v2' } + + options { + timestamps() + buildDiscarder(logRotator(numToKeepStr: '30')) + } + + stages { + stage('Validate') { + parallel { + stage('Changelog') { + steps { sh './ci/parse-changelog.sh' } + } + } + } + + stage('Run conjur_variable unit tests') { + steps { + sh './dev/test_unit.sh -r' + publishHTML (target : [allowMissing: false, + alwaysLinkToLastBuild: false, + keepAll: true, + reportDir: 'tests/output/reports/coverage=units/', + reportFiles: 'index.html', + reportName: 'Ansible Coverage Report', + reportTitles: 'Conjur Ansible Collection report']) + } + } + + stage('Run integration tests with Conjur Open Source') { + stages { + stage('Ansible v6 - latest') { + parallel { + stage('Testing conjur_variable lookup plugin') { + steps { + sh './ci/test.sh -d conjur_variable' + junit 'tests/conjur_variable/junit/*' + } + } + + stage('Testing conjur_host_identity role') { + steps { + sh './ci/test.sh -d conjur_host_identity' + junit 'roles/conjur_host_identity/tests/junit/*' + } + } + } + } + + stage('Ansible v5') { + when { + anyOf { + branch 'main' + buildingTag() + } + } + parallel { + stage('Testing conjur_variable lookup plugin') { + steps { + sh './ci/test.sh -v 5 -d conjur_variable' + junit 'tests/conjur_variable/junit/*' + } + } + + stage('Testing conjur_host_identity role') { + steps { + sh './ci/test.sh -v 5 -d conjur_host_identity' + junit 'roles/conjur_host_identity/tests/junit/*' + } + } + } + } + } + } + + stage('Run integration tests with Conjur Enterprise') { + stages { + stage("Testing conjur_variable lookup plugin") { + steps { + sh './ci/test.sh -e -d conjur_variable' + junit 'tests/conjur_variable/junit/*' + } + } + + stage("Testing conjur_host_identity role") { + steps { + sh './ci/test.sh -e -d conjur_host_identity' + junit 'roles/conjur_host_identity/tests/junit/*' + } + } + } + } + + stage('Build Release Artifacts') { + when { + anyOf { + branch 'main' + buildingTag() + } + } + + steps { + sh './ci/build_release' + archiveArtifacts 'cyberark-conjur-*.tar.gz' + } + } + + stage('Publish to Ansible Galaxy') { + when { + buildingTag() + } + + steps { + sh 'summon ./ci/publish_to_galaxy' + } + } + } + + post { + always { + cleanupAndNotify(currentBuild.currentResult) + } + } +}
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/LICENSE b/ansible_collections/cyberark/conjur/LICENSE new file mode 100644 index 000000000..af8afbaf4 --- /dev/null +++ b/ansible_collections/cyberark/conjur/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2020 CyberArk Software Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ansible_collections/cyberark/conjur/MANIFEST.json b/ansible_collections/cyberark/conjur/MANIFEST.json new file mode 100644 index 000000000..e3ecbed80 --- /dev/null +++ b/ansible_collections/cyberark/conjur/MANIFEST.json @@ -0,0 +1,43 @@ +{ + "collection_info": { + "namespace": "cyberark", + "name": "conjur", + "version": "1.2.0", + "authors": [ + "CyberArk Business Development (@cyberark-bizdev)", + "(@cyberark/community-and-integrations-team)" + ], + "readme": "README.md", + "tags": [ + "cyberark", + "conjur", + "access", + "security", + "account", + "vault", + "identity", + "credential", + "secret", + "privileged", + "devops" + ], + "description": "This is a Collection of the CyberArk Conjur/DAP toolkit.", + "license": [ + "Apache-2.0" + ], + "license_file": null, + "dependencies": {}, + "repository": "https://github.com/cyberark/ansible-conjur-collection", + "documentation": null, + "homepage": null, + "issues": "https://github.com/cyberark/ansible-conjur-collection/issues" + }, + "file_manifest_file": { + "name": "FILES.json", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4c7843e25d53f8c2c8b96576286bfc6b138b4d24784289888c832f761992aadf", + "format": 1 + }, + "format": 1 +}
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/README.md b/ansible_collections/cyberark/conjur/README.md new file mode 100644 index 000000000..7b9b35471 --- /dev/null +++ b/ansible_collections/cyberark/conjur/README.md @@ -0,0 +1,228 @@ +# CyberArk Ansible Conjur Collection + +This collection contains components to be used with CyberArk Conjur & Conjur Enterprise +hosted in [Ansible Galaxy](https://galaxy.ansible.com/cyberark/conjur). + +## Table of Contents + +* [Certification Level](#certification-level) +* [Requirements](#requirements) +* [Installation](#installation) +* [Conjur Ansible Role](#conjur-ansible-role) + + [Usage](#usage) + + [Role Variables](#role-variables) + + [Example Playbook](#example-playbook) + + [Summon & Service Managers](#summon---service-managers) + + [Recommendations](#recommendations) +* [Conjur Ansible Lookup Plugin](#conjur-ansible-lookup-plugin) + + [Environment variables](#environment-variables) + + [Role Variables](#role-variables-1) + + [Examples](#examples) + - [Retrieve a secret in a Playbook](#retrieve-a-secret-in-a-playbook) + - [Retrieve a private key in an Inventory file](#retrieve-a-private-key-in-an-inventory-file) +* [Contributing](#contributing) +* [License](#license) + +<!-- Table of contents generated with markdown-toc +http://ecotrust-canada.github.io/markdown-toc/ --> + +## Certification Level + +![](https://img.shields.io/badge/Certification%20Level-Certified-6C757D?link=https://github.com/cyberark/community/blob/main/Conjur/conventions/certification-levels.md) + +This repo is a **Certified** level project. It's been reviewed by CyberArk to +verify that it will securely work with CyberArk Enterprise as documented. In +addition, CyberArk offers Enterprise-level support for these features. For more +detailed information on our certification levels, see +[our community guidelines](https://github.com/cyberark/community/blob/main/Conjur/conventions/certification-levels.md#community). + +## Requirements + +- An instance of [CyberArk Conjur Open Source](https://www.conjur.org) v1.x+ or [CyberArk + Conjur Enterprise](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Resources/_TopNav/cc_Home.htm) + (formerly DAP) v10.x+ accessible from the target node +- Ansible >= 2.9 + +## Using ansible-conjur-collection with Conjur Open Source + +Are you using this project with [Conjur Open Source](https://github.com/cyberark/conjur)? Then we +**strongly** recommend choosing the version of this project to use from the latest [Conjur OSS +suite release](https://docs.conjur.org/Latest/en/Content/Overview/Conjur-OSS-Suite-Overview.html). +Conjur maintainers perform additional testing on the suite release versions to ensure +compatibility. When possible, upgrade your Conjur version to match the +[latest suite release](https://docs.conjur.org/Latest/en/Content/ReleaseNotes/ConjurOSS-suite-RN.htm); +when using integrations, choose the latest suite release that matches your Conjur version. For any +questions, please contact us on [Discourse](https://discuss.cyberarkcommons.org/c/conjur/5). + +## Installation + +From terminal, run the following command: +```sh +ansible-galaxy collection install cyberark.conjur +``` + +## Conjur Ansible Role + +This Ansible role provides the ability to grant Conjur machine identity to a host. Based on that +identity, secrets can then be retrieved securely using the [Conjur Lookup +Plugin](#conjur-ansible-lookup-plugin) or using the [Summon](https://github.com/cyberark/summon) +tool (installed on hosts with identities created by this role). + +### Usage + +The Conjur role provides a method to establish the Conjur identity of a remote node with Ansible. +The node can then be granted least-privilege access to retrieve the secrets it needs in a secure +manner. + +### Role Variables + +* `conjur_appliance_url` _(Required)_: URL of the running Conjur service +* `conjur_account` _(Required)_: Conjur account name +* `conjur_host_factory_token` _(Required)_: [Host + Factory](https://developer.conjur.net/reference/services/host_factory/) token for layer + enrollment. This should be specified in the environment on the Ansible controlling host. +* `conjur_host_name` _(Required)_: Name of the host to be created. +* `conjur_ssl_certificate`: Public SSL certificate of the Conjur endpoint +* `conjur_validate_certs`: Boolean value to indicate if the Conjur endpoint should validate + certificates +* `state`: Specifies whether to install of uninstall the Role on the specified nodes +* `summon.version`: version of Summon to install. Default is `0.8.2`. +* `summon_conjur.version`: version of Summon-Conjur provider to install. Default is `0.5.3`. + +The variables not marked _`(Required)`_ are required for running with an HTTPS Conjur endpoint. + +### Example Playbook + +Configure a remote node with a Conjur identity and Summon: +```yml +- hosts: servers + roles: + - role: cyberark.conjur.conjur_host_identity + conjur_appliance_url: 'https://conjur.myorg.com' + conjur_account: 'myorg' + conjur_host_factory_token: "{{ lookup('env', 'HFTOKEN') }}" + conjur_host_name: "{{ inventory_hostname }}" + conjur_ssl_certificate: "{{ lookup('file', '/path/to/conjur.pem') }}" + conjur_validate_certs: yes +``` + +This example: +- Registers the host `{{ inventory_hostname }}` with Conjur, adding it into the Conjur policy layer + defined for the provided host factory token. +- Installs Summon with the Summon Conjur provider for secret retrieval from Conjur. + +### Role Cleanup + +Executing the following playbook will clean up configuration and identity files +written to the specified remote nodes, as well as uninstalling Summon and the +Summon Conjur provider: +```yml +- hosts: servers + roles: + - role: cyberark.conjur.conjur_host_identity + state: absent +``` + +### Summon & Service Managers + +With Summon installed, using Conjur with a Service Manager (like systemd) becomes a snap. Here's a +simple example of a `systemd` file connecting to Conjur: + +```ini +[Unit] +Description=DemoApp +After=network-online.target + +[Service] +User=DemoUser +#Environment=CONJUR_MAJOR_VERSION=4 +ExecStart=/usr/local/bin/summon --yaml 'DB_PASSWORD: !var staging/demoapp/database/password' /usr/local/bin/myapp +``` + +> Note: When connecting to Conjur 4 (Conjur Enterprise), Summon requires the environment variable +`CONJUR_MAJOR_VERSION` set to `4`. You can provide it by uncommenting the relevant line above. + +The above example uses Summon to retrieve the password stored in `staging/myapp/database/password`, +set it to an environment variable `DB_PASSWORD`, and provide it to the demo application process. +Using Summon, the secret is kept off disk. If the service is restarted, Summon retrieves the +password as the application is started. + +### Recommendations + +- Add `no_log: true` to each play that uses sensitive data, otherwise that data can be printed to + the logs. + +- Set the Ansible files to minimum permissions. Ansible uses the permissions of the user that runs + it. + +## Conjur Ansible Lookup Plugin + +Fetch credentials from CyberArk Conjur using the controlling host's Conjur identity or environment +variables. + +The controlling host running Ansible must have a Conjur identity, provided for example by the +[ConjurAnsible role](#conjur-ansible-role). + +### Environment variables + +The following environment variables will be used by the lookup plugin to authenticate with the +Conjur host, if they are present on the system running the lookup plugin. + +- `CONJUR_ACCOUNT` : The Conjur account name +- `CONJUR_APPLIANCE_URL` : URL of the running Conjur service +- `CONJUR_CERT_FILE` : Path to the Conjur certificate file +- `CONJUR_AUTHN_LOGIN` : A valid Conjur host username +- `CONJUR_AUTHN_API_KEY` : The api key that corresponds to the Conjur host username +- `CONJUR_AUTHN_TOKEN_FILE` : Path to a file containing a valid Conjur auth token + +### Role Variables + +None. + +### Examples + +#### Retrieve a secret in a Playbook + +```yaml +--- +- hosts: localhost + tasks: + - name: Lookup variable in Conjur + debug: + msg: "{{ lookup('cyberark.conjur.conjur_variable', '/path/to/secret') }}" +``` + +#### Retrieve a private key in an Inventory file + +```yaml +--- +ansible_host: <host> +ansible_ssh_private_key_file: "{{ lookup('cyberark.conjur.conjur_variable', 'path/to/secret-id', as_file=True) }}" +``` + +**Note:** Using the `as_file=True` condition, the private key is stored in a temporary file and its path is written +in `ansible_ssh_private_key_file`. + +## Contributing + +We welcome contributions of all kinds to this repository. For instructions on how to get started and +descriptions of our development workflows, please see our [contributing guide][contrib]. + +[contrib]: https://github.com/cyberark/ansible-conjur-collection/blob/main/CONTRIBUTING.md + +## License + +Copyright (c) 2020 CyberArk Software Ltd. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is +distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing permissions and limitations under the +License. + +For the full license text see [`LICENSE`](LICENSE). diff --git a/ansible_collections/cyberark/conjur/SECURITY.md b/ansible_collections/cyberark/conjur/SECURITY.md new file mode 100644 index 000000000..5315a3953 --- /dev/null +++ b/ansible_collections/cyberark/conjur/SECURITY.md @@ -0,0 +1,42 @@ +# Security Policies and Procedures + +This document outlines security procedures and general policies for the CyberArk Conjur +suite of tools and products. + + * [Reporting a Bug](#reporting-a-bug) + * [Disclosure Policy](#disclosure-policy) + * [Comments on this Policy](#comments-on-this-policy) + +## Reporting a Bug + +The CyberArk Conjur team and community take all security bugs in the Conjur suite seriously. +Thank you for improving the security of the Conjur suite. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing the lead maintainers at security@conjur.org. + +The maintainers will acknowledge your email within 2 business days. Subsequently, we will +send a more detailed response within 2 business days of our acknowledgement indicating +the next steps in handling your report. After the initial reply to your report, the security +team will endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +## Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + + * Confirm the problem and determine the affected versions. + * Audit code to find any potential similar problems. + * Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible. + +## Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. diff --git a/ansible_collections/cyberark/conjur/ci/build_release b/ansible_collections/cyberark/conjur/ci/build_release new file mode 100755 index 000000000..07baf8898 --- /dev/null +++ b/ansible_collections/cyberark/conjur/ci/build_release @@ -0,0 +1,14 @@ +#!/bin/bash + +set -euo pipefail + +TOP_LEVEL_DIR="$(cd "$(dirname "$BASH_SOURCE")"; pwd)/.." + +pushd "$TOP_LEVEL_DIR" >/dev/null + docker run --rm -t \ + -v "$TOP_LEVEL_DIR:/collection" \ + python:3 /bin/bash -c " + pip install ansible + ansible-galaxy collection build --force --output /collection/. /collection + " +popd >/dev/null diff --git a/ansible_collections/cyberark/conjur/ci/parse-changelog.sh b/ansible_collections/cyberark/conjur/ci/parse-changelog.sh new file mode 100755 index 000000000..be7d8270e --- /dev/null +++ b/ansible_collections/cyberark/conjur/ci/parse-changelog.sh @@ -0,0 +1,6 @@ +#!/bin/bash -ex + +docker run \ + --rm \ + --volume "${PWD}/CHANGELOG.md":/CHANGELOG.md \ + cyberark/parse-a-changelog
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/ci/publish_to_galaxy b/ansible_collections/cyberark/conjur/ci/publish_to_galaxy new file mode 100755 index 000000000..44a2aa16d --- /dev/null +++ b/ansible_collections/cyberark/conjur/ci/publish_to_galaxy @@ -0,0 +1,18 @@ +#!/bin/bash + +set -euo pipefail + +# Strip the 'v' from the Tag Name +TAG=${TAG_NAME//"v"} + +TOP_LEVEL_DIR="$(cd "$(dirname "$BASH_SOURCE")"; pwd)/.." + +pushd "$TOP_LEVEL_DIR" >/dev/null + docker run --rm -t \ + -e GALAXY_API_KEY \ + -v "$TOP_LEVEL_DIR:/collection" \ + python:3 /bin/bash -c " + pip install ansible + ansible-galaxy collection publish --api-key \${GALAXY_API_KEY} /collection/cyberark-conjur-${TAG}.tar.gz + " +popd >/dev/null diff --git a/ansible_collections/cyberark/conjur/ci/test.sh b/ansible_collections/cyberark/conjur/ci/test.sh new file mode 100755 index 000000000..2a535d750 --- /dev/null +++ b/ansible_collections/cyberark/conjur/ci/test.sh @@ -0,0 +1,107 @@ +#!/bin/bash -ex + +# Test runner for Ansible Conjur Collection + +# Test subdirectors containing a `test.sh` file +test_directories=("conjur_variable") + +# Roles containing a test subdirectory +role_directories=("conjur_host_identity") + +# Target directory that can be manually set by passing a value to the `-d` flag +target="" + +# Flags to be applied to testing scripts +flags="" + +declare -x ANSIBLE_VERSION="${ANSIBLE_VERSION:-6}" + +# Print usage instructions +function help { + echo "Test runner for Ansible Conjur Collection" + + echo "-a Run all test files in default test directories" + echo "-v <ver> Run tests against the given Ansible major version" + echo "-d <arg> Run test file in given directory. Valid options are: ${test_directories[*]} all" + echo "-e Run tests against Conjur Enterprise. Default: Conjur Open Source" + echo " This option is currently only available when testing against the conjur_variable plugin" + echo "-h View help and available commands" + exit 1 +} + +# Run a `test.sh` file in a given subdirectory of the top-level `tests` directory +# Expected directory structure is "tests/<plugin>/test.sh" +function run_test { + pushd "${PWD}/tests/${1}" + echo "Running ${1} tests..." + ./test.sh "$flags" + popd +} + +# Run a `test.sh` file for a given role +# Expected directory structure is "roles/<role>/tests/test.sh" +function run_role_test { + pushd "${PWD}/roles/${1}/tests" + echo "Running ${1} tests..." + ./test.sh "$flags" + popd +} + +# Handles input to dictate wether all tests should be ran, or just one set +function handle_input { + if [[ -n ${target} ]]; then + for test_dir in "${test_directories[@]}"; do + if [[ ${target} == "${test_dir}" ]]; then + run_test ${target} + exit 0 + fi + done + for test_dir in "${role_directories[@]}"; do + if [[ ${target} == "${test_dir}" ]]; then + run_role_test ${target} + exit 0 + fi + done + echo "Error: unrecognized test directory given: ${target}" + echo "" + help + else + echo "Running all tests..." + for test_dir in "${test_directories[@]}"; do + run_test "${test_dir}" + done + for test_dir in "${role_directories[@]}"; do + run_role_test "${test_dir}" + done + exit 0 + fi +} + +# Exit if no input given +if [[ $# -eq 0 ]] ; then + echo "Error: No test directory or flag given" + echo "" + help +fi + +while getopts ad:ehv: option; do + case "$option" in + a) handle_input + ;; + d) target=${OPTARG} + handle_input + ;; + e) flags="-e" + ;; + h) help + ;; + v) ANSIBLE_VERSION="${OPTARG}" + ;; + * ) + echo "$1 is not a valid option" + help + exit 1 + ;; + esac +done + diff --git a/ansible_collections/cyberark/conjur/dev/Dockerfile b/ansible_collections/cyberark/conjur/dev/Dockerfile new file mode 100644 index 000000000..f8ebcaccb --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/Dockerfile @@ -0,0 +1,38 @@ +FROM ubuntu:20.04 + +ENV DEBIAN_FRONTEND=noninteractive + +WORKDIR /cyberark + +# install python 3 +RUN apt-get update && \ + apt-get install -y python3-pip && \ + pip3 install --upgrade pip + +# install ansible and its test tool +RUN pip3 install ansible pytest-testinfra + +# install docker installation requirements +RUN apt-get update && \ + apt-get install -y apt-transport-https \ + ca-certificates \ + curl \ + software-properties-common + +# install docker +RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +RUN add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + +RUN apt-get update && \ + apt-get -y install docker-ce + +# NOTE: Everything above is copied from REPO_ROOT/tests/conjur_variable/Dockerfile. It defines a +# standard container image for running ansible tests + +# install ruby +RUN apt-get update && apt-get install -y gcc build-essential +RUN apt-add-repository -y ppa:brightbox/ruby-ng && apt-get update && apt-get install -y ruby2.7 ruby2.7-dev +RUN gem install conjur-cli diff --git a/ansible_collections/cyberark/conjur/dev/Dockerfile_nginx b/ansible_collections/cyberark/conjur/dev/Dockerfile_nginx new file mode 100644 index 000000000..d9f18c7bd --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/Dockerfile_nginx @@ -0,0 +1,16 @@ +FROM nginx:1.13.3 + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y iputils-ping procps openssl && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /etc/nginx/ + +COPY proxy/ssl.conf /etc/ssl/openssl.cnf + +RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -config /etc/ssl/openssl.cnf -extensions v3_ca \ + -keyout cert.key -out cert.crt + +COPY proxy/default.conf /etc/nginx/conf.d/default.conf diff --git a/ansible_collections/cyberark/conjur/dev/ansible.cfg b/ansible_collections/cyberark/conjur/dev/ansible.cfg new file mode 100644 index 000000000..5b1d8246b --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/ansible.cfg @@ -0,0 +1,7 @@ +[defaults] +host_key_checking = False +error_on_undefined_vars = True +timeout = 60 +inventory = inventory.tmp +roles_path = /cyberark +remote_tmp = /tmp diff --git a/ansible_collections/cyberark/conjur/dev/docker-compose.yml b/ansible_collections/cyberark/conjur/dev/docker-compose.yml new file mode 100644 index 000000000..8e1d2dd9f --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/docker-compose.yml @@ -0,0 +1,74 @@ +version: '3' +services: + ansible: + build: + context: . + dockerfile: Dockerfile + command: /bin/sleep 1d + environment: + CONJUR_APPLIANCE_URL: http://conjur:3000 + CONJUR_ACCOUNT: cucumber + CONJUR_AUTHN_LOGIN: host/ansible/ansible-master + CONJUR_AUTHN_API_KEY: ${ANSIBLE_CONJUR_AUTHN_API_KEY} + CONJUR_CUSTOM_AUTHN_API_KEY: ${CUSTOM_CONJUR_AUTHN_API_KEY} + COMPOSE_PROJECT_NAME: ${COMPOSE_PROJECT_NAME} + # NOTE: Explicitly setting the ANSIBLE_CONFIG envvar avoids Ansible ignoring + # the configuration because it is in a world-writable working directory, + # see https://docs.ansible.com/ansible/latest/reference_appendices/config.html#avoiding-security-risks-with-ansible-cfg-in-the-current-directory. + ANSIBLE_CONFIG: ./ansible.cfg + volumes: + - ../roles/conjur_host_identity:/cyberark/cyberark.conjur.conjur-host-identity/ + - .:/cyberark/dev/ + - /var/run/docker.sock:/var/run/docker.sock + + pg: + image: postgres:9.3 + + conjur: + image: cyberark/conjur + command: server -a cucumber -p 3000 + environment: + CONJUR_APPLIANCE_URL: http://localhost:3000 + DATABASE_URL: postgres://postgres@pg/postgres + CONJUR_DATA_KEY: "W0BuL8iTr/7QvtjIluJbrb5LDAnmXzmcpxkqihO3dXA=" + networks: + - default + links: + - pg + + conjur_cli: + image: cyberark/conjur-cli:5-latest + entrypoint: [] + command: sleep infinity + environment: + CONJUR_APPLIANCE_URL: http://conjur:3000 + CONJUR_ACCOUNT: cucumber + CONJUR_AUTHN_LOGIN: admin + CONJUR_AUTHN_API_KEY: ${CLI_CONJUR_AUTHN_API_KEY} + volumes: + - ./policy:/policy + networks: + - default + links: + - conjur + + test_app_ubuntu: + build: ./test_app_ubuntu + entrypoint: sleep + command: infinity + + test_app_centos: + build: ./test_app_centos + entrypoint: sleep + command: infinity + + conjur-proxy-nginx: + build: + context: . + dockerfile: Dockerfile_nginx + entrypoint: nginx-debug -g 'daemon off;' + environment: + TERM: xterm + depends_on: + - conjur + - conjur_cli diff --git a/ansible_collections/cyberark/conjur/dev/playbooks/conjur-identity-setup/conjur_role_playbook.yml b/ansible_collections/cyberark/conjur/dev/playbooks/conjur-identity-setup/conjur_role_playbook.yml new file mode 100644 index 000000000..6972b50ed --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/playbooks/conjur-identity-setup/conjur_role_playbook.yml @@ -0,0 +1,11 @@ +--- +- name: Configuring conjur identity on remote hosts + hosts: testapp + roles: + - role: "cyberark.conjur.conjur-host-identity" + conjur_account: cucumber + conjur_appliance_url: "https://conjur-proxy-nginx" + conjur_host_factory_token: "{{lookup('env', 'HFTOKEN')}}" + conjur_host_name: "conjur_{{ ansible_hostname }}" + conjur_ssl_certificate: "{{lookup('file', '../../conjur.pem')}}" + conjur_validate_certs: yes diff --git a/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-playbook-v2.yml b/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-playbook-v2.yml new file mode 100644 index 000000000..3bf92eaf8 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-playbook-v2.yml @@ -0,0 +1,6 @@ +--- +- name: Compile inventory template locally + hosts: localhost + tasks: + - name: compile inventory template + template: src=inventory-v2.j2 dest=/cyberark/dev/inventory.tmp diff --git a/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-playbook.yml b/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-playbook.yml new file mode 100644 index 000000000..e61ee8053 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-playbook.yml @@ -0,0 +1,6 @@ +--- +- name: Compile inventory template locally + hosts: localhost + tasks: + - name: compile inventory template + template: src=inventory.j2 dest=/cyberark/dev/inventory.tmp diff --git a/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-v2.j2 b/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-v2.j2 new file mode 100644 index 000000000..4a004fb13 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-v2.j2 @@ -0,0 +1,6 @@ +[testapp] +{{ lookup('env','COMPOSE_PROJECT_NAME') }}-test_app_ubuntu-[1:2] ansible_connection=docker +{{ lookup('env','COMPOSE_PROJECT_NAME') }}-test_app_centos-[1:2] ansible_connection=docker + +[ansible] +{{ lookup('env','COMPOSE_PROJECT_NAME') }}-ansible-1 ansible_connection=docker diff --git a/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory.j2 b/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory.j2 new file mode 100644 index 000000000..62d48ef82 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory.j2 @@ -0,0 +1,6 @@ +[testapp] +{{ lookup('env','COMPOSE_PROJECT_NAME') }}_test_app_ubuntu_[1:2] ansible_connection=docker +{{ lookup('env','COMPOSE_PROJECT_NAME') }}_test_app_centos_[1:2] ansible_connection=docker + +[ansible] +{{ lookup('env','COMPOSE_PROJECT_NAME') }}_ansible_1 ansible_connection=docker diff --git a/ansible_collections/cyberark/conjur/dev/policy/root.yml b/ansible_collections/cyberark/conjur/dev/policy/root.yml new file mode 100644 index 000000000..0309cf702 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/policy/root.yml @@ -0,0 +1,32 @@ +--- +- !policy + id: ansible + annotations: + description: Policy for Ansible master and remote hosts + body: + + - !host + id: ansible-master + annotations: + description: Host for running Ansible on remote targets + + - !layer &remote_hosts_layer + id: remote_hosts + annotations: + description: Layer for Ansible remote hosts + + - !host-factory + id: ansible-factory + annotations: + description: Factory to create new hosts for ansible + layer: [ *remote_hosts_layer ] + + - !variable + id: target-password + annotations: + description: Password needed by the Ansible remote machine + + - !permit + role: *remote_hosts_layer + privileges: [ execute ] + resources: [ !variable target-password ] diff --git a/ansible_collections/cyberark/conjur/dev/proxy/default.conf b/ansible_collections/cyberark/conjur/dev/proxy/default.conf new file mode 100644 index 000000000..db2153a71 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/proxy/default.conf @@ -0,0 +1,33 @@ +server { + listen 80; + return 301 https://conjur$request_uri; +} + +server { + listen 443; + server_name localhost; + ssl_certificate /etc/nginx/cert.crt; + ssl_certificate_key /etc/nginx/cert.key; + + ssl on; + ssl_session_cache builtin:1000 shared:SSL:10m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; + ssl_prefer_server_ciphers on; + + access_log /var/log/nginx/access.log; + + location / { + proxy_pass http://conjur:3000; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + +} diff --git a/ansible_collections/cyberark/conjur/dev/proxy/ssl.conf b/ansible_collections/cyberark/conjur/dev/proxy/ssl.conf new file mode 100644 index 000000000..e78716b27 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/proxy/ssl.conf @@ -0,0 +1,39 @@ +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +req_extensions = req_ext +distinguished_name = dn +x509_extensions = v3_ca # The extentions to add to the self signed cert +req_extensions = v3_req +x509_extensions = usr_cert + +[ dn ] +C=IL +ST=Israel +L=TLV +O=Onyx +OU=CyberArk +CN=conjur-proxy-nginx + +[ usr_cert ] +basicConstraints=CA:FALSE +nsCertType = client, server, email +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection +nsComment = "OpenSSL Generated Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +[ v3_req ] +extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +subjectAltName = @alt_names + +[ alt_names ] +DNS.1 = localhost +DNS.2 = conjur-proxy-nginx +IP.1 = 127.0.0.1 diff --git a/ansible_collections/cyberark/conjur/dev/start.sh b/ansible_collections/cyberark/conjur/dev/start.sh new file mode 100755 index 000000000..f9ba8b525 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/start.sh @@ -0,0 +1,113 @@ +#!/bin/bash +set -ex + + +declare -x ANSIBLE_CONJUR_AUTHN_API_KEY='' +declare -x CLI_CONJUR_AUTHN_API_KEY='' +declare cli_cid='' +declare conjur_cid='' +declare ansible_cid='' +# normalises project name by filtering non alphanumeric characters and transforming to lowercase +declare -x COMPOSE_PROJECT_NAME + +COMPOSE_PROJECT_NAME=$(echo "${BUILD_TAG:-ansible-pluging-testing}-conjur-host-identity" | sed -e 's/[^[:alnum:]]//g' | tr '[:upper:]' '[:lower:]') +export COMPOSE_PROJECT_NAME + +# get conjur client auth api key +function api_key_for { + local role_id=$1 + if [ -n "$role_id" ] + then + docker exec "${conjur_cid}" rails r "print Credentials['${role_id}'].api_key" + else + echo ERROR: api_key_for called with no argument 1>&2 + exit 1 + fi +} + +function hf_token { + docker exec "${cli_cid}" bash -c 'conjur hostfactory tokens create --duration-days=5 ansible/ansible-factory | jq -r ".[0].token"' +} + +function setup_conjur { + echo "---- setting up conjur ----" + # run policy + docker exec "${cli_cid}" conjur policy load root /policy/root.yml + # set secret values + docker exec "${cli_cid}" bash -ec 'conjur variable values add ansible/target-password target_secret_password' +} + +function setup_conjur_identities { + echo "---scale up inventory nodes and setup the conjur identity there---" + teardown_and_setup + docker exec "${ansible_cid}" env HFTOKEN="$(hf_token)" bash -ec " + cd dev + ansible-playbook playbooks/conjur-identity-setup/conjur_role_playbook.yml" +} + + # Scale up inventory nodes +function teardown_and_setup { + docker-compose up -d --force-recreate --scale test_app_ubuntu=2 test_app_ubuntu + docker-compose up -d --force-recreate --scale test_app_centos=2 test_app_centos +} + +function wait_for_server { + # shellcheck disable=SC2016 + docker exec "${cli_cid}" bash -ec ' + for i in $( seq 20 ); do + curl -o /dev/null -fs -X OPTIONS ${CONJUR_APPLIANCE_URL} > /dev/null && echo "server is up" && break + echo "." + sleep 2 + done + ' +} + +function fetch_ssl_cert { + (docker-compose exec -T conjur-proxy-nginx cat cert.crt) > conjur.pem +} + +function generate_inventory { + # Use a different inventory file for docker-compose v1 and v2 or later + playbook_file="inventory-playbook-v2.yml" + compose_ver=$(docker-compose version --short) + if [[ $compose_ver == "1"* ]]; then + playbook_file="inventory-playbook.yml" + fi + + # uses .j2 template to generate inventory prepended with COMPOSE_PROJECT_NAME + docker-compose exec -T ansible bash -ec " + cd dev + ansible-playbook playbooks/inventory-setup/$playbook_file + " +} + +function clean { + echo 'Removing dev environment' + echo '---' + docker-compose down -v + rm -rf inventory.tmp +} + +function main() { + clean + docker-compose up -d --build + generate_inventory + + conjur_cid=$(docker-compose ps -q conjur) + cli_cid=$(docker-compose ps -q conjur_cli) + fetch_ssl_cert + wait_for_server + + CLI_CONJUR_AUTHN_API_KEY=$(api_key_for 'cucumber:user:admin') + docker-compose up -d conjur_cli + + cli_cid=$(docker-compose ps -q conjur_cli) + setup_conjur + + ANSIBLE_CONJUR_AUTHN_API_KEY=$(api_key_for 'cucumber:host:ansible/ansible-master') + docker-compose up -d ansible + + ansible_cid=$(docker-compose ps -q ansible) + setup_conjur_identities +} + main
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/dev/test_app_centos/Dockerfile b/ansible_collections/cyberark/conjur/dev/test_app_centos/Dockerfile new file mode 100644 index 000000000..ee474e7bf --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/test_app_centos/Dockerfile @@ -0,0 +1,4 @@ +FROM centos:7 + +# Install Python so Ansible can run against node +RUN yum update -y && yum install -y python3 diff --git a/ansible_collections/cyberark/conjur/dev/test_app_ubuntu/Dockerfile b/ansible_collections/cyberark/conjur/dev/test_app_ubuntu/Dockerfile new file mode 100644 index 000000000..1721241ba --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/test_app_ubuntu/Dockerfile @@ -0,0 +1,5 @@ +FROM ubuntu:20.04 + +# Install Python so Ansible can run against node +RUN apt-get update -y && apt-get install -y python3-minimal + diff --git a/ansible_collections/cyberark/conjur/dev/test_unit.sh b/ansible_collections/cyberark/conjur/dev/test_unit.sh new file mode 100755 index 000000000..0a00da865 --- /dev/null +++ b/ansible_collections/cyberark/conjur/dev/test_unit.sh @@ -0,0 +1,47 @@ +#!/bin/bash -eu + +ansible_version="stable-2.10" +python_version="3.9" +gen_report="false" + +cd "$(dirname "$0")"/.. + +function print_usage() { + cat << EOF +Run unit tests for Conjur Variable Lookup plugin. + +./ansibletest.sh [options] + +-a <version> Run tests against specified Ansible version (Default: stable-2.10) +-p <version> Run tests against specified Python version (Default: 3.9) +-r Generate test coverage report +EOF +} + +while getopts 'a:p:r' flag; do + case "${flag}" in + a) ansible_version="${OPTARG}" ;; + p) python_version="${OPTARG}" ;; + r) gen_report="true" ;; + *) print_usage + exit 1 ;; + esac +done + +test_cmd="ansible-test units -v --python $python_version" +if [[ "$gen_report" == "true" ]]; then + test_cmd="ansible-test coverage erase; + $test_cmd --coverage; + ansible-test coverage html --requirements --group-by command; + " +fi + +docker build \ + --build-arg PYTHON_VERSION="${python_version}" \ + --build-arg ANSIBLE_VERSION="${ansible_version}" \ + -t pytest-tools:latest \ + -f tests/unit/Dockerfile . +docker run --rm \ + -v "${PWD}/":/ansible_collections/cyberark/conjur/ \ + -w /ansible_collections/cyberark/conjur/tests/unit/ \ + pytest-tools:latest /bin/bash -c "$test_cmd" diff --git a/ansible_collections/cyberark/conjur/examples/test.yml b/ansible_collections/cyberark/conjur/examples/test.yml new file mode 100644 index 000000000..9f9ad15ad --- /dev/null +++ b/ansible_collections/cyberark/conjur/examples/test.yml @@ -0,0 +1,11 @@ +--- + - hosts: localhost + + tasks: + - name: Lookup variable in Conjur + debug: + msg: "{{ lookup('cyberark.conjur.conjur_variable', '/path/to/secret') }}" + + - name: Lookup variable in Conjur to not validate certs (in case of self-signed) + debug: + msg: "{{ lookup('cyberark.conjur.conjur_variable', '/path/to/secret', validate_certs=false) }}" diff --git a/ansible_collections/cyberark/conjur/meta/runtime.yml b/ansible_collections/cyberark/conjur/meta/runtime.yml new file mode 100644 index 000000000..58bc85789 --- /dev/null +++ b/ansible_collections/cyberark/conjur/meta/runtime.yml @@ -0,0 +1,2 @@ +--- + requires_ansible: '>=2.9' diff --git a/ansible_collections/cyberark/conjur/plugins/lookup/conjur_variable.py b/ansible_collections/cyberark/conjur/plugins/lookup/conjur_variable.py new file mode 100644 index 000000000..8b523c6c5 --- /dev/null +++ b/ansible_collections/cyberark/conjur/plugins/lookup/conjur_variable.py @@ -0,0 +1,367 @@ +# (c) 2020 CyberArk Software Ltd. All rights reserved. +# (c) 2018 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = """ + name: conjur_variable + version_added: "1.0.2" + short_description: Fetch credentials from CyberArk Conjur. + author: + - CyberArk BizDev (@cyberark-bizdev) + description: + Retrieves credentials from Conjur using the controlling host's Conjur identity + or environment variables. + Environment variables could be CONJUR_ACCOUNT, CONJUR_APPLIANCE_URL, CONJUR_CERT_FILE, CONJUR_AUTHN_LOGIN, CONJUR_AUTHN_API_KEY, CONJUR_AUTHN_TOKEN_FILE + Conjur info - U(https://www.conjur.org/). + requirements: + - 'The controlling host running Ansible has a Conjur identity. + (More: U(https://docs.conjur.org/latest/en/Content/Get%20Started/key_concepts/machine_identity.html))' + options: + _terms: + description: Variable path + required: True + validate_certs: + description: Flag to control SSL certificate validation + type: boolean + default: True + as_file: + description: > + Store lookup result in a temporary file and returns the file path. Thus allowing it to be consumed as an ansible file parameter + (eg ansible_ssh_private_key_file). + type: boolean + default: False + identity_file: + description: Path to the Conjur identity file. The identity file follows the netrc file format convention. + type: path + default: /etc/conjur.identity + required: False + ini: + - section: conjur, + key: identity_file_path + env: + - name: CONJUR_IDENTITY_FILE + authn_token_file: + description: Path to the access token file. + type: path + default: /var/run/conjur/access-token + required: False + ini: + - section: conjur, + key: authn_token_file + env: + - name: CONJUR_AUTHN_TOKEN_FILE + config_file: + description: Path to the Conjur configuration file. The configuration file is a YAML file. + type: path + default: /etc/conjur.conf + required: False + ini: + - section: conjur, + key: config_file_path + env: + - name: CONJUR_CONFIG_FILE +""" + +EXAMPLES = """ +--- + - hosts: localhost + collections: + - cyberark.conjur + tasks: + - name: Lookup variable in Conjur + debug: + msg: "{{ lookup('cyberark.conjur.conjur_variable', '/path/to/secret') }}" +""" + +RETURN = """ + _raw: + description: + - Value stored in Conjur. +""" + +import os.path +import socket +from ansible.errors import AnsibleError +from ansible.plugins.lookup import LookupBase +from base64 import b64encode +from netrc import netrc +from os import environ +from time import time, sleep +from ansible.module_utils.six.moves.urllib.parse import quote +from ansible.module_utils.urls import urllib_error +from stat import S_IRUSR, S_IWUSR +from tempfile import gettempdir, NamedTemporaryFile +import yaml + +from ansible.module_utils.urls import open_url +from ansible.utils.display import Display +import ssl + +display = Display() + + +# Load configuration and return as dictionary if file is present on file system +def _load_conf_from_file(conf_path): + display.vvv('conf file: {0}'.format(conf_path)) + + if not os.path.exists(conf_path): + return {} + # raise AnsibleError('Conjur configuration file `{0}` was not found on the controlling host' + # .format(conf_path)) + + display.vvvv('Loading configuration from: {0}'.format(conf_path)) + with open(conf_path) as f: + config = yaml.safe_load(f.read()) + return config + + +# Load identity and return as dictionary if file is present on file system +def _load_identity_from_file(identity_path, appliance_url): + display.vvvv('identity file: {0}'.format(identity_path)) + + if not os.path.exists(identity_path): + return {} + # raise AnsibleError('Conjur identity file `{0}` was not found on the controlling host' + # .format(identity_path)) + + display.vvvv('Loading identity from: {0} for {1}'.format(identity_path, appliance_url)) + + conjur_authn_url = '{0}/authn'.format(appliance_url) + identity = netrc(identity_path) + + if identity.authenticators(conjur_authn_url) is None: + raise AnsibleError('The netrc file on the controlling host does not contain an entry for: {0}' + .format(conjur_authn_url)) + + id, account, api_key = identity.authenticators(conjur_authn_url) + if not id or not api_key: + return {} + + return {'id': id, 'api_key': api_key} + + +# Merge multiple dictionaries by using dict.update mechanism +def _merge_dictionaries(*arg): + ret = {} + for item in arg: + ret.update(item) + return ret + + +# The `quote` method's default value for `safe` is '/' so it doesn't encode slashes +# into "%2F" which is what the Conjur server expects. Thus, we need to use this +# method with no safe characters. We can't use the method `quote_plus` (which encodes +# slashes correctly) because it encodes spaces into the character '+' instead of "%20" +# as expected by the Conjur server +def _encode_str(input_str): + return quote(input_str, safe='') + + +# Use credentials to retrieve temporary authorization token +def _fetch_conjur_token(conjur_url, account, username, api_key, validate_certs, cert_file): + conjur_url = '{0}/authn/{1}/{2}/authenticate'.format(conjur_url, account, _encode_str(username)) + display.vvvv('Authentication request to Conjur at: {0}, with user: {1}'.format( + conjur_url, + _encode_str(username))) + + response = open_url(conjur_url, + data=api_key, + method='POST', + validate_certs=validate_certs, + ca_path=cert_file) + code = response.getcode() + if code != 200: + raise AnsibleError('Failed to authenticate as \'{0}\' (got {1} response)' + .format(username, code)) + + return response.read() + + +def retry(retries, retry_interval): + """ + Custom retry decorator + + Args: + retries (int, optional): Number of retries. Defaults to 5. + retry_interval (int, optional): Time to wait between intervals. Defaults to 10. + """ + def parameters_wrapper(target): + def decorator(*args, **kwargs): + retry_count = 0 + while True: + retry_count += 1 + try: + return_value = target(*args, **kwargs) + return return_value + except urllib_error.HTTPError as e: + if retry_count >= retries: + raise e + display.v('Error encountered. Retrying..') + except socket.timeout: + if retry_count >= retries: + raise e + display.v('Socket timeout encountered. Retrying..') + sleep(retry_interval) + return decorator + return parameters_wrapper + + +@retry(retries=5, retry_interval=10) +def _repeat_open_url(url, headers=None, method=None, validate_certs=True, ca_path=None): + return open_url(url, + headers=headers, + method=method, + validate_certs=validate_certs, + ca_path=ca_path) + + +# Retrieve Conjur variable using the temporary token +def _fetch_conjur_variable(conjur_variable, token, conjur_url, account, validate_certs, cert_file): + token = b64encode(token) + headers = {'Authorization': 'Token token="{0}"'.format(token.decode("utf-8"))} + + url = '{0}/secrets/{1}/variable/{2}'.format(conjur_url, account, _encode_str(conjur_variable)) + display.vvvv('Conjur Variable URL: {0}'.format(url)) + + response = _repeat_open_url(url, + headers=headers, + method='GET', + validate_certs=validate_certs, + ca_path=cert_file) + + if response.getcode() == 200: + display.vvvv('Conjur variable {0} was successfully retrieved'.format(conjur_variable)) + value = response.read().decode("utf-8") + return [value] + if response.getcode() == 401: + raise AnsibleError('Conjur request has invalid authorization credentials') + if response.getcode() == 403: + raise AnsibleError('The controlling host\'s Conjur identity does not have authorization to retrieve {0}' + .format(conjur_variable)) + if response.getcode() == 404: + raise AnsibleError('The variable {0} does not exist'.format(conjur_variable)) + + return {} + + +def _default_tmp_path(): + if os.access("/dev/shm", os.W_OK): + return "/dev/shm" + + return gettempdir() + + +def _store_secret_in_file(value): + secrets_file = NamedTemporaryFile(mode='w', dir=_default_tmp_path(), delete=False) + os.chmod(secrets_file.name, S_IRUSR | S_IWUSR) + secrets_file.write(value[0]) + + return [secrets_file.name] + + +class LookupModule(LookupBase): + + def run(self, terms, variables=None, **kwargs): + if terms == []: + raise AnsibleError("Invalid secret path: no secret path provided.") + elif not terms[0] or terms[0].isspace(): + raise AnsibleError("Invalid secret path: empty secret path not accepted.") + + self.set_options(direct=kwargs) + validate_certs = self.get_option('validate_certs') + conf_file = self.get_option('config_file') + as_file = self.get_option('as_file') + + if validate_certs is False: + display.warning('Certificate validation has been disabled. Please enable with validate_certs option.') + + if 'http://' in str(environ.get("CONJUR_APPLIANCE_URL")): + raise AnsibleError(('[WARNING]: Conjur URL uses insecure connection. Please consider using HTTPS.')) + + conf = _merge_dictionaries( + _load_conf_from_file(conf_file), + { + "account": environ.get('CONJUR_ACCOUNT'), + "appliance_url": environ.get("CONJUR_APPLIANCE_URL") + } if ( + environ.get('CONJUR_ACCOUNT') is not None + and environ.get('CONJUR_APPLIANCE_URL') is not None + ) + else {}, + { + "cert_file": environ.get('CONJUR_CERT_FILE') + } if (environ.get('CONJUR_CERT_FILE') is not None) + else {}, + { + "authn_token_file": environ.get('CONJUR_AUTHN_TOKEN_FILE') + } if (environ.get('CONJUR_AUTHN_TOKEN_FILE') is not None) + else {} + ) + + if 'authn_token_file' not in conf: + identity_file = self.get_option('identity_file') + identity = _merge_dictionaries( + _load_identity_from_file(identity_file, conf['appliance_url']), + { + "id": environ.get('CONJUR_AUTHN_LOGIN'), + "api_key": environ.get('CONJUR_AUTHN_API_KEY') + } if (environ.get('CONJUR_AUTHN_LOGIN') is not None + and environ.get('CONJUR_AUTHN_API_KEY') is not None) + else {} + ) + + if 'account' not in conf or 'appliance_url' not in conf: + raise AnsibleError( + ("Configuration file on the controlling host must " + "define `account` and `appliance_url`" + "entries or they should be environment variables") + ) + + if 'id' not in identity or 'api_key' not in identity: + raise AnsibleError( + ("Identity file on the controlling host must contain " + "`login` and `password` entries for Conjur appliance" + " URL or they should be environment variables") + ) + + cert_file = None + if 'cert_file' in conf: + display.vvv("Using cert file path {0}".format(conf['cert_file'])) + cert_file = conf['cert_file'] + + token = None + if 'authn_token_file' not in conf: + token = _fetch_conjur_token( + conf['appliance_url'], + conf['account'], + identity['id'], + identity['api_key'], + validate_certs, + cert_file + ) + else: + if not os.path.exists(conf['authn_token_file']): + raise AnsibleError('Conjur authn token file `{0}` was not found on the host' + .format(conf['authn_token_file'])) + with open(conf['authn_token_file'], 'rb') as f: + token = f.read() + + conjur_variable = _fetch_conjur_variable( + terms[0], + token, + conf['appliance_url'], + conf['account'], + validate_certs, + cert_file + ) + + if as_file: + return _store_secret_in_file(conjur_variable) + + return conjur_variable diff --git a/ansible_collections/cyberark/conjur/requirements.txt b/ansible_collections/cyberark/conjur/requirements.txt new file mode 100644 index 000000000..40d19fd88 --- /dev/null +++ b/ansible_collections/cyberark/conjur/requirements.txt @@ -0,0 +1 @@ +ansible>=2.9 diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/README.md b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/README.md new file mode 100644 index 000000000..138d549da --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/README.md @@ -0,0 +1,8 @@ +# Conjur Ansible Role + +This Ansible role provides the ability to grant Conjur machine identity to a host. +Once a host has an identity created by this role, secrets can be retrieved securely +using the [Summon](https://github.com/cyberark/summon) tool. + +For full usage and installation instructions, please see our +[collection documentation](https://github.com/cyberark/ansible-conjur-collection#installation). diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/defaults/main.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/defaults/main.yml new file mode 100644 index 000000000..d04410d8b --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/defaults/main.yml @@ -0,0 +1,6 @@ +summon: + version: 0.8.2 + os: linux-amd64 +summon_conjur: + version: 0.5.3 + os: linux-amd64 diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/meta/main.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/meta/main.yml new file mode 100644 index 000000000..1fc12ef18 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/meta/main.yml @@ -0,0 +1,26 @@ +dependencies: [] + +galaxy_info: + short_description: Grants Conjur machine identity + description: Grants Conjur machine identity to hosts + company: CyberArk + license: Apache + author: + - Cyberark Community and Integrations Team (@cyberark/community-and-integrations-team) + + min_ansible_version: '2.9' + + platforms: + - name: Ubuntu + versions: + - trusty + - xenial + - name: EL + versions: + - 7 + + galaxy_tags: + - identity + - cyberark + - conjur + - security diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/identity.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/identity.yml new file mode 100644 index 000000000..c87f6e37b --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/identity.yml @@ -0,0 +1,73 @@ +--- +- name: Create group conjur + group: + name: conjur + state: present + +- block: + - name: Install "ca-certificates" + package: + name: ca-certificates + retries: 10 + delay: 2 + + - name: Place Conjur public SSL certificate + copy: + dest: "{{ conjur_ssl_certificate_path }}" + content: "{{ conjur_ssl_certificate }}" + mode: 0644 + + - name: Symlink Conjur public SSL certificate into /etc/ssl/certs + file: + src: "{{ conjur_ssl_certificate_path }}" + dest: /etc/ssl/certs/conjur.crt + state: link + register: cert_symlink + + - name: Install openssl-perl Package + yum: + name: openssl-perl + when: + ansible_os_family == 'RedHat' + retries: 10 + delay: 2 + + - name: Rehash certs + command: 'c_rehash' + when: cert_symlink.changed + when: ssl_configuration + +- name: Render /etc/conjur.conf + template: + src: templates/conjur.conf.j2 + dest: /etc/conjur.conf + mode: 0644 + +- block: + - name: Warn against disabling cert validation + debug: + msg: "[WARNING]: Certificate validation has been disabled. Please enable with conjur_validate_certs variable." + when: not conjur_validate_certs + + - name: Request identity from Conjur + uri: + url: "{{ conjur_appliance_url }}/host_factories/hosts" + method: POST + body: "id={{ conjur_host_name }}" + headers: + Authorization: Token token="{{ conjur_host_factory_token }}" + Content-Type: "application/x-www-form-urlencoded" + status_code: 201 + validate_certs: "{{ conjur_validate_certs }}" + register: host_factory_response + retries: 3 + delay: 10 + until: host_factory_response.status == 201 + + - name: Place identity file /etc/conjur.identity + template: + src: templates/conjur.identity.j2 + dest: /etc/conjur.identity + mode: 0640 + group: conjur + when: not conjurized diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/identity_check.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/identity_check.yml new file mode 100644 index 000000000..8661daf70 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/identity_check.yml @@ -0,0 +1,53 @@ +--- +- name: Check if /etc/conjur.identity already exists + stat: + path: /etc/conjur.identity + register: identity_file + +- name: Set fact "conjurized" + set_fact: + conjurized: "{{ identity_file.stat.exists|bool }}" + +- name: Ensure all required variables are set + fail: msg="Variable '{{ item }}' is not set!" + when: item is undefined + with_items: + - "{{ conjur_account }}" + - "{{ conjur_appliance_url }}" + - "{{ conjur_host_name }}" + +- name: Set fact "ssl_configuration" + set_fact: + ssl_configuration: "{{ 'https' in conjur_appliance_url }}" + +- block: + - name: Ensure all required ssl variables are set + fail: msg="Variable '{{ item }}' is not set!" + when: item is undefined + with_items: + - "{{ conjur_ssl_certificate }}" + - "{{ conjur_validate_certs }}" + + - name: Set fact "ssl file path" + set_fact: + conjur_ssl_certificate_path: "/etc/conjur.pem" + when: ssl_configuration + +- block: + - name: Set fact "non ssl configuration" + set_fact: + conjur_ssl_certificate_path: "" + conjur_validate_certs: no + + - name: Warn against using insecure connection schemes + debug: + msg: "[WARNING]: Provided Conjur URL uses insecure connection scheme. Please consider using HTTPS." + when: not ssl_configuration + +- block: + - name: Ensure "conjur_host_factory_token" is set (if node is not already conjurized) + fail: msg="Variable '{{ item }}' is not set!" + when: item is undefined + with_items: + - "{{ conjur_host_factory_token }}" + when: not conjurized diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/install.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/install.yml new file mode 100644 index 000000000..a2fc9993f --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/install.yml @@ -0,0 +1,5 @@ +--- +- import_tasks: identity_check.yml # registers variable 'conjurized' +- import_tasks: identity.yml +- import_tasks: summon.yml +- import_tasks: summon-conjur.yml diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/main.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/main.yml new file mode 100644 index 000000000..d7b94878f --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/main.yml @@ -0,0 +1,6 @@ +--- +- import_tasks: install.yml + when: state|default('present') == "present" + +- import_tasks: uninstall.yml + when: state|default('present') == "absent" diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/summon-conjur.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/summon-conjur.yml new file mode 100644 index 000000000..2e003cd45 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/summon-conjur.yml @@ -0,0 +1,13 @@ +--- +- name: Create folder for Summon-Conjur to be installed into + file: + path: /usr/local/lib/summon + state: directory + recurse: yes + +- name: Download and unpack Summon-Conjur + unarchive: + src: https://github.com/cyberark/summon-conjur/releases/download/v{{ summon_conjur.version }}/summon-conjur-{{ summon_conjur.os }}.tar.gz + dest: /usr/local/lib/summon + remote_src: yes + creates: /usr/local/lib/summon/summon-conjur diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/summon.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/summon.yml new file mode 100644 index 000000000..98ae0b82a --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/summon.yml @@ -0,0 +1,7 @@ +--- +- name: Download and unpack Summon + unarchive: + src: https://github.com/cyberark/summon/releases/download/v{{ summon.version }}/summon-{{ summon.os }}.tar.gz + dest: /usr/local/bin + remote_src: yes + creates: /usr/local/bin/summon diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/uninstall.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/uninstall.yml new file mode 100644 index 000000000..17f7e3b05 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/uninstall.yml @@ -0,0 +1,35 @@ +--- +- block: + - name: Clean Summon binary + file: + path: /usr/local/bin/summon + state: absent + - name: Clean Summon library + file: + path: /usr/local/lib/summon/ + state: absent + +- name: Clean conjur.identity + file: + path: /etc/conjur.identity + state: absent + +- name: Clean conjur.conf + file: + path: /etc/conjur.conf + state: absent + +- name: Clean Conjur SSL certificate Symlink + file: + path: /etc/ssl/certs/conjur.crt + state: absent + +- name: Clean Conjur SSL certificate + file: + path: /etc/conjur.pem + state: absent + +- name: Remove group conjur + group: + name: conjur + state: absent diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/templates/conjur.conf.j2 b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/templates/conjur.conf.j2 new file mode 100644 index 000000000..cd1403ce7 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/templates/conjur.conf.j2 @@ -0,0 +1,5 @@ +account: {{conjur_account}} +appliance_url: {{conjur_appliance_url}} +cert_file: {{conjur_ssl_certificate_path}} +netrc_path: /etc/conjur.identity +plugins: [] diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/templates/conjur.identity.j2 b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/templates/conjur.identity.j2 new file mode 100644 index 000000000..7bde0ff2e --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/templates/conjur.identity.j2 @@ -0,0 +1,3 @@ +machine {{conjur_appliance_url}}/authn + login host/{{conjur_host_name}} + password {{host_factory_response.json.api_key}} diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.dockerignore b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.dockerignore new file mode 100644 index 000000000..5ed3ebd29 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.dockerignore @@ -0,0 +1 @@ +conjur-intro/
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/.gitignore b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/.gitignore new file mode 100644 index 000000000..bc1a1f616 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/.gitignore @@ -0,0 +1,2 @@ +# Created by pytest automatically. +* diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/CACHEDIR.TAG b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/CACHEDIR.TAG new file mode 100644 index 000000000..fce15ad7e --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/CACHEDIR.TAG @@ -0,0 +1,4 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by pytest. +# For information about cache directory tags, see: +# https://bford.info/cachedir/spec.html diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/README.md b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/README.md new file mode 100644 index 000000000..b89018ced --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/README.md @@ -0,0 +1,8 @@ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information. diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/v/cache/nodeids b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/v/cache/nodeids new file mode 100644 index 000000000..ffadcb1be --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/v/cache/nodeids @@ -0,0 +1,22 @@ +[ + "test_cases/cleanup-conjur-identity/tests/test_default.py::test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]", + "test_cases/cleanup-conjur-identity/tests/test_default.py::test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]", + "test_cases/cleanup-conjur-identity/tests/test_default.py::test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]", + "test_cases/cleanup-conjur-identity/tests/test_default.py::test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]", + "test_cases/cleanup-conjur-identity/tests/test_default.py::test_is_not_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]", + "test_cases/cleanup-conjur-identity/tests/test_default.py::test_is_not_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]", + "test_cases/cleanup-conjur-identity/tests/test_default.py::test_is_not_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]", + "test_cases/cleanup-conjur-identity/tests/test_default.py::test_is_not_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_is_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_is_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_is_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_is_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_retrieve_secret_with_summon[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_retrieve_secret_with_summon[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_retrieve_secret_with_summon[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]", + "test_cases/configure-conjur-identity/tests/test_default.py::test_retrieve_secret_with_summon[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]" +]
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/v/cache/stepwise b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/v/cache/stepwise new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/v/cache/stepwise @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/Dockerfile b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/Dockerfile new file mode 100644 index 000000000..3985b12ad --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/Dockerfile @@ -0,0 +1,39 @@ +FROM ubuntu:20.04 + +ENV DEBIAN_FRONTEND=noninteractive + +WORKDIR /cyberark + +# install python 3 +RUN apt-get update && \ + apt-get install -y python3-pip && \ + pip3 install --upgrade pip + +ARG ANSIBLE_VERSION +# install ansible and its test tool +RUN pip3 install ansible==${ANSIBLE_VERSION}.* pytest-testinfra + +# install docker installation requirements +RUN apt-get update && \ + apt-get install -y apt-transport-https \ + ca-certificates \ + curl \ + software-properties-common + +# install docker +RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +RUN add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + +RUN apt-get update && \ + apt-get -y install docker-ce + +# NOTE: Everything above is copied from REPO_ROOT/tests/conjur_variable/Dockerfile. It defines a +# standard container image for running ansible tests + +# install ruby +RUN apt-get update && apt-get install -y gcc build-essential +RUN apt-add-repository -y ppa:brightbox/ruby-ng && apt-get update && apt-get install -y ruby2.7 ruby2.7-dev +RUN gem install conjur-cli
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/Dockerfile_nginx b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/Dockerfile_nginx new file mode 100644 index 000000000..d9f18c7bd --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/Dockerfile_nginx @@ -0,0 +1,16 @@ +FROM nginx:1.13.3 + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y iputils-ping procps openssl && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /etc/nginx/ + +COPY proxy/ssl.conf /etc/ssl/openssl.cnf + +RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -config /etc/ssl/openssl.cnf -extensions v3_ca \ + -keyout cert.key -out cert.crt + +COPY proxy/default.conf /etc/nginx/conf.d/default.conf diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/ansible.cfg b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/ansible.cfg new file mode 100644 index 000000000..56026b775 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/ansible.cfg @@ -0,0 +1,8 @@ +[defaults] +display_skipped_hosts = False +host_key_checking = False +error_on_undefined_vars = True +timeout = 60 +inventory = inventory.tmp +roles_path = /cyberark +remote_tmp = /tmp diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/docker-compose.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/docker-compose.yml new file mode 100644 index 000000000..832655687 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/docker-compose.yml @@ -0,0 +1,84 @@ +version: '3' +services: + ansible: + build: + context: . + dockerfile: Dockerfile + args: + ANSIBLE_VERSION: ${ANSIBLE_VERSION} + command: /bin/sleep 1d + environment: + CONJUR_APPLIANCE_URL: ${CONJUR_APPLIANCE_URL} + CONJUR_ACCOUNT: ${CONJUR_ACCOUNT} + CONJUR_AUTHN_LOGIN: ${CONJUR_AUTHN_LOGIN} + CONJUR_AUTHN_API_KEY: ${ANSIBLE_CONJUR_AUTHN_API_KEY} + CONJUR_CUSTOM_AUTHN_API_KEY: ${CUSTOM_CONJUR_AUTHN_API_KEY} + COMPOSE_PROJECT_NAME: ${COMPOSE_PROJECT_NAME} + # NOTE: Explicitly setting the ANSIBLE_CONFIG envvar avoids Ansible ignoring + # the configuration because it is in a world-writable working directory, + # see https://docs.ansible.com/ansible/latest/reference_appendices/config.html#avoiding-security-risks-with-ansible-cfg-in-the-current-directory. + ANSIBLE_CONFIG: ./ansible.cfg + networks: + - "${DOCKER_NETWORK}" + volumes: + - ..:/cyberark/cyberark.conjur.conjur-host-identity/ + - .:/cyberark/tests/ + - /var/run/docker.sock:/var/run/docker.sock + pg: + image: postgres:9.3 + + conjur: + image: cyberark/conjur + command: server -a cucumber -p 3000 + environment: + CONJUR_APPLIANCE_URL: http://localhost:3000 + DATABASE_URL: postgres://postgres@pg/postgres + CONJUR_DATA_KEY: "W0BuL8iTr/7QvtjIluJbrb5LDAnmXzmcpxkqihO3dXA=" + networks: + - default + links: + - pg + + conjur_cli: + image: cyberark/conjur-cli:5-latest + entrypoint: [] + command: sleep infinity + environment: + CONJUR_APPLIANCE_URL: http://conjur:3000 + CONJUR_ACCOUNT: cucumber + CONJUR_AUTHN_LOGIN: admin + CONJUR_AUTHN_API_KEY: ${CLI_CONJUR_AUTHN_API_KEY} + volumes: + - ./policy:/policy + links: + - conjur + + test_app_ubuntu: + build: ./test_app_ubuntu + entrypoint: sleep + command: infinity + networks: + - "${DOCKER_NETWORK}" + + test_app_centos: + build: ./test_app_centos + entrypoint: sleep + command: infinity + networks: + - "${DOCKER_NETWORK}" + + conjur-proxy-nginx: + build: + context: . + dockerfile: Dockerfile_nginx + entrypoint: nginx-debug -g 'daemon off;' + environment: + TERM: xterm + depends_on: + - conjur + - conjur_cli + +networks: + dap_net: + name: dap_net + external: true diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-playbook-v2.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-playbook-v2.yml new file mode 100644 index 000000000..d47081cbe --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-playbook-v2.yml @@ -0,0 +1,6 @@ +--- +- name: Compile inventory template locally + hosts: localhost + tasks: + - name: compile inventory template + template: src=inventory-v2.j2 dest=/cyberark/tests/inventory.tmp diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-playbook.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-playbook.yml new file mode 100644 index 000000000..91d44fcb8 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-playbook.yml @@ -0,0 +1,6 @@ +--- +- name: Compile inventory template locally + hosts: localhost + tasks: + - name: compile inventory template + template: src=inventory.j2 dest=/cyberark/tests/inventory.tmp diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-v2.j2 b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-v2.j2 new file mode 100644 index 000000000..4a004fb13 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-v2.j2 @@ -0,0 +1,6 @@ +[testapp] +{{ lookup('env','COMPOSE_PROJECT_NAME') }}-test_app_ubuntu-[1:2] ansible_connection=docker +{{ lookup('env','COMPOSE_PROJECT_NAME') }}-test_app_centos-[1:2] ansible_connection=docker + +[ansible] +{{ lookup('env','COMPOSE_PROJECT_NAME') }}-ansible-1 ansible_connection=docker diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory.j2 b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory.j2 new file mode 100644 index 000000000..62d48ef82 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory.j2 @@ -0,0 +1,6 @@ +[testapp] +{{ lookup('env','COMPOSE_PROJECT_NAME') }}_test_app_ubuntu_[1:2] ansible_connection=docker +{{ lookup('env','COMPOSE_PROJECT_NAME') }}_test_app_centos_[1:2] ansible_connection=docker + +[ansible] +{{ lookup('env','COMPOSE_PROJECT_NAME') }}_ansible_1 ansible_connection=docker diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/junit/cleanup-conjur-identity b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/junit/cleanup-conjur-identity new file mode 100644 index 000000000..d1372eaea --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/junit/cleanup-conjur-identity @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="8" time="4.102" timestamp="2022-09-09T15:12:54.260298" hostname="3ef34ba116db"><testcase classname="test_cases.cleanup-conjur-identity.tests.test_default" name="test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]" time="0.681" /><testcase classname="test_cases.cleanup-conjur-identity.tests.test_default" name="test_is_not_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]" time="0.198" /><testcase classname="test_cases.cleanup-conjur-identity.tests.test_default" name="test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]" time="0.687" /><testcase classname="test_cases.cleanup-conjur-identity.tests.test_default" name="test_is_not_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]" time="0.201" /><testcase classname="test_cases.cleanup-conjur-identity.tests.test_default" name="test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]" time="0.698" /><testcase classname="test_cases.cleanup-conjur-identity.tests.test_default" name="test_is_not_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]" time="0.213" /><testcase classname="test_cases.cleanup-conjur-identity.tests.test_default" name="test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]" time="0.702" /><testcase classname="test_cases.cleanup-conjur-identity.tests.test_default" name="test_is_not_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]" time="0.190" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/junit/configure-conjur-identity b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/junit/configure-conjur-identity new file mode 100644 index 000000000..d982cbaa2 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/junit/configure-conjur-identity @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="12" time="5.511" timestamp="2022-09-09T15:14:31.194874" hostname="3ef34ba116db"><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]" time="0.691" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_is_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]" time="0.412" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_retrieve_secret_with_summon[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_1]" time="0.133" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]" time="0.710" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_is_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]" time="0.384" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_retrieve_secret_with_summon[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_centos_2]" time="0.126" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]" time="0.727" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_is_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]" time="0.383" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_retrieve_secret_with_summon[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_1]" time="0.155" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_hosts_file[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]" time="0.719" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_is_conjurized[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]" time="0.387" /><testcase classname="test_cases.configure-conjur-identity.tests.test_default" name="test_retrieve_secret_with_summon[docker://jenkinscyberarkansibleconjurcollectionv1201conjurhostidentity_test_app_ubuntu_2]" time="0.143" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/policy/root.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/policy/root.yml new file mode 100644 index 000000000..0309cf702 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/policy/root.yml @@ -0,0 +1,32 @@ +--- +- !policy + id: ansible + annotations: + description: Policy for Ansible master and remote hosts + body: + + - !host + id: ansible-master + annotations: + description: Host for running Ansible on remote targets + + - !layer &remote_hosts_layer + id: remote_hosts + annotations: + description: Layer for Ansible remote hosts + + - !host-factory + id: ansible-factory + annotations: + description: Factory to create new hosts for ansible + layer: [ *remote_hosts_layer ] + + - !variable + id: target-password + annotations: + description: Password needed by the Ansible remote machine + + - !permit + role: *remote_hosts_layer + privileges: [ execute ] + resources: [ !variable target-password ] diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/proxy/default.conf b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/proxy/default.conf new file mode 100644 index 000000000..db2153a71 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/proxy/default.conf @@ -0,0 +1,33 @@ +server { + listen 80; + return 301 https://conjur$request_uri; +} + +server { + listen 443; + server_name localhost; + ssl_certificate /etc/nginx/cert.crt; + ssl_certificate_key /etc/nginx/cert.key; + + ssl on; + ssl_session_cache builtin:1000 shared:SSL:10m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; + ssl_prefer_server_ciphers on; + + access_log /var/log/nginx/access.log; + + location / { + proxy_pass http://conjur:3000; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + +} diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/proxy/ssl.conf b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/proxy/ssl.conf new file mode 100644 index 000000000..e78716b27 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/proxy/ssl.conf @@ -0,0 +1,39 @@ +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +req_extensions = req_ext +distinguished_name = dn +x509_extensions = v3_ca # The extentions to add to the self signed cert +req_extensions = v3_req +x509_extensions = usr_cert + +[ dn ] +C=IL +ST=Israel +L=TLV +O=Onyx +OU=CyberArk +CN=conjur-proxy-nginx + +[ usr_cert ] +basicConstraints=CA:FALSE +nsCertType = client, server, email +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection +nsComment = "OpenSSL Generated Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +[ v3_req ] +extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +subjectAltName = @alt_names + +[ alt_names ] +DNS.1 = localhost +DNS.2 = conjur-proxy-nginx +IP.1 = 127.0.0.1 diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test.sh b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test.sh new file mode 100755 index 000000000..9a54cb8b9 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test.sh @@ -0,0 +1,249 @@ +#!/bin/bash -eu + +set -o pipefail + +# normalises project name by filtering non alphanumeric characters and transforming to lowercase +declare -x COMPOSE_PROJECT_NAME='' +declare -x ENTERPRISE_PROJECT='conjur-intro-host' +declare -x ANSIBLE_PROJECT='' + +declare -x ANSIBLE_CONJUR_AUTHN_API_KEY='' +declare -x CLI_CONJUR_AUTHN_API_KEY='' +declare -x DOCKER_NETWORK="default" +declare -x ANSIBLE_VERSION="${ANSIBLE_VERSION:-6}" + +declare cli_cid='' +declare ansible_cid='' +declare enterprise='false' +declare test_dir='' + + ANSIBLE_PROJECT=$(echo "${BUILD_TAG:-ansible-plugin-testing}-conjur-host-identity" | sed -e 's/[^[:alnum:]]//g' | tr '[:upper:]' '[:lower:]') + test_dir="$(pwd)" + +function clean { + echo 'Removing test environment' + echo '---' + + # Escape conjur-intro dir if Enterprise setup fails + cd "${test_dir}" + + if [[ -d conjur-intro ]]; then + pushd conjur-intro + COMPOSE_PROJECT_NAME="${ENTERPRISE_PROJECT}" + ./bin/dap --stop + popd + rm -rf conjur-intro + fi + + COMPOSE_PROJECT_NAME="${ANSIBLE_PROJECT}" + docker-compose down -v + rm -rf inventory.tmp \ + conjur.pem +} +function finish { + rv=$? + clean || true + exit $rv +} +trap finish EXIT + +while getopts 'e' flag; do + case "${flag}" in + e) enterprise="true" ;; + *) exit 1 ;; + esac +done + +clean + +function setup_admin_api_key { + if [[ "$enterprise" == "true" ]]; then + docker exec "${cli_cid}" \ + conjur user rotate_api_key + else + docker-compose exec -T conjur \ + conjurctl role retrieve-key "${CONJUR_ACCOUNT}:user:admin" + fi +} + +function setup_ansible_api_key { + docker exec "${cli_cid}" \ + conjur host rotate_api_key --host ansible/ansible-master +} + +function hf_token { + docker exec "${cli_cid}" bash -c "conjur hostfactory tokens create --duration-days=5 ansible/ansible-factory | jq -r '.[0].token'" +} + +function setup_conjur_resources { + echo "---- setting up conjur ----" + policy_path="root.yml" + if [[ "${enterprise}" == "false" ]]; then + policy_path="/policy/${policy_path}" + fi + + docker exec "${cli_cid}" bash -ec " + conjur policy load root ${policy_path} + conjur variable values add ansible/target-password target_secret_password + " +} + +function run_test_cases { + for test_case in test_cases/*; do + teardown_and_setup + run_test_case "$(basename -- "$test_case")" + done +} + +function run_test_case { + echo "---- testing ${test_case} ----" + local test_case=$1 + if [ -n "$test_case" ]; then + docker exec "${ansible_cid}" \ + env HFTOKEN="$(hf_token)" \ + env CONJUR_ACCOUNT="${CONJUR_ACCOUNT}" \ + env CONJUR_APPLIANCE_URL="${CONJUR_APPLIANCE_URL}" \ + bash -ec " + cd tests + ansible-playbook test_cases/${test_case}/playbook.yml + " + if [ -d "${test_dir}/test_cases/${test_case}/tests/" ]; then + docker exec "${ansible_cid}" bash -ec " + cd tests + py.test --junitxml=./junit/${test_case} --connection docker -v test_cases/${test_case}/tests/test_default.py + " + fi + else + echo ERROR: run_test called with no argument 1>&2 + exit 1 + fi +} + +function teardown_and_setup { + docker-compose up -d --force-recreate --scale test_app_ubuntu=2 test_app_ubuntu + docker-compose up -d --force-recreate --scale test_app_centos=2 test_app_centos +} + +function wait_for_server { + # shellcheck disable=SC2016 + docker exec "${cli_cid}" bash -ec ' + for i in $( seq 20 ); do + curl -o /dev/null -fs -X OPTIONS ${CONJUR_APPLIANCE_URL} > /dev/null && echo "server is up" && break + echo "." + sleep 2 + done + ' +} + +function fetch_ssl_cert { + echo "Fetching SSL certs" + service_id="conjur-proxy-nginx" + cert_path="cert.crt" + if [[ "${enterprise}" == "true" ]]; then + service_id="conjur-master.mycompany.local" + cert_path="/etc/ssl/certs/ca.pem" + fi + + (docker-compose exec -T "${service_id}" cat "${cert_path}") > conjur.pem +} + +function generate_inventory { + # Use a different inventory file for docker-compose v1 and v2 or later + playbook_file="inventory-playbook-v2.yml" + compose_ver=$(docker-compose version --short) + if [[ $compose_ver == "1"* ]]; then + playbook_file="inventory-playbook.yml" + fi + + # uses .j2 template to generate inventory prepended with COMPOSE_PROJECT_NAME + docker-compose exec -T ansible bash -ec " + cd tests + ansible-playbook $playbook_file + " + + cat inventory.tmp +} + +function setup_conjur_open_source() { + docker-compose up -d --build + + cli_cid="$(docker-compose ps -q conjur_cli)" + + fetch_ssl_cert + wait_for_server + + echo "Recreating Conjur CLI with admin credentials" + CLI_CONJUR_AUTHN_API_KEY=$(setup_admin_api_key) + docker-compose up -d conjur_cli + cli_cid=$(docker-compose ps -q conjur_cli) + + setup_conjur_resources +} + +function setup_conjur_enterprise() { + git clone --single-branch --branch main https://github.com/conjurdemos/conjur-intro.git + pushd ./conjur-intro + + echo "Provisioning Enterprise leader and follower" + ./bin/dap --provision-master + ./bin/dap --provision-follower + + cp ../policy/root.yml . + + # Run 'sleep infinity' in the CLI container, so the scripts + # have access to an alive and authenticated CLI until the script terminates + cli_cid="$(docker-compose run -d \ + -w /src/cli \ + --entrypoint sleep client infinity)" + + echo "Authenticate Conjur CLI container" + docker exec "${cli_cid}" \ + /bin/bash -c " + if [ ! -e /root/conjur-demo.pem ]; then + yes 'yes' | conjur init -u ${CONJUR_APPLIANCE_URL} -a ${CONJUR_ACCOUNT} + fi + conjur authn login -u admin -p MySecretP@ss1 + hostname -I + " + + fetch_ssl_cert + setup_conjur_resources + + echo "Relocate credential files" + mv conjur.pem ../. + popd +} + +function main() { + if [[ "${enterprise}" == "true" ]]; then + echo "Deploying Conjur Enterprise" + + export DOCKER_NETWORK="dap_net" + export CONJUR_APPLIANCE_URL="https://conjur-master.mycompany.local" + export CONJUR_ACCOUNT="demo" + COMPOSE_PROJECT_NAME="${ENTERPRISE_PROJECT}" + DOCKER_NETWORK="dap_net" + + setup_conjur_enterprise + else + echo "Deploying Conjur Open Source" + + export CONJUR_APPLIANCE_URL="https://conjur-proxy-nginx" + export CONJUR_ACCOUNT="cucumber" + COMPOSE_PROJECT_NAME="${ANSIBLE_PROJECT}" + + setup_conjur_open_source + fi + + echo "Preparing Ansible for test run" + COMPOSE_PROJECT_NAME="${ANSIBLE_PROJECT}" + ANSIBLE_CONJUR_AUTHN_API_KEY=$(setup_ansible_api_key) + docker-compose up -d ansible + ansible_cid=$(docker-compose ps -q ansible) + generate_inventory + + echo "Running tests" + run_test_cases +} + +main
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_app_centos/Dockerfile b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_app_centos/Dockerfile new file mode 100644 index 000000000..ee474e7bf --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_app_centos/Dockerfile @@ -0,0 +1,4 @@ +FROM centos:7 + +# Install Python so Ansible can run against node +RUN yum update -y && yum install -y python3 diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_app_ubuntu/Dockerfile b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_app_ubuntu/Dockerfile new file mode 100644 index 000000000..ce919aa57 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_app_ubuntu/Dockerfile @@ -0,0 +1,4 @@ +FROM ubuntu:20.04 + +# Install Python so Ansible can run against node +RUN apt-get update -y && apt-get install -y python3-minimal diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/playbook.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/playbook.yml new file mode 100644 index 000000000..dfdbe2804 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/playbook.yml @@ -0,0 +1,17 @@ +--- +- name: Configuring Conjur identity on remote hosts + hosts: testapp + roles: + - role: "cyberark.conjur.conjur-host-identity" + conjur_account: "{{lookup('env', 'CONJUR_ACCOUNT')}}" + conjur_appliance_url: "{{lookup('env', 'CONJUR_APPLIANCE_URL')}}" + conjur_host_factory_token: "{{lookup('env', 'HFTOKEN')}}" + conjur_host_name: "conjur_{{ ansible_hostname }}" + conjur_ssl_certificate: "{{lookup('file', '../../conjur.pem')}}" + conjur_validate_certs: yes + +- name: Revoke Conjur identity from remote hosts + hosts: testapp + roles: + - role: "cyberark.conjur.conjur-host-identity" + state: absent diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/tests/test_default.py b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/tests/test_default.py new file mode 100644 index 000000000..9139ea87a --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/tests/test_default.py @@ -0,0 +1,23 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + '/cyberark/tests/inventory.tmp').get_hosts('testapp') + + +def test_hosts_file(host): + f = host.file('/etc/hosts') + + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + + +def test_is_not_conjurized(host): + identity_file = host.file('/etc/conjur.identity') + assert not identity_file.exists + + conf_file = host.file('/etc/conjur.conf') + assert not conf_file.exists diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/playbook.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/playbook.yml new file mode 100644 index 000000000..2f1ec4556 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/playbook.yml @@ -0,0 +1,11 @@ +--- +- name: Configuring Conjur identity on remote hosts + hosts: testapp + roles: + - role: "cyberark.conjur.conjur-host-identity" + conjur_account: "{{lookup('env', 'CONJUR_ACCOUNT')}}" + conjur_appliance_url: "{{lookup('env', 'CONJUR_APPLIANCE_URL')}}" + conjur_host_factory_token: "{{lookup('env', 'HFTOKEN')}}" + conjur_host_name: "conjur_{{ ansible_hostname }}" + conjur_ssl_certificate: "{{lookup('file', '../../conjur.pem')}}" + conjur_validate_certs: yes diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/tests/test_default.py b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/tests/test_default.py new file mode 100644 index 000000000..80513230a --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/tests/test_default.py @@ -0,0 +1,33 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + '/cyberark/tests/inventory.tmp').get_hosts('testapp') + + +def test_hosts_file(host): + f = host.file('/etc/hosts') + + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + + +def test_is_conjurized(host): + identity_file = host.file('/etc/conjur.identity') + + assert identity_file.exists + assert identity_file.user == 'root' + + conf_file = host.file('/etc/conjur.conf') + + assert conf_file.exists + assert conf_file.user == 'root' + + +def test_retrieve_secret_with_summon(host): + result = host.check_output("summon --yaml 'DB_USERNAME: !var ansible/target-password' bash -c 'printenv DB_USERNAME'", shell=True) + + assert result == "target_secret_password" diff --git a/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/misconfig-conjur-identity/playbook.yml b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/misconfig-conjur-identity/playbook.yml new file mode 100644 index 000000000..2ae9ec144 --- /dev/null +++ b/ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/misconfig-conjur-identity/playbook.yml @@ -0,0 +1,22 @@ +--- +- name: Configuring Conjur identity on remote hosts fails when missing required variable + hosts: testapp + tasks: + - name: Attempt to configure Conjur identity + block: + - import_role: + name: "cyberark.conjur.conjur-host-identity" + vars: + conjur_account: cucumber + # conjur_appliance_url: "https://conjur-proxy-nginx" + conjur_host_factory_token: "{{lookup('env', 'HFTOKEN')}}" + conjur_host_name: "conjur_{{ ansible_hostname }}" + conjur_ssl_certificate: "{{lookup('file', '../../conjur.pem')}}" + conjur_validate_certs: yes + rescue: + - name: Confirm Role setup fails + assert: + that: ansible_failed_result.failed == true + - name: Confirm error message + assert: + that: ansible_failed_result.msg == "'conjur_appliance_url' is undefined" diff --git a/ansible_collections/cyberark/conjur/secrets.yml b/ansible_collections/cyberark/conjur/secrets.yml new file mode 100644 index 000000000..87c9771bf --- /dev/null +++ b/ansible_collections/cyberark/conjur/secrets.yml @@ -0,0 +1,2 @@ +--- +GALAXY_API_KEY: !var ecosystems/ansible/galaxy/api-key diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/.dockerignore b/ansible_collections/cyberark/conjur/tests/conjur_variable/.dockerignore new file mode 100644 index 000000000..5ed3ebd29 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/.dockerignore @@ -0,0 +1 @@ +conjur-intro/
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/.gitignore b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/.gitignore new file mode 100644 index 000000000..bc1a1f616 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/.gitignore @@ -0,0 +1,2 @@ +# Created by pytest automatically. +* diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/CACHEDIR.TAG b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/CACHEDIR.TAG new file mode 100644 index 000000000..fce15ad7e --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/CACHEDIR.TAG @@ -0,0 +1,4 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by pytest. +# For information about cache directory tags, see: +# https://bford.info/cachedir/spec.html diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/README.md b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/README.md new file mode 100644 index 000000000..b89018ced --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/README.md @@ -0,0 +1,8 @@ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information. diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/v/cache/nodeids b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/v/cache/nodeids new file mode 100644 index 000000000..c6b2f5e13 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/v/cache/nodeids @@ -0,0 +1,11 @@ +[ + "test_cases/retrieve-variable-bad-cert-path/tests/test_default.py::test_retrieval_failed[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]", + "test_cases/retrieve-variable-bad-certs/tests/test_default.py::test_retrieval_failed[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]", + "test_cases/retrieve-variable-disable-verify-certs/tests/test_default.py::test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]", + "test_cases/retrieve-variable-into-file/tests/test_default.py::test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]", + "test_cases/retrieve-variable-no-cert-provided/tests/test_default.py::test_retrieval_failed[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]", + "test_cases/retrieve-variable-with-authn-token-bad-cert/tests/test_default.py::test_retrieve_secret_failed[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]", + "test_cases/retrieve-variable-with-authn-token/tests/test_default.py::test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]", + "test_cases/retrieve-variable-with-spaces-secret/tests/test_default.py::test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]", + "test_cases/retrieve-variable/tests/test_default.py::test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" +]
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/v/cache/stepwise b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/v/cache/stepwise new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/v/cache/stepwise @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/Dockerfile b/ansible_collections/cyberark/conjur/tests/conjur_variable/Dockerfile new file mode 100644 index 000000000..293ccdca0 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/Dockerfile @@ -0,0 +1,31 @@ +FROM ubuntu:20.04 + +ENV DEBIAN_FRONTEND=noninteractive + +WORKDIR /cyberark + +# install python 3 +RUN apt-get update && \ + apt-get install -y python3-pip && \ + pip3 install --upgrade pip + +ARG ANSIBLE_VERSION +# install ansible and its test tool +RUN pip3 install ansible==${ANSIBLE_VERSION}.* pytest-testinfra + +# install docker installation requirements +RUN apt-get update && \ + apt-get install -y apt-transport-https \ + ca-certificates \ + curl \ + software-properties-common + +# install docker +RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +RUN add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + +RUN apt-get update && \ + apt-get -y install docker-ce diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/Dockerfile_nginx b/ansible_collections/cyberark/conjur/tests/conjur_variable/Dockerfile_nginx new file mode 100644 index 000000000..6f1e28107 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/Dockerfile_nginx @@ -0,0 +1,17 @@ +FROM nginx:1.13.3 + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y iputils-ping \ + procps \ + openssl && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /etc/nginx/ + +COPY proxy/ssl.conf /etc/ssl/openssl.cnf +COPY proxy/default.conf /etc/nginx/conf.d/default.conf + +RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -config /etc/ssl/openssl.cnf -extensions v3_ca \ + -keyout cert.key -out cert.crt diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/docker-compose.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/docker-compose.yml new file mode 100644 index 000000000..01294d94b --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/docker-compose.yml @@ -0,0 +1,67 @@ +version: '3' +services: + ansible: + image: ansiblecontainername + container_name: ${COMPOSE_PROJECT_NAME}-ansible + build: + context: . + dockerfile: Dockerfile + args: + ANSIBLE_VERSION: ${ANSIBLE_VERSION} + entrypoint: sleep + command: infinity + environment: + CONJUR_APPLIANCE_URL: ${CONJUR_APPLIANCE_URL} + CONJUR_ACCOUNT: ${CONJUR_ACCOUNT} + CONJUR_AUTHN_LOGIN: ${CONJUR_AUTHN_LOGIN} + CONJUR_AUTHN_API_KEY: ${ANSIBLE_MASTER_AUTHN_API_KEY} + COMPOSE_PROJECT_NAME: ${COMPOSE_PROJECT_NAME} + networks: + - "${DOCKER_NETWORK}" + volumes: + - ../../plugins:/root/.ansible/plugins + - ../..:/cyberark + - /var/run/docker.sock:/var/run/docker.sock + + pg: + image: postgres:9.4 + environment: + POSTGRES_HOST_AUTH_METHOD: password + POSTGRES_PASSWORD: StrongPass + + conjur: + image: cyberark/conjur + command: server -a cucumber -p 3000 + environment: + DATABASE_URL: postgres://postgres:StrongPass@pg/postgres + CONJUR_DATA_KEY: "W0BuL8iTr/7QvtjIluJbrb5LDAnmXzmcpxkqihO3dXA=" + depends_on: + - pg + + conjur_https: + hostname: conjur-https + build: + context: . + dockerfile: Dockerfile_nginx + entrypoint: nginx-debug -g 'daemon off;' + environment: + TERM: xterm + depends_on: + - conjur + + conjur_cli: + image: cyberark/conjur-cli:5 + entrypoint: sleep + command: infinity + environment: + CONJUR_APPLIANCE_URL: http://conjur:3000 + CONJUR_ACCOUNT: cucumber + CONJUR_AUTHN_LOGIN: admin + CONJUR_AUTHN_API_KEY: ${CONJUR_ADMIN_AUTHN_API_KEY} + volumes: + - ./policy:/policy + +networks: + dap_net: + name: dap_net + external: true diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable new file mode 100644 index 000000000..08c9ccb5e --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.575" timestamp="2022-09-09T15:07:48.307449" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable.tests.test_default" name="test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.530" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-bad-cert-path b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-bad-cert-path new file mode 100644 index 000000000..0ed22fad7 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-bad-cert-path @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.458" timestamp="2022-09-09T15:07:51.763243" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable-bad-cert-path.tests.test_default" name="test_retrieval_failed[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.422" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-bad-certs b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-bad-certs new file mode 100644 index 000000000..6b0b865c1 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-bad-certs @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.459" timestamp="2022-09-09T15:07:55.122204" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable-bad-certs.tests.test_default" name="test_retrieval_failed[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.423" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-disable-verify-certs b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-disable-verify-certs new file mode 100644 index 000000000..9f1fc6494 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-disable-verify-certs @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.568" timestamp="2022-09-09T15:07:58.851346" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable-disable-verify-certs.tests.test_default" name="test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.532" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-into-file b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-into-file new file mode 100644 index 000000000..5fcc68f80 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-into-file @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.863" timestamp="2022-09-09T15:08:02.658511" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable-into-file.tests.test_default" name="test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.828" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-no-cert-provided b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-no-cert-provided new file mode 100644 index 000000000..f1c9029a8 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-no-cert-provided @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.464" timestamp="2022-09-09T15:08:06.406130" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable-no-cert-provided.tests.test_default" name="test_retrieval_failed[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.429" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-authn-token b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-authn-token new file mode 100644 index 000000000..407145017 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-authn-token @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.551" timestamp="2022-09-09T15:08:10.115226" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable-with-authn-token.tests.test_default" name="test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.516" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-authn-token-bad-cert b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-authn-token-bad-cert new file mode 100644 index 000000000..680f3913f --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-authn-token-bad-cert @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.460" timestamp="2022-09-09T15:08:13.541799" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable-with-authn-token-bad-cert.tests.test_default" name="test_retrieve_secret_failed[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.425" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-spaces-secret b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-spaces-secret new file mode 100644 index 000000000..65e72fecb --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-spaces-secret @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="1" time="0.571" timestamp="2022-09-09T15:08:17.207877" hostname="96989ca8092d"><testcase classname="test_cases.retrieve-variable-with-spaces-secret.tests.test_default" name="test_retrieved_secret[docker://jenkinscyberarkansibleconjurcollectionv1201conjurvariable-ansible]" time="0.536" /></testsuite></testsuites>
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/policy/root.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/policy/root.yml new file mode 100644 index 000000000..dbaea73fa --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/policy/root.yml @@ -0,0 +1,21 @@ +--- +- !policy + id: ansible + annotations: + description: Policy for Ansible master + body: + + - !host + id: ansible-master + annotations: + description: Host for running Ansible on remote targets + + - &variables + - !variable test-secret + - !variable test-secret-in-file + - !variable var with spaces + + - !permit + role: !host ansible-master + privileges: [ read, execute ] + resource: *variables diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/proxy/default.conf b/ansible_collections/cyberark/conjur/tests/conjur_variable/proxy/default.conf new file mode 100644 index 000000000..578b3c5f8 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/proxy/default.conf @@ -0,0 +1,29 @@ +server { + listen 80; + return 301 https://conjur$request_uri; +} + +server { + listen 443; + server_name localhost; + ssl_certificate /etc/nginx/cert.crt; + ssl_certificate_key /etc/nginx/cert.key; + + ssl on; + ssl_session_cache builtin:1000 shared:SSL:10m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; + ssl_prefer_server_ciphers on; + + access_log /var/log/nginx/access.log; + + location / { + proxy_pass http://conjur:3000; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + +} diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/proxy/ssl.conf b/ansible_collections/cyberark/conjur/tests/conjur_variable/proxy/ssl.conf new file mode 100644 index 000000000..1b11cd755 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/proxy/ssl.conf @@ -0,0 +1,39 @@ +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +req_extensions = req_ext +distinguished_name = dn +x509_extensions = v3_ca # The extentions to add to the self signed cert +req_extensions = v3_req +x509_extensions = usr_cert + +[ dn ] +C=IL +ST=Israel +L=TLV +O=Onyx +OU=CyberArk +CN=conjur-https + +[ usr_cert ] +basicConstraints=CA:FALSE +nsCertType = client, server, email +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection +nsComment = "OpenSSL Generated Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +[ v3_req ] +extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +subjectAltName = @alt_names + +[ alt_names ] +DNS.1 = localhost +DNS.2 = conjur-https +IP.1 = 127.0.0.1 diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/pytest.ini b/ansible_collections/cyberark/conjur/tests/conjur_variable/pytest.ini new file mode 100644 index 000000000..fe55d2ed6 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +junit_family=xunit2 diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test.sh b/ansible_collections/cyberark/conjur/tests/conjur_variable/test.sh new file mode 100755 index 000000000..464921b81 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test.sh @@ -0,0 +1,225 @@ +#!/bin/bash -eu + +set -o pipefail + +# normalises project name by filtering non alphanumeric characters and transforming to lowercase +declare -x COMPOSE_PROJECT_NAME='' +declare -x ENTERPRISE_PROJECT='conjur-intro-variable' +declare -x ANSIBLE_PROJECT='' + +declare -x ANSIBLE_MASTER_AUTHN_API_KEY='' +declare -x CONJUR_ADMIN_AUTHN_API_KEY='' +declare -x DOCKER_NETWORK="default" +declare -x ANSIBLE_VERSION="${ANSIBLE_VERSION:-6}" + +ANSIBLE_PROJECT=$(echo "${BUILD_TAG:-ansible-plugin-testing}-conjur-variable" | sed -e 's/[^[:alnum:]]//g' | tr '[:upper:]' '[:lower:]') + +enterprise="false" +cli_cid="" +test_dir="$(pwd)" + +function cleanup { + echo 'Removing test environment' + echo '---' + + # Escape conjur-intro dir if Enterprise setup fails + cd "${test_dir}" + + if [[ -d conjur-intro ]]; then + pushd conjur-intro + COMPOSE_PROJECT_NAME="${ENTERPRISE_PROJECT}" + ./bin/dap --stop + popd + rm -rf conjur-intro + fi + + COMPOSE_PROJECT_NAME="${ANSIBLE_PROJECT}" + docker-compose down -v + rm -f conjur.pem \ + access_token +} +trap cleanup EXIT + +while getopts 'e' flag; do + case "${flag}" in + e) enterprise="true" ;; + *) exit 1 ;; + esac +done + +cleanup + +function wait_for_conjur { + echo "Waiting for Conjur server to come up" + docker-compose exec -T conjur conjurctl wait -r 30 -p 3000 +} + +function fetch_ssl_certs { + echo "Fetching SSL certs" + service_id="conjur_https" + cert_path="cert.crt" + if [[ "${enterprise}" == "true" ]]; then + service_id="conjur-master.mycompany.local" + cert_path="/etc/ssl/certs/ca.pem" + fi + + (docker-compose exec -T "${service_id}" cat "${cert_path}") > conjur.pem +} + +function setup_conjur_resources { + echo "Configuring Conjur via CLI" + + policy_path="root.yml" + if [[ "${enterprise}" == "false" ]]; then + policy_path="/policy/${policy_path}" + fi + + docker exec "${cli_cid}" bash -c " + conjur policy load root ${policy_path} + conjur variable values add ansible/test-secret test_secret_password + conjur variable values add ansible/test-secret-in-file test_secret_in_file_password + conjur variable values add 'ansible/var with spaces' var_with_spaces_secret_password + " +} + +function setup_admin_api_key { + echo "Fetching admin API key" + if [[ "$enterprise" == "true" ]]; then + CONJUR_ADMIN_AUTHN_API_KEY="$(docker exec "${cli_cid}" conjur user rotate_api_key)" + else + CONJUR_ADMIN_AUTHN_API_KEY="$(docker-compose exec -T conjur conjurctl role retrieve-key "${CONJUR_ACCOUNT}":user:admin)" + fi +} + +function setup_ansible_api_key { + echo "Fetching Ansible master host credentials" + ANSIBLE_MASTER_AUTHN_API_KEY="$(docker exec "${cli_cid}" conjur host rotate_api_key --host ansible/ansible-master)" +} + +function setup_access_token { + echo "Get Access Token" + docker exec "${cli_cid}" bash -c " + export CONJUR_AUTHN_LOGIN=host/ansible/ansible-master + export CONJUR_AUTHN_API_KEY=\"$ANSIBLE_MASTER_AUTHN_API_KEY\" + conjur authn authenticate + " > access_token +} + +function setup_conjur_open_source() { + docker-compose up -d --build conjur \ + conjur_https + + wait_for_conjur + fetch_ssl_certs + setup_admin_api_key + + echo "Creating Conjur CLI with admin credentials" + docker-compose up -d conjur_cli + cli_cid="$(docker-compose ps -q conjur_cli)" + + setup_conjur_resources + setup_ansible_api_key + setup_access_token +} + +function setup_conjur_enterprise() { + git clone --single-branch --branch main https://github.com/conjurdemos/conjur-intro.git + pushd ./conjur-intro + + echo "Provisioning Enterprise leader and follower" + ./bin/dap --provision-master + ./bin/dap --provision-follower + + cp ../policy/root.yml . + + # Run 'sleep infinity' in the CLI container, so the scripts + # have access to an alive and authenticated CLI until the script terminates + cli_cid="$(docker-compose run -d \ + -w /src/cli \ + --entrypoint sleep client infinity)" + + echo "Authenticate Conjur CLI container" + docker exec "${cli_cid}" \ + /bin/bash -c " + if [ ! -e /root/conjur-demo.pem ]; then + yes 'yes' | conjur init -u ${CONJUR_APPLIANCE_URL} -a ${CONJUR_ACCOUNT} + fi + conjur authn login -u admin -p MySecretP@ss1 + hostname -I + " + + fetch_ssl_certs + setup_conjur_resources + setup_admin_api_key + setup_ansible_api_key + setup_access_token + + echo "Relocate credential files" + mv conjur.pem ../. + mv access_token ../. + popd +} + +function run_test_cases { + for test_case in test_cases/*; do + run_test_case "$(basename -- "$test_case")" + done +} + +function run_test_case { + local test_case=$1 + echo "---- testing ${test_case} ----" + + if [ -z "$test_case" ]; then + echo ERROR: run_test called with no argument 1>&2 + exit 1 + fi + + docker-compose exec -T ansible bash -exc " + cd tests/conjur_variable + + # If env vars were provided, load them + if [ -e 'test_cases/${test_case}/env' ]; then + . ./test_cases/${test_case}/env + fi + + # You can add -vvvv here for debugging + ansible-playbook 'test_cases/${test_case}/playbook.yml' + + py.test --junitxml='./junit/${test_case}' \ + --connection docker \ + -v 'test_cases/${test_case}/tests/test_default.py' + " +} + +function main() { + if [[ "$enterprise" == "true" ]]; then + echo "Deploying Conjur Enterprise" + + export CONJUR_APPLIANCE_URL="https://conjur-master.mycompany.local" + export CONJUR_ACCOUNT="demo" + COMPOSE_PROJECT_NAME="${ENTERPRISE_PROJECT}" + DOCKER_NETWORK="dap_net" + + setup_conjur_enterprise + else + echo "Deploying Conjur Open Source" + + export CONJUR_APPLIANCE_URL="https://conjur-https" + export CONJUR_ACCOUNT="cucumber" + COMPOSE_PROJECT_NAME="${ANSIBLE_PROJECT}" + + setup_conjur_open_source + fi + + COMPOSE_PROJECT_NAME="${ANSIBLE_PROJECT}" + export CONJUR_AUTHN_LOGIN="host/ansible/ansible-master" + + echo "Preparing Ansible for test run" + docker-compose up -d --build ansible + + echo "Running tests" + run_test_cases +} + +main diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/env b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/env new file mode 100644 index 000000000..07d7632c0 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/env @@ -0,0 +1 @@ +export CONJUR_CERT_FILE=./bad/cert/path diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/playbook.yml new file mode 100644 index 000000000..516faec41 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/playbook.yml @@ -0,0 +1,15 @@ +--- +- name: Retrieve Conjur variable fails with bad cert + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secrets.txt + + - name: Retrieve Conjur variable with bad cert + vars: + super_secret_key: "{{lookup('conjur_variable', 'ansible/test-secret')}}" + shell: echo "{{super_secret_key}}" > /conjur_secrets.txt + ignore_errors: True diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/tests/test_default.py new file mode 100644 index 000000000..a3f2bbdf3 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/tests/test_default.py @@ -0,0 +1,13 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieval_failed(host): + secrets_file = host.file('/conjur_secrets.txt') + + assert not secrets_file.exists diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/bad-cert.pem b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/bad-cert.pem new file mode 100644 index 000000000..a3831e0ce --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/bad-cert.pem @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgIQN/xr5EKbXSqdyhGyGBWCizANBgkqhkiG9w0BAQsFADAY +MRYwFAYDVQQDEw1jb25qdXItb3NzLWNhMB4XDTIwMDYxMjIwNTYzOVoXDTIxMDYx +MjIwNTYzOVowGzEZMBcGA1UEAxMQY29uanVyLm15b3JnLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAOewPeFNcuLuE1tgpINSm4EajDXC+C6qsPhn +Jf3PhDFCpAEHckx1BVK01kFUdC6FOI6JEuI6pFnV1Tb9+WFYTX6wcGBAy90i+K9u +Xcjqb3sz5O3p6MjKL4xVvT4TxllT8cslNJix8gFrTYSvBFaUqCioGJAgyQyJ4SV+ +Tm/bXu/KdtfJQaLie+J5Xz/28220hC5NYlIjhMg5YgtRB7JjCj5bPe3PYykN5m8i +INWEw20EW+54YKNs5RDFNKzXOqF5h6Mrc/RcE1rbCGNOqveQ43DTFUgS4rVF8T8S +juO+LGfso2w6YvO7pT+ob9GxZytZXQSxrOXe8LpU4jSDS5g0+cECAwEAAaOB6zCB +6DAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC +MAwGA1UdEwEB/wQCMAAwgagGA1UdEQSBoDCBnYIQY29uanVyLm15b3JnLmNvbYIK +Y29uanVyLW9zc4IhY29uanVyLW9zcy50ZXN0LWRlcGxveS1kZWZhdWx0cy0xgiVj +b25qdXItb3NzLnRlc3QtZGVwbG95LWRlZmF1bHRzLTEuc3ZjgjNjb25qdXItb3Nz +LnRlc3QtZGVwbG95LWRlZmF1bHRzLTEuc3ZjLmNsdXN0ZXIubG9jYWwwDQYJKoZI +hvcNAQELBQADggEBAIdtOYlIdnojqVBbHGKPAJS8ZWDUm97W1KajZ6QGy6X7fD66 +tOb0QNhzLwbi4HQsuNR0rpWa48Z/sN1E6V5WlfG8pTrNRjqAc/sdobERMMS+rhtu +RfLu1UbYCRLXYIAQFIQFtGDVNXnuvhkCwDz6PV4rniml24qhnGeL3+8ZkW6m5+8u +XIt4Wq9otR3qj/Jx8eUg9eY/7RKgqCClP5Eg4szO0LaqQNblSR+3OgcGxmdTaJQt +BlXRIH0CPpX+3p3mO4zfKIDRHZ0tueWLqOVRARyx9n9qBbhlpBJnecS19PNUAGVa +10H1XkmpVXdadcV/8vBhjEpeq4cVgguS5oozG7Y= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIRAMUGxDd4cpSs7m9hvzTHoi4wDQYJKoZIhvcNAQELBQAw +GDEWMBQGA1UEAxMNY29uanVyLW9zcy1jYTAeFw0yMDA2MTIyMDU2MzhaFw0yMTA2 +MTIyMDU2MzhaMBgxFjAUBgNVBAMTDWNvbmp1ci1vc3MtY2EwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC111bZxfhVHPerwHXvc+ycgCcI02VtfsrH9Tyk +cmMsbUO6jF5aKBQj4fKSwbOCdXcqYoGwaQHQzOVMCGGruOYrOwfusOg2t2EQ7KIE +KWdP0BpAvASvkKwk/GGfaBqtzy1DvVyl0B8b/4C7tnta21Zs5HFOKo0CE+iX/FUQ +RDjpncE9Zhg2E2f1eCef4D+h2JJLtZPLOUZIUs0IMBPqQiL7iNSfY+e8dy6dRC9v +AhyFLULpK34aPm1DqwX3rHDPoLJl24sZFo8q9UvpCwj3sqVoABagS32yL/8//LvU +DaR4pgwuyd9sWf/CQkT0OHsHup5CH7xbYB0DSdmRJPeb07lHAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwICpDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYD +VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANrAiuLkZGmSQlURpWtvm +PgfPFPKPt1PAqjNwWhzMjHZg2P3UNBUTLeUdo52yJai6/iajlYTRPVvNUqiVnTay +/X9LwWH5EXTKCHagfQh4fYtTSFa12BUBlSP7at3S25pMDOpylb3CxdGe/Oh8S0HZ +gu7MMayFhcGCSJnT+F+JIqwnWkbWPYgHn0VCbBXN+5s7GJWFWwZljQzMCIa/xvwr +xuSX6Lsgai1Abqo1pDJA8RNyxMtn5V8RHgwjQ/BdeodptqZc/kULVDOZ0dkAKxyH +UYfqxxk4Ywc2JSSJYRs/RJpjngGnnLIOHgnruEIDtdOHw2yxAJZ/e7p8y9ThSxRo +5Q== +-----END CERTIFICATE----- diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/env b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/env new file mode 100644 index 000000000..73e6e980a --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/env @@ -0,0 +1 @@ +export CONJUR_CERT_FILE=./test_cases/retrieve-variable-bad-certs/bad_cert.pem diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/playbook.yml new file mode 100644 index 000000000..516faec41 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/playbook.yml @@ -0,0 +1,15 @@ +--- +- name: Retrieve Conjur variable fails with bad cert + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secrets.txt + + - name: Retrieve Conjur variable with bad cert + vars: + super_secret_key: "{{lookup('conjur_variable', 'ansible/test-secret')}}" + shell: echo "{{super_secret_key}}" > /conjur_secrets.txt + ignore_errors: True diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/tests/test_default.py new file mode 100644 index 000000000..a3f2bbdf3 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/tests/test_default.py @@ -0,0 +1,13 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieval_failed(host): + secrets_file = host.file('/conjur_secrets.txt') + + assert not secrets_file.exists diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/playbook.yml new file mode 100644 index 000000000..f1085642f --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/playbook.yml @@ -0,0 +1,14 @@ +--- +- name: Retrieve Conjur variable with disabled cert verification + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secrets.txt + + - name: Retrieve Conjur variable with disabled cert verification + vars: + super_secret_key: "{{lookup('conjur_variable', 'ansible/test-secret', validate_certs=False)}}" + shell: echo "{{super_secret_key}}" > /conjur_secrets.txt diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/tests/test_default.py new file mode 100644 index 000000000..a98ce29e9 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/tests/test_default.py @@ -0,0 +1,17 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieved_secret(host): + secrets_file = host.file('/conjur_secrets.txt') + + assert secrets_file.exists + + result = host.check_output("cat /conjur_secrets.txt", shell=True) + + assert result == "test_secret_password" diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/env b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/env new file mode 100644 index 000000000..2363951d1 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/env @@ -0,0 +1 @@ +export CONJUR_CERT_FILE=./conjur.pem diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/playbook.yml new file mode 100644 index 000000000..ef982db4f --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/playbook.yml @@ -0,0 +1,14 @@ +--- +- name: Retrieve Conjur variable into file + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secret_path.txt + + - name: Retrieve Conjur variable into file using as_file option + vars: + secret_path: "{{lookup('conjur_variable', 'ansible/test-secret-in-file', as_file=True)}}" + shell: echo -n "{{secret_path}}" > /lookup_output.txt diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/tests/test_default.py new file mode 100644 index 000000000..5d05f950b --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/tests/test_default.py @@ -0,0 +1,22 @@ +from __future__ import (absolute_import, division, print_function) + +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieved_secret(host): + """ + Verify that the as_file parameter makes the lookup plugin return the path to a temporary file + containing the secret. + """ + lookup_output_file = host.file('/lookup_output.txt') + assert lookup_output_file.exists + + secret_file = host.file(lookup_output_file.content_string) + assert secret_file.exists + assert secret_file.mode == 0o600 + assert secret_file.content_string == "test_secret_in_file_password" diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/playbook.yml new file mode 100644 index 000000000..516faec41 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/playbook.yml @@ -0,0 +1,15 @@ +--- +- name: Retrieve Conjur variable fails with bad cert + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secrets.txt + + - name: Retrieve Conjur variable with bad cert + vars: + super_secret_key: "{{lookup('conjur_variable', 'ansible/test-secret')}}" + shell: echo "{{super_secret_key}}" > /conjur_secrets.txt + ignore_errors: True diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/tests/test_default.py new file mode 100644 index 000000000..a3f2bbdf3 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/tests/test_default.py @@ -0,0 +1,13 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieval_failed(host): + secrets_file = host.file('/conjur_secrets.txt') + + assert not secrets_file.exists diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/bad-cert.pem b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/bad-cert.pem new file mode 100644 index 000000000..a3831e0ce --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/bad-cert.pem @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgIQN/xr5EKbXSqdyhGyGBWCizANBgkqhkiG9w0BAQsFADAY +MRYwFAYDVQQDEw1jb25qdXItb3NzLWNhMB4XDTIwMDYxMjIwNTYzOVoXDTIxMDYx +MjIwNTYzOVowGzEZMBcGA1UEAxMQY29uanVyLm15b3JnLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAOewPeFNcuLuE1tgpINSm4EajDXC+C6qsPhn +Jf3PhDFCpAEHckx1BVK01kFUdC6FOI6JEuI6pFnV1Tb9+WFYTX6wcGBAy90i+K9u +Xcjqb3sz5O3p6MjKL4xVvT4TxllT8cslNJix8gFrTYSvBFaUqCioGJAgyQyJ4SV+ +Tm/bXu/KdtfJQaLie+J5Xz/28220hC5NYlIjhMg5YgtRB7JjCj5bPe3PYykN5m8i +INWEw20EW+54YKNs5RDFNKzXOqF5h6Mrc/RcE1rbCGNOqveQ43DTFUgS4rVF8T8S +juO+LGfso2w6YvO7pT+ob9GxZytZXQSxrOXe8LpU4jSDS5g0+cECAwEAAaOB6zCB +6DAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC +MAwGA1UdEwEB/wQCMAAwgagGA1UdEQSBoDCBnYIQY29uanVyLm15b3JnLmNvbYIK +Y29uanVyLW9zc4IhY29uanVyLW9zcy50ZXN0LWRlcGxveS1kZWZhdWx0cy0xgiVj +b25qdXItb3NzLnRlc3QtZGVwbG95LWRlZmF1bHRzLTEuc3ZjgjNjb25qdXItb3Nz +LnRlc3QtZGVwbG95LWRlZmF1bHRzLTEuc3ZjLmNsdXN0ZXIubG9jYWwwDQYJKoZI +hvcNAQELBQADggEBAIdtOYlIdnojqVBbHGKPAJS8ZWDUm97W1KajZ6QGy6X7fD66 +tOb0QNhzLwbi4HQsuNR0rpWa48Z/sN1E6V5WlfG8pTrNRjqAc/sdobERMMS+rhtu +RfLu1UbYCRLXYIAQFIQFtGDVNXnuvhkCwDz6PV4rniml24qhnGeL3+8ZkW6m5+8u +XIt4Wq9otR3qj/Jx8eUg9eY/7RKgqCClP5Eg4szO0LaqQNblSR+3OgcGxmdTaJQt +BlXRIH0CPpX+3p3mO4zfKIDRHZ0tueWLqOVRARyx9n9qBbhlpBJnecS19PNUAGVa +10H1XkmpVXdadcV/8vBhjEpeq4cVgguS5oozG7Y= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIRAMUGxDd4cpSs7m9hvzTHoi4wDQYJKoZIhvcNAQELBQAw +GDEWMBQGA1UEAxMNY29uanVyLW9zcy1jYTAeFw0yMDA2MTIyMDU2MzhaFw0yMTA2 +MTIyMDU2MzhaMBgxFjAUBgNVBAMTDWNvbmp1ci1vc3MtY2EwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC111bZxfhVHPerwHXvc+ycgCcI02VtfsrH9Tyk +cmMsbUO6jF5aKBQj4fKSwbOCdXcqYoGwaQHQzOVMCGGruOYrOwfusOg2t2EQ7KIE +KWdP0BpAvASvkKwk/GGfaBqtzy1DvVyl0B8b/4C7tnta21Zs5HFOKo0CE+iX/FUQ +RDjpncE9Zhg2E2f1eCef4D+h2JJLtZPLOUZIUs0IMBPqQiL7iNSfY+e8dy6dRC9v +AhyFLULpK34aPm1DqwX3rHDPoLJl24sZFo8q9UvpCwj3sqVoABagS32yL/8//LvU +DaR4pgwuyd9sWf/CQkT0OHsHup5CH7xbYB0DSdmRJPeb07lHAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwICpDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYD +VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANrAiuLkZGmSQlURpWtvm +PgfPFPKPt1PAqjNwWhzMjHZg2P3UNBUTLeUdo52yJai6/iajlYTRPVvNUqiVnTay +/X9LwWH5EXTKCHagfQh4fYtTSFa12BUBlSP7at3S25pMDOpylb3CxdGe/Oh8S0HZ +gu7MMayFhcGCSJnT+F+JIqwnWkbWPYgHn0VCbBXN+5s7GJWFWwZljQzMCIa/xvwr +xuSX6Lsgai1Abqo1pDJA8RNyxMtn5V8RHgwjQ/BdeodptqZc/kULVDOZ0dkAKxyH +UYfqxxk4Ywc2JSSJYRs/RJpjngGnnLIOHgnruEIDtdOHw2yxAJZ/e7p8y9ThSxRo +5Q== +-----END CERTIFICATE----- diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/env b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/env new file mode 100644 index 000000000..b93328faf --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/env @@ -0,0 +1,4 @@ +unset CONJUR_AUTHN_API_KEY +unset CONJUR_AUTHN_LOGIN +export CONJUR_AUTHN_TOKEN_FILE=./access_token +export CONJUR_CERT_FILE=./test_cases/retrieve-variable-with-authn-token-bad-cert/bad-cert.pem diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/playbook.yml new file mode 100644 index 000000000..8423a2c13 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/playbook.yml @@ -0,0 +1,15 @@ +--- +- name: Retrieve Conjur variable with authn-token fails with bad cert + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secrets.txt + + - name: Retrieve Conjur variable with bad cert + vars: + super_secret_key: "{{lookup('conjur_variable', 'ansible/test-secret')}}" + shell: echo "{{super_secret_key}}" > /conjur_secrets.txt + ignore_errors: True diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/tests/test_default.py new file mode 100644 index 000000000..c87b160f4 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/tests/test_default.py @@ -0,0 +1,13 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieve_secret_failed(host): + secrets_file = host.file('/conjur_secrets.txt') + + assert not secrets_file.exists diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/env b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/env new file mode 100644 index 000000000..f4e4155ea --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/env @@ -0,0 +1,4 @@ +export CONJUR_CERT_FILE=./conjur.pem +unset CONJUR_AUTHN_API_KEY +unset CONJUR_AUTHN_LOGIN +export CONJUR_AUTHN_TOKEN_FILE=./access_token diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/playbook.yml new file mode 100644 index 000000000..e515b0f11 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/playbook.yml @@ -0,0 +1,14 @@ +--- +- name: Retrieve Conjur variable with authn-token + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secrets.txt + + - name: Retrieve Conjur variable + vars: + super_secret_key: "{{lookup('conjur_variable', 'ansible/test-secret')}}" + shell: echo "{{super_secret_key}}" > /conjur_secrets.txt diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/tests/test_default.py new file mode 100644 index 000000000..a98ce29e9 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/tests/test_default.py @@ -0,0 +1,17 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieved_secret(host): + secrets_file = host.file('/conjur_secrets.txt') + + assert secrets_file.exists + + result = host.check_output("cat /conjur_secrets.txt", shell=True) + + assert result == "test_secret_password" diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/env b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/env new file mode 100644 index 000000000..2363951d1 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/env @@ -0,0 +1 @@ +export CONJUR_CERT_FILE=./conjur.pem diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/playbook.yml new file mode 100644 index 000000000..103d7e082 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/playbook.yml @@ -0,0 +1,14 @@ +--- +- name: Retrieve Conjur variable with spaces in the variable name + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secrets.txt + + - name: Retrieve Conjur variable with spaces in the variable name + vars: + super_secret_key: "{{lookup('conjur_variable', 'ansible/var with spaces')}}" + shell: echo "{{super_secret_key}}" > /conjur_secrets.txt diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/tests/test_default.py new file mode 100644 index 000000000..145cbb2eb --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/tests/test_default.py @@ -0,0 +1,17 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieved_secret(host): + secrets_file = host.file('/conjur_secrets.txt') + + assert secrets_file.exists + + result = host.check_output("cat /conjur_secrets.txt", shell=True) + + assert result == "var_with_spaces_secret_password" diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/env b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/env new file mode 100644 index 000000000..2363951d1 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/env @@ -0,0 +1 @@ +export CONJUR_CERT_FILE=./conjur.pem diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/playbook.yml b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/playbook.yml new file mode 100644 index 000000000..44e993f97 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/playbook.yml @@ -0,0 +1,14 @@ +--- +- name: Retrieve Conjur variable + hosts: localhost + connection: local + tasks: + - name: Clean artifact path + file: + state: absent + path: /conjur_secrets.txt + + - name: Retrieve Conjur variable + vars: + super_secret_key: "{{lookup('conjur_variable', 'ansible/test-secret')}}" + shell: echo "{{super_secret_key}}" > /conjur_secrets.txt diff --git a/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/tests/test_default.py b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/tests/test_default.py new file mode 100644 index 000000000..a98ce29e9 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/tests/test_default.py @@ -0,0 +1,17 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = [os.environ['COMPOSE_PROJECT_NAME'] + '-ansible'] + + +def test_retrieved_secret(host): + secrets_file = host.file('/conjur_secrets.txt') + + assert secrets_file.exists + + result = host.check_output("cat /conjur_secrets.txt", shell=True) + + assert result == "test_secret_password" diff --git a/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.10.txt b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.10.txt new file mode 100644 index 000000000..92bf04480 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.10.txt @@ -0,0 +1,10 @@ +dev/start.sh shebang +Jenkinsfile shebang +tests/conjur_variable/policy/root.yml yamllint:unparsable-with-libyaml +roles/conjur_host_identity/tests/policy/root.yml yamllint:unparsable-with-libyaml # File loaded by summon utility (in Jenkinsfile), not via Python +ci/build_release shebang +ci/parse-changelog.sh shebang +ci/publish_to_galaxy shebang +ci/test.sh shebang +secrets.yml yamllint:unparsable-with-libyaml # File loaded by Conjur server, not via Python +dev/policy/root.yml yamllint:unparsable-with-libyaml
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.11.txt b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.11.txt new file mode 100644 index 000000000..6049963fb --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.11.txt @@ -0,0 +1,10 @@ +Jenkinsfile shebang +dev/start.sh shebang +tests/conjur_variable/policy/root.yml yamllint:unparsable-with-libyaml +roles/conjur_host_identity/tests/policy/root.yml yamllint:unparsable-with-libyaml # File loaded by summon utility (in Jenkinsfile), not via Python +ci/build_release shebang +ci/parse-changelog.sh shebang +ci/publish_to_galaxy shebang +ci/test.sh shebang +secrets.yml yamllint:unparsable-with-libyaml # File loaded by Conjur server, not via Python +dev/policy/root.yml yamllint:unparsable-with-libyaml
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.12.txt b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.12.txt new file mode 100644 index 000000000..5d750b26c --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.12.txt @@ -0,0 +1,10 @@ +Jenkinsfile shebang +dev/start.sh shebang +tests/conjur_variable/policy/root.yml yamllint:unparsable-with-libyaml # File loaded by Conjur server, not via Python +roles/conjur_host_identity/tests/policy/root.yml yamllint:unparsable-with-libyaml # File loaded by Conjur server, not via Python +ci/build_release shebang +ci/parse-changelog.sh shebang +ci/publish_to_galaxy shebang +ci/test.sh shebang +secrets.yml yamllint:unparsable-with-libyaml # File loaded by Summon utility (in Jenkinsfile), not via Python +dev/policy/root.yml yamllint:unparsable-with-libyaml
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.13.txt b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.13.txt new file mode 100644 index 000000000..5d750b26c --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.13.txt @@ -0,0 +1,10 @@ +Jenkinsfile shebang +dev/start.sh shebang +tests/conjur_variable/policy/root.yml yamllint:unparsable-with-libyaml # File loaded by Conjur server, not via Python +roles/conjur_host_identity/tests/policy/root.yml yamllint:unparsable-with-libyaml # File loaded by Conjur server, not via Python +ci/build_release shebang +ci/parse-changelog.sh shebang +ci/publish_to_galaxy shebang +ci/test.sh shebang +secrets.yml yamllint:unparsable-with-libyaml # File loaded by Summon utility (in Jenkinsfile), not via Python +dev/policy/root.yml yamllint:unparsable-with-libyaml
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.14.txt b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.14.txt new file mode 100644 index 000000000..00a2d8432 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.14.txt @@ -0,0 +1,11 @@ +Jenkinsfile shebang +dev/start.sh shebang +tests/conjur_variable/policy/root.yml yamllint:unparsable-with-libyaml # File loaded by Conjur server, not via Python +roles/conjur_host_identity/tests/policy/root.yml yamllint:unparsable-with-libyaml # File loaded by Conjur server, not via Python +ci/build_release shebang +ci/parse-changelog.sh shebang +ci/publish_to_galaxy shebang +ci/test.sh shebang +secrets.yml yamllint:unparsable-with-libyaml # File loaded by Summon utility (in Jenkinsfile), not via Python +dev/policy/root.yml yamllint:unparsable-with-libyaml +plugins/lookup/conjur_variable.py validate-modules:version-added-must-be-major-or-minor # Lookup plugin added in v1.0.2
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.9.txt b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.9.txt new file mode 100644 index 000000000..45c7c7e97 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/sanity/ignore-2.9.txt @@ -0,0 +1,8 @@ +Jenkinsfile shebang +dev/start.sh shebang +tests/conjur_variable/test.sh shebang +roles/conjur_host_identity/tests/test.sh shebang +ci/build_release shebang +ci/parse-changelog.sh shebang +ci/publish_to_galaxy shebang +ci/test.sh shebang
\ No newline at end of file diff --git a/ansible_collections/cyberark/conjur/tests/unit/Dockerfile b/ansible_collections/cyberark/conjur/tests/unit/Dockerfile new file mode 100644 index 000000000..66e584669 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/unit/Dockerfile @@ -0,0 +1,8 @@ +ARG PYTHON_VERSION +FROM python:${PYTHON_VERSION} + +ARG ANSIBLE_VERSION +RUN pip install https://github.com/ansible/ansible/archive/${ANSIBLE_VERSION}.tar.gz --disable-pip-version-check + +COPY tests/unit/requirements.txt /tmp/requirements.txt +RUN pip install -r /tmp/requirements.txt diff --git a/ansible_collections/cyberark/conjur/tests/unit/plugins/lookup/__init__.py b/ansible_collections/cyberark/conjur/tests/unit/plugins/lookup/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/unit/plugins/lookup/__init__.py diff --git a/ansible_collections/cyberark/conjur/tests/unit/plugins/lookup/test_conjur_variable.py b/ansible_collections/cyberark/conjur/tests/unit/plugins/lookup/test_conjur_variable.py new file mode 100644 index 000000000..7a0db1e12 --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/unit/plugins/lookup/test_conjur_variable.py @@ -0,0 +1,159 @@ +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +from unittest import TestCase +from unittest.mock import call, MagicMock, patch +from ansible.errors import AnsibleError +from ansible.plugins.loader import lookup_loader + +from ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable import _merge_dictionaries, _fetch_conjur_token, _fetch_conjur_variable +from ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable import _load_identity_from_file, _load_conf_from_file + + +class MockMergeDictionaries(MagicMock): + RESPONSE = {'id': 'host/ansible/ansible-fake', 'api_key': 'fakekey'} + + +class MockFileload(MagicMock): + RESPONSE = {} + + +class TestConjurLookup(TestCase): + def setUp(self): + self.lookup = lookup_loader.get("conjur_variable") + + def test_merge_dictionaries(self): + functionOutput = _merge_dictionaries( + {}, + {'id': 'host/ansible/ansible-fake', 'api_key': 'fakekey'} + ) + self.assertEquals(MockMergeDictionaries.RESPONSE, functionOutput) + + def test_load_identity_from_file(self): + load_identity = _load_identity_from_file("/etc/conjur.identity", "https://conjur-fake") + self.assertEquals(MockFileload.RESPONSE, load_identity) + + def test_load_conf_from_file(self): + load_conf = _load_conf_from_file("/etc/conjur.conf") + self.assertEquals(MockFileload.RESPONSE, load_conf) + + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable.open_url') + def test_fetch_conjur_token(self, mock_open_url): + mock_response = MagicMock() + mock_response.getcode.return_value = 200 + mock_response.read.return_value = "response body" + mock_open_url.return_value = mock_response + result = _fetch_conjur_token("url", "account", "username", "api_key", True, "cert_file") + mock_open_url.assert_called_with("url/authn/account/username/authenticate", + data="api_key", + method="POST", + validate_certs=True, + ca_path="cert_file") + self.assertEquals("response body", result) + + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._repeat_open_url') + def test_fetch_conjur_variable(self, mock_repeat_open_url): + mock_response = MagicMock() + mock_response.getcode.return_value = 200 + mock_response.read.return_value = "response body".encode("utf-8") + mock_repeat_open_url.return_value = mock_response + result = _fetch_conjur_variable("variable", b'{"protected":"fakeid"}', "url", "account", True, "cert_file") + mock_repeat_open_url.assert_called_with("url/secrets/account/variable/variable", + headers={'Authorization': 'Token token="eyJwcm90ZWN0ZWQiOiJmYWtlaWQifQ=="'}, + method="GET", + validate_certs=True, + ca_path="cert_file") + self.assertEquals(['response body'], result) + + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._fetch_conjur_variable') + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._fetch_conjur_token') + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._merge_dictionaries') + def test_run(self, mock_merge_dictionaries, mock_fetch_conjur_token, mock_fetch_conjur_variable): + mock_fetch_conjur_token.return_value = "token" + mock_fetch_conjur_variable.return_value = ["conjur_variable"] + mock_merge_dictionaries.side_effect = [ + {'account': 'fakeaccount', 'appliance_url': 'https://conjur-fake', 'cert_file': './conjurfake.pem'}, + {'id': 'host/ansible/ansible-fake', 'api_key': 'fakekey'} + ] + + terms = ['ansible/fake-secret'] + kwargs = {'as_file': False, 'conf_file': 'conf_file', 'validate_certs': False} + result = self.lookup.run(terms, **kwargs) + + self.assertEquals(result, ["conjur_variable"]) + + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._fetch_conjur_variable') + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._fetch_conjur_token') + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._merge_dictionaries') + def test_retrieve_to_file(self, mock_merge_dictionaries, mock_fetch_conjur_token, mock_fetch_conjur_variable): + mock_fetch_conjur_token.return_value = "token" + mock_fetch_conjur_variable.return_value = ["conjur_variable"] + mock_merge_dictionaries.side_effect = [ + {'account': 'fakeaccount', 'appliance_url': 'https://conjur-fake', 'cert_file': './conjurfake.pem'}, + {'id': 'host/ansible/ansible-fake', 'api_key': 'fakekey'} + ] + + terms = ['ansible/fake-secret'] + kwargs = {'as_file': True, 'conf_file': 'conf_file', 'validate_certs': False} + filepaths = self.lookup.run(terms, **kwargs) + self.assertRegex(filepaths[0], '/dev/shm/.*') + + with open(filepaths[0], "r") as file: + content = file.read() + self.assertEqual(content, "conjur_variable") + + # Negative test cases + + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._merge_dictionaries') + def test_run_bad_config(self, mock_merge_dictionaries): + # Withhold 'account' field + mock_merge_dictionaries.side_effect = [ + {'appliance_url': 'https://conjur-fake', 'cert_file': './conjurfake.pem'}, + {'id': 'host/ansible/ansible-fake', 'api_key': 'fakekey'} + ] + + terms = ['ansible/fake-secret'] + kwargs = {'as_file': False, 'conf_file': 'conf_file', 'validate_certs': True} + with self.assertRaises(AnsibleError) as context: + self.lookup.run(terms, **kwargs) + self.assertEqual( + context.exception.message, + "Configuration file on the controlling host must define `account` and `appliance_url` entries or they should be environment variables" + ) + + # Withhold 'id' and 'api_key' fields + mock_merge_dictionaries.side_effect = [ + {'account': 'fakeaccount', 'appliance_url': 'https://conjur-fake', 'cert_file': './conjurfake.pem'}, + {} + ] + + with self.assertRaises(AnsibleError) as context: + self.lookup.run(terms, **kwargs) + self.assertEqual( + context.exception.message, + ("Identity file on the controlling host must contain `login` and `password` " + "entries for Conjur appliance URL or they should be environment variables") + ) + + @patch('ansible_collections.cyberark.conjur.plugins.lookup.conjur_variable._merge_dictionaries') + def test_run_bad_cert_path(self, mock_merge_dictionaries): + mock_merge_dictionaries.side_effect = [ + {'account': 'fakeaccount', 'appliance_url': 'https://conjur-fake', 'cert_file': './conjurfake.pem'}, + {'id': 'host/ansible/ansible-fake', 'api_key': 'fakekey'} + ] + + terms = ['ansible/fake-secret'] + kwargs = {'as_file': False, 'conf_file': 'conf_file', 'validate_certs': True} + with self.assertRaises(FileNotFoundError): + self.lookup.run(terms, **kwargs) + + def test_run_no_variable_path(self): + kwargs = {'as_file': False, 'conf_file': 'conf_file', 'validate_certs': True} + + with self.assertRaises(AnsibleError) as context: + self.lookup.run([], **kwargs) + self.assertEqual(context.exception.message, "Invalid secret path: no secret path provided.") + + with self.assertRaises(AnsibleError) as context: + self.lookup.run([''], **kwargs) + self.assertEqual(context.exception.message, "Invalid secret path: empty secret path not accepted.") diff --git a/ansible_collections/cyberark/conjur/tests/unit/requirements.txt b/ansible_collections/cyberark/conjur/tests/unit/requirements.txt new file mode 100644 index 000000000..9b481ce1d --- /dev/null +++ b/ansible_collections/cyberark/conjur/tests/unit/requirements.txt @@ -0,0 +1,14 @@ +mock +pytest +pytest-mock +pytest-xdist +pytest-forked +pyyaml # required by the collection loader (only needed for collections) +coverage==4.5.4 + +bcrypt ; python_version >= '3.8' # controller only +passlib ; python_version >= '3.8' # controller only +pexpect ; python_version >= '3.8' # controller only +pytz +pywinrm ; python_version >= '3.8' # controller only +unittest2 ; python_version < '2.7' |