Merge "Add support for clouds config file"
This commit is contained in:
commit
24361e9dd5
44
tobiko/openstack/keystone/_config_files.py
Normal file
44
tobiko/openstack/keystone/_config_files.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Copyright 2019 Red Hat
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import appdirs
|
||||||
|
|
||||||
|
|
||||||
|
APPDIRS = appdirs.AppDirs('openstack', 'OpenStack', multipath='/etc')
|
||||||
|
CONFIG_HOME = APPDIRS.user_config_dir
|
||||||
|
CACHE_PATH = APPDIRS.user_cache_dir
|
||||||
|
|
||||||
|
UNIX_CONFIG_HOME = os.path.join(
|
||||||
|
os.path.expanduser(os.path.join('~', '.config')), 'openstack')
|
||||||
|
UNIX_SITE_CONFIG_HOME = '/etc/openstack'
|
||||||
|
|
||||||
|
SITE_CONFIG_HOME = APPDIRS.site_config_dir
|
||||||
|
|
||||||
|
CONFIG_SEARCH_PATH = [
|
||||||
|
os.getcwd(),
|
||||||
|
CONFIG_HOME, UNIX_CONFIG_HOME,
|
||||||
|
SITE_CONFIG_HOME, UNIX_SITE_CONFIG_HOME
|
||||||
|
]
|
||||||
|
YAML_SUFFIXES = ('.yaml', '.yml')
|
||||||
|
JSON_SUFFIXES = ('.json',)
|
||||||
|
|
||||||
|
|
||||||
|
def get_cloud_config_files():
|
||||||
|
return [
|
||||||
|
os.path.join(d, 'clouds' + s)
|
||||||
|
for d in CONFIG_SEARCH_PATH
|
||||||
|
for s in YAML_SUFFIXES + JSON_SUFFIXES]
|
@ -14,6 +14,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ from oslo_log import log
|
|||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
import tobiko
|
import tobiko
|
||||||
|
from tobiko.openstack.keystone import _config_files
|
||||||
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
@ -223,6 +225,58 @@ class EnvironKeystoneCredentialsFixture(KeystoneCredentialsFixture):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class CloudsFileKeystoneCredentialsFixture(EnvironKeystoneCredentialsFixture):
|
||||||
|
|
||||||
|
def __init__(self, credentials=None, environ=None, clouds_files=None):
|
||||||
|
super(CloudsFileKeystoneCredentialsFixture, self).__init__(
|
||||||
|
credentials=credentials, environ=environ)
|
||||||
|
self.clouds_files = (
|
||||||
|
clouds_files or _config_files.get_cloud_config_files())
|
||||||
|
|
||||||
|
def _load_yaml_json_file(self, filelist):
|
||||||
|
for path in filelist:
|
||||||
|
if os.path.exists(path):
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
if path.endswith('json'):
|
||||||
|
return path, json.load(f)
|
||||||
|
else:
|
||||||
|
return path, yaml.safe_load(f)
|
||||||
|
return None, {}
|
||||||
|
|
||||||
|
def get_credentials(self):
|
||||||
|
cloud_name = self.get_env("OS_CLOUD")
|
||||||
|
if not cloud_name:
|
||||||
|
LOG.debug('No OS_CLOUD env variable')
|
||||||
|
return None
|
||||||
|
|
||||||
|
file_name, clouds_config = self._load_yaml_json_file(self.clouds_files)
|
||||||
|
|
||||||
|
clouds_config = clouds_config.get("clouds")
|
||||||
|
if not clouds_config:
|
||||||
|
LOG.debug('No clouds configs found in any of %s',
|
||||||
|
self.clouds_files)
|
||||||
|
return None
|
||||||
|
|
||||||
|
config = clouds_config.get(cloud_name)
|
||||||
|
if not config:
|
||||||
|
LOG.debug("No %s cloud config found in cloud configs file %s",
|
||||||
|
cloud_name, file_name)
|
||||||
|
return None
|
||||||
|
|
||||||
|
auth = config.get("auth", {})
|
||||||
|
return keystone_credentials(
|
||||||
|
api_version=int(config.get("identity_api_version")),
|
||||||
|
auth_url=auth.get("auth_url"),
|
||||||
|
username=auth.get("username"),
|
||||||
|
password=auth.get("password"),
|
||||||
|
project_name=auth.get("project_name"),
|
||||||
|
domain_name=auth.get("domain_name"),
|
||||||
|
user_domain_name=auth.get("user_domain_name"),
|
||||||
|
project_domain_name=auth.get("project_domain_name"),
|
||||||
|
project_domain_id=auth.get("project_domain_id"),
|
||||||
|
trust_id=auth.get("trust_id"))
|
||||||
|
|
||||||
|
|
||||||
class ConfigKeystoneCredentialsFixture(KeystoneCredentialsFixture):
|
class ConfigKeystoneCredentialsFixture(KeystoneCredentialsFixture):
|
||||||
|
|
||||||
def get_credentials(self):
|
def get_credentials(self):
|
||||||
@ -258,6 +312,7 @@ class ConfigKeystoneCredentialsFixture(KeystoneCredentialsFixture):
|
|||||||
|
|
||||||
|
|
||||||
DEFAULT_KEYSTONE_CREDENTIALS_FIXTURES = [
|
DEFAULT_KEYSTONE_CREDENTIALS_FIXTURES = [
|
||||||
|
CloudsFileKeystoneCredentialsFixture,
|
||||||
EnvironKeystoneCredentialsFixture,
|
EnvironKeystoneCredentialsFixture,
|
||||||
ConfigKeystoneCredentialsFixture]
|
ConfigKeystoneCredentialsFixture]
|
||||||
|
|
||||||
|
@ -14,8 +14,12 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import mock
|
||||||
|
import yaml
|
||||||
|
|
||||||
import tobiko
|
import tobiko
|
||||||
from tobiko import config
|
from tobiko import config
|
||||||
from tobiko.openstack import keystone
|
from tobiko.openstack import keystone
|
||||||
@ -61,6 +65,17 @@ V3_ENVIRON = {
|
|||||||
'OS_USER_DOMAIN_NAME': 'Default',
|
'OS_USER_DOMAIN_NAME': 'Default',
|
||||||
'OS_PROJECT_DOMAIN_NAME': 'Default'}
|
'OS_PROJECT_DOMAIN_NAME': 'Default'}
|
||||||
|
|
||||||
|
CLOUDS_CONFIG = {
|
||||||
|
'clouds': {
|
||||||
|
'test-cloud': {
|
||||||
|
'auth': {'auth_url': V3_PARAMS['auth_url'],
|
||||||
|
'password': V3_PARAMS['password'],
|
||||||
|
'project_domain_name': V3_PARAMS['project_domain_name'],
|
||||||
|
'project_name': V3_PARAMS['project_name'],
|
||||||
|
'user_domain_name': V3_PARAMS['user_domain_name'],
|
||||||
|
'username': V3_PARAMS['username']},
|
||||||
|
'identity_api_version': str(V3_PARAMS['api_version'])}}}
|
||||||
|
|
||||||
V3_ENVIRON_WITH_VERSION = dict(V3_ENVIRON, OS_IDENTITY_API_VERSION='3')
|
V3_ENVIRON_WITH_VERSION = dict(V3_ENVIRON, OS_IDENTITY_API_VERSION='3')
|
||||||
|
|
||||||
|
|
||||||
@ -163,6 +178,56 @@ class EnvironKeystoneCredentialsFixtureTest(openstack.OpenstackTest):
|
|||||||
self.assertEqual(V3_PARAMS, fixture.credentials.to_dict())
|
self.assertEqual(V3_PARAMS, fixture.credentials.to_dict())
|
||||||
|
|
||||||
|
|
||||||
|
class CloudsFileKeystoneCredentialsFixtureTestJson(openstack.OpenstackTest):
|
||||||
|
|
||||||
|
clouds_file_name = "/tmp/test-cloud-file.json"
|
||||||
|
json_cloud_data = json.dumps(CLOUDS_CONFIG)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(CloudsFileKeystoneCredentialsFixtureTestJson, self).setUp()
|
||||||
|
self.patch(os, 'environ', {'OS_CLOUD': 'test-cloud'})
|
||||||
|
self.patch(os.path, 'exists', return_value=True)
|
||||||
|
mocked_open = mock.mock_open(read_data=self.json_cloud_data)
|
||||||
|
self.patch(_credentials, "open", mocked_open)
|
||||||
|
|
||||||
|
def test_setup_from_clouds_config_file(self):
|
||||||
|
fixture = _credentials.CloudsFileKeystoneCredentialsFixture(
|
||||||
|
clouds_files=[self.clouds_file_name])
|
||||||
|
fixture.setUp()
|
||||||
|
fixture.credentials.validate()
|
||||||
|
self.assertEqual(
|
||||||
|
V3_PARAMS, fixture.credentials.to_dict())
|
||||||
|
|
||||||
|
def test_setup_from_file_no_os_cloud_env_set(self):
|
||||||
|
self.patch(os, 'environ', {})
|
||||||
|
fixture = _credentials.CloudsFileKeystoneCredentialsFixture(
|
||||||
|
clouds_files=[self.clouds_file_name])
|
||||||
|
fixture.setUp()
|
||||||
|
self.assertIsNone(fixture.credentials)
|
||||||
|
|
||||||
|
def test_setup_from_file_no_clouds_config_in_file(self):
|
||||||
|
mocked_open = mock.mock_open(read_data=json.dumps({}))
|
||||||
|
self.patch(_credentials, "open", mocked_open)
|
||||||
|
fixture = _credentials.CloudsFileKeystoneCredentialsFixture(
|
||||||
|
clouds_files=[self.clouds_file_name])
|
||||||
|
fixture.setUp()
|
||||||
|
self.assertIsNone(fixture.credentials)
|
||||||
|
|
||||||
|
def test_setup_from_file_no_specified_cloud_config_in_file(self):
|
||||||
|
self.patch(os, 'environ', {'OS_CLOUD': 'some-other-cloud'})
|
||||||
|
fixture = _credentials.CloudsFileKeystoneCredentialsFixture(
|
||||||
|
clouds_files=[self.clouds_file_name])
|
||||||
|
fixture.setUp()
|
||||||
|
self.assertIsNone(fixture.credentials)
|
||||||
|
|
||||||
|
|
||||||
|
class CloudsFileKeystoneCredentialsFixtureTestYaml(
|
||||||
|
CloudsFileKeystoneCredentialsFixtureTestJson):
|
||||||
|
|
||||||
|
clouds_file_name = "/tmp/test-cloud-file.yaml"
|
||||||
|
json_cloud_data = yaml.dump(CLOUDS_CONFIG)
|
||||||
|
|
||||||
|
|
||||||
class ConfigKeystoneCredentialsFixtureTest(openstack.OpenstackTest):
|
class ConfigKeystoneCredentialsFixtureTest(openstack.OpenstackTest):
|
||||||
|
|
||||||
def patch_config(self, params, **kwargs):
|
def patch_config(self, params, **kwargs):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user