├── .editorconfig ├── .gitchangelog.rc ├── .github └── workflows │ └── test.yml ├── .gitignore ├── .travis.yml ├── AUTHORS ├── CHANGELOG.rst ├── LICENSE ├── MANIFEST.in ├── README.rst ├── SECURITY.md ├── action_plugins ├── ansible.cfg ├── ansible ├── __init__.py ├── module_utils │ ├── __init__.py │ └── hashivault.py ├── modules │ ├── __init__.py │ └── hashivault │ │ ├── __init__.py │ │ ├── hashivault_acl_policy.py │ │ ├── hashivault_acl_policy_get.py │ │ ├── hashivault_acl_policy_list.py │ │ ├── hashivault_approle_role.py │ │ ├── hashivault_approle_role_get.py │ │ ├── hashivault_approle_role_id.py │ │ ├── hashivault_approle_role_list.py │ │ ├── hashivault_approle_role_secret.py │ │ ├── hashivault_approle_role_secret_accessor_get.py │ │ ├── hashivault_approle_role_secret_get.py │ │ ├── hashivault_approle_role_secret_list.py │ │ ├── hashivault_audit.py │ │ ├── hashivault_audit_list.py │ │ ├── hashivault_auth_ldap.py │ │ ├── hashivault_auth_list.py │ │ ├── hashivault_auth_method.py │ │ ├── hashivault_aws_auth_config.py │ │ ├── hashivault_aws_auth_role.py │ │ ├── hashivault_azure_auth_config.py │ │ ├── hashivault_azure_auth_role.py │ │ ├── hashivault_azure_secret_engine_config.py │ │ ├── hashivault_azure_secret_engine_role.py │ │ ├── hashivault_cluster_status.py │ │ ├── hashivault_consul_secret_engine_config.py │ │ ├── hashivault_consul_secret_engine_role.py │ │ ├── hashivault_db_secret_engine_config.py │ │ ├── hashivault_db_secret_engine_role.py │ │ ├── hashivault_delete.py │ │ ├── hashivault_generate_root.py │ │ ├── hashivault_generate_root_cancel.py │ │ ├── hashivault_generate_root_init.py │ │ ├── hashivault_generate_root_status.py │ │ ├── hashivault_identity_entity.py │ │ ├── hashivault_identity_entity_alias.py │ │ ├── hashivault_identity_group.py │ │ ├── hashivault_identity_group_alias.py │ │ ├── hashivault_identity_group_alias_list.py │ │ ├── hashivault_init.py │ │ ├── hashivault_jwt_auth_method_config.py │ │ ├── hashivault_jwt_auth_role.py │ │ ├── hashivault_k8s_auth_config.py │ │ ├── hashivault_k8s_auth_role.py │ │ ├── hashivault_ldap_group.py │ │ ├── hashivault_leader.py │ │ ├── hashivault_list.py │ │ ├── hashivault_namespace.py │ │ ├── hashivault_oidc_auth_method_config.py │ │ ├── hashivault_oidc_auth_role.py │ │ ├── hashivault_pki_ca.py │ │ ├── hashivault_pki_ca_set.py │ │ ├── hashivault_pki_cert_get.py │ │ ├── hashivault_pki_cert_issue.py │ │ ├── hashivault_pki_cert_list.py │ │ ├── hashivault_pki_cert_revoke.py │ │ ├── hashivault_pki_cert_sign.py │ │ ├── hashivault_pki_crl.py │ │ ├── hashivault_pki_crl_get.py │ │ ├── hashivault_pki_crl_rotate.py │ │ ├── hashivault_pki_role.py │ │ ├── hashivault_pki_role_get.py │ │ ├── hashivault_pki_role_list.py │ │ ├── hashivault_pki_set_signed.py │ │ ├── hashivault_pki_tidy.py │ │ ├── hashivault_pki_url.py │ │ ├── hashivault_pki_url_get.py │ │ ├── hashivault_policy.py │ │ ├── hashivault_policy_get.py │ │ ├── hashivault_policy_list.py │ │ ├── hashivault_read.py │ │ ├── hashivault_read_to_file.py │ │ ├── hashivault_rekey.py │ │ ├── hashivault_rekey_cancel.py │ │ ├── hashivault_rekey_init.py │ │ ├── hashivault_rekey_status.py │ │ ├── hashivault_rekey_verify.py │ │ ├── hashivault_seal.py │ │ ├── hashivault_secret.py │ │ ├── hashivault_secret_engine.py │ │ ├── hashivault_secret_list.py │ │ ├── hashivault_ssh_role.py │ │ ├── hashivault_ssh_role_list.py │ │ ├── hashivault_status.py │ │ ├── hashivault_token_create.py │ │ ├── hashivault_token_lookup.py │ │ ├── hashivault_token_renew.py │ │ ├── hashivault_token_revoke.py │ │ ├── hashivault_token_role.py │ │ ├── hashivault_token_role_list.py │ │ ├── hashivault_unseal.py │ │ ├── hashivault_userpass.py │ │ ├── hashivault_write.py │ │ └── hashivault_write_from_file.py └── plugins │ ├── action │ ├── hashivault_read_to_file.py │ └── hashivault_write_from_file.py │ ├── doc_fragments │ └── hashivault.py │ └── lookup │ └── hashivault.py ├── example ├── Dockerfile ├── README.rst ├── ansible.cfg ├── hosts ├── run.sh └── test_remote_host.yml ├── functional ├── ansible.cfg ├── cacert.pem ├── hosts.ini ├── jwt.jws ├── run.sh ├── start.sh ├── stop.sh ├── templates │ ├── approlenv.sh.j2 │ ├── policy_rules.hcl │ ├── userpassenv.sh.j2 │ └── vaultenv.sh.j2 ├── test_acl_policy.yml ├── test_approle.yml ├── test_approle_check_mode.yml ├── test_approle_mount_point.yml ├── test_audit.yml ├── test_auth.yml ├── test_auth_method.yml ├── test_aws_auth_config.yml ├── test_aws_auth_role.yml ├── test_azure_auth_config.yml ├── test_azure_auth_role.yml ├── test_azure_config.yml ├── test_azure_role.yml ├── test_cas.yml ├── test_check.yml ├── test_consul_config.yml ├── test_consul_role.yml ├── test_db_config.yml ├── test_db_role.yml ├── test_delete.yml ├── test_delete_permanent.yml ├── test_enable_kv.yml ├── test_environment_lookup.yml ├── test_ephemeral.yml ├── test_full_path.yml ├── test_generate_root.yml ├── test_identity_entity.yml ├── test_identity_group.yml ├── test_init.yml ├── test_jwt_auth_method_config.yml ├── test_jwt_auth_role.yml ├── test_k8_auth.yml ├── test_kv2.yml ├── test_ldap_group.yml ├── test_list.yml ├── test_lookup.yml ├── test_mounts.yml ├── test_namespace.yml ├── test_not_there.yml ├── test_oidc_auth_method_config.yml ├── test_oidc_auth_role.yml ├── test_pki.yml ├── test_policy.yml ├── test_read.yml ├── test_read_write_file.yml ├── test_rekey.yml ├── test_rekey_verify.yml ├── test_secret.yml ├── test_secret_engine.yml ├── test_secret_list.yml ├── test_ssh_role.yml ├── test_ssh_role_check_mode.yml ├── test_status.yml ├── test_token_role.yml ├── test_token_role_check_mode.yml ├── test_tokens.yml ├── test_unseal.yml ├── test_userpass.yml ├── test_userpass_idempotent.yml ├── test_userpass_no_pass.yml ├── test_userpass_no_policy.yml └── test_write.yml ├── library ├── link.sh ├── lookup_plugins ├── makedocs.sh ├── meta └── main.yml ├── module_utils ├── setup.cfg ├── setup.py ├── test-requirements.txt ├── tox.ini └── upload.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.{py,rst,ini}] 12 | indent_style = space 13 | indent_size = 4 14 | 15 | [*.yml] 16 | indent_style = space 17 | indent_size = 2 18 | -------------------------------------------------------------------------------- /.gitchangelog.rc: -------------------------------------------------------------------------------- 1 | include_merge = False 2 | OUTPUT_FILE = "CHANGELOG.rst" 3 | INSERT_POINT = r"(?P[0-9]+\.[0-9]+(\.[0-9]+))\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n" 4 | revs = [ 5 | Caret(FileFirstRegexMatch(OUTPUT_FILE, INSERT_POINT)), 6 | "HEAD" 7 | ] 8 | 9 | publish = FileInsertAtFirstRegexMatch( 10 | OUTPUT_FILE, 11 | INSERT_POINT, 12 | idx=lambda m: m.start(1) 13 | ) 14 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | lint: 14 | name: Lint 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v2 18 | - uses: actions/setup-python@v2 19 | with: 20 | python-version: 3.9 21 | 22 | - name: Install requirements 23 | run: pip install -r test-requirements.txt 24 | 25 | - name: Lint with pycodestyle 26 | run: pycodestyle --max-line-length=120 ansible 27 | 28 | tests: 29 | name: Tests 30 | runs-on: ubuntu-latest 31 | strategy: 32 | matrix: 33 | python-version: 34 | - 3.9 35 | 36 | steps: 37 | - uses: "actions/checkout@v2" 38 | 39 | - name: Set up Python ${{ matrix.python-version }} 40 | uses: actions/setup-python@v2 41 | with: 42 | python-version: ${{ matrix.python-version }} 43 | 44 | - name: Install requirements 45 | run: pip install -r test-requirements.txt tox-gh-actions 46 | 47 | - name: Run tox 48 | run: tox 49 | 50 | docs: 51 | name: Documentation Tests 52 | runs-on: ubuntu-latest 53 | steps: 54 | - uses: actions/checkout@v2 55 | - uses: actions/setup-python@v2 56 | with: 57 | python-version: 3.9 58 | 59 | - name: Make docs 60 | run: ./makedocs.sh 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | .venv 3 | .cache 4 | .testenv 5 | 6 | # Packages 7 | .eggs 8 | *.egg 9 | *.egg-info 10 | dist 11 | build 12 | eggs 13 | sdist 14 | MANIFEST 15 | 16 | # Test 17 | .tox 18 | .testrepository 19 | 20 | # Editors 21 | *~ 22 | .*.swp 23 | .idea 24 | .vscode 25 | 26 | functional/approlenv.sh 27 | functional/userpassenv.sh 28 | functional/vaultenv.sh 29 | example/.ssh 30 | 31 | # Git 32 | *.orig 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - test 3 | language: python 4 | jobs: 5 | include: 6 | - stage: linting 7 | install: pip install pycodestyle==2.5.0 8 | name: "Linting with pycodestyle" 9 | python: "3.6" 10 | script: pycodestyle --max-line-length=120 ansible 11 | - stage: test 12 | name: Tests Python 2.7 13 | sudo: required 14 | python: 15 | - '2.7' 16 | services: 17 | - docker 18 | before_install: 19 | - docker pull vault:latest 20 | - docker ps -a 21 | install: pip install tox-travis 22 | script: tox 23 | - stage: test 24 | name: Tests Python 3.6 25 | sudo: required 26 | python: 27 | - '3.6' 28 | services: 29 | - docker 30 | before_install: 31 | - docker pull vault:latest 32 | - docker ps -a 33 | install: pip install tox-travis 34 | script: tox 35 | - stage: test 36 | name: Generating docs 37 | python: '3.6' 38 | deploy: 39 | local-dir: ansible-repo/ansible/docs/docsite/_build/html 40 | provider: pages 41 | skip-cleanup: true 42 | github-token: "$GITHUB_TOKEN" 43 | keep-history: true 44 | on: 45 | tags: true 46 | env: 47 | - PLUGINS='' 48 | install: 49 | - pip install sphinx sphinx_rtd_theme 50 | script: 51 | - ./makedocs.sh 52 | on: 53 | tags: true 54 | env: 55 | global: 56 | secure: oCC/bugXphWhcjNNFEGp5Cq7VrSrKiP7Nfw8BL8rNUia1RXD1DxE5jdddLdfWapFO9BRViOInyST9clN4Q67PmJAiTkeOcF0GbkyWzrwA7Tu9g0D7YjlgHo/euqL33hqf0iRst9gW4If0Gq9sa20+US6yNOX9OGa4LHGBjB55S0ayckCzRrOJg+eZNTe1M6YibQuvZXqBPJN3Juj3q37S4QGrIz275RrmdKdezZFs+JHt8W+HRm88lFTOMINSuc3tuoJjnAC0c+jJLiAC2HQ6AKgFS8DNqr8G8gMwhqtvAiSegQrgxot8bFdKmE0sQ61aKKzMF/GOGDPFPPeUlk33rXFyIsFEmEzhqtoGPobyZX/KRlJu55Aqgr/fHgoEAGOkb2wTsLPX9tI2GIuZ/oaV2rxgYsZhIMXG6i4+yXM4U6OBgHfdJPHwZoCpZRX6kixc3/aFny3E9jrVtDVZGwoJHq1e3O0pL0sYB5CHO7icLJrf4mOjI0hoPV9byd9JrJi5ROFwRfXeuMFYYHe/yhcclnYI/Cg91wrzLq+2877+vYWvBFoPEeKvCsLMSz3ko7QLv7s8dAhgV4TXrYNuayLtFcvij4H1s0DQcCTmFIf/LHp3Jnv2YsoNtcSYDLxGrg8w/jq4pgObyw0VXlznj2X6pMvYhufW6ObTUH4aoEQ3OA= 57 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Terry Howe 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Terry L Howe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS 2 | include CHANGELOG.rst 3 | include LICENSE 4 | include README.rst 5 | exclude .gitignore 6 | 7 | global-exclude *.pyc 8 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 5.x.x | :white_check_mark: | 8 | | 4.7.x | :white_check_mark: | 9 | | < 4.7 | :x: | 10 | 11 | ## Reporting a Vulnerability 12 | 13 | Direct message at https://www.linkedin.com/in/terrylhowe/ 14 | -------------------------------------------------------------------------------- /action_plugins: -------------------------------------------------------------------------------- 1 | ansible/plugins/action -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | retry_files_enabled = False 3 | nocows = 1 4 | -------------------------------------------------------------------------------- /ansible/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TerryHowe/ansible-modules-hashivault/8a1e65d1c5682f40a8fd051fa4a03534cface00e/ansible/__init__.py -------------------------------------------------------------------------------- /ansible/module_utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TerryHowe/ansible-modules-hashivault/8a1e65d1c5682f40a8fd051fa4a03534cface00e/ansible/module_utils/__init__.py -------------------------------------------------------------------------------- /ansible/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TerryHowe/ansible-modules-hashivault/8a1e65d1c5682f40a8fd051fa4a03534cface00e/ansible/modules/__init__.py -------------------------------------------------------------------------------- /ansible/modules/hashivault/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TerryHowe/ansible-modules-hashivault/8a1e65d1c5682f40a8fd051fa4a03534cface00e/ansible/modules/hashivault/__init__.py -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_acl_policy_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | from hvac.exceptions import InvalidPath 8 | 9 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 10 | DOCUMENTATION = ''' 11 | --- 12 | module: hashivault_acl_policy_get 13 | version_added: "5.3.0" 14 | short_description: Hashicorp Vault ACL policy get module 15 | description: 16 | - Module to get an ACL policy from Hashicorp Vault. 17 | options: 18 | name: 19 | description: 20 | - policy name. 21 | extends_documentation_fragment: hashivault 22 | ''' 23 | EXAMPLES = ''' 24 | --- 25 | - hosts: localhost 26 | tasks: 27 | - hashivault_acl_policy_get: 28 | name: 'annie' 29 | register: 'vault_acl_policy_get' 30 | - debug: msg="User policy is {{vault_acl_policy_get.policy}}" 31 | ''' 32 | 33 | 34 | def main(): 35 | argspec = hashivault_argspec() 36 | argspec['name'] = dict(required=True, type='str') 37 | module = hashivault_init(argspec) 38 | result = hashivault_acl_policy_get(module.params) 39 | if result.get('failed'): 40 | module.fail_json(**result) 41 | else: 42 | module.exit_json(**result) 43 | 44 | 45 | @hashiwrapper 46 | def hashivault_acl_policy_get(params): 47 | name = params.get('name') 48 | client = hashivault_auth_client(params) 49 | try: 50 | policy = client.sys.read_acl_policy(name) 51 | policy = policy.get('data', policy).get('policy', policy) 52 | except InvalidPath as e: 53 | policy = None 54 | 55 | if policy is None: 56 | result = {"changed": False, "rc": 1, "failed": True} 57 | result['msg'] = u"Policy \"%s\" does not exist." % name 58 | return result 59 | else: 60 | return {'rules': policy} 61 | 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_acl_policy_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_acl_policy_list 12 | version_added: "5.3.0" 13 | short_description: Hashicorp Vault ACL policy list module 14 | description: 15 | - Module to list ACL policies in Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_acl_policy_list: 23 | register: 'vault_acl_policy_list' 24 | - debug: msg="Policies are {{vault_acl_policy_list.policy}}" 25 | ''' 26 | 27 | 28 | def main(): 29 | argspec = hashivault_argspec() 30 | module = hashivault_init(argspec) 31 | result = hashivault_acl_policy_list(module.params) 32 | if result.get('failed'): 33 | module.fail_json(**result) 34 | else: 35 | module.exit_json(**result) 36 | 37 | 38 | @hashiwrapper 39 | def hashivault_acl_policy_list(params): 40 | client = hashivault_auth_client(params) 41 | current_policies = client.sys.list_acl_policies() 42 | if isinstance(current_policies, dict): 43 | current_policies = current_policies.get('data', current_policies) 44 | current_policies = current_policies.get('keys', current_policies) 45 | return {'policies': current_policies} 46 | 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_approle_role_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_approle_role_get 12 | version_added: "3.8.0" 13 | short_description: Hashicorp Vault approle role get module 14 | description: 15 | - Module to get a approle role from Hashicorp Vault. 16 | options: 17 | name: 18 | description: 19 | - role name. 20 | mount_point: 21 | description: 22 | - mount point for role 23 | default: approle 24 | extends_documentation_fragment: hashivault 25 | ''' 26 | EXAMPLES = ''' 27 | --- 28 | - hosts: localhost 29 | tasks: 30 | - hashivault_approle_role_get: 31 | name: 'ashley' 32 | register: 'vault_approle_role_get' 33 | - debug: msg="Role is {{vault_approle_role_get.role}}" 34 | ''' 35 | 36 | 37 | def main(): 38 | argspec = hashivault_argspec() 39 | argspec['name'] = dict(required=True, type='str') 40 | argspec['mount_point'] = dict(required=False, type='str', default='approle') 41 | module = hashivault_init(argspec) 42 | result = hashivault_approle_role_get(module.params) 43 | if result.get('failed'): 44 | module.fail_json(**result) 45 | else: 46 | module.exit_json(**result) 47 | 48 | 49 | @hashiwrapper 50 | def hashivault_approle_role_get(params): 51 | name = params.get('name') 52 | client = hashivault_auth_client(params) 53 | result = client.auth.approle.read_role(name, mount_point=params.get('mount_point')) 54 | return {'role': result} 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_approle_role_id.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_approle_role_id 12 | version_added: "3.8.0" 13 | short_description: Hashicorp Vault approle get role id module 14 | description: 15 | - Module to get a approle role id from Hashicorp Vault. 16 | options: 17 | name: 18 | description: 19 | - role name. 20 | mount_point: 21 | description: 22 | - mount point for role 23 | default: approle 24 | extends_documentation_fragment: hashivault 25 | ''' 26 | EXAMPLES = ''' 27 | --- 28 | - hosts: localhost 29 | tasks: 30 | - hashivault_approle_role_id: 31 | name: 'ashley' 32 | register: 'vault_approle_role_id' 33 | - debug: msg="Role id is {{vault_approle_role_id.id}}" 34 | ''' 35 | 36 | 37 | def main(): 38 | argspec = hashivault_argspec() 39 | argspec['name'] = dict(required=True, type='str') 40 | argspec['mount_point'] = dict(required=False, type='str', default='approle') 41 | module = hashivault_init(argspec) 42 | result = hashivault_approle_role_id(module.params) 43 | if result.get('failed'): 44 | module.fail_json(**result) 45 | else: 46 | module.exit_json(**result) 47 | 48 | 49 | @hashiwrapper 50 | def hashivault_approle_role_id(params): 51 | name = params.get('name') 52 | client = hashivault_auth_client(params) 53 | result = client.auth.approle.read_role_id(name, mount_point=params.get('mount_point')) 54 | data = result.get('data', {}) 55 | role_id = data.get('role_id', '') 56 | return {'id': role_id, 'data': data} 57 | 58 | 59 | if __name__ == '__main__': 60 | main() 61 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_approle_role_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_approle_role_list 12 | version_added: "3.8.0" 13 | short_description: Hashicorp Vault approle list roles module 14 | description: 15 | - Module to list approle roles from Hashicorp Vault. 16 | options: 17 | mount_point: 18 | description: 19 | - mount point for role 20 | default: approle 21 | extends_documentation_fragment: hashivault 22 | ''' 23 | EXAMPLES = ''' 24 | --- 25 | - hosts: localhost 26 | tasks: 27 | - hashivault_approle_role_list: 28 | register: 'vault_approle_role_list' 29 | - debug: msg="Roles are {{vault_approle_role_list.roles}}" 30 | ''' 31 | 32 | 33 | def main(): 34 | argspec = hashivault_argspec() 35 | argspec['mount_point'] = dict(required=False, type='str', default='approle') 36 | module = hashivault_init(argspec) 37 | result = hashivault_approle_role_list(module.params) 38 | if result.get('failed'): 39 | module.fail_json(**result) 40 | else: 41 | module.exit_json(**result) 42 | 43 | 44 | @hashiwrapper 45 | def hashivault_approle_role_list(params): 46 | client = hashivault_auth_client(params) 47 | roles = client.auth.approle.list_roles(mount_point=params.get('mount_point')) 48 | roles = roles.get('data', {}).get('keys', []) 49 | return {'roles': roles} 50 | 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_approle_role_secret_accessor_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_approle_role_secret_accessor_get 12 | version_added: "3.8.0" 13 | short_description: Hashicorp Vault approle role secret accessor get module 14 | description: 15 | - Module to get a approle role secret accessor from Hashicorp Vault. 16 | options: 17 | name: 18 | description: 19 | - role name. 20 | mount_point: 21 | description: 22 | - mount point for role 23 | default: approle 24 | accessor: 25 | description: 26 | - accessor id. 27 | extends_documentation_fragment: hashivault 28 | ''' 29 | EXAMPLES = ''' 30 | --- 31 | - hosts: localhost 32 | tasks: 33 | - hashivault_approle_role_secret_accessor_get: 34 | name: 'ashley' 35 | accessor: 'ec4bedee-e44b-c096-9ac8-1600e52ed8f8' 36 | register: 'vault_approle_role_secret_accessor_get' 37 | - debug: msg="Role secret is {{vault_approle_role_secret_accessor_get.secret}}" 38 | ''' 39 | 40 | 41 | def main(): 42 | argspec = hashivault_argspec() 43 | argspec['name'] = dict(required=True, type='str') 44 | argspec['mount_point'] = dict(required=False, type='str', default='approle') 45 | argspec['accessor'] = dict(required=True, type='str') 46 | module = hashivault_init(argspec) 47 | result = hashivault_approle_role_secret_accessor_get(module.params) 48 | if result.get('failed'): 49 | module.fail_json(**result) 50 | else: 51 | module.exit_json(**result) 52 | 53 | 54 | @hashiwrapper 55 | def hashivault_approle_role_secret_accessor_get(params): 56 | name = params.get('name') 57 | mount_point = params.get('mount_point') 58 | accessor = params.get('accessor') 59 | client = hashivault_auth_client(params) 60 | return {'secret': client.auth.approle.read_secret_id_accessor(name, accessor, mount_point=mount_point)['data']} 61 | 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_approle_role_secret_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_auth_client 6 | from ansible.module_utils.hashivault import hashivault_init 7 | from ansible.module_utils.hashivault import hashiwrapper 8 | 9 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 10 | DOCUMENTATION = ''' 11 | --- 12 | module: hashivault_approle_role_secret_get 13 | version_added: "3.8.0" 14 | short_description: Hashicorp Vault approle role secret id get module 15 | description: 16 | - Module to get a approle role secret id from Hashicorp Vault. 17 | options: 18 | name: 19 | description: 20 | - role name. 21 | mount_point: 22 | description: 23 | - mount point for role 24 | default: approle 25 | secret: 26 | description: 27 | - secret id. 28 | extends_documentation_fragment: hashivault 29 | ''' 30 | EXAMPLES = ''' 31 | --- 32 | - hosts: localhost 33 | tasks: 34 | - hashivault_approle_role_secret_get: 35 | name: 'ashley' 36 | secret: 'ec4bedee-e44b-c096-9ac8-1600e52ed8f8' 37 | register: 'vault_approle_role_secret_get' 38 | - debug: msg="Role secret is {{vault_approle_role_secret_get.secret}}" 39 | ''' 40 | 41 | 42 | def main(): 43 | argspec = hashivault_argspec() 44 | argspec['name'] = dict(required=True, type='str') 45 | argspec['mount_point'] = dict(required=False, type='str', default='approle') 46 | argspec['secret'] = dict(required=True, type='str') 47 | module = hashivault_init(argspec) 48 | result = hashivault_approle_role_secret_get(module.params) 49 | if result.get('failed'): 50 | module.fail_json(**result) 51 | else: 52 | module.exit_json(**result) 53 | 54 | 55 | @hashiwrapper 56 | def hashivault_approle_role_secret_get(params): 57 | try: 58 | name = params.get('name') 59 | mount_point = params.get('mount_point') 60 | secret = params.get('secret') 61 | client = hashivault_auth_client(params) 62 | response = client.auth.approle.read_secret_id(name, secret, mount_point=mount_point) 63 | if type(response) is not dict and response.status_code == 204: # No content 64 | return {'secret': {}, 'status': 'absent'} 65 | else: 66 | return {'secret': response['data'], 'response': response, 'status': 'present'} 67 | except Exception as e: 68 | return {'failed': True, 'msg': str(e)} 69 | 70 | 71 | if __name__ == '__main__': 72 | main() 73 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_approle_role_secret_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from hvac.exceptions import InvalidPath 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_auth_client 6 | from ansible.module_utils.hashivault import hashivault_init 7 | from ansible.module_utils.hashivault import hashiwrapper 8 | 9 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 10 | DOCUMENTATION = ''' 11 | --- 12 | module: hashivault_approle_role_secret_list 13 | version_added: "3.8.0" 14 | short_description: Hashicorp Vault approle role secret id get module 15 | description: 16 | - Module to get a approle role secret id from Hashicorp Vault. 17 | options: 18 | name: 19 | description: 20 | - role name. 21 | mount_point: 22 | description: 23 | - mount point for role 24 | default: approle 25 | extends_documentation_fragment: hashivault 26 | ''' 27 | EXAMPLES = ''' 28 | --- 29 | - hosts: localhost 30 | tasks: 31 | - hashivault_approle_role_secret_list: 32 | name: 'ashley' 33 | register: 'vault_approle_role_secret_list' 34 | - debug: msg="Role secrets are {{vault_approle_role_secret_list.secrets}}" 35 | ''' 36 | 37 | 38 | def main(): 39 | argspec = hashivault_argspec() 40 | argspec['name'] = dict(required=True, type='str') 41 | argspec['mount_point'] = dict(required=False, type='str', default='approle') 42 | module = hashivault_init(argspec) 43 | result = hashivault_approle_role_secret_list(module.params) 44 | if result.get('failed'): 45 | module.fail_json(**result) 46 | else: 47 | module.exit_json(**result) 48 | 49 | 50 | @hashiwrapper 51 | def hashivault_approle_role_secret_list(params): 52 | name = params.get('name') 53 | mount_point = params.get('mount_point') 54 | client = hashivault_auth_client(params) 55 | try: 56 | secrets = client.auth.approle.list_secret_id_accessors(name, mount_point=mount_point) 57 | except InvalidPath: 58 | return {'secrets': []} 59 | secrets = secrets.get('data', {}).get('keys', []) 60 | return {'secrets': str(secrets)} 61 | 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_audit_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_audit_list 12 | version_added: "2.2.0" 13 | short_description: Hashicorp Vault audit list module 14 | description: 15 | - Module to list audit backends in Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_audit_list: 23 | ''' 24 | 25 | 26 | def main(): 27 | argspec = hashivault_argspec() 28 | module = hashivault_init(argspec) 29 | result = hashivault_audit_list(module.params) 30 | if result.get('failed'): 31 | module.fail_json(**result) 32 | else: 33 | module.exit_json(**result) 34 | 35 | 36 | @hashiwrapper 37 | def hashivault_audit_list(params): 38 | client = hashivault_auth_client(params) 39 | backends = client.sys.list_enabled_audit_devices() 40 | backends = backends.get('data', backends) 41 | return {'changed': False, 'backends': backends} 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_auth_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_auth_list 12 | version_added: "2.2.0" 13 | short_description: Hashicorp Vault auth list module 14 | description: 15 | - Module to list authentication backends in Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_auth_list: 23 | register: 'hashivault_auth_list' 24 | ''' 25 | 26 | 27 | def main(): 28 | argspec = hashivault_argspec() 29 | module = hashivault_init(argspec, supports_check_mode=True) 30 | result = hashivault_auth_list(module.params) 31 | if result.get('failed'): 32 | module.fail_json(**result) 33 | else: 34 | module.exit_json(**result) 35 | 36 | 37 | @hashiwrapper 38 | def hashivault_auth_list(params): 39 | client = hashivault_auth_client(params) 40 | result = client.sys.list_auth_methods() 41 | if isinstance(result, dict): 42 | result = result.get('data', result) 43 | return {'changed': False, 'backends': result} 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_cluster_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_cluster_status 12 | version_added: "3.16.4" 13 | short_description: Hashicorp Vault cluster status module 14 | description: 15 | - Module to get cluster status of Hashicorp Vault. 16 | options: 17 | standby_ok: 18 | description: 19 | - Specifies if being a standby should still return the active status code instead of the standby status code 20 | default: False 21 | method: 22 | description: 23 | - Method to use to get cluster status, supported methods are HEAD (produces 000 (empty body)) and GET (produces 24 | 000 application/json) 25 | default: HEAD 26 | extends_documentation_fragment: hashivault 27 | ''' 28 | EXAMPLES = ''' 29 | --- 30 | - hosts: localhost 31 | tasks: 32 | - hashivault_cluster_status: 33 | register: 'vault_cluster_status' 34 | - debug: msg="Cluster is initialized: {{vault_cluster_status.status.initialized}}" 35 | ''' 36 | 37 | 38 | def main(): 39 | argspec = hashivault_argspec() 40 | argspec['standby_ok'] = dict(required=False, type='bool', default=True) 41 | argspec['method'] = dict(required=False, default="HEAD") 42 | module = hashivault_init(argspec) 43 | result = hashivault_cluster_status(module.params) 44 | if result.get('failed'): 45 | module.fail_json(**result) 46 | else: 47 | module.exit_json(**result) 48 | 49 | 50 | @hashiwrapper 51 | def hashivault_cluster_status(params): 52 | client = hashivault_client(params) 53 | response = client.sys.read_health_status(standby_ok=params.get("standby_ok"), method=params.get("method")) 54 | from requests.models import Response 55 | if isinstance(response, Response): 56 | try: 57 | status = response.json() 58 | except Exception: 59 | status = response.content 60 | else: 61 | status = response 62 | return {'status': status} 63 | 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_consul_secret_engine_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_consul_secret_engine_config 12 | version_added: "4.4.7" 13 | short_description: Hashicorp Vault consul secrets engine config 14 | description: 15 | - Module to configure the consul secrets engine 16 | options: 17 | mount_point: 18 | description: 19 | - name of the secret engine mount name. 20 | default: consul 21 | consul_address: 22 | description: 23 | - Specifies the address of the Consul instance, provided as "host:port" like "127.0.0.1:8500" 24 | scheme: 25 | description: 26 | - Specifies the URL scheme to use 27 | consul_token: 28 | description: 29 | - Specifies the Consul ACL token to use. This must be a management type token. 30 | extends_documentation_fragment: hashivault 31 | ''' 32 | EXAMPLES = ''' 33 | --- 34 | - hosts: localhost 35 | tasks: 36 | - hashivault_consul_secret_engine_config: 37 | consul_address: consul.local:8500 38 | scheme: https 39 | consul_token: myAwesomeConsulManagementToken 40 | ''' 41 | 42 | 43 | def main(): 44 | argspec = hashivault_argspec() 45 | argspec['mount_point'] = dict(required=False, type='str', default='consul') 46 | argspec['consul_address'] = dict(required=True, type='str') 47 | argspec['scheme'] = dict(required=True, type='str') 48 | argspec['consul_token'] = dict(required=True, type='str') 49 | 50 | module = hashivault_init(argspec, supports_check_mode=True) 51 | result = hashivault_consul_secret_engine_config(module) 52 | if result.get('failed'): 53 | module.fail_json(**result) 54 | else: 55 | module.exit_json(**result) 56 | 57 | 58 | @hashiwrapper 59 | def hashivault_consul_secret_engine_config(module): 60 | params = module.params 61 | client = hashivault_auth_client(params) 62 | mount_point = params.get('mount_point').strip('/') 63 | consul_address = params.get('consul_address') 64 | scheme = params.get('scheme') 65 | token = params.get('consul_token') 66 | 67 | if (mount_point + "/") not in client.sys.list_mounted_secrets_engines()['data']: 68 | return {'failed': True, 'msg': 'Consul secret engine is not enabled', 'rc': 1} 69 | 70 | if module.check_mode: 71 | return {'changed': True} 72 | 73 | response = client.secrets.consul.configure_access(consul_address, token, scheme=scheme, mount_point=mount_point) 74 | if response.ok: 75 | return {'changed': True} 76 | return {'failed': True, 'msg': response.text} 77 | 78 | 79 | if __name__ == '__main__': 80 | main() 81 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_generate_root.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_init 5 | from ansible.module_utils.hashivault import hashiwrapper 6 | from ansible.module_utils.hashivault import hashivault_client 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_generate_root 12 | version_added: "3.14.0" 13 | short_description: Hashicorp Vault generate_root module 14 | description: 15 | - Module to (update) generate_root Hashicorp Vault. 16 | options: 17 | key: 18 | description: 19 | - vault key shard. 20 | nonce: 21 | description: 22 | - generate_root nonce. 23 | extends_documentation_fragment: hashivault 24 | ''' 25 | EXAMPLES = ''' 26 | --- 27 | - hosts: localhost 28 | tasks: 29 | - hashivault_generate_root: 30 | key: '{{vault_unseal_key}}' 31 | nonce: '{{nonce}}' 32 | ''' 33 | 34 | 35 | def main(): 36 | argspec = hashivault_argspec() 37 | argspec['key'] = dict(required=False, type='str', no_log=True) 38 | argspec['nonce'] = dict(required=True, type='str') 39 | module = hashivault_init(argspec) 40 | result = hashivault_generate_root(module.params) 41 | if result.get('failed'): 42 | module.fail_json(**result) 43 | else: 44 | module.exit_json(**result) 45 | 46 | 47 | @hashiwrapper 48 | def hashivault_generate_root(params): 49 | key = params.get('key') 50 | nonce = params.get('nonce') 51 | client = hashivault_client(params) 52 | return {'status': client.sys.generate_root(key, nonce), 'changed': True} 53 | 54 | 55 | if __name__ == '__main__': 56 | main() 57 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_generate_root_cancel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_generate_root_cancel 12 | version_added: "3.14.0" 13 | short_description: Hashicorp Vault generate_root cancel module 14 | description: 15 | - Module to cancel generation of root token of Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_generate_root_cancel: 23 | ''' 24 | 25 | 26 | def main(): 27 | argspec = hashivault_argspec() 28 | module = hashivault_init(argspec) 29 | result = hashivault_generate_root_cancel(module.params) 30 | if result.get('failed'): 31 | module.fail_json(**result) 32 | else: 33 | module.exit_json(**result) 34 | 35 | 36 | @hashiwrapper 37 | def hashivault_generate_root_cancel(params): 38 | client = hashivault_client(params) 39 | # Check if generate_root is on-going & return when generate_root not in progress 40 | status = client.sys.read_root_generation_progress() 41 | if not status['started']: 42 | return {'changed': False} 43 | return {'status': client.sys.cancel_root_generation().ok, 'getter': str(status), 'changed': True} 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_generate_root_init.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_generate_root_init 12 | version_added: "3.14.0" 13 | short_description: Hashicorp Vault generate root token init module 14 | description: 15 | - Module to start root token generation of Hashicorp Vault. 16 | options: 17 | secret_shares: 18 | description: 19 | - specifies the number of shares to split the master key into. 20 | default: 5 21 | secret_threshold: 22 | description: 23 | - specifies the number of shares required to reconstruct the master key. 24 | default: 3 25 | pgp_key: 26 | description: 27 | - specifies PGP public keys used to encrypt the output root token. 28 | default: None 29 | otp: 30 | description: 31 | - must specify either pgp_key or otp 32 | default: None 33 | extends_documentation_fragment: hashivault 34 | ''' 35 | EXAMPLES = ''' 36 | --- 37 | - hosts: localhost 38 | tasks: 39 | - hashivault_generate_root_init: 40 | pgp_key: key 41 | ''' 42 | 43 | 44 | def main(): 45 | argspec = hashivault_argspec() 46 | argspec['pgp_key'] = dict(required=False, type='str', default=None) 47 | argspec['otp'] = dict(required=False, type='str', default=None) 48 | module = hashivault_init(argspec) 49 | result = hashivault_generate_root_init(module.params) 50 | if result.get('failed'): 51 | module.fail_json(**result) 52 | else: 53 | module.exit_json(**result) 54 | 55 | 56 | @hashiwrapper 57 | def hashivault_generate_root_init(params): 58 | client = hashivault_client(params) 59 | # Check if rekey is on-going 60 | status = client.sys.read_root_generation_progress() 61 | if status['started']: 62 | return {'changed': False} 63 | pgp_key = params.get('pgp_key') 64 | otp = params.get('otp') 65 | return {'status': client.sys.start_root_token_generation(otp=otp, pgp_key=pgp_key), 'changed': True} 66 | 67 | 68 | if __name__ == '__main__': 69 | main() 70 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_generate_root_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_generate_root_status 12 | version_added: "3.14.0" 13 | short_description: Hashicorp Vault generate_root status module 14 | description: 15 | - Module to get generate_root status of Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_generate_root_status: 23 | ''' 24 | 25 | 26 | def main(): 27 | argspec = hashivault_argspec() 28 | module = hashivault_init(argspec) 29 | result = hashivault_generate_root_status(module.params) 30 | if result.get('failed'): 31 | module.fail_json(**result) 32 | else: 33 | module.exit_json(**result) 34 | 35 | 36 | @hashiwrapper 37 | def hashivault_generate_root_status(params): 38 | client = hashivault_client(params) 39 | return {'status': client.generate_root_status} 40 | 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_identity_group_alias_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_identity_group_alias_list 12 | version_added: "4.7.1" 13 | short_description: Hashicorp Vault group alias list 14 | description: 15 | - Module to list group aliases from Hashicorp Vault. 16 | options: 17 | mount_point: 18 | description: 19 | - mount point for identity secrets engine 20 | default: identity 21 | extends_documentation_fragment: hashivault 22 | ''' 23 | EXAMPLES = ''' 24 | --- 25 | - hosts: localhost 26 | tasks: 27 | - hashivault_identity_group_alias_list: 28 | register: 'vault_group_alias_list' 29 | - debug: msg="Group Aliases are {{vault_group_alias_list.keys}}" 30 | ''' 31 | 32 | 33 | def main(): 34 | argspec = hashivault_argspec() 35 | argspec['mount_point'] = dict(required=False, type='str', default='identity') 36 | argspec['method'] = dict(required=False, type='str', default='GET') 37 | module = hashivault_init(argspec) 38 | result = hashivault_identity_group_alias_list(module.params) 39 | if result.get('failed'): 40 | module.fail_json(**result) 41 | else: 42 | module.exit_json(**result) 43 | 44 | 45 | @hashiwrapper 46 | def hashivault_identity_group_alias_list(params): 47 | client = hashivault_auth_client(params) 48 | result = client.secrets.identity.list_group_aliases( 49 | mount_point=params.get('mount_point'), 50 | method=params.get('method').upper()) 51 | if isinstance(result, dict): 52 | result = result.get('data', result) 53 | return {'changed': False, 'group_aliases': result} 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_leader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_leader 12 | version_added: "3.16.4" 13 | short_description: Hashicorp Vault leader module 14 | description: 15 | - Module to get leader information of Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_leader: 23 | register: 'vault_leader' 24 | - debug: msg="Leader is {{vault_leader.status.leader_address}}" 25 | ''' 26 | 27 | 28 | def main(): 29 | argspec = hashivault_argspec() 30 | module = hashivault_init(argspec) 31 | result = hashivault_leader(module.params) 32 | if result.get('failed'): 33 | module.fail_json(**result) 34 | else: 35 | module.exit_json(**result) 36 | 37 | 38 | @hashiwrapper 39 | def hashivault_leader(params): 40 | client = hashivault_client(params) 41 | return {'status': client.sys.read_leader_status()} 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_namespace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_namespace 12 | version_added: "4.0.1" 13 | short_description: Hashicorp Vault create / delete namespaces 14 | description: 15 | - Module to create or delete Hashicorp Vault namespaces (enterprise only) 16 | options: 17 | name: 18 | description: 19 | - name of the namespace 20 | state: 21 | description: 22 | - state of secret backend. choices: present, disabled 23 | extends_documentation_fragment: hashivault 24 | ''' 25 | EXAMPLES = ''' 26 | --- 27 | - hosts: localhost 28 | tasks: 29 | - hashivault_namespace: 30 | name: teama 31 | 32 | - name: "create a child namespace 'team1' in 'teama' ns: teama/team1" 33 | hashivault_namespace: 34 | name: team1 35 | namespace: teama 36 | ''' 37 | 38 | 39 | def main(): 40 | argspec = hashivault_argspec() 41 | argspec['name'] = dict(required=True, type='str') 42 | argspec['state'] = dict(required=False, type='str', choices=['present', 'absent'], default='present') 43 | module = hashivault_init(argspec) 44 | result = hashivault_secret_engine(module) 45 | if result.get('failed'): 46 | module.fail_json(**result) 47 | else: 48 | module.exit_json(**result) 49 | 50 | 51 | @hashiwrapper 52 | def hashivault_secret_engine(module): 53 | params = module.params 54 | client = hashivault_auth_client(params) 55 | name = params.get('name') 56 | state = params.get('state') 57 | current_state = dict() 58 | exists = False 59 | changed = False 60 | 61 | try: 62 | # does the ns exist already? 63 | current_state = client.sys.list_namespaces()['data']['keys'] 64 | if (name + '/') in current_state: 65 | exists = True 66 | except Exception: 67 | # doesnt exist 68 | pass 69 | 70 | # doesnt exist and should or does exist and shouldnt 71 | if (exists and state == 'absent') or (not exists and state == 'present'): 72 | changed = True 73 | 74 | # create 75 | if changed and not exists and state == 'present' and not module.check_mode: 76 | client.sys.create_namespace(path=name) 77 | 78 | # delete 79 | elif changed and (state == 'absent' or state == 'disabled') and not module.check_mode: 80 | client.sys.delete_namespace(path=name) 81 | 82 | return {'changed': changed} 83 | 84 | 85 | if __name__ == '__main__': 86 | main() 87 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_ca_set.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_ca_set 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI Submit CA Information 14 | description: 15 | - This module allows submitting the CA information for the backend via a PEM file containing the CA certificate and 16 | its private key, concatenated. 17 | - May optionally append additional CA certificates. Useful when creating an intermediate CA to ensure a full chain 18 | is returned when signing or generating certificates. 19 | - Not needed if you are generating a self-signed root certificate, and not used if you have a signed intermediate 20 | CA certificate with a generated key, use the hashivault_pki_set_signed for that. If you have already set a 21 | certificate and key, they will be overridden. 22 | options: 23 | mount_point: 24 | default: pki 25 | description: 26 | - location where secrets engine is mounted. also known as path 27 | pem_bundle: 28 | required: true 29 | type: str 30 | description: 31 | - Specifies the key and certificate concatenated in PEM format. 32 | extends_documentation_fragment: 33 | - hashivault 34 | ''' 35 | EXAMPLES = r''' 36 | --- 37 | - hosts: localhost 38 | tasks: 39 | - hashivault_pki_ca_set: 40 | pem_bundle: '-----BEGIN RSA PRIVATE KEY-----\n...\n-----END CERTIFICATE-----' 41 | ''' 42 | 43 | 44 | def main(): 45 | argspec = hashivault_argspec() 46 | argspec['pem_bundle'] = dict(required=True, type='str') 47 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 48 | 49 | supports_check_mode = True 50 | 51 | module = hashivault_init(argspec, supports_check_mode) 52 | result = hashivault_pki_ca_set(module) 53 | 54 | if result.get('failed'): 55 | module.fail_json(**result) 56 | else: 57 | module.exit_json(**result) 58 | 59 | 60 | @hashiwrapper 61 | def hashivault_pki_ca_set(module): 62 | params = module.params 63 | client = hashivault_auth_client(params) 64 | mount_point = params.get('mount_point').strip('/') 65 | pem_bundle = params.get('pem_bundle') 66 | 67 | if module.check_mode: 68 | return {'changed': True} 69 | 70 | result = {'changed': True} 71 | data = client.secrets.pki.submit_ca_information(pem_bundle=pem_bundle, mount_point=mount_point) 72 | if data: 73 | from requests.models import Response 74 | if isinstance(data, Response): 75 | result['data'] = data.text 76 | else: 77 | result['data'] = data 78 | 79 | return result 80 | 81 | 82 | if __name__ == '__main__': 83 | main() 84 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_cert_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_cert_get 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI Read Certificate 14 | description: 15 | - This module retrieves one of a selection of certificates. 16 | options: 17 | serial: 18 | recuired: true 19 | defaul: ca 20 | choices: ["ca", "ca_chain", "crl", ""] 21 | description: 22 | - Specifies the serial of the key to read. 23 | mount_point: 24 | default: pki 25 | description: 26 | - location where secrets engine is mounted. also known as path 27 | extends_documentation_fragment: 28 | - hashivault 29 | ''' 30 | EXAMPLES = r''' 31 | --- 32 | - hosts: localhost 33 | tasks: 34 | - hashivault_pki_cert_get: 35 | register: cert 36 | - debug: msg="{{ cert }}" 37 | 38 | - hashivault_pki_cert_get: 39 | serial: 0f-d0-bf-cc-7a-d2-b5-b8-ec-6d-8f-cb-9d-0a-c7-d1-e2-3b-82-7d 40 | register: cert 41 | - debug: msg="{{ cert }}" 42 | ''' 43 | 44 | 45 | def main(): 46 | argspec = hashivault_argspec() 47 | argspec['serial'] = dict(required=False, type='str', default='ca') 48 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 49 | 50 | module = hashivault_init(argspec) 51 | result = hashivault_pki_cert_get(module) 52 | 53 | if result.get('failed'): 54 | module.fail_json(**result) 55 | else: 56 | module.exit_json(**result) 57 | 58 | 59 | @hashiwrapper 60 | def hashivault_pki_cert_get(module): 61 | params = module.params 62 | client = hashivault_auth_client(params) 63 | 64 | serial = params.get('serial') 65 | mount_point = params.get('mount_point').strip('/') 66 | 67 | try: 68 | return {'data': client.secrets.pki.read_certificate(serial=serial, mount_point=mount_point).get('data')} 69 | except Exception: 70 | return {'data': {}} 71 | 72 | 73 | if __name__ == '__main__': 74 | main() 75 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_cert_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_cert_list 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI List Certificates 14 | description: 15 | - This module returns a list of the current certificates by serial number only. 16 | options: 17 | mount_point: 18 | default: pki 19 | description: 20 | - location where secrets engine is mounted. also known as path 21 | extends_documentation_fragment: 22 | - hashivault 23 | ''' 24 | EXAMPLES = r''' 25 | --- 26 | - hosts: localhost 27 | tasks: 28 | - hashivault_pki_cert_list: 29 | mount_point: pki 30 | register: roles_list 31 | - debug: msg="{{ roles_list.data }}" 32 | ''' 33 | RETURN = r''' 34 | --- 35 | data: 36 | description: list of roles, if pki engine has no roles will return empty list 37 | returned: success 38 | type: list 39 | ''' 40 | 41 | 42 | def main(): 43 | argspec = hashivault_argspec() 44 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 45 | 46 | module = hashivault_init(argspec) 47 | result = hashivault_pki_cert_list(module) 48 | 49 | if result.get('failed'): 50 | module.fail_json(**result) 51 | else: 52 | module.exit_json(**result) 53 | 54 | 55 | @hashiwrapper 56 | def hashivault_pki_cert_list(module): 57 | params = module.params 58 | client = hashivault_auth_client(params) 59 | 60 | mount_point = params.get('mount_point').strip('/') 61 | 62 | try: 63 | return {'data': client.secrets.pki.list_certificates(mount_point=mount_point).get('data').get('keys')} 64 | except Exception: 65 | return {'data': []} 66 | 67 | 68 | if __name__ == '__main__': 69 | main() 70 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_cert_revoke.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_cert_revoke 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI Revoke Certificate 14 | description: 15 | - This module revokes a certificate using its serial number. 16 | - This is an alternative option to the standard method of revoking using Vault lease IDs. 17 | - A successful revocation will rotate the CRL. 18 | options: 19 | serial: 20 | recuired: true 21 | description: 22 | - Specifies the serial number of the certificate to revoke, in hyphen-separated or colon-separated octal. 23 | mount_point: 24 | default: pki 25 | description: 26 | - location where secrets engine is mounted. also known as path 27 | extends_documentation_fragment: 28 | - hashivault 29 | ''' 30 | 31 | EXAMPLES = r''' 32 | --- 33 | - hosts: localhost 34 | tasks: 35 | - hashivault_pki_cert_revoke: 36 | role: 'tester' 37 | common_name: 'test.example.com' 38 | register: cert 39 | - debug: msg="{{ cert }}" 40 | 41 | ''' 42 | 43 | 44 | def main(): 45 | argspec = hashivault_argspec() 46 | argspec['serial'] = dict(required=True, type='str') 47 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 48 | 49 | module = hashivault_init(argspec) 50 | result = hashivault_pki_cert_revoke(module) 51 | 52 | if result.get('failed'): 53 | module.fail_json(**result) 54 | else: 55 | module.exit_json(**result) 56 | 57 | 58 | @hashiwrapper 59 | def hashivault_pki_cert_revoke(module): 60 | params = module.params 61 | client = hashivault_auth_client(params) 62 | 63 | serial = params.get('serial') 64 | mount_point = params.get('mount_point').strip('/') 65 | 66 | result = {"changed": False, "rc": 0} 67 | try: 68 | result['data'] = client.secrets.pki.revoke_certificate(serial_number=serial, 69 | mount_point=mount_point).get('data') 70 | except Exception as e: 71 | result['rc'] = 1 72 | result['failed'] = True 73 | result['msg'] = u"Exception: " + str(e) 74 | return result 75 | 76 | 77 | if __name__ == '__main__': 78 | main() 79 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_crl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import is_state_changed 7 | from ansible.module_utils.hashivault import hashiwrapper 8 | 9 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 10 | DOCUMENTATION = r''' 11 | --- 12 | module: hashivault_pki_crl 13 | version_added: "4.5.0" 14 | short_description: Hashicorp Vault PKI Set CRL Configuration 15 | description: 16 | - This module allows setting the duration for which the generated CRL should be marked valid. 17 | - If the CRL is disabled, it will return a signed but zero-length CRL for any request. 18 | - If enabled, it will re-build the CRL. 19 | options: 20 | mount_point: 21 | default: pki 22 | description: 23 | - location where secrets engine is mounted. also known as path 24 | expiry: 25 | required: true 26 | type: str 27 | description: 28 | - Specifies the time until expiration. 29 | disable: 30 | type: bool 31 | default: false 32 | description: 33 | - Disables or enables CRL building. 34 | extends_documentation_fragment: 35 | - hashivault 36 | ''' 37 | EXAMPLES = r''' 38 | --- 39 | - hosts: localhost 40 | tasks: 41 | - hashivault_pki_crl: 42 | expiry: 72h 43 | disable: false 44 | 45 | ''' 46 | 47 | 48 | def main(): 49 | argspec = hashivault_argspec() 50 | argspec['expiry'] = dict(required=True, type='str') 51 | argspec['disable'] = dict(required=False, type='bool', default=False) 52 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 53 | 54 | supports_check_mode = True 55 | 56 | module = hashivault_init(argspec, supports_check_mode) 57 | result = hashivault_pki_crl(module) 58 | 59 | if result.get('failed'): 60 | module.fail_json(**result) 61 | else: 62 | module.exit_json(**result) 63 | 64 | 65 | @hashiwrapper 66 | def hashivault_pki_crl(module): 67 | params = module.params 68 | client = hashivault_auth_client(params) 69 | 70 | mount_point = params.get('mount_point').strip('/') 71 | 72 | desired_state = { 73 | 'disable': params.get('disable'), 74 | 'expiry': params.get('expiry') 75 | } 76 | 77 | # compare current_state to desired_state 78 | from hvac.exceptions import InvalidPath 79 | try: 80 | current_state = client.secrets.pki.read_crl_configuration(mount_point=mount_point).get('data') 81 | changed = is_state_changed(desired_state, current_state) 82 | except InvalidPath: 83 | changed = True 84 | 85 | # make the changes! 86 | if changed and not module.check_mode: 87 | client.secrets.pki.set_crl_configuration(mount_point=mount_point, extra_params=desired_state) 88 | return {'changed': changed} 89 | 90 | 91 | if __name__ == '__main__': 92 | main() 93 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_crl_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_crl_get 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI Read CRL Configuration 14 | description: 15 | - This module allows getting the duration for which the generated CRL should be marked valid. 16 | options: 17 | mount_point: 18 | default: pki 19 | description: 20 | - location where secrets engine is mounted. also known as path 21 | extends_documentation_fragment: 22 | - hashivault 23 | ''' 24 | EXAMPLES = r''' 25 | --- 26 | - hosts: localhost 27 | tasks: 28 | - hashivault_pki_crl_get: 29 | register: clr_config 30 | - debug: msg="{{ clr_config }}" 31 | ''' 32 | 33 | 34 | def main(): 35 | argspec = hashivault_argspec() 36 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 37 | 38 | module = hashivault_init(argspec) 39 | result = hashivault_pki_crl_get(module) 40 | 41 | if result.get('failed'): 42 | module.fail_json(**result) 43 | else: 44 | module.exit_json(**result) 45 | 46 | 47 | @hashiwrapper 48 | def hashivault_pki_crl_get(module): 49 | params = module.params 50 | client = hashivault_auth_client(params) 51 | 52 | mount_point = params.get('mount_point').strip('/') 53 | 54 | result = {"changed": False, "rc": 0} 55 | from hvac.exceptions import InvalidPath 56 | try: 57 | result['data'] = client.secrets.pki.read_crl_configuration(mount_point=mount_point).get('data') 58 | except InvalidPath: 59 | result['rc'] = 1 60 | result['failed'] = True 61 | result['msg'] = u"CRLs must be configured before reading" 62 | except Exception as e: 63 | result['rc'] = 1 64 | result['failed'] = True 65 | result['msg'] = u"Exception: " + str(e) 66 | return result 67 | 68 | 69 | if __name__ == '__main__': 70 | main() 71 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_crl_rotate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_crl_rotate 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI Rotate CRLs 14 | description: 15 | - This module forces a rotation of the CRL. 16 | - This can be used by administrators to cut the size of the CRL if it contains a number of certificates that have 17 | now expired, but has not been rotated due to no further certificates being revoked. 18 | options: 19 | mount_point: 20 | default: pki 21 | description: 22 | - location where secrets engine is mounted. also known as path 23 | extends_documentation_fragment: 24 | - hashivault 25 | ''' 26 | EXAMPLES = r''' 27 | --- 28 | - hosts: localhost 29 | tasks: 30 | - hashivault_pki_crl_rotate: 31 | ''' 32 | 33 | 34 | def main(): 35 | argspec = hashivault_argspec() 36 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 37 | 38 | supports_check_mode = True 39 | 40 | module = hashivault_init(argspec, supports_check_mode) 41 | result = hashivault_pki_crl_rotate(module) 42 | 43 | if result.get('failed'): 44 | module.fail_json(**result) 45 | else: 46 | module.exit_json(**result) 47 | 48 | 49 | @hashiwrapper 50 | def hashivault_pki_crl_rotate(module): 51 | params = module.params 52 | client = hashivault_auth_client(params) 53 | 54 | mount_point = params.get('mount_point').strip('/') 55 | 56 | failed = False 57 | 58 | # make the changes! 59 | if not module.check_mode: 60 | failed = not client.secrets.pki.rotate_crl(mount_point=mount_point).get('data').get('success') 61 | return {'failed': failed, 'changed': not failed, 62 | 'msg': 'oops, something went wrong.' if failed else '', 'rc': 1 if failed else 0} 63 | 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_role_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_role_get 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI Read Role 14 | description: 15 | - This module queries the role definition. 16 | options: 17 | name: 18 | recuired: true 19 | description: 20 | - Specifies the name of the role to create. 21 | mount_point: 22 | default: pki 23 | description: 24 | - location where secrets engine is mounted. also known as path 25 | extends_documentation_fragment: 26 | - hashivault 27 | ''' 28 | EXAMPLES = r''' 29 | --- 30 | - hosts: localhost 31 | tasks: 32 | - hashivault_pki_role_get: 33 | name: tester 34 | register: role 35 | - debug: msg="{{ role }}" 36 | ''' 37 | 38 | 39 | def main(): 40 | argspec = hashivault_argspec() 41 | argspec['name'] = dict(required=True, type='str') 42 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 43 | 44 | module = hashivault_init(argspec) 45 | result = hashivault_pki_role_get(module) 46 | 47 | if result.get('failed'): 48 | module.fail_json(**result) 49 | else: 50 | module.exit_json(**result) 51 | 52 | 53 | @hashiwrapper 54 | def hashivault_pki_role_get(module): 55 | params = module.params 56 | client = hashivault_auth_client(params) 57 | 58 | name = params.get('name').strip('/') 59 | mount_point = params.get('mount_point').strip('/') 60 | 61 | result = {"changed": False, "rc": 0} 62 | from hvac.exceptions import InvalidPath 63 | try: 64 | result['data'] = client.secrets.pki.read_role(name=name, mount_point=mount_point).get('data') 65 | except InvalidPath: 66 | result['rc'] = 1 67 | result['failed'] = True 68 | result['msg'] = u"Role not found" 69 | except Exception as e: 70 | result['rc'] = 1 71 | result['failed'] = True 72 | result['msg'] = u"Exception: " + str(e) 73 | return result 74 | 75 | 76 | if __name__ == '__main__': 77 | main() 78 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_role_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_role_list 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI List Roles 14 | description: 15 | - This module returns a list of available roles. 16 | - Only the role names are returned, not any values. 17 | options: 18 | mount_point: 19 | default: pki 20 | description: 21 | - location where secrets engine is mounted. also known as path 22 | extends_documentation_fragment: 23 | - hashivault 24 | ''' 25 | EXAMPLES = r''' 26 | --- 27 | - hosts: localhost 28 | tasks: 29 | - hashivault_pki_role_list: 30 | mount_point: pki 31 | register: roles_list 32 | - debug: msg="{{ roles_list.data }}" 33 | ''' 34 | RETURN = r''' 35 | --- 36 | data: 37 | description: list of roles, if pki engine has no roles will return empty list 38 | returned: success 39 | type: list 40 | ''' 41 | 42 | 43 | def main(): 44 | argspec = hashivault_argspec() 45 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 46 | 47 | module = hashivault_init(argspec, supports_check_mode=True) 48 | result = hashivault_pki_role_list(module) 49 | 50 | if result.get('failed'): 51 | module.fail_json(**result) 52 | else: 53 | module.exit_json(**result) 54 | 55 | 56 | @hashiwrapper 57 | def hashivault_pki_role_list(module): 58 | params = module.params 59 | client = hashivault_auth_client(params) 60 | 61 | mount_point = params.get('mount_point').strip('/') 62 | 63 | try: 64 | return {'data': client.secrets.pki.list_roles(mount_point=mount_point).get('data').get('keys')} 65 | except Exception as e: 66 | return {'failed': True, 'data': [], 'msg': str(e)} 67 | 68 | 69 | if __name__ == '__main__': 70 | main() 71 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_pki_url_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = r''' 10 | --- 11 | module: hashivault_pki_url_get 12 | version_added: "4.5.0" 13 | short_description: Hashicorp Vault PKI Read URLs 14 | description: 15 | - This module fetches the URLs to be encoded in generated certificates. 16 | options: 17 | mount_point: 18 | default: pki 19 | description: 20 | - location where secrets engine is mounted. also known as path 21 | extends_documentation_fragment: 22 | - hashivault 23 | ''' 24 | EXAMPLES = r''' 25 | --- 26 | - hosts: localhost 27 | tasks: 28 | - hashivault_pki_url_get: 29 | register: url_config 30 | - debug: msg="{{ url_config }}" 31 | ''' 32 | 33 | 34 | def main(): 35 | argspec = hashivault_argspec() 36 | argspec['mount_point'] = dict(required=False, type='str', default='pki') 37 | 38 | module = hashivault_init(argspec) 39 | result = hashivault_pki_url_get(module) 40 | 41 | if result.get('failed'): 42 | module.fail_json(**result) 43 | else: 44 | module.exit_json(**result) 45 | 46 | 47 | @hashiwrapper 48 | def hashivault_pki_url_get(module): 49 | params = module.params 50 | client = hashivault_auth_client(params) 51 | 52 | mount_point = params.get('mount_point').strip('/') 53 | 54 | result = {"changed": False, "rc": 0} 55 | from hvac.exceptions import InvalidPath 56 | try: 57 | result['data'] = client.secrets.pki.read_urls(mount_point=mount_point).get('data') 58 | except InvalidPath: 59 | result['rc'] = 1 60 | result['failed'] = True 61 | result['msg'] = u"URLs must be configured before beeng read" 62 | except Exception as e: 63 | result['rc'] = 1 64 | result['failed'] = True 65 | result['msg'] = u"Exception: " + str(e) 66 | return result 67 | 68 | 69 | if __name__ == '__main__': 70 | main() 71 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_policy_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_policy_get 12 | version_added: "2.1.0" 13 | short_description: Hashicorp Vault policy get module 14 | description: 15 | - Module to get a policy from Hashicorp Vault. 16 | options: 17 | name: 18 | description: 19 | - policy name. 20 | extends_documentation_fragment: hashivault 21 | ''' 22 | EXAMPLES = ''' 23 | --- 24 | - hosts: localhost 25 | tasks: 26 | - hashivault_policy_get: 27 | name: 'annie' 28 | register: 'vault_policy_get' 29 | - debug: msg="User policy is {{vault_policy_get.policy}}" 30 | ''' 31 | 32 | 33 | def main(): 34 | argspec = hashivault_argspec() 35 | argspec['name'] = dict(required=True, type='str') 36 | module = hashivault_init(argspec) 37 | result = hashivault_policy_get(module.params) 38 | if result.get('failed'): 39 | module.fail_json(**result) 40 | else: 41 | module.exit_json(**result) 42 | 43 | 44 | @hashiwrapper 45 | def hashivault_policy_get(params): 46 | name = params.get('name') 47 | client = hashivault_auth_client(params) 48 | policy = client.get_policy(name) 49 | if policy is None: 50 | result = {"changed": False, "rc": 1, "failed": True} 51 | result['msg'] = u"Policy \"%s\" does not exist." % name 52 | return result 53 | else: 54 | return {'rules': policy} 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_policy_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_policy_list 12 | version_added: "2.1.0" 13 | short_description: Hashicorp Vault policy list module 14 | description: 15 | - Module to list policies in Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_policy_list: 23 | register: 'vault_policy_list' 24 | - debug: msg="Policies are {{vault_policy_list.policy}}" 25 | ''' 26 | 27 | 28 | def main(): 29 | argspec = hashivault_argspec() 30 | module = hashivault_init(argspec, supports_check_mode=True) 31 | result = hashivault_policy_list(module.params) 32 | if result.get('failed'): 33 | module.fail_json(**result) 34 | else: 35 | module.exit_json(**result) 36 | 37 | 38 | @hashiwrapper 39 | def hashivault_policy_list(params): 40 | client = hashivault_auth_client(params) 41 | current_policies = client.sys.list_policies() 42 | if isinstance(current_policies, dict): 43 | current_policies = current_policies.get('data', current_policies) 44 | current_policies = current_policies.get('policies', current_policies) 45 | return {'policies': current_policies} 46 | 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_read.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashivault_read 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_read 12 | version_added: "0.1" 13 | short_description: Hashicorp Vault read module 14 | description: 15 | - Module to read to Hashicorp Vault. 16 | options: 17 | version: 18 | description: 19 | - version of the kv engine (int) 20 | default: 1 21 | mount_point: 22 | description: 23 | - secret mount point 24 | default: secret 25 | secret: 26 | description: 27 | - secret to read. 28 | key: 29 | description: 30 | - secret key to read. 31 | secret_version: 32 | description: 33 | - secret version to read kv2 only. 34 | extends_documentation_fragment: hashivault 35 | ''' 36 | EXAMPLES = ''' 37 | --- 38 | - hosts: localhost 39 | tasks: 40 | - hashivault_read: 41 | secret: 'giant' 42 | key: 'fie' 43 | register: 'fie' 44 | - debug: msg="Value is {{fie.value}}" 45 | ''' 46 | 47 | 48 | def main(): 49 | argspec = hashivault_argspec() 50 | argspec['version'] = dict(required=False, type='int', default=1) 51 | argspec['mount_point'] = dict(required=False, type='str', default='secret') 52 | argspec['secret'] = dict(required=True, type='str') 53 | argspec['key'] = dict(required=False, type='str') 54 | argspec['default'] = dict(required=False, default=None, type='str') 55 | argspec['secret_version'] = dict(required=False, type='int') 56 | module = hashivault_init(argspec) 57 | result = hashivault_read(module.params) 58 | if result.get('failed'): 59 | module.fail_json(**result) 60 | else: 61 | module.exit_json(**result) 62 | 63 | 64 | if __name__ == '__main__': 65 | main() 66 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_read_to_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 4 | DOCUMENTATION = ''' 5 | --- 6 | module: hashivault_read_to_file 7 | version_added: "3.8.3" 8 | short_description: Hashicorp Vault read module 9 | description: 10 | - "Reads and deocdes a base64 encoded file from Hashicorp Vault and saves it to disk. Implementation in\ 11 | `/plugins/action/hashivault_read_to_file.py`." 12 | options: 13 | secret: 14 | description: 15 | - vault secret to read. 16 | key: 17 | description: 18 | - secret key/name of file to read from vault. 19 | dest: 20 | description: 21 | - fully qualified path name of file to write to remote host. 22 | force: 23 | description: 24 | - force overwrite of file. 25 | default: false 26 | mode: 27 | description: 28 | - file permissions of file to write on remote host. 29 | - in octal, don't forget leading zero! 30 | default: 0664 31 | base64: 32 | description: 33 | - Secret is base64 encoded 34 | default: True 35 | extends_documentation_fragment: hashivault 36 | ''' 37 | EXAMPLES = ''' 38 | --- 39 | - hosts: localhost 40 | tasks: 41 | - hashivault_read_to_file: 42 | secret: 'giant' 43 | key: 'foo.dat' 44 | dest: '/tmp/foo.dat' 45 | ''' 46 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_rekey.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_rekey 12 | version_added: "3.3.0" 13 | short_description: Hashicorp Vault rekey module 14 | description: 15 | - Module to (update) rekey Hashicorp Vault. Requires that a rekey 16 | be started with hashivault_rekey_init. 17 | options: 18 | key: 19 | description: 20 | - vault key shard (aka unseal key). 21 | nonce: 22 | description: 23 | - rekey nonce. 24 | extends_documentation_fragment: hashivault 25 | ''' 26 | EXAMPLES = ''' 27 | --- 28 | - hosts: localhost 29 | tasks: 30 | - name: Start a rekey 31 | hashivault_rekey_init: 32 | secret_shares: 1 33 | secret_threshold: 1 34 | verification_required: True 35 | register: 'vault_rekey_init' 36 | 37 | - name: Update the rekey 38 | hashivault_rekey: 39 | key: "{{ unseal_key }}" 40 | nonce: "{{ vault_rekey_init.status.nonce }}" 41 | ''' 42 | 43 | 44 | def main(): 45 | argspec = hashivault_argspec() 46 | argspec['key'] = dict(required=True, type='str', no_log=True) 47 | argspec['nonce'] = dict(required=True, type='str') 48 | module = hashivault_init(argspec) 49 | result = hashivault_rekey(module.params) 50 | if result.get('failed'): 51 | module.fail_json(**result) 52 | else: 53 | module.exit_json(**result) 54 | 55 | 56 | @hashiwrapper 57 | def hashivault_rekey(params): 58 | key = params.get('key') 59 | nonce = params.get('nonce') 60 | client = hashivault_client(params) 61 | return {'status': client.sys.rekey(key, nonce), 'changed': True} 62 | 63 | 64 | if __name__ == '__main__': 65 | main() 66 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_rekey_cancel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_rekey_cancel 12 | version_added: "3.3.0" 13 | short_description: Hashicorp Vault rekey cancel module 14 | description: 15 | - Module to cancel rekey Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_rekey_cancel: 23 | register: "vault_rekey_cancel" 24 | ''' 25 | 26 | 27 | def main(): 28 | argspec = hashivault_argspec() 29 | module = hashivault_init(argspec) 30 | result = hashivault_rekey_cancel(module.params) 31 | if result.get('failed'): 32 | module.fail_json(**result) 33 | else: 34 | module.exit_json(**result) 35 | 36 | 37 | @hashiwrapper 38 | def hashivault_rekey_cancel(params): 39 | client = hashivault_client(params) 40 | # Check if rekey is on-going & return when rekey not in progress 41 | status = client.rekey_status 42 | if not status['started']: 43 | return {'changed': False} 44 | return {'status': client.sys.cancel_rekey().ok, 'changed': True} 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_rekey_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_rekey_status 12 | version_added: "3.3.0" 13 | short_description: Hashicorp Vault rekey status module 14 | description: 15 | - Module to get rekey status of Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_rekey_status: 23 | register: "vault_rekey_status" 24 | ''' 25 | 26 | 27 | def main(): 28 | argspec = hashivault_argspec() 29 | module = hashivault_init(argspec) 30 | result = hashivault_rekey_status(module.params) 31 | if result.get('failed'): 32 | module.fail_json(**result) 33 | else: 34 | module.exit_json(**result) 35 | 36 | 37 | @hashiwrapper 38 | def hashivault_rekey_status(params): 39 | client = hashivault_client(params) 40 | return {'status': client.rekey_status} 41 | 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_rekey_verify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_rekey_verify 12 | version_added: "4.6.2" 13 | short_description: Hashicorp Vault rekey verify module 14 | description: 15 | - Module to verify a rekey of Hashicorp Vault. Requires that a rekey 16 | be started with hashivault_rekey_init passing verification_required == True 17 | and being successfully completed. 18 | options: 19 | key: 20 | description: 21 | - vault key shard (aka unseal key). The new, freshly generated one. 22 | nonce: 23 | description: 24 | - verify nonce. 25 | extends_documentation_fragment: hashivault 26 | ''' 27 | EXAMPLES = ''' 28 | --- 29 | - hosts: localhost 30 | tasks: 31 | - hashivault_rekey_verify: 32 | key: '{{vault_key}}' 33 | nonce: '{{nonce}}' 34 | ''' 35 | 36 | 37 | def main(): 38 | argspec = hashivault_argspec() 39 | argspec['key'] = dict(required=True, type='str', no_log=True) 40 | argspec['nonce'] = dict(required=True, type='str') 41 | module = hashivault_init(argspec) 42 | result = hashivault_rekey_verify(module.params) 43 | if result.get('failed'): 44 | module.fail_json(**result) 45 | else: 46 | module.exit_json(**result) 47 | 48 | 49 | @hashiwrapper 50 | def hashivault_rekey_verify(params): 51 | key = params.get('key') 52 | nonce = params.get('nonce') 53 | client = hashivault_client(params) 54 | return {'status': client.sys.rekey_verify(key, nonce), 'changed': True} 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_seal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_seal 12 | version_added: "1.2.0" 13 | short_description: Hashicorp Vault seal module 14 | description: 15 | - Module to seal Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_seal: 23 | register: 'vault_seal' 24 | - debug: msg="Seal return is {{vault_seal.rc}}" 25 | ''' 26 | 27 | 28 | def main(): 29 | argspec = hashivault_argspec() 30 | module = hashivault_init(argspec) 31 | result = hashivault_seal(module.params) 32 | if result.get('failed'): 33 | module.fail_json(**result) 34 | else: 35 | module.exit_json(**result) 36 | 37 | 38 | @hashiwrapper 39 | def hashivault_seal(params): 40 | client = hashivault_auth_client(params) 41 | if not client.sys.is_sealed(): 42 | status = client.sys.seal().ok 43 | return {'status': status, 'changed': True} 44 | else: 45 | return {'changed': False} 46 | 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_secret_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_secret_list 12 | version_added: "2.2.0" 13 | short_description: Hashicorp Vault secret list module 14 | description: 15 | - Module to list secret backends in Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_secret_list: 23 | register: 'hashivault_secret_list' 24 | ''' 25 | 26 | 27 | def main(): 28 | argspec = hashivault_argspec() 29 | module = hashivault_init(argspec, supports_check_mode=True) 30 | result = hashivault_secret_list(module.params) 31 | if result.get('failed'): 32 | module.fail_json(**result) 33 | else: 34 | module.exit_json(**result) 35 | 36 | 37 | @hashiwrapper 38 | def hashivault_secret_list(params): 39 | client = hashivault_auth_client(params) 40 | current_backends = client.sys.list_mounted_secrets_engines() 41 | if isinstance(current_backends, dict): 42 | current_backends = current_backends.get('data', current_backends) 43 | return {'changed': False, 'backends': current_backends} 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_ssh_role_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | from hvac.exceptions import InvalidPath 8 | 9 | ANSIBLE_METADATA = { 10 | "status": ["preview"], 11 | "supported_by": "community", 12 | "version": "1.1", 13 | } 14 | DOCUMENTATION = r""" 15 | --- 16 | module: hashivault_ssh_role_list 17 | version_added: "4.7.0" 18 | short_description: Hashicorp Vault SSH List Roles 19 | description: 20 | - This module returns a list of available roles. 21 | - Only the role names are returned, not any values. 22 | options: 23 | mount_point: 24 | default: ssh 25 | description: 26 | - location where secrets engine is mounted. also known as path 27 | extends_documentation_fragment: 28 | - hashivault 29 | """ 30 | EXAMPLES = r""" 31 | --- 32 | - hosts: localhost 33 | tasks: 34 | - hashivault_ssh_role_list: 35 | mount_point: ssh 36 | register: roles_list 37 | - debug: msg="{{ roles_list.data }}" 38 | """ 39 | RETURN = r""" 40 | --- 41 | data: 42 | description: list of roles, if ssh engine has no roles will return empty list 43 | returned: success 44 | type: list 45 | """ 46 | 47 | 48 | def main(): 49 | argspec = hashivault_argspec() 50 | argspec["mount_point"] = dict(required=False, type="str", default="ssh") 51 | 52 | module = hashivault_init(argspec, supports_check_mode=True) 53 | result = hashivault_pki_role_list(module) 54 | 55 | if result.get("failed"): 56 | module.fail_json(**result) 57 | else: 58 | module.exit_json(**result) 59 | 60 | 61 | @hashiwrapper 62 | def hashivault_pki_role_list(module): 63 | params = module.params 64 | client = hashivault_auth_client(params) 65 | 66 | mount_point = params.get("mount_point").strip("/") 67 | 68 | try: 69 | return { 70 | "data": client.secrets.kv.v1.list_secrets( 71 | mount_point=mount_point, 72 | path="roles", 73 | ) 74 | .get("data") 75 | .get("keys") 76 | } 77 | except InvalidPath as exc: 78 | if len(exc.errors) == 0: # Path is valid but no roles exist. 79 | return {"data": []} 80 | return {"failed": True, "data": [], "msg": str(exc)} 81 | except Exception as exc: 82 | return {"failed": True, "data": [], "msg": str(exc)} 83 | 84 | 85 | if __name__ == "__main__": 86 | main() 87 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_status 12 | version_added: "1.2.0" 13 | short_description: Hashicorp Vault status module 14 | description: 15 | - Module to get status of Hashicorp Vault. 16 | extends_documentation_fragment: hashivault 17 | ''' 18 | EXAMPLES = ''' 19 | --- 20 | - hosts: localhost 21 | tasks: 22 | - hashivault_status: 23 | register: 'vault_status' 24 | - debug: msg="Seal progress is {{vault_status.status.progress}}" 25 | ''' 26 | 27 | 28 | def main(): 29 | argspec = hashivault_argspec() 30 | module = hashivault_init(argspec) 31 | result = hashivault_status(module.params) 32 | if result.get('failed'): 33 | module.fail_json(**result) 34 | else: 35 | module.exit_json(**result) 36 | 37 | 38 | @hashiwrapper 39 | def hashivault_status(params): 40 | client = hashivault_client(params) 41 | return {'status': client.sys.read_seal_status()} 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_token_lookup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_auth_client 6 | from ansible.module_utils.hashivault import hashivault_init 7 | from ansible.module_utils.hashivault import hashiwrapper 8 | 9 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 10 | DOCUMENTATION = ''' 11 | --- 12 | module: hashivault_token_lookup 13 | version_added: "3.3.0" 14 | short_description: Hashicorp Vault token lookup module 15 | description: 16 | - Module to look up / check for existence of tokens in Hashicorp Vault. 17 | options: 18 | lookup_token: 19 | description: 20 | - token to lookup if different from auth token 21 | default: to authentication token 22 | accessor: 23 | description: 24 | - If set, lookups will use the this accessor token 25 | wrap_ttl: 26 | description: 27 | - Indicates that the response should be wrapped in a cubbyhole token with the requested TTL. 28 | extends_documentation_fragment: hashivault 29 | ''' 30 | EXAMPLES = ''' 31 | --- 32 | - hosts: localhost 33 | tasks: 34 | - name: "Lookup token" 35 | hashivault_token_lookup: 36 | lookup_token: "{{client_token}}" 37 | register: "vault_token_lookup" 38 | ''' 39 | 40 | 41 | def main(): 42 | argspec = hashivault_argspec() 43 | argspec['lookup_token'] = dict(required=False, type='str', no_log=True) 44 | argspec['accessor'] = dict(required=False, type='bool', default=False) 45 | argspec['wrap_ttl'] = dict(required=False, type='int') 46 | module = hashivault_init(argspec) 47 | result = hashivault_token_lookup(module.params) 48 | if result.get('failed'): 49 | module.fail_json(**result) 50 | else: 51 | module.exit_json(**result) 52 | 53 | 54 | @hashiwrapper 55 | def hashivault_token_lookup(params): 56 | client = hashivault_auth_client(params) 57 | accessor = params.get('accessor') 58 | lookup_token = params.get('lookup_token') 59 | if lookup_token is None: 60 | lookup_token = params.get('token') 61 | wrap_ttl = params.get('wrap_ttl') 62 | lookup = client.lookup_token(token=lookup_token, accessor=accessor, wrap_ttl=wrap_ttl) 63 | return {'changed': False, 'lookup': lookup} 64 | 65 | 66 | if __name__ == '__main__': 67 | main() 68 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_token_renew.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_token_renew 12 | version_added: "3.11.0" 13 | short_description: Hashicorp Vault token renew module 14 | description: 15 | - Module to renew tokens in Hashicorp Vault. 16 | options: 17 | renew_token: 18 | description: 19 | - token to renew if different from auth token 20 | default: to authentication token 21 | increment: 22 | description: 23 | - "Request a specific increment for renewal. Vault is not required to honor this request. If not supplied,\ 24 | Vault will use the default TTL." 25 | self_renew: 26 | description: 27 | - Self renew token 28 | wrap_ttl: 29 | description: 30 | - Indicates that the response should be wrapped in a cubbyhole token with the requested TTL. 31 | extends_documentation_fragment: hashivault 32 | ''' 33 | EXAMPLES = ''' 34 | --- 35 | - hosts: localhost 36 | tasks: 37 | - name: "Renew token" 38 | hashivault_token_renew: 39 | renew_token: "{{client_token}}" 40 | increment: "5m" 41 | register: "vault_token_renew" 42 | ''' 43 | 44 | 45 | def main(): 46 | argspec = hashivault_argspec() 47 | argspec['renew_token'] = dict(required=False, type='str', no_log=True) 48 | argspec['increment'] = dict(required=False, type='str', default=None) 49 | argspec['self_renew'] = dict(required=False, type='bool', default=False) 50 | argspec['wrap_ttl'] = dict(required=False, type='int') 51 | module = hashivault_init(argspec) 52 | result = hashivault_token_renew(module.params) 53 | if result.get('failed'): 54 | module.fail_json(**result) 55 | else: 56 | module.exit_json(**result) 57 | 58 | 59 | @hashiwrapper 60 | def hashivault_token_renew(params): 61 | client = hashivault_auth_client(params) 62 | renew_token = params.get('renew_token') 63 | increment = params.get('increment') 64 | self_renew = params.get('self_renew') 65 | if renew_token is None: 66 | renew_token = params.get('token') 67 | wrap_ttl = params.get('wrap_ttl') 68 | if self_renew is True: 69 | renew = client.renew_self_token(increment=increment, wrap_ttl=wrap_ttl) 70 | else: 71 | renew = client.renew_token(token=renew_token, increment=increment, wrap_ttl=wrap_ttl) 72 | return {'changed': True, 'renew': renew} 73 | 74 | 75 | if __name__ == '__main__': 76 | main() 77 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_token_revoke.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_auth_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_token_revoke 12 | version_added: "3.11.0" 13 | short_description: Hashicorp Vault token revoke module 14 | description: 15 | - Module to revoke tokens in Hashicorp Vault. 16 | options: 17 | revoke_token: 18 | description: 19 | - token to revoke if different from auth token 20 | default: to authentication token 21 | accessor: 22 | description: 23 | - If set, lookups will use the this accessor token 24 | orphan: 25 | description: 26 | - If set, Vault will revoke only the token, leaving the children as orphans. 27 | extends_documentation_fragment: hashivault 28 | ''' 29 | EXAMPLES = ''' 30 | --- 31 | - hosts: localhost 32 | tasks: 33 | - name: "revoke token" 34 | hashivault_token_revoke: 35 | revoke_token: "{{client_token}}" 36 | register: "vault_token_revoke" 37 | ''' 38 | 39 | 40 | def main(): 41 | argspec = hashivault_argspec() 42 | argspec['revoke_token'] = dict(required=False, type='str') 43 | argspec['accessor'] = dict(required=False, type='bool', default=False) 44 | argspec['orphan'] = dict(required=False, type='bool', default=False) 45 | module = hashivault_init(argspec) 46 | result = hashivault_token_revoke(module.params) 47 | if result.get('failed'): 48 | module.fail_json(**result) 49 | else: 50 | module.exit_json(**result) 51 | 52 | 53 | @hashiwrapper 54 | def hashivault_token_revoke(params): 55 | client = hashivault_auth_client(params) 56 | accessor = params.get('accessor') 57 | orphan = params.get('orphan') 58 | revoke_token = params.get('revoke_token') 59 | if revoke_token is None: 60 | revoke_token = params.get('token') 61 | revoke = client.revoke_token(token=revoke_token, orphan=orphan, accessor=accessor) 62 | return {'changed': True, 'revoke': revoke} 63 | 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_token_role_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_auth_client 4 | from ansible.module_utils.hashivault import hashivault_argspec 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | from hvac.exceptions import InvalidPath 8 | 9 | ANSIBLE_METADATA = { 10 | "status": ["preview"], 11 | "supported_by": "community", 12 | "version": "1.1", 13 | } 14 | DOCUMENTATION = r""" 15 | --- 16 | module: hashivault_token_role_list 17 | version_added: "4.7.0" 18 | short_description: Hashicorp Vault Token List Roles 19 | description: 20 | - This module returns a list of available token roles. 21 | - Only the role names are returned, not any values. 22 | options: 23 | mount_point: 24 | default: token 25 | description: 26 | - location where the token auth engine is mounted. also known as path 27 | extends_documentation_fragment: 28 | - hashivault 29 | """ 30 | EXAMPLES = r""" 31 | --- 32 | - hosts: localhost 33 | tasks: 34 | - hashivault_token_role_list: 35 | mount_point: token 36 | register: roles_list 37 | - debug: msg="{{ roles_list.data }}" 38 | """ 39 | RETURN = r""" 40 | --- 41 | data: 42 | description: list of roles, if auth token engine has no roles will return empty list 43 | returned: success 44 | type: list 45 | """ 46 | 47 | 48 | def main(): 49 | argspec = hashivault_argspec() 50 | argspec["mount_point"] = dict(required=False, type="str", default="token") 51 | 52 | module = hashivault_init(argspec, supports_check_mode=True) 53 | result = hashivault_token_role_list(module) 54 | 55 | if result.get("failed"): 56 | module.fail_json(**result) 57 | else: 58 | module.exit_json(**result) 59 | 60 | 61 | @hashiwrapper 62 | def hashivault_token_role_list(module): 63 | params = module.params 64 | client = hashivault_auth_client(params) 65 | 66 | mount_point = params.get("mount_point").strip("/") 67 | 68 | try: 69 | return { 70 | "data": client.auth.token.list_roles(mount_point=mount_point) 71 | .get("data") 72 | .get("keys") 73 | } 74 | except InvalidPath as exc: 75 | if len(exc.errors) == 0: # Path is valid but no roles exist. 76 | return {"data": []} 77 | return {"failed": True, "data": [], "msg": str(exc)} 78 | except Exception as exc: 79 | return {"failed": True, "data": [], "msg": str(exc)} 80 | 81 | 82 | if __name__ == "__main__": 83 | main() 84 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_unseal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.hashivault import hashivault_argspec 4 | from ansible.module_utils.hashivault import hashivault_client 5 | from ansible.module_utils.hashivault import hashivault_init 6 | from ansible.module_utils.hashivault import hashiwrapper 7 | 8 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 9 | DOCUMENTATION = ''' 10 | --- 11 | module: hashivault_unseal 12 | version_added: "1.2.0" 13 | short_description: Hashicorp Vault unseal module 14 | description: 15 | - Module to unseal Hashicorp Vault. 16 | options: 17 | keys: 18 | description: 19 | - vault key shard(s). 20 | extends_documentation_fragment: hashivault 21 | ''' 22 | EXAMPLES = ''' 23 | --- 24 | - hosts: localhost 25 | tasks: 26 | - hashivault_unseal: 27 | keys: '{{vault_keys}}' 28 | ''' 29 | 30 | 31 | def main(): 32 | argspec = hashivault_argspec() 33 | argspec['keys'] = dict(required=True, type='str', no_log=True) 34 | module = hashivault_init(argspec) 35 | result = hashivault_unseal(module.params) 36 | if result.get('failed'): 37 | module.fail_json(**result) 38 | else: 39 | module.exit_json(**result) 40 | 41 | 42 | @hashiwrapper 43 | def hashivault_unseal(params): 44 | keys = params.get('keys') 45 | client = hashivault_client(params) 46 | if client.sys.is_sealed(): 47 | return {'status': client.sys.submit_unseal_keys(keys.split()), 'changed': True} 48 | else: 49 | return {'changed': False} 50 | 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /ansible/modules/hashivault/hashivault_write_from_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'} 4 | DOCUMENTATION = ''' 5 | --- 6 | module: hashivault_write_from_file 7 | version_added: "3.8.3" 8 | short_description: Hashicorp Vault write file module 9 | description: 10 | - "Writes a file encoded in base64 to Hashicorp Vault. Implementation in 11 | `/plugins/action/hashivault_write_from_file.py`." 12 | options: 13 | secret: 14 | description: 15 | - vault secret to write. 16 | key: 17 | description: 18 | - secret key/name of file to write to vault. 19 | dest: 20 | description: 21 | - fully qualified path name of file to read from remote host. 22 | update: 23 | description: 24 | - Update secret rather than overwrite. 25 | default: True 26 | extends_documentation_fragment: hashivault 27 | ''' 28 | EXAMPLES = ''' 29 | --- 30 | - hosts: localhost 31 | tasks: 32 | - hashivault_write_from_file: 33 | secret: giant 34 | key: foo.dat 35 | path: /tmp/foo.dat 36 | ''' 37 | -------------------------------------------------------------------------------- /ansible/plugins/action/hashivault_write_from_file.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # 3 | # Developed for AT&T by Nicholas Gibson, August 2017 4 | # 5 | # Action plugin for hashivault_write_from_file module. 6 | # 7 | # Reads file from remote host using slurp module. (base64 encoded) 8 | # Stores file/secret to Vault using hashivault_read module on localhost. 9 | # 10 | ######################################################################## 11 | 12 | from ansible.plugins.action import ActionBase 13 | from ansible.utils.vars import merge_hash 14 | 15 | 16 | class ActionModule(ActionBase): 17 | 18 | def run(self, tmp=None, task_vars=None): 19 | 20 | if task_vars is None: 21 | task_vars = dict() 22 | 23 | results = super(ActionModule, self).run(tmp, task_vars) 24 | 25 | args = self._task.args.copy() 26 | 27 | key = args.pop('key', None) 28 | path = args.pop('path', None) 29 | 30 | new_module_args = { 31 | 'src': path 32 | } 33 | self._update_module_args('slurp', new_module_args, task_vars) 34 | 35 | results = merge_hash( 36 | results, 37 | # executes slurp module on remote host 38 | self._execute_module(module_name='slurp', tmp=tmp, task_vars=task_vars, module_args=new_module_args) 39 | ) 40 | 41 | if 'failed' in results and results['failed'] is True: 42 | return results 43 | 44 | # already base64 encoded from slurp 45 | content = results.pop('content', None) 46 | 47 | self._play_context.become = False 48 | self._play_context.become_method = None 49 | 50 | self._connection = self._shared_loader_obj.connection_loader.get('local', self._play_context, 51 | self._connection._new_stdin) 52 | 53 | args['data'] = {key: content} 54 | if 'update' not in args: 55 | args['update'] = True 56 | 57 | results = merge_hash( 58 | results, 59 | # executes hashivault_write module on localhost 60 | self._execute_module(module_name='hashivault_write', tmp=tmp, task_vars=task_vars, module_args=args) 61 | ) 62 | 63 | results['invocation']['module_args']['data'] = 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' 64 | 65 | return results 66 | -------------------------------------------------------------------------------- /ansible/plugins/doc_fragments/hashivault.py: -------------------------------------------------------------------------------- 1 | class ModuleDocFragment(object): 2 | # Standard documentation 3 | DOCUMENTATION = r''' 4 | requirements: 5 | - hvac>=2.1.0 6 | - ansible>=2.12.0 7 | - requests 8 | options: 9 | url: 10 | description: 11 | - url for vault 12 | default: to environment variable `VAULT_ADDR` 13 | ca_cert: 14 | description: 15 | - Path to a PEM-encoded CA cert file to use to verify the Vault server TLS certificate 16 | default: to environment variable `VAULT_CACERT` 17 | ca_path: 18 | description: 19 | - Path to a directory of PEM-encoded CA cert files to verify the Vault server TLS certificate. If 20 | ca_cert is specified, its value will take precedence 21 | default: to environment variable `VAULT_CAPATH` 22 | client_cert: 23 | description: 24 | - Path to a PEM-encoded client certificate for TLS authentication to the Vault server 25 | default: to environment variable `VAULT_CLIENT_CERT` 26 | client_key: 27 | description: 28 | - Path to an unencrypted PEM-encoded private key matching the client certificate 29 | default: to environment variable `VAULT_CLIENT_KEY` 30 | verify: 31 | description: 32 | - If set, do not verify presented TLS certificate before communicating with Vault server. Setting this 33 | variable is not recommended except during testing 34 | default: to environment variable `VAULT_SKIP_VERIFY` 35 | authtype: 36 | description: 37 | - authentication type 38 | default: token or environment variable `VAULT_AUTHTYPE` 39 | choices: ["token", "userpass", "github", "ldap", "approle"] 40 | login_mount_point: 41 | description: 42 | - authentication mount point 43 | default: value of authtype or environment varialbe `VAULT_LOGIN_MOUNT_POINT` 44 | token: 45 | description: 46 | - token for vault 47 | default: to environment variable `VAULT_TOKEN` 48 | username: 49 | description: 50 | - username to login to vault. 51 | default: to environment variable `VAULT_USER` 52 | password: 53 | description: 54 | - password to login to vault. 55 | default: to environment variable `VAULT_PASSWORD` 56 | aws_header: 57 | description: 58 | - X-Vault-AWS-IAM-Server-ID Header value to prevent replay attacks. 59 | default: to environment variable `VAULT_AWS_HEADER` 60 | namespace: 61 | description: 62 | - namespace for vault 63 | default: to environment variable VAULT_NAMESPACE 64 | timeout: 65 | description: 66 | - The timeout value (seconds) for requests sent to Vault. 67 | default: 30 68 | ''' 69 | -------------------------------------------------------------------------------- /ansible/plugins/lookup/hashivault.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Vault Lookup Plugin 5 | # 6 | # A simple example of using the vault plugin in a role: 7 | # --- 8 | # - debug: msg="{{lookup('vault', 'ldapadmin', 'password', mount_point='kv2')}}" 9 | # 10 | # The plugin must be run with VAULT_ADDR and VAULT_TOKEN set and 11 | # exported. 12 | # 13 | # The plugin can be run manually for testing: 14 | # python ansible/plugins/lookup/hashivault.py ldapadmin password 15 | # 16 | import os 17 | import sys 18 | 19 | from ansible.errors import AnsibleError 20 | from ansible.module_utils.basic import AnsibleFallbackNotFound 21 | from ansible.plugins.lookup import LookupBase 22 | 23 | from ansible.module_utils.hashivault import hashivault_argspec 24 | from ansible.module_utils.hashivault import hashivault_read 25 | 26 | 27 | class LookupModule(LookupBase): 28 | 29 | def _get_params(self, argspec, terms, kwargs): 30 | params = {} 31 | for arg in argspec: 32 | spec = argspec[arg] 33 | if arg in kwargs: 34 | params[arg] = kwargs[arg] 35 | elif 'default' in spec: 36 | params[arg] = spec.get('default') 37 | elif 'fallback' in spec: 38 | fall_func, fall_args = spec.get('fallback') 39 | try: 40 | params[arg] = fall_func(*tuple(fall_args)) 41 | except AnsibleFallbackNotFound: 42 | pass 43 | 44 | params['secret'] = terms[0] 45 | try: 46 | params['key'] = terms[1] 47 | except IndexError: 48 | params['key'] = None 49 | return params 50 | 51 | def run(self, terms, variables=None, **kwargs): 52 | # self._display.v('Running lookup') 53 | argspec = hashivault_argspec() 54 | argspec['version'] = dict(required=False, type='int', default=1) 55 | argspec['mount_point'] = dict(required=False, type='str', default='secret') 56 | argspec['secret'] = dict(required=True, type='str') 57 | argspec['key'] = dict(required=False, type='str') 58 | argspec['default'] = dict(required=False, default=None, type='str') 59 | params = self._get_params(argspec, terms, kwargs) 60 | # self._display.v('ARGSPEC: ' + str(argspec)) 61 | # self._display.v('KWARGS: ' + str(kwargs)) 62 | # self._display.v('PARAMS: ' + str(params)) 63 | result = hashivault_read(params=params) 64 | if 'value' not in result: 65 | path = terms[0] 66 | try: 67 | key = '/' + terms[1] 68 | except IndexError: 69 | key = '' 70 | raise AnsibleError('Error reading vault %s%s: %s\n%s' % (path, key, result.get('msg', 'msg not set'), 71 | result.get('stack_trace', ''))) 72 | return [result['value']] 73 | 74 | 75 | def main(argv=sys.argv[1:]): 76 | if len(argv) < 1: 77 | print("Usage: hashivault.py path [key]") 78 | return -1 79 | print(LookupModule().run(argv, {})[0]) 80 | return 0 81 | 82 | 83 | if __name__ == "__main__": 84 | sys.exit(main(sys.argv[1:])) 85 | -------------------------------------------------------------------------------- /example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | 3 | RUN apt-get update 4 | RUN apt-get install -y openssh-server python 5 | RUN mkdir /var/run/sshd 6 | RUN mkdir /root/.ssh 7 | RUN chmod 0700 /root/.ssh 8 | COPY .ssh/id_rsa.pub /root/.ssh/authorized_keys 9 | RUN chmod 0600 /root/.ssh/authorized_keys 10 | RUN echo 'root:root' |chpasswd 11 | RUN echo 'PermitRootLogin yes' >>/etc/ssh/sshd_config 12 | RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config 13 | RUN sed -ri 's/^#PubkeyAuthentication/PubkeyAuthentication/g' /etc/ssh/sshd_config 14 | RUN sed -ri 's/^#AuthorizedKeysFile/AuthorizedKeysFile/g' /etc/ssh/sshd_config 15 | 16 | EXPOSE 22 17 | 18 | CMD ["/usr/sbin/sshd", "-D"] 19 | -------------------------------------------------------------------------------- /example/README.rst: -------------------------------------------------------------------------------- 1 | Ansible Modules Hashivault 2 | ========================== 3 | 4 | Example sandbox for Ansible modules for Hashicorp Vault. These example 5 | directions assume you have Docker installed. You need to install the 6 | Ansible module first to use it:: 7 | 8 | pip install ansible-modules-hashivault 9 | 10 | Optionally Run Vault in Docker 11 | ------------------------------ 12 | 13 | You can use the automated functional test to create a Vault instance running 14 | in Docker. The `./start.sh` script in the `functional` directory will start 15 | an initialized vault instance. The script will create a `vaultenv.sh` which 16 | contains the environment variables needed to communicate with Vault.:: 17 | 18 | cd ../functional 19 | ./start.sh 20 | source ./vaultenv.sh 21 | 22 | Run a Ansible Ready Container 23 | ----------------------------- 24 | 25 | Use the `./run.sh` script to build and run a Ansible ready Docker container. 26 | The container will be called `sandbox`.:: 27 | 28 | ./run.sh 29 | 30 | You can see it running with `docker ps` for example:: 31 | 32 | $ docker ps 33 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS 34 | 3b214f80daf0 sandbox:latest "/usr/sbin/sshd -D" 6 minutes ago Up 6 minutes 127.0.0.1:3022->22/tcp 35 | 36 | 37 | There is a sample playbook here that writes a scret to Vault and writes it to 38 | the sandbox:: 39 | 40 | ansible-playbook test_remote_host.yml 41 | 42 | You can ssh into your sandbox and check your secret:: 43 | 44 | $ ssh -i .ssh/id_rsa -p 3022 root@127.0.0.1 45 | Last login: Wed Jan 3 16:55:09 2018 from 172.17.0.1 46 | root@sandbox:~# cat /giant.txt 47 | I smell the blood 48 | root@sandbox:~# 49 | 50 | If you run the sandbox more than once, you'll need to clear the entry in the 51 | `~/.ssh/known_hosts` file 52 | -------------------------------------------------------------------------------- /example/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | retry_files_enabled = False 3 | inventory = ./hosts 4 | private_key_file = .ssh/id_rsa 5 | remote_port = 3022 6 | remote_user = root 7 | -------------------------------------------------------------------------------- /example/hosts: -------------------------------------------------------------------------------- 1 | sandbox ansible_port=3022 ansible_host=127.0.0.1 2 | -------------------------------------------------------------------------------- /example/run.sh: -------------------------------------------------------------------------------- 1 | docker stop sandbox 2>/dev/null 2 | docker rm -f sandbox 2>/dev/null 3 | docker rmi -f sandbox 2>/dev/null 4 | mkdir -p .ssh 5 | chmod 700 .ssh 6 | ssh-keygen -t rsa -f .ssh/id_rsa -N '' -q $TMP_CONFIG 14 | storage "file" { 15 | path = "/vault/file" 16 | } 17 | 18 | "listener" "tcp" { 19 | "address" = "0.0.0.0:${PORT}" 20 | 21 | "tls_disable" = 1 22 | } 23 | 24 | "default_lease_ttl" = "168h" 25 | 26 | "max_lease_ttl" = "720h" 27 | 28 | "disable_mlock" = true 29 | EOF 30 | chmod a+r $TMP_CONFIG 31 | 32 | # Current is not tagged latest and vault won't push images 33 | # after 1.14, but this image is okay today 34 | # # Current is not tagged latest and vault won't push images 35 | # after 1.14, but this image is okay today 36 | TAG=latest 37 | TAG=1.18 38 | docker stop $DOCKER_NAME 2>/dev/null || true 39 | docker rm -f $DOCKER_NAME 2>/dev/null || true 40 | docker run --name $DOCKER_NAME -h $DOCKER_NAME -d \ 41 | --cap-add IPC_LOCK \ 42 | -p 127.0.0.1:${PORT}:${PORT} \ 43 | -v $TMP_CONFIG:/etc/vault/config.hcl:ro \ 44 | hashicorp/vault:${TAG} server -config /etc/vault/config.hcl 45 | 46 | # 47 | # Wait for vault to come up 48 | # 49 | CNT=0 50 | while ! curl -sI "$VAULT_ADDR/v1/sys/health" > /dev/null; do 51 | sleep 0.1 52 | CNT=$(expr $CNT + 1) 53 | if [ $CNT -gt 20 ] 54 | then 55 | docker logs $DOCKER_NAME 56 | exit 1 57 | fi 58 | done 59 | 60 | # 61 | # Initialize the vault 62 | # 63 | ansible-playbook -v test_init.yml 64 | source ./vaultenv.sh 65 | ansible-playbook -v test_enable_kv.yml 66 | exit $? 67 | -------------------------------------------------------------------------------- /functional/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | # 3 | # Stop the test vault container 4 | # 5 | export NAME=${NAME:-test_vault} 6 | docker stop $NAME 2>/dev/null || true 7 | rm -f ./vaultenv.sh approlenv.sh 8 | -------------------------------------------------------------------------------- /functional/templates/approlenv.sh.j2: -------------------------------------------------------------------------------- 1 | export VAULT_ADDR='{{lookup('env','VAULT_ADDR')}}' 2 | export VAULT_AUTHTYPE=approle 3 | export VAULT_LOGIN_MOUNT_POINT='{{ approle_login_mount_point }}' 4 | export VAULT_ROLE_ID='{{ approle_role_id }}' 5 | export VAULT_SECRET_ID='{{ approle_secret_id }}' 6 | unset VAULT_TOKEN 7 | unset VAULT_KEYS 8 | unset VAULT_USER 9 | unset VAULT_PASSWORD 10 | -------------------------------------------------------------------------------- /functional/templates/policy_rules.hcl: -------------------------------------------------------------------------------- 1 | path "secret/bob/*" { 2 | capabilities = ["create", "read", "update", "delete", "list"] 3 | } 4 | path "secret/bob" { 5 | capabilities = ["list"] 6 | } 7 | -------------------------------------------------------------------------------- /functional/templates/userpassenv.sh.j2: -------------------------------------------------------------------------------- 1 | export VAULT_ADDR='{{lookup('env','VAULT_ADDR')}}' 2 | export VAULT_AUTHTYPE=userpass 3 | export VAULT_USER='{{ username }}' 4 | export VAULT_PASSWORD='{{ userpass }}' 5 | unset VAULT_LOGIN_MOUNT_POINT 6 | unset VAULT_ROLE_ID 7 | unset VAULT_SECRET_ID 8 | unset VAULT_TOKEN 9 | unset VAULT_KEYS 10 | -------------------------------------------------------------------------------- /functional/templates/vaultenv.sh.j2: -------------------------------------------------------------------------------- 1 | export VAULT_ADDR='{{lookup('env','VAULT_ADDR')}}' 2 | export VAULT_TOKEN='{{vault_init['root_token']}}' 3 | export VAULT_KEYS='{{vault_init['keys'] | join(' ')}}' 4 | unset VAULT_AUTHTYPE 5 | unset VAULT_LOGIN_MOUNT_POINT 6 | unset VAULT_USER 7 | unset VAULT_PASSWORD 8 | unset VAULT_ROLE_ID 9 | unset VAULT_SECRET_ID 10 | -------------------------------------------------------------------------------- /functional/test_approle_check_mode.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: create role check_mode exists 6 | hashivault_approle_role: 7 | name: testrole 8 | token_policies: 9 | - approle_test_policy 10 | state: present 11 | check_mode: true 12 | register: 'vault_role_create' 13 | - assert: { that: "vault_role_create is not changed" } 14 | - assert: { that: "vault_role_create.rc == 0" } 15 | 16 | - name: create role check_mode does not exist 17 | hashivault_approle_role: 18 | name: testrole_two 19 | token_policies: 20 | - approle_test_policy 21 | state: present 22 | check_mode: true 23 | register: 'vault_role_create' 24 | - assert: { that: "vault_role_create is changed" } 25 | - assert: { that: "vault_role_create.rc == 0" } 26 | 27 | - name: delete role check_mode exists 28 | hashivault_approle_role: 29 | name: testrole 30 | state: absent 31 | check_mode: true 32 | register: 'vault_role_create' 33 | - assert: { that: "vault_role_create is changed" } 34 | - assert: { that: "vault_role_create.rc == 0" } 35 | 36 | - name: delete role check_mode does not exist 37 | hashivault_approle_role: 38 | name: testrole_two 39 | state: absent 40 | check_mode: true 41 | register: 'vault_role_create' 42 | - assert: { that: "vault_role_create is not changed" } 43 | - assert: { that: "vault_role_create.rc == 0" } 44 | 45 | - name: create secret for check_mode test 46 | hashivault_approle_role_secret: 47 | name: testrole 48 | state: present 49 | register: 'vault_role_secret_create' 50 | - set_fact: 51 | approle_secret_id: "{{vault_role_secret_create.data.secret_id}}" 52 | - set_fact: 53 | approle_secret_id_accessor: "{{vault_role_secret_create.data.secret_id_accessor}}" 54 | 55 | - name: delete secret exists check_mode 56 | hashivault_approle_role_secret: 57 | name: testrole 58 | secret: "{{approle_secret_id}}" 59 | state: absent 60 | check_mode: true 61 | register: 'vault_role_secret_delete' 62 | - assert: { that: "vault_role_secret_delete is changed" } 63 | - assert: { that: "vault_role_secret_delete.rc == 0" } 64 | 65 | - name: delete secret does not exist check_mode 66 | hashivault_approle_role_secret: 67 | name: testrole_two 68 | secret: "{{approle_secret_id}}" 69 | state: absent 70 | check_mode: true 71 | register: 'vault_role_secret_delete' 72 | - assert: { that: "vault_role_secret_delete is not changed" } 73 | - assert: { that: "vault_role_secret_delete.rc == 0" } 74 | -------------------------------------------------------------------------------- /functional/test_audit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - hashivault_audit: 6 | device_type: file 7 | state: absent 8 | register: audit_module 9 | 10 | - hashivault_audit: 11 | device_type: file 12 | path: pathy 13 | state: absent 14 | register: audit_module 15 | 16 | - hashivault_audit_list: 17 | register: vault_audit_list 18 | 19 | - name: Create audit 20 | hashivault_audit: 21 | device_type: file 22 | options: 23 | path: "/tmp/vault.log" 24 | register: audit_module 25 | - assert: { that: "audit_module is changed" } 26 | - assert: { that: "audit_module.rc == 0" } 27 | 28 | - name: Create audit idempotent (Vault does not support update at the moment anyway) 29 | hashivault_audit: 30 | device_type: file 31 | options: 32 | path: "/tmp/vault.log" 33 | register: audit_module 34 | - assert: { that: "audit_module is not changed" } 35 | - assert: { that: "audit_module.rc == 0" } 36 | 37 | - name: Delete audit only one audit allowed 38 | hashivault_audit: 39 | device_type: file 40 | state: absent 41 | register: audit_module 42 | - assert: { that: "audit_module is changed" } 43 | - assert: { that: "audit_module.rc == 0" } 44 | 45 | 46 | - name: Create audit path 47 | hashivault_audit: 48 | device_type: file 49 | path: pathy 50 | options: 51 | path: "/tmp/path_vault.log" 52 | register: audit_module 53 | - assert: { that: "audit_module is changed" } 54 | - assert: { that: "audit_module.rc == 0" } 55 | 56 | - name: Create audit path again 57 | hashivault_audit: 58 | device_type: file 59 | path: pathy 60 | options: 61 | path: "/tmp/path_vault.log" 62 | register: audit_module 63 | - assert: { that: "audit_module is not changed" } 64 | - assert: { that: "audit_module.rc == 0" } 65 | 66 | - name: Delete audit path 67 | hashivault_audit: 68 | device_type: file 69 | path: pathy 70 | state: absent 71 | register: audit_module 72 | - assert: { that: "audit_module is changed" } 73 | - assert: { that: "audit_module.rc == 0" } 74 | 75 | - name: Delete audit idempotent 76 | hashivault_audit: 77 | device_type: file 78 | state: absent 79 | register: audit_module 80 | - assert: { that: "audit_module is not changed" } 81 | - assert: { that: "audit_module.rc == 0" } 82 | -------------------------------------------------------------------------------- /functional/test_auth.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - hashivault_auth_list: 6 | register: auth_list 7 | - assert: { that: "'token/' in auth_list.backends" } 8 | - assert: { that: "'userpass/' not in auth_list.backends" } 9 | - name: Delete any lingering userpass 10 | hashivault_auth_method: 11 | method_type: "userpass" 12 | state: disable 13 | failed_when: False 14 | - name: Enable userpass first time for this test 15 | hashivault_auth_method: 16 | method_type: "userpass" 17 | description: "my userpass" 18 | register: 'vault_auth' 19 | - assert: { that: "vault_auth is changed" } 20 | - assert: { that: "vault_auth.created == True" } 21 | - assert: { that: "vault_auth.failed == False" } 22 | - assert: { that: "vault_auth.rc == 0" } 23 | - hashivault_auth_list: 24 | check_mode: true 25 | register: auth_list 26 | - assert: { that: "'userpass/' in auth_list.backends" } 27 | - name: Enable userpass when it is already enabled 28 | hashivault_auth_method: 29 | method_type: "userpass" 30 | description: "my userpass" 31 | register: 'vault_auth' 32 | - assert: { that: "vault_auth is not changed" } 33 | - assert: { that: "vault_auth.created == False" } 34 | - assert: { that: "vault_auth.failed == False" } 35 | - assert: { that: "vault_auth.rc == 0" } 36 | - name: Enable userpass auth for the third time with change 37 | hashivault_auth_method: 38 | method_type: "userpass" 39 | description: "our userpass" 40 | register: 'vault_auth' 41 | - assert: { that: "vault_auth is changed" } 42 | - assert: { that: "vault_auth.created == False" } 43 | - assert: { that: "vault_auth.rc == 0" } 44 | - name: Enable userpass at a different mount point 45 | hashivault_auth_method: 46 | method_type: "userpass" 47 | mount_point: "another-userpass" 48 | register: 'vault_auth_mount_point' 49 | - assert: { that: "vault_auth_mount_point is changed" } 50 | - assert: { that: "vault_auth_mount_point.rc == 0" } 51 | -------------------------------------------------------------------------------- /functional/test_auth_method.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | tasks: 6 | - hashivault_auth_method: 7 | method_type: oidc 8 | state: disabled 9 | - hashivault_auth_method: 10 | method_type: azure 11 | state: disabled 12 | 13 | - name: disable auth idempotent 14 | hashivault_auth_method: 15 | method_type: azure 16 | state: disabled 17 | register: disable_idem 18 | - assert: { that: "disable_idem is not changed" } 19 | 20 | - name: enable azure secret engine 21 | hashivault_auth_method: 22 | method_type: azure 23 | register: enable_chg 24 | - assert: { that: "enable_chg is changed" } 25 | 26 | - name: disable azure 27 | hashivault_auth_method: 28 | method_type: azure 29 | state: disabled 30 | register: disable_chg 31 | - assert: { that: "disable_chg is changed" } 32 | 33 | - name: "Enable OIDC auth method" 34 | hashivault_auth_method: 35 | method_type: oidc 36 | state: enabled 37 | config: 38 | default_lease_ttl: 0 39 | max_lease_ttl: 0 40 | register: oidc_idempotent 41 | - assert: { that: "oidc_idempotent.rc == 0" } 42 | - assert: { that: "oidc_idempotent is changed" } 43 | 44 | - name: "Enable OIDC auth method idempotent" 45 | hashivault_auth_method: 46 | method_type: oidc 47 | state: enabled 48 | config: 49 | default_lease_ttl: 0 50 | max_lease_ttl: 0 51 | register: oidc_idempotent 52 | - assert: { that: "oidc_idempotent.rc == 0" } 53 | - assert: { that: "oidc_idempotent is not changed" } 54 | 55 | - name: "Enable OIDC auth method update" 56 | hashivault_auth_method: 57 | method_type: oidc 58 | state: enabled 59 | config: 60 | default_lease_ttl: 0 61 | max_lease_ttl: 0 62 | description: 'my oidc' 63 | register: oidc_idempotent 64 | - assert: { that: "oidc_idempotent.rc == 0" } 65 | - assert: { that: "oidc_idempotent is changed" } 66 | 67 | - name: "Enable OIDC auth method update description idempotent" 68 | hashivault_auth_method: 69 | method_type: oidc 70 | state: enabled 71 | config: 72 | default_lease_ttl: 0 73 | max_lease_ttl: 0 74 | description: 'my oidc' 75 | register: oidc_idempotent 76 | - assert: { that: "oidc_idempotent.rc == 0" } 77 | - assert: { that: "oidc_idempotent is not changed" } 78 | 79 | - name: "Enable OIDC auth method update" 80 | hashivault_auth_method: 81 | method_type: oidc 82 | state: enabled 83 | config: 84 | default_lease_ttl: 2764799 85 | register: oidc_idempotent 86 | - assert: { that: "oidc_idempotent.rc == 0" } 87 | - assert: { that: "oidc_idempotent is changed" } 88 | 89 | - name: "Enable OIDC auth method update idempotent" 90 | hashivault_auth_method: 91 | method_type: oidc 92 | state: enabled 93 | config: 94 | default_lease_ttl: 2764799 95 | register: oidc_idempotent 96 | - assert: { that: "oidc_idempotent.rc == 0" } 97 | - assert: { that: "oidc_idempotent is not changed" } 98 | -------------------------------------------------------------------------------- /functional/test_aws_auth_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | tasks: 5 | - hashivault_auth_list: 6 | register: auth_list 7 | 8 | - hashivault_auth_method: 9 | method_type: aws 10 | when: "'strokes/' not in auth_list.backends" 11 | 12 | - hashivault_aws_auth_config: 13 | mount_point: aws 14 | access_key: bob 15 | secret_key: topsecret 16 | register: aws_result 17 | - assert: { that: "aws_result is changed" } 18 | - assert: { that: "aws_result.rc == 0" } 19 | 20 | - hashivault_aws_auth_config: 21 | mount_point: aws 22 | state: absent 23 | register: aws_result 24 | - assert: { that: "aws_result is changed" } 25 | - assert: { that: "aws_result.rc == 0" } 26 | -------------------------------------------------------------------------------- /functional/test_aws_auth_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | tasks: 5 | - hashivault_auth_list: 6 | register: auth_list 7 | 8 | - hashivault_auth_method: 9 | method_type: aws 10 | when: "'aws/' not in auth_list.backends" 11 | 12 | - hashivault_aws_auth_role: 13 | name: ec2-role 14 | auth_type: iam 15 | inferred_entity_type: ec2_instance 16 | inferred_aws_region: eu-west-1 17 | bound_iam_role_arn: arn:aws:iam::12345678:role/ec2-role 18 | register: aws_result 19 | - assert: { that: "aws_result is changed" } 20 | - assert: { that: "aws_result.rc == 0" } 21 | 22 | - hashivault_aws_auth_role: 23 | name: ec2-role 24 | state: absent 25 | register: aws_result 26 | - assert: { that: "aws_result is changed" } 27 | - assert: { that: "aws_result.rc == 0" } 28 | -------------------------------------------------------------------------------- /functional/test_azure_auth_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | client_id: values 7 | client_secret: dont 8 | tenant_id: matter 9 | tasks: 10 | - hashivault_auth_method: 11 | method_type: azure 12 | state: disabled 13 | failed_when: false 14 | 15 | - name: make sure test fails when no mount exists 16 | hashivault_azure_auth_config: 17 | client_id: "{{ client_id }}" 18 | client_secret: "{{ client_secret }}" 19 | tenant_id: "{{ tenant_id }}" 20 | register: fail_config 21 | failed_when: false 22 | 23 | - assert: { that: "fail_config is not changed" } 24 | 25 | - name: enable azure auth method 26 | hashivault_auth_method: 27 | method_type: azure 28 | 29 | - name: successfully configure method 30 | hashivault_azure_auth_config: 31 | client_id: "{{ client_id }}" 32 | client_secret: "{{ client_secret }}" 33 | tenant_id: "{{ tenant_id }}" 34 | register: success_config 35 | 36 | - assert: { that: "success_config is changed" } 37 | 38 | - name: attempt 2nd config with same values 39 | hashivault_azure_auth_config: 40 | client_id: "{{ client_id }}" 41 | client_secret: "{{ client_secret }}" 42 | tenant_id: "{{ tenant_id }}" 43 | register: idem_config 44 | 45 | - assert: { that: "idem_config is not changed" } 46 | 47 | - name: attempt 3rd config with different values 48 | hashivault_azure_auth_config: 49 | client_id: flergh 50 | client_secret: mlergh 51 | tenant_id: splurgh 52 | register: overwrite_config 53 | 54 | - assert: { that: "overwrite_config is changed" } 55 | -------------------------------------------------------------------------------- /functional/test_azure_auth_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | client_id: values 7 | client_secret: dont 8 | tenant_id: matter 9 | tasks: 10 | - hashivault_auth_method: 11 | method_type: azure 12 | state: disabled 13 | failed_when: false 14 | 15 | - name: enable azure secret engine 16 | hashivault_auth_method: 17 | method_type: azure 18 | 19 | - name: successfully configure mount 20 | hashivault_azure_auth_config: 21 | client_id: "{{ client_id }}" 22 | client_secret: "{{ client_secret }}" 23 | tenant_id: "{{ tenant_id }}" 24 | 25 | - name: create 1st role 26 | hashivault_azure_auth_role: 27 | name: "test" 28 | policies: ["test"] 29 | bound_subscription_ids: ["6a1d5988-5917-4221-b224-904cd7e24a25"] 30 | num_uses: 3 31 | register: success_config 32 | 33 | - assert: { that: "success_config is changed" } 34 | 35 | - name: idempotently create role 36 | hashivault_azure_auth_role: 37 | name: "test" 38 | policies: ["test"] 39 | bound_subscription_ids: ["6a1d5988-5917-4221-b224-904cd7e24a25"] 40 | num_uses: 3 41 | register: idem_config 42 | 43 | - assert: { that: "idem_config is not changed" } 44 | 45 | - name: delete role 46 | hashivault_azure_auth_role: 47 | name: test 48 | state: absent 49 | register: del_config 50 | 51 | - assert: { that: "del_config is changed" } 52 | -------------------------------------------------------------------------------- /functional/test_azure_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | subscription_id: test 7 | client_id: values 8 | client_secret: dont 9 | tenant_id: matter 10 | tasks: 11 | - hashivault_secret_engine: 12 | name: azure 13 | state: disabled 14 | failed_when: false 15 | 16 | - name: make sure test fails when no mount exists 17 | hashivault_azure_secret_engine_config: 18 | subscription_id: "{{ subscription_id }}" 19 | client_id: "{{ client_id }}" 20 | client_secret: "{{ client_secret }}" 21 | tenant_id: "{{ tenant_id }}" 22 | register: fail_config 23 | failed_when: false 24 | 25 | - assert: { that: "fail_config is not changed" } 26 | 27 | - hashivault_secret_engine: 28 | name: azure 29 | state: enabled 30 | backend: azure 31 | 32 | - name: successfully enable mount 33 | hashivault_azure_secret_engine_config: 34 | subscription_id: "{{ subscription_id }}" 35 | client_id: "{{ client_id }}" 36 | client_secret: "{{ client_secret }}" 37 | tenant_id: "{{ tenant_id }}" 38 | register: success_config 39 | 40 | - assert: { that: "success_config is changed" } 41 | 42 | - name: attempt 2nd config with same values 43 | hashivault_azure_secret_engine_config: 44 | subscription_id: "{{ subscription_id }}" 45 | client_id: "{{ client_id }}" 46 | client_secret: "{{ client_secret }}" 47 | tenant_id: "{{ tenant_id }}" 48 | register: idem_config 49 | 50 | - assert: { that: "idem_config is not changed" } 51 | 52 | - name: attempt 3rd config with different values 53 | hashivault_azure_secret_engine_config: 54 | subscription_id: blergh 55 | client_id: flergh 56 | client_secret: mlergh 57 | tenant_id: splurgh 58 | register: overwrite_config 59 | 60 | - assert: { that: "overwrite_config is changed" } 61 | -------------------------------------------------------------------------------- /functional/test_azure_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | subscription_id: "xyz" 7 | client_id: "" 8 | client_secret: "" 9 | tenant_id: "" 10 | azure_role1: [{ "role_name": "Contributor","scope": "/subscriptions/xyz"}] 11 | azure_role2: [{ "role_name": "Contributor","scope": "/subscriptions/xyz"}, { "role_name": "Reader","scope": "/subscriptions/xyz"}] 12 | tasks: 13 | - hashivault_secret_engine: 14 | name: azure 15 | state: disable 16 | failed_when: false 17 | 18 | - name: fail before mount is configured 19 | hashivault_azure_secret_engine_role: 20 | name: test 21 | azure_role: "{{ azure_role1 }}" 22 | failed_when: false 23 | register: fail_config 24 | 25 | - assert: { that: "fail_config is not changed" } # fail 26 | 27 | - name: enable azure secret engine 28 | hashivault_secret_engine: 29 | name: azure 30 | backend: azure 31 | 32 | - name: configure azure mount 33 | hashivault_azure_secret_engine_config: 34 | subscription_id: "{{ subscription_id }}" 35 | client_id: "{{ client_id }}" 36 | client_secret: "{{ client_secret }}" 37 | tenant_id: "{{ tenant_id }}" 38 | 39 | - name: write 1 azure_role 40 | hashivault_azure_secret_engine_role: 41 | name: test 42 | azure_role: "{{ azure_role1 }}" 43 | register: success_write 44 | 45 | - assert: { that: "success_write is changed" } # changed 46 | 47 | - name: idem same azure_role 48 | hashivault_azure_secret_engine_role: 49 | name: test 50 | azure_role: "{{ azure_role1 }}" 51 | register: idem_write 52 | 53 | - assert: { that: "idem_write is not changed" } # not changed 54 | 55 | - name: overwrite existing 56 | hashivault_azure_secret_engine_role: 57 | name: test 58 | azure_role: "{{ azure_role2 }}" 59 | register: overwrite 60 | 61 | - assert: { that: "overwrite is changed" } # changed 62 | 63 | # since we're doing dict compare, ensure that a dict with less obj 64 | # correctly is overwritten 65 | - name: ensure smaller azure_role successfully overwrites 66 | hashivault_azure_secret_engine_role: 67 | name: test 68 | azure_role: "{{ azure_role1 }}" 69 | register: overwrite_smaller 70 | 71 | - assert: { that: "overwrite_smaller is changed" } # changed 72 | -------------------------------------------------------------------------------- /functional/test_check.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | noo_value: 'noe' 6 | nie_value: 'num' 7 | dict_value: 8 | noo: 'bar' 9 | baz: 'stuff' 10 | tasks: 11 | - name: Write basic secret and verify it is changed 12 | hashivault_write: 13 | secret: 'check_one' 14 | data: 15 | noo: '{{noo_value}}' 16 | nie: '{{nie_value}}' 17 | register: 'vault_write' 18 | - assert: { that: vault_write.changed == True } 19 | - assert: { that: vault_write.rc == 0 } 20 | 21 | - name: Write single secret in folder 22 | hashivault_write: 23 | secret: check/two 24 | data: 25 | height: tall 26 | register: vault_write 27 | - assert: { that: vault_write.changed == True } 28 | - assert: { that: vault_write.rc == 0 } 29 | 30 | - name: Write secret dictionary 31 | hashivault_write: 32 | secret: 'check_three' 33 | data: "{{ dict_value }}" 34 | register: vault_write 35 | - assert: { that: vault_write.changed == True } 36 | - assert: { that: vault_write.rc == 0 } 37 | -------------------------------------------------------------------------------- /functional/test_consul_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | consul_address: consul.local:8500 6 | scheme: https 7 | consul_token: myAwesomeConsulManagementToken 8 | tasks: 9 | - name: start with engine disabled 10 | hashivault_secret_engine: 11 | name: consul 12 | backend: consul 13 | state: absent 14 | 15 | - name: make sure test fails when no mount exists 16 | hashivault_consul_secret_engine_config: 17 | consul_address: "{{ consul_address }}" 18 | scheme: "{{ scheme }}" 19 | consul_token: "{{ consul_token }}" 20 | register: fail_config 21 | failed_when: false 22 | - assert: { that: "fail_config is not changed" } 23 | - assert: { that: "fail_config.rc == 1" } 24 | 25 | - name: enable database secret engine 26 | hashivault_secret_engine: 27 | name: consul 28 | backend: consul 29 | 30 | - name: successfully configure 31 | hashivault_consul_secret_engine_config: 32 | consul_address: "{{ consul_address }}" 33 | scheme: "{{ scheme }}" 34 | consul_token: "{{ consul_token }}" 35 | register: success_config 36 | - assert: { that: "success_config is changed" } 37 | - assert: { that: "success_config.rc == 0" } 38 | -------------------------------------------------------------------------------- /functional/test_consul_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | role_name: test 6 | policy: a2V5ICIvZm9vL2JhciIgeyBwb2xpY3kgPSAicmVhZCIgfQ== 7 | tasks: 8 | - name: enable consul secret engine 9 | hashivault_secret_engine: 10 | name: consul 11 | backend: consul 12 | 13 | - name: configure secret engine 14 | hashivault_consul_secret_engine_config: 15 | consul_address: consul.local:8500 16 | scheme: https 17 | consul_token: myAwesomeConsulManagementToken 18 | 19 | - name: make sure role is gone 20 | hashivault_consul_secret_engine_role: 21 | name: "{{ role_name }}" 22 | state: absent 23 | 24 | - name: fail role create when no policy 25 | hashivault_consul_secret_engine_role: 26 | name: "{{ role_name }}" 27 | register: fail_write 28 | failed_when: false 29 | - assert: { that: "fail_write.rc == 1" } 30 | - assert: { that: "fail_write is not changed" } 31 | 32 | - name: successfully write a role 33 | hashivault_consul_secret_engine_role: 34 | name: "{{ role_name }}" 35 | policy: "{{ policy }}" 36 | register: success_write 37 | - assert: { that: "success_write.rc == 0" } 38 | - assert: { that: "success_write is changed" } 39 | 40 | - name: idempotent write a role 41 | hashivault_consul_secret_engine_role: 42 | name: "{{ role_name }}" 43 | policy: "{{ policy }}" 44 | register: idem_write 45 | - assert: { that: "idem_write.rc == 0" } 46 | - assert: { that: "idem_write is not changed" } 47 | 48 | - name: successfully update a role 49 | hashivault_consul_secret_engine_role: 50 | name: "{{ role_name }}" 51 | policy: "{{ policy }}" 52 | max_ttl: 12345 53 | register: success_write 54 | - assert: { that: "success_write.rc == 0" } 55 | - assert: { that: "success_write is changed" } 56 | 57 | - name: delete role 58 | hashivault_consul_secret_engine_role: 59 | name: "{{ role_name }}" 60 | state: absent 61 | register: success_del 62 | - assert: { that: "success_del.rc == 0" } 63 | - assert: { that: "success_del is changed" } 64 | 65 | - name: idempotent delete role 66 | hashivault_consul_secret_engine_role: 67 | name: "{{ role_name }}" 68 | state: absent 69 | register: success_del 70 | - assert: { that: "success_del.rc == 0" } 71 | - assert: { that: "success_del is not changed" } 72 | -------------------------------------------------------------------------------- /functional/test_db_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | plugin_name: blergh 7 | allowed_roles: ["flergh"] 8 | allowed_roles2: ["splurgh", "doesnt-exist"] 9 | connection_details: 10 | username: "user@dbnamer" 11 | password: "P@ssw0rd" 12 | connection_url: "postgresql://{{'{{username}}'}}:{{'{{password}}'}}@cool-modern-db-name" 13 | tasks: 14 | - name: start with engine disabled 15 | hashivault_secret_engine: 16 | name: database 17 | state: disable 18 | 19 | - name: make sure test fails when no mount exists 20 | hashivault_db_secret_engine_config: 21 | name: test 22 | plugin_name: "{{ plugin_name }}" 23 | allowed_roles: "{{ allowed_roles }}" 24 | connection_details: 25 | username: "{{ db_username }}" 26 | password: "{{ db_password }}" 27 | connection_url: "{{ connection_url }}" 28 | register: fail_config 29 | failed_when: false 30 | 31 | - assert: { that: "fail_config is not changed" } 32 | 33 | - name: enable database secret engine 34 | hashivault_secret_engine: 35 | name: database 36 | backend: database 37 | 38 | - name: successfully configure 39 | hashivault_db_secret_engine_config: 40 | name: test 41 | plugin_name: "{{ plugin_name }}" 42 | allowed_roles: "{{ allowed_roles }}" 43 | connection_details: 44 | username: "{{ db_username }}" 45 | password: "{{ db_password }}" 46 | connection_url: "{{ connection_url }}" 47 | register: success_config 48 | 49 | - assert: { that: "success_config is changed" } 50 | 51 | - name: skip 2nd config attempt with same values 52 | hashivault_db_secret_engine_config: 53 | name: test 54 | plugin_name: "{{ plugin_name }}" 55 | allowed_roles: "{{ allowed_roles }}" 56 | connection_details: 57 | username: "{{ db_username }}" 58 | password: "{{ db_password }}" 59 | connection_url: "{{ connection_url }}" 60 | register: idem_config 61 | 62 | - assert: { that: "idem_config is not changed" } 63 | 64 | - name: attempt 3rd config with different values 65 | hashivault_db_secret_engine_config: 66 | name: test 67 | plugin_name: "{{ plugin_name }}" 68 | allowed_roles: "{{ allowed_roles2 }}" 69 | connection_details: 70 | username: "{{ db_username }}" 71 | password: "{{ db_password }}" 72 | connection_url: "{{ connection_url }}" 73 | register: overwrite_config 74 | 75 | - assert: { that: "overwrite_config is changed" } 76 | -------------------------------------------------------------------------------- /functional/test_db_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | plugin_name: blergh 7 | allowed_roles: ["flergh"] 8 | allowed_roles2: ["splurgh", "doesnt-exist"] 9 | username: "user@dbnamer" 10 | password: "P@ssw0rd" 11 | connection_url: "postgresql://{{'{{username}}'}}:{{'{{password}}'}}@cool-modern-db-name" 12 | tasks: 13 | - name: start with engine disabled 14 | hashivault_secret_engine: 15 | name: database 16 | state: disable 17 | 18 | - name: make sure test fails when no mount exists 19 | hashivault_db_secret_engine_config: 20 | name: test 21 | plugin_name: "{{ plugin_name }}" 22 | allowed_roles: "{{ allowed_roles }}" 23 | username: "{{ username }}" 24 | password: "{{ password }}" 25 | connection_url: "{{ connection_url }}" 26 | register: fail_config 27 | failed_when: false 28 | 29 | - assert: { that: "fail_config is not changed" } 30 | 31 | - name: enable database secret engine 32 | hashivault_secret_engine: 33 | name: database 34 | backend: database 35 | 36 | - name: successfully configure 37 | hashivault_db_secret_engine_config: 38 | name: test 39 | plugin_name: "{{ plugin_name }}" 40 | allowed_roles: "{{ allowed_roles }}" 41 | username: "{{ username }}" 42 | password: "{{ password }}" 43 | connection_url: "{{ connection_url }}" 44 | register: success_config 45 | 46 | - assert: { that: "success_config is changed" } 47 | 48 | - name: successfully write a role 49 | hashivault_db_secret_engine_role: 50 | name: tester 51 | db_name: test 52 | creation_statements: [] 53 | register: success_write 54 | 55 | - assert: { that: "success_write is changed" } 56 | 57 | - name: skip write a role 58 | hashivault_db_secret_engine_role: 59 | name: tester 60 | db_name: test 61 | creation_statements: [] 62 | register: idem_write 63 | 64 | - assert: { that: "idem_write is not changed" } 65 | 66 | - name: delete role 67 | hashivault_db_secret_engine_role: 68 | name: tester 69 | db_name: test 70 | state: absent 71 | register: success_del 72 | 73 | - assert: { that: "success_del is changed" } 74 | 75 | - name: skip delete role 76 | hashivault_db_secret_engine_role: 77 | name: tester 78 | db_name: test 79 | state: absent 80 | register: success_del 81 | 82 | - assert: { that: "success_del is not changed" } 83 | -------------------------------------------------------------------------------- /functional/test_delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - hashivault_write: 6 | secret: test_delete 7 | data: 8 | uno: 'beck' 9 | duo: 'clash' 10 | 11 | - name: Make sure we can read it 12 | hashivault_read: 13 | secret: test_delete 14 | 15 | - name: Delete secret 16 | hashivault_delete: 17 | secret: test_delete 18 | register: vault_delete 19 | - assert: { that: "vault_delete is changed" } 20 | - assert: { that: "vault_delete.rc == 0" } 21 | - assert: { that: "vault_delete.msg == 'Secret secret/test_delete deleted'" } 22 | 23 | - name: Make sure secret value is gone 24 | hashivault_read: 25 | secret: test_delete 26 | register: vault_read 27 | failed_when: False 28 | - assert: { that: "vault_read is not changed" } 29 | - assert: { that: "vault_read.msg == 'Secret secret/test_delete is not in vault'" } 30 | -------------------------------------------------------------------------------- /functional/test_delete_permanent.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - hashivault_write: 6 | secret: test_delete_permanent 7 | data: 8 | uno: 'beck' 9 | duo: 'clash' 10 | 11 | - name: Make sure we can read it 12 | hashivault_read: 13 | secret: test_delete_permanent 14 | 15 | - name: Delete secret 16 | hashivault_delete: 17 | secret: test_delete_permanent 18 | permanent: true 19 | register: vault_delete 20 | - assert: { that: "vault_delete is changed" } 21 | - assert: { that: "vault_delete.rc == 0" } 22 | - assert: { that: "vault_delete.msg == 'Secret secret/test_delete_permanent deleted'" } 23 | 24 | - name: Make sure secret value is gone 25 | hashivault_read: 26 | secret: test_delete_permanent 27 | register: vault_read 28 | failed_when: False 29 | - assert: { that: "vault_read is not changed" } 30 | - assert: { that: "vault_read.msg == 'Secret secret/test_delete_permanent is not in vault'" } 31 | -------------------------------------------------------------------------------- /functional/test_enable_kv.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: Make surea backend is enabled 6 | hashivault_secret_list: 7 | register: vault_secret_list 8 | - block: 9 | - name: Enable secret backend 10 | hashivault_secret_engine: 11 | name: "secret" 12 | backend: "kv" 13 | when: "'secret/' not in vault_secret_list.backends" 14 | -------------------------------------------------------------------------------- /functional/test_environment_lookup.yml: -------------------------------------------------------------------------------- 1 | # 2 | # This test depends on successful test_write run 3 | # 4 | --- 5 | - hosts: localhost 6 | gather_facts: no 7 | environment: 8 | VAULT_ADDR: 'http://127.0.0.1:8201' 9 | BOGUS: 'asdf' 10 | vars: 11 | namespace: '' 12 | name_root: '{{namespace}}basic' 13 | name_folder: '{{namespace}}stalks/bean' 14 | name_dict: '{{namespace}}_dict' 15 | name_array: '{{namespace}}_array' 16 | vars_foo: "{{lookup('hashivault', '{{name_root}}', 'foo')}}" 17 | dict_value: 18 | foo: 'bar' 19 | baz: 'stuff' 20 | array_value: 21 | - 'one' 22 | - 'two' 23 | - 'three' 24 | tasks: 25 | - set_fact: 26 | a_set_fie: "{{lookup('hashivault', '{{name_root}}', 'fie')}}" 27 | - assert: { that: "a_set_fie == 'fum'" } 28 | -------------------------------------------------------------------------------- /functional/test_ephemeral.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: Make sure ephemeral secret store is disabled 6 | hashivault_secret_engine: 7 | name: "ephemeral" 8 | state: absent 9 | failed_when: False 10 | - name: Enable ephemeral secret store 11 | hashivault_secret_engine: 12 | name: "ephemeral" 13 | backend: "generic" 14 | register: 'vault_secret_enable' 15 | - assert: { that: "vault_secret_enable is changed" } 16 | - assert: { that: "vault_secret_enable.rc == 0" } 17 | 18 | - name: Enable same secret store again and check it doesn't fail 19 | hashivault_secret_engine: 20 | name: "ephemeral" 21 | backend: "generic" 22 | register: 'vault_secret_enable_twice' 23 | - assert: { that: "vault_secret_enable_twice is not changed" } 24 | - assert: { that: "vault_secret_enable_twice.rc == 0" } 25 | 26 | - name: Write a value to the ephemeral store 27 | hashivault_write: 28 | secret: '/ephemeral/name' 29 | data: 30 | value: 'ephemeral_stuff' 31 | 32 | - name: Read the ephemeral value 33 | hashivault_read: 34 | secret: '/ephemeral/name' 35 | key: 'value' 36 | register: 'vault_read' 37 | - assert: { that: "vault_read.value == 'ephemeral_stuff'" } 38 | 39 | - set_fact: 40 | looky_ephemeral: "{{lookup('hashivault', '/ephemeral/name', 'value')}}" 41 | - assert: { that: "looky_ephemeral == 'ephemeral_stuff'" } 42 | 43 | - name: Delete ephemeral secret 44 | hashivault_delete: 45 | secret: '/ephemeral/name' 46 | register: 'vault_secret_eph_delete' 47 | - assert: { that: "vault_secret_eph_delete is changed" } 48 | - assert: { that: "vault_secret_eph_delete.rc == 0" } 49 | - assert: { that: "vault_secret_eph_delete.msg == 'Secret ephemeral/name deleted'" } 50 | 51 | - name: Make sure ephemeral value is gone 52 | hashivault_read: 53 | secret: '/ephemeral/name' 54 | register: 'vault_read' 55 | failed_when: False 56 | - assert: { that: "vault_read is not changed" } 57 | - assert: { that: "vault_read.msg == 'Secret ephemeral/name is not in vault'" } 58 | 59 | - name: Tune ephemeral secret store 60 | hashivault_secret_engine: 61 | name: "ephemeral" 62 | backend: "generic" 63 | description: "new description" 64 | register: vault_update 65 | - assert: { that: "vault_update is changed" } 66 | - assert: { that: "vault_update.rc == 0" } 67 | 68 | - name: Idempotent tuning ephemeral secret store 69 | hashivault_secret_engine: 70 | name: "ephemeral" 71 | backend: "generic" 72 | description: "new description" 73 | register: vault_update 74 | - assert: { that: "vault_update is not changed" } 75 | - assert: { that: "vault_update.rc == 0" } 76 | 77 | - name: Disable ephemeral secret store 78 | hashivault_secret_engine: 79 | name: "ephemeral" 80 | state: disabled 81 | register: 'vault_secret_disable' 82 | - assert: { that: "vault_secret_enable is changed" } 83 | - assert: { that: "vault_secret_enable.rc == 0" } 84 | -------------------------------------------------------------------------------- /functional/test_full_path.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: Delete full path before we start 6 | hashivault_delete: 7 | secret: /secret/full/path 8 | failed_when: False 9 | 10 | - name: Write full path 11 | hashivault_write: 12 | secret: /secret/full/path 13 | data: 14 | basket: ball 15 | register: vault_write 16 | - assert: { that: "vault_write is changed" } 17 | - assert: { that: "vault_write.msg == 'Secret secret/full/path written'" } 18 | - assert: { that: "vault_write.rc == 0" } 19 | 20 | - name: Read full path 21 | hashivault_read: 22 | secret: /secret/full/path 23 | key: basket 24 | register: vault_read 25 | - assert: { that: "vault_read.value == 'ball'" } 26 | 27 | - set_fact: 28 | basket: "{{lookup('hashivault', '/secret/full/path', 'basket')}}" 29 | - assert: { that: "basket == 'ball'" } 30 | 31 | - name: Delete full path 32 | hashivault_delete: 33 | secret: /secret/full/path 34 | register: vault_delete 35 | - assert: { that: "vault_delete is changed" } 36 | - assert: { that: "vault_delete.rc == 0" } 37 | - assert: { that: "vault_delete.msg == 'Secret secret/full/path deleted'" } 38 | -------------------------------------------------------------------------------- /functional/test_generate_root.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | vault_keys: "{{ lookup('env','VAULT_KEYS') }}" 6 | tasks: 7 | - assert: 8 | that: "vault_keys != ''" 9 | msg: "VAULT_KEYS must be set to run this test" 10 | 11 | - name: Cancel anything that might be going 12 | hashivault_generate_root_cancel: 13 | register: hashivault_generate_root_cancel 14 | - assert: { that: "hashivault_generate_root_cancel.rc == 0" } 15 | 16 | - name: Generate root token initialize 17 | hashivault_generate_root_init: 18 | register: hashivault_generate_root_init 19 | - assert: { that: "hashivault_generate_root_init is changed" } 20 | - assert: { that: "hashivault_generate_root_init.rc == 0" } 21 | 22 | - name: Generate root status 23 | hashivault_generate_root_status: 24 | register: hashivault_generate_root_status 25 | - assert: { that: "hashivault_generate_root_status is not changed" } 26 | - assert: { that: "hashivault_generate_root_status.rc == 0" } 27 | 28 | - name: Generate a root token 29 | hashivault_generate_root: 30 | key: "{{vault_keys}}" 31 | nonce: "{{hashivault_generate_root_init.status.nonce}}" 32 | register: hashivault_generate_root 33 | - assert: { that: "hashivault_generate_root is changed" } 34 | - assert: { that: "hashivault_generate_root.rc == 0" } 35 | - assert: { that: "hashivault_generate_root.status.complete == True" } 36 | 37 | - name: Generate root token initialize 38 | hashivault_generate_root_init: 39 | register: hashivault_generate_root_init 40 | - assert: { that: "hashivault_generate_root_init is changed" } 41 | - assert: { that: "hashivault_generate_root_init.rc == 0" } 42 | 43 | - name: Generate root status 44 | hashivault_generate_root_status: 45 | register: hashivault_generate_root_status 46 | - assert: { that: "hashivault_generate_root_status is not changed" } 47 | - assert: { that: "hashivault_generate_root_status.rc == 0" } 48 | - assert: { that: "hashivault_generate_root_status.status.started == True" } 49 | 50 | - name: Cancel that 51 | hashivault_generate_root_cancel: 52 | register: hashivault_generate_root_cancel 53 | - assert: { that: "hashivault_generate_root_cancel is changed" } 54 | - assert: { that: "hashivault_generate_root_cancel.rc == 0" } 55 | 56 | - name: Generate root status 57 | hashivault_generate_root_status: 58 | register: hashivault_generate_root_status 59 | - assert: { that: "hashivault_generate_root_status is not changed" } 60 | - assert: { that: "hashivault_generate_root_status.rc == 0" } 61 | - assert: { that: "hashivault_generate_root_status.status.started == False" } 62 | -------------------------------------------------------------------------------- /functional/test_identity_entity.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - hashivault_identity_entity: 6 | name: bob 7 | state: absent 8 | - hashivault_identity_entity: 9 | name: sam 10 | state: absent 11 | 12 | - name: Create for the first time 13 | hashivault_identity_entity: 14 | name: bob 15 | policies: bob 16 | register: vault_identity 17 | - assert: { that: "vault_identity is changed" } 18 | - assert: { that: "vault_identity.rc == 0" } 19 | 20 | - name: Update no change 21 | hashivault_identity_entity: 22 | name: bob 23 | policies: bob 24 | register: vault_identity 25 | - assert: { that: "vault_identity is not changed" } 26 | - assert: { that: "vault_identity.rc == 0" } 27 | 28 | - name: Update remove policy 29 | hashivault_identity_entity: 30 | name: bob 31 | policies: null 32 | register: vault_identity 33 | - assert: { that: "vault_identity is not changed" } 34 | - assert: { that: "vault_identity.rc == 0" } 35 | 36 | - name: Update readd policy 37 | hashivault_identity_entity: 38 | name: bob 39 | policies: bob 40 | register: vault_identity 41 | - assert: { that: "vault_identity is not changed" } 42 | - assert: { that: "vault_identity.rc == 0" } 43 | 44 | - name: Update 45 | hashivault_identity_entity: 46 | name: bob 47 | policies: bob 48 | metadata: 49 | a: b 50 | c: d 51 | disabled: True 52 | register: vault_identity 53 | - assert: { that: "vault_identity is changed" } 54 | - assert: { that: "vault_identity.rc == 0" } 55 | 56 | - name: Delete it for the first time 57 | hashivault_identity_entity: 58 | name: bob 59 | state: absent 60 | register: vault_identity 61 | - assert: { that: "vault_identity is changed" } 62 | - assert: { that: "vault_identity.rc == 0" } 63 | 64 | - name: Delete it again 65 | hashivault_identity_entity: 66 | name: bob 67 | state: absent 68 | register: vault_identity 69 | - assert: { that: "vault_identity is not changed" } 70 | - assert: { that: "vault_identity.rc == 0" } 71 | 72 | - name: Create new one 73 | hashivault_identity_entity: 74 | name: sam 75 | policies: sam 76 | register: vault_identity 77 | - assert: { that: "vault_identity is changed" } 78 | - assert: { that: "vault_identity.rc == 0" } 79 | 80 | - hashivault_identity_entity_alias: 81 | name: sammy 82 | entity_name: sam 83 | register: vault_identity_alias 84 | - assert: { that: "vault_identity_alias is changed" } 85 | - assert: { that: "vault_identity_alias.rc == 0" } 86 | - hashivault_identity_entity_alias: 87 | name: sammy 88 | entity_name: sam 89 | state: absent 90 | register: vault_identity_alias 91 | - assert: { that: "vault_identity_alias is changed" } 92 | - assert: { that: "vault_identity_alias.rc == 0" } 93 | -------------------------------------------------------------------------------- /functional/test_init.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: Initialize vault 6 | hashivault_init: 7 | secret_shares: 1 8 | secret_threshold: 1 9 | register: 'vault_init' 10 | - block: 11 | - assert: { that: "vault_init.rc == 0" } 12 | when: "vault_init is not changed" 13 | - block: 14 | - assert: { that: "'keys' in vault_init" } 15 | - assert: { that: "'root_token' in vault_init" } 16 | - assert: { that: "vault_init.rc == 0" } 17 | - set_fact: 18 | vault_keys: "{{vault_init['keys'] | join(' ')}}" 19 | - name: Unseal the vault 20 | hashivault_unseal: 21 | keys: '{{vault_keys}}' 22 | register: 'vault_unseal' 23 | - assert: { that: "vault_unseal is changed" } 24 | - assert: { that: "vault_unseal.status.progress == 0" } 25 | - assert: { that: "vault_unseal.status.sealed == False" } 26 | - assert: { that: "vault_unseal.rc == 0" } 27 | - template: 28 | src: "{{playbook_dir}}/templates/vaultenv.sh.j2" 29 | dest: "{{playbook_dir}}/vaultenv.sh" 30 | mode: 0700 31 | when: "vault_init is changed" 32 | -------------------------------------------------------------------------------- /functional/test_jwt_auth_method_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | oidc_discovery_url: https://samples.auth0.com/ 7 | oidc_client_id: dont 8 | oidc_client_secret: matter 9 | tasks: 10 | - hashivault_auth_method: 11 | method_type: jwt 12 | state: disabled 13 | failed_when: false 14 | 15 | - name: make sure test fails when no mount exists 16 | hashivault_jwt_auth_method_config: 17 | oidc_discovery_url: "{{ oidc_discovery_url }}" 18 | oidc_client_id: "{{ oidc_client_id }}" 19 | oidc_client_secret: "{{ oidc_client_secret }}" 20 | register: fail_config 21 | failed_when: false 22 | 23 | - assert: { that: "fail_config is not changed" } 24 | 25 | - name: enable oidc auth method 26 | hashivault_auth_method: 27 | method_type: jwt 28 | 29 | - name: successfully configure method 30 | hashivault_jwt_auth_method_config: 31 | oidc_discovery_url: "{{ oidc_discovery_url }}" 32 | oidc_client_id: "{{ oidc_client_id }}" 33 | oidc_client_secret: "{{ oidc_client_secret }}" 34 | register: success_config 35 | 36 | - assert: { that: "success_config is changed" } 37 | 38 | - name: attempt 2nd config with same values 39 | hashivault_jwt_auth_method_config: 40 | oidc_discovery_url: "{{ oidc_discovery_url }}" 41 | oidc_client_id: "{{ oidc_client_id }}" 42 | register: idem_config 43 | 44 | - assert: { that: "idem_config is not changed" } 45 | 46 | - name: attempt 3rd config with different values 47 | hashivault_jwt_auth_method_config: 48 | oidc_discovery_url: "{{ oidc_discovery_url }}" 49 | oidc_client_id: mango 50 | oidc_client_secret: pineapple 51 | register: overwrite_config 52 | 53 | - assert: { that: "overwrite_config is changed" } 54 | -------------------------------------------------------------------------------- /functional/test_jwt_auth_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | oidc_discovery_url: https://samples.auth0.com/ 7 | oidc_client_id: dont 8 | oidc_client_secret: matter 9 | tasks: 10 | - hashivault_auth_method: 11 | method_type: jwt 12 | state: disabled 13 | failed_when: false 14 | 15 | - name: enable jwt secret engine 16 | hashivault_auth_method: 17 | method_type: jwt 18 | 19 | - name: successfully configure mount 20 | hashivault_jwt_auth_method_config: 21 | oidc_discovery_url: "{{ oidc_discovery_url }}" 22 | oidc_client_id: "{{ oidc_client_id }}" 23 | oidc_client_secret: "{{ oidc_client_secret }}" 24 | 25 | - name: create 1st role 26 | hashivault_jwt_auth_role: 27 | name: "test" 28 | bound_audiences: ["123456"] 29 | allowed_redirect_uris: ["https://123456.com/callback"] 30 | token_policies: ["test"] 31 | register: success_config 32 | 33 | - assert: { that: "success_config is changed" } 34 | 35 | - name: idempotently create role 36 | hashivault_jwt_auth_role: 37 | name: "test" 38 | bound_audiences: ["123456"] 39 | allowed_redirect_uris: ["https://123456.com/callback"] 40 | token_policies: ["test"] 41 | register: idem_config 42 | 43 | - assert: { that: "idem_config is not changed" } 44 | 45 | - name: update role 46 | hashivault_jwt_auth_role: 47 | name: "test" 48 | bound_audiences: ["123456"] 49 | allowed_redirect_uris: ["https://123456.com/callback"] 50 | token_policies: ["test","test2"] 51 | register: new_config 52 | 53 | - assert: { that: "new_config is changed" } 54 | 55 | - name: delete role 56 | hashivault_jwt_auth_role: 57 | name: "test" 58 | state: absent 59 | allowed_redirect_uris: ["https://123456.com/callback"] 60 | register: del_config 61 | 62 | - assert: { that: "del_config is changed" } 63 | -------------------------------------------------------------------------------- /functional/test_ldap_group.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: arrange - policies - functional_testing_policy_one 6 | hashivault_policy: 7 | name: functional_testing_policy_one 8 | rules: 'path "secret/*" {capabilities = ["read", "list"]}' 9 | 10 | - name: arrange - policies - functional_testing_policy_two 11 | hashivault_policy: 12 | name: functional_testing_policy_two 13 | rules: 'path "secret/*" {capabilities = ["read", "list"]}' 14 | 15 | - name: enable ldap authentication 16 | hashivault_auth_method: 17 | method_type: ldap 18 | 19 | - name: ldap configuration 20 | hashivault_auth_ldap: 21 | ldap_url: ldap://localhost 22 | register: ldap_module 23 | - assert: { that: "ldap_module is changed" } 24 | - assert: { that: "ldap_module.rc == 0" } 25 | 26 | - name: ldap configuration is idempotent 27 | hashivault_auth_ldap: 28 | ldap_url: ldap://localhost 29 | register: ldap_module_idempotent 30 | - assert: { that: "ldap_module_idempotent is not changed" } 31 | 32 | - name: remove ldap group 33 | hashivault_ldap_group: 34 | name: test 35 | state: absent 36 | 37 | - name: add ldap group 38 | hashivault_ldap_group: 39 | name: test 40 | state: present 41 | register: success_config 42 | 43 | - assert: { that: "success_config is changed" } 44 | 45 | - name: chg policies - add functional_testing_policy_one 46 | hashivault_ldap_group: 47 | name: test 48 | state: present 49 | policies: 50 | - functional_testing_policy_one 51 | register: chg_policies 52 | 53 | - assert: { that: "chg_policies is changed" } 54 | 55 | - name: duplicate policies 56 | hashivault_ldap_group: 57 | name: test 58 | state: present 59 | policies: 60 | - functional_testing_policy_one 61 | register: chg_policies 62 | 63 | - assert: { that: "chg_policies is not changed" } 64 | 65 | - name: chg policies - add functional_testing_policy_two 66 | hashivault_ldap_group: 67 | name: test 68 | state: present 69 | policies: 70 | - functional_testing_policy_one 71 | - functional_testing_policy_two 72 | register: chg_policies 73 | 74 | - assert: { that: "chg_policies is changed" } 75 | 76 | - name: chg policies - remove functional_testing_policy_one 77 | hashivault_ldap_group: 78 | name: test 79 | state: present 80 | policies: 81 | - functional_testing_policy_two 82 | register: chg_policies 83 | 84 | - assert: { that: "chg_policies is changed" } 85 | -------------------------------------------------------------------------------- /functional/test_lookup.yml: -------------------------------------------------------------------------------- 1 | # 2 | # This test depends on successful test_write run 3 | # 4 | --- 5 | - hosts: localhost 6 | gather_facts: no 7 | vars: 8 | namespace: '' 9 | name_root: '{{namespace}}basic' 10 | name_folder: '{{namespace}}stalks/bean' 11 | name_dict: '{{namespace}}_dict' 12 | name_array: '{{namespace}}_array' 13 | vars_foo: "{{lookup('hashivault', '{{name_root}}', 'foo')}}" 14 | dict_value: 15 | foo: 'bar' 16 | baz: 'stuff' 17 | array_value: 18 | - 'one' 19 | - 'two' 20 | - 'three' 21 | tasks: 22 | - assert: { that: "vars_foo == 'new'" } 23 | 24 | - set_fact: 25 | a_set_fie: "{{lookup('hashivault', '{{name_root}}', 'fie')}}" 26 | - assert: { that: "a_set_fie == 'fum'" } 27 | 28 | - set_fact: 29 | a_set_fie: "{{lookup('hashivault', '{{name_folder}}', 'height')}}" 30 | - assert: { that: "a_set_fie == 'tall'" } 31 | 32 | - set_fact: 33 | a_set_dict: "{{lookup('hashivault', '{{name_dict}}', 'foo')}}" 34 | - assert: { that: "a_set_dict == 'bar'" } 35 | 36 | - set_fact: 37 | a_set_array: "{{lookup('hashivault', '{{name_array}}', 'value') | first}}" 38 | - assert: { that: "a_set_array == 'one'" } 39 | 40 | - set_fact: 41 | a_set_dict_all: "{{lookup('hashivault', '{{name_dict}}')}}" 42 | - assert: { that: "a_set_dict_all == dict_value" } 43 | 44 | - set_fact: 45 | a_set_array_all: "{{lookup('hashivault', '{{name_array}}')['value']}}" 46 | - assert: { that: "a_set_array_all == array_value" } 47 | 48 | - set_fact: 49 | looky_secret: "{{lookup('hashivault', '{{namespace}}fourofour/notfound', 'value', default='noob')}}" 50 | - assert: { that: "looky_secret == 'noob'" } 51 | 52 | - set_fact: 53 | looky_secret: "{{lookup('hashivault', '{{name_root}}', 'fie', url='http://bogus', errors='ignore')}}" 54 | - assert: { that: "looky_secret == ''" } 55 | -------------------------------------------------------------------------------- /functional/test_mounts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | tasks: 6 | - hashivault_secret_engine: 7 | name: kv 8 | state: absent 9 | 10 | - hashivault_secret_engine: 11 | name: blergh 12 | state: absent 13 | 14 | - name: enable with config defaults 15 | hashivault_secret_engine: 16 | name: kv 17 | state: present 18 | register: success_config 19 | 20 | - assert: { that: "success_config is changed" } 21 | 22 | - name: skip with config defaults 23 | hashivault_secret_engine: 24 | name: kv 25 | state: present 26 | register: skip_config 27 | 28 | - assert: { that: "skip_config is not changed" } 29 | 30 | - name: changed with config vars 31 | hashivault_secret_engine: 32 | name: kv 33 | state: present 34 | config: {'default_lease_ttl': 1234567} 35 | register: chg_config 36 | 37 | - assert: { that: "chg_config is changed" } 38 | 39 | - name: changed to version 2 40 | hashivault_secret_engine: 41 | name: kv 42 | state: present 43 | config: {'default_lease_ttl': 1234567} 44 | options: {'version': '2'} 45 | register: chg_version 46 | 47 | - assert: { that: "chg_version is changed" } 48 | 49 | - name: dont fail when options passed to non kv 50 | hashivault_secret_engine: 51 | name: blergh 52 | backend: gcp 53 | state: present 54 | config: {'default_lease_ttl': 1234567} 55 | options: {'version': '2'} 56 | register: dont_pass_options 57 | 58 | - assert: { that: "dont_pass_options is changed" } 59 | 60 | - name: cleanup 1 61 | hashivault_secret_engine: 62 | name: blergh 63 | backend: gcp 64 | state: absent 65 | config: {'default_lease_ttl': 1234567} 66 | options: {'version': '2'} 67 | register: disable 68 | 69 | - assert: { that: "disable is changed" } 70 | 71 | - name: cleanup 2 72 | hashivault_secret_engine: 73 | name: kv 74 | backend: kv 75 | state: absent 76 | config: {'default_lease_ttl': 1234567} 77 | options: {'version': '2'} 78 | register: disable2 79 | 80 | - assert: { that: "disable2 is changed" } 81 | -------------------------------------------------------------------------------- /functional/test_namespace.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | connection: localhost 4 | tasks: 5 | 6 | - hashivault_namespace: 7 | name: hvtest 8 | state: absent 9 | 10 | - hashivault_namespace: 11 | name: hvtest 12 | register: first_create 13 | 14 | - assert: { that: "first_create is changed" } 15 | 16 | - hashivault_namespace: 17 | name: hvtest 18 | register: idem_create 19 | 20 | - assert: { that: "idem_create is not changed" } 21 | 22 | - hashivault_namespace: 23 | name: child 24 | namespace: hvtest 25 | register: second_create 26 | 27 | - assert: { that: "second_create is changed" } 28 | 29 | - hashivault_namespace: 30 | name: child 31 | namespace: hvtest 32 | register: second_idem_create 33 | 34 | - assert: { that: "second_idem_create is not changed" } 35 | 36 | - hashivault_namespace: 37 | name: child2 38 | namespace: hvtest/child 39 | register: third_create 40 | 41 | - assert: { that: "third_create is changed" } 42 | 43 | - hashivault_namespace: 44 | name: child2 45 | namespace: hvtest/child 46 | register: third_idem_create 47 | 48 | - assert: { that: "third_idem_create is not changed" } 49 | 50 | - hashivault_namespace: 51 | name: hvtest 52 | state: absent 53 | register: delete_fail 54 | failed_when: False 55 | - assert: { that: "delete_fail.rc != 0" } 56 | 57 | 58 | - hashivault_namespace: 59 | name: child2 60 | namespace: hvtest/child 61 | state: absent 62 | register: delete_one 63 | 64 | - assert: { that: "delete_one is changed" } 65 | 66 | - hashivault_namespace: 67 | name: child 68 | namespace: hvtest 69 | state: absent 70 | register: delete_two 71 | 72 | - assert: { that: "delete_two is changed" } 73 | 74 | - hashivault_namespace: 75 | name: hvtest 76 | state: absent 77 | register: delete_three 78 | 79 | - assert: { that: "delete_three is changed" } 80 | 81 | - hashivault_namespace: 82 | name: hvtest 83 | state: absent 84 | register: delete_idem 85 | 86 | - assert: { that: "delete_idem is not changed" } 87 | -------------------------------------------------------------------------------- /functional/test_not_there.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | secret_name: 'fourofour/nothome' 6 | tasks: 7 | - hashivault_delete: 8 | secret: '{{secret_name}}' 9 | 10 | - name: Read nonexistent secret value ignoring error 11 | hashivault_read: 12 | secret: '{{secret_name}}' 13 | key: 'value' 14 | register: 'vault_read' 15 | failed_when: False 16 | - assert: { that: "vault_read.failed == False" } 17 | - assert: { that: "vault_read.rc == 1" } 18 | - assert: { that: "vault_read.msg == 'Secret secret/fourofour/nothome is not in vault'" } 19 | 20 | - name: Nonexistent secret path with empty default 21 | hashivault_read: 22 | secret: '{{secret_name}}' 23 | key: 'value' 24 | default: '' 25 | register: 'vault_read' 26 | - assert: { that: "vault_read.value == ''" } 27 | - assert: { that: "vault_read.failed == False" } 28 | - assert: { that: "vault_read.rc == 0" } 29 | 30 | - name: Nonexistent secret path with default 31 | hashivault_read: 32 | secret: '{{secret_name}}' 33 | key: 'value' 34 | default: 'carseat' 35 | register: 'vault_read' 36 | - assert: { that: "vault_read.value == 'carseat'" } 37 | 38 | - set_fact: 39 | looky_secret: "{{lookup('hashivault', '{{secret_name}}', 'value', default='headrest')}}" 40 | - assert: { that: "looky_secret == 'headrest'" } 41 | 42 | - name: Write new different value to secret store 43 | hashivault_write: 44 | secret: '{{secret_name}}' 45 | data: 46 | othervalue: 'one' 47 | 48 | - name: Nonexistent key with default 49 | hashivault_read: 50 | secret: '{{secret_name}}' 51 | key: 'value' 52 | default: 'better' 53 | register: 'vault_read' 54 | - assert: { that: "vault_read.value == 'better'" } 55 | 56 | - set_fact: 57 | looky_secret: "{{lookup('hashivault', '{{secret_name}}', 'othervalue', default='noob')}}" 58 | - assert: { that: "looky_secret == 'one'" } 59 | 60 | - set_fact: 61 | looky_secret: "{{lookup('hashivault', '{{secret_name}}', 'value', default='noob')}}" 62 | - assert: { that: "looky_secret == 'noob'" } 63 | -------------------------------------------------------------------------------- /functional/test_oidc_auth_method_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | oidc_discovery_url: https://samples.auth0.com/ 7 | oidc_client_id: dont 8 | oidc_client_secret: matter 9 | tasks: 10 | - hashivault_auth_method: 11 | method_type: oidc 12 | state: disabled 13 | failed_when: false 14 | 15 | - name: make sure test fails when no mount exists 16 | hashivault_oidc_auth_method_config: 17 | oidc_discovery_url: "{{ oidc_discovery_url }}" 18 | oidc_client_id: "{{ oidc_client_id }}" 19 | oidc_client_secret: "{{ oidc_client_secret }}" 20 | register: fail_config 21 | failed_when: false 22 | 23 | - assert: { that: "fail_config is not changed" } 24 | 25 | - name: enable oidc auth method 26 | hashivault_auth_method: 27 | method_type: oidc 28 | 29 | - name: successfully configure method 30 | hashivault_oidc_auth_method_config: 31 | oidc_discovery_url: "{{ oidc_discovery_url }}" 32 | oidc_client_id: "{{ oidc_client_id }}" 33 | oidc_client_secret: "{{ oidc_client_secret }}" 34 | register: success_config 35 | 36 | - assert: { that: "success_config is changed" } 37 | 38 | - name: attempt 2nd config with same values 39 | hashivault_oidc_auth_method_config: 40 | oidc_discovery_url: "{{ oidc_discovery_url }}" 41 | oidc_client_id: "{{ oidc_client_id }}" 42 | register: idem_config 43 | 44 | - assert: { that: "idem_config is not changed" } 45 | 46 | - name: attempt 3rd config with different values 47 | hashivault_oidc_auth_method_config: 48 | oidc_discovery_url: "{{ oidc_discovery_url }}" 49 | oidc_client_id: mango 50 | oidc_client_secret: pineapple 51 | register: overwrite_config 52 | 53 | - assert: { that: "overwrite_config is changed" } 54 | -------------------------------------------------------------------------------- /functional/test_oidc_auth_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: localhost 4 | gather_facts: no 5 | vars: 6 | oidc_discovery_url: https://samples.auth0.com/ 7 | oidc_client_id: dont 8 | oidc_client_secret: matter 9 | tasks: 10 | - hashivault_auth_method: 11 | method_type: oidc 12 | state: disabled 13 | failed_when: false 14 | 15 | - name: enable oidc secret engine 16 | hashivault_auth_method: 17 | method_type: oidc 18 | 19 | - name: successfully configure mount 20 | hashivault_oidc_auth_method_config: 21 | oidc_discovery_url: "{{ oidc_discovery_url }}" 22 | oidc_client_id: "{{ oidc_client_id }}" 23 | oidc_client_secret: "{{ oidc_client_secret }}" 24 | 25 | - name: create 1st role 26 | hashivault_oidc_auth_role: 27 | name: "test" 28 | bound_audiences: ["123456"] 29 | allowed_redirect_uris: ["https://123456.com/callback"] 30 | token_policies: ["test"] 31 | register: success_config 32 | 33 | - assert: { that: "success_config is changed" } 34 | 35 | - name: idempotently create role 36 | hashivault_oidc_auth_role: 37 | name: "test" 38 | bound_audiences: ["123456"] 39 | allowed_redirect_uris: ["https://123456.com/callback"] 40 | token_policies: ["test"] 41 | register: idem_config 42 | 43 | - assert: { that: "idem_config is not changed" } 44 | 45 | - name: delete role 46 | hashivault_oidc_auth_role: 47 | name: "test" 48 | state: absent 49 | allowed_redirect_uris: ["https://123456.com/callback"] 50 | register: del_config 51 | 52 | - assert: { that: "del_config is changed" } 53 | -------------------------------------------------------------------------------- /functional/test_read.yml: -------------------------------------------------------------------------------- 1 | # 2 | # This test depends on successful test_write run 3 | # 4 | --- 5 | - hosts: localhost 6 | gather_facts: no 7 | vars: 8 | namespace: '' 9 | name_root: '{{namespace}}basic' 10 | name_folder: '{{namespace}}stalks/bean' 11 | name_dict: '{{namespace}}_dict' 12 | name_array: '{{namespace}}_array' 13 | dict_value: 14 | foo: 'bar' 15 | baz: 'stuff' 16 | array_value: 17 | - 'one' 18 | - 'two' 19 | - 'three' 20 | tasks: 21 | - name: Read the secret value 22 | hashivault_read: 23 | secret: '{{name_root}}' 24 | key: foo 25 | register: vault_read 26 | - assert: { that: "vault_read.value == 'new'" } 27 | 28 | - name: Read other secret value 29 | hashivault_read: 30 | secret: '{{name_root}}' 31 | key: fie 32 | register: vault_read 33 | - assert: { that: "vault_read.value == 'fum'" } 34 | 35 | - name: Read other secret folder 36 | hashivault_read: 37 | secret: '{{name_folder}}' 38 | key: height 39 | register: vault_read 40 | - assert: { that: "vault_read.value == 'tall'" } 41 | 42 | - name: Read secret dictionary 43 | hashivault_read: 44 | secret: '{{name_dict}}' 45 | register: vault_read 46 | - assert: { that: "vault_read.value == dict_value" } 47 | - assert: { that: "vault_read.rc == 0" } 48 | 49 | - name: Read array type secret and make sure it matches 50 | hashivault_read: 51 | secret: '{{name_array}}' 52 | key: value 53 | register: vault_read 54 | - assert: { that: "vault_read.value == array_value" } 55 | - assert: { that: "vault_read.value[0] == array_value[0]" } 56 | - assert: { that: "vault_read.value[1] == array_value[1]" } 57 | - assert: { that: "vault_read.value[2] == array_value[2]" } 58 | 59 | - set_fact: 60 | looky_secret: "{{lookup('hashivault', '{{name_array}}', 'value') | first}}" 61 | - assert: { that: "looky_secret == 'one'" } 62 | -------------------------------------------------------------------------------- /functional/test_rekey.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | unseal_key: "{{ lookup('env','VAULT_KEYS') }}" 6 | tasks: 7 | - name: Check rekey status 8 | hashivault_rekey_status: 9 | register: 'vault_rekey_status' 10 | - assert: { that: "vault_rekey_status is not changed" } 11 | - assert: { that: "vault_rekey_status.rc == 0" } 12 | 13 | - block: 14 | - name: Cancel the rekey if one was started 15 | hashivault_rekey_cancel: 16 | register: 'vault_rekey_cancel' 17 | - assert: { that: "vault_rekey_cancel is changed" } 18 | - assert: { that: "vault_rekey_cancel.rc == 0" } 19 | when: "vault_rekey_status.status.started == True" 20 | 21 | - name: Start a rekey 22 | hashivault_rekey_init: 23 | secret_shares: 1 24 | secret_threshold: 1 25 | register: 'vault_rekey_init' 26 | - assert: { that: "vault_rekey_init is changed" } 27 | - assert: { that: "vault_rekey_init.status.progress == 0" } 28 | - assert: { that: "vault_rekey_init.status.started == True" } 29 | - assert: { that: "vault_rekey_init.rc == 0" } 30 | - assert: { that: "vault_rekey_init.status.verification_required == False" } 31 | 32 | - name: Make sure the rekey started 33 | hashivault_rekey_status: 34 | register: 'vault_rekey_status' 35 | - assert: { that: "vault_rekey_status is not changed" } 36 | - assert: { that: "vault_rekey_status.rc == 0" } 37 | - assert: { that: "vault_rekey_init.status.progress == 0" } 38 | - assert: { that: "vault_rekey_status.status.started == True" } 39 | 40 | - name: Canel the rekey 41 | hashivault_rekey_cancel: 42 | register: 'vault_rekey_cancel' 43 | - assert: { that: "vault_rekey_cancel is changed" } 44 | - assert: { that: "vault_rekey_cancel.rc == 0" } 45 | 46 | - name: Restart that rekey again 47 | hashivault_rekey_init: 48 | secret_shares: 1 49 | secret_threshold: 1 50 | register: 'vault_rekey_init' 51 | - assert: { that: "vault_rekey_init is changed" } 52 | - assert: { that: "vault_rekey_init.status.progress == 0" } 53 | - assert: { that: "vault_rekey_init.status.started == True" } 54 | - assert: { that: "vault_rekey_init.rc == 0" } 55 | - assert: { that: "vault_rekey_init.status.verification_required == False" } 56 | 57 | - name: Update the rekey 58 | hashivault_rekey: 59 | key: "{{ unseal_key }}" 60 | nonce: "{{ vault_rekey_init.status.nonce }}" 61 | register: 'vault_rekey' 62 | - assert: { that: "vault_rekey is changed" } 63 | - assert: { that: "vault_rekey.rc == 0" } 64 | - assert: { that: "vault_rekey.status.complete == True" } 65 | - assert: { that: "vault_rekey.status.verification_required == False" } 66 | 67 | - name: Update vaultenv.sh with new keys 68 | lineinfile: 69 | name: vaultenv.sh 70 | regexp: '^export VAULT_KEYS=' 71 | line: export VAULT_KEYS='{{ vault_rekey['status']['keys'][0] }}' 72 | -------------------------------------------------------------------------------- /functional/test_secret_list.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: List secret stores 6 | hashivault_secret_list: 7 | register: 'vault_secret_list' 8 | - assert: { that: "vault_secret_list is not changed" } 9 | - assert: { that: "vault_secret_list.failed == False" } 10 | - assert: { that: "'backends' in vault_secret_list" } 11 | - assert: { that: "vault_secret_list.rc == 0" } 12 | -------------------------------------------------------------------------------- /functional/test_ssh_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | namespace: 'application' 6 | rules: > 7 | path "ssh/{{namespace}}/*" { 8 | capabilities = ["create", "read", "update", "delete", "list"] 9 | } 10 | path "ssh/{{namespace}}" { 11 | capabilities = ["list"] 12 | } 13 | tasks: 14 | - name: Enable ssh secret engine 15 | hashivault_secret_engine: 16 | name: ssh 17 | state: enabled 18 | 19 | - name: Set ssh role policy 20 | hashivault_policy: 21 | name: "sshrole_test_user_original" 22 | rules: "{{rules}}" 23 | register: vault_policy 24 | - assert: { that: "vault_policy.rc == 0" } 25 | 26 | - name: Set another ssh role policy 27 | hashivault_policy: 28 | name: "sshrole_test_user" 29 | rules: "{{rules}}" 30 | register: vault_policy 31 | - assert: { that: "vault_policy.rc == 0" } 32 | 33 | - name: delete role 34 | hashivault_ssh_role: 35 | name: testrole 36 | state: absent 37 | failed_when: false 38 | 39 | - name: list ssh roles empty 40 | hashivault_ssh_role_list: 41 | register: 'vault_role_list' 42 | - assert: { that: "vault_role_list is not changed" } 43 | - assert: { that: "vault_role_list.rc == 0" } 44 | - assert: { that: "vault_role_list.data|length == 0"} 45 | 46 | - name: create role 47 | hashivault_ssh_role: 48 | name: testrole 49 | config: 50 | key_type: ca 51 | allowed_users: sshrole_test_user_original 52 | allow_host_certificates: true 53 | state: present 54 | register: 'vault_role_create' 55 | - assert: { that: "vault_role_create is changed" } 56 | - assert: { that: "vault_role_create.rc == 0" } 57 | 58 | - name: update role 59 | hashivault_ssh_role: 60 | name: testrole 61 | config: 62 | allowed_users: sshrole_test_user 63 | state: present 64 | register: 'vault_role_update' 65 | - assert: { that: "vault_role_update is changed" } 66 | - assert: { that: "vault_role_update.rc == 0" } 67 | 68 | - name: update role idempotent 69 | hashivault_ssh_role: 70 | name: testrole 71 | config: 72 | allowed_users: sshrole_test_user 73 | allow_host_certificates: true 74 | state: present 75 | register: 'vault_role_update' 76 | - assert: { that: "vault_role_update is not changed" } 77 | - assert: { that: "vault_role_update.rc == 0" } 78 | 79 | - name: list ssh roles 80 | hashivault_ssh_role_list: 81 | register: 'vault_role_list' 82 | - assert: { that: "vault_role_list is not changed" } 83 | - assert: { that: "vault_role_list.rc == 0" } 84 | - fail: msg="role testrole not in list {{vault_role_list.data}}" 85 | when: '"testrole" not in vault_role_list.data' 86 | -------------------------------------------------------------------------------- /functional/test_ssh_role_check_mode.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: create ssh role check_mode exists 6 | hashivault_ssh_role: 7 | name: testrole 8 | config: 9 | key_type: ca 10 | allowed_users: sshrole_test_user 11 | state: present 12 | check_mode: true 13 | register: 'vault_role_create' 14 | - assert: { that: "vault_role_create is not changed" } 15 | - assert: { that: "vault_role_create.rc == 0" } 16 | 17 | - name: create ssh role check_mode does not exist 18 | hashivault_ssh_role: 19 | name: testrole_two 20 | config: 21 | key_type: ca 22 | allowed_users: sshrole_test_user 23 | state: present 24 | check_mode: true 25 | register: 'vault_role_create' 26 | - assert: { that: "vault_role_create is changed" } 27 | - assert: { that: "vault_role_create.rc == 0" } 28 | 29 | - name: delete ssh role check_mode exists 30 | hashivault_ssh_role: 31 | name: testrole 32 | state: absent 33 | check_mode: true 34 | register: 'vault_role_create' 35 | - assert: { that: "vault_role_create is changed" } 36 | - assert: { that: "vault_role_create.rc == 0" } 37 | 38 | - name: delete ssh role check_mode does not exist 39 | hashivault_ssh_role: 40 | name: testrole_two 41 | state: absent 42 | check_mode: true 43 | register: 'vault_role_create' 44 | - assert: { that: "vault_role_create is not changed" } 45 | - assert: { that: "vault_role_create.rc == 0" } 46 | 47 | - name: list ssh roles check_mode 48 | hashivault_ssh_role_list: 49 | register: 'vault_role_list' 50 | check_mode: true 51 | - assert: { that: "vault_role_list is not changed" } 52 | - assert: { that: "vault_role_list.rc == 0" } 53 | - fail: msg="role testrole not in list {{vault_role_list.data}}" 54 | when: '"testrole" not in vault_role_list.data' 55 | -------------------------------------------------------------------------------- /functional/test_status.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: Get vault status and make sure it is unsealed 6 | hashivault_status: 7 | register: 'vault_status' 8 | - assert: { that: "vault_status is not changed" } 9 | - assert: { that: "vault_status.status.progress == 0" } 10 | - assert: { that: "vault_status.status.sealed == False" } 11 | - assert: { that: "vault_status.rc == 0" } 12 | 13 | - name: Get hashivault_leader 14 | hashivault_leader: 15 | register: 'vault_status' 16 | - assert: { that: "vault_status is not changed" } 17 | - assert: { that: "vault_status.status.ha_enabled == False" } 18 | - assert: { that: "vault_status.rc == 0" } 19 | 20 | - name: Get hashivault_cluster_status 21 | hashivault_cluster_status: 22 | register: 'vault_status' 23 | - assert: { that: "vault_status is not changed" } 24 | - assert: { that: "vault_status.rc == 0" } 25 | 26 | - name: Get hashivault_cluster_status 27 | hashivault_cluster_status: 28 | standby_ok: false 29 | register: 'vault_status' 30 | - assert: { that: "vault_status is not changed" } 31 | - assert: { that: "vault_status.rc == 0" } 32 | 33 | - name: Get hashivault_cluster_status 34 | hashivault_cluster_status: 35 | method: GET 36 | register: 'vault_status' 37 | - assert: { that: "vault_status is not changed" } 38 | - assert: { that: "vault_status.rc == 0" } 39 | 40 | - name: Get hashivault_cluster_status 41 | hashivault_cluster_status: 42 | standby_ok: false 43 | method: GET 44 | register: 'vault_status' 45 | - assert: { that: "vault_status is not changed" } 46 | - assert: { that: "vault_status.rc == 0" } 47 | -------------------------------------------------------------------------------- /functional/test_token_role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | namespace: 'application' 6 | rules: > 7 | path "token/{{namespace}}/*" { 8 | capabilities = ["create", "read", "update", "delete", "list"] 9 | } 10 | path "token/{{namespace}}" { 11 | capabilities = ["list"] 12 | } 13 | tasks: 14 | - name: Set token role policy 15 | hashivault_policy: 16 | name: "tokenrole_test_policy_original" 17 | rules: "{{rules}}" 18 | register: vault_policy 19 | - assert: { that: "vault_policy.rc == 0" } 20 | 21 | - name: Set another token role policy 22 | hashivault_policy: 23 | name: "tokenrole_test_policy" 24 | rules: "{{rules}}" 25 | register: vault_policy 26 | - assert: { that: "vault_policy.rc == 0" } 27 | 28 | - name: delete role 29 | hashivault_token_role: 30 | name: testrole 31 | state: absent 32 | failed_when: false 33 | 34 | - name: list token roles empty 35 | hashivault_token_role_list: 36 | register: 'vault_role_list' 37 | - assert: { that: "vault_role_list is not changed" } 38 | - assert: { that: "vault_role_list.rc == 0" } 39 | - assert: { that: "vault_role_list.data|length == 0"} 40 | 41 | - name: create role 42 | hashivault_token_role: 43 | name: testrole 44 | config: 45 | allowed_policies: 46 | - tokenrole_test_policy_original 47 | state: present 48 | register: 'vault_role_create' 49 | - assert: { that: "vault_role_create is changed" } 50 | - assert: { that: "vault_role_create.rc == 0" } 51 | 52 | - name: update role 53 | hashivault_token_role: 54 | name: testrole 55 | config: 56 | allowed_policies: 57 | - tokenrole_test_policy 58 | state: present 59 | register: 'vault_role_update' 60 | - assert: { that: "vault_role_update is changed" } 61 | - assert: { that: "vault_role_update.rc == 0" } 62 | 63 | - name: update role idempotent 64 | hashivault_token_role: 65 | name: testrole 66 | config: 67 | allowed_policies: 68 | - tokenrole_test_policy 69 | state: present 70 | register: 'vault_role_update' 71 | - assert: { that: "vault_role_update is not changed" } 72 | - assert: { that: "vault_role_update.rc == 0" } 73 | 74 | - name: list token roles 75 | hashivault_token_role_list: 76 | register: 'vault_role_list' 77 | - assert: { that: "vault_role_list is not changed" } 78 | - assert: { that: "vault_role_list.rc == 0" } 79 | - fail: msg="role testrole not in list {{vault_role_list.data}}" 80 | when: '"testrole" not in vault_role_list.data' 81 | -------------------------------------------------------------------------------- /functional/test_token_role_check_mode.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | tasks: 5 | - name: create token role check_mode exists 6 | hashivault_token_role: 7 | name: testrole 8 | config: 9 | allowed_policies: 10 | - tokenrole_test_policy 11 | state: present 12 | check_mode: true 13 | register: 'vault_role_create' 14 | - assert: { that: "vault_role_create is not changed" } 15 | - assert: { that: "vault_role_create.rc == 0" } 16 | 17 | - name: create token role check_mode does not exist 18 | hashivault_token_role: 19 | name: testrole_two 20 | config: 21 | allowed_policies: 22 | - tokenrole_test_policy 23 | state: present 24 | check_mode: true 25 | register: 'vault_role_create' 26 | - assert: { that: "vault_role_create is changed" } 27 | - assert: { that: "vault_role_create.rc == 0" } 28 | 29 | - name: delete token role check_mode exists 30 | hashivault_token_role: 31 | name: testrole 32 | state: absent 33 | check_mode: true 34 | register: 'vault_role_create' 35 | - assert: { that: "vault_role_create is changed" } 36 | - assert: { that: "vault_role_create.rc == 0" } 37 | 38 | - name: delete token role check_mode does not exist 39 | hashivault_token_role: 40 | name: testrole_two 41 | state: absent 42 | check_mode: true 43 | register: 'vault_role_create' 44 | - assert: { that: "vault_role_create is not changed" } 45 | - assert: { that: "vault_role_create.rc == 0" } 46 | 47 | - name: list token roles check_mode 48 | hashivault_token_role_list: 49 | register: 'vault_role_list' 50 | check_mode: true 51 | - assert: { that: "vault_role_list is not changed" } 52 | - assert: { that: "vault_role_list.rc == 0" } 53 | - fail: msg="role testrole not in list {{vault_role_list.data}}" 54 | when: '"testrole" not in vault_role_list.data' 55 | -------------------------------------------------------------------------------- /functional/test_unseal.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | vault_keys: "{{ lookup('env','VAULT_KEYS') }}" 6 | tasks: 7 | - assert: 8 | that: "vault_keys != ''" 9 | msg: "VAULT_KEYS must be set to run this test" 10 | - name: Get status of vault before unseal 11 | hashivault_status: 12 | register: 'vault_status' 13 | 14 | - block: 15 | - name: Vault is not sealed so seal it 16 | hashivault_seal: 17 | register: 'vault_seal' 18 | - assert: { that: "vault_seal is changed" } 19 | - assert: { that: "vault_seal.rc == 0" } 20 | when: "vault_status.status.sealed == False" 21 | 22 | - name: Seal the vault but it is already sealed 23 | hashivault_seal: 24 | register: 'vault_seal_st' 25 | - assert: { that: "vault_seal_st is not changed" } 26 | - assert: { that: "vault_seal_st.rc == 0" } 27 | 28 | - name: Unseal the vault 29 | hashivault_unseal: 30 | keys: '{{vault_keys}}' 31 | register: 'vault_unseal' 32 | - assert: { that: "vault_unseal is changed" } 33 | - assert: { that: "vault_unseal.status.progress == 0" } 34 | - assert: { that: "vault_unseal.status.sealed == False" } 35 | - assert: { that: "vault_unseal.rc == 0" } 36 | 37 | - name: Unseal the vault but it is not sealed 38 | hashivault_unseal: 39 | keys: '{{vault_keys}}' 40 | register: 'vault_unseal_st' 41 | - assert: { that: "vault_unseal_st is not changed" } 42 | - assert: { that: "vault_unseal_st.rc == 0" } 43 | -------------------------------------------------------------------------------- /functional/test_userpass.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | username: 'portugal' 6 | userpass: 'Th3m@n!!' 7 | rules: > 8 | path "secret/userpass/*" { 9 | capabilities = ["create", "read", "update", "delete", "list"] 10 | } 11 | path "secret/userpass" { 12 | capabilities = ["list"] 13 | } 14 | tasks: 15 | - hashivault_auth_method: 16 | method_type: "userpass" 17 | failed_when: False 18 | - hashivault_userpass: 19 | name: "{{username}}" 20 | state: absent 21 | - hashivault_policy: 22 | name: "{{username}}" 23 | state: absent 24 | 25 | - name: Set policy for userpass 26 | hashivault_policy: 27 | name: "{{username}}" 28 | rules: "{{rules}}" 29 | register: vault_policy 30 | - assert: { that: "vault_policy is changed" } 31 | - assert: { that: "vault_policy.rc == 0" } 32 | 33 | - name: Create user pass with policy 34 | hashivault_userpass: 35 | name: "{{username}}" 36 | pass: "{{userpass}}" 37 | policies: "{{username}}" 38 | register: 'vault_userpass_create' 39 | no_log: True 40 | - assert: { that: "vault_userpass_create is changed" } 41 | - assert: { that: "vault_userpass_create.rc == 0" } 42 | 43 | - name: Create user to delete with policy 44 | hashivault_userpass: 45 | name: "delete_{{username}}" 46 | pass: "{{userpass}}" 47 | policies: "{{username}}" 48 | register: 'vault_userpass_create' 49 | no_log: True 50 | - assert: { that: "vault_userpass_create is changed" } 51 | - assert: { that: "vault_userpass_create.rc == 0" } 52 | 53 | - hashivault_userpass: 54 | name: "delete_{{username}}" 55 | state: absent 56 | register: 'vault_userpass_delete' 57 | - assert: { that: "vault_userpass_delete is changed" } 58 | - assert: { that: "vault_userpass_delete.rc == 0" } 59 | 60 | - template: 61 | src: "{{playbook_dir}}/templates/userpassenv.sh.j2" 62 | dest: "{{playbook_dir}}/userpassenv.sh" 63 | mode: 0700 64 | -------------------------------------------------------------------------------- /functional/test_userpass_idempotent.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | username: 'portugal_idempotent' 6 | userpass: 'Th3m@n!!' 7 | tasks: 8 | - name: Enable kv2 secret store 9 | hashivault_userpass: 10 | name: bob 11 | state: absent 12 | no_log: True 13 | 14 | - name: Enable kv2 secret store 15 | hashivault_userpass: 16 | name: bob 17 | pass: S3cre7s 18 | policies: bob 19 | register: hashivault_userpass 20 | no_log: True 21 | - assert: { that: "hashivault_userpass is changed" } 22 | - assert: { that: "hashivault_userpass.rc == 0" } 23 | 24 | - name: Set token_bound_cidr for userpass 25 | hashivault_userpass: 26 | name: "{{username}}" 27 | pass: "{{userpass}}" 28 | policies: "default" 29 | token_bound_cidrs: "127.0.0.1" 30 | register: 'hashivault_userpass_token_bound_cidr' 31 | - assert: { that: "hashivault_userpass_token_bound_cidr is changed" } 32 | - assert: { that: "hashivault_userpass_token_bound_cidr.rc == 0" } 33 | 34 | - name: Set token_bound_cidr for userpass (idempotent) 35 | hashivault_userpass: 36 | name: "{{username}}" 37 | pass: "{{userpass}}" 38 | policies: "default" 39 | token_bound_cidrs: "127.0.0.1" 40 | register: 'hashivault_userpass_token_bound_cidr' 41 | - assert: { that: "hashivault_userpass_token_bound_cidr is not changed" } 42 | - assert: { that: "hashivault_userpass_token_bound_cidr.rc == 0" } 43 | -------------------------------------------------------------------------------- /functional/test_userpass_no_policy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: no 4 | vars: 5 | username: 'bob' 6 | userpass: 'Th3m@n!!' 7 | bobs_rules: > 8 | path "secret/*" { 9 | capabilities = ["create", "read", "update", "delete", "list"] 10 | } 11 | path "auth/token/create*" { 12 | capabilities = ["create", "read", "update", "delete", "list", "sudo"] 13 | } 14 | path "auth/token/lookup*" { 15 | capabilities = ["read", "list"] 16 | } 17 | path "auth/token/lookup/*" { 18 | capabilities = ["read", "list"] 19 | } 20 | path "sys/policy" { 21 | capabilities = ["read"] 22 | } 23 | path "sys/policy/*" { 24 | capabilities = ["create", "read", "update", "delete", "list"] 25 | } 26 | 27 | tasks: 28 | - name: Enable kv2 secret store 29 | hashivault_userpass: 30 | name: "{{username}}" 31 | state: absent 32 | no_log: True 33 | 34 | #- pause: 35 | # prompt: "Make sure org.foo.FooOverload exception is not present" 36 | 37 | - name: Create userpass for bob via POST to omit the policies field 38 | uri: 39 | url: "{{ lookup('env','VAULT_ADDR') }}/v1/auth/userpass/users/{{username}}" 40 | method: POST 41 | return_content: yes 42 | body_format: json 43 | body: 44 | password: "{{userpass}}" 45 | headers: 46 | X-Vault-Token: "{{ lookup('env','VAULT_TOKEN') }}" 47 | status_code: 204 48 | 49 | - name: Update policies 50 | hashivault_userpass: 51 | name: "{{username}}" 52 | password: "" 53 | policies: ["policy-bob", "default"] 54 | register: 'hashivault_userpass_update_policies' 55 | - assert: { that: "hashivault_userpass_update_policies is changed" } 56 | - assert: { that: "hashivault_userpass_update_policies.rc == 0" } 57 | -------------------------------------------------------------------------------- /library: -------------------------------------------------------------------------------- 1 | ansible/modules/hashivault -------------------------------------------------------------------------------- /link.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | DEST=$(echo "${VIRTUAL_ENV}"/lib/python*/site-packages/ansible/) 3 | 4 | rm -rf "$DEST"/modules/hashivault 5 | rm -f "$DEST"/module_utils/hashivault.py 6 | rm -f "$DEST"/plugins/lookup/hashivault.py 7 | rm -f "$DEST"/plugins/doc_fragments/hashivault.py 8 | rm -f "$DEST"/plugins/action/hashivault_read_to_file.py 9 | rm -f "$DEST"/plugins/action/hashivault_write_from_file.py 10 | 11 | ln -s "$PWD"/ansible/modules/hashivault "$DEST"/modules/hashivault 12 | ln "$PWD"/ansible/module_utils/hashivault.py "$DEST"/module_utils/hashivault.py 13 | ln "$PWD"/ansible/plugins/lookup/hashivault.py "$DEST"/plugins/lookup/hashivault.py 14 | ln "$PWD"/ansible/plugins/doc_fragments/hashivault.py "$DEST"/plugins/doc_fragments/hashivault.py 15 | ln "$PWD"/ansible/plugins/action/hashivault_read_to_file.py "$DEST"/plugins/action/hashivault_read_to_file.py 16 | ln "$PWD"/ansible/plugins/action/hashivault_write_from_file.py "$DEST"/plugins/action/hashivault_write_from_file.py 17 | -------------------------------------------------------------------------------- /lookup_plugins: -------------------------------------------------------------------------------- 1 | ansible/plugins/lookup -------------------------------------------------------------------------------- /makedocs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | CHANGES=$(git diff-index --name-only HEAD --) 3 | export PLUGINS='' 4 | rm -rf ansible-repo 5 | mkdir -p ansible-repo 6 | cd ansible-repo 7 | VERSION='v2.9.26' 8 | git clone --branch ${VERSION} https://github.com/ansible/ansible.git 9 | 10 | # Copy 11 | rm -rf ansible/lib/ansible/modules/ 12 | mkdir -p ansible/lib/ansible/modules/hashivault 13 | cp -r ../ansible/modules/hashivault/hashivault*.py ansible/lib/ansible/modules/hashivault/ 14 | rm -f ansible/lib/ansible/plugins/doc_fragments/hashivault.py 15 | cp ../ansible/plugins/doc_fragments/hashivault.py ansible/lib/ansible/plugins/doc_fragments/hashivault.py 16 | ls ansible/lib/ansible/modules/hashivault 17 | export MODULES=$(ls -m ansible/lib/ansible/modules/hashivault/ | grep -v '^_' | tr -d '[:space:]' | sed 's/.py//g') 18 | 19 | # Install 20 | pip install -r ansible/requirements.txt 21 | pip install -r ansible/docs/docsite/requirements.txt 22 | # hacky newer jinja broken 23 | pip install jinja2==3.0.3 24 | 25 | # Build 26 | cd ansible/docs/docsite/ 27 | rm -f $(find . -name developing_modules_general_windows.rst) 28 | set -x 29 | # hacky test build broken 30 | MODULES=$MODULES make config cli keywords modules 31 | # hacky -j $CPUS option not working right on mac 32 | pip install 'Sphinx>=5.1,<6' 33 | sed -i -e 's/AnsibleOutputLexer(startinline=True)/AnsibleOutputPrimaryLexer(startinline=True)/g' _extensions/pygments_lexer.py 34 | sphinx-build -M html "rst" "_build" -n -w rst_warnings 35 | touch _build/html/.nojekyll 36 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Terry Howe 3 | description: Ansible modules for Hashicorp Vault 4 | license: MIT 5 | 6 | min_ansible_version: 2.0 7 | 8 | galaxy_tags: 9 | - hashicorp 10 | - vault 11 | - secrets 12 | - security 13 | 14 | dependencies: [] 15 | -------------------------------------------------------------------------------- /module_utils: -------------------------------------------------------------------------------- 1 | ansible/module_utils -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.rst 3 | 4 | [tool:pytest] 5 | pep8maxlinelength = 120 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import setup 3 | 4 | py_files = [ 5 | "ansible/module_utils/hashivault", 6 | "ansible/plugins/lookup/hashivault", 7 | "ansible/plugins/action/hashivault_read_to_file", 8 | "ansible/plugins/action/hashivault_write_from_file", 9 | "ansible/plugins/doc_fragments/hashivault", 10 | ] 11 | files = [ 12 | "ansible/modules/hashivault", 13 | ] 14 | 15 | long_description = open('README.rst', 'r').read() 16 | 17 | setup( 18 | name='ansible-modules-hashivault', 19 | version='5.3.0', 20 | description='Ansible Modules for Hashicorp Vault', 21 | long_description=long_description, 22 | long_description_content_type='text/x-rst', 23 | author='Terry Howe', 24 | author_email='terrylhowe@example.com', 25 | url='https://github.com/TerryHowe/ansible-modules-hashivault', 26 | py_modules=py_files, 27 | packages=files, 28 | install_requires=[ 29 | 'ansible-core>=2.12.0', 30 | 'hvac>=2.1.0', 31 | 'requests', 32 | ], 33 | ) 34 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | pycodestyle==2.5.0 2 | tox==3.24.2 3 | sphinx 4 | sphinx_rtd_theme 5 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = pep8,py39,docs 3 | 4 | [gh-actions] 5 | python = 6 | 3.9: py39 7 | 8 | [testenv] 9 | install_command = pip install {opts} {packages} 10 | setenv = 11 | OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES 12 | VIRTUAL_ENV={envdir} 13 | allowlist_externals = bash 14 | commands = bash -ex {toxinidir}/functional/run.sh 15 | 16 | [testenv:venv] 17 | commands = {posargs} 18 | 19 | [testenv:pep8] 20 | install_command = pip install {opts} {packages} 21 | setenv = 22 | VIRTUAL_ENV={envdir} 23 | deps = pycodestyle==2.5.0 24 | commands = 25 | pycodestyle --max-line-length=120 --statistics ansible 26 | 27 | [testenv:docs] 28 | setenv = 29 | VIRTUAL_ENV={envdir} 30 | allowlist_externals = bash 31 | commands = bash ./makedocs.sh 32 | -------------------------------------------------------------------------------- /upload.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Make sure you have a ~/.pypirc file first 4 | # 5 | CHANGES=$(git diff-index --name-only HEAD --) 6 | if [ -n "${CHANGES}" ] 7 | then 8 | echo "Changes have not been committed" 9 | exit 1 10 | fi 11 | BRANCH=$(git rev-parse --abbrev-ref HEAD) 12 | if [ "${BRANCH}" != "main" ] 13 | then 14 | echo "You must be on main" 15 | exit 1 16 | fi 17 | git pull 18 | pip install gitchangelog 19 | pip install twine 20 | OLDVERSION=$(grep version setup.py | sed -e "s/.*='//" -e "s/',//") 21 | vi setup.py 22 | VERSION=$(grep version setup.py | sed -e "s/.*='//" -e "s/',//") 23 | if [ "$OLDVERSION" == "$VERSION" ] 24 | then 25 | echo "Old version $OLDVERSION same as $VERSION" 26 | read ANS 27 | fi 28 | git tag -a $VERSION -m v$VERSION 29 | gitchangelog 30 | vi CHANGELOG.rst 31 | echo "Ready to push $VERSION (cntrl-c to quit)?" 32 | read ANS 33 | git commit -m "Version $VERSION" CHANGELOG.rst setup.py 34 | git push origin main 35 | git tag --force -a $VERSION -m v$VERSION 36 | git push origin --tags 37 | #python setup.py register -r pypi 38 | 39 | # old school 40 | # python setup.py sdist upload -r pypi 41 | 42 | # twine 43 | rm -rf dist 44 | python setup.py sdist # bdist_wheel 45 | twine upload dist/* 46 | --------------------------------------------------------------------------------