def test_configure_approle(self):
     hvac_client = mock.MagicMock()
     hvac_client.get_role_id.return_value = 'some-UUID'
     self.assertEqual(
         vault.configure_approle(hvac_client, 'test-role', '10.5.0.20/32',
                                 ['test-policy']), 'some-UUID')
     hvac_client.create_role.assert_called_once_with(
         'test-role',
         token_ttl='60s',
         token_max_ttl='60s',
         policies=['test-policy'],
         bind_secret_id='true',
         bound_cidr_list='10.5.0.20/32')
     hvac_client.get_role_id.assert_called_with('test-role')
示例#2
0
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')