Add service_type, endpoint_type & region_name querying Keystone Catalog

Monasca URL is pulled from Keystone Service Catalog when not given
explicitly in agent.yaml, but only the URL with service_type=monitoring
and endpoint_type=publicURL will be retrieved.

These two options together with the region_name have been included in
the agent.yaml template and may be configured by monasca-setup, so that
the KSClient object is initialized with such keywords. This client will
retrieve the URL from Catalog accordingly.

Change-Id: Icfbfa7c46db648e3d3c27f8e5c72d02957c778f1
Closes-Bug: #1625573
This commit is contained in:
Pablo Rodriguez 2016-09-21 15:44:39 +02:00
parent e91434e2e4
commit 0556ea6888
4 changed files with 121 additions and 3 deletions

View File

@ -6,9 +6,14 @@ Api:
# Set username, password and project id.
# Set username, password, project name and (domain id or domain name).
#
# Monitoring API URL: URL for the monitoring API, if undefined it will be pulled from the keystone service catalog
# Example: https://region-a.geo-1.monitoring.hpcloudsvc.com:8080/v2.0
# Monitoring API URL (example: https://region-a.geo-1.monitoring.hpcloudsvc.com:8080/v2.0)
# If undefined, it will be pulled from Keystone Service Catalog optionally filtering by
# service_type ('monitoring' by default), endpoint_type ('publicURL' by default) and/or
# region_name (none by default).
url: {args.monasca_url}
service_type: {args.service_type}
endpoint_type: {args.endpoint_type}
region_name: {args.region_name}
# Keystone Username
username: {args.username}
# Keystone Password

View File

