Accept multiple path options for decrypt

Change-Id: Ic6c337334f1a21e1f3e303f4ccfb56caeddf4500
This commit is contained in:
Ian H. Pittwood 2020-01-09 15:43:43 -06:00 committed by Ian H Pittwood
parent ff9c95f423
commit 1ef5024eb0
4 changed files with 92 additions and 17 deletions

View File

@ -717,7 +717,7 @@ repository folder structure. This is used to ensure the correct revision of
the site and global repositories are used, as specified in the site's
:file:`site-definition.yaml`.
**\\-\\-path** (Required).
**\\-\\-path** (Required). Multiple entries allowed.
Path to pegleg managed encrypted secrets file or directory of files.
@ -748,8 +748,11 @@ Example:
./pegleg.sh site -r /opt/site-manifests \
-e global=/opt/manifests \
-e secrets=/opt/security-manifests \
secrets decrypt site1 -f \
/opt/security-manifests/site/site1/passwords/password1.yaml
secrets decrypt site1 \
--path /opt/security-manifests/site/site1/passwords/password1.yaml \
--path /opt/security-manifests/site/site1/passwords/password2.yaml \
--path /opt/security-manifests/site/site1/passwords/passwordN.yaml \
--path /opt/security-manifests/site/site1/certificates
Wrap
^^^^

View File

@ -601,7 +601,8 @@ def encrypt(*, path, save_location, author, site_name):
'path',
type=click.Path(exists=True, readable=True),
required=True,
help='The file or directory path to decrypt.')
multiple=True,
help='The file or directory path to decrypt. Multiple entries allowed.')
@click.option(
'-s',
'--save-location',

View File

@ -390,7 +390,7 @@ def run_decrypt(overwrite, path, save_location, site_name):
"""Unwraps and decrypts secret documents for a site
:param overwrite: if True, overwrites original files with decrypted
:param path: file or directory to decrypt
:param path: file(s) or directory(ies) to decrypt
:param save_location: if specified saves to the given path, otherwise
returns list of decrypted information
:param site_name: site name to process
@ -399,18 +399,21 @@ def run_decrypt(overwrite, path, save_location, site_name):
"""
decrypted_data = []
config.set_global_enc_keys(site_name)
decrypted = engine.secrets.decrypt(path, site_name=site_name)
if overwrite:
for path, data in decrypted.items():
files.write(data, path)
elif save_location is None:
for data in decrypted.values():
decrypted_data.append(data)
else:
for path, data in decrypted.items():
file_name = os.path.split(path)[1]
file_save_location = os.path.join(save_location, file_name)
files.write(data, file_save_location)
if type(path) is not list and type(path) is not tuple:
path = [path]
for p in path:
decrypted = engine.secrets.decrypt(p, site_name=site_name)
if overwrite:
for file_path, data in decrypted.items():
files.write(data, file_path)
elif save_location is None:
for data in decrypted.values():
decrypted_data.append(data)
else:
for file_path, data in decrypted.items():
file_name = os.path.split(file_path)[1]
file_save_location = os.path.join(save_location, file_name)
files.write(data, file_save_location)
return decrypted_data

View File

@ -610,6 +610,74 @@ class TestSiteSecretsActions(BaseCLIActionTest):
commands.site, ['--no-decrypt', '-r', repo_path] + secrets_opts)
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')
@mock.patch.dict(
os.environ, {
"PEGLEG_PASSPHRASE": "123456789012345678901234567890",
"PEGLEG_SALT": "MySecretSalt1234567890]["
})
def test_site_secrets_encrypt_and_decrypt_multiple_paths(self):
"""Validates decrypt using multiple paths."""
# Scenario:
#
# 1) Encrypt a file in a local repo
repo_path = self.treasuremap_path
file_path = os.path.join(
repo_path, "site", "seaworthy", "secrets", "passphrases",
"ceph_fsid.yaml")
file_path_2 = os.path.join(
repo_path, "site", "seaworthy", "secrets", "passphrases",
"ucp_oslo_messaging_password.yaml")
with open(file_path, "r") as ceph_fsid_fi:
ceph_fsid = yaml.safe_load(ceph_fsid_fi)
ceph_fsid["metadata"]["storagePolicy"] = "encrypted"
ceph_fsid["metadata"]["layeringDefinition"]["layer"] = "site"
with open(file_path_2, "r") as oslo_messaging_file:
oslo_messaging = yaml.safe_load(oslo_messaging_file)
oslo_messaging["metadata"]["storagePolicy"] = "encrypted"
oslo_messaging["metadata"]["layeringDefinition"]["layer"] = "site"
with open(file_path, "w") as ceph_fsid_fi:
yaml.dump(ceph_fsid, ceph_fsid_fi)
with open(file_path_2, "w") as oslo_messaging_file:
yaml.dump(oslo_messaging, oslo_messaging_file)
secrets_opts = [
'secrets', 'encrypt', '--save-location', repo_path, '-a', 'test',
self.site_name
]
result = self.runner.invoke(
commands.site, ['--no-decrypt', '-r', repo_path] + secrets_opts)
assert result.exit_code == 0
with open(file_path, "r") as ceph_fsid_fi:
ceph_fsid = yaml.safe_load(ceph_fsid_fi)
assert "encrypted" in ceph_fsid["data"]
assert "managedDocument" in ceph_fsid["data"]
with open(file_path_2, "r") as oslo_messaging_file:
oslo_messaging = yaml.safe_load(oslo_messaging_file)
assert "encrypted" in oslo_messaging["data"]
assert "managedDocument" in oslo_messaging["data"]
secrets_opts = [
'secrets', 'decrypt', '-o', '--path', file_path, '--path',
file_path_2, self.site_name
]
result = self.runner.invoke(
commands.site, ['-r', repo_path] + secrets_opts)
assert result.exit_code == 0
with open(file_path, "r") as ceph_fsid_fi:
ceph_fsid = yaml.safe_load(ceph_fsid_fi)
assert "managedDocument" not in ceph_fsid["data"]
with open(file_path_2, "r") as oslo_messaging_file:
oslo_messaging = yaml.safe_load(oslo_messaging_file)
assert "managedDocument" not in oslo_messaging["data"]
@pytest.mark.skipif(
not pki_utility.PKIUtility.cfssl_exists(),
reason='cfssl must be installed to execute these tests')