Add CLI passphrase generation
1. Add support to pegleg to generate a passphrase from CLI 2. Update unit test to ensure encryption/decryption supports passphrase rotation 3. Update order of import statements to satisfy pep8 4. Add unit test for CLI passphrase generation 5. Resolve merge conflicts via rebase Change-Id: I5cb9e41b2f0fac2451bd2b74f33c48cda417c22d
This commit is contained in:
parent
e6af6ae87e
commit
4b00a4340c
@ -809,3 +809,40 @@ P003 - All repos contain expected directories.
|
||||
.. _Shipyard: https://github.com/openstack/airship-shipyard
|
||||
.. _CLI documentation: https://airship-shipyard.readthedocs.io/en/latest/CLI.html#openstack-keystone-authorization-environment-variables
|
||||
.. _Pegleg Passphrase Catalog: https://airship-specs.readthedocs.io/en/latest/specs/approved/pegleg-secrets.html#document-generation
|
||||
|
||||
|
||||
Generate
|
||||
========
|
||||
|
||||
Allows you to perform generate operations.
|
||||
|
||||
Passphrase
|
||||
----------
|
||||
|
||||
Generate a passphrase and print to ``stdout``.
|
||||
|
||||
**-l / --length** (Optional).
|
||||
|
||||
Length of passphrase to generate. By default length is 24.
|
||||
Minimum length is 24. No maximum length.
|
||||
|
||||
Usage:
|
||||
|
||||
::
|
||||
|
||||
./pegleg.sh generate passphrase -l <length>
|
||||
|
||||
Examples
|
||||
^^^^^^^^
|
||||
|
||||
Example without length specified:
|
||||
|
||||
::
|
||||
|
||||
./pegleg.sh generate passphrase
|
||||
|
||||
Example with length specified:
|
||||
|
||||
::
|
||||
|
||||
./pegleg.sh generate passphrase -l <length>
|
||||
|
@ -528,9 +528,25 @@ def encrypt(*, save_location, author, site_name):
|
||||
@click.argument('site_name')
|
||||
def decrypt(*, file_name, site_name):
|
||||
engine.repository.process_repositories(site_name)
|
||||
try:
|
||||
click.echo(engine.secrets.decrypt(file_name, site_name))
|
||||
except FileNotFoundError:
|
||||
raise click.exceptions.FileError("Couldn't find file %s, "
|
||||
"check your arguments and try "
|
||||
"again." % file_name)
|
||||
|
||||
engine.secrets.decrypt(file_name, site_name)
|
||||
|
||||
|
||||
@main.group(help="Miscellaneous generate commands")
|
||||
def generate():
|
||||
pass
|
||||
|
||||
|
||||
@generate.command(
|
||||
'passphrase',
|
||||
help='Command to generate a passphrase and print out to stdout')
|
||||
@click.option(
|
||||
'-l',
|
||||
'--length',
|
||||
'length',
|
||||
default=24,
|
||||
help='Generate a passphrase of the given length. '
|
||||
'Length is >= 24, default length is 24, no maximum length')
|
||||
def generate_passphrase(length):
|
||||
click.echo("Generated Passhprase: {}".format(
|
||||
engine.secrets.generate_passphrase(length)))
|
||||
|
@ -15,9 +15,10 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from pegleg.engine.generators.passpharase_generator import PassphraseGenerator
|
||||
from pegleg.engine.generators.passphrase_generator import PassphraseGenerator
|
||||
from pegleg.engine.util import definition
|
||||
from pegleg.engine.util import files
|
||||
from pegleg.engine.util.passphrase import Passphrase
|
||||
from pegleg.engine.util.pegleg_secret_management import PeglegSecretManagement
|
||||
|
||||
__all__ = ('encrypt', 'decrypt', 'generate_passphrases')
|
||||
@ -129,3 +130,14 @@ def generate_passphrases(site_name, save_location, author, interactive=False):
|
||||
|
||||
PassphraseGenerator(site_name, save_location, author).generate(
|
||||
interactive=interactive)
|
||||
|
||||
|
||||
def generate_passphrase(length):
|
||||
"""
|
||||
Create a passphrase.
|
||||
|
||||
:param int length: Length of passphrase.
|
||||
:rtype: string
|
||||
"""
|
||||
|
||||
return Passphrase().get_pass(length)
|
||||
|
@ -20,7 +20,7 @@ import string
|
||||
import yaml
|
||||
|
||||
from pegleg.engine.util.passphrase import Passphrase
|
||||
from pegleg.engine.generators.passpharase_generator import PassphraseGenerator
|
||||
from pegleg.engine.generators.passphrase_generator import PassphraseGenerator
|
||||
from pegleg.engine.util import encryption
|
||||
from pegleg.engine import util
|
||||
import pegleg
|
||||
|
@ -64,6 +64,12 @@ def test_encrypt_and_decrypt():
|
||||
enc2 = crypt.encrypt(dec1, passphrase, salt)
|
||||
dec2 = crypt.decrypt(enc2, passphrase, salt)
|
||||
assert data == dec2
|
||||
passphrase2 = test_utils.rand_name("passphrase2", "pegleg").encode()
|
||||
salt2 = test_utils.rand_name("salt2", "pegleg").encode()
|
||||
enc3 = crypt.encrypt(dec2, passphrase2, salt2)
|
||||
dec3 = crypt.decrypt(enc3, passphrase2, salt2)
|
||||
assert data == dec3
|
||||
assert data != enc3
|
||||
|
||||
|
||||
@mock.patch.dict(os.environ, {
|
||||
|
@ -383,6 +383,13 @@ class TestSiteCliActions(BaseCLIActionTest):
|
||||
mock_obj.assert_called_once()
|
||||
|
||||
|
||||
class TestGenerateActions(BaseCLIActionTest):
|
||||
def test_generate_passphrase(self):
|
||||
result = self.runner.invoke(cli.generate, ['passphrase'])
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
|
||||
|
||||
class TestRepoCliActions(BaseCLIActionTest):
|
||||
"""Tests repo-level CLI actions."""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user