def test_configure_secret_backend(self): hvac_client = mock.MagicMock() hvac_client.list_secret_backends.return_value = ['secrets/'] vault.configure_secret_backend(hvac_client, 'test') hvac_client.enable_secret_backend.assert_called_once_with( backend_type='kv', description=mock.ANY, mount_point='test')
def configure_secrets_backend(): """ Process requests for setup and access to simple kv secret backends """ @tenacity.retry(wait=tenacity.wait_exponential(multiplier=1, max=10), stop=tenacity.stop_after_attempt(10), reraise=True) def _check_vault_status(client): if (not service_running('vault') or not client.is_initialized() or client.is_sealed()): return False return True # NOTE: use localhost listener as policy only allows 127.0.0.1 to # administer the local vault instances via the charm client = vault.get_client(url=vault.VAULT_LOCALHOST_URL) status_ok = _check_vault_status(client) if not status_ok: log( 'Unable to process new secret backend requests,' ' deferring until vault is fully configured', level=DEBUG) return charm_role_id = vault.get_local_charm_access_role_id() if charm_role_id is None: log( 'Charm access to vault not configured, deferring' ' secrets backend setup', level=DEBUG) return client.auth_approle(charm_role_id) secrets = (endpoint_from_flag('endpoint.secrets.new-request') or endpoint_from_flag('secrets.connected')) requests = secrets.requests() # Configure KV secret backends backends = set([request['secret_backend'] for request in requests]) for backend in backends: if not backend.startswith('charm-'): continue vault.configure_secret_backend(client, name=backend) refresh_secrets = is_flag_set('secrets.refresh') # Configure AppRoles for application unit access for request in requests: # NOTE: backends must start with charm- backend_name = request['secret_backend'] if not backend_name.startswith('charm-'): continue unit = request['unit'] hostname = request['hostname'] access_address = request['ingress_address'] isolated = request['isolated'] unit_name = request.get('unit_name', unit.unit_name).replace('/', '-') policy_name = approle_name = 'charm-{}'.format(unit_name) if isolated: policy_template = vault.SECRET_BACKEND_HCL else: policy_template = vault.SECRET_BACKEND_SHARED_HCL vault.configure_policy(client, name=policy_name, hcl=policy_template.format(backend=backend_name, hostname=hostname)) cidr = '{}/32'.format(access_address) new_role = (approle_name not in client.list_roles()) approle_id = vault.configure_approle(client, name=approle_name, cidr=cidr, policies=[policy_name]) if new_role or refresh_secrets: wrapped_secret = vault.generate_role_secret_id(client, name=approle_name, cidr=cidr) secrets.set_role_id(unit=unit, role_id=approle_id, token=wrapped_secret) clear_flag('endpoint.secrets.new-request') clear_flag('secrets.refresh')
def test_configure_secret_backend_noop(self): hvac_client = mock.MagicMock() hvac_client.list_secret_backends.return_value = ['secrets/'] vault.configure_secret_backend(hvac_client, 'secrets') hvac_client.enable_secret_backend.assert_not_called()