Merge "PKI Cert generation and check updates"
This commit is contained in:
commit
05dc91eda4
@ -477,6 +477,14 @@ Dashes in the document names will be converted to underscores for consistency.
|
|||||||
|
|
||||||
Name of site.
|
Name of site.
|
||||||
|
|
||||||
|
**days** (Optional).
|
||||||
|
|
||||||
|
Duration (in days) certificates should be valid. Default=365,
|
||||||
|
minimum=0, no maximum.
|
||||||
|
|
||||||
|
NOTE: A generated certificate where days = 0 should only be used for testing.
|
||||||
|
A certificate generated in such a way will be valid for 0 seconds.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
""""""""
|
""""""""
|
||||||
|
|
||||||
@ -492,10 +500,78 @@ Examples
|
|||||||
secrets generate-pki \
|
secrets generate-pki \
|
||||||
<site_name> \
|
<site_name> \
|
||||||
-o <output> \
|
-o <output> \
|
||||||
-f <filename>
|
-f <filename> \
|
||||||
|
-d <days>
|
||||||
|
|
||||||
.. _command-line-repository-overrides:
|
.. _command-line-repository-overrides:
|
||||||
|
|
||||||
|
|
||||||
|
Check PKI Certs
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Determine if any PKI certificates from a site are expired, or will be expired
|
||||||
|
within N days (default N=60, no maximum, minimum 0). Print those cert names
|
||||||
|
and expiration dates to ``stdout``.
|
||||||
|
|
||||||
|
**-d / --days** (Optional).
|
||||||
|
|
||||||
|
Number of days past today's date to check certificate expirations.
|
||||||
|
Default days=60. Minimum days=0, days less than 0 will raise an exception.
|
||||||
|
No maximum days.
|
||||||
|
|
||||||
|
**site_name** (Required).
|
||||||
|
|
||||||
|
Name of the ``site``. The ``site_name`` must match a ``site`` name in the site
|
||||||
|
repository folder structure.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
./pegleg.sh site -r <site_repo> \
|
||||||
|
secrets check-pki-certs <site_name> <options>
|
||||||
|
|
||||||
|
Examples
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
Example without days specified:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
./pegleg.sh site -r <site_repo> secrets check-pki-certs <site_name>
|
||||||
|
|
||||||
|
Example with days specified:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
./pegleg.sh site -r <site_repo> secrets check-pki-certs <site_name> -d <days>
|
||||||
|
|
||||||
|
Secrets
|
||||||
|
-------
|
||||||
|
|
||||||
|
A sub-group of site command group, which allows you to perform secrets
|
||||||
|
level operations for secrets documents of a site.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
For the CLI commands ``encrypt`` and ``decrypt`` in the ``secrets`` command
|
||||||
|
group, which encrypt or decrypt site secrets, two environment variables,
|
||||||
|
``PEGLEG_PASSPHRASE``, and ``PEGLEG_SALT``, are used to capture the
|
||||||
|
master passphrase, and the salt needed for encryption and decryption of the
|
||||||
|
site secrets. The contents of ``PEGLEG_PASSPHRASE``, and ``PEGLEG_SALT``
|
||||||
|
are not generated by Pegleg, but are created externally, and set by a
|
||||||
|
deployment engineers or tooling.
|
||||||
|
|
||||||
|
A minimum length of 24 for master passphrases will be checked by all CLI
|
||||||
|
commands, which use the ``PEGLEG_PASSPHRASE``. All other criteria around
|
||||||
|
master passphrase strength are assumed to be enforced elsewhere.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
./pegleg.sh site -r <site_repo> -e <extra_repo> secrets <command> <options>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Encrypt
|
Encrypt
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
|
@ -401,8 +401,15 @@ def secrets():
|
|||||||
'for tracking provenance information in the PeglegManagedDocuments. '
|
'for tracking provenance information in the PeglegManagedDocuments. '
|
||||||
'An attempt is made to automatically determine this value, '
|
'An attempt is made to automatically determine this value, '
|
||||||
'but should be provided.')
|
'but should be provided.')
|
||||||
|
@click.option(
|
||||||
|
'-d',
|
||||||
|
'--days',
|
||||||
|
'days',
|
||||||
|
default=365,
|
||||||
|
help='Duration in days generated certificates should be valid. '
|
||||||
|
'Default is 365 days.')
|
||||||
@click.argument('site_name')
|
@click.argument('site_name')
|
||||||
def generate_pki(site_name, author):
|
def generate_pki(site_name, author, days):
|
||||||
"""Generate certificates, certificate authorities and keypairs for a given
|
"""Generate certificates, certificate authorities and keypairs for a given
|
||||||
site.
|
site.
|
||||||
|
|
||||||
@ -410,7 +417,8 @@ def generate_pki(site_name, author):
|
|||||||
|
|
||||||
engine.repository.process_repositories(site_name,
|
engine.repository.process_repositories(site_name,
|
||||||
overwrite_existing=True)
|
overwrite_existing=True)
|
||||||
pkigenerator = catalog.pki_generator.PKIGenerator(site_name, author=author)
|
pkigenerator = catalog.pki_generator.PKIGenerator(
|
||||||
|
site_name, author=author, duration=days)
|
||||||
output_paths = pkigenerator.generate()
|
output_paths = pkigenerator.generate()
|
||||||
|
|
||||||
click.echo("Generated PKI files written to:\n%s" % '\n'.join(output_paths))
|
click.echo("Generated PKI files written to:\n%s" % '\n'.join(output_paths))
|
||||||
@ -509,6 +517,29 @@ def genesis_bundle(*, build_dir, validators, site_name):
|
|||||||
site_name)
|
site_name)
|
||||||
|
|
||||||
|
|
||||||
|
@secrets.command(
|
||||||
|
'check-pki-certs',
|
||||||
|
help='Determine if certificates in a sites PKICatalog are expired or '
|
||||||
|
'expiring within a specified number of days.')
|
||||||
|
@click.option(
|
||||||
|
'-d',
|
||||||
|
'--days',
|
||||||
|
'days',
|
||||||
|
default=60,
|
||||||
|
help='The number of days past today to check if certificates are valid.')
|
||||||
|
@click.argument('site_name')
|
||||||
|
def check_pki_certs(site_name, days):
|
||||||
|
"""Check PKI certificates of a site for expiration."""
|
||||||
|
|
||||||
|
engine.repository.process_repositories(site_name,
|
||||||
|
overwrite_existing=True)
|
||||||
|
|
||||||
|
cert_results = engine.secrets.check_cert_expiry(site_name, duration=days)
|
||||||
|
|
||||||
|
click.echo("The following certs will expire within {} days: \n{}"
|
||||||
|
.format(days, cert_results))
|
||||||
|
|
||||||
|
|
||||||
@main.group(help='Commands related to types')
|
@main.group(help='Commands related to types')
|
||||||
@MAIN_REPOSITORY_OPTION
|
@MAIN_REPOSITORY_OPTION
|
||||||
@REPOSITORY_CLONE_PATH_OPTION
|
@REPOSITORY_CLONE_PATH_OPTION
|
||||||
|
@ -44,9 +44,12 @@ class PKIGenerator(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sitename, block_strings=True, author=None):
|
def __init__(self, sitename, block_strings=True, author=None,
|
||||||
|
duration=365):
|
||||||
"""Constructor for ``PKIGenerator``.
|
"""Constructor for ``PKIGenerator``.
|
||||||
|
|
||||||
|
:param int duration: Duration in days that generated certificates
|
||||||
|
are valid.
|
||||||
:param str sitename: Site name for which to retrieve documents used for
|
:param str sitename: Site name for which to retrieve documents used for
|
||||||
certificate and keypair generation.
|
certificate and keypair generation.
|
||||||
:param bool block_strings: Whether to dump out certificate data as
|
:param bool block_strings: Whether to dump out certificate data as
|
||||||
@ -60,7 +63,8 @@ class PKIGenerator(object):
|
|||||||
self._documents = util.definition.documents_for_site(sitename)
|
self._documents = util.definition.documents_for_site(sitename)
|
||||||
self._author = author
|
self._author = author
|
||||||
|
|
||||||
self.keys = pki_utility.PKIUtility(block_strings=block_strings)
|
self.keys = pki_utility.PKIUtility(block_strings=block_strings,
|
||||||
|
duration=duration)
|
||||||
self.outputs = collections.defaultdict(dict)
|
self.outputs = collections.defaultdict(dict)
|
||||||
|
|
||||||
# Maps certificates to CAs in order to derive certificate paths.
|
# Maps certificates to CAs in order to derive certificate paths.
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from datetime import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@ -25,11 +25,11 @@ from dateutil import parser
|
|||||||
import pytz
|
import pytz
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
from pegleg.engine import exceptions
|
||||||
from pegleg.engine.util.pegleg_managed_document import \
|
from pegleg.engine.util.pegleg_managed_document import \
|
||||||
PeglegManagedSecretsDocument
|
PeglegManagedSecretsDocument
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
_ONE_YEAR_IN_HOURS = '8760h' # 365 * 24
|
|
||||||
|
|
||||||
__all__ = ['PKIUtility']
|
__all__ = ['PKIUtility']
|
||||||
|
|
||||||
@ -57,23 +57,27 @@ class PKIUtility(object):
|
|||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __init__(self, *, block_strings=True):
|
def __init__(self, *, block_strings=True, duration=None):
|
||||||
self.block_strings = block_strings
|
self.block_strings = block_strings
|
||||||
self._ca_config_string = None
|
self._ca_config_string = None
|
||||||
|
self.duration = duration
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ca_config(self):
|
def ca_config(self):
|
||||||
|
if self.duration is not None and self.duration >= 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise exceptions.PKICertificateInvalidDuration()
|
||||||
|
|
||||||
if not self._ca_config_string:
|
if not self._ca_config_string:
|
||||||
self._ca_config_string = json.dumps({
|
self._ca_config_string = json.dumps({
|
||||||
'signing': {
|
'signing': {
|
||||||
'default': {
|
'default': {
|
||||||
# TODO(felipemonteiro): Make this configurable.
|
|
||||||
'expiry':
|
'expiry':
|
||||||
_ONE_YEAR_IN_HOURS,
|
str(24 * self.duration) + 'h',
|
||||||
'usages': [
|
'usages': [
|
||||||
'signing', 'key encipherment', 'server auth',
|
'signing', 'key encipherment', 'server auth',
|
||||||
'client auth'
|
'client auth'],
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -198,17 +202,27 @@ class PKIUtility(object):
|
|||||||
"""Chek whether a given certificate is expired.
|
"""Chek whether a given certificate is expired.
|
||||||
|
|
||||||
:param str cert: Client certificate that contains the public key.
|
:param str cert: Client certificate that contains the public key.
|
||||||
:returns: True if certificate is expired, else False.
|
:returns: In dictionary format returns the expiration date of the cert
|
||||||
:rtype: bool
|
and True if the cert is or will be expired within the next
|
||||||
|
expire_in_days
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if self.duration is not None and self.duration >= 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise exceptions.PKICertificateInvalidDuration()
|
||||||
|
|
||||||
info = self.cert_info(cert)
|
info = self.cert_info(cert)
|
||||||
expiry_str = info['not_after']
|
expiry_str = info['not_after']
|
||||||
expiry = parser.parse(expiry_str)
|
expiry = parser.parse(expiry_str)
|
||||||
# expiry is timezone-aware; do the same for `now`.
|
# expiry is timezone-aware; do the same for `now`.
|
||||||
now = pytz.utc.localize(datetime.utcnow())
|
expiry_window = pytz.utc.localize(datetime.datetime.utcnow()) + \
|
||||||
return now > expiry
|
datetime.timedelta(days=self.duration)
|
||||||
|
expired = expiry_window > expiry
|
||||||
|
expiry = expiry.strftime('%d-%b-%Y %H:%M:%S %Z')
|
||||||
|
return {'expiry_date': expiry, 'expired': expired}
|
||||||
|
|
||||||
def _cfssl(self, command, *, files=None):
|
def _cfssl(self, command, *, files=None):
|
||||||
"""Executes ``cfssl`` command via ``subprocess`` call."""
|
"""Executes ``cfssl`` command via ``subprocess`` call."""
|
||||||
|
@ -99,10 +99,17 @@ class GenesisBundleGenerateException(PeglegBaseException):
|
|||||||
message = 'Bundle generation failed on deckhand validation.'
|
message = 'Bundle generation failed on deckhand validation.'
|
||||||
|
|
||||||
|
|
||||||
|
class PKICertificateInvalidDuration(PeglegBaseException):
|
||||||
|
"""Exception for invalid duration of PKI Certificate."""
|
||||||
|
message = ('Provided duration is invalid. Certificate durations must be '
|
||||||
|
'a positive integer.')
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# CREDENTIALS EXCEPTIONS
|
# CREDENTIALS EXCEPTIONS
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class PassphraseNotFoundException(PeglegBaseException):
|
class PassphraseNotFoundException(PeglegBaseException):
|
||||||
"""Exception raised when passphrase is not set."""
|
"""Exception raised when passphrase is not set."""
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
from prettytable import PrettyTable
|
||||||
|
|
||||||
|
from pegleg.engine.catalog.pki_utility import PKIUtility
|
||||||
from pegleg.engine.generators.passphrase_generator import PassphraseGenerator
|
from pegleg.engine.generators.passphrase_generator import PassphraseGenerator
|
||||||
from pegleg.engine.util.cryptostring import CryptoString
|
from pegleg.engine.util.cryptostring import CryptoString
|
||||||
from pegleg.engine.util import definition
|
from pegleg.engine.util import definition
|
||||||
@ -186,3 +189,38 @@ def wrap_secret(author, file_name, output_path, schema,
|
|||||||
output_doc = managed_secret.pegleg_document
|
output_doc = managed_secret.pegleg_document
|
||||||
with open(output_path, "w") as output_fi:
|
with open(output_path, "w") as output_fi:
|
||||||
yaml.safe_dump(output_doc, output_fi)
|
yaml.safe_dump(output_doc, output_fi)
|
||||||
|
|
||||||
|
|
||||||
|
def check_cert_expiry(site_name, duration=60):
|
||||||
|
"""
|
||||||
|
Check certs from a sites PKICatalog to determine if they are expired or
|
||||||
|
expiring within N days
|
||||||
|
|
||||||
|
:param str site_name: The site to read from
|
||||||
|
:param int duration: Number of days from today to check cert
|
||||||
|
expirations
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
pki_util = PKIUtility(duration=duration)
|
||||||
|
# Create a table to output expired/expiring certs for this site.
|
||||||
|
cert_table = PrettyTable()
|
||||||
|
cert_table.field_names = ['cert_name', 'expiration_date']
|
||||||
|
|
||||||
|
s = definition.site_files(site_name)
|
||||||
|
for doc in s:
|
||||||
|
if 'certificate' in doc:
|
||||||
|
with open(doc, 'r') as f:
|
||||||
|
results = yaml.safe_load_all(f) # Validate valid YAML.
|
||||||
|
results = PeglegSecretManagement(
|
||||||
|
docs=results).get_decrypted_secrets()
|
||||||
|
for result in results:
|
||||||
|
if result['schema'] == \
|
||||||
|
"deckhand/Certificate/v1":
|
||||||
|
cert = result['data']
|
||||||
|
cert_info = pki_util.check_expiry(cert)
|
||||||
|
if cert_info['expired'] is True:
|
||||||
|
cert_table.add_row([doc, cert_info['expiry_date']])
|
||||||
|
|
||||||
|
# Return table of cert names and expiration dates that are expiring
|
||||||
|
return cert_table.get_string()
|
||||||
|
@ -91,7 +91,7 @@ class TestPKIUtility(object):
|
|||||||
assert PRIVATE_KEY_HEADER in priv_key['data']
|
assert PRIVATE_KEY_HEADER in priv_key['data']
|
||||||
|
|
||||||
def test_generate_certificate(self):
|
def test_generate_certificate(self):
|
||||||
pki_obj = pki_utility.PKIUtility()
|
pki_obj = pki_utility.PKIUtility(duration=365)
|
||||||
ca_cert_wrapper, ca_key_wrapper = pki_obj.generate_ca(
|
ca_cert_wrapper, ca_key_wrapper = pki_obj.generate_ca(
|
||||||
self.__class__.__name__)
|
self.__class__.__name__)
|
||||||
ca_cert = ca_cert_wrapper['data']['managedDocument']
|
ca_cert = ca_cert_wrapper['data']['managedDocument']
|
||||||
@ -121,7 +121,7 @@ class TestPKIUtility(object):
|
|||||||
|
|
||||||
def test_check_expiry_is_expired_false(self):
|
def test_check_expiry_is_expired_false(self):
|
||||||
"""Check that ``check_expiry`` returns False if cert isn't expired."""
|
"""Check that ``check_expiry`` returns False if cert isn't expired."""
|
||||||
pki_obj = pki_utility.PKIUtility()
|
pki_obj = pki_utility.PKIUtility(duration=0)
|
||||||
|
|
||||||
ca_config = json.loads(pki_obj.ca_config)
|
ca_config = json.loads(pki_obj.ca_config)
|
||||||
ca_config['signing']['default']['expiry'] = '1h'
|
ca_config['signing']['default']['expiry'] = '1h'
|
||||||
@ -141,7 +141,7 @@ class TestPKIUtility(object):
|
|||||||
cert = cert_wrapper['data']['managedDocument']
|
cert = cert_wrapper['data']['managedDocument']
|
||||||
|
|
||||||
# Validate that the cert hasn't expired.
|
# Validate that the cert hasn't expired.
|
||||||
is_expired = pki_obj.check_expiry(cert=cert['data'])
|
is_expired = pki_obj.check_expiry(cert=cert['data'])['expired']
|
||||||
assert not is_expired
|
assert not is_expired
|
||||||
|
|
||||||
def test_check_expiry_is_expired_true(self):
|
def test_check_expiry_is_expired_true(self):
|
||||||
@ -149,7 +149,7 @@ class TestPKIUtility(object):
|
|||||||
|
|
||||||
Second values are used to demonstrate precision down to the second.
|
Second values are used to demonstrate precision down to the second.
|
||||||
"""
|
"""
|
||||||
pki_obj = pki_utility.PKIUtility()
|
pki_obj = pki_utility.PKIUtility(duration=0)
|
||||||
|
|
||||||
ca_config = json.loads(pki_obj.ca_config)
|
ca_config = json.loads(pki_obj.ca_config)
|
||||||
ca_config['signing']['default']['expiry'] = '1s'
|
ca_config['signing']['default']['expiry'] = '1s'
|
||||||
@ -171,5 +171,5 @@ class TestPKIUtility(object):
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
# Validate that the cert has expired.
|
# Validate that the cert has expired.
|
||||||
is_expired = pki_obj.check_expiry(cert=cert['data'])
|
is_expired = pki_obj.check_expiry(cert=cert['data'])['expired']
|
||||||
assert is_expired
|
assert is_expired
|
||||||
|
@ -237,7 +237,7 @@ def test_generate_pki_using_local_repo_path(create_tmp_deployment_files):
|
|||||||
repo_path = str(git.git_handler(TEST_PARAMS["repo_url"],
|
repo_path = str(git.git_handler(TEST_PARAMS["repo_url"],
|
||||||
ref=TEST_PARAMS["repo_rev"]))
|
ref=TEST_PARAMS["repo_rev"]))
|
||||||
with mock.patch.dict(config.GLOBAL_CONTEXT, {"site_repo": repo_path}):
|
with mock.patch.dict(config.GLOBAL_CONTEXT, {"site_repo": repo_path}):
|
||||||
pki_generator = PKIGenerator(sitename=TEST_PARAMS["site_name"])
|
pki_generator = PKIGenerator(duration=365, sitename=TEST_PARAMS["site_name"])
|
||||||
generated_files = pki_generator.generate()
|
generated_files = pki_generator.generate()
|
||||||
|
|
||||||
assert len(generated_files), 'No secrets were generated'
|
assert len(generated_files), 'No secrets were generated'
|
||||||
@ -259,10 +259,10 @@ def test_check_expiry(create_tmp_deployment_files):
|
|||||||
repo_path = str(git.git_handler(TEST_PARAMS["repo_url"],
|
repo_path = str(git.git_handler(TEST_PARAMS["repo_url"],
|
||||||
ref=TEST_PARAMS["repo_rev"]))
|
ref=TEST_PARAMS["repo_rev"]))
|
||||||
with mock.patch.dict(config.GLOBAL_CONTEXT, {"site_repo": repo_path}):
|
with mock.patch.dict(config.GLOBAL_CONTEXT, {"site_repo": repo_path}):
|
||||||
pki_generator = PKIGenerator(sitename=TEST_PARAMS["site_name"])
|
pki_generator = PKIGenerator(duration=365, sitename=TEST_PARAMS["site_name"])
|
||||||
generated_files = pki_generator.generate()
|
generated_files = pki_generator.generate()
|
||||||
|
|
||||||
pki_util = pki_utility.PKIUtility()
|
pki_util = pki_utility.PKIUtility(duration=0)
|
||||||
|
|
||||||
assert len(generated_files), 'No secrets were generated'
|
assert len(generated_files), 'No secrets were generated'
|
||||||
for generated_file in generated_files:
|
for generated_file in generated_files:
|
||||||
@ -276,5 +276,7 @@ def test_check_expiry(create_tmp_deployment_files):
|
|||||||
if result['schema'] == \
|
if result['schema'] == \
|
||||||
"deckhand/Certificate/v1":
|
"deckhand/Certificate/v1":
|
||||||
cert = result['data']
|
cert = result['data']
|
||||||
assert not pki_util.check_expiry(cert), \
|
cert_info = pki_util.check_expiry(cert)
|
||||||
"%s is expired!" % generated_file.name
|
assert cert_info['expired'] is False, \
|
||||||
|
"%s is expired/expiring on %s" % \
|
||||||
|
(generated_file.name, cert_info['expiry_date'])
|
||||||
|
@ -562,6 +562,15 @@ class TestSiteSecretsActions(BaseCLIActionTest):
|
|||||||
result = self.runner.invoke(cli.site, ['-r', repo_path] + secrets_opts)
|
result = self.runner.invoke(cli.site, ['-r', repo_path] + secrets_opts)
|
||||||
assert result.exit_code == 0, result.output
|
assert result.exit_code == 0, result.output
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
not pki_utility.PKIUtility.cfssl_exists(),
|
||||||
|
reason='cfssl must be installed to execute these tests')
|
||||||
|
def test_check_pki_certs(self):
|
||||||
|
repo_path = self.treasuremap_path
|
||||||
|
secrets_opts = ['secrets', 'check-pki-certs', self.site_name]
|
||||||
|
result = self.runner.invoke(cli.site, ['-r', repo_path] + secrets_opts)
|
||||||
|
assert result.exit_code == 0, result.output
|
||||||
|
|
||||||
@mock.patch.dict(os.environ, {
|
@mock.patch.dict(os.environ, {
|
||||||
"PEGLEG_PASSPHRASE": "123456789012345678901234567890",
|
"PEGLEG_PASSPHRASE": "123456789012345678901234567890",
|
||||||
"PEGLEG_SALT": "123456"
|
"PEGLEG_SALT": "123456"
|
||||||
@ -608,7 +617,6 @@ class TestSiteSecretsActions(BaseCLIActionTest):
|
|||||||
assert "encrypted" in doc["data"]
|
assert "encrypted" in doc["data"]
|
||||||
assert "managedDocument" in doc["data"]
|
assert "managedDocument" in doc["data"]
|
||||||
|
|
||||||
|
|
||||||
class TestTypeCliActions(BaseCLIActionTest):
|
class TestTypeCliActions(BaseCLIActionTest):
|
||||||
"""Tests type-level CLI actions."""
|
"""Tests type-level CLI actions."""
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user