You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ansible/test/integration/targets/ansible-vault/test-vault-client.py

66 lines
1.8 KiB
Python

Vault secrets script client inc new 'keyring' client (#27669) This adds a new type of vault-password script (a 'client') that takes advantage of and enhances the multiple vault password support. If a vault password script basename ends with the name '-client', consider it a vault password script client. A vault password script 'client' just means that the script will take a '--vault-id' command line arg. The previous vault password script (as invoked by --vault-password-file pointing to an executable) takes no args and returns the password on stdout. But it doesnt know anything about --vault-id or multiple vault passwords. The new 'protocol' of the vault password script takes a cli arg ('--vault-id') so that it can lookup that specific vault-id and return it's password. Since existing vault password scripts don't know the new 'protocol', a way to distinguish password scripts that do understand the protocol was needed. The convention now is to consider password scripts that are named like 'something-client.py' (and executable) to be vault password client scripts. The new client scripts get invoked with the '--vault-id' they were requested for. An example: ansible-playbook --vault-id my_vault_id@contrib/vault/vault-keyring-client.py some_playbook.yml That will cause the 'contrib/vault/vault-keyring-client.py' script to be invoked as: contrib/vault/vault-keyring-client.py --vault-id my_vault_id The previous vault-keyring.py password script was extended to become vault-keyring-client.py. It uses the python 'keyring' module to request secrets from various backends. The plain 'vault-keyring.py' script would determine which key id and keyring name to use based on values that had to be set in ansible.cfg. So it was also limited to one keyring name. The new vault-keyring-client.py will request the secret for the vault id provided via the '--vault-id' option. The script can be used without config and can be used for multiple keyring ids (and keyrings). On success, a vault password client script will print the password to stdout and exit with a return code of 0. If the 'client' script can't find a secret for the --vault-id, the script will exit with return code of 2 and print an error to stderr.
7 years ago
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import annotations
Vault secrets script client inc new 'keyring' client (#27669) This adds a new type of vault-password script (a 'client') that takes advantage of and enhances the multiple vault password support. If a vault password script basename ends with the name '-client', consider it a vault password script client. A vault password script 'client' just means that the script will take a '--vault-id' command line arg. The previous vault password script (as invoked by --vault-password-file pointing to an executable) takes no args and returns the password on stdout. But it doesnt know anything about --vault-id or multiple vault passwords. The new 'protocol' of the vault password script takes a cli arg ('--vault-id') so that it can lookup that specific vault-id and return it's password. Since existing vault password scripts don't know the new 'protocol', a way to distinguish password scripts that do understand the protocol was needed. The convention now is to consider password scripts that are named like 'something-client.py' (and executable) to be vault password client scripts. The new client scripts get invoked with the '--vault-id' they were requested for. An example: ansible-playbook --vault-id my_vault_id@contrib/vault/vault-keyring-client.py some_playbook.yml That will cause the 'contrib/vault/vault-keyring-client.py' script to be invoked as: contrib/vault/vault-keyring-client.py --vault-id my_vault_id The previous vault-keyring.py password script was extended to become vault-keyring-client.py. It uses the python 'keyring' module to request secrets from various backends. The plain 'vault-keyring.py' script would determine which key id and keyring name to use based on values that had to be set in ansible.cfg. So it was also limited to one keyring name. The new vault-keyring-client.py will request the secret for the vault id provided via the '--vault-id' option. The script can be used without config and can be used for multiple keyring ids (and keyrings). On success, a vault password client script will print the password to stdout and exit with a return code of 0. If the 'client' script can't find a secret for the --vault-id, the script will exit with return code of 2 and print an error to stderr.
7 years ago
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
import argparse
import sys
# TODO: could read these from the files I suppose...
secrets = {'vault-password': 'test-vault-password',
'vault-password-wrong': 'hunter42',
'vault-password-ansible': 'ansible',
'password': 'password',
'vault-client-password-1': 'password-1',
'vault-client-password-2': 'password-2'}
def build_arg_parser():
parser = argparse.ArgumentParser(description='Get a vault password from user keyring')
parser.add_argument('--vault-id', action='store', default=None,
dest='vault_id',
help='name of the vault secret to get from keyring')
parser.add_argument('--username', action='store', default=None,
help='the username whose keyring is queried')
parser.add_argument('--set', action='store_true', default=False,
dest='set_password',
help='set the password instead of getting it')
return parser
def get_secret(keyname):
return secrets.get(keyname, None)
def main():
rc = 0
arg_parser = build_arg_parser()
args = arg_parser.parse_args()
# print('args: %s' % args)
keyname = args.vault_id or 'ansible'
if args.set_password:
print('--set is not supported yet')
sys.exit(1)
secret = get_secret(keyname)
if secret is None:
sys.stderr.write('test-vault-client could not find key for vault-id="%s"\n' % keyname)
# key not found rc=2
return 2
sys.stdout.write('%s\n' % secret)
return rc
if __name__ == '__main__':
sys.exit(main())