Browse Source

Search all scopes for catalogs

This patch revises pegleg to check all scopes for catalog files,
rather than just the site scope.

Change-Id: Icf03ce739968ef3ed5fd218ca0fe87e24451ba0d
changes/21/634821/10
Lev Morgan 3 months ago
parent
commit
0252b71750

+ 10
- 12
pegleg/engine/catalogs/base_catalog.py View File

@@ -14,7 +14,6 @@
14 14
 
15 15
 from abc import ABC
16 16
 import logging
17
-import os
18 17
 import re
19 18
 
20 19
 from pegleg import config
@@ -43,7 +42,7 @@ class BaseCatalog(ABC):
43 42
         """
44 43
         self._documents = documents or definition.documents_for_site(sitename)
45 44
         self._site_name = sitename
46
-        self._catalog_path = None
45
+        self._catalog_path = []
47 46
         self._kind = kind
48 47
         self._catalog_docs = list()
49 48
         for document in self._documents:
@@ -61,7 +60,7 @@ class BaseCatalog(ABC):
61 60
 
62 61
     @property
63 62
     def catalog_path(self):
64
-        if self._catalog_path is None:
63
+        if not self._catalog_path:
65 64
             self._set_catalog_path()
66 65
         return self._catalog_path
67 66
 
@@ -69,15 +68,14 @@ class BaseCatalog(ABC):
69 68
         repo_name = git.repo_url(config.get_site_repo())
70 69
         catalog_name = self._get_document_name('{}.yaml'.format(self._kind))
71 70
         for file_path in definition.site_files(self.site_name):
72
-            if file_path.endswith(catalog_name) and repo_name in file_path:
73
-                self._catalog_path = os.path.join(
74
-                    repo_name, file_path.split(repo_name)[1].lstrip('/'))
75
-                return
76
-        # Cound not find the Catalog for this generated passphrase
77
-        # raise an exception.
78
-        LOG.error('Catalog path: {} was not found in repo: {}'.format(
79
-            catalog_name, repo_name))
80
-        raise PassphraseCatalogNotFoundException()
71
+            if file_path.endswith(catalog_name):
72
+                self._catalog_path.append(file_path)
73
+        if not self._catalog_path:
74
+            # Cound not find the Catalog for this generated passphrase
75
+            # raise an exception.
76
+            LOG.error('Catalog path: {} was not found in repo: {}'.format(
77
+                catalog_name, repo_name))
78
+            raise PassphraseCatalogNotFoundException()
81 79
 
82 80
     def _get_document_name(self, name):
83 81
         s1 = re.sub('(.)([A-Z][a-z]+)', r'\1-\2', name)

+ 72
- 4
tests/unit/engine/test_generate_cryptostring.py View File

@@ -69,6 +69,24 @@ data:
69 69
 ...
70 70
 """)
71 71
 
