Merge "Add support for clouds config file"

This commit is contained in:
Zuul 2019-09-02 13:08:35 +00:00 committed by Gerrit Code Review
commit 24361e9dd5
3 changed files with 164 additions and 0 deletions

View 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]

View File

@ -14,6 +14,7 @@
from __future__ import absolute_import
import collections
import json
import os
import sys
@ -21,6 +22,7 @@ from oslo_log import log
import yaml
import tobiko
from tobiko.openstack.keystone import _config_files
LOG = log.getLogger(__name__)
@ -223,6 +225,58 @@ class EnvironKeystoneCredentialsFixture(KeystoneCredentialsFixture):
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):
def get_credentials(self):
@ -258,6 +312,7 @@ class ConfigKeystoneCredentialsFixture(KeystoneCredentialsFixture):
DEFAULT_KEYSTONE_CREDENTIALS_FIXTURES = [
CloudsFileKeystoneCredentialsFixture,
EnvironKeystoneCredentialsFixture,
ConfigKeystoneCredentialsFixture]

View File

@ -14,8 +14,12 @@
# under the License.
from __future__ import absolute_import
import json
import os
import mock
import yaml
import tobiko
from tobiko import config
from tobiko.openstack import keystone
@ -61,6 +65,17 @@ V3_ENVIRON = {
'OS_USER_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')
@ -163,6 +178,56 @@ class EnvironKeystoneCredentialsFixtureTest(openstack.OpenstackTest):
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):
def patch_config(self, params, **kwargs):