summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Hughes <ah8742@att.com>2019-01-02 12:10:35 -0600
committerAlexander Hughes <ah8742@att.com>2019-02-04 12:32:39 -0600
commit4b00a4340c65280177b4efd7d2430e06258e964e (patch)
treec64763fd3685c8942b8d18d04549b83d6ce90bac
parente6af6ae87e1d9265a09204eaf955a4965ad7e15f (diff)
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
Notes
Notes (review): Code-Review+2: Matt McEuen <matt.mceuen@att.com> Code-Review+1: chittibabu <chittibabu1299@gmail.com> Code-Review+2: Bryan Strassner <strassner.bryan@gmail.com> Workflow+1: Bryan Strassner <strassner.bryan@gmail.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Tue, 05 Feb 2019 17:07:15 +0000 Reviewed-on: https://review.openstack.org/628021 Project: openstack/airship-pegleg Branch: refs/heads/master
-rw-r--r--doc/source/cli/cli.rst37
-rw-r--r--pegleg/cli.py28
-rw-r--r--pegleg/engine/generators/passphrase_generator.py (renamed from pegleg/engine/generators/passpharase_generator.py)0
-rw-r--r--pegleg/engine/secrets.py14
-rw-r--r--tests/unit/engine/test_generate_passphrases.py2
-rw-r--r--tests/unit/engine/test_secrets.py6
-rw-r--r--tests/unit/test_cli.py7
7 files changed, 86 insertions, 8 deletions
diff --git a/doc/source/cli/cli.rst b/doc/source/cli/cli.rst
index 16fea95..7279bb0 100644
--- a/doc/source/cli/cli.rst
+++ b/doc/source/cli/cli.rst
@@ -809,3 +809,40 @@ P003 - All repos contain expected directories.
809.. _Shipyard: https://github.com/openstack/airship-shipyard 809.. _Shipyard: https://github.com/openstack/airship-shipyard
810.. _CLI documentation: https://airship-shipyard.readthedocs.io/en/latest/CLI.html#openstack-keystone-authorization-environment-variables 810.. _CLI documentation: https://airship-shipyard.readthedocs.io/en/latest/CLI.html#openstack-keystone-authorization-environment-variables
811.. _Pegleg Passphrase Catalog: https://airship-specs.readthedocs.io/en/latest/specs/approved/pegleg-secrets.html#document-generation 811.. _Pegleg Passphrase Catalog: https://airship-specs.readthedocs.io/en/latest/specs/approved/pegleg-secrets.html#document-generation
812
813
814Generate
815========
816
817Allows you to perform generate operations.
818
819Passphrase
820----------
821
822Generate a passphrase and print to ``stdout``.
823
824**-l / --length** (Optional).
825
826Length of passphrase to generate. By default length is 24.
827Minimum length is 24. No maximum length.
828
829Usage:
830
831::
832
833 ./pegleg.sh generate passphrase -l <length>
834
835Examples
836^^^^^^^^
837
838Example without length specified:
839
840::
841
842 ./pegleg.sh generate passphrase
843
844Example with length specified:
845
846::
847
848 ./pegleg.sh generate passphrase -l <length>
diff --git a/pegleg/cli.py b/pegleg/cli.py
index 603e10f..ca38864 100644
--- a/pegleg/cli.py
+++ b/pegleg/cli.py
@@ -528,9 +528,25 @@ def encrypt(*, save_location, author, site_name):
528@click.argument('site_name') 528@click.argument('site_name')
529def decrypt(*, file_name, site_name): 529def decrypt(*, file_name, site_name):
530 engine.repository.process_repositories(site_name) 530 engine.repository.process_repositories(site_name)
531 try: 531
532 click.echo(engine.secrets.decrypt(file_name, site_name)) 532 engine.secrets.decrypt(file_name, site_name)
533 except FileNotFoundError: 533
534 raise click.exceptions.FileError("Couldn't find file %s, " 534
535 "check your arguments and try " 535@main.group(help="Miscellaneous generate commands")
536 "again." % file_name) 536def generate():
537 pass
538
539
540@generate.command(
541 'passphrase',
542 help='Command to generate a passphrase and print out to stdout')
543@click.option(
544 '-l',
545 '--length',
546 'length',
547 default=24,
548 help='Generate a passphrase of the given length. '
549 'Length is >= 24, default length is 24, no maximum length')
550def generate_passphrase(length):
551 click.echo("Generated Passhprase: {}".format(
552 engine.secrets.generate_passphrase(length)))
diff --git a/pegleg/engine/generators/passpharase_generator.py b/pegleg/engine/generators/passphrase_generator.py
index c20f7f8..c20f7f8 100644
--- a/pegleg/engine/generators/passpharase_generator.py
+++ b/pegleg/engine/generators/passphrase_generator.py
diff --git a/pegleg/engine/secrets.py b/pegleg/engine/secrets.py
index 743e86f..0402690 100644
--- a/pegleg/engine/secrets.py
+++ b/pegleg/engine/secrets.py
@@ -15,9 +15,10 @@
15import logging 15import logging
16import os 16import os
17 17
18from pegleg.engine.generators.passpharase_generator import PassphraseGenerator 18from pegleg.engine.generators.passphrase_generator import PassphraseGenerator
19from pegleg.engine.util import definition 19from pegleg.engine.util import definition
20from pegleg.engine.util import files 20from pegleg.engine.util import files
21from pegleg.engine.util.passphrase import Passphrase
21from pegleg.engine.util.pegleg_secret_management import PeglegSecretManagement 22from pegleg.engine.util.pegleg_secret_management import PeglegSecretManagement
22 23
23__all__ = ('encrypt', 'decrypt', 'generate_passphrases') 24__all__ = ('encrypt', 'decrypt', 'generate_passphrases')
@@ -129,3 +130,14 @@ def generate_passphrases(site_name, save_location, author, interactive=False):
129 130
130 PassphraseGenerator(site_name, save_location, author).generate( 131 PassphraseGenerator(site_name, save_location, author).generate(
131 interactive=interactive) 132 interactive=interactive)
133
134
135def generate_passphrase(length):
136 """
137 Create a passphrase.
138
139 :param int length: Length of passphrase.
140 :rtype: string
141 """
142
143 return Passphrase().get_pass(length)
diff --git a/tests/unit/engine/test_generate_passphrases.py b/tests/unit/engine/test_generate_passphrases.py
index d14ed69..74f0af7 100644
--- a/tests/unit/engine/test_generate_passphrases.py
+++ b/tests/unit/engine/test_generate_passphrases.py
@@ -20,7 +20,7 @@ import string
20import yaml 20import yaml
21 21
22from pegleg.engine.util.passphrase import Passphrase 22from pegleg.engine.util.passphrase import Passphrase
23from pegleg.engine.generators.passpharase_generator import PassphraseGenerator 23from pegleg.engine.generators.passphrase_generator import PassphraseGenerator
24from pegleg.engine.util import encryption 24from pegleg.engine.util import encryption
25from pegleg.engine import util 25from pegleg.engine import util
26import pegleg 26import pegleg
diff --git a/tests/unit/engine/test_secrets.py b/tests/unit/engine/test_secrets.py
index 3940325..cfe147c 100644
--- a/tests/unit/engine/test_secrets.py
+++ b/tests/unit/engine/test_secrets.py
@@ -64,6 +64,12 @@ def test_encrypt_and_decrypt():
64 enc2 = crypt.encrypt(dec1, passphrase, salt) 64 enc2 = crypt.encrypt(dec1, passphrase, salt)
65 dec2 = crypt.decrypt(enc2, passphrase, salt) 65 dec2 = crypt.decrypt(enc2, passphrase, salt)
66 assert data == dec2 66 assert data == dec2
67 passphrase2 = test_utils.rand_name("passphrase2", "pegleg").encode()
68 salt2 = test_utils.rand_name("salt2", "pegleg").encode()
69 enc3 = crypt.encrypt(dec2, passphrase2, salt2)
70 dec3 = crypt.decrypt(enc3, passphrase2, salt2)
71 assert data == dec3
72 assert data != enc3
67 73
68 74
69@mock.patch.dict(os.environ, { 75@mock.patch.dict(os.environ, {
diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py
index ea7dd32..170d81b 100644
--- a/tests/unit/test_cli.py
+++ b/tests/unit/test_cli.py
@@ -383,6 +383,13 @@ class TestSiteCliActions(BaseCLIActionTest):
383 mock_obj.assert_called_once() 383 mock_obj.assert_called_once()
384 384
385 385
386class TestGenerateActions(BaseCLIActionTest):
387 def test_generate_passphrase(self):
388 result = self.runner.invoke(cli.generate, ['passphrase'])
389
390 assert result.exit_code == 0, result.output
391
392
386class TestRepoCliActions(BaseCLIActionTest): 393class TestRepoCliActions(BaseCLIActionTest):
387 """Tests repo-level CLI actions.""" 394 """Tests repo-level CLI actions."""
388 395