72
+TEST_GLOBAL_PASSPHRASES_CATALOG = yaml.load("""
73
+---
74
+schema: pegleg/PassphraseCatalog/v1
75
+metadata:
76
+  schema: metadata/Document/v1
77
+  name: cluster-passphrases
78
+  layeringDefinition:
79
+    abstract: false
80
+    layer: global
81
+  storagePolicy: cleartext
82
+data:
83
+  passphrases:
84
+    - description: 'description of passphrase from global'
85
+      document_name: passphrase_from_global
86
+      encrypted: true
87
+...
88
+""")
89
+
72 90
 TEST_REPOSITORIES = {
73 91
     'repositories': {
74 92
         'global': {
@@ -101,6 +119,7 @@ TEST_SITE_DEFINITION = {
101 119
 }
102 120
 
103 121
 TEST_SITE_DOCUMENTS = [TEST_SITE_DEFINITION, TEST_PASSPHRASES_CATALOG]
122
+TEST_GLOBAL_SITE_DOCUMENTS = [TEST_SITE_DEFINITION, TEST_GLOBAL_PASSPHRASES_CATALOG]
104 123
 
105 124
 
106 125
 def test_cryptostring_default_len():
@@ -149,13 +168,13 @@ def test_cryptostring_long_len():
149 168
     ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
150 169
     ENV_SALT: 'MySecretSalt'})
151 170
 def test_generate_passphrases(*_):
152
-    dir = tempfile.mkdtemp()
153
-    os.makedirs(os.path.join(dir, 'cicd_site_repo'), exist_ok=True)
154
-    PassphraseGenerator('cicd', dir, 'test_author').generate()
171
+    _dir = tempfile.mkdtemp()
172
+    os.makedirs(os.path.join(_dir, 'cicd_site_repo'), exist_ok=True)
173
+    PassphraseGenerator('cicd', _dir, 'test_author').generate()
155 174
 
156 175
     for passphrase in TEST_PASSPHRASES_CATALOG['data']['passphrases']:
157 176
         passphrase_file_name = '{}.yaml'.format(passphrase['document_name'])
158
-        passphrase_file_path = os.path.join(dir, 'site', 'cicd', 'secrets',
177
+        passphrase_file_path = os.path.join(_dir, 'site', 'cicd', 'secrets',
159 178
                                             'passphrases',
160 179
                                             passphrase_file_name)
161 180
         assert os.path.isfile(passphrase_file_path)
@@ -200,3 +219,52 @@ def test_generate_passphrases_exception(capture):
200 219
                    ('Signature verification to decrypt secrets failed. '
201 220
                     'Please check your provided passphrase and salt and '
202 221
                     'try again.')))
222
+
223
+
224
+@mock.patch.object(
225
+    util.definition,
226
+    'documents_for_site',
227
+    autospec=True,
228
+    return_value=TEST_GLOBAL_SITE_DOCUMENTS)
229
+@mock.patch.object(
230
+    pegleg.config,
231
+    'get_site_repo',
232
+    autospec=True,
233
+    return_value='cicd_site_repo')
234
+@mock.patch.object(
235
+    util.definition,
236
+    'site_files',
237
+    autospec=True,
238
+    return_value=[
239
+        'cicd_global_repo/site/cicd/passphrases/passphrase-catalog.yaml', ])
240
+@mock.patch.dict(os.environ, {
241
+    ENV_PASSPHRASE: 'ytrr89erARAiPE34692iwUMvWqqBvC',
242
+    ENV_SALT: 'MySecretSalt'})
243
+def test_global_passphrase_catalog(*_):
244
+    _dir = tempfile.mkdtemp()
245
+    os.makedirs(os.path.join(_dir, 'cicd_site_repo'), exist_ok=True)
246
+    PassphraseGenerator('cicd', _dir, 'test_author').generate()
247
+
248
+    for passphrase in TEST_GLOBAL_PASSPHRASES_CATALOG['data']['passphrases']:
249
+        passphrase_file_name = '{}.yaml'.format(passphrase['document_name'])
250
+        passphrase_file_path = os.path.join(_dir, 'site', 'cicd', 'secrets',
251
+                                            'passphrases',
252
+                                            passphrase_file_name)
253
+        assert os.path.isfile(passphrase_file_path)
254
+        with open(passphrase_file_path) as stream:
255
+            doc = yaml.safe_load(stream)
256
+            assert doc['schema'] == 'pegleg/PeglegManagedDocument/v1'
257
+            assert doc['metadata']['storagePolicy'] == 'cleartext'
258
+            assert 'encrypted' in doc['data']
259
+            assert doc['data']['encrypted']['by'] == 'test_author'
260
+            assert 'generated' in doc['data']
261
+            assert doc['data']['generated']['by'] == 'test_author'
262
+            assert 'managedDocument' in doc['data']
263
+            assert doc['data']['managedDocument']['metadata'][
264
+                       'storagePolicy'] == 'encrypted'
265
+            decrypted_passphrase = encryption.decrypt(
266
+                doc['data']['managedDocument']['data'],
267
+                os.environ['PEGLEG_PASSPHRASE'].encode(),
268
+                os.environ['PEGLEG_SALT'].encode())
269
+            if passphrase_file_name == "passphrase_from_global.yaml":
270
+                assert len(decrypted_passphrase) == 24

Loading…
Cancel
Save