From 35ef2f7832eb995b700a882262305a0dfedbc4c1 Mon Sep 17 00:00:00 2001 From: "vijay.r" Date: Tue, 30 Apr 2019 17:55:49 +0530 Subject: [PATCH] Gerrit id-7270 Enhancing NBI to define APIs for metric collection changes are made aligning to project architecture Change-Id: Icde144c97ac29ff988c553c22406e357b099101c Signed-off-by: vijay.r --- Dockerfile.local | 5 +++- osm_nbi/engine.py | 4 +++ osm_nbi/nbi.cfg | 4 +++ osm_nbi/nbi.py | 18 +++++++++-- osm_nbi/pmjobs_topics.py | 64 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 osm_nbi/pmjobs_topics.py diff --git a/Dockerfile.local b/Dockerfile.local index def89c4..7ac6091 100644 --- a/Dockerfile.local +++ b/Dockerfile.local @@ -21,7 +21,7 @@ WORKDIR /app/NBI/osm_nbi RUN apt-get update && apt-get install -y git python3 python3-jsonschema \ python3-pymongo python3-yaml python3-pip python3-keystoneclient \ && pip3 install pip==9.0.3 \ - && pip3 install aiokafka cherrypy==18.0.0 keystoneauth1 requests \ + && pip3 install aiokafka aiohttp cherrypy==18.0.0 keystoneauth1 requests \ && mkdir -p /app/storage/kafka && mkdir -p /app/log # OSM_COMMON @@ -90,6 +90,9 @@ ENV OSMNBI_AUTHENTICATION_BACKEND internal # RBAC ENV OSMNBI_RBAC_RESOURCES_TO_OPERATIONS /app/NBI/osm_nbi/resources_to_operations.yml ENV OSMNBI_RBAC_ROLES_TO_OPERATIONS /app/NBI/osm_nbi/roles_to_operations.yml +# prometheus +ENV OSMNBI_PROMETHEUS_HOST prometheus +ENV OSMNBI_PROMETHEUS_PORT 9090 # Copy the current directory contents into the container at /app ADD . /app/NBI diff --git a/osm_nbi/engine.py b/osm_nbi/engine.py index db45ce7..5e42858 100644 --- a/osm_nbi/engine.py +++ b/osm_nbi/engine.py @@ -27,6 +27,7 @@ from admin_topics import UserTopic, ProjectTopic, VimAccountTopic, WimAccountTop from admin_topics import UserTopicAuth, ProjectTopicAuth, RoleTopicAuth from descriptor_topics import VnfdTopic, NsdTopic, PduTopic, NstTopic from instance_topics import NsrTopic, VnfrTopic, NsLcmOpTopic, NsiTopic, NsiLcmOpTopic +from pmjobs_topics import PmJobsTopic from base64 import b64encode from os import urandom, path from threading import Lock @@ -52,6 +53,7 @@ class Engine(object): "nsis": NsiTopic, "nsilcmops": NsiLcmOpTopic # [NEW_TOPIC]: add an entry here + # "pm_jobs": PmJobsTopic will be added manually because it needs other parameters } def __init__(self): @@ -147,6 +149,8 @@ class Engine(object): self.operations) else: self.map_topic[topic] = topic_class(self.db, self.fs, self.msg) + self.map_topic[topic] = topic_class(self.db, self.fs, self.msg) + self.map_topic["pm_jobs"] = PmJobsTopic(config["prometheus"].get("host"), config["prometheus"].get("port")) except (DbException, FsException, MsgException) as e: raise EngineException(str(e), http_code=e.http_code) diff --git a/osm_nbi/nbi.cfg b/osm_nbi/nbi.cfg index 81237cd..9f0eaa4 100644 --- a/osm_nbi/nbi.cfg +++ b/osm_nbi/nbi.cfg @@ -65,6 +65,10 @@ name: "osm" # password: "password" # commonkey: "commonkey" +[prometheus] +host: "prometheus" #hostname or IP +port: 9090 + loglevel: "DEBUG" #logfile: /var/log/osm/nbi-database.log diff --git a/osm_nbi/nbi.py b/osm_nbi/nbi.py index fcc1e04..705979b 100644 --- a/osm_nbi/nbi.py +++ b/osm_nbi/nbi.py @@ -337,6 +337,17 @@ class Server(object): }, } }, + "nspm": { + "v1": { + "pm_jobs": { + "": { + "reports": { + "": {"METHODS": ("GET")} + } + }, + }, + }, + }, } def _format_in(self, kwargs): @@ -699,7 +710,7 @@ class Server(object): if not main_topic or not version or not topic: raise NbiException("URL must contain at least 'main_topic/version/topic'", HTTPStatus.METHOD_NOT_ALLOWED) - if main_topic not in ("admin", "vnfpkgm", "nsd", "nslcm", "pdu", "nst", "nsilcm"): + if main_topic not in ("admin", "vnfpkgm", "nsd", "nslcm", "pdu", "nst", "nsilcm", "nspm"): raise NbiException("URL main_topic '{}' not supported".format(main_topic), HTTPStatus.METHOD_NOT_ALLOWED) if version != 'v1': @@ -723,7 +734,7 @@ class Server(object): engine_topic = topic if topic == "subscriptions": engine_topic = main_topic + "_" + topic - if item: + if item and topic != "pm_jobs": engine_topic = item if main_topic == "nsd": @@ -763,6 +774,9 @@ class Server(object): elif not _id: outdata = self.engine.get_item_list(session, engine_topic, kwargs) else: + if item == "reports": + # TODO check that project_id (_id in this context) has permissions + _id = args[0] outdata = self.engine.get_item(session, engine_topic, _id) elif method == "POST": if topic in ("ns_descriptors_content", "vnf_packages_content", "netslice_templates_content"): diff --git a/osm_nbi/pmjobs_topics.py b/osm_nbi/pmjobs_topics.py new file mode 100644 index 0000000..5123cdc --- /dev/null +++ b/osm_nbi/pmjobs_topics.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- + +# 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. + + +import asyncio +import aiohttp +from base_topic import EngineException + +__author__ = "Vijay R S " + + +class PmJobsTopic(): + def __init__(self, host=None, port=None): + self.url = 'http://{}:{}'.format(host, port) + self.metric_list = ['cpu_utilization', 'average_memory_utilization', 'disk_read_ops', + 'disk_write_ops', 'disk_read_bytes', 'disk_write_bytes', 'packets_dropped', + 'packets_sent', 'packets_received'] + + async def _prom_metric_request(self, ns_id): + try: + async with aiohttp.ClientSession() as session: + data = [] + for metlist in self.metric_list: + request_url = self.url+'/api/v1/query?query=osm_'+metlist+"{ns_id='"+ns_id+"'}" + async with session.get(request_url) as resp: + resp = await resp.json() + resp = resp['data']['result'] + if resp: + data.append(resp) + return data + except aiohttp.client_exceptions.ClientConnectorError as e: + raise EngineException("Connection Failure: {}".format(e)) + + def show(self, session, ns_id): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + prom_metric = loop.run_until_complete(self._prom_metric_request(ns_id)) + metric = {} + metric_temp = [] + for index_list in prom_metric: + for index in index_list: + process_metric = {'performanceValue': {'performanceValue': {}}} + process_metric['objectInstanceId'] = index['metric']['ns_id'] + process_metric['performanceMetric'] = index['metric']['__name__'] + process_metric['performanceValue']['timestamp'] = index['value'][0] + process_metric['performanceValue']['performanceValue']['performanceValue'] = index['value'][1] + process_metric['performanceValue']['performanceValue']['vnfMemberIndex'] \ + = index['metric']['vnf_member_index'] + process_metric['performanceValue']['performanceValue']['vduName'] = index['metric']['vdu_name'] + metric_temp.append(process_metric) + metric['entries'] = metric_temp + return metric -- 2.17.1