diff --git a/awx/main/credential_plugins/hashivault.py b/awx/main/credential_plugins/hashivault.py index c9caafba6b..41213f45cd 100644 --- a/awx/main/credential_plugins/hashivault.py +++ b/awx/main/credential_plugins/hashivault.py @@ -32,14 +32,33 @@ base_inputs = { 'type': 'string', 'multiline': True, 'help_text': _('The CA certificate used to verify the SSL certificate of the Vault server') - }], + }, { + 'id': 'role_id', + 'label': _('AppRole role_id'), + 'type': 'string', + 'multiline': False, + 'help_text': _('The Role ID for AppRole Authentication') + }, { + 'id': 'secret_id', + 'label': _('AppRole secret_id'), + 'type': 'string', + 'multiline': False, + 'secret': True, + 'help_text': _('The Secret ID for AppRole Authentication') + } + ], 'metadata': [{ 'id': 'secret_path', 'label': _('Path to Secret'), 'type': 'string', 'help_text': _('The path to the secret stored in the secret backend e.g, /some/secret/') + },{ + 'id': 'auth_path', + 'label': _('Path to Auth'), + 'type': 'string', + 'help_text': _('The path where the Authentication method is mounted e.g, approle') }], - 'required': ['url', 'token', 'secret_path'], + 'required': ['url', 'secret_path'], } hashi_kv_inputs = copy.deepcopy(base_inputs) @@ -87,9 +106,45 @@ hashi_ssh_inputs['metadata'] = [{ }] hashi_ssh_inputs['required'].extend(['public_key', 'role']) +def handle_auth(**kwargs): + result = None + + if bool(kwargs.get('token')): + result = kwargs['token'] + else: + if bool(kwargs.get('role_id')) and bool(kwargs.get('secret_id')): + result = approle_auth(**kwargs) + else: + raise Exception('Either Vault token or Auth parameters must be set') + + return result + +def approle_auth(**kwargs): + role_id = kwargs['role_id'] + secret_id = kwargs['secret_id'] + auth_path = "approle" + + if bool(kwargs.get('auth_path')): + auth_path = kwargs.get('auth_path', "approle") + + url = urljoin(kwargs['url'], 'v1') + cacert = kwargs.get('cacert', None) + + request_kwargs = {'timeout': 30} + if cacert: + request_kwargs['verify'] = create_temporary_fifo(cacert.encode()) + + # AppRole Login + request_kwargs['json'] = {'role_id': role_id, 'secret_id': secret_id} + sess = requests.Session() + request_url = '/'.join([url, 'auth', auth_path, 'login']).rstrip('/') + resp = sess.post(request_url, **request_kwargs) + resp.raise_for_status() + token = resp.json()['auth']['client_token'] + return token def kv_backend(**kwargs): - token = kwargs['token'] + token = handle_auth(**kwargs) url = kwargs['url'] secret_path = kwargs['secret_path'] secret_backend = kwargs.get('secret_backend', None) @@ -144,7 +199,7 @@ def kv_backend(**kwargs): def ssh_backend(**kwargs): - token = kwargs['token'] + token = handle_auth(**kwargs) url = urljoin(kwargs['url'], 'v1') secret_path = kwargs['secret_path'] role = kwargs['role']