def __init__(self): super(HashiVaultPlugin, self).__init__() self.helper = HashiVaultHelper() self._options_adapter = HashiVaultOptionAdapter.from_ansible_plugin( self) self.connection_options = HashiVaultConnectionOptions( self._options_adapter)
def __init__(self, connection_options, adapter, **kwargs): # taking adapter during transition period self.adapter = adapter self.connection_options = connection_options self.options = kwargs self.helper = HashiVaultHelper() # check early that auth method is actually available self.auth_function = 'auth_' + self.options['auth_method'] if not (hasattr(self, self.auth_function) and callable(getattr(self, self.auth_function))): raise AnsibleError( "Authentication method '%s' is not implemented. ('%s' member function not found)" % (self.options['auth_method'], self.auth_function) ) client_args = self.connection_options.get_hvac_connection_options() self.client = self.helper.get_vault_client(**client_args)
def __init__(self): super(HashiVaultPlugin, self).__init__() self.helper = HashiVaultHelper() self._options_adapter = HashiVaultOptionAdapter.from_ansible_plugin( self) self.connection_options = HashiVaultConnectionOptions( self._options_adapter, self._generate_retry_callback) self.authenticator = HashiVaultAuthenticator(self._options_adapter, display.warning)
def __init__(self, *args, **kwargs): if 'hashi_vault_custom_retry_callback' in kwargs: callback = kwargs.pop('hashi_vault_custom_retry_callback') else: callback = self._generate_retry_callback super(HashiVaultModule, self).__init__(*args, **kwargs) self.helper = HashiVaultHelper() self.adapter = HashiVaultOptionAdapter.from_dict(self.params) self.connection_options = HashiVaultConnectionOptions( option_adapter=self.adapter, retry_callback_generator=callback) self.authenticator = HashiVaultAuthenticator( option_adapter=self.adapter, warning_callback=self.warn)
class HashiVault: # NOTE: the HashiVault class here is in the process of being removed, as functionality moves to shared classes def get_options(self, *option_names, **kwargs): ret = {} include_falsey = kwargs.get('include_falsey', False) for option in option_names: val = self.options.get(option) if val or include_falsey: ret[option] = val return ret def __init__(self, connection_options, adapter, **kwargs): # taking adapter during transition period self.adapter = adapter self.connection_options = connection_options self.options = kwargs self.helper = HashiVaultHelper() # check early that auth method is actually available self.auth_function = 'auth_' + self.options['auth_method'] if not (hasattr(self, self.auth_function) and callable(getattr(self, self.auth_function))): raise AnsibleError( "Authentication method '%s' is not implemented. ('%s' member function not found)" % (self.options['auth_method'], self.auth_function) ) client_args = self.connection_options.get_hvac_connection_options() self.client = self.helper.get_vault_client(**client_args) def authenticate(self): # We've already checked to ensure a method exists for a particular auth_method, of the form: # # auth_<method_name> # # so just call it getattr(self, self.auth_function)() def get(self): '''gets a secret. should always return a list''' secret = self.options['secret'] field = self.options['secret_field'] return_as = self.options['return_format'] try: data = self.client.read(secret) except hvac.exceptions.Forbidden: raise AnsibleError("Forbidden: Permission Denied to secret '%s'." % secret) if data is None: raise AnsibleError("The secret '%s' doesn't seem to exist." % secret) if return_as == 'raw': return [data] # Check response for KV v2 fields and flatten nested secret data. # https://vaultproject.io/api/secret/kv/kv-v2.html#sample-response-1 try: # sentinel field checks check_dd = data['data']['data'] check_md = data['data']['metadata'] # unwrap nested data data = data['data'] except KeyError: pass if return_as == 'values': return list(data['data'].values()) # everything after here implements return_as == 'dict' if not field: return [data['data']] if field not in data['data']: raise AnsibleError("The secret %s does not contain the field '%s'. for hashi_vault lookup" % (secret, field)) return [data['data'][field]] # begin auth implementation methods # # To add new backends, 3 things should be added: # # 1. Add a new validate_auth_<method_name> method to the LookupModule, which is responsible for validating # that it has the necessary options and whatever else it needs. # # 2. Update the avail_auth_methods list in the LookupModule's auth_methods() method (for now this is static). # # 3. Add a new auth_<method_name> method to this class. These implementations are faily minimal as they should # already have everything they need. This is also the place to check for deprecated auth methods as hvac # continues to move backends into the auth_methods class. # # hvac is moving auth methods into the auth_methods class (added in 0.7.0) # which lives in the client.auth member. # https://github.com/hvac/hvac/releases/tag/v0.7.0 # # Attempting to find which backends were moved into the class when (this is primarily for warnings): # 0.7.0 -- github, ldap, mfa, azure?, gcp # 0.7.1 -- okta # 0.8.0 -- kubernetes # 0.9.0 -- azure?, radius # 0.9.3 -- aws # 0.9.6 -- userpass # 0.10.5 -- jwt (new) # 0.10.6 -- approle # def auth_token(self): if self.options['auth_method'] == 'token': self.client.token = self.options.get('token') if self.options.get('token_validate') and not self.client.is_authenticated(): raise AnsibleError("Invalid Hashicorp Vault Token Specified for hashi_vault lookup.") def auth_userpass(self): params = self.get_options('username', 'password', 'mount_point') try: response = self.client.auth.userpass.login(**params) # must manually set the client token with userpass login # see https://github.com/hvac/hvac/issues/644 self.client.token = response['auth']['client_token'] except (NotImplementedError, AttributeError): display.warning("HVAC should be updated to version 0.9.6 or higher. Deprecated method 'auth_userpass' will be used.") self.client.auth_userpass(**params) def auth_ldap(self): params = self.get_options('username', 'password', 'mount_point') try: self.client.auth.ldap.login(**params) except (NotImplementedError, AttributeError): display.warning("HVAC should be updated to version 0.7.0 or higher. Deprecated method 'auth_ldap' will be used.") self.client.auth_ldap(**params) def auth_approle(self): params = self.get_options('role_id', 'secret_id', 'mount_point') try: self.client.auth.approle.login(**params) except (NotImplementedError, AttributeError): display.warning("HVAC should be updated to version 0.10.6 or higher. Deprecated method 'auth_approle' will be used.") self.client.auth_approle(**params) def auth_aws_iam_login(self): params = self.options['_auth_aws_iam_login_params'] try: self.client.auth.aws.iam_login(**params) except (NotImplementedError, AttributeError): display.warning("HVAC should be updated to version 0.9.3 or higher. Deprecated method 'auth_aws_iam' will be used.") self.client.auth_aws_iam(**params) def auth_jwt(self): params = self.get_options('role_id', 'jwt', 'mount_point') params['role'] = params.pop('role_id') if 'mount_point' in params: params['path'] = params.pop('mount_point') try: response = self.client.auth.jwt.jwt_login(**params) # must manually set the client token with JWT login # see https://github.com/hvac/hvac/issues/644 self.client.token = response['auth']['client_token'] except (NotImplementedError, AttributeError): raise AnsibleError("JWT authentication requires HVAC version 0.10.5 or higher.")
def hashi_vault_helper(): return HashiVaultHelper()