From 614454027a59c0bd662d29b26e4ce6e918e0b26f Mon Sep 17 00:00:00 2001 From: Alexandru Coman Date: Thu, 23 Mar 2017 16:00:59 +0200 Subject: [PATCH] Change oslo.config with a global dictionary Change-Id: I7bca2e01e74645273b708c4c8ca305c5d4da8478 --- etc/hnv/README.md | 4 -- etc/hnv/hnv_client-config-generator.conf | 5 -- hnv/__init__.py | 11 ++++ hnv/client.py | 51 +++++++++++----- hnv/common/utils.py | 9 ++- hnv/config/__init__.py | 24 -------- hnv/config/base.py | 44 ------------- hnv/config/client.py | 78 ------------------------ hnv/config/factory.py | 31 ---------- hnv/config/options.py | 34 ----------- hnv/tests/common/test_utils.py | 12 ++-- hnv/tests/test_client.py | 8 +-- hnv/tests/utils.py | 22 +++---- requirements.txt | 1 - setup.cfg | 2 - 15 files changed, 66 insertions(+), 270 deletions(-) delete mode 100644 etc/hnv/README.md delete mode 100644 etc/hnv/hnv_client-config-generator.conf delete mode 100644 hnv/config/__init__.py delete mode 100644 hnv/config/base.py delete mode 100644 hnv/config/client.py delete mode 100644 hnv/config/factory.py delete mode 100644 hnv/config/options.py diff --git a/etc/hnv/README.md b/etc/hnv/README.md deleted file mode 100644 index 64467f4..0000000 --- a/etc/hnv/README.md +++ /dev/null @@ -1,4 +0,0 @@ -To generate the sample hnv.conf file, run the following command from the top -level of the python-hnv directory: - - oslo-config-generator --config-file etc/python-hnv/hnv-config-generator.conf diff --git a/etc/hnv/hnv_client-config-generator.conf b/etc/hnv/hnv_client-config-generator.conf deleted file mode 100644 index 09727e1..0000000 --- a/etc/hnv/hnv_client-config-generator.conf +++ /dev/null @@ -1,5 +0,0 @@ -[DEFAULT] -output_file = etc/python-hnv/hnv.conf -wrap_width = 80 -namespace = hnv.conf -namespace = oslo.log diff --git a/hnv/__init__.py b/hnv/__init__.py index 5c6245e..c4db02f 100644 --- a/hnv/__init__.py +++ b/hnv/__init__.py @@ -15,3 +15,14 @@ import pbr.version __version__ = pbr.version.VersionInfo( 'hnv').version_string() + +CONFIG = { + "url": None, + "username": None, + "password": None, + "https_allow_insecure": False, + "https_ca_bundle": None, + "retry_count": 5, + "retry_interval": 1, + "http_request_timeout": None, +} diff --git a/hnv/client.py b/hnv/client.py index b57df91..984648c 100644 --- a/hnv/client.py +++ b/hnv/client.py @@ -24,15 +24,14 @@ from hnv.common import constant from hnv.common import exception from hnv.common import model from hnv.common import utils -from hnv import config as hnv_config +from hnv import CONFIG LOG = logging.getLogger(__name__) -CONFIG = hnv_config.CONFIG class _BaseHNVModel(model.Model): - _endpoint = CONFIG.HNV.url + _endpoint = CONFIG["url"] resource_ref = model.Field(name="resource_ref", key="resourceRef", is_property=False) @@ -138,11 +137,13 @@ class _BaseHNVModel(model.Model): @staticmethod def _get_client(): """Create a new client for the HNV REST API.""" - return utils.get_client(url=CONFIG.HNV.url, - username=CONFIG.HNV.username, - password=CONFIG.HNV.password, - allow_insecure=CONFIG.HNV.https_allow_insecure, - ca_bundle=CONFIG.HNV.https_ca_bundle) + return utils.get_client( + url=CONFIG["url"], + username=CONFIG["username"], + password=CONFIG["password"], + allow_insecure=CONFIG["https_allow_insecure"], + ca_bundle=CONFIG["https_ca_bundle"] + ) @classmethod def _get_all(cls, parent_id=None, grandparent_id=None): @@ -237,10 +238,10 @@ class _BaseHNVModel(model.Model): LOG.debug("The resource was successfully removed.") break - elapsed_time += CONFIG.HNV.retry_interval + elapsed_time += CONFIG["retry_interval"] if timeout and elapsed_time > timeout: raise exception.TimeOut("The request timed out.") - time.sleep(CONFIG.HNV.retry_interval) + time.sleep(CONFIG["retry_interval"]) def refresh(self): """Get the latest representation of the current model.""" @@ -289,10 +290,10 @@ class _BaseHNVModel(model.Model): self.refresh() # Update the representation of the current model if self.is_ready(): break - elapsed_time += CONFIG.HNV.retry_interval + elapsed_time += CONFIG["retry_interval"] if timeout and elapsed_time > timeout: raise exception.TimeOut("The request timed out.") - time.sleep(CONFIG.HNV.retry_interval) + time.sleep(CONFIG["retry_interval"]) else: self._reset_model(response) @@ -2808,9 +2809,6 @@ class BGPPeersStatistics(model.Model): @classmethod def process_raw_data(cls, raw_data): """Create a new model using raw API response.""" - - # pylint: disable=redefined-variable-type - raw_content = raw_data.get("updateMessageStats", None) if raw_content is not None: statistics = UpdateMessageStatistics.from_raw_data(raw_content) @@ -3188,3 +3186,26 @@ class LoadBalancerMux(_BaseHNVModel): properties["virtualServer"] = resource return super(LoadBalancerMux, cls).process_raw_data(raw_data) + + +def setup(**config): + """Update the global configurations for the HNV client. + + :param url: The base URL where the agent looks for Network + Controller API. + :param username: The username required for connecting to the + Network Controller API. + :param password: The password required for connecting to the + Network Controller API. + :param https_allow_insecure: Whether to disable the validation + of HTTPS certificates. + :param https_ca_bundle: The path to a CA_BUNDLE file or directory + with certificates of trusted CAs. + :param retry_count: Max. number of attempts for fetching content in + case of transient errors. + :param retry_interval: Interval between attempts in case of transient + errors, expressed in seconds. + :param http_request_timeout: Number of seconds until network requests + stop waiting for a response. + """ + CONFIG.update(config) diff --git a/hnv/common/utils.py b/hnv/common/utils.py index 01d9ce5..f173abd 100644 --- a/hnv/common/utils.py +++ b/hnv/common/utils.py @@ -25,10 +25,9 @@ import six from hnv.common import constant from hnv.common import exception -from hnv import config as hnv_config +from hnv import CONFIG LOG = logging.getLogger(__name__) -CONFIG = hnv_config.CONFIG class _HNVClient(object): @@ -124,7 +123,7 @@ class _HNVClient(object): response = self._session.request( method=method, url=url, headers=headers, data=json.dumps(body) if body else None, - timeout=CONFIG.HNV.http_request_timeout + timeout=CONFIG["http_request_timeout"] ) break except (requests.ConnectionError, @@ -132,12 +131,12 @@ class _HNVClient(object): attemts += 1 self._http_session = None LOG.debug("Request failed: %s", exc) - if attemts > CONFIG.HNV.retry_count: + if attemts > CONFIG["retry_count"]: if isinstance(exc, requests.exceptions.SSLError): raise exception.CertificateVerifyFailed( "HTTPS certificate validation failed.") raise - time.sleep(CONFIG.HNV.retry_interval) + time.sleep(CONFIG["retry_interval"]) try: response.raise_for_status() diff --git a/hnv/config/__init__.py b/hnv/config/__init__.py deleted file mode 100644 index ce98fa1..0000000 --- a/hnv/config/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2017 Cloudbase Solutions Srl -# -# 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. - -"""Config options available for HNV client project.""" - -from oslo_config import cfg - -from hnv.config import factory as options_factory - - -CONFIG = cfg.CONF -for option_class in options_factory.get_options(): - option_class(CONFIG).register() diff --git a/hnv/config/base.py b/hnv/config/base.py deleted file mode 100644 index 9c0add5..0000000 --- a/hnv/config/base.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2017 Cloudbase Solutions Srl -# -# 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. - -"""Contact class for all the collections of config options.""" - -import abc - -import six - - -@six.add_metaclass(abc.ABCMeta) -class Options(object): - - """Contact class for all the collections of config options.""" - - def __init__(self, config, group="DEFAULT"): - self._config = config - self._group_name = group - - @property - def group_name(self): - """The group name for the current options.""" - return self._group_name - - @abc.abstractmethod - def register(self): - """Register the current options to the global ConfigOpts object.""" - pass - - @abc.abstractmethod - def list(self): - """Return a list which contains all the available options.""" - pass diff --git a/hnv/config/client.py b/hnv/config/client.py deleted file mode 100644 index f0ebb14..0000000 --- a/hnv/config/client.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2017 Cloudbase Solutions Srl -# -# 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. - -"""Config options available for HVN.""" - -from oslo_config import cfg - -from hnv.config import base as config_base - - -class HVNOptions(config_base.Options): - - """Config options available for HVN.""" - - def __init__(self, config): - super(HVNOptions, self).__init__(config, group="HNV") - self._options = [ - cfg.StrOpt( - "url", default="http://127.0.0.1/", - help=("The base URL where the agent looks for " - "Network Controller API.")), - cfg.StrOpt( - "username", - help=("The username required for connecting to the Netowork " - "Controller API.")), - cfg.StrOpt( - "password", - help=("The password required for connecting to the Netowork " - "Controller API."), - secret=True), - cfg.BoolOpt( - "https_allow_insecure", default=False, - help=("Whether to disable the validation of " - "HTTPS certificates.")), - cfg.StrOpt( - "https_ca_bundle", default=None, - help=("The path to a CA_BUNDLE file or directory with " - "certificates of trusted CAs.")), - cfg.IntOpt( - "retry_count", default=5, - help="Max. number of attempts for fetching metadata in " - "case of transient errors"), - cfg.FloatOpt( - "retry_interval", default=1, - help=("Interval between attempts in case of transient errors, " - "expressed in seconds")), - cfg.IntOpt( - "http_request_timeout", default=None, - help=("Number of seconds until network requests stop waiting " - "for a response")), - cfg.StrOpt( - "logical_network", default=None, - help=("Logical network to use as a medium for tenant network " - "traffic.")), - ] - - def register(self): - """Register the current options to the global ConfigOpts object.""" - group = cfg.OptGroup( - self.group_name, - title="HNV (Hyper-V Network Virtualization) Options") - self._config.register_group(group) - self._config.register_opts(self._options, group=group) - - def list(self): - """Return a list which contains all the available options.""" - return self._options diff --git a/hnv/config/factory.py b/hnv/config/factory.py deleted file mode 100644 index 496e22c..0000000 --- a/hnv/config/factory.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2017 Cloudbase Solutions Srl -# -# 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. - -"""Factory for all the available config options.""" - -_OPT_PATHS = ( - 'hnv.config.client.HVNOptions', -) - - -def _load_class(class_path): - """Load the module and return the required class.""" - parts = class_path.rsplit('.', 1) - module = __import__(parts[0], fromlist=parts[1]) - return getattr(module, parts[1]) - - -def get_options(): - """Return a list of all the available `Options` subclasses.""" - return [_load_class(class_path) for class_path in _OPT_PATHS] diff --git a/hnv/config/options.py b/hnv/config/options.py deleted file mode 100644 index 440c7c4..0000000 --- a/hnv/config/options.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2017 Cloudbase Solutions Srl -# -# 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. - -""" -This is the single point of entry to generate the sample configuration -file for Cloudbase-Init. -""" - -import collections - -from hnv.config import base as config_base -from hnv.config import factory as config_factory - - -def get_options(): - """Collect all the options info from the other modules.""" - options = collections.defaultdict(list) - for opt_class in config_factory.get_options(): - if not issubclass(opt_class, config_base.Options): - continue - config_options = opt_class(None) - options[config_options.group_name].extend(config_options.list()) - return [(key, value) for key, value in options.items()] diff --git a/hnv/tests/common/test_utils.py b/hnv/tests/common/test_utils.py index 5ba63b3..42856b1 100644 --- a/hnv/tests/common/test_utils.py +++ b/hnv/tests/common/test_utils.py @@ -25,11 +25,9 @@ import requests from hnv.common import constant from hnv.common import exception from hnv.common import utils as hnv_utils -from hnv import config as hnv_config +from hnv import CONFIG from hnv.tests import utils as test_utils -CONFIG = hnv_config.CONFIG - class TestHNVClient(unittest.TestCase): @@ -142,7 +140,7 @@ class TestHNVClient(unittest.TestCase): session_request.assert_called_once_with( method=method, url=mock.sentinel.url, headers=headers, data=mock.sentinel.content if body else None, - timeout=CONFIG.HNV.http_request_timeout + timeout=CONFIG["http_request_timeout"] ) elif len(response) > 1: # Note(alexcoman): The first response is an exception @@ -170,7 +168,7 @@ class TestHNVClient(unittest.TestCase): def test_http_request_with_connection_error(self): response = [requests.ConnectionError(), mock.MagicMock()] - with test_utils.ConfigPatcher('retry_count', 1, "HNV"): + with test_utils.ConfigPatcher('retry_count', 1): self._test_http_request(method=constant.GET, body=mock.sentinel.body, response=response, @@ -179,7 +177,7 @@ class TestHNVClient(unittest.TestCase): def test_http_request_connection_error(self): response = [requests.ConnectionError(), requests.ConnectionError()] - with test_utils.ConfigPatcher('retry_count', 1, "HNV"): + with test_utils.ConfigPatcher('retry_count', 1): self._test_http_request(method=constant.GET, body=mock.sentinel.body, response=response, @@ -189,7 +187,7 @@ class TestHNVClient(unittest.TestCase): def test_http_request_ssl_error(self): response = [requests.exceptions.SSLError(), requests.exceptions.SSLError()] - with test_utils.ConfigPatcher('retry_count', 1, "HNV"): + with test_utils.ConfigPatcher('retry_count', 1): self._test_http_request(method=constant.GET, body=mock.sentinel.body, response=response, diff --git a/hnv/tests/test_client.py b/hnv/tests/test_client.py index d87fd05..2ec44c3 100644 --- a/hnv/tests/test_client.py +++ b/hnv/tests/test_client.py @@ -23,12 +23,10 @@ except ImportError: from hnv import client from hnv.common import exception -from hnv import config as hnv_config +from hnv import CONFIG from hnv.tests.fake import fake_response from hnv.tests import utils as test_utils -CONFIG = hnv_config.CONFIG - class TestBaseHNVModel(unittest.TestCase): @@ -94,7 +92,7 @@ class TestBaseHNVModel(unittest.TestCase): side_effect.append(True if not timeout else False) is_ready.side_effect = side_effect - request_timeout = CONFIG.HNV.retry_interval * loop_count + request_timeout = CONFIG["retry_interval"] * loop_count request_wait = True if loop_count > 0 else False if timeout: @@ -146,7 +144,7 @@ class TestBaseHNVModel(unittest.TestCase): side_effect.append(True) mock_is_ready.side_effect = side_effect - request_timeout = CONFIG.HNV.retry_interval * loop_count + request_timeout = CONFIG["retry_interval"] * loop_count request_wait = True if loop_count > 0 else False model = client._BaseHNVModel(resource_id="hnv-client", diff --git a/hnv/tests/utils.py b/hnv/tests/utils.py index c72257d..0f7c4d4 100644 --- a/hnv/tests/utils.py +++ b/hnv/tests/utils.py @@ -21,10 +21,7 @@ import logging as base_logging from oslo_log import log as oslo_logging -from hnv import config as hnv_conf - - -CONFIG = hnv_conf.CONFIG +from hnv import CONFIG as hnv_config class SnatchHandler(base_logging.Handler): @@ -83,15 +80,11 @@ class ConfigPatcher(object): This class can be used both as a context manager and as a decorator. """ - def __init__(self, key, value, group=None, conf=CONFIG): - if group: - self._original_value = conf.get(group).get(key) - else: - self._original_value = conf.get(key) + def __init__(self, key, value): self._key = key self._value = value - self._group = group - self._config = conf + self._original_value = None + self._config = hnv_config def __call__(self, func, *args, **kwargs): def _wrapped_f(*args, **kwargs): @@ -102,10 +95,9 @@ class ConfigPatcher(object): return _wrapped_f def __enter__(self): - self._config.set_override(self._key, self._value, - group=self._group) + self._original_value = self._config[self._key] + self._config[self._key] = self._value return self def __exit__(self, exc_type, exc_val, exc_tb): - self._config.set_override(self._key, self._original_value, - group=self._group) + self._config[self._key] = self._original_value diff --git a/requirements.txt b/requirements.txt index 5b7c4d8..16070f0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,6 @@ pbr>=1.8 # Apache-2.0 six>=1.7.0 -oslo.config!=3.18.0,>=3.14.0 # Apache-2.0 oslo.i18n>=2.1.0 # Apache-2.0 oslo.log>=3.11.0 # Apache-2.0 requests diff --git a/setup.cfg b/setup.cfg index 614e9d5..c0e3192 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,8 +29,6 @@ setup-hooks = pbr.hooks.setup_hook [entry_points] -oslo.config.opts = - hnv.conf = hnv.config.options:get_options [build_sphinx] source-dir = doc/source