From 204a5820995dd694fcd58d61fc6cf34a8955da92 Mon Sep 17 00:00:00 2001 From: Ben Nemec Date: Tue, 16 May 2017 16:06:41 -0500 Subject: [PATCH] Add nested sample environments for inject-trust-anchor Fix a bug that prevented these working. A unit test and documentation for the nested environment functionality is also included. Change-Id: I2d4aeb584eb624178d601cfd6bc0a6473cb5289f --- environments/inject-trust-anchor-hiera.yaml | 4 ++ environments/inject-trust-anchor.yaml | 4 ++ .../ssl/inject-trust-anchor-hiera.yaml | 22 +++++++ environments/ssl/inject-trust-anchor.yaml | 20 ++++++ sample-env-generator/README.rst | 11 ++++ sample-env-generator/ssl.yaml | 33 ++++++++++ .../environment_generator.py | 1 + .../tests/test_environment_generator.py | 65 ++++++++++++++++++- 8 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 environments/ssl/inject-trust-anchor-hiera.yaml create mode 100644 environments/ssl/inject-trust-anchor.yaml diff --git a/environments/inject-trust-anchor-hiera.yaml b/environments/inject-trust-anchor-hiera.yaml index b4908c1bab..95d2de953c 100644 --- a/environments/inject-trust-anchor-hiera.yaml +++ b/environments/inject-trust-anchor-hiera.yaml @@ -1,3 +1,7 @@ +# ************************************************************************************** +# DEPRECATED: Use tripleo-heat-templates/environments/ssl/inject-trust-anchor-hiera.yaml +# instead. +# ************************************************************************************** parameter_defaults: CAMap: first-ca-name: diff --git a/environments/inject-trust-anchor.yaml b/environments/inject-trust-anchor.yaml index 3ecb0d272e..1b0f7066b6 100644 --- a/environments/inject-trust-anchor.yaml +++ b/environments/inject-trust-anchor.yaml @@ -1,3 +1,7 @@ +# ******************************************************************************** +# DEPRECATED: Use tripleo-heat-templates/environments/ssl/inject-trust-anchor.yaml +# instead. +# ******************************************************************************** parameter_defaults: SSLRootCertificate: | The contents of your root CA certificate go here diff --git a/environments/ssl/inject-trust-anchor-hiera.yaml b/environments/ssl/inject-trust-anchor-hiera.yaml new file mode 100644 index 0000000000..db3f26779f --- /dev/null +++ b/environments/ssl/inject-trust-anchor-hiera.yaml @@ -0,0 +1,22 @@ +# ******************************************************************* +# This file was created automatically by the sample environment +# generator. Developers should use `tox -e genconfig` to update it. +# Users are recommended to make changes to a copy of the file instead +# of the original, if any customizations are needed. +# ******************************************************************* +# title: Inject SSL Trust Anchor on Overcloud Nodes +# description: | +# When using an SSL certificate signed by a CA that is not in the default +# list of CAs, this environment allows adding a custom CA certificate to +# the overcloud nodes. +parameter_defaults: + # Map containing the CA certs and information needed for deploying them. + # Type: json + CAMap: + first-ca-name: + content: | + The content of the CA cert goes here + second-ca-name: + content: | + The content of the CA cert goes here + diff --git a/environments/ssl/inject-trust-anchor.yaml b/environments/ssl/inject-trust-anchor.yaml new file mode 100644 index 0000000000..521a41916c --- /dev/null +++ b/environments/ssl/inject-trust-anchor.yaml @@ -0,0 +1,20 @@ +# ******************************************************************* +# This file was created automatically by the sample environment +# generator. Developers should use `tox -e genconfig` to update it. +# Users are recommended to make changes to a copy of the file instead +# of the original, if any customizations are needed. +# ******************************************************************* +# title: Inject SSL Trust Anchor on Overcloud Nodes +# description: | +# When using an SSL certificate signed by a CA that is not in the default +# list of CAs, this environment allows adding a custom CA certificate to +# the overcloud nodes. +parameter_defaults: + # The content of a CA's SSL certificate file in PEM format. This is evaluated on the client side. + # Mandatory. This parameter must be set by the user. + # Type: string + SSLRootCertificate: | + The contents of your certificate go here + +resource_registry: + OS::TripleO::NodeTLSCAData: ../../puppet/extraconfig/tls/ca-inject.yaml diff --git a/sample-env-generator/README.rst b/sample-env-generator/README.rst index 55f3bacf96..32e94f9864 100644 --- a/sample-env-generator/README.rst +++ b/sample-env-generator/README.rst @@ -23,6 +23,11 @@ appropriate file in the ``sample-env-generator/`` directory. The existing entries in the files can be used as examples, and a more detailed explanation of the different available keys is below: +Top-level: +- **environments**: This is the top-level key in the file. All other keys + below should appear in a list of dictionaries that define environments. + +Environment-specific: - **name**: the output file will be this name + .yaml, in the ``environments`` directory. - **title**: a human-readable title for the environment. @@ -52,6 +57,12 @@ explanation of the different available keys is below: - **resource_registry**: Many environments also need to pass resource_registry entries when they are used. This can be used to specify that in the configuration file. +- **children**: For environments that share a lot of common values but may + need minor variations for different use cases, sample environment entries + can be nested. ``children`` takes a list of environments with the same + structure as the top-level ``environments`` key. The main difference is + that all keys are optional, and any that are omitted will be inherited from + the parent environment definition. Some behavioral notes: diff --git a/sample-env-generator/ssl.yaml b/sample-env-generator/ssl.yaml index 2f379f30fb..6963e84223 100644 --- a/sample-env-generator/ssl.yaml +++ b/sample-env-generator/ssl.yaml @@ -22,6 +22,39 @@ environments: The contents of the private key go here resource_registry: OS::TripleO::NodeTLSData: ../../puppet/extraconfig/tls/tls-cert-inject.yaml + - name: ssl/inject-trust-anchor + title: Inject SSL Trust Anchor on Overcloud Nodes + description: | + When using an SSL certificate signed by a CA that is not in the default + list of CAs, this environment allows adding a custom CA certificate to + the overcloud nodes. + files: + puppet/extraconfig/tls/ca-inject.yaml: + parameters: + - SSLRootCertificate + sample_values: + SSLRootCertificate: |- + | + The contents of your certificate go here + resource_registry: + OS::TripleO::NodeTLSCAData: ../../puppet/extraconfig/tls/ca-inject.yaml + children: + - name: ssl/inject-trust-anchor-hiera + files: + puppet/services/ca-certs.yaml: + parameters: + - CAMap + # Need to clear this so we don't inherit the parent registry + resource_registry: {} + sample_values: + CAMap: |-2 + + first-ca-name: + content: | + The content of the CA cert goes here + second-ca-name: + content: | + The content of the CA cert goes here - name: ssl/tls-endpoints-public-ip title: Deploy Public SSL Endpoints as IP Addresses diff --git a/tripleo_heat_templates/environment_generator.py b/tripleo_heat_templates/environment_generator.py index b3e327f0fa..876dd854a4 100755 --- a/tripleo_heat_templates/environment_generator.py +++ b/tripleo_heat_templates/environment_generator.py @@ -68,6 +68,7 @@ def _generate_environment(input_env, parent_env=None): if parent_env is None: parent_env = {} env = dict(parent_env) + env.pop('children', None) env.update(input_env) parameter_defaults = {} param_names = [] diff --git a/tripleo_heat_templates/tests/test_environment_generator.py b/tripleo_heat_templates/tests/test_environment_generator.py index f4c4cdbf61..94d13c7197 100644 --- a/tripleo_heat_templates/tests/test_environment_generator.py +++ b/tripleo_heat_templates/tests/test_environment_generator.py @@ -89,6 +89,7 @@ class GeneratorTestCase(base.BaseTestCase): ('basic', {'template': basic_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -115,6 +116,7 @@ parameter_defaults: ('basic-one-param', {'template': basic_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -138,6 +140,7 @@ parameter_defaults: ('basic-static-param', {'template': basic_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -173,6 +176,7 @@ parameter_defaults: ('basic-static-param-sample', {'template': basic_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -211,6 +215,7 @@ parameter_defaults: ('basic-private', {'template': basic_private_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -233,6 +238,7 @@ parameter_defaults: ('mandatory', {'template': mandatory_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -256,6 +262,7 @@ parameter_defaults: ('basic-sample', {'template': basic_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -284,6 +291,7 @@ parameter_defaults: ('basic-resource-registry', {'template': basic_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -314,6 +322,7 @@ resource_registry: ('basic-hidden', {'template': basic_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -349,6 +358,7 @@ parameter_defaults: ('missing-param', {'template': basic_template, 'exception': RuntimeError, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -364,6 +374,7 @@ parameter_defaults: ('percent-index', {'template': index_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -381,11 +392,51 @@ parameter_defaults: # Type: string FooParam: '%index%' +''', + }), + ('nested', + {'template': multiline_template, + 'exception': None, + 'input_file': '''environments: + - + name: basic + title: Basic Environment + description: Basic description + files: + foo.yaml: + parameters: all + children: + - name: nested + title: Nested Environment + description: Nested description + sample_values: + FooParam: bar +''', + 'expected_output': '''# title: Basic Environment +# description: | +# Basic description +parameter_defaults: + # Parameter with + # multi-line description + # Type: string + FooParam: '' + +''', + 'nested_output': '''# title: Nested Environment +# description: | +# Nested description +parameter_defaults: + # Parameter with + # multi-line description + # Type: string + FooParam: bar + ''', }), ('multi-line-desc', {'template': multiline_template, 'exception': None, + 'nested_output': '', 'input_file': '''environments: - name: basic @@ -420,7 +471,14 @@ parameter_defaults: fake_output = open(fake_output_path, 'w') with mock.patch('tripleo_heat_templates.environment_generator.open', create=True) as mock_open: - mock_open.side_effect = [fake_input, fake_template, fake_output] + mock_se = [fake_input, fake_template, fake_output] + if self.nested_output: + _, fake_nested_output_path = tempfile.mkstemp() + fake_nested_output = open(fake_nested_output_path, 'w') + fake_template2 = io.StringIO(six.text_type(self.template)) + mock_se = [fake_input, fake_template, fake_output, + fake_template2, fake_nested_output] + mock_open.side_effect = mock_se if not self.exception: environment_generator.generate_environments('ignored.yaml') else: @@ -431,5 +489,10 @@ parameter_defaults: expected = environment_generator._FILE_HEADER + self.expected_output with open(fake_output_path) as f: self.assertEqual(expected, f.read()) + if self.nested_output: + with open(fake_nested_output_path) as f: + expected = (environment_generator._FILE_HEADER + + self.nested_output) + self.assertEqual(expected, f.read()) GeneratorTestCase.generate_scenarios()