Only add fall through cloud as a fall through

We only want do define the 'openstack' cloud if there are neither
environment varaibles nor config files. We need to define it as a place
to put passed-in-parameters in the case of neither, but we don't want it
any other time.

The behavior can now be described as:
- If you have a config file, you will get the clouds listed in it
- If you have environment variable, you will get a cloud named 'envvars'
- If you have neither, you will get a cloud named 'defaults'

Change-Id: I6752c1ccecf1ef979b2603246eeaab7da360c8a4
This commit is contained in:
Monty Taylor 2015-05-09 08:49:59 -04:00
parent aefb164f9b
commit 2f1e6c13be
5 changed files with 56 additions and 26 deletions

View File

@ -9,6 +9,10 @@ put in a config file. It will read environment variables and config files,
and it also contains some vendor specific default values so that you don't
have to know extra info to use OpenStack
* If you have a config file, you will get the clouds listed in it
* If you have environment variables, you will get a cloud named 'envvars'
* If you have neither, you will get a cloud named 'defaults' with base defaults
Environment Variables
---------------------
@ -16,10 +20,10 @@ os-client-config honors all of the normal `OS_*` variables. It does not
provide backwards compatibility to service-specific variables such as
`NOVA_USERNAME`.
If you have OpenStack environment variables seet and no config files,
os-client-config will produce a cloud config object named "envvars" containing
your values from the environment. If you don't like the name "envvars", that's
ok, you can override it by setting `OS_CLOUD_NAME`.
If you have OpenStack environment variables set, os-client-config will produce
a cloud config object named "envvars" containing your values from the
environment. If you don't like the name "envvars", that's ok, you can override
it by setting `OS_CLOUD_NAME`.
Service specific settings, like the nova service type, are set with the
default service type as a prefix. For instance, to set a special service_type

View File

@ -91,31 +91,34 @@ class OpenStackConfig(object):
self.defaults = dict(defaults._defaults)
# use a config file if it exists where expected
# First, use a config file if it exists where expected
self.cloud_config = self._load_config_file()
if not self.cloud_config:
self.cloud_config = dict(
clouds=dict(openstack=dict(self.defaults)))
self.envvar_key = os.environ.pop('OS_CLOUD_NAME', None)
if self.envvar_key:
if self.envvar_key in self.cloud_config['clouds']:
raise exceptions.OpenStackConfigException(
'clouds.yaml defines a cloud named "{0}", but'
' OS_CLOUD_NAME is also set to "{0}". Please rename'
' either your environment based cloud, or one of your'
' file-based clouds.'.format(self.envvar_key))
else:
self.envvar_key = 'envvars'
if not self.cloud_config:
self.cloud_config = {'clouds': {}}
if 'clouds' not in self.cloud_config:
self.cloud_config['clouds'] = {}
# Next, process environment variables and add them to the mix
self.envvar_key = os.environ.pop('OS_CLOUD_NAME', 'envvars')
if self.envvar_key in self.cloud_config['clouds']:
raise exceptions.OpenStackConfigException(
'clouds.yaml defines a cloud named "{0}", but'
' OS_CLOUD_NAME is also set to "{0}". Please rename'
' either your environment based cloud, or one of your'
' file-based clouds.'.format(self.envvar_key))
envvars = _get_os_environ()
if envvars:
if self.envvar_key in self.cloud_config['clouds']:
raise exceptions.OpenStackConfigException(
'clouds.yaml defines a cloud named {0}, and OS_*'
' env vars are set')
self.cloud_config['clouds'][self.envvar_key] = envvars
# Finally, fall through and make a cloud that starts with defaults
# because we need somewhere to put arguments, and there are neither
# config files or env vars
if not self.cloud_config['clouds']:
self.cloud_config = dict(
clouds=dict(defaults=dict(self.defaults)))
self._cache_max_age = 0
self._cache_path = CACHE_PATH
self._cache_class = 'dogpile.cache.null'

View File

@ -59,6 +59,9 @@ USER_CONF = {
},
'cache': {'max_age': 1},
}
NO_CONF = {
'cache': {'max_age': 1},
}
def _write_yaml(obj):
@ -80,6 +83,7 @@ class TestCase(base.BaseTestCase):
conf['cache']['path'] = tdir.path
self.cloud_yaml = _write_yaml(conf)
self.vendor_yaml = _write_yaml(VENDOR_CONF)
self.no_yaml = _write_yaml(NO_CONF)
# Isolate the test runs from the environment
# Do this as two loops because you can't modify the dict in a loop

View File

@ -12,6 +12,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
import fixtures
from os_client_config import cloud_config
from os_client_config import config
from os_client_config import exceptions
@ -44,6 +48,14 @@ class TestConfig(base.TestCase):
self.assertRaises(
exceptions.OpenStackConfigException, c.get_one_cloud, 'envvars')
def test_fallthrough(self):
c = config.OpenStackConfig(config_files=[self.no_yaml],
vendor_files=[self.no_yaml])
for k in os.environ.keys():
if k.startswith('OS_'):
self.useFixture(fixtures.EnvironmentVariable(k))
c.get_one_cloud(cloud='defaults')
def test_get_one_cloud_auth_merge(self):
c = config.OpenStackConfig(config_files=[self.cloud_yaml])
cc = c.get_one_cloud(cloud='_test_cloud_', auth={'username': 'user'})

View File

@ -15,6 +15,7 @@
from os_client_config import cloud_config
from os_client_config import config
from os_client_config import exceptions
from os_client_config.tests import base
import fixtures
@ -36,12 +37,18 @@ class TestEnviron(base.TestCase):
vendor_files=[self.vendor_yaml])
self.assertIsInstance(c.get_one_cloud(), cloud_config.CloudConfig)
def test_envvar_name_override(self):
self.useFixture(
fixtures.EnvironmentVariable('OS_CLOUD_NAME', 'openstack'))
def test_no_fallthrough(self):
c = config.OpenStackConfig(config_files=[self.cloud_yaml],
vendor_files=[self.vendor_yaml])
cc = c.get_one_cloud('openstack')
self.assertRaises(
exceptions.OpenStackConfigException, c.get_one_cloud, 'openstack')
def test_envvar_name_override(self):
self.useFixture(
fixtures.EnvironmentVariable('OS_CLOUD_NAME', 'override'))
c = config.OpenStackConfig(config_files=[self.cloud_yaml],
vendor_files=[self.vendor_yaml])
cc = c.get_one_cloud('override')
self._assert_cloud_details(cc)
def test_environ_exists(self):