summaryrefslogtreecommitdiffstats
path: root/ansible_collections/cyberark/conjur
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/cyberark/conjur')
-rw-r--r--ansible_collections/cyberark/conjur/.codeclimate.yml162
-rw-r--r--ansible_collections/cyberark/conjur/.github/CODEOWNERS10
-rw-r--r--ansible_collections/cyberark/conjur/.github/workflows/ansible-test.yml91
-rw-r--r--ansible_collections/cyberark/conjur/.gitignore39
-rw-r--r--ansible_collections/cyberark/conjur/CHANGELOG.md84
-rw-r--r--ansible_collections/cyberark/conjur/CONTRIBUTING.md251
-rw-r--r--ansible_collections/cyberark/conjur/FILES.json1419
-rw-r--r--ansible_collections/cyberark/conjur/Jenkinsfile127
-rw-r--r--ansible_collections/cyberark/conjur/LICENSE201
-rw-r--r--ansible_collections/cyberark/conjur/MANIFEST.json43
-rw-r--r--ansible_collections/cyberark/conjur/README.md228
-rw-r--r--ansible_collections/cyberark/conjur/SECURITY.md42
-rwxr-xr-xansible_collections/cyberark/conjur/ci/build_release14
-rwxr-xr-xansible_collections/cyberark/conjur/ci/parse-changelog.sh6
-rwxr-xr-xansible_collections/cyberark/conjur/ci/publish_to_galaxy18
-rwxr-xr-xansible_collections/cyberark/conjur/ci/test.sh107
-rw-r--r--ansible_collections/cyberark/conjur/dev/Dockerfile38
-rw-r--r--ansible_collections/cyberark/conjur/dev/Dockerfile_nginx16
-rw-r--r--ansible_collections/cyberark/conjur/dev/ansible.cfg7
-rw-r--r--ansible_collections/cyberark/conjur/dev/docker-compose.yml74
-rw-r--r--ansible_collections/cyberark/conjur/dev/playbooks/conjur-identity-setup/conjur_role_playbook.yml11
-rw-r--r--ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-playbook-v2.yml6
-rw-r--r--ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-playbook.yml6
-rw-r--r--ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory-v2.j26
-rw-r--r--ansible_collections/cyberark/conjur/dev/playbooks/inventory-setup/inventory.j26
-rw-r--r--ansible_collections/cyberark/conjur/dev/policy/root.yml32
-rw-r--r--ansible_collections/cyberark/conjur/dev/proxy/default.conf33
-rw-r--r--ansible_collections/cyberark/conjur/dev/proxy/ssl.conf39
-rwxr-xr-xansible_collections/cyberark/conjur/dev/start.sh113
-rw-r--r--ansible_collections/cyberark/conjur/dev/test_app_centos/Dockerfile4
-rw-r--r--ansible_collections/cyberark/conjur/dev/test_app_ubuntu/Dockerfile5
-rwxr-xr-xansible_collections/cyberark/conjur/dev/test_unit.sh47
-rw-r--r--ansible_collections/cyberark/conjur/examples/test.yml11
-rw-r--r--ansible_collections/cyberark/conjur/meta/runtime.yml2
-rw-r--r--ansible_collections/cyberark/conjur/plugins/lookup/conjur_variable.py367
-rw-r--r--ansible_collections/cyberark/conjur/requirements.txt1
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/README.md8
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/defaults/main.yml6
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/meta/main.yml26
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/identity.yml73
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/identity_check.yml53
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/install.yml5
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/main.yml6
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/summon-conjur.yml13
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/summon.yml7
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tasks/uninstall.yml35
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/templates/conjur.conf.j25
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/templates/conjur.identity.j23
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.dockerignore1
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/.gitignore2
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/CACHEDIR.TAG4
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/README.md8
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/v/cache/nodeids22
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/.pytest_cache/v/cache/stepwise1
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/Dockerfile39
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/Dockerfile_nginx16
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/ansible.cfg8
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/docker-compose.yml84
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-playbook-v2.yml6
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-playbook.yml6
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory-v2.j26
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/inventory.j26
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/junit/cleanup-conjur-identity1
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/junit/configure-conjur-identity1
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/policy/root.yml32
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/proxy/default.conf33
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/proxy/ssl.conf39
-rwxr-xr-xansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test.sh249
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_app_centos/Dockerfile4
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_app_ubuntu/Dockerfile4
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/playbook.yml17
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/cleanup-conjur-identity/tests/test_default.py23
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/playbook.yml11
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/configure-conjur-identity/tests/test_default.py33
-rw-r--r--ansible_collections/cyberark/conjur/roles/conjur_host_identity/tests/test_cases/misconfig-conjur-identity/playbook.yml22
-rw-r--r--ansible_collections/cyberark/conjur/secrets.yml2
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/.dockerignore1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/.gitignore2
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/CACHEDIR.TAG4
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/README.md8
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/v/cache/nodeids11
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/.pytest_cache/v/cache/stepwise1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/Dockerfile31
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/Dockerfile_nginx17
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/docker-compose.yml67
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-bad-cert-path1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-bad-certs1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-disable-verify-certs1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-into-file1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-no-cert-provided1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-authn-token1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-authn-token-bad-cert1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/junit/retrieve-variable-with-spaces-secret1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/policy/root.yml21
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/proxy/default.conf29
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/proxy/ssl.conf39
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/pytest.ini2
-rwxr-xr-xansible_collections/cyberark/conjur/tests/conjur_variable/test.sh225
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/env1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/playbook.yml15
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-cert-path/tests/test_default.py13
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/bad-cert.pem41
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/env1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/playbook.yml15
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-bad-certs/tests/test_default.py13
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/playbook.yml14
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-disable-verify-certs/tests/test_default.py17
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/env1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/playbook.yml14
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-into-file/tests/test_default.py22
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/playbook.yml15
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-no-cert-provided/tests/test_default.py13
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/bad-cert.pem41
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/env4
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/playbook.yml15
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token-bad-cert/tests/test_default.py13
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/env4
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/playbook.yml14
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-authn-token/tests/test_default.py17
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/env1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/playbook.yml14
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable-with-spaces-secret/tests/test_default.py17
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/env1
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/playbook.yml14
-rw-r--r--ansible_collections/cyberark/conjur/tests/conjur_variable/test_cases/retrieve-variable/tests/test_default.py17
-rw-r--r--ansible_collections/cyberark/conjur/tests/sanity/ignore-2.10.txt10
-rw-r--r--ansible_collections/cyberark/conjur/tests/sanity/ignore-2.11.txt10
-rw-r--r--ansible_collections/cyberark/conjur/tests/sanity/ignore-2.12.txt10
-rw-r--r--ansible_collections/cyberark/conjur/tests/sanity/ignore-2.13.txt10
-rw-r--r--ansible_collections/cyberark/conjur/tests/sanity/ignore-2.14.txt11
-rw-r--r--ansible_collections/cyberark/conjur/tests/sanity/ignore-2.9.txt8
-rw-r--r--ansible_collections/cyberark/conjur/tests/unit/Dockerfile8
-rw-r--r--ansible_collections/cyberark/conjur/tests/unit/plugins/lookup/__init__.py0
-rw-r--r--ansible_collections/cyberark/conjur/tests/unit/plugins/lookup/test_conjur_variable.py159
-rw-r--r--ansible_collections/cyberark/conjur/tests/unit/requirements.txt14
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'