Merge "Set salt when generating genesis bundle"

This commit is contained in:
Zuul 2019-03-25 16:16:57 +00:00 committed by Gerrit Code Review
commit bc0e420bc4
9 changed files with 82 additions and 37 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -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,

View File

@ -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():

View File

@ -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.'

View File

@ -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

View 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)

View File

@ -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 """

View File

@ -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
@ -102,6 +106,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:
@ -128,6 +136,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:

View File

@ -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."""