Adding CORD specific ceilometer changes to monitoring repository
- ceilometer custom notification plugins for ONOS, vSG, vOLT and Infra layers
- ceilometer publish/subscribe module
- ceilometer dynamic pipeline config module
- ceilometer UDP proxy
- ceilometer Custom Image(ceilometer -v2 -v3 versions,kafka_installer,startup scripts)
Change-Id: Ie2ab8ce89cdadbd1fb4dc54ee15e46f8cc8c4c18
diff --git a/xos/synchronizer/ceilometer/ceilometer-plugins/network/statistics/onos/client.py b/xos/synchronizer/ceilometer/ceilometer-plugins/network/statistics/onos/client.py
new file mode 100644
index 0000000..46b6285
--- /dev/null
+++ b/xos/synchronizer/ceilometer/ceilometer-plugins/network/statistics/onos/client.py
@@ -0,0 +1,250 @@
+#
+# Copyright 2013 NEC Corporation. All rights reserved.
+#
+# 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 abc
+
+from oslo_config import cfg
+import requests
+from requests import auth
+import six
+import json
+
+from ceilometer.i18n import _
+from ceilometer.openstack.common import log
+
+
+CONF = cfg.CONF
+CONF.import_opt('http_timeout', 'ceilometer.service')
+
+
+LOG = log.getLogger(__name__)
+
+
+@six.add_metaclass(abc.ABCMeta)
+class _Base(object):
+ """Base class of ONOS REST APIs Clients."""
+
+ @abc.abstractproperty
+ def base_url(self):
+ """Returns base url for each REST API."""
+
+ def __init__(self, client):
+ self.client = client
+
+ def request(self, path, container_name):
+ return self.client.request(self.base_url + path, container_name)
+
+
+class ONOSRESTAPIFailed(Exception):
+ pass
+
+
+class ONOSRESTAPIClient(_Base):
+ """ONOS Statistics REST API Client
+
+ Base URL:
+ {endpoint}/onos/v1
+ """
+
+ base_url = '/onos/v1'
+
+ def get_devices(self, container_name):
+ """Get device informations
+
+ URL:
+ {Base URL}/devices
+ """
+ output = '{ "devices":[ \
+ { \
+ "id":"of:0000000000000001", \
+ "type":"SWITCH", \
+ "available":true, \
+ "role":"MASTER", \
+ "mfr":"Stanford University, Ericsson Research and CPqD Research", \
+ "hw":"OpenFlow 1.3 Reference Userspace Switch", \
+ "sw":"Apr 6 2015 16:10:53", \
+ "serial":"1", \
+ "chassisId":"1", \
+ "annotations":{"protocol":"OF_13","channelId":"192.168.10.50:39306"} \
+ }]}'
+
+ return self.request('/devices', container_name)
+ #LOG.info("SRIKANTH: Returning dummy ONOS devices output")
+ #outputJson = json.loads(output)
+ #return outputJson
+
+ def get_flow_statistics(self, container_name):
+ """Get flow statistics
+
+ URL:
+ {Base URL}/flows
+ """
+ output = '{"flows":[ \
+ { \
+ "deviceId":"of:0000000000000001", \
+ "id":"3377699721451393", \
+ "tableId":2, \
+ "appId":12, \
+ "groupId":0, \
+ "priority":100, \
+ "timeout":0, \
+ "isPermanent":true, \
+ "state":"PENDING_ADD", \
+ "life":0, \
+ "packets":0, \
+ "bytes":0, \
+ "lastSeen":1439355470576, \
+ "treatment":{"instructions":[],"deferred":[]}, \
+ "selector":{"criteria":[]} \
+ }]}'
+ return self.request('/flows', container_name)
+ #LOG.info("SRIKANTH: Returning dummy ONOS flow statistics output")
+ #outputJson = json.loads(output)
+ #return outputJson
+
+ def get_port_statistics(self, container_name):
+ """Get port statistics
+
+ URL:
+ {Base URL}/portstats
+ """
+ output = '{ "portstats": [ \
+ { \
+ "deviceId":"of:0000000000000001", \
+ "id":"3", \
+ "receivePackets": "182", \
+ "sentPackets": "173", \
+ "receiveBytes": "12740", \
+ "sentBytes": "12110", \
+ "receiveDrops": "740", \
+ "sentDrops": "110", \
+ "receiveErrors": "740", \
+ "sentErrors": "110", \
+ "receiveFrameError": "740", \
+ "receiveOverRunError": "740", \
+ "receiveCrcError": "740", \
+ "collisionCount": "110" \
+ }]}'
+ #TODO Add Portstats REST API to ONOS
+ return self.request('/statistics/ports', container_name)
+ #LOG.info("SRIKANTH: Returning dummy ONOS port statistics output")
+ #outputJson = json.loads(output)
+ #return outputJson
+
+ def get_table_statistics(self, container_name):
+ """Get table statistics
+
+ URL:
+ {Base URL}/table
+ """
+ output = '{ \
+ "tableStatistics": [ \
+ { \
+ "deviceId":"of:0000000000000001", \
+ "id":"4", \
+ "activeCount": "11", \
+ "lookupCount": "816", \
+ "matchedCount": "220", \
+ "maximumEntries": "1000" \
+ } \
+ ] \
+ }'
+ #TODO Add table statistics REST API to ONOS
+ return self.request('/statistics/flows/tables', container_name)
+ #LOG.info("SRIKANTH: Returning dummy ONOS table statistics output")
+ #outputJson = json.loads(output)
+ #return outputJson
+
+class Client(object):
+
+ def __init__(self, endpoint, params):
+ self.rest_client = ONOSRESTAPIClient(self)
+
+ self._endpoint = endpoint
+
+ self._req_params = self._get_req_params(params)
+
+ @staticmethod
+ def _get_req_params(params):
+ req_params = {
+ 'headers': {
+ 'Accept': 'application/json'
+ },
+ 'timeout': CONF.http_timeout,
+ }
+
+ auth_way = params.get('auth')
+ if auth_way in ['basic', 'digest']:
+ user = params.get('user')
+ password = params.get('password')
+
+ if auth_way == 'basic':
+ auth_class = auth.HTTPBasicAuth
+ else:
+ auth_class = auth.HTTPDigestAuth
+
+ req_params['auth'] = auth_class(user, password)
+ return req_params
+
+ def _log_req(self, url):
+
+ curl_command = ['REQ: curl -i -X GET ', '"%s" ' % (url)]
+
+ if 'auth' in self._req_params:
+ auth_class = self._req_params['auth']
+ if isinstance(auth_class, auth.HTTPBasicAuth):
+ curl_command.append('--basic ')
+ else:
+ curl_command.append('--digest ')
+
+ curl_command.append('--user "%s":"%s" ' % (auth_class.username,
+ auth_class.password))
+
+ for name, value in six.iteritems(self._req_params['headers']):
+ curl_command.append('-H "%s: %s" ' % (name, value))
+
+ LOG.debug(''.join(curl_command))
+
+ @staticmethod
+ def _log_res(resp):
+
+ dump = ['RES: \n', 'HTTP %.1f %s %s\n' % (resp.raw.version,
+ resp.status_code,
+ resp.reason)]
+ dump.extend('%s: %s\n' % (k, v)
+ for k, v in six.iteritems(resp.headers))
+ dump.append('\n')
+ if resp.content:
+ dump.extend([resp.content, '\n'])
+
+ LOG.debug(''.join(dump))
+
+ def _http_request(self, url):
+ if CONF.debug:
+ self._log_req(url)
+ resp = requests.get(url, **self._req_params)
+ if CONF.debug:
+ self._log_res(resp)
+ if resp.status_code / 100 != 2:
+ raise ONOSRESTAPIFailed(
+ _('ONOS API returned %(status)s %(reason)s') %
+ {'status': resp.status_code, 'reason': resp.reason})
+
+ return resp.json()
+
+ def request(self, path, container_name):
+
+ url = self._endpoint + path % {'container_name': container_name}
+ return self._http_request(url)