diff options
author | Zuul <zuul@review.openstack.org> | 2018-11-14 22:34:23 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2018-11-14 22:34:23 +0000 |
commit | 03d7269b6ad9d7b734cb3a7bc1693139e639a9c5 (patch) | |
tree | 57d32bb5b0d3c9170e8697f759c78907db3d8799 | |
parent | 84d99967bca73bef43e9ed70adc7e47cbd53ecf3 (diff) | |
parent | 407cdc76d084fb27404104ee183da042d421ad7e (diff) |
Merge "Ensure SY gets redacted rendered documents"
13 files changed, 59 insertions, 18 deletions
diff --git a/charts/shipyard/values.yaml b/charts/shipyard/values.yaml index fc51894..60233b1 100644 --- a/charts/shipyard/values.yaml +++ b/charts/shipyard/values.yaml | |||
@@ -370,6 +370,7 @@ conf: | |||
370 | workflow_orchestrator:get_configdocs: rule:admin_read_access | 370 | workflow_orchestrator:get_configdocs: rule:admin_read_access |
371 | workflow_orchestrator:commit_configdocs: rule:admin_create | 371 | workflow_orchestrator:commit_configdocs: rule:admin_create |
372 | workflow_orchestrator:get_renderedconfigdocs: rule:admin_read_access | 372 | workflow_orchestrator:get_renderedconfigdocs: rule:admin_read_access |
373 | workflow_orchestrator:get_renderedconfigdocs_cleartext: rule:admin_read_access | ||
373 | workflow_orchestrator:list_workflows: rule:admin_read_access | 374 | workflow_orchestrator:list_workflows: rule:admin_read_access |
374 | workflow_orchestrator:get_workflow: rule:admin_read_access | 375 | workflow_orchestrator:get_workflow: rule:admin_read_access |
375 | workflow_orchestrator:get_notedetails: rule:admin_read_access | 376 | workflow_orchestrator:get_notedetails: rule:admin_read_access |
diff --git a/doc/source/API.rst b/doc/source/API.rst index 79bc8ea..1abce10 100644 --- a/doc/source/API.rst +++ b/doc/source/API.rst | |||
@@ -259,8 +259,11 @@ Returns the full set of configdocs in their rendered form. | |||
259 | 259 | ||
260 | Query Parameters | 260 | Query Parameters |
261 | '''''''''''''''' | 261 | '''''''''''''''' |
262 | version=committed | last_site_action | successful_site_action | **buffer** | 262 | - version=committed | last_site_action | successful_site_action | **buffer** |
263 | Return the documents for the version specified - buffer by default. | 263 | Return the documents for the version specified - buffer by default. |
264 | - cleartext-secrets=true/**false** | ||
265 | If true then returns cleartext secrets in encrypted documents, otherwise | ||
266 | those values are redacted. | ||
264 | 267 | ||
265 | Responses | 268 | Responses |
266 | ''''''''' | 269 | ''''''''' |
diff --git a/doc/source/CLI.rst b/doc/source/CLI.rst index abbdca7..bca045f 100644 --- a/doc/source/CLI.rst +++ b/doc/source/CLI.rst | |||
@@ -726,6 +726,7 @@ applying Deckhand layering and substitution. | |||
726 | 726 | ||
727 | shipyard get renderedconfigdocs | 727 | shipyard get renderedconfigdocs |
728 | [--committed | --last-site-action | --successful-site-action | --buffer] | 728 | [--committed | --last-site-action | --successful-site-action | --buffer] |
729 | [--cleartext-secrets] | ||
729 | 730 | ||
730 | Example: | 731 | Example: |
731 | shipyard get renderedconfigdocs | 732 | shipyard get renderedconfigdocs |
@@ -743,6 +744,10 @@ applying Deckhand layering and substitution. | |||
743 | Retrieve the documents that have been loaded into Shipyard since the | 744 | Retrieve the documents that have been loaded into Shipyard since the |
744 | prior commit. (default) | 745 | prior commit. (default) |
745 | 746 | ||
747 | \--cleartext-secrets | ||
748 | Returns secrets as cleartext for encrypted documents if the user has the appropriate | ||
749 | permissions in the target environment. | ||
750 | |||
746 | Sample | 751 | Sample |
747 | ^^^^^^ | 752 | ^^^^^^ |
748 | 753 | ||
diff --git a/src/bin/shipyard_airflow/shipyard_airflow/control/configdocs/configdocs_api.py b/src/bin/shipyard_airflow/shipyard_airflow/control/configdocs/configdocs_api.py index a778c98..2b2f61e 100644 --- a/src/bin/shipyard_airflow/shipyard_airflow/control/configdocs/configdocs_api.py +++ b/src/bin/shipyard_airflow/shipyard_airflow/control/configdocs/configdocs_api.py | |||
@@ -98,7 +98,7 @@ class ConfigDocsResource(BaseResource): | |||
98 | Returns a collection of documents | 98 | Returns a collection of documents |
99 | """ | 99 | """ |
100 | version = (req.params.get('version') or 'buffer') | 100 | version = (req.params.get('version') or 'buffer') |
101 | cleartext_secrets = req.get_param_as_bool('cleartext-secrets') | 101 | cleartext_secrets = req.get_param_as_bool('cleartext-secrets') or False |
102 | self._validate_version_parameter(version) | 102 | self._validate_version_parameter(version) |
103 | helper = ConfigdocsHelper(req.context) | 103 | helper = ConfigdocsHelper(req.context) |
104 | # Not reformatting to JSON or YAML since just passing through | 104 | # Not reformatting to JSON or YAML since just passing through |
diff --git a/src/bin/shipyard_airflow/shipyard_airflow/control/configdocs/rendered_configdocs_api.py b/src/bin/shipyard_airflow/shipyard_airflow/control/configdocs/rendered_configdocs_api.py index 0bb8d47..e5c2494 100644 --- a/src/bin/shipyard_airflow/shipyard_airflow/control/configdocs/rendered_configdocs_api.py +++ b/src/bin/shipyard_airflow/shipyard_airflow/control/configdocs/rendered_configdocs_api.py | |||
@@ -43,11 +43,19 @@ class RenderedConfigDocsResource(BaseResource): | |||
43 | Returns the whole set of rendered documents | 43 | Returns the whole set of rendered documents |
44 | """ | 44 | """ |
45 | version = (req.params.get('version') or 'buffer') | 45 | version = (req.params.get('version') or 'buffer') |
46 | cleartext_secrets = req.get_param_as_bool('cleartext-secrets') or False | ||
46 | self._validate_version_parameter(version) | 47 | self._validate_version_parameter(version) |
47 | helper = ConfigdocsHelper(req.context) | 48 | helper = ConfigdocsHelper(req.context) |
49 | |||
50 | # Check access to cleartext_secrets | ||
51 | if cleartext_secrets: | ||
52 | policy.check_auth(req.context, | ||
53 | policy.GET_RENDEREDCONFIGDOCS_CLRTXT) | ||
54 | |||
48 | resp.body = self.get_rendered_configdocs( | 55 | resp.body = self.get_rendered_configdocs( |
49 | helper=helper, | 56 | helper=helper, |
50 | version=version | 57 | version=version, |
58 | cleartext_secrets=cleartext_secrets | ||
51 | ) | 59 | ) |
52 | resp.append_header('Content-Type', 'application/x-yaml') | 60 | resp.append_header('Content-Type', 'application/x-yaml') |
53 | resp.status = falcon.HTTP_200 | 61 | resp.status = falcon.HTTP_200 |
@@ -64,8 +72,9 @@ class RenderedConfigDocsResource(BaseResource): | |||
64 | retry=False, | 72 | retry=False, |
65 | ) | 73 | ) |
66 | 74 | ||
67 | def get_rendered_configdocs(self, helper, version='buffer'): | 75 | def get_rendered_configdocs(self, helper, version='buffer', |
76 | cleartext_secrets=False): | ||
68 | """ | 77 | """ |
69 | Get and return the rendered configdocs from the helper/Deckhand | 78 | Get and return the rendered configdocs from the helper/Deckhand |
70 | """ | 79 | """ |
71 | return helper.get_rendered_configdocs(version) | 80 | return helper.get_rendered_configdocs(version, cleartext_secrets) |
diff --git a/src/bin/shipyard_airflow/shipyard_airflow/control/helpers/configdocs_helper.py b/src/bin/shipyard_airflow/shipyard_airflow/control/helpers/configdocs_helper.py index 3ba2722..19982e0 100644 --- a/src/bin/shipyard_airflow/shipyard_airflow/control/helpers/configdocs_helper.py +++ b/src/bin/shipyard_airflow/shipyard_airflow/control/helpers/configdocs_helper.py | |||
@@ -375,7 +375,7 @@ class ConfigdocsHelper(object): | |||
375 | status=falcon.HTTP_404, | 375 | status=falcon.HTTP_404, |
376 | retry=False) | 376 | retry=False) |
377 | 377 | ||
378 | def get_rendered_configdocs(self, version=BUFFER): | 378 | def get_rendered_configdocs(self, version=BUFFER, cleartext_secrets=False): |
379 | """ | 379 | """ |
380 | Returns the rendered configuration documents for the specified | 380 | Returns the rendered configuration documents for the specified |
381 | revision (by name BUFFER, COMMITTED, LAST_SITE_ACTION, | 381 | revision (by name BUFFER, COMMITTED, LAST_SITE_ACTION, |
@@ -397,6 +397,7 @@ class ConfigdocsHelper(object): | |||
397 | 397 | ||
398 | try: | 398 | try: |
399 | return self.deckhand.get_rendered_docs_from_revision( | 399 | return self.deckhand.get_rendered_docs_from_revision( |
400 | cleartext_secrets=cleartext_secrets, | ||
400 | revision_id=revision_id) | 401 | revision_id=revision_id) |
401 | except DeckhandError as de: | 402 | except DeckhandError as de: |
402 | raise ApiError( | 403 | raise ApiError( |
diff --git a/src/bin/shipyard_airflow/shipyard_airflow/control/helpers/deckhand_client.py b/src/bin/shipyard_airflow/shipyard_airflow/control/helpers/deckhand_client.py index 4b43028..487e1fc 100644 --- a/src/bin/shipyard_airflow/shipyard_airflow/control/helpers/deckhand_client.py +++ b/src/bin/shipyard_airflow/shipyard_airflow/control/helpers/deckhand_client.py | |||
@@ -232,7 +232,8 @@ class DeckhandClient(object): | |||
232 | response.text))}) | 232 | response.text))}) |
233 | return errors | 233 | return errors |
234 | 234 | ||
235 | def get_rendered_docs_from_revision(self, revision_id, bucket_id=None): | 235 | def get_rendered_docs_from_revision(self, revision_id, bucket_id=None, |
236 | cleartext_secrets=False): | ||
236 | """ | 237 | """ |
237 | Returns the full set of rendered documents for a revision | 238 | Returns the full set of rendered documents for a revision |
238 | """ | 239 | """ |
@@ -240,9 +241,11 @@ class DeckhandClient(object): | |||
240 | DeckhandPaths.RENDERED_REVISION_DOCS | 241 | DeckhandPaths.RENDERED_REVISION_DOCS |
241 | ).format(revision_id) | 242 | ).format(revision_id) |
242 | 243 | ||
243 | query = None | 244 | query = {} |
244 | if bucket_id is not None: | 245 | if bucket_id is not None: |
245 | query = {'status.bucket': bucket_id} | 246 | query = {'status.bucket': bucket_id} |
247 | if cleartext_secrets is True: | ||
248 | query['cleartext-secrets'] = 'true' | ||
246 | response = self._get_request(url, params=query) | 249 | response = self._get_request(url, params=query) |
247 | self._handle_bad_response(response) | 250 | self._handle_bad_response(response) |
248 | return response.text | 251 | return response.text |
diff --git a/src/bin/shipyard_airflow/shipyard_airflow/policy.py b/src/bin/shipyard_airflow/shipyard_airflow/policy.py index 731503c..fe506c3 100644 --- a/src/bin/shipyard_airflow/shipyard_airflow/policy.py +++ b/src/bin/shipyard_airflow/shipyard_airflow/policy.py | |||
@@ -38,6 +38,7 @@ CREATE_CONFIGDOCS = 'workflow_orchestrator:create_configdocs' | |||
38 | GET_CONFIGDOCS = 'workflow_orchestrator:get_configdocs' | 38 | GET_CONFIGDOCS = 'workflow_orchestrator:get_configdocs' |
39 | COMMIT_CONFIGDOCS = 'workflow_orchestrator:commit_configdocs' | 39 | COMMIT_CONFIGDOCS = 'workflow_orchestrator:commit_configdocs' |
40 | GET_RENDEREDCONFIGDOCS = 'workflow_orchestrator:get_renderedconfigdocs' | 40 | GET_RENDEREDCONFIGDOCS = 'workflow_orchestrator:get_renderedconfigdocs' |
41 | GET_RENDEREDCONFIGDOCS_CLRTXT = 'workflow_orchestrator:get_renderedconfigdocs_cleartext' # noqa | ||
41 | LIST_WORKFLOWS = 'workflow_orchestrator:list_workflows' | 42 | LIST_WORKFLOWS = 'workflow_orchestrator:list_workflows' |
42 | GET_WORKFLOW = 'workflow_orchestrator:get_workflow' | 43 | GET_WORKFLOW = 'workflow_orchestrator:get_workflow' |
43 | GET_NOTEDETAILS = 'workflow_orchestrator:get_notedetails' | 44 | GET_NOTEDETAILS = 'workflow_orchestrator:get_notedetails' |
@@ -188,6 +189,16 @@ class ShipyardPolicy(object): | |||
188 | }] | 189 | }] |
189 | ), | 190 | ), |
190 | policy.DocumentedRuleDefault( | 191 | policy.DocumentedRuleDefault( |
192 | GET_RENDEREDCONFIGDOCS_CLRTXT, | ||
193 | RULE_ADMIN_REQUIRED, | ||
194 | ('Retrieve the configuration documents with cleartext secrets ' | ||
195 | 'rendered by Deckhand into a complete design'), | ||
196 | [{ | ||
197 | 'path': '/api/v1.0/renderedconfigdocs', | ||
198 | 'method': 'GET' | ||
199 | }] | ||
200 | ), | ||
201 | policy.DocumentedRuleDefault( | ||
191 | LIST_WORKFLOWS, | 202 | LIST_WORKFLOWS, |
192 | RULE_ADMIN_REQUIRED, | 203 | RULE_ADMIN_REQUIRED, |
193 | ('Retrieve the list of workflows (DAGs) that have been invoked ' | 204 | ('Retrieve the list of workflows (DAGs) that have been invoked ' |
diff --git a/src/bin/shipyard_airflow/tests/unit/control/test_rendered_configdocs_api.py b/src/bin/shipyard_airflow/tests/unit/control/test_rendered_configdocs_api.py index 9128616..fb122cb 100644 --- a/src/bin/shipyard_airflow/tests/unit/control/test_rendered_configdocs_api.py +++ b/src/bin/shipyard_airflow/tests/unit/control/test_rendered_configdocs_api.py | |||
@@ -52,7 +52,7 @@ def test_get_rendered_configdocs(): | |||
52 | helper = ConfigdocsHelper(CTX) | 52 | helper = ConfigdocsHelper(CTX) |
53 | rcdr.get_rendered_configdocs(helper, version='buffer') | 53 | rcdr.get_rendered_configdocs(helper, version='buffer') |
54 | 54 | ||
55 | mock_method.assert_called_once_with('buffer') | 55 | mock_method.assert_called_once_with('buffer', False) |
56 | 56 | ||
57 | 57 | ||
58 | def test_get_rendered_last_site_action_configdocs(): | 58 | def test_get_rendered_last_site_action_configdocs(): |
@@ -68,7 +68,7 @@ def test_get_rendered_last_site_action_configdocs(): | |||
68 | helper = ConfigdocsHelper(CTX) | 68 | helper = ConfigdocsHelper(CTX) |
69 | rcdr.get_rendered_configdocs(helper, version='last_site_action') | 69 | rcdr.get_rendered_configdocs(helper, version='last_site_action') |
70 | 70 | ||
71 | mock_method.assert_called_once_with('last_site_action') | 71 | mock_method.assert_called_once_with('last_site_action', False) |
72 | 72 | ||
73 | 73 | ||
74 | def test_get_rendered_successful_site_action_configdocs(): | 74 | def test_get_rendered_successful_site_action_configdocs(): |
@@ -84,4 +84,4 @@ def test_get_rendered_successful_site_action_configdocs(): | |||
84 | helper = ConfigdocsHelper(CTX) | 84 | helper = ConfigdocsHelper(CTX) |
85 | rcdr.get_rendered_configdocs(helper, version='successful_site_action') | 85 | rcdr.get_rendered_configdocs(helper, version='successful_site_action') |
86 | 86 | ||
87 | mock_method.assert_called_once_with('successful_site_action') | 87 | mock_method.assert_called_once_with('successful_site_action', False) |
diff --git a/src/bin/shipyard_client/shipyard_client/api_client/shipyard_api_client.py b/src/bin/shipyard_client/shipyard_client/api_client/shipyard_api_client.py index 42b578f..1b25140 100644 --- a/src/bin/shipyard_client/shipyard_client/api_client/shipyard_api_client.py +++ b/src/bin/shipyard_client/shipyard_client/api_client/shipyard_api_client.py | |||
@@ -96,7 +96,7 @@ class ShipyardClient(BaseClient): | |||
96 | url = ApiPaths.GET_CONFIGDOCS.value.format(self.get_endpoint()) | 96 | url = ApiPaths.GET_CONFIGDOCS.value.format(self.get_endpoint()) |
97 | return self.get_resp(url, query_params) | 97 | return self.get_resp(url, query_params) |
98 | 98 | ||
99 | def get_rendereddocs(self, version='buffer'): | 99 | def get_rendereddocs(self, version='buffer', cleartext_secrets=False): |
100 | """ | 100 | """ |
101 | :param str version: committed|buffer|last_site_action| | 101 | :param str version: committed|buffer|last_site_action| |
102 | successful_site_action | 102 | successful_site_action |
@@ -104,6 +104,8 @@ class ShipyardClient(BaseClient): | |||
104 | :rtype: Response object | 104 | :rtype: Response object |
105 | """ | 105 | """ |
106 | query_params = {"version": version} | 106 | query_params = {"version": version} |
107 | if cleartext_secrets is True: | ||
108 | query_params['cleartext-secrets'] = 'true' | ||
107 | url = ApiPaths.GET_RENDERED.value.format( | 109 | url = ApiPaths.GET_RENDERED.value.format( |
108 | self.get_endpoint() | 110 | self.get_endpoint() |
109 | ) | 111 | ) |
diff --git a/src/bin/shipyard_client/shipyard_client/cli/get/actions.py b/src/bin/shipyard_client/shipyard_client/cli/get/actions.py index b839756..05b7c68 100644 --- a/src/bin/shipyard_client/shipyard_client/cli/get/actions.py +++ b/src/bin/shipyard_client/shipyard_client/cli/get/actions.py | |||
@@ -119,16 +119,18 @@ class GetConfigdocsStatus(CliAction): | |||
119 | class GetRenderedConfigdocs(CliAction): | 119 | class GetRenderedConfigdocs(CliAction): |
120 | """Action to Get Rendered Configdocs""" | 120 | """Action to Get Rendered Configdocs""" |
121 | 121 | ||
122 | def __init__(self, ctx, version): | 122 | def __init__(self, ctx, version, cleartext_secrets=False): |
123 | """Sets parameters.""" | 123 | """Sets parameters.""" |
124 | super().__init__(ctx) | 124 | super().__init__(ctx) |
125 | self.logger.debug("GetRenderedConfigdocs action initialized") | 125 | self.logger.debug("GetRenderedConfigdocs action initialized") |
126 | self.version = version | 126 | self.version = version |
127 | self.cleartext_secrets = cleartext_secrets | ||
127 | 128 | ||
128 | def invoke(self): | 129 | def invoke(self): |
129 | """Calls API Client and formats response from API Client""" | 130 | """Calls API Client and formats response from API Client""" |
130 | self.logger.debug("Calling API Client get_rendereddocs.") | 131 | self.logger.debug("Calling API Client get_rendereddocs.") |
131 | return self.get_api_client().get_rendereddocs(version=self.version) | 132 | return self.get_api_client().get_rendereddocs( |
133 | version=self.version, cleartext_secrets=self.cleartext_secrets) | ||
132 | 134 | ||
133 | # Handle 404 with default error handler for cli. | 135 | # Handle 404 with default error handler for cli. |
134 | cli_handled_err_resp_codes = [404] | 136 | cli_handled_err_resp_codes = [404] |
diff --git a/src/bin/shipyard_client/shipyard_client/cli/get/commands.py b/src/bin/shipyard_client/shipyard_client/cli/get/commands.py index 48adc47..1bbffa2 100644 --- a/src/bin/shipyard_client/shipyard_client/cli/get/commands.py +++ b/src/bin/shipyard_client/shipyard_client/cli/get/commands.py | |||
@@ -100,7 +100,6 @@ SHORT_DESC_CONFIGDOCS = ("Retrieve documents loaded into Shipyard, either " | |||
100 | 'executed site action.') | 100 | 'executed site action.') |
101 | @click.option( | 101 | @click.option( |
102 | '--cleartext-secrets', | 102 | '--cleartext-secrets', |
103 | '-t', | ||
104 | help='Returns cleartext secrets in documents', | 103 | help='Returns cleartext secrets in documents', |
105 | is_flag=True) | 104 | is_flag=True) |
106 | @click.pass_context | 105 | @click.pass_context |
@@ -170,14 +169,19 @@ SHORT_DESC_RENDEREDCONFIGDOCS = ( | |||
170 | flag_value='successful_site_action', | 169 | flag_value='successful_site_action', |
171 | help='Holds the revision information for the most recent successfully ' | 170 | help='Holds the revision information for the most recent successfully ' |
172 | 'executed site action.') | 171 | 'executed site action.') |
172 | @click.option( | ||
173 | '--cleartext-secrets', | ||
174 | help='Returns cleartext secrets in encrypted documents', | ||
175 | is_flag=True) | ||
173 | @click.pass_context | 176 | @click.pass_context |
174 | def get_renderedconfigdocs(ctx, buffer, committed, last_site_action, | 177 | def get_renderedconfigdocs(ctx, buffer, committed, last_site_action, |
175 | successful_site_action): | 178 | successful_site_action, cleartext_secrets): |
176 | # Get version | 179 | # Get version |
177 | _version = get_version(ctx, buffer, committed, last_site_action, | 180 | _version = get_version(ctx, buffer, committed, last_site_action, |
178 | successful_site_action) | 181 | successful_site_action) |
179 | 182 | ||
180 | click.echo(GetRenderedConfigdocs(ctx, _version).invoke_and_return_resp()) | 183 | click.echo(GetRenderedConfigdocs(ctx, _version, |
184 | cleartext_secrets).invoke_and_return_resp()) | ||
181 | 185 | ||
182 | 186 | ||
183 | DESC_WORKFLOWS = """ | 187 | DESC_WORKFLOWS = """ |
diff --git a/src/bin/shipyard_client/tests/unit/cli/get/test_get_commands.py b/src/bin/shipyard_client/tests/unit/cli/get/test_get_commands.py index 25bf411..cf84072 100644 --- a/src/bin/shipyard_client/tests/unit/cli/get/test_get_commands.py +++ b/src/bin/shipyard_client/tests/unit/cli/get/test_get_commands.py | |||
@@ -88,7 +88,7 @@ def test_get_renderedconfigdocs(*args): | |||
88 | runner = CliRunner() | 88 | runner = CliRunner() |
89 | with patch.object(GetRenderedConfigdocs, '__init__') as mock_method: | 89 | with patch.object(GetRenderedConfigdocs, '__init__') as mock_method: |
90 | runner.invoke(shipyard, [auth_vars, 'get', 'renderedconfigdocs']) | 90 | runner.invoke(shipyard, [auth_vars, 'get', 'renderedconfigdocs']) |
91 | mock_method.assert_called_once_with(ANY, 'buffer') | 91 | mock_method.assert_called_once_with(ANY, 'buffer', False) |
92 | 92 | ||
93 | 93 | ||
94 | def test_get_renderedconfigdocs_negative(*args): | 94 | def test_get_renderedconfigdocs_negative(*args): |