def hashivault_pki_crl(module): params = module.params client = hashivault_auth_client(params) mount_point = params.get('mount_point').strip('/') desired_state = { 'disable': params.get('disable'), 'expiry': params.get('expiry') } # compare current_state to desired_state from hvac.exceptions import InvalidPath try: current_state = client.secrets.pki.read_crl_configuration( mount_point=mount_point).get('data') changed = is_state_changed(desired_state, current_state) except InvalidPath: changed = True # make the changes! if changed and not module.check_mode: client.secrets.pki.set_crl_configuration(mount_point=mount_point, extra_params=desired_state) return {'changed': changed}
def hashivault_pki_url(module): params = module.params client = hashivault_auth_client(params) mount_point = params.get('mount_point').strip('/') desired_state = { 'issuing_certificates': params.get('issuing_certificates'), 'crl_distribution_points': params.get('crl_distribution_points'), 'ocsp_servers': params.get('ocsp_servers') } # check if config exists changed = False current_state = {} try: current_state = client.secrets.pki.read_urls( mount_point=mount_point).get('data') except Exception: # not configured yet. changed = True # compare current_state to desired_state if not changed: changed = is_state_changed(desired_state, current_state) # make the changes! if changed and not module.check_mode: client.secrets.pki.set_urls(mount_point=mount_point, params=desired_state) return {'changed': changed}
def hashivault_auth_method(module): params = module.params client = hashivault_auth_client(params) method_type = params.get('method_type') description = params.get('description') mount_point = params.get('mount_point') config = params.get('config') if params.get('state') in ['enabled', 'enable']: state = 'enabled' else: state = 'disabled' exists = False changed = False create = False if mount_point is None: mount_point = method_type try: result = client.sys.list_auth_methods() auth_methods = result.get('data', result) if (mount_point + u"/") in auth_methods: exists = True except Exception: pass if state == 'enabled' and not exists: changed = True create = True elif state == 'disabled' and exists: changed = True elif exists and state == 'enabled': current_state = client.sys.read_auth_method_tuning(path=mount_point)['data'] if 'description' in current_state: if description != current_state['description']: changed = True if not changed: changed = is_state_changed(config, current_state) if module.check_mode: return {'changed': changed, 'created': create, 'state': state} if not changed: return {'changed': changed, 'created': False, 'state': state} if state == 'enabled': if create: client.sys.enable_auth_method(method_type, description=description, path=mount_point, config=config) else: client.sys.tune_auth_method(description=description, path=mount_point, **config) if state == 'disabled': client.sys.disable_auth_method(path=mount_point) return {'changed': changed, 'created': create}
def hashivault_secret_engine(module): params = module.params client = hashivault_auth_client(params) name = params.get('name') backend = params.get('backend') description = params.get('description') config = params.get('config') if params.get('state') in ['present', 'enabled']: state = 'enabled' else: state = 'disabled' options = params.get('options') cas_required = params.get('cas_required') max_versions = params.get('max_versions') new_engine_configuration = {} if str(options.get('version', '1')) == '2': if cas_required: new_engine_configuration['cas_required'] = cas_required if max_versions: new_engine_configuration['max_versions'] = max_versions current_state = dict() exists = False created = False changed = False if not backend: backend = name try: # does the mount exist already? configuration = client.sys.read_mount_configuration(path=name) current_state = configuration['data'] exists = True except Exception: # doesn't exist pass # doesnt exist and should or does exist and shouldnt if (exists and state == 'disabled'): changed = True elif (not exists and state == 'enabled'): changed = True elif state == 'enabled': if 'version' in options: options['version'] = str(options['version']) if 'description' in current_state: if description != current_state['description']: changed = True if 'options' in current_state: current_options = current_state['options'] if not changed: changed = is_state_changed(options, current_options) elif options: changed = True for key in config.keys(): if key not in current_state: changed = True elif current_state[key] != config[key]: changed = True if new_engine_configuration and not changed: engine_configuration = client.secrets.kv.read_configuration( name)['data'] if cas_required is not None and engine_configuration.get( 'cas_required', None) != cas_required: changed = True elif max_versions is not None and engine_configuration.get( 'max_versions', None) != max_versions: changed = True else: new_engine_configuration = {} # create if changed and not exists and state == 'enabled' and not module.check_mode: if backend == 'kv': client.sys.enable_secrets_engine(backend, description=description, path=name, config=config, options=options) if new_engine_configuration: client.secrets.kv.v2.configure(mount_point=name, cas_required=cas_required, max_versions=max_versions) else: client.sys.enable_secrets_engine(backend, description=description, path=name, config=config) created = True # update elif changed and exists and state == 'enabled' and not module.check_mode: if backend == 'kv': client.sys.tune_mount_configuration(path=name, description=description, options=options, **config) if new_engine_configuration: client.secrets.kv.v2.configure(mount_point=name, cas_required=cas_required, max_versions=max_versions) else: client.sys.tune_mount_configuration(path=name, description=description, **config) # delete elif changed and state == 'disabled' and not module.check_mode: client.sys.disable_secrets_engine(path=name) return {'changed': changed, 'created': created}
def hashivault_secret(module): params = module.params client = hashivault_auth_client(params) state = params.get('state') version = params.get('version') mount_point = params.get('mount_point') secret = params.get('secret') data = params.get('data') cas = params.get('cas') permanent = params.get('permanent') if mount_point: secret_path = '%s/%s' % (mount_point, secret) else: secret_path = secret result = {"changed": False, "rc": 0} try: if version == 2: read_data = client.secrets.kv.v2.read_secret_version( secret, mount_point=mount_point) read_data = read_data.get('data', {}) else: read_data = client.secrets.kv.v1.read_secret( secret, mount_point=mount_point) read_data = read_data.get('data', {}) except InvalidPath: if state != 'present': result['msg'] = u"Secret %s nonexistent" % secret_path return result read_data = {} except Exception as e: result['rc'] = 1 result['failed'] = True error_string = "%s(%s)" % (e.__class__.__name__, e) result['msg'] = u"Error %s reading %s" % (error_string, secret_path) return result if state == 'present' or state == 'update': if state == 'update': write_data = dict(read_data) write_data.update(data) else: write_data = data changed = is_state_changed(write_data, read_data) # result['write_data'] = write_data # result['read_data'] = read_data if not changed: result['msg'] = u"Secret %s unchanged" % secret_path return result if not module.check_mode: try: if version == 2: client.secrets.kv.v2.create_or_update_secret( mount_point=mount_point, cas=cas, path=secret, secret=write_data) else: client.secrets.kv.v1.create_or_update_secret( mount_point=mount_point, path=secret, secret=write_data) except Exception as e: result['rc'] = 1 result['failed'] = True error_string = "%s(%s)" % (e.__class__.__name__, e) result['msg'] = u"Error %s writing %s" % (error_string, secret_path) return result result['msg'] = u"Secret %s written" % secret_path result['changed'] = True else: try: if version == 2: if permanent: client.secrets.kv.v2.delete_metadata_and_all_versions( secret, mount_point=mount_point) else: client.secrets.kv.v2.delete_latest_version_of_secret( secret, mount_point=mount_point) else: client.secrets.kv.v1.delete_secret(secret, mount_point=mount_point) except InvalidPath: result['msg'] = u"Secret %s nonexistent" % secret_path return result except Exception as e: result['rc'] = 1 result['failed'] = True error_string = "%s(%s)" % (e.__class__.__name__, e) result['msg'] = u"Error %s deleting %s" % (error_string, secret_path) return result result['msg'] = u"Secret %s deleted" % secret_path result['changed'] = True return result
def hashivault_pki_role(module): params = module.params client = hashivault_auth_client(params) name = params.get('name').strip('/') mount_point = params.get('mount_point').strip('/') state = params.get('state') role_file = params.get('role_file') config = params.get('config') desired_state = {} exists = False if role_file: import json desired_state = json.loads(open(role_file, 'r').read()) elif config: import yaml doc = yaml.safe_load(DOCUMENTATION) args = doc.get('options').get('config').get('suboptions').items() for key, value in args: arg = config.get(key) if arg is not None: try: desired_state[key] = normalize[value.get('type')](arg) except Exception: return { 'changed': False, 'failed': True, 'msg': 'config item \'{}\' has wrong data format'.format(key) } changed = False try: current_state = client.secrets.pki.read_role( name=name, mount_point=mount_point).get('data') except Exception: current_state = {} if current_state: exists = True if (exists and state == 'absent') or (not exists and state == 'present'): changed = True # compare current_state to desired_state if exists and state == 'present' and not changed: changed = is_state_changed(desired_state, current_state) # make the changes! if changed and state == 'present' and not module.check_mode: client.secrets.pki.create_or_update_role(name=name, mount_point=mount_point, extra_params=desired_state) elif changed and state == 'absent' and not module.check_mode: client.secrets.pki.delete_role(name=name, mount_point=mount_point) return {'changed': changed}
def hashivault_write(module): result = {"changed": False, "rc": 0} params = module.params client = hashivault_auth_client(params) version = params.get('version') mount_point = params.get('mount_point') secret = params.get('secret') data = params.get('data') data = data or params.get('alternate_data') cas = params.get('cas') if secret.startswith('/'): secret = secret.lstrip('/') mount_point = '' if mount_point: secret_path = '%s/%s' % (mount_point, secret) else: secret_path = secret changed = True write_data = data if params.get('update') or module.check_mode: # Do not move these reads outside of the update read_data = None try: if version == 2: read_data = client.secrets.kv.v2.read_secret_version(secret, mount_point=mount_point) else: read_data = client.secrets.kv.v1.read_secret(secret, mount_point=mount_point) except InvalidPath: read_data = None except Exception as e: result['rc'] = 1 result['failed'] = True error_string = "%s(%s)" % (e.__class__.__name__, e) result['msg'] = u"Error %s reading %s" % (error_string, secret_path) return result if not read_data: read_data = {} read_data = read_data.get('data', {}) if version == 2: read_data = read_data.get('data', {}) write_data = dict(read_data) write_data.update(data) # result['write_data'] = write_data # result['read_data'] = read_data changed = is_state_changed(write_data, read_data) if changed: if not module.check_mode: try: if version == 2: returned_data = client.secrets.kv.v2.create_or_update_secret(mount_point=mount_point, cas=cas, path=secret, secret=write_data) else: returned_data = client.write(secret_path, **write_data) if returned_data: from requests.models import Response if isinstance(returned_data, Response): result['data'] = returned_data.text else: result['data'] = returned_data except Exception as e: result['rc'] = 1 result['failed'] = True error_string = "%s(%s)" % (e.__class__.__name__, e) result['msg'] = u"Error %s writing %s" % (error_string, secret_path) return result result['msg'] = u"Secret %s written" % secret_path result['changed'] = changed return result