@ -60,10 +60,25 @@ class Keystone(object):
return kc_args
def _get_ksclient(self):
"""Get an endpoint and auth token from Keystone.
"""Get a new keystone client object.
The client provides a monasca_url property whose value is pulled from
Keystone Service Catalog filtering by service_type, endpoint_type
and/or region_name.
"""
service_type = self.config.get('service_type', None)
endpoint_type = self.config.get('endpoint_type', None)
region_name = self.config.get('region_name', None)
kc_args = self.get_credential_args()
if service_type:
kc_args.update({'service_type': service_type})
if endpoint_type:
kc_args.update({'endpoint_type': endpoint_type})
if region_name:
kc_args.update({'region_name': region_name})
return ksclient.KSClient(**kc_args)
def get_monasca_url(self):

View File

@ -215,6 +215,9 @@ def parse_arguments(parser):
parser.add_argument('--project_id', help="Keystone project id for keystone authentication", default='')
parser.add_argument('--monasca_url', help="Monasca API url, if not defined the url is pulled from keystone",
default='')
parser.add_argument('--service_type', help="Monasca API url service type in keystone catalog", default='')
parser.add_argument('--endpoint_type', help="Monasca API url endpoint type in keystone catalog", default='')
parser.add_argument('--region_name', help="Monasca API url region name in keystone catalog", default='')
parser.add_argument('--system_only', help="Setup the service but only configure the base config and system " +
"metrics (cpu, disk, load, memory, network).",
action="store_true", default=False)

View File

@ -1,9 +1,15 @@
import unittest
import mock
from monasca_agent.common.keystone import Keystone
from tests.common import base_config
class TestKeystone(unittest.TestCase):
default_endpoint_type = 'publicURL'
default_service_type = 'monitoring'
def testKeyStoneIsSingleton(self):
keystone_1 = Keystone({})
keystone_2 = Keystone({})
@ -11,3 +17,92 @@ class TestKeystone(unittest.TestCase):
self.assertTrue(keystone_1 is keystone_2)
self.assertTrue(keystone_1 is keystone_3)
def testServiceCatalogMonascaUrlUsingDefaults(self):
Keystone.instance = None
with mock.patch('keystoneclient.v3.client.Client') as client:
config = base_config.get_config('Api')
keystone = Keystone(config)
keystone.get_monasca_url()
self.assertTrue(client.called)
self.assertIn('auth_url', client.call_args[client.call_count])
self.assertNotIn('service_type', client.call_args[client.call_count])
self.assertNotIn('endpoint_type', client.call_args[client.call_count])
self.assertNotIn('region_name', client.call_args[client.call_count])
client.return_value.service_catalog.url_for.assert_has_calls([
mock.call(endpoint_type=self.default_endpoint_type, service_type=self.default_service_type)
])
def testServiceCatalogMonascaUrlWithCustomServiceType(self):
Keystone.instance = None
service_type = 'my_service_type'
with mock.patch('keystoneclient.v3.client.Client') as client:
config = base_config.get_config('Api')
config.update({'service_type': service_type})
keystone = Keystone(config)
keystone.get_monasca_url()
self.assertTrue(client.called)
self.assertIn('auth_url', client.call_args[client.call_count])
self.assertNotIn('service_type', client.call_args[client.call_count])
self.assertNotIn('endpoint_type', client.call_args[client.call_count])
self.assertNotIn('region_name', client.call_args[client.call_count])
client.return_value.service_catalog.url_for.assert_has_calls([
mock.call(endpoint_type=self.default_endpoint_type, service_type=service_type)
])
def testServiceCatalogMonascaUrlWithCustomEndpointType(self):
Keystone.instance = None
endpoint_type = 'internalURL'
with mock.patch('keystoneclient.v3.client.Client') as client:
config = base_config.get_config('Api')
config.update({'endpoint_type': endpoint_type})
keystone = Keystone(config)
keystone.get_monasca_url()
self.assertTrue(client.called)
self.assertIn('auth_url', client.call_args[client.call_count])
self.assertNotIn('service_type', client.call_args[client.call_count])
self.assertNotIn('endpoint_type', client.call_args[client.call_count])
self.assertNotIn('region_name', client.call_args[client.call_count])
client.return_value.service_catalog.url_for.assert_has_calls([
mock.call(endpoint_type=endpoint_type, service_type=self.default_service_type)
])
def testServiceCatalogMonascaUrlWithCustomRegionName(self):
Keystone.instance = None
region_name = 'my_region'
with mock.patch('keystoneclient.v3.client.Client') as client:
config = base_config.get_config('Api')
config.update({'region_name': region_name})
keystone = Keystone(config)
keystone.get_monasca_url()
self.assertTrue(client.called)
self.assertIn('auth_url', client.call_args[client.call_count])
self.assertNotIn('service_type', client.call_args[client.call_count])
self.assertNotIn('endpoint_type', client.call_args[client.call_count])
self.assertNotIn('region_name', client.call_args[client.call_count])
client.return_value.service_catalog.url_for.assert_has_calls([
mock.call(endpoint_type=self.default_endpoint_type, service_type=self.default_service_type,
attr='region', filter_value=region_name)
])
def testServiceCatalogMonascaUrlWithThreeCustomParameters(self):
Keystone.instance = None
endpoint_type = 'internalURL'
service_type = 'my_service_type'
region_name = 'my_region'
with mock.patch('keystoneclient.v3.client.Client') as client:
config = base_config.get_config('Api')
config.update({'endpoint_type': endpoint_type})
config.update({'service_type': service_type})
config.update({'region_name': region_name})
keystone = Keystone(config)
keystone.get_monasca_url()
self.assertTrue(client.called)
self.assertIn('auth_url', client.call_args[client.call_count])
self.assertNotIn('service_type', client.call_args[client.call_count])
self.assertNotIn('endpoint_type', client.call_args[client.call_count])
self.assertNotIn('region_name', client.call_args[client.call_count])
client.return_value.service_catalog.url_for.assert_has_calls([
mock.call(endpoint_type=endpoint_type, service_type=service_type,
attr='region', filter_value=region_name)
])