Allow authentification method to be chosen

To reach Cloudkitty API endpoints, an authentification method must be set.
No authentification or Keystone authentification are allowed.
This should be set in the configuration file, within the DEFAULT block,
using the auth_strategy field.

Task: 4902
Story: 2001168

Change-Id: I3f9d5700e4c2d1a69b5514fd9932a62238ee659c
This commit is contained in:
Martin CAMEY 2017-09-18 14:30:03 +02:00
parent 9daa7c668f
commit 5baa3b8fe3
10 changed files with 114 additions and 7 deletions

View File

@ -98,7 +98,10 @@ def load_app():
if not cfg_file:
raise cfg.ConfigFilesNotFoundError([cfg.CONF.api_paste_config])
LOG.info("Full WSGI config used: %s", cfg_file)
return deploy.loadapp("config:" + cfg_file)
appname = "cloudkitty+{}".format(cfg.CONF.auth_strategy)
LOG.info("Cloudkitty api with '%s' auth type will be loaded.",
cfg.CONF.auth_strategy)
return deploy.loadapp("config:" + cfg_file, name=appname)
def build_wsgi_app(argv=None):

View File

@ -30,10 +30,12 @@ from oslo_policy import opts as policy_opts
import six
from stevedore import driver
from stevedore import extension
import webob.dec
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from cloudkitty.api import app
from cloudkitty.api import middleware
from cloudkitty import db
from cloudkitty.db import api as ck_db_api
from cloudkitty import messaging
@ -43,6 +45,7 @@ from cloudkitty.storage.sqlalchemy import models
from cloudkitty import tests
from cloudkitty import utils as ck_utils
INITIAL_TIMESTAMP = 1420070400
@ -179,6 +182,8 @@ class RatingModulesFixture(BaseExtensionFixture):
class ConfigFixture(fixture.GabbiFixture):
auth_strategy = 'noauth'
def start_fixture(self):
self.conf = None
conf = conf_fixture.Config().conf
@ -186,7 +191,7 @@ class ConfigFixture(fixture.GabbiFixture):
msg_conf = conffixture.ConfFixture(conf)
msg_conf.transport_driver = 'fake'
conf.import_group('api', 'cloudkitty.api.app')
conf.set_override('auth_strategy', 'noauth')
conf.set_override('auth_strategy', self.auth_strategy)
conf.set_override('connection', 'sqlite:///', 'database')
conf.set_override('policy_file',
os.path.abspath('etc/cloudkitty/policy.json'),
@ -208,6 +213,35 @@ class ConfigFixture(fixture.GabbiFixture):
db.get_engine().dispose()
class ConfigFixtureKeystoneAuth(ConfigFixture):
auth_strategy = 'keystone'
def start_fixture(self):
# Mocking the middleware process_request which check for credentials
# here, the only check done is that the hardcoded token is the one
# send by the query. If not, 401, else 200.
def _mock_proc_request(self, request):
token = 'c93e3e31342e4e32ba201fd3d70878b5'
http_code = 401
if 'X-Auth-Token' in request.headers and \
request.headers['X-Auth-Token'] == token:
http_code = 200
return webob.Response(
status_code=http_code,
content_type='application/json'
)
self._orig_func = middleware.auth_token.AuthProtocol.process_request
middleware.auth_token.AuthProtocol.process_request = _mock_proc_request
super(ConfigFixtureKeystoneAuth, self).start_fixture()
def stop_fixture(self):
super(ConfigFixtureKeystoneAuth, self).stop_fixture()
middleware.auth_token.AuthProtocol.process_request = self._orig_func
class BaseFakeRPC(fixture.GabbiFixture):
endpoint = None

View File

@ -1,15 +1,23 @@
# This is a custom paste.ini for our gabbi tests. It enables all middleware
# except for auth tokens.
[pipeline:cloudkitty+noauth]
pipeline = cors http_proxy_to_wsgi request_id ck_api_v1
[pipeline:main]
pipeline = cors request_id ck_api_v1
[pipeline:cloudkitty+keystone]
pipeline = cors http_proxy_to_wsgi request_id authtoken ck_api_v1
[app:ck_api_v1]
paste.app_factory = cloudkitty.api.app:app_factory
[filter:authtoken]
acl_public_routes = /, /v1
paste.filter_factory = cloudkitty.api.middleware:AuthTokenMiddleware.factory
[filter:request_id]
paste.filter_factory = oslo_middleware:RequestId.factory
[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
oslo_config_project = cloudkitty
[filter:http_proxy_to_wsgi]
paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory
oslo_config_project = cloudkitty

View File

@ -0,0 +1,21 @@
fixtures:
- ConfigFixtureKeystoneAuth
- StorageDataFixture
- NowStorageDataFixture
tests:
- name: Can't query api without token
GET: /v1/storage/dataframes
status: 401
- name: Can't query api with non valid token
GET: /v1/storage/dataframes
status: 401
request_headers:
X-Auth-Token: bf08a02dbd52406b94fcc2447bb3e266
- name: Can query api with valid token
GET: /v1/storage/dataframes
status: 200
request_headers:
X-Auth-Token: c93e3e31342e4e32ba201fd3d70878b5

View File

@ -0,0 +1,9 @@
fixtures:
- ConfigFixture
- StorageDataFixture
- NowStorageDataFixture
tests:
- name: Can query api without auth
url: /v1/storage/dataframes
status: 200

View File

@ -138,6 +138,7 @@ function configure_cloudkitty {
iniset $CLOUDKITTY_CONF DEFAULT notification_topics 'notifications'
iniset $CLOUDKITTY_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
iniset $CLOUDKITTY_CONF DEFAULT auth_strategy $CLOUDKITTY_AUTH_STRATEGY
# auth
iniset $CLOUDKITTY_CONF authinfos auth_type v3password

View File

@ -14,6 +14,7 @@ CLOUDKITTY_WSGI_DIR=${CLOUDKITTY_WSGI_DIR:-/var/www/cloudkitty}
CLOUDKITTY_AUTH_CACHE_DIR=${CLOUDKITTY_AUTH_CACHE_DIR:-/var/cache/cloudkitty}
CLOUDKITTY_DATA_DIR=${CLOUDKITTY_DATA_DIR:-/var/lib/cloudkitty}
CLOUDKITTY_REPORTS_DIR=${DATA_DIR}/cloudkitty/reports
CLOUDKITTY_AUTH_STRATEGY=keystone
# Horizon enabled file
CLOUDKITTY_DASHBOARD=$DEST/cloudkitty-dashboard/cloudkittydashboard

View File

@ -10,6 +10,31 @@ Edit :file:`/etc/cloudkitty/cloudkitty.conf` to configure cloudkitty.
Then you need to know which keystone API version you use (which can be
determined using `openstack endpoint list`)
The first thing to set is the authentification method wished to reach Cloudkitty API endpoints.
Without authentification
------------------------
If wanted, you can choose to not set any authentification method.
This should be set in de DEFAULT block of the configuration file owing to the auth_strategy field:
.. code-block:: ini
[DEFAULT]
verbose = True
log_dir = /var/log/cloudkitty
# oslo_messaging_rabbit is deprecated
transport_url = rabbit://openstack:RABBIT_PASSWORD@RABBIT_HOST
auth_strategy = noauth
Otherwise, the only other officially implemented authentification method is keystone.
More methods will be implemented soon.
It should be set in the DEFAULT configuration block too, with the auth_stategy field.
For keystone (identity) API v2 (deprecated)
-------------------------------------------
@ -20,6 +45,7 @@ For keystone (identity) API v2 (deprecated)
log_dir = /var/log/cloudkitty
# oslo_messaging_rabbit is deprecated
transport_url = rabbit://openstack:RABBIT_PASSWORD@RABBIT_HOST/
auth_strategy = keystone
[auth]
username = cloudkitty
@ -80,6 +106,7 @@ The following shows the basic configuration items:
log_dir = /var/log/cloudkitty
# oslo_messaging_rabbit is deprecated
transport_url = rabbit://openstack:RABBIT_PASSWORD@RABBIT_HOST/
auth_strategy = keystone
[ks_auth]
auth_type = v3password

View File

@ -1,4 +1,7 @@
[pipeline:main]
[pipeline:cloudkitty+noauth]
pipeline = cors http_proxy_to_wsgi request_id ck_api_v1
[pipeline:cloudkitty+keystone]
pipeline = cors http_proxy_to_wsgi request_id authtoken ck_api_v1
[app:ck_api_v1]