diff --git a/neutron/services/metering/agents/metering_agent.py b/neutron/services/metering/agents/metering_agent.py index f8c5bd377db..d2782440791 100644 --- a/neutron/services/metering/agents/metering_agent.py +++ b/neutron/services/metering/agents/metering_agent.py @@ -21,9 +21,9 @@ import oslo_messaging from oslo_service import loopingcall from oslo_service import periodic_task from oslo_service import service -from oslo_utils import importutils from oslo_utils import timeutils +from neutron.services.metering.drivers import utils as driverutils from neutron._i18n import _, _LE, _LI, _LW from neutron.agent.common import config from neutron.agent import rpc as agent_rpc @@ -86,8 +86,8 @@ class MeteringAgent(MeteringPluginRpc, manager.Manager): LOG.info(_LI("Loading Metering driver %s"), self.conf.driver) if not self.conf.driver: raise SystemExit(_('A metering driver must be specified')) - self.metering_driver = importutils.import_object( - self.conf.driver, self, self.conf) + self.metering_driver = driverutils.load_metering_driver(self, + self.conf) def _metering_notification(self): for label_id, info in self.metering_infos.items(): diff --git a/neutron/services/metering/drivers/utils.py b/neutron/services/metering/drivers/utils.py new file mode 100644 index 00000000000..cdf6c933027 --- /dev/null +++ b/neutron/services/metering/drivers/utils.py @@ -0,0 +1,42 @@ +# Copyright 2017 Red Hat, Inc. +# All Rights Reserved. +# +# 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 oslo_log import log as logging + +from neutron._i18n import _LE +from neutron.common import utils as utils + + +LOG = logging.getLogger(__name__) + +METERING_NAMESPACE = 'neutron.services.metering_drivers' + + +def load_metering_driver(plugin, conf): + """Load metering driver + + :param plugin: the metering plugin + :param conf: driver configuration object + :raises SystemExit of 1 if driver cannot be loaded + """ + + try: + loaded_class = utils.load_class_by_alias_or_classname( + METERING_NAMESPACE, conf.driver) + return loaded_class(plugin, conf) + except ImportError: + LOG.error(_LE("Error loading metering driver '%s'"), + conf.driver) + raise SystemExit(1) diff --git a/neutron/tests/unit/services/metering/agents/test_metering_agent.py b/neutron/tests/unit/services/metering/agents/test_metering_agent.py index eee1ad7c050..ae19e8b300f 100644 --- a/neutron/tests/unit/services/metering/agents/test_metering_agent.py +++ b/neutron/tests/unit/services/metering/agents/test_metering_agent.py @@ -54,7 +54,7 @@ class TestMeteringOperations(base.BaseTestCase): self.noop_driver = ('neutron.services.metering.drivers.noop.' 'noop_driver.NoopMeteringDriver') - cfg.CONF.set_override('driver', self.noop_driver) + cfg.CONF.set_override('driver', 'noop') cfg.CONF.set_override('measure_interval', 0) cfg.CONF.set_override('report_interval', 0) @@ -230,9 +230,7 @@ class TestMeteringDriver(base.BaseTestCase): super(TestMeteringDriver, self).setUp() metering_agent_config.register_metering_agent_opts() - self.noop_driver = ('neutron.services.metering.drivers.noop.' - 'noop_driver.NoopMeteringDriver') - cfg.CONF.set_override('driver', self.noop_driver) + cfg.CONF.set_override('driver', 'noop') self.agent = metering_agent.MeteringAgent('my agent', cfg.CONF) self.driver = mock.Mock() @@ -244,7 +242,7 @@ class TestMeteringDriver(base.BaseTestCase): with mock.patch.object(metering_agent, 'LOG') as log: self.agent.add_metering_label(None, ROUTERS) log.exception.assert_called_with(mock.ANY, - {'driver': self.noop_driver, + {'driver': 'noop', 'func': 'add_metering_label'}) def test_add_metering_label_runtime_error(self): @@ -253,7 +251,7 @@ class TestMeteringDriver(base.BaseTestCase): with mock.patch.object(metering_agent, 'LOG') as log: self.agent.add_metering_label(None, ROUTERS) log.exception.assert_called_with(mock.ANY, - {'driver': self.noop_driver, + {'driver': 'noop', 'func': 'add_metering_label'}) diff --git a/releasenotes/notes/metering-driver-stevedore-alias-2c4fdb0556205a3a.yaml b/releasenotes/notes/metering-driver-stevedore-alias-2c4fdb0556205a3a.yaml new file mode 100644 index 00000000000..019dbe49b23 --- /dev/null +++ b/releasenotes/notes/metering-driver-stevedore-alias-2c4fdb0556205a3a.yaml @@ -0,0 +1,6 @@ +--- +features: + - The metering agent driver can now be specified with a stevedore + alias in the ``metering_agent.ini`` file. For example, + ``driver = iptables`` instead of + ``driver = neutron.services.metering.iptables.iptables_driver:IptablesMeteringDriver``. diff --git a/setup.cfg b/setup.cfg index a210ff4810e..2945475abff 100644 --- a/setup.cfg +++ b/setup.cfg @@ -151,6 +151,9 @@ neutron.agent.firewall_drivers = iptables = neutron.agent.linux.iptables_firewall:IptablesFirewallDriver iptables_hybrid = neutron.agent.linux.iptables_firewall:OVSHybridIptablesFirewallDriver openvswitch = neutron.agent.linux.openvswitch_firewall:OVSFirewallDriver +neutron.services.metering_drivers = + noop = neutron.services.metering.drivers.noop.noop_driver:NoopMeteringDriver + iptables = neutron.services.metering.iptables.iptables_driver:IptablesMeteringDriver tempest.test_plugins = neutron_tests = neutron.tests.tempest.plugin:NeutronTempestPlugin