From 3ad132bde24b31313a01ac6b05c0500aa0c3a437 Mon Sep 17 00:00:00 2001 From: Marc Abramowitz Date: Wed, 6 Jul 2016 23:43:29 -0700 Subject: [PATCH] Support dynamic config w/ OS_TENANT_NAME in addition to `OS_REGION_NAME`. E.g.: [sjc] ... snip ... OS_TENANT_NAME=dev;test;production ... snip ... --- docs/configuring.md | 17 +++++++++++++++-- supernova/config.py | 34 ++++++++++++++++++++-------------- tests/test_config.py | 23 +++++++++++++++++++++++ 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/docs/configuring.md b/docs/configuring.md index 61d8278..bb92278 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -92,7 +92,7 @@ When supernova runs, it will take the configuration options and pass them direct For accounts where you would like to utilize the same configuration, it is possible to use the same entry. -In the configuration, you can separate the regions by a semicolon:: +In the configuration, you can separate the regions by a semicolon: [personal] ..snip.. @@ -101,7 +101,6 @@ In the configuration, you can separate the regions by a semicolon:: OS_USERNAME=username OS_PASSWORD=somelongapikey - This will create the super group "personal" as well as the individual groups "personal-DFW" and "personal-ORD":: > supernova -l | grep personal @@ -109,3 +108,17 @@ This will create the super group "personal" as well as the individual groups "pe SUPERNOVA_GROUP : personal -- personal-ORD ------------------------------------------------------------- SUPERNOVA_GROUP : personal + +You can also use dynamic configuration with tenants (in the `OS_TENANT_NAME` setting): + + [personal] + ..snip.. + OS_TENANT_NAME=dev;prod + OS_USERNAME=username + OS_PASSWORD=somelongapikey + + > supernova -l | grep personal + -- personal-dev ------------------------------------------------------------- + SUPERNOVA_GROUP : personal + -- personal-prod ------------------------------------------------------------- + SUPERNOVA_GROUP : personal diff --git a/supernova/config.py b/supernova/config.py index d0be3c1..5788669 100644 --- a/supernova/config.py +++ b/supernova/config.py @@ -77,7 +77,8 @@ def get_config_file(override_files=False): raise Exception("Couldn't find a valid configuration file to parse") -def create_dynamic_configs(config, region_name='OS_REGION_NAME', +def create_dynamic_configs(config, + dynamic_attrs=('OS_REGION_NAME', 'OS_TENANT_NAME'), delimiter=';'): if not isinstance(config, ConfigObj): raise ValueError("config should be ConfigObj, not %s" % type(config)) @@ -85,24 +86,29 @@ def create_dynamic_configs(config, region_name='OS_REGION_NAME', sections = copy.copy(config.sections) for section in sections: + delete_original_section = False - # Check to see if we should generate new sections. - if delimiter in config[section].get(region_name, ''): - for new_section_arg in config[section][region_name].split( - delimiter): + for dynamic_attr in dynamic_attrs: + # Check to see if we should generate new sections. + if delimiter in config[section].get(dynamic_attr, ''): + for new_section_arg in config[section][dynamic_attr].split( + delimiter): - new_section = section + '-' + new_section_arg + new_section = section + '-' + new_section_arg - # Use default section - config[new_section] = {} + # Use default section + config[new_section] = {} - # Copy the existing section config. - config[new_section].update(config[section]) - config[new_section][region_name] = new_section_arg + # Copy the existing section config. + config[new_section].update(config[section]) + config[new_section][dynamic_attr] = new_section_arg - # We are eventually going to delete the old section. - # Lets use it as a supernova group - config[new_section]['SUPERNOVA_GROUP'] = section + # We are eventually going to delete the old section. + # Lets use it as a supernova group + config[new_section]['SUPERNOVA_GROUP'] = section + delete_original_section = True + + if delete_original_section: # We are done, lets remove the original section del config[section] diff --git a/tests/test_config.py b/tests/test_config.py index 54c98a2..8cdc5da 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -78,3 +78,26 @@ def test_dynamic_sections_without_default(self): result['dynamic-section-ORD'].get('OS_REGION_NAME') assert 'DFW' == \ result['dynamic-section-DFW'].get('OS_REGION_NAME') + + def test_dynamic_sections_using_tenant(self): + result = config.load_config() + result['dynamic-section'] = {'OS_TENANT_NAME': "dev;prod"} + config.create_dynamic_configs(result) + # The new sections exist + assert 'dynamic-section-dev' in result.sections + assert 'dynamic-section-prod' in result.sections + + # The default section is no longer provided + assert 'dynamic-section' not in result.sections + + # The super group is set up correctly + assert 'dynamic-section' in \ + result['dynamic-section-dev'].get('SUPERNOVA_GROUP') + assert 'dynamic-section' == \ + result['dynamic-section-prod'].get('SUPERNOVA_GROUP') + + # The regions are correct + assert 'dev' == \ + result['dynamic-section-dev'].get('OS_TENANT_NAME') + assert 'prod' == \ + result['dynamic-section-prod'].get('OS_TENANT_NAME')