Set salt when generating genesis bundle
This patch: 1. Sets the salt in config when running genesis bundle 2. Updates the genesis bundle CLI method 3. Adds exception types for credentials 4. Updates unit tests to be compliant with new exceptions Change-Id: I8869f897e2c25b98c30eaa6be52356aae4ac63b6
This commit is contained in:
parent
c4f25b4d4f
commit
fce12add18
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
@ -434,26 +434,15 @@ def generate_pki(site_name, author):
|
||||
'to genesis.sh script.')
|
||||
@SITE_REPOSITORY_ARGUMENT
|
||||
def genesis_bundle(*, build_dir, validators, site_name):
|
||||
prom_encryption_key = os.environ.get("PROMENADE_ENCRYPTION_KEY")
|
||||
peg_encryption_key = os.environ.get("PEGLEG_PASSPHRASE")
|
||||
encryption_key = None
|
||||
if (prom_encryption_key and len(prom_encryption_key) > 24 and
|
||||
peg_encryption_key and len(peg_encryption_key) > 24):
|
||||
click.echo("WARNING: PROMENADE_ENCRYPTION_KEY is deprecated, "
|
||||
"using PEGLEG_PASSPHRASE instead", err=True)
|
||||
config.set_passphrase(peg_encryption_key)
|
||||
encryption_key = peg_encryption_key
|
||||
elif prom_encryption_key and len(prom_encryption_key) > 24:
|
||||
click.echo("ERROR: PROMENADE_ENCRYPTION_KEY is deprecated, "
|
||||
"use PEGLEG_PASSPHRASE instead", err=True)
|
||||
raise click.ClickException("ERROR: PEGLEG_PASSPHRASE must be set "
|
||||
"and at least 24 characters long.")
|
||||
elif peg_encryption_key and len(peg_encryption_key) > 24:
|
||||
config.set_passphrase(peg_encryption_key)
|
||||
encryption_key = peg_encryption_key
|
||||
else:
|
||||
raise click.ClickException("ERROR: PEGLEG_PASSPHRASE must be set "
|
||||
"and at least 24 characters long.")
|
||||
passphrase = os.environ.get("PEGLEG_PASSPHRASE")
|
||||
salt = os.environ.get("PEGLEG_SALT")
|
||||
encryption_key = passphrase
|
||||
if passphrase:
|
||||
passphrase = passphrase.encode()
|
||||
if salt:
|
||||
salt = salt.encode()
|
||||
config.set_passphrase(passphrase)
|
||||
config.set_salt(salt)
|
||||
|
||||
PeglegSecretManagement.check_environment()
|
||||
bundle.build_genesis(build_dir,
|
||||
|
@ -16,6 +16,8 @@
|
||||
# context passing but will require a somewhat heavy code refactor. See:
|
||||
# http://click.pocoo.org/5/commands/#nested-handling-and-contexts
|
||||
|
||||
from pegleg.engine import exceptions
|
||||
|
||||
try:
|
||||
if GLOBAL_CONTEXT:
|
||||
pass
|
||||
@ -28,7 +30,9 @@ except NameError:
|
||||
'site_rev': None,
|
||||
'type_path': 'type',
|
||||
'passphrase': None,
|
||||
'salt': None
|
||||
'salt': None,
|
||||
'salt_min_length': 24,
|
||||
'passphrase_min_length': 24
|
||||
}
|
||||
|
||||
|
||||
@ -151,9 +155,15 @@ def set_rel_type_path(p):
|
||||
GLOBAL_CONTEXT['type_path'] = p
|
||||
|
||||
|
||||
def set_passphrase(p):
|
||||
def set_passphrase(passphrase):
|
||||
"""Set the passphrase for encryption and decryption."""
|
||||
GLOBAL_CONTEXT['passphrase'] = p
|
||||
|
||||
if not passphrase:
|
||||
raise exceptions.PassphraseNotFoundException()
|
||||
elif len(passphrase) < GLOBAL_CONTEXT['passphrase_min_length']:
|
||||
raise exceptions.PassphraseInsufficientLengthException()
|
||||
|
||||
GLOBAL_CONTEXT['passphrase'] = passphrase
|
||||
|
||||
|
||||
def get_passphrase():
|
||||
@ -161,9 +171,15 @@ def get_passphrase():
|
||||
return GLOBAL_CONTEXT['passphrase']
|
||||
|
||||
|
||||
def set_salt(p):
|
||||
def set_salt(salt):
|
||||
"""Set the salt for encryption and decryption."""
|
||||
GLOBAL_CONTEXT['salt'] = p
|
||||
|
||||
if not salt:
|
||||
raise exceptions.SaltNotFoundException()
|
||||
elif len(salt) < GLOBAL_CONTEXT['salt_min_length']:
|
||||
raise exceptions.SaltInsufficientLengthException()
|
||||
|
||||
GLOBAL_CONTEXT['salt'] = salt
|
||||
|
||||
|
||||
def get_salt():
|
||||
|
@ -102,3 +102,31 @@ class GenesisBundleGenerateException(PeglegBaseException):
|
||||
"""
|
||||
|
||||
message = 'Bundle generation failed on deckhand validation.'
|
||||
|
||||
|
||||
#
|
||||
# CREDENTIALS EXCEPTIONS
|
||||
#
|
||||
|
||||
class PassphraseNotFoundException(PeglegBaseException):
|
||||
"""Exception raised when passphrase is not set."""
|
||||
|
||||
message = 'PEGLEG_PASSPHRASE must be set'
|
||||
|
||||
|
||||
class PassphraseInsufficientLengthException(PeglegBaseException):
|
||||
"""Exception raised when passphrase is too short."""
|
||||
|
||||
message = 'PEGLEG_PASSPHRASE must be at least 24 characters long.'
|
||||
|
||||
|
||||
class SaltNotFoundException(PeglegBaseException):
|
||||
"""Exception raised when salt is not set."""
|
||||
|
||||
message = 'PEGLEG_SALT must be set'
|
||||
|
||||
|
||||
class SaltInsufficientLengthException(PeglegBaseException):
|
||||
"""Exception raised when salt is too short."""
|
||||
|
||||
message = 'PEGLEG_SALT must be at least 24 characters long.'
|
||||
|
@ -91,7 +91,7 @@ data: ABAgagajajkb839215387
|
||||
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_no_encryption_key(temp_path):
|
||||
# Write the test data to temp file
|
||||
@ -119,7 +119,7 @@ def test_no_encryption_key(temp_path):
|
||||
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_failed_deckhand_validation(temp_path):
|
||||
# Write the test data to temp file
|
||||
|
@ -166,7 +166,7 @@ def test_cryptostring_long_len():
|
||||
'cicd_site_repo/site/cicd/passphrases/passphrase-catalog.yaml', ])
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'})
|
||||
ENV_SALT: 'MySecretSalt1234567890]['})
|
||||
def test_generate_passphrases(*_):
|
||||
_dir = tempfile.mkdtemp()
|
||||
os.makedirs(os.path.join(_dir, 'cicd_site_repo'), exist_ok=True)
|
||||
@ -239,7 +239,7 @@ def test_generate_passphrases_exception(capture):
|
||||
'cicd_global_repo/site/cicd/passphrases/passphrase-catalog.yaml', ])
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'})
|
||||
ENV_SALT: 'MySecretSalt1234567890]['})
|
||||
def test_global_passphrase_catalog(*_):
|
||||
_dir = tempfile.mkdtemp()
|
||||
os.makedirs(os.path.join(_dir, 'cicd_site_repo'), exist_ok=True)
|
||||
|
@ -74,7 +74,7 @@ def test_encrypt_and_decrypt():
|
||||
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'aShortPassphrase',
|
||||
ENV_SALT: 'MySecretSalt'
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_short_passphrase():
|
||||
with pytest.raises(click.ClickException,
|
||||
@ -84,7 +84,7 @@ def test_short_passphrase():
|
||||
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'})
|
||||
ENV_SALT: 'MySecretSalt1234567890]['})
|
||||
def test_secret_encrypt_and_decrypt(create_tmp_deployment_files, tmpdir):
|
||||
site_dir = tmpdir.join("deployment_files", "site", "cicd")
|
||||
passphrase_doc = """---
|
||||
@ -160,7 +160,7 @@ def test_pegleg_secret_management_constructor_with_invalid_arguments():
|
||||
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_encrypt_decrypt_using_file_path(temp_path):
|
||||
# write the test data to temp file
|
||||
@ -190,7 +190,7 @@ def test_encrypt_decrypt_using_file_path(temp_path):
|
||||
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_encrypt_decrypt_using_docs(temp_path):
|
||||
# write the test data to temp file
|
||||
@ -226,7 +226,7 @@ def test_encrypt_decrypt_using_docs(temp_path):
|
||||
reason='cfssl must be installed to execute these tests')
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_generate_pki_using_local_repo_path(create_tmp_deployment_files):
|
||||
"""Validates ``generate-pki`` action using local repo path."""
|
||||
@ -252,7 +252,7 @@ def test_generate_pki_using_local_repo_path(create_tmp_deployment_files):
|
||||
reason='cfssl must be installed to execute these tests')
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt'
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_check_expiry(create_tmp_deployment_files):
|
||||
""" Validates check_expiry """
|
||||
|
@ -12,6 +12,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
|
||||
import json
|
||||
import mock
|
||||
import pytest
|
||||
@ -20,6 +22,8 @@ from tests.unit import test_utils
|
||||
from mock import ANY
|
||||
|
||||
from pegleg.engine import util
|
||||
from pegleg.engine.util.pegleg_secret_management import ENV_PASSPHRASE
|
||||
from pegleg.engine.util.pegleg_secret_management import ENV_SALT
|
||||
from pegleg.engine.util.shipyard_helper import ShipyardHelper
|
||||
from pegleg.engine.util.shipyard_helper import ShipyardClient
|
||||
|
||||
@ -89,6 +93,10 @@ def test_shipyard_helper_init_():
|
||||
return_value=DATA)
|
||||
@mock.patch.object(ShipyardHelper, 'formatted_response_handler',
|
||||
autospec=True, return_value=None)
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_upload_documents(*args):
|
||||
""" Tests upload document """
|
||||
# Scenario:
|
||||
@ -115,6 +123,10 @@ def test_upload_documents(*args):
|
||||
return_value=DATA)
|
||||
@mock.patch.object(ShipyardHelper, 'formatted_response_handler',
|
||||
autospec=True, return_value=None)
|
||||
@mock.patch.dict(os.environ, {
|
||||
ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
ENV_SALT: 'MySecretSalt1234567890]['
|
||||
})
|
||||
def test_upload_documents_fail(*args):
|
||||
""" Tests Document upload error """
|
||||
# Scenario:
|
||||
|
@ -459,7 +459,7 @@ class TestSiteSecretsActions(BaseCLIActionTest):
|
||||
super(TestSiteSecretsActions, cls).setup_class()
|
||||
cls.runner = CliRunner(env={
|
||||
"PEGLEG_PASSPHRASE": 'ytrr89erARAiPE34692iwUMvWqqBvC',
|
||||
"PEGLEG_SALT": "MySecretSalt"
|
||||
"PEGLEG_SALT": "MySecretSalt1234567890]["
|
||||
})
|
||||
|
||||
def _validate_generate_pki_action(self, result):
|
||||
@ -514,7 +514,7 @@ class TestSiteSecretsActions(BaseCLIActionTest):
|
||||
reason='cfssl must be installed to execute these tests')
|
||||
@mock.patch.dict(os.environ, {
|
||||
"PEGLEG_PASSPHRASE": "123456789012345678901234567890",
|
||||
"PEGLEG_SALT": "123456"
|
||||
"PEGLEG_SALT": "MySecretSalt1234567890]["
|
||||
})
|
||||
def test_site_secrets_encrypt_and_decrypt_local_repo_path(self):
|
||||
"""Validates ``generate-pki`` action using local repo path."""
|
||||
|
Loading…
Reference in New Issue
Block a user