Update hvac library to latest version
Update deprecated method calls where possible, and use new methods instead of lower level read/write calls. Change-Id: I991435cdf8d36016e75c46823ec47f3290a42fe4
This commit is contained in:
parent
4fccd71076
commit
68fecd9ba8
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
*~
|
||||
build/*
|
||||
.tox/*
|
||||
src/.tox/*
|
||||
.stestr/*
|
||||
__pycache__
|
||||
.unit-state.db
|
||||
|
@ -179,8 +179,8 @@ def enable_approle_auth(client):
|
||||
|
||||
:param client: Vault client
|
||||
:type client: hvac.Client"""
|
||||
if 'approle/' not in client.list_auth_backends():
|
||||
client.enable_auth_backend('approle')
|
||||
if 'approle/' not in client.sys.list_auth_methods():
|
||||
client.sys.enable_auth_method('approle')
|
||||
|
||||
|
||||
def create_local_charm_access_role(client, policies):
|
||||
@ -192,14 +192,15 @@ def create_local_charm_access_role(client, policies):
|
||||
:type policies: [str, str, ...]
|
||||
:returns: Id of created role
|
||||
:rtype: str"""
|
||||
client.create_role(
|
||||
client.auth.approle.create_or_update_approle(
|
||||
CHARM_ACCESS_ROLE,
|
||||
token_ttl='60s',
|
||||
token_max_ttl='60s',
|
||||
policies=policies,
|
||||
token_policies=policies,
|
||||
bind_secret_id='false',
|
||||
bound_cidr_list='127.0.0.1/32')
|
||||
return client.get_role_id(CHARM_ACCESS_ROLE)
|
||||
token_bound_cidrs=['127.0.0.1/32'])
|
||||
response = client.auth.approle.read_role_id(CHARM_ACCESS_ROLE)
|
||||
return response["data"]["role_id"]
|
||||
|
||||
|
||||
def setup_charm_vault_access(token=None):
|
||||
@ -216,7 +217,7 @@ def setup_charm_vault_access(token=None):
|
||||
token=token)
|
||||
enable_approle_auth(client)
|
||||
policies = [CHARM_POLICY_NAME]
|
||||
client.set_policy(CHARM_POLICY_NAME, CHARM_POLICY)
|
||||
client.sys.create_or_update_policy(CHARM_POLICY_NAME, CHARM_POLICY)
|
||||
return create_local_charm_access_role(client, policies=policies)
|
||||
|
||||
|
||||
@ -254,8 +255,7 @@ def get_local_client():
|
||||
if not app_role_id:
|
||||
hookenv.log('Could not retrieve app_role_id', level=hookenv.DEBUG)
|
||||
raise VaultNotReady("Cannot initialise local client")
|
||||
client = hvac.Client(url=VAULT_LOCALHOST_URL)
|
||||
client.auth_approle(app_role_id)
|
||||
client.auth.approle.login(app_role_id)
|
||||
return client
|
||||
|
||||
|
||||
@ -312,7 +312,7 @@ def initialize_vault(shares=1, threshold=1):
|
||||
:type threshold: int
|
||||
"""
|
||||
client = get_client(url=VAULT_LOCALHOST_URL)
|
||||
result = client.initialize(shares, threshold)
|
||||
result = client.sys.initialize(shares, threshold)
|
||||
client.token = result['root_token']
|
||||
hookenv.leader_set(
|
||||
root_token=result['root_token'],
|
||||
@ -326,7 +326,7 @@ def unseal_vault(keys=None):
|
||||
if not keys:
|
||||
keys = json.loads(hookenv.leader_get()['keys'])
|
||||
for key in keys:
|
||||
client.unseal(key)
|
||||
client.sys.submit_unseal_key(key)
|
||||
|
||||
|
||||
def can_restart():
|
||||
@ -342,9 +342,9 @@ def can_restart():
|
||||
safe_restart = True
|
||||
else:
|
||||
client = get_client(url=VAULT_LOCALHOST_URL)
|
||||
if not client.is_initialized():
|
||||
if not client.sys.is_initialized():
|
||||
safe_restart = True
|
||||
elif client.is_sealed():
|
||||
elif client.sys.is_sealed():
|
||||
safe_restart = True
|
||||
hookenv.log(
|
||||
"Safe to restart: {}".format(safe_restart),
|
||||
@ -359,11 +359,13 @@ def configure_secret_backend(client, name):
|
||||
:ptype client: hvac.Client
|
||||
:param name: Name of backend to enable
|
||||
:ptype name: str"""
|
||||
if '{}/'.format(name) not in client.list_secret_backends():
|
||||
client.enable_secret_backend(backend_type='kv',
|
||||
description='Charm created KV backend',
|
||||
mount_point=name,
|
||||
options={'version': 1})
|
||||
if '{}/'.format(name) not in client.sys.list_mounted_secrets_engines():
|
||||
client.sys.enable_secrets_engine(
|
||||
backend_type='kv',
|
||||
description='Charm created KV backend',
|
||||
path=name,
|
||||
options={'version': 1}
|
||||
)
|
||||
|
||||
|
||||
def configure_policy(client, name, hcl):
|
||||
@ -375,7 +377,7 @@ def configure_policy(client, name, hcl):
|
||||
:ptype name: str
|
||||
:param hcl: Vault policy HCL
|
||||
:ptype hcl: str"""
|
||||
client.set_policy(name, hcl)
|
||||
client.sys.create_or_update_policy(name, hcl)
|
||||
|
||||
|
||||
def configure_approle(client, name, cidr, policies):
|
||||
@ -391,14 +393,14 @@ def configure_approle(client, name, cidr, policies):
|
||||
:ptype policies: [str, str, ...]
|
||||
:returns: Id of created role
|
||||
:rtype: str"""
|
||||
client.create_role(
|
||||
client.auth.approle.create_or_update_approle(
|
||||
name,
|
||||
token_ttl='60s',
|
||||
token_max_ttl='60s',
|
||||
policies=policies,
|
||||
token_policies=policies,
|
||||
bind_secret_id='true',
|
||||
bound_cidr_list=cidr)
|
||||
return client.get_role_id(name)
|
||||
token_bound_cidrs=[cidr])
|
||||
return client.auth.approle.read_role_id(name)["data"]["role_id"]
|
||||
|
||||
|
||||
def generate_role_secret_id(client, name, cidr):
|
||||
@ -412,6 +414,9 @@ def generate_role_secret_id(client, name, cidr):
|
||||
:ptype cidr: str
|
||||
:returns: Vault token to retrieve the response-wrapped response
|
||||
:rtype: str"""
|
||||
# NOTE: cannot use client.auth.approle.generate_secret_id()
|
||||
# because that doesn't support wrap_ttl
|
||||
# https://github.com/hvac/hvac/issues/683
|
||||
response = client.write('auth/approle/role/{}/secret-id'.format(name),
|
||||
wrap_ttl='1h', cidr_list=cidr)
|
||||
return response['wrap_info']['token']
|
||||
@ -423,7 +428,7 @@ def is_backend_mounted(client, name):
|
||||
:returns: Whether mount point is in use
|
||||
:rtype: bool
|
||||
"""
|
||||
return '{}/'.format(name) in client.list_secret_backends()
|
||||
return '{}/'.format(name) in client.sys.list_mounted_secrets_engines()
|
||||
|
||||
|
||||
def vault_ready_for_clients():
|
||||
@ -433,8 +438,8 @@ def vault_ready_for_clients():
|
||||
reraise=True)
|
||||
def _check_vault_status(client):
|
||||
if (not host.service_running('vault') or
|
||||
not client.is_initialized() or
|
||||
client.is_sealed()):
|
||||
not client.sys.is_initialized() or
|
||||
client.sys.is_sealed()):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -28,10 +28,10 @@ def configure_pki_backend(client, name, ttl=None, max_ttl=None):
|
||||
:type ttl: str
|
||||
"""
|
||||
if not vault.is_backend_mounted(client, name):
|
||||
client.enable_secret_backend(
|
||||
client.sys.enable_secrets_engine(
|
||||
backend_type='pki',
|
||||
description='Charm created PKI backend',
|
||||
mount_point=name,
|
||||
path=name,
|
||||
# Default ttl to 10 years
|
||||
config={
|
||||
'default_lease_ttl': ttl or '8759h',
|
||||
@ -43,12 +43,12 @@ def disable_pki_backend():
|
||||
"""
|
||||
client = vault.get_local_client()
|
||||
if vault.is_backend_mounted(client, CHARM_PKI_MP):
|
||||
client.delete('{}/root'.format(CHARM_PKI_MP))
|
||||
client.delete('{}/roles/{}'.format(CHARM_PKI_MP,
|
||||
CHARM_PKI_ROLE_CLIENT))
|
||||
client.delete('{}/roles/{}'.format(CHARM_PKI_MP,
|
||||
CHARM_PKI_ROLE))
|
||||
client.disable_secret_backend(CHARM_PKI_MP)
|
||||
client.secrets.pki.delete_root(mount_point=CHARM_PKI_MP)
|
||||
client.secrets.pki.delete_role(CHARM_PKI_ROLE_CLIENT,
|
||||
mount_point=CHARM_PKI_MP)
|
||||
client.secrets.pki.delete_role(CHARM_PKI_ROLE,
|
||||
mount_point=CHARM_PKI_MP)
|
||||
client.sys.disable_secrets_engine(CHARM_PKI_MP)
|
||||
|
||||
|
||||
def tune_pki_backend(ttl=None, max_ttl=None):
|
||||
@ -59,9 +59,8 @@ def tune_pki_backend(ttl=None, max_ttl=None):
|
||||
"""
|
||||
client = vault.get_local_client()
|
||||
if vault.is_backend_mounted(client, CHARM_PKI_MP):
|
||||
client.tune_secret_backend(
|
||||
backend_type='pki',
|
||||
mount_point=CHARM_PKI_MP,
|
||||
client.sys.tune_mount_configuration(
|
||||
path=CHARM_PKI_MP,
|
||||
default_lease_ttl=ttl or '8759h',
|
||||
max_lease_ttl=max_ttl or '87600h')
|
||||
|
||||
@ -72,7 +71,7 @@ def is_ca_ready(client, name, role):
|
||||
:returns: Whether CA is ready
|
||||
:rtype: bool
|
||||
"""
|
||||
return client.read('{}/roles/{}'.format(name, role)) is not None
|
||||
return client.secrets.pki.read_role(role, mount_point=name) is not None
|
||||
|
||||
|
||||
def get_chain(name=None):
|
||||
@ -84,7 +83,9 @@ def get_chain(name=None):
|
||||
client = vault.get_local_client()
|
||||
if not name:
|
||||
name = CHARM_PKI_MP
|
||||
return client.read('{}/cert/ca_chain'.format(name))['data']['certificate']
|
||||
response = client.secrets.pki.read_certificate('ca_chain',
|
||||
mount_point=name)
|
||||
return response['data']['certificate']
|
||||
|
||||
|
||||
def get_ca():
|
||||
@ -120,9 +121,7 @@ def generate_certificate(cert_type, common_name, sans, ttl, max_ttl):
|
||||
else:
|
||||
raise vault.VaultInvalidRequest('Unsupported cert_type: '
|
||||
'{}'.format(cert_type))
|
||||
config = {
|
||||
'common_name': common_name,
|
||||
}
|
||||
config = {}
|
||||
if sans:
|
||||
ip_sans, alt_names = sort_sans(sans)
|
||||
if ip_sans:
|
||||
@ -130,8 +129,12 @@ def generate_certificate(cert_type, common_name, sans, ttl, max_ttl):
|
||||
if alt_names:
|
||||
config['alt_names'] = ','.join(alt_names)
|
||||
try:
|
||||
response = client.write('{}/issue/{}'.format(CHARM_PKI_MP, role),
|
||||
**config)
|
||||
response = client.secrets.pki.generate_certificate(
|
||||
role,
|
||||
common_name,
|
||||
extra_params=config,
|
||||
mount_point=CHARM_PKI_MP,
|
||||
)
|
||||
if not response['data']:
|
||||
raise vault.VaultError(response.get('warnings', 'unknown error'))
|
||||
except hvac.exceptions.InvalidRequest as e:
|
||||
@ -168,6 +171,11 @@ def get_csr(ttl=None, common_name=None, locality=None,
|
||||
"""
|
||||
client = vault.get_local_client()
|
||||
configure_pki_backend(client, CHARM_PKI_MP)
|
||||
if common_name is None:
|
||||
common_name = (
|
||||
"Vault Intermediate Certificate Authority "
|
||||
"({})".format(CHARM_PKI_MP)
|
||||
)
|
||||
config = {
|
||||
# Year - 1 hour
|
||||
'ttl': ttl or '87599h',
|
||||
@ -175,14 +183,14 @@ def get_csr(ttl=None, common_name=None, locality=None,
|
||||
'province': province,
|
||||
'ou': organizational_unit,
|
||||
'organization': organization,
|
||||
'common_name': common_name or ("Vault Intermediate Certificate "
|
||||
"Authority " "({})".format(CHARM_PKI_MP)
|
||||
),
|
||||
'locality': locality}
|
||||
config = {k: v for k, v in config.items() if v}
|
||||
csr_info = client.write(
|
||||
'{}/intermediate/generate/internal'.format(CHARM_PKI_MP),
|
||||
**config)
|
||||
csr_info = client.secrets.pki.generate_intermediate(
|
||||
'internal',
|
||||
common_name,
|
||||
extra_params=config,
|
||||
mount_point=CHARM_PKI_MP,
|
||||
)
|
||||
if not csr_info['data']:
|
||||
raise vault.VaultError(csr_info.get('warnings', 'unknown error'))
|
||||
return csr_info['data']['csr']
|
||||
@ -210,17 +218,20 @@ def upload_signed_csr(pem, allowed_domains, allow_subdomains=True,
|
||||
client = vault.get_local_client()
|
||||
# Set the intermediate certificate authorities signing certificate to the
|
||||
# signed certificate.
|
||||
# (hvac module doesn't expose a method for this, hence the _post call)
|
||||
client._post(
|
||||
'v1/{}/intermediate/set-signed'.format(CHARM_PKI_MP),
|
||||
json={'certificate': pem.rstrip()})
|
||||
client.secrets.pki.set_signed_intermediate(
|
||||
pem.rstrip(),
|
||||
mount_point=CHARM_PKI_MP
|
||||
)
|
||||
# Generated certificates can have the CRL location and the location of the
|
||||
# issuing certificate encoded.
|
||||
addr = vault.get_access_address()
|
||||
client.write(
|
||||
'{}/config/urls'.format(CHARM_PKI_MP),
|
||||
issuing_certificates="{}/v1/{}/ca".format(addr, CHARM_PKI_MP),
|
||||
crl_distribution_points="{}/v1/{}/crl".format(addr, CHARM_PKI_MP)
|
||||
client.secrets.pki.set_urls(
|
||||
{
|
||||
"issuing_certificates": "{}/v1/{}/ca".format(addr, CHARM_PKI_MP),
|
||||
"crl_distribution_points":
|
||||
"{}/v1/{}/crl".format(addr, CHARM_PKI_MP),
|
||||
},
|
||||
mount_point=CHARM_PKI_MP
|
||||
)
|
||||
# Configure a role which maps to a policy for accessing this pki
|
||||
if not max_ttl:
|
||||
@ -271,23 +282,28 @@ def generate_root_ca(ttl='87599h', allow_any_name=True, allowed_domains=None,
|
||||
if is_ca_ready(client, CHARM_PKI_MP, CHARM_PKI_ROLE):
|
||||
raise vault.VaultError('PKI CA already configured')
|
||||
config = {
|
||||
'common_name': ("Vault Root Certificate Authority "
|
||||
"({})".format(CHARM_PKI_MP)),
|
||||
'ttl': ttl,
|
||||
}
|
||||
csr_info = client.write(
|
||||
'{}/root/generate/internal'.format(CHARM_PKI_MP),
|
||||
**config)
|
||||
common_name = "Vault Root Certificate Authority ({})".format(CHARM_PKI_MP)
|
||||
csr_info = client.secrets.pki.generate_root(
|
||||
'internal',
|
||||
common_name,
|
||||
extra_params=config,
|
||||
mount_point=CHARM_PKI_MP,
|
||||
)
|
||||
if not csr_info['data']:
|
||||
raise vault.VaultError(csr_info.get('warnings', 'unknown error'))
|
||||
cert = csr_info['data']['certificate']
|
||||
# Generated certificates can have the CRL location and the location of the
|
||||
# issuing certificate encoded.
|
||||
addr = vault.get_access_address()
|
||||
client.write(
|
||||
'{}/config/urls'.format(CHARM_PKI_MP),
|
||||
issuing_certificates="{}/v1/{}/ca".format(addr, CHARM_PKI_MP),
|
||||
crl_distribution_points="{}/v1/{}/crl".format(addr, CHARM_PKI_MP)
|
||||
client.secrets.pki.set_urls(
|
||||
{
|
||||
"issuing_certificates": "{}/v1/{}/ca".format(addr, CHARM_PKI_MP),
|
||||
"crl_distribution_points":
|
||||
"{}/v1/{}/crl".format(addr, CHARM_PKI_MP),
|
||||
},
|
||||
mount_point=CHARM_PKI_MP
|
||||
)
|
||||
|
||||
write_roles(client,
|
||||
@ -318,23 +334,33 @@ def sort_sans(sans):
|
||||
|
||||
def write_roles(client, **kwargs):
|
||||
# Configure a role for using this PKI to issue server certs
|
||||
client.write(
|
||||
'{}/roles/{}'.format(CHARM_PKI_MP, CHARM_PKI_ROLE),
|
||||
server_flag=True,
|
||||
**kwargs)
|
||||
client.secrets.pki.create_or_update_role(
|
||||
CHARM_PKI_ROLE,
|
||||
extra_params={
|
||||
'server_flag': True,
|
||||
**kwargs,
|
||||
},
|
||||
mount_point=CHARM_PKI_MP,
|
||||
)
|
||||
# Configure a role for using this PKI to issue client-only certs
|
||||
client.write(
|
||||
'{}/roles/{}'.format(CHARM_PKI_MP, CHARM_PKI_ROLE_CLIENT),
|
||||
server_flag=False, # client certs cannot be used as server certs
|
||||
**kwargs)
|
||||
client.secrets.pki.create_or_update_role(
|
||||
CHARM_PKI_ROLE_CLIENT,
|
||||
extra_params={
|
||||
# client certs cannot be used as server certs
|
||||
'server_flag': False,
|
||||
**kwargs,
|
||||
},
|
||||
mount_point=CHARM_PKI_MP,
|
||||
)
|
||||
|
||||
|
||||
def update_roles(**kwargs):
|
||||
client = vault.get_local_client()
|
||||
# local and local-client contain the same data except for server_flag,
|
||||
# so we only need to read one, but update both
|
||||
local = client.read(
|
||||
'{}/roles/{}'.format(CHARM_PKI_MP, CHARM_PKI_ROLE))['data']
|
||||
local = client.secrets.pki.read_role(
|
||||
CHARM_PKI_ROLE, mount_point=CHARM_PKI_MP
|
||||
)['data']
|
||||
# the reason we handle as kwargs here is because updating n-1 fields
|
||||
# causes all the others to reset. Therefore we always need to read what
|
||||
# the current values of all fields are, and apply all of them as well
|
||||
|
@ -505,8 +505,8 @@ def configure_secrets_backend():
|
||||
reraise=True)
|
||||
def _check_vault_status(client):
|
||||
if (not service_running('vault') or
|
||||
not client.is_initialized() or
|
||||
client.is_sealed()):
|
||||
not client.sys.is_initialized() or
|
||||
client.sys.is_sealed()):
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -525,7 +525,7 @@ def configure_secrets_backend():
|
||||
log('Charm access to vault not configured, deferring'
|
||||
' secrets backend setup', level=DEBUG)
|
||||
return
|
||||
client.auth_approle(charm_role_id)
|
||||
client.auth.approle.login(charm_role_id)
|
||||
|
||||
secrets = (endpoint_from_flag('endpoint.secrets.new-request') or
|
||||
endpoint_from_flag('secrets.connected'))
|
||||
@ -568,7 +568,7 @@ def configure_secrets_backend():
|
||||
)
|
||||
|
||||
cidr = '{}/32'.format(access_address)
|
||||
new_role = (approle_name not in client.list_roles())
|
||||
new_role = (approle_name not in client.auth.approle.list_roles())
|
||||
|
||||
approle_id = vault.configure_approle(
|
||||
client,
|
||||
@ -965,7 +965,7 @@ def publish_ca_info():
|
||||
return
|
||||
client = vault.get_client(url=vault.VAULT_LOCALHOST_URL)
|
||||
tls = endpoint_from_flag('certificates.available')
|
||||
if client.is_sealed():
|
||||
if client.sys.is_sealed():
|
||||
log("Unable to publish ca info, service sealed.")
|
||||
else:
|
||||
tls.set_ca(vault_pki.get_ca())
|
||||
@ -1165,7 +1165,7 @@ def tune_pki_backend_config_changed():
|
||||
set_flag('failed.to.start')
|
||||
return
|
||||
client = vault.get_client(url=vault.VAULT_LOCALHOST_URL)
|
||||
if client.is_sealed():
|
||||
if client.sys.is_sealed():
|
||||
log("Unable to tune pki backend, service sealed.")
|
||||
else:
|
||||
ttl = config()['default-ttl']
|
||||
|
@ -1,5 +1,5 @@
|
||||
netifaces
|
||||
hvac<0.7.0
|
||||
hvac<0.12.0
|
||||
# for xenial support, tenacity 8.0.0+ drops support for py35
|
||||
tenacity<8.0.0
|
||||
pbr
|
||||
|
@ -50,5 +50,5 @@ tenacity # vault
|
||||
pbr==5.6.0 # vault
|
||||
cryptography<3.4 # vault, keystone-saml-mellon
|
||||
lxml # keystone-saml-mellon
|
||||
hvac # vault, barbican-vault
|
||||
hvac<0.12.0 # vault, barbican-vault
|
||||
psutil # cinder-lvm
|
||||
|
@ -25,9 +25,9 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
|
||||
def test_enable_approle_auth(self):
|
||||
client_mock = mock.MagicMock()
|
||||
client_mock.list_auth_backends.return_value = []
|
||||
client_mock.sys.list_auth_methods.return_value = []
|
||||
vault.enable_approle_auth(client_mock)
|
||||
client_mock.enable_auth_backend.assert_called_once_with('approle')
|
||||
client_mock.sys.enable_auth_method.assert_called_once_with('approle')
|
||||
|
||||
def test_enable_approle_auth_mounted(self):
|
||||
client_mock = mock.MagicMock()
|
||||
@ -37,17 +37,19 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
|
||||
def test_create_local_charm_access_role(self):
|
||||
client_mock = mock.MagicMock()
|
||||
client_mock.get_role_id.return_value = '123'
|
||||
client_mock.auth.approle.read_role_id.return_value = {
|
||||
'data': {'role_id': '123'}}
|
||||
policies = ['policy1', 'pilicy2']
|
||||
role_id = vault.create_local_charm_access_role(client_mock, policies)
|
||||
self.assertEqual(role_id, '123')
|
||||
client_mock.create_role.assert_called_once_with(
|
||||
'local-charm-access',
|
||||
bind_secret_id='false',
|
||||
bound_cidr_list='127.0.0.1/32',
|
||||
policies=['policy1', 'pilicy2'],
|
||||
token_max_ttl='60s',
|
||||
token_ttl='60s')
|
||||
client_mock.auth.approle.create_or_update_approle.\
|
||||
assert_called_once_with(
|
||||
'local-charm-access',
|
||||
bind_secret_id='false',
|
||||
token_bound_cidrs=['127.0.0.1/32'],
|
||||
token_policies=['policy1', 'pilicy2'],
|
||||
token_max_ttl='60s',
|
||||
token_ttl='60s')
|
||||
|
||||
@patch.object(vault.hvac, 'Client')
|
||||
@patch.object(vault, 'get_api_url')
|
||||
@ -64,7 +66,7 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
mock_enable_approle_auth.assert_called_once_with(client_mock)
|
||||
policy_calls = [
|
||||
mock.call('local-charm-policy', mock.ANY)]
|
||||
client_mock.set_policy.assert_has_calls(policy_calls)
|
||||
client_mock.sys.create_or_update_policy.assert_has_calls(policy_calls)
|
||||
mock_create_local_charm_access_role.assert_called_once_with(
|
||||
client_mock,
|
||||
policies=['local-charm-policy'])
|
||||
@ -164,10 +166,10 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
config.return_value = False
|
||||
service_running.return_value = True
|
||||
hvac_mock = mock.MagicMock()
|
||||
hvac_mock.is_initialized.return_value = False
|
||||
hvac_mock.sys.is_initialized.return_value = False
|
||||
get_client.return_value = hvac_mock
|
||||
self.assertTrue(vault.can_restart())
|
||||
hvac_mock.is_initialized.assert_called_once_with()
|
||||
hvac_mock.sys.is_initialized.assert_called_once_with()
|
||||
|
||||
@patch.object(vault.host, 'service_running')
|
||||
@patch.object(vault.hookenv, 'config')
|
||||
@ -176,12 +178,12 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
config.return_value = False
|
||||
service_running.return_value = True
|
||||
hvac_mock = mock.MagicMock()
|
||||
hvac_mock.is_initialized.return_value = True
|
||||
hvac_mock.is_sealed.return_value = True
|
||||
hvac_mock.sys.is_initialized.return_value = True
|
||||
hvac_mock.sys.is_sealed.return_value = True
|
||||
get_client.return_value = hvac_mock
|
||||
self.assertTrue(vault.can_restart())
|
||||
hvac_mock.is_initialized.assert_called_once_with()
|
||||
hvac_mock.is_sealed.assert_called_once_with()
|
||||
hvac_mock.sys.is_initialized.assert_called_once_with()
|
||||
hvac_mock.sys.is_sealed.assert_called_once_with()
|
||||
|
||||
@patch.object(vault.host, 'service_running')
|
||||
@patch.object(vault.hookenv, 'config')
|
||||
@ -190,8 +192,8 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
config.return_value = False
|
||||
service_running.return_value = True
|
||||
hvac_mock = mock.MagicMock()
|
||||
hvac_mock.is_initialized.return_value = True
|
||||
hvac_mock.is_sealed.return_value = False
|
||||
hvac_mock.sys.is_initialized.return_value = True
|
||||
hvac_mock.sys.is_sealed.return_value = False
|
||||
get_client.return_value = hvac_mock
|
||||
self.assertFalse(vault.can_restart())
|
||||
|
||||
@ -328,15 +330,15 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
@patch.object(vault, 'get_client')
|
||||
def test_initialize_vault(self, get_client, leader_set):
|
||||
hvac_mock = mock.MagicMock()
|
||||
hvac_mock.is_initialized.return_value = True
|
||||
hvac_mock.initialize.return_value = {
|
||||
hvac_mock.sys.is_initialized.return_value = True
|
||||
hvac_mock.sys.initialize.return_value = {
|
||||
'keys': ['c579a143d55423483b9076ea7bba49b63ae432bf74729f77afb4e'],
|
||||
'keys_base64': ['xX35oUPVVCNIO5B26nu6SbY65DK/dHKfd6+05y1Afcw='],
|
||||
'root_token': 'dee94df7-23a3-9bf2-cb96-e943537c2b76'
|
||||
}
|
||||
get_client.return_value = hvac_mock
|
||||
vault.initialize_vault()
|
||||
hvac_mock.initialize.assert_called_once_with(1, 1)
|
||||
hvac_mock.sys.initialize.assert_called_once_with(1, 1)
|
||||
leader_set.assert_called_once_with(
|
||||
keys='["c579a143d55423483b9076ea7bba49b63ae432bf74729f77afb4e"]',
|
||||
root_token='dee94df7-23a3-9bf2-cb96-e943537c2b76')
|
||||
@ -351,7 +353,7 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
'keys': '["c579a143d55423483b9076ea7bba49b63ae432bf74729f77afb4e"]'
|
||||
}
|
||||
vault.unseal_vault()
|
||||
hvac_mock.unseal.assert_called_once_with(
|
||||
hvac_mock.sys.submit_unseal_key.assert_called_once_with(
|
||||
'c579a143d55423483b9076ea7bba49b63ae432bf74729f77afb4e')
|
||||
|
||||
@patch.object(vault.hookenv, 'log')
|
||||
@ -373,12 +375,13 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
|
||||
def test_configure_secret_backend(self):
|
||||
hvac_client = mock.MagicMock()
|
||||
hvac_client.list_secret_backends.return_value = ['secrets/']
|
||||
hvac_client.sys.list_mounted_secrets_engines.return_value = [
|
||||
'secrets/']
|
||||
vault.configure_secret_backend(hvac_client, 'test')
|
||||
hvac_client.enable_secret_backend.assert_called_once_with(
|
||||
hvac_client.sys.enable_secrets_engine.assert_called_once_with(
|
||||
backend_type='kv',
|
||||
description=mock.ANY,
|
||||
mount_point='test',
|
||||
path='test',
|
||||
options={'version': 1})
|
||||
|
||||
def test_configure_secret_backend_noop(self):
|
||||
@ -404,14 +407,15 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
def test_configure_policy(self):
|
||||
hvac_client = mock.MagicMock()
|
||||
vault.configure_policy(hvac_client, 'test-policy', 'test-hcl')
|
||||
hvac_client.set_policy.assert_called_once_with(
|
||||
hvac_client.sys.create_or_update_policy.assert_called_once_with(
|
||||
'test-policy',
|
||||
'test-hcl',
|
||||
)
|
||||
|
||||
def test_configure_approle(self):
|
||||
hvac_client = mock.MagicMock()
|
||||
hvac_client.get_role_id.return_value = 'some-UUID'
|
||||
hvac_client.auth.approle.read_role_id.return_value = {
|
||||
'data': {'role_id': 'some-UUID'}}
|
||||
self.assertEqual(
|
||||
vault.configure_approle(hvac_client,
|
||||
'test-role',
|
||||
@ -419,12 +423,34 @@ class TestLibCharmVault(unit_tests.test_utils.CharmTestCase):
|
||||
['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')
|
||||
hvac_client.auth.approle.create_or_update_approle.\
|
||||
assert_called_once_with(
|
||||
'test-role',
|
||||
token_ttl='60s',
|
||||
token_max_ttl='60s',
|
||||
token_policies=['test-policy'],
|
||||
bind_secret_id='true',
|
||||
token_bound_cidrs=['10.5.0.20/32']
|
||||
)
|
||||
hvac_client.auth.approle.read_role_id.assert_called_with('test-role')
|
||||
|
||||
@patch.object(vault.hookenv, 'leader_get')
|
||||
@patch.object(vault, 'get_client')
|
||||
def test_get_local_client(self, get_client, mock_leader_get):
|
||||
leader_db = {'local-charm-access-id': '12'}
|
||||
mock_leader_get.side_effect = lambda x: leader_db[x]
|
||||
hvac_client = mock.MagicMock()
|
||||
get_client.return_value = hvac_client
|
||||
client = vault.get_local_client()
|
||||
self.assertEqual(client, hvac_client)
|
||||
hvac_client.auth.approle.login.assert_called_once_with('12')
|
||||
|
||||
@patch.object(vault.hookenv, 'leader_get')
|
||||
@patch.object(vault, 'get_client')
|
||||
def test_get_local_client_not_ready(self, get_client, mock_leader_get):
|
||||
leader_db = {'local-charm-access-id': None}
|
||||
mock_leader_get.side_effect = lambda x: leader_db[x]
|
||||
hvac_client = mock.MagicMock()
|
||||
get_client.return_value = hvac_client
|
||||
with self.assertRaises(vault.VaultNotReady):
|
||||
vault.get_local_client()
|
||||
|
@ -24,13 +24,13 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
client_mock,
|
||||
'my_backend',
|
||||
ttl=42, max_ttl=42)
|
||||
client_mock.enable_secret_backend.assert_called_once_with(
|
||||
client_mock.sys.enable_secrets_engine.assert_called_once_with(
|
||||
backend_type='pki',
|
||||
config={
|
||||
'default_lease_ttl': 42,
|
||||
'max_lease_ttl': 42},
|
||||
description='Charm created PKI backend',
|
||||
mount_point='my_backend')
|
||||
path='my_backend')
|
||||
|
||||
@patch.object(vault_pki.vault, 'is_backend_mounted')
|
||||
def test_configure_pki_backend_default_ttl(self, is_backend_mounted):
|
||||
@ -39,13 +39,13 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
vault_pki.configure_pki_backend(
|
||||
client_mock,
|
||||
'my_backend')
|
||||
client_mock.enable_secret_backend.assert_called_once_with(
|
||||
client_mock.sys.enable_secrets_engine.assert_called_once_with(
|
||||
backend_type='pki',
|
||||
config={
|
||||
'default_lease_ttl': '8759h',
|
||||
'max_lease_ttl': '87600h'},
|
||||
description='Charm created PKI backend',
|
||||
mount_point='my_backend')
|
||||
path='my_backend')
|
||||
|
||||
@patch.object(vault_pki.vault, 'is_backend_mounted')
|
||||
def test_configure_pki_backend_noop(self, is_backend_mounted):
|
||||
@ -59,34 +59,42 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
|
||||
def test_is_ca_ready(self):
|
||||
client_mock = mock.MagicMock()
|
||||
vault_pki.is_ca_ready(client_mock, 'my_backend', 'local')
|
||||
client_mock.read.assert_called_once_with('my_backend/roles/local')
|
||||
|
||||
def read_role(role, mount_point=None):
|
||||
if role == "role":
|
||||
return "role info"
|
||||
|
||||
client_mock.secrets.pki.read_role.side_effect = read_role
|
||||
self.assertTrue(vault_pki.is_ca_ready(client_mock, 'mp', 'role'))
|
||||
self.assertFalse(
|
||||
vault_pki.is_ca_ready(client_mock, 'mp', 'doesnotexist')
|
||||
)
|
||||
|
||||
@patch.object(vault_pki.vault, 'get_local_client')
|
||||
def test_get_chain(self, get_local_client):
|
||||
client_mock = mock.MagicMock()
|
||||
client_mock.read.return_value = {
|
||||
client_mock.secrets.pki.read_certificate.return_value = {
|
||||
'data': {
|
||||
'certificate': 'somecert'}}
|
||||
get_local_client.return_value = client_mock
|
||||
self.assertEqual(
|
||||
vault_pki.get_chain('my_backend'),
|
||||
'somecert')
|
||||
client_mock.read.assert_called_once_with(
|
||||
'my_backend/cert/ca_chain')
|
||||
client_mock.secrets.pki.read_certificate.assert_called_once_with(
|
||||
'ca_chain', mount_point='my_backend')
|
||||
|
||||
@patch.object(vault_pki.vault, 'get_local_client')
|
||||
def test_get_chain_default_pki(self, get_local_client):
|
||||
client_mock = mock.MagicMock()
|
||||
client_mock.read.return_value = {
|
||||
client_mock.secrets.pki.read_certificate.return_value = {
|
||||
'data': {
|
||||
'certificate': 'somecert'}}
|
||||
get_local_client.return_value = client_mock
|
||||
self.assertEqual(
|
||||
vault_pki.get_chain(),
|
||||
'somecert')
|
||||
client_mock.read.assert_called_once_with(
|
||||
'charm-pki-local/cert/ca_chain')
|
||||
client_mock.secrets.pki.read_certificate.assert_called_once_with(
|
||||
'ca_chain', mount_point=vault_pki.CHARM_PKI_MP)
|
||||
|
||||
@patch.object(vault_pki.hookenv, 'leader_get')
|
||||
def test_get_ca(self, leader_get):
|
||||
@ -102,28 +110,11 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
is_ca_ready,
|
||||
sort_sans):
|
||||
client_mock = mock.MagicMock()
|
||||
client_mock.write.return_value = {'data': 'data'}
|
||||
client_mock.secrets.pki.generate_certificate.return_value = {
|
||||
'data': 'data'}
|
||||
get_local_client.return_value = client_mock
|
||||
is_ca_ready.return_value = True
|
||||
sort_sans.side_effect = lambda l: (l[0], l[1])
|
||||
write_calls = [
|
||||
mock.call(
|
||||
'charm-pki-local/issue/local',
|
||||
common_name='example.com',
|
||||
),
|
||||
mock.call(
|
||||
'charm-pki-local/issue/local',
|
||||
common_name='example.com',
|
||||
ip_sans='ip1',
|
||||
alt_names='alt1',
|
||||
),
|
||||
mock.call(
|
||||
'charm-pki-local/issue/local-client',
|
||||
common_name='example.com',
|
||||
ip_sans='ip1,ip2',
|
||||
alt_names='alt1,alt2',
|
||||
),
|
||||
]
|
||||
vault_pki.generate_certificate('server',
|
||||
'example.com',
|
||||
([], []),
|
||||
@ -136,7 +127,29 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
'example.com',
|
||||
(['ip1', 'ip2'], ['alt1', 'alt2']),
|
||||
ttl='3456h', max_ttl='3456h')
|
||||
client_mock.write.assert_has_calls(write_calls)
|
||||
client_mock.secrets.pki.generate_certificate.assert_has_calls([
|
||||
mock.call(
|
||||
vault_pki.CHARM_PKI_ROLE, 'example.com',
|
||||
mount_point=vault_pki.CHARM_PKI_MP,
|
||||
extra_params={},
|
||||
),
|
||||
mock.call(
|
||||
vault_pki.CHARM_PKI_ROLE, 'example.com',
|
||||
mount_point=vault_pki.CHARM_PKI_MP,
|
||||
extra_params={
|
||||
'ip_sans': 'ip1',
|
||||
'alt_names': 'alt1',
|
||||
}
|
||||
),
|
||||
mock.call(
|
||||
vault_pki.CHARM_PKI_ROLE_CLIENT, 'example.com',
|
||||
mount_point=vault_pki.CHARM_PKI_MP,
|
||||
extra_params={
|
||||
'ip_sans': 'ip1,ip2',
|
||||
'alt_names': 'alt1,alt2',
|
||||
}
|
||||
),
|
||||
])
|
||||
|
||||
@patch.object(vault_pki, 'is_ca_ready')
|
||||
@patch.object(vault_pki, 'configure_pki_backend')
|
||||
@ -173,7 +186,9 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
client_mock = mock.MagicMock()
|
||||
get_local_client.return_value = client_mock
|
||||
is_ca_ready.return_value = True
|
||||
client_mock.write.side_effect = hvac.exceptions.InvalidRequest
|
||||
client_mock.secrets.pki.generate_certificate.side_effect = (
|
||||
hvac.exceptions.InvalidRequest
|
||||
)
|
||||
with self.assertRaises(vault_pki.vault.VaultInvalidRequest):
|
||||
vault_pki.generate_certificate('server', 'example.com', [],
|
||||
ttl='3456h', max_ttl='3456h')
|
||||
@ -183,24 +198,23 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
def test_get_csr(self, get_local_client, configure_pki_backend):
|
||||
client_mock = mock.MagicMock()
|
||||
get_local_client.return_value = client_mock
|
||||
client_mock.write.return_value = {
|
||||
client_mock.secrets.pki.generate_intermediate.return_value = {
|
||||
'data': {
|
||||
'csr': 'somecert'}}
|
||||
self.assertEqual(vault_pki.get_csr(), 'somecert')
|
||||
client_mock.write.assert_called_once_with(
|
||||
'charm-pki-local/intermediate/generate/internal',
|
||||
common_name=('Vault Intermediate Certificate Authority'
|
||||
' (charm-pki-local)'),
|
||||
ttl='87599h')
|
||||
client_mock.secrets.pki.generate_intermediate.assert_called_once_with(
|
||||
'internal',
|
||||
'Vault Intermediate Certificate Authority (charm-pki-local)',
|
||||
extra_params={'ttl': '87599h'},
|
||||
mount_point=vault_pki.CHARM_PKI_MP)
|
||||
|
||||
@patch.object(vault_pki, 'configure_pki_backend')
|
||||
@patch.object(vault_pki.vault, 'get_local_client')
|
||||
def test_get_csr_explicit(self, get_local_client, configure_pki_backend):
|
||||
client_mock = mock.MagicMock()
|
||||
get_local_client.return_value = client_mock
|
||||
client_mock.write.return_value = {
|
||||
'data': {
|
||||
'csr': 'somecert'}}
|
||||
client_mock.secrets.pki.generate_intermediate.return_value = {
|
||||
'data': {'csr': 'somecert'}}
|
||||
self.assertEqual(
|
||||
vault_pki.get_csr(
|
||||
ttl='2h',
|
||||
@ -210,16 +224,19 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
organizational_unit='My Department',
|
||||
organization='My Company'),
|
||||
'somecert')
|
||||
client_mock.write.assert_called_once_with(
|
||||
'charm-pki-local/intermediate/generate/internal',
|
||||
common_name=('Vault Intermediate Certificate Authority '
|
||||
'(charm-pki-local)'),
|
||||
country='GB',
|
||||
locality='here',
|
||||
organization='My Company',
|
||||
ou='My Department',
|
||||
province='Kent',
|
||||
ttl='2h')
|
||||
client_mock.secrets.pki.generate_intermediate.assert_called_once_with(
|
||||
'internal',
|
||||
'Vault Intermediate Certificate Authority (charm-pki-local)',
|
||||
extra_params=dict(
|
||||
country='GB',
|
||||
locality='here',
|
||||
organization='My Company',
|
||||
ou='My Department',
|
||||
province='Kent',
|
||||
ttl='2h'
|
||||
),
|
||||
mount_point=vault_pki.CHARM_PKI_MP
|
||||
)
|
||||
|
||||
@patch.object(vault_pki.vault, 'get_access_address')
|
||||
@patch.object(vault_pki.vault, 'get_local_client')
|
||||
@ -227,36 +244,11 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
get_access_address.return_value = 'https://vault.local:8200'
|
||||
client_mock = mock.MagicMock()
|
||||
get_local_client.return_value = client_mock
|
||||
local_url = 'https://vault.local:8200/v1/charm-pki-local'
|
||||
write_calls = [
|
||||
mock.call(
|
||||
'charm-pki-local/config/urls',
|
||||
issuing_certificates='{}/ca'.format(local_url),
|
||||
crl_distribution_points='{}/crl'.format(local_url)),
|
||||
mock.call(
|
||||
'charm-pki-local/roles/local',
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=True,
|
||||
enforce_hostnames=False,
|
||||
allow_any_name=True,
|
||||
max_ttl='87598h',
|
||||
server_flag=True,
|
||||
client_flag=True),
|
||||
mock.call(
|
||||
'charm-pki-local/roles/local-client',
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=True,
|
||||
enforce_hostnames=False,
|
||||
allow_any_name=True,
|
||||
max_ttl='87598h',
|
||||
server_flag=False,
|
||||
client_flag=True),
|
||||
]
|
||||
vault_pki.upload_signed_csr('MYPEM', 'example.com')
|
||||
client_mock._post.assert_called_once_with(
|
||||
'v1/charm-pki-local/intermediate/set-signed',
|
||||
json={'certificate': 'MYPEM'})
|
||||
client_mock.write.assert_has_calls(write_calls)
|
||||
client_mock.secrets.pki.set_signed_intermediate.\
|
||||
assert_called_once_with(
|
||||
'MYPEM', mount_point=vault_pki.CHARM_PKI_MP
|
||||
)
|
||||
|
||||
@patch.object(vault_pki.vault, 'get_access_address')
|
||||
@patch.object(vault_pki.vault, 'get_local_client')
|
||||
@ -267,35 +259,43 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
client_mock = mock.MagicMock()
|
||||
get_local_client.return_value = client_mock
|
||||
local_url = 'https://127.0.0.1:8200/v1/charm-pki-local'
|
||||
write_calls = [
|
||||
mock.call(
|
||||
'charm-pki-local/config/urls',
|
||||
issuing_certificates='{}/ca'.format(local_url),
|
||||
crl_distribution_points='{}/crl'.format(local_url)),
|
||||
mock.call(
|
||||
'charm-pki-local/roles/local',
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=True,
|
||||
enforce_hostnames=False,
|
||||
allow_any_name=True,
|
||||
max_ttl='87598h',
|
||||
server_flag=True,
|
||||
client_flag=True),
|
||||
mock.call(
|
||||
'charm-pki-local/roles/local-client',
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=True,
|
||||
enforce_hostnames=False,
|
||||
allow_any_name=True,
|
||||
max_ttl='87598h',
|
||||
server_flag=False,
|
||||
client_flag=True),
|
||||
]
|
||||
vault_pki.upload_signed_csr('MYPEM', 'example.com')
|
||||
client_mock._post.assert_called_once_with(
|
||||
'v1/charm-pki-local/intermediate/set-signed',
|
||||
json={'certificate': 'MYPEM'})
|
||||
client_mock.write.assert_has_calls(write_calls)
|
||||
client_mock.secrets.pki.set_signed_intermediate.\
|
||||
assert_called_once_with(
|
||||
'MYPEM', mount_point=vault_pki.CHARM_PKI_MP
|
||||
)
|
||||
client_mock.secrets.pki.set_urls.assert_called_once_with({
|
||||
'issuing_certificates': '{}/ca'.format(local_url),
|
||||
'crl_distribution_points': '{}/crl'.format(local_url),
|
||||
}, mount_point=vault_pki.CHARM_PKI_MP)
|
||||
client_mock.secrets.pki.create_or_update_role.assert_has_calls([
|
||||
mock.call(
|
||||
vault_pki.CHARM_PKI_ROLE,
|
||||
extra_params=dict(
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=True,
|
||||
enforce_hostnames=False,
|
||||
allow_any_name=True,
|
||||
max_ttl='87598h',
|
||||
server_flag=True,
|
||||
client_flag=True,
|
||||
),
|
||||
mount_point=vault_pki.CHARM_PKI_MP,
|
||||
),
|
||||
mock.call(
|
||||
vault_pki.CHARM_PKI_ROLE_CLIENT,
|
||||
extra_params=dict(
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=True,
|
||||
enforce_hostnames=False,
|
||||
allow_any_name=True,
|
||||
max_ttl='87598h',
|
||||
server_flag=False,
|
||||
client_flag=True,
|
||||
),
|
||||
mount_point=vault_pki.CHARM_PKI_MP,
|
||||
),
|
||||
])
|
||||
|
||||
@patch.object(vault_pki.vault, 'get_access_address')
|
||||
@patch.object(vault_pki.vault, 'get_local_client')
|
||||
@ -305,36 +305,11 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
get_access_address.return_value = 'https://[::1]:8200'
|
||||
client_mock = mock.MagicMock()
|
||||
get_local_client.return_value = client_mock
|
||||
local_url = 'https://[::1]:8200/v1/charm-pki-local'
|
||||
write_calls = [
|
||||
mock.call(
|
||||
'charm-pki-local/config/urls',
|
||||
issuing_certificates='{}/ca'.format(local_url),
|
||||
crl_distribution_points='{}/crl'.format(local_url)),
|
||||
mock.call(
|
||||
'charm-pki-local/roles/local',
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=True,
|
||||
enforce_hostnames=False,
|
||||
allow_any_name=True,
|
||||
max_ttl='87598h',
|
||||
server_flag=True,
|
||||
client_flag=True),
|
||||
mock.call(
|
||||
'charm-pki-local/roles/local-client',
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=True,
|
||||
enforce_hostnames=False,
|
||||
allow_any_name=True,
|
||||
max_ttl='87598h',
|
||||
server_flag=False,
|
||||
client_flag=True),
|
||||
]
|
||||
vault_pki.upload_signed_csr('MYPEM', 'example.com')
|
||||
client_mock._post.assert_called_once_with(
|
||||
'v1/charm-pki-local/intermediate/set-signed',
|
||||
json={'certificate': 'MYPEM'})
|
||||
client_mock.write.assert_has_calls(write_calls)
|
||||
client_mock.secrets.pki.set_signed_intermediate.\
|
||||
assert_called_once_with(
|
||||
'MYPEM', mount_point=vault_pki.CHARM_PKI_MP
|
||||
)
|
||||
|
||||
@patch.object(vault_pki.vault, 'get_access_address')
|
||||
@patch.object(vault_pki.vault, 'get_local_client')
|
||||
@ -344,30 +319,6 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
get_access_address.return_value = 'https://vault.local:8200'
|
||||
get_local_client.return_value = client_mock
|
||||
local_url = 'https://vault.local:8200/v1/charm-pki-local'
|
||||
write_calls = [
|
||||
mock.call(
|
||||
'charm-pki-local/config/urls',
|
||||
issuing_certificates='{}/ca'.format(local_url),
|
||||
crl_distribution_points='{}/crl'.format(local_url)),
|
||||
mock.call(
|
||||
'charm-pki-local/roles/local',
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=False,
|
||||
enforce_hostnames=True,
|
||||
allow_any_name=False,
|
||||
max_ttl='42h',
|
||||
server_flag=True,
|
||||
client_flag=True),
|
||||
mock.call(
|
||||
'charm-pki-local/roles/local-client',
|
||||
allowed_domains='example.com',
|
||||
allow_subdomains=False,
|
||||
enforce_hostnames=True,
|
||||
allow_any_name=False,
|
||||
max_ttl='42h',
|
||||
server_flag=False,
|
||||
client_flag=True),
|
||||
]
|
||||
vault_pki.upload_signed_csr(
|
||||
'MYPEM',
|
||||
'example.com',
|
||||
@ -375,10 +326,17 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
enforce_hostnames=True,
|
||||
allow_any_name=False,
|
||||
max_ttl='42h')
|
||||
client_mock._post.assert_called_once_with(
|
||||
'v1/charm-pki-local/intermediate/set-signed',
|
||||
json={'certificate': 'MYPEM'})
|
||||
client_mock.write.assert_has_calls(write_calls)
|
||||
client_mock.secrets.pki.set_signed_intermediate.\
|
||||
assert_called_once_with(
|
||||
'MYPEM', mount_point='charm-pki-local'
|
||||
)
|
||||
client_mock.secrets.pki.set_urls.assert_called_once_with(
|
||||
{
|
||||
'issuing_certificates': '{}/ca'.format(local_url),
|
||||
'crl_distribution_points': '{}/crl'.format(local_url),
|
||||
},
|
||||
mount_point=vault_pki.CHARM_PKI_MP
|
||||
)
|
||||
|
||||
@patch.object(vault_pki.vault, 'get_access_address')
|
||||
@patch.object(vault_pki, 'is_ca_ready')
|
||||
@ -390,7 +348,8 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
is_ca_ready,
|
||||
get_access_address):
|
||||
mock_client = get_local_client.return_value
|
||||
mock_client.write.return_value = {'data': {'certificate': 'cert'}}
|
||||
mock_client.secrets.pki.generate_root.return_value = {
|
||||
'data': {'certificate': 'cert'}}
|
||||
is_ca_ready.return_value = False
|
||||
get_access_address.return_value = 'addr'
|
||||
rv = vault_pki.generate_root_ca(ttl='0h',
|
||||
@ -402,35 +361,6 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
enforce_hostnames=True,
|
||||
max_ttl='0h')
|
||||
self.assertEqual(rv, 'cert')
|
||||
mock_client.write.assert_has_calls([
|
||||
mock.call('charm-pki-local/root/generate/internal',
|
||||
common_name='Vault Root Certificate Authority '
|
||||
'(charm-pki-local)',
|
||||
ttl='0h'),
|
||||
mock.call('charm-pki-local/config/urls',
|
||||
issuing_certificates='addr/v1/charm-pki-local/ca',
|
||||
crl_distribution_points='addr/v1/charm-pki-local/crl'),
|
||||
mock.call('charm-pki-local/roles/local',
|
||||
allow_any_name=True,
|
||||
allowed_domains='domains',
|
||||
allow_bare_domains=True,
|
||||
allow_subdomains=True,
|
||||
allow_glob_domains=False,
|
||||
enforce_hostnames=True,
|
||||
max_ttl='0h',
|
||||
server_flag=True,
|
||||
client_flag=True),
|
||||
mock.call('charm-pki-local/roles/local-client',
|
||||
allow_any_name=True,
|
||||
allowed_domains='domains',
|
||||
allow_bare_domains=True,
|
||||
allow_subdomains=True,
|
||||
allow_glob_domains=False,
|
||||
enforce_hostnames=True,
|
||||
max_ttl='0h',
|
||||
server_flag=False,
|
||||
client_flag=True),
|
||||
])
|
||||
|
||||
@patch.object(vault_pki.vault, 'get_access_address')
|
||||
@patch.object(vault_pki, 'is_ca_ready')
|
||||
@ -467,9 +397,8 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
vault_pki.tune_pki_backend(ttl='3456h', max_ttl='3456h')
|
||||
is_backend_mounted.assert_called_with(mock_client,
|
||||
vault_pki.CHARM_PKI_MP)
|
||||
mock_client.tune_secret_backend.assert_called_with(
|
||||
backend_type='pki',
|
||||
mount_point=vault_pki.CHARM_PKI_MP,
|
||||
mock_client.sys.tune_mount_configuration.assert_called_with(
|
||||
path=vault_pki.CHARM_PKI_MP,
|
||||
max_lease_ttl='3456h',
|
||||
default_lease_ttl='3456h'
|
||||
)
|
||||
@ -478,7 +407,7 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
def test_update_roles(self, get_local_client):
|
||||
mock_client = mock.MagicMock()
|
||||
get_local_client.return_value = mock_client
|
||||
mock_client.read.return_value = {
|
||||
mock_client.secrets.pki.read_role.return_value = {
|
||||
'data': {
|
||||
'allow_any_name': True,
|
||||
'allowed_domains': 'domains',
|
||||
@ -492,29 +421,35 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase):
|
||||
}
|
||||
}
|
||||
vault_pki.update_roles(max_ttl='20h')
|
||||
mock_client.write.assert_has_calls([
|
||||
mock.call('{}/roles/{}'.format(
|
||||
vault_pki.CHARM_PKI_MP, vault_pki.CHARM_PKI_ROLE),
|
||||
allow_any_name=True,
|
||||
allowed_domains='domains',
|
||||
allow_bare_domains=True,
|
||||
allow_subdomains=True,
|
||||
allow_glob_domains=False,
|
||||
enforce_hostnames=True,
|
||||
max_ttl='20h',
|
||||
server_flag=True,
|
||||
client_flag=True),
|
||||
mock.call('{}/roles/{}'.format(
|
||||
vault_pki.CHARM_PKI_MP, vault_pki.CHARM_PKI_ROLE_CLIENT),
|
||||
allow_any_name=True,
|
||||
allowed_domains='domains',
|
||||
allow_bare_domains=True,
|
||||
allow_subdomains=True,
|
||||
allow_glob_domains=False,
|
||||
enforce_hostnames=True,
|
||||
max_ttl='20h',
|
||||
server_flag=False,
|
||||
client_flag=True),
|
||||
mock_client.secrets.pki.create_or_update_role.assert_has_calls([
|
||||
mock.call(
|
||||
vault_pki.CHARM_PKI_ROLE,
|
||||
mount_point=vault_pki.CHARM_PKI_MP,
|
||||
extra_params=dict(
|
||||
allow_any_name=True,
|
||||
allowed_domains='domains',
|
||||
allow_bare_domains=True,
|
||||
allow_subdomains=True,
|
||||
allow_glob_domains=False,
|
||||
enforce_hostnames=True,
|
||||
max_ttl='20h',
|
||||
server_flag=True,
|
||||
client_flag=True)
|
||||
),
|
||||
mock.call(
|
||||
vault_pki.CHARM_PKI_ROLE_CLIENT,
|
||||
mount_point=vault_pki.CHARM_PKI_MP,
|
||||
extra_params=dict(
|
||||
allow_any_name=True,
|
||||
allowed_domains='domains',
|
||||
allow_bare_domains=True,
|
||||
allow_subdomains=True,
|
||||
allow_glob_domains=False,
|
||||
enforce_hostnames=True,
|
||||
max_ttl='20h',
|
||||
server_flag=False,
|
||||
client_flag=True)
|
||||
),
|
||||
])
|
||||
|
||||
@patch.object(vault_pki.hookenv, 'leader_get')
|
||||
|
@ -670,8 +670,8 @@ class TestHandlers(unit_tests.test_utils.CharmTestCase):
|
||||
hvac_client = mock.MagicMock()
|
||||
_vault.get_client.return_value = hvac_client
|
||||
# Vault is up and running, init'ed and unsealed
|
||||
hvac_client.is_initialized.return_value = True
|
||||
hvac_client.is_sealed.return_value = False
|
||||
hvac_client.sys.is_initialized.return_value = True
|
||||
hvac_client.sys.is_sealed.return_value = False
|
||||
self.service_running.return_value = True
|
||||
|
||||
_vault.get_local_charm_access_role_id.return_value = 'local-approle'
|
||||
@ -687,7 +687,7 @@ class TestHandlers(unit_tests.test_utils.CharmTestCase):
|
||||
|
||||
handlers.configure_secrets_backend()
|
||||
|
||||
hvac_client.auth_approle.assert_called_once_with('local-approle')
|
||||
hvac_client.auth.approle.login.assert_called_once_with('local-approle')
|
||||
_vault.configure_secret_backend.assert_has_calls([
|
||||
mock.call(hvac_client, name='charm-vaultlocker'),
|
||||
mock.call(hvac_client, name='charm-supersecrets'),
|
||||
@ -883,7 +883,7 @@ class TestHandlers(unit_tests.test_utils.CharmTestCase):
|
||||
def _set_sealed(self, _vault, status):
|
||||
hvac_client = mock.MagicMock()
|
||||
_vault.get_client.return_value = hvac_client
|
||||
hvac_client.is_sealed.return_value = status
|
||||
hvac_client.sys.is_sealed.return_value = status
|
||||
|
||||
@mock.patch.object(handlers, 'client_approle_authorized')
|
||||
@mock.patch.object(handlers, 'vault')
|
||||
|
Loading…
x
Reference in New Issue
Block a user