Integrate with newer client
In overall following change adjustes monasca-ui code to the shape of the python-monascaclient (integrated with osc-lib, see Depends-On for details). Extra: - added profiling capabilities - added caching of client instances - installing master python-monascaclient for test purposes - supporting installing python-monascaclient if specified via Depends-On Depends-On: I1712a24739438e2d8331a495f18f357749a633c5 Change-Id: I01d0f3d9814376f9358feb23494e1ca5231aedac
This commit is contained in:
parent
91f7719951
commit
9dc87decbf
@ -12,6 +12,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
from django.contrib import messages
|
||||
from django.core.paginator import Paginator, EmptyPage
|
||||
from django.core.urlresolvers import reverse_lazy, reverse # noqa
|
||||
@ -24,7 +26,7 @@ from horizon import tables
|
||||
from horizon.utils import functions as utils
|
||||
from horizon import workflows
|
||||
|
||||
import monascaclient.exc as exc
|
||||
from monascaclient import exc
|
||||
from monitoring.alarmdefs import constants
|
||||
from monitoring.alarmdefs import forms as alarm_forms
|
||||
from monitoring.alarmdefs import tables as alarm_tables
|
||||
@ -34,6 +36,7 @@ from monitoring import api
|
||||
from openstack_dashboard import policy
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
PREV_PAGE_LIMIT = 100
|
||||
|
||||
|
||||
@ -53,7 +56,8 @@ class IndexView(tables.DataTableView):
|
||||
results = paginator.page(1)
|
||||
except EmptyPage:
|
||||
results = paginator.page(paginator.num_pages)
|
||||
except Exception:
|
||||
except Exception as ex:
|
||||
LOG.exception(str(ex))
|
||||
messages.error(self.request, _("Could not retrieve alarm definitions"))
|
||||
|
||||
return results
|
||||
@ -147,7 +151,7 @@ class AlarmDetailView(TemplateView):
|
||||
notification['undetermined'] = False
|
||||
notifications.append(notification)
|
||||
# except exceptions.NOT_FOUND:
|
||||
except exc.HTTPException:
|
||||
except exc.HttpError:
|
||||
msg = _("Notification %s has already been deleted.") % id
|
||||
notifications.append({"id": id,
|
||||
"name": unicode(msg),
|
||||
@ -214,7 +218,7 @@ class AlarmEditView(forms.ModalFormView):
|
||||
notification['undetermined'] = False
|
||||
notifications.append(notification)
|
||||
# except exceptions.NOT_FOUND:
|
||||
except exc.HTTPException:
|
||||
except exc.HttpError:
|
||||
msg = _("Notification %s has already been deleted.") % id
|
||||
messages.warning(self.request, msg)
|
||||
|
||||
|
@ -297,9 +297,9 @@ class AlarmHistoryView(tables.DataTableView):
|
||||
limit = utils.get_page_size(self.request)
|
||||
try:
|
||||
results = api.monitor.alarm_history(self.request,
|
||||
object_id,
|
||||
page_offset,
|
||||
limit)
|
||||
object_id,
|
||||
page_offset,
|
||||
limit)
|
||||
paginator = Paginator(results, limit)
|
||||
contacts = paginator.page(1)
|
||||
except EmptyPage:
|
||||
|
99
monitoring/api/client.py
Normal file
99
monitoring/api/client.py
Normal file
@ -0,0 +1,99 @@
|
||||
# Copyright 2017 Fujitsu LIMITED
|
||||
#
|
||||
# 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 horizon import exceptions
|
||||
from horizon.utils import memoized
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from openstack_dashboard.api import base
|
||||
|
||||
from monascaclient import client as mon_client
|
||||
from monitoring.config import local_settings as settings
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
INSECURE = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
|
||||
CACERT = getattr(settings, 'OPENSTACK_SSL_CACERT', None)
|
||||
|
||||
KEYSTONE_SERVICE = 'identity'
|
||||
MONITORING_SERVICE = getattr(settings, 'MONITORING_SERVICE_TYPE', 'monitoring')
|
||||
|
||||
VERSIONS = base.APIVersionManager(
|
||||
MONITORING_SERVICE,
|
||||
preferred_version=getattr(settings,
|
||||
'OPENSTACK_API_VERSIONS',
|
||||
{}).get(MONITORING_SERVICE, 2.0)
|
||||
)
|
||||
VERSIONS.load_supported_version(2.0, {'client': mon_client, 'version': '2_0'})
|
||||
|
||||
|
||||
def _get_endpoint(request):
|
||||
try:
|
||||
endpoint = base.url_for(request,
|
||||
service_type=settings.MONITORING_SERVICE_TYPE,
|
||||
endpoint_type=settings.MONITORING_ENDPOINT_TYPE)
|
||||
except exceptions.ServiceCatalogException:
|
||||
endpoint = 'http://127.0.0.1:8070/v2.0'
|
||||
LOG.warning('Monasca API location could not be found in Service '
|
||||
'Catalog, using default: {0}'.format(endpoint))
|
||||
return endpoint
|
||||
|
||||
|
||||
def _get_auth_params_from_request(request):
|
||||
"""Extracts the properties from the request object needed by the monascaclient
|
||||
call below. These will be used to memoize the calls to monascaclient
|
||||
"""
|
||||
LOG.debug('Extracting intel from request')
|
||||
return (
|
||||
request.user.user_domain_id,
|
||||
request.user.token.id,
|
||||
request.user.tenant_id,
|
||||
request.user.token.project.get('domain_id'),
|
||||
base.url_for(request, MONITORING_SERVICE),
|
||||
base.url_for(request, KEYSTONE_SERVICE)
|
||||
)
|
||||
|
||||
|
||||
@memoized.memoized_with_request(_get_auth_params_from_request)
|
||||
def monascaclient(request_auth_params, version=None):
|
||||
|
||||
(
|
||||
user_domain_id,
|
||||
token_id,
|
||||
project_id,
|
||||
project_domain_id,
|
||||
monasca_url,
|
||||
auth_url
|
||||
) = request_auth_params
|
||||
|
||||
# NOTE(trebskit) this is bit hacky, we should
|
||||
# go straight into using numbers as version representation
|
||||
version = (VERSIONS.get_active_version()['version']
|
||||
if not version else version)
|
||||
|
||||
LOG.debug('Monasca::Client <Url: %s> <Version: %s>'
|
||||
% (monasca_url, version))
|
||||
|
||||
c = mon_client.Client(api_version=version,
|
||||
token=token_id,
|
||||
project_id=project_id,
|
||||
user_domain_id=user_domain_id,
|
||||
project_domain_id=project_domain_id,
|
||||
insecure=INSECURE,
|
||||
cert=CACERT,
|
||||
auth_url=auth_url,
|
||||
endpoint=monasca_url)
|
||||
return c
|
@ -10,59 +10,25 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
from oslo_log import log
|
||||
|
||||
from monascaclient import client as monasca_client
|
||||
from openstack_dashboard.api import base
|
||||
from monitoring.config import local_settings as settings
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def format_parameters(params):
|
||||
parameters = {}
|
||||
for count, p in enumerate(params, 1):
|
||||
parameters['Parameters.member.%d.ParameterKey' % count] = p
|
||||
parameters['Parameters.member.%d.ParameterValue' % count] = params[p]
|
||||
return parameters
|
||||
|
||||
|
||||
def monasca_endpoint(request):
|
||||
endpoint = base.url_for(request, settings.MONITORING_SERVICE_TYPE)
|
||||
if endpoint.endswith('/'):
|
||||
endpoint = endpoint[:-1]
|
||||
return endpoint
|
||||
|
||||
|
||||
def monascaclient(request, password=None):
|
||||
api_version = "2_0"
|
||||
endpoint = monasca_endpoint(request)
|
||||
LOG.debug('monascaclient connection created using token "%s" , url "%s"' %
|
||||
(request.user.token.id, endpoint))
|
||||
kwargs = {
|
||||
'token': request.user.token.id,
|
||||
'insecure': settings.OPENSTACK_SSL_NO_VERIFY,
|
||||
'ca_file': settings.OPENSTACK_SSL_CACERT,
|
||||
'username': request.user.username,
|
||||
'password': password
|
||||
# 'timeout': args.timeout,
|
||||
# 'ca_file': args.ca_file,
|
||||
# 'cert_file': args.cert_file,
|
||||
# 'key_file': args.key_file,
|
||||
}
|
||||
client = monasca_client.Client(api_version, endpoint, **kwargs)
|
||||
client.format_parameters = format_parameters
|
||||
return client
|
||||
from openstack_dashboard.contrib.developer.profiler import api as profiler
|
||||
|
||||
from monitoring.api import client
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarm_list(request, offset=0, limit=10000, marker=None, paginate=False):
|
||||
result = monascaclient(request).alarms.list(offset=offset, limit=limit)
|
||||
result = client.monascaclient(request).alarms.list(offset=offset,
|
||||
limit=limit)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarm_list_by_dimension(request, dimensions, offset=0, limit=10000,
|
||||
marker=None, paginate=False):
|
||||
marker=None, paginate=False):
|
||||
dim_dict = {}
|
||||
metric = None
|
||||
dimensions = dimensions.split(",")
|
||||
@ -76,118 +42,152 @@ def alarm_list_by_dimension(request, dimensions, offset=0, limit=10000,
|
||||
else:
|
||||
dim_dict[item] = None
|
||||
if metric:
|
||||
result = monascaclient(request).alarms.list(offset=offset, limit=limit,
|
||||
metric_dimensions=dim_dict,
|
||||
metric_name=metric)
|
||||
result = client.monascaclient(request).alarms.list(offset=offset,
|
||||
limit=limit,
|
||||
metric_dimensions=dim_dict,
|
||||
metric_name=metric)
|
||||
else:
|
||||
result = monascaclient(request).alarms.list(offset=offset, limit=limit,
|
||||
metric_dimensions=dim_dict)
|
||||
result = client.monascaclient(request).alarms.list(offset=offset,
|
||||
limit=limit,
|
||||
metric_dimensions=dim_dict)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarm_show(request, alarm_id):
|
||||
result = monascaclient(request).alarms.get(alarm_id=alarm_id)
|
||||
result = client.monascaclient(request).alarms.get(alarm_id=alarm_id)
|
||||
return result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarm_delete(request, alarm_id):
|
||||
return monascaclient(request).alarms.delete(alarm_id=alarm_id)
|
||||
return client.monascaclient(request).alarms.delete(alarm_id=alarm_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarm_history(request, alarm_id, offset=0, limit=10000):
|
||||
result = monascaclient(request).alarms.history(alarm_id=alarm_id, offset=offset, limit=limit)
|
||||
result = client.monascaclient(request).alarms.history(alarm_id=alarm_id,
|
||||
offset=offset,
|
||||
limit=limit)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarm_get(request, alarm_id):
|
||||
return monascaclient(request).alarms.get(alarm_id=alarm_id)
|
||||
return client.monascaclient(request).alarms.get(alarm_id=alarm_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarm_patch(request, **kwargs):
|
||||
return monascaclient(request).alarms.patch(**kwargs)
|
||||
return client.monascaclient(request).alarms.patch(**kwargs)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarmdef_list(request, offset=0, limit=10000, marker=None, paginate=False):
|
||||
result = monascaclient(request).alarm_definitions.list(offset=offset, limit=limit)
|
||||
result = client.monascaclient(request).alarm_definitions.list(offset=offset,
|
||||
limit=limit)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
def alarmdef_list_by_service(request, service_name, marker=None, paginate=False):
|
||||
@profiler.trace
|
||||
def alarmdef_list_by_service(request, service_name, marker=None,
|
||||
paginate=False):
|
||||
service_dim = {'service': service_name}
|
||||
result = monascaclient(request).alarm_definitions.list(dimensions=service_dim)
|
||||
result = client.monascaclient(request).alarm_definitions.list(
|
||||
dimensions=service_dim)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarmdef_delete(request, alarm_id):
|
||||
return monascaclient(request).alarm_definitions.delete(alarm_id=alarm_id)
|
||||
return client.monascaclient(request).alarm_definitions.delete(
|
||||
alarm_id=alarm_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarmdef_history(request, alarm_id):
|
||||
return monascaclient(request).alarm_definitions.history(alarm_id=alarm_id)
|
||||
return client.monascaclient(request).alarm_definitions.history(
|
||||
alarm_id=alarm_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarmdef_get(request, alarm_id):
|
||||
return monascaclient(request).alarm_definitions.get(alarm_id=alarm_id)
|
||||
return client.monascaclient(request).alarm_definitions.get(alarm_id=alarm_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarmdef_get_by_name(request, name):
|
||||
return monascaclient(request).alarm_definitions.list(
|
||||
return client.monascaclient(request).alarm_definitions.list(
|
||||
name=name,
|
||||
limit=1
|
||||
)
|
||||
|
||||
|
||||
def alarmdef_create(request, password=None, **kwargs):
|
||||
return monascaclient(request, password).alarm_definitions.create(**kwargs)
|
||||
@profiler.trace
|
||||
def alarmdef_create(request, **kwargs):
|
||||
return client.monascaclient(request).alarm_definitions.create(**kwargs)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarmdef_update(request, **kwargs):
|
||||
return monascaclient(request).alarm_definitions.update(**kwargs)
|
||||
return client.monascaclient(request).alarm_definitions.update(**kwargs)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def alarmdef_patch(request, **kwargs):
|
||||
return monascaclient(request).alarm_definitions.patch(**kwargs)
|
||||
return client.monascaclient(request).alarm_definitions.patch(**kwargs)
|
||||
|
||||
|
||||
def notification_list(request, offset=0, limit=10000, marker=None, paginate=False):
|
||||
result = monascaclient(request).notifications.list(offset=offset, limit=limit)
|
||||
@profiler.trace
|
||||
def notification_list(request, offset=0, limit=10000, marker=None,
|
||||
paginate=False):
|
||||
result = client.monascaclient(request).notifications.list(offset=offset,
|
||||
limit=limit)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def notification_delete(request, notification_id):
|
||||
return monascaclient(request).notifications.delete(
|
||||
return client.monascaclient(request).notifications.delete(
|
||||
notification_id=notification_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def notification_get(request, notification_id):
|
||||
return monascaclient(request).notifications. \
|
||||
return client.monascaclient(request).notifications. \
|
||||
get(notification_id=notification_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def notification_create(request, **kwargs):
|
||||
return monascaclient(request).notifications.create(**kwargs)
|
||||
return client.monascaclient(request).notifications.create(**kwargs)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def notification_update(request, notification_id, **kwargs):
|
||||
return monascaclient(request).notifications. \
|
||||
return client.monascaclient(request).notifications. \
|
||||
update(notification_id=notification_id, **kwargs)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def notification_type_list(request, **kwargs):
|
||||
result = monascaclient(request).notificationtypes.list(**kwargs)
|
||||
result = client.monascaclient(request).notificationtypes.list(**kwargs)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def metrics_list(request, **kwargs):
|
||||
result = monascaclient(request).metrics.list(**kwargs)
|
||||
result = client.monascaclient(request).metrics.list(**kwargs)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def metrics_measurement_list(request, **kwargs):
|
||||
result = monascaclient(request).metrics.list_measurements(**kwargs)
|
||||
result = client.monascaclient(request).metrics.list_measurements(**kwargs)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def metrics_stat_list(request, **kwargs):
|
||||
result = monascaclient(request).metrics.list_statistics(**kwargs)
|
||||
result = client.monascaclient(request).metrics.list_statistics(**kwargs)
|
||||
return result['elements'] if type(result) is dict else result
|
||||
|
@ -41,9 +41,16 @@ MONITORING_SERVICES = getattr(
|
||||
# {'name': _('Instances'), 'groupBy': 'hostname'}]},
|
||||
# ]
|
||||
|
||||
MONITORING_SERVICE_VERSION = getattr(
|
||||
settings, 'MONITORING_SERVICE_VERSION', '2_0'
|
||||
)
|
||||
MONITORING_SERVICE_TYPE = getattr(
|
||||
settings, 'MONITORING_SERVICE_TYPE', 'monitoring'
|
||||
)
|
||||
MONITORING_ENDPOINT_TYPE = getattr(
|
||||
# NOTE(trebskit) # will default to OPENSTACK_ENDPOINT_TYPE
|
||||
settings, 'MONITORING_ENDPOINT_TYPE', None
|
||||
)
|
||||
|
||||
# Grafana button titles/file names (global across all projects):
|
||||
GRAFANA_LINKS = []
|
||||
|
@ -10,6 +10,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from monascaclient import exc
|
||||
|
||||
DASHBOARD = "monitoring"
|
||||
|
||||
# A list of applications to be added to INSTALLED_APPS.
|
||||
@ -29,10 +31,15 @@ ADD_JS_FILES = ['monitoring/js/app.js',
|
||||
ADD_SCSS_FILES = [
|
||||
'monitoring/css/alarm-create.scss']
|
||||
|
||||
from monascaclient import exc
|
||||
# A dictionary of exception classes to be added to HORIZON['exceptions'].
|
||||
_RECOVERABLE_ERRORS = (exc.UnprocessableEntity, exc.Conflict,
|
||||
exc.BadRequest, exc.ConnectionError,
|
||||
exc.Forbidden, exc.InternalServerError)
|
||||
_NOT_FOUND_ERRORS = (exc.NotFound,)
|
||||
_UNAUTHORIZED_ERRORS = (exc.Unauthorized,)
|
||||
|
||||
ADD_EXCEPTIONS = {
|
||||
'recoverable': (exc.HTTPUnProcessable, exc.HTTPConflict, exc.HTTPException),
|
||||
'not_found': (exc.HTTPNotFound,),
|
||||
'unauthorized': (exc.HTTPUnauthorized,),
|
||||
'recoverable': _RECOVERABLE_ERRORS,
|
||||
'not_found': _NOT_FOUND_ERRORS,
|
||||
'unauthorized': _UNAUTHORIZED_ERRORS,
|
||||
}
|
||||
|
@ -12,17 +12,14 @@
|
||||
# under the License.
|
||||
|
||||
# NOTE(dmllr): Remove me when we require monascaclient >= 1.3.0
|
||||
try:
|
||||
from monascaclient.apiclient import exceptions as monascacli
|
||||
except ImportError:
|
||||
from monascaclient.openstack.common.apiclient import exceptions as monascacli
|
||||
|
||||
from monascaclient import exc
|
||||
from openstack_dashboard.test.test_data import exceptions
|
||||
|
||||
|
||||
def data(TEST):
|
||||
TEST.exceptions = exceptions.data
|
||||
|
||||
monitoring_exception = monascacli.ClientException
|
||||
monitoring_exception = exc.ClientException
|
||||
TEST.exceptions.monitoring = exceptions.create_stubbed_exception(
|
||||
monitoring_exception)
|
||||
|
@ -9,6 +9,27 @@ BRANCH_NAME=master
|
||||
PACKAGE_NAME=monasca-ui
|
||||
requirements_installed=$(echo "import openstack_requirements" | python 2>/dev/null ; echo $?)
|
||||
|
||||
function install_client_depends_on() {
|
||||
local client_location
|
||||
if [ -x "$ZUUL_CLONER" ]; then
|
||||
# install in gate environment
|
||||
pushd $mydir
|
||||
$ZUUL_CLONER --cache-dir \
|
||||
/opt/git \
|
||||
git://git.openstack.org \
|
||||
openstack/python-monascaclient
|
||||
cd openstack/python-monascaclient
|
||||
echo "Using python-monascaclient $(git log -n 1 --oneline)"
|
||||
client_location="file://$PWD#egg=python_monascaclient"
|
||||
popd
|
||||
else
|
||||
echo "Using python-monascaclient@master"
|
||||
client_location="git+https://git.openstack.org/openstack/python-monascaclient@master#egg=python_monascaclient"
|
||||
fi
|
||||
edit-constraints $localfile -- "python-monascaclient" "$client_location"
|
||||
$install_cmd -U "$client_location"
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
git config --global url.https://git.openstack.org/.insteadOf git://git.openstack.org/
|
||||
@ -37,8 +58,7 @@ elif [ -x "$ZUUL_CLONER" ]; then
|
||||
--branch $BRANCH_NAME \
|
||||
git://git.openstack.org \
|
||||
openstack/requirements
|
||||
cd openstack/requirements
|
||||
$install_cmd -e .
|
||||
cd openstack/requirements ; $install_cmd -e . ; cd -
|
||||
popd
|
||||
else
|
||||
echo "PIP HARDCODE" > /tmp/tox_install.txt
|
||||
@ -52,6 +72,7 @@ fi
|
||||
# the current repo. It is listed in constraints file and thus any
|
||||
# install will be constrained and we need to unconstrain it.
|
||||
edit-constraints $localfile -- $PACKAGE_NAME "-e file://$PWD#egg=$PACKAGE_NAME"
|
||||
install_client_depends_on
|
||||
|
||||
$install_cmd -U $*
|
||||
exit $?
|
||||
|
Loading…
Reference in New Issue
Block a user