Added support for pluggable tenant fetcher
CloudKitty doesn't rely on Keystone at all anymore. Moved Keystone related code in a new driver so that tenant list fetching can be pluggable. Only keystone fetcher is implemented at the moment. Change-Id: Ib9de445b93f16696e6b9d205a6101a902349b76e
This commit is contained in:
parent
5e8a820656
commit
84e269d094
@ -24,6 +24,8 @@ import cloudkitty.openstack.common.lockutils
|
||||
import cloudkitty.openstack.common.log
|
||||
import cloudkitty.service
|
||||
import cloudkitty.storage
|
||||
import cloudkitty.tenant_fetcher
|
||||
import cloudkitty.tenant_fetcher.keystone
|
||||
|
||||
__all__ = ['list_opts']
|
||||
|
||||
@ -36,12 +38,16 @@ _opts = [
|
||||
cloudkitty.collector.ceilometer.ceilometer_collector_opts))),
|
||||
('collect', list(itertools.chain(
|
||||
cloudkitty.collector.collect_opts))),
|
||||
('keystone_fetcher', list(itertools.chain(
|
||||
cloudkitty.tenant_fetcher.keystone.keystone_fetcher_opts))),
|
||||
('output', list(itertools.chain(
|
||||
cloudkitty.config.output_opts))),
|
||||
('state', list(itertools.chain(
|
||||
cloudkitty.config.state_opts))),
|
||||
('storage', list(itertools.chain(
|
||||
cloudkitty.storage.storage_opts))),
|
||||
('tenant_fetcher', list(itertools.chain(
|
||||
cloudkitty.tenant_fetcher.fetchers_opts))),
|
||||
(None, list(itertools.chain(
|
||||
cloudkitty.openstack.common.lockutils.util_opts,
|
||||
cloudkitty.openstack.common.log.common_cli_opts,
|
||||
|
@ -25,23 +25,6 @@ except ImportError:
|
||||
from cloudkitty.openstack.common import log # noqa
|
||||
|
||||
|
||||
auth_opts = [
|
||||
cfg.StrOpt('username',
|
||||
default='',
|
||||
help='OpenStack username.'),
|
||||
cfg.StrOpt('password',
|
||||
default='',
|
||||
help='OpenStack password.'),
|
||||
cfg.StrOpt('tenant',
|
||||
default='',
|
||||
help='OpenStack tenant.'),
|
||||
cfg.StrOpt('region',
|
||||
default='',
|
||||
help='OpenStack region.'),
|
||||
cfg.StrOpt('url',
|
||||
default='',
|
||||
help='OpenStack auth URL.'), ]
|
||||
|
||||
state_opts = [
|
||||
cfg.StrOpt('backend',
|
||||
default='cloudkitty.backend.file.FileBackend',
|
||||
@ -62,7 +45,6 @@ output_opts = [
|
||||
help='Output pipeline'), ]
|
||||
|
||||
|
||||
cfg.CONF.register_opts(auth_opts, 'auth')
|
||||
cfg.CONF.register_opts(state_opts, 'state')
|
||||
cfg.CONF.register_opts(output_opts, 'output')
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
import decimal
|
||||
|
||||
import eventlet
|
||||
from keystoneclient.v2_0 import client as kclient
|
||||
from oslo.config import cfg
|
||||
try:
|
||||
import oslo_messaging as messaging
|
||||
@ -42,8 +41,10 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.import_opt('backend', 'cloudkitty.storage', 'storage')
|
||||
CONF.import_opt('backend', 'cloudkitty.tenant_fetcher', 'tenant_fetcher')
|
||||
|
||||
COLLECTORS_NAMESPACE = 'cloudkitty.collector.backends'
|
||||
FETCHERS_NAMESPACE = 'cloudkitty.tenant.fetchers'
|
||||
TRANSFORMERS_NAMESPACE = 'cloudkitty.transformers'
|
||||
PROCESSORS_NAMESPACE = 'cloudkitty.rating.processors'
|
||||
STORAGES_NAMESPACE = 'cloudkitty.storage.backends'
|
||||
@ -196,19 +197,11 @@ class Worker(BaseWorker):
|
||||
|
||||
class Orchestrator(object):
|
||||
def __init__(self):
|
||||
# Load credentials informations
|
||||
self.user = CONF.auth.username
|
||||
self.password = CONF.auth.password
|
||||
self.tenant = CONF.auth.tenant
|
||||
self.region = CONF.auth.region
|
||||
self.keystone_url = CONF.auth.url
|
||||
|
||||
# Initialize keystone admin session
|
||||
self.admin_ks = kclient.Client(username=self.user,
|
||||
password=self.password,
|
||||
tenant_name=self.tenant,
|
||||
region_name=self.region,
|
||||
auth_url=self.keystone_url)
|
||||
# Tenant fetcher
|
||||
self.fetcher = driver.DriverManager(
|
||||
FETCHERS_NAMESPACE,
|
||||
CONF.fetchers.backend,
|
||||
invoke_on_load=True).driver
|
||||
|
||||
# Transformers
|
||||
self.transformers = {}
|
||||
@ -235,18 +228,7 @@ class Orchestrator(object):
|
||||
self._init_messaging()
|
||||
|
||||
def _load_tenant_list(self):
|
||||
ks = kclient.Client(username=self.user,
|
||||
password=self.password,
|
||||
auth_url=self.keystone_url,
|
||||
region_name=self.region)
|
||||
tenant_list = ks.tenants.list()
|
||||
self._tenants = []
|
||||
for tenant in tenant_list:
|
||||
roles = self.admin_ks.roles.roles_for_user(self.admin_ks.user_id,
|
||||
tenant)
|
||||
for role in roles:
|
||||
if role.name == 'rating':
|
||||
self._tenants.append(tenant)
|
||||
self._tenants = self.fetcher.get_tenants()
|
||||
|
||||
def _init_messaging(self):
|
||||
target = messaging.Target(topic='cloudkitty',
|
||||
|
42
cloudkitty/tenant_fetcher/__init__.py
Normal file
42
cloudkitty/tenant_fetcher/__init__.py
Normal file
@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# !/usr/bin/env python
|
||||
# Copyright 2015 Objectif Libre
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# @author: Stéphane Albert
|
||||
#
|
||||
import abc
|
||||
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
|
||||
fetchers_opts = [
|
||||
cfg.StrOpt('backend',
|
||||
default='keystone',
|
||||
help='Driver used to fetch tenant list.')
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(fetchers_opts, 'tenant_fetcher')
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseFetcher(object):
|
||||
"""CloudKitty tenants fetcher.
|
||||
|
||||
Provides Cloudkitty integration with a backend announcing ratable tenants.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_tenants(self):
|
||||
"""Get a list a tenants to rate."""
|
74
cloudkitty/tenant_fetcher/keystone.py
Normal file
74
cloudkitty/tenant_fetcher/keystone.py
Normal file
@ -0,0 +1,74 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# !/usr/bin/env python
|
||||
# Copyright 2015 Objectif Libre
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# @author: Stéphane Albert
|
||||
#
|
||||
from keystoneclient.v2_0 import client as kclient
|
||||
from oslo.config import cfg
|
||||
|
||||
from cloudkitty import tenant_fetcher
|
||||
|
||||
keystone_fetcher_opts = [
|
||||
cfg.StrOpt('username',
|
||||
default='',
|
||||
help='OpenStack username.'),
|
||||
cfg.StrOpt('password',
|
||||
default='',
|
||||
help='OpenStack password.'),
|
||||
cfg.StrOpt('tenant',
|
||||
default='',
|
||||
help='OpenStack tenant.'),
|
||||
cfg.StrOpt('region',
|
||||
default='',
|
||||
help='OpenStack region.'),
|
||||
cfg.StrOpt('url',
|
||||
default='',
|
||||
help='OpenStack auth URL.'), ]
|
||||
|
||||
cfg.CONF.register_opts(keystone_fetcher_opts, 'keystone_fetcher')
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class KeystoneFetcher(tenant_fetcher.BaseFetcher):
|
||||
"""Keystone tenants fetcher."""
|
||||
|
||||
def __init__(self):
|
||||
self.user = CONF.auth.username
|
||||
self.password = CONF.auth.password
|
||||
self.tenant = CONF.auth.tenant
|
||||
self.region = CONF.auth.region
|
||||
self.keystone_url = CONF.auth.url
|
||||
self.admin_ks = kclient.Client(
|
||||
username=self.user,
|
||||
password=self.password,
|
||||
tenant_name=self.tenant,
|
||||
region_name=self.region,
|
||||
auth_url=self.keystone_url)
|
||||
|
||||
def get_tenants(self):
|
||||
ks = kclient.Client(username=self.user,
|
||||
password=self.password,
|
||||
auth_url=self.keystone_url,
|
||||
region_name=self.region)
|
||||
tenant_list = ks.tenants.list()
|
||||
for tenant in tenant_list:
|
||||
roles = self.admin_ks.roles.roles_for_user(self.admin_ks.user_id,
|
||||
tenant)
|
||||
for role in roles:
|
||||
if role.name == 'rating':
|
||||
tenant_list.remove(tenant)
|
||||
|
||||
return tenant_list
|
@ -38,11 +38,16 @@ class OrchestratorTest(tests.TestCase):
|
||||
super(OrchestratorTest, self).setUp()
|
||||
messaging_conf = self.useFixture(conffixture.ConfFixture(self.conf))
|
||||
messaging_conf.transport_driver = 'fake'
|
||||
self.conf.set_override('username', 'cloudkitty', 'auth')
|
||||
self.conf.set_override('password', 'cloudkitty', 'auth')
|
||||
self.conf.set_override('tenant', 'cloudkitty', 'auth')
|
||||
self.conf.set_override('region', 'RegionOne', 'auth')
|
||||
self.conf.set_override('url', 'http://127.0.0.1:5000/v2.0', 'auth')
|
||||
self.conf.set_override('backend', 'keystone', 'tenant_fetcher')
|
||||
self.conf.import_group('keystone_fetcher',
|
||||
'cloudkitty.tenant_fetcher.keystone')
|
||||
self.conf.set_override('username', 'cloudkitty', 'keystone_fetcher')
|
||||
self.conf.set_override('password', 'cloudkitty', 'keystone_fetcher')
|
||||
self.conf.set_override('tenant', 'cloudkitty', 'keystone_fetcher')
|
||||
self.conf.set_override('region', 'RegionOne', 'keystone_fetcher')
|
||||
self.conf.set_override('url',
|
||||
'http://127.0.0.1:5000/v2.0',
|
||||
'keystone_fetcher')
|
||||
|
||||
def setup_fake_modules(self):
|
||||
fake_module1 = tests.FakeRatingModule()
|
||||
|
@ -33,6 +33,9 @@ cloudkitty.collector.backends =
|
||||
ceilometer = cloudkitty.collector.ceilometer:CeilometerCollector
|
||||
meta = cloudkitty.collector.meta:MetaCollector
|
||||
|
||||
cloudkitty.tenant.fetchers =
|
||||
keystone = cloudkitty.tenant_fetcher.keystone:KeystoneFetcher
|
||||
|
||||
cloudkitty.transformers =
|
||||
CloudKittyFormatTransformer = cloudkitty.transformer.format:CloudKittyFormatTransformer
|
||||
CeilometerTransformer = cloudkitty.transformer.ceilometer:CeilometerTransformer
|
||||
|
Loading…
Reference in New Issue
Block a user