From e1e89cc75034e0ea13ca835f92125bdd45f08830 Mon Sep 17 00:00:00 2001 From: bravof Date: Wed, 1 Apr 2020 11:22:42 -0300 Subject: [PATCH 01/16] chore(gitignore): vscode files to gitignore Change-Id: I7c0eabdacad70c50ab9ee12c69cd774dee345e06 Signed-off-by: bravof --- .gitignore | 6 ++++++ .vscode/settings.json | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 204364f..ae5b1ce 100644 --- a/.gitignore +++ b/.gitignore @@ -79,6 +79,12 @@ ChangeLog __pycache__/ .idea *.db +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace deb_dist *.tar.gz diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c5c5d21..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "cornflakes.linter.executablePath": "/usr/local/bin/flake8" -} \ No newline at end of file -- 2.25.1 From 8a77165ce022c148d39cfa45a5090cb19bcb3833 Mon Sep 17 00:00:00 2001 From: beierlm Date: Fri, 17 Apr 2020 13:08:11 -0400 Subject: [PATCH 02/16] Fix MON Stein Metrics Gnocchi deprecated the use of the cpu_util parameter after Rocky. What is needed instead is to use the ceilometer-low-rate cpu metric and covert that to a percentage using value/time interval. This metric was introduced in Mitaka, and has been shown to work with Rocky as part of the Whitestack WhiteCloud Rocky deployment, as well as Stein with Canonical Charmed OpenStack Stein deployment. Bug 790 Change-Id: I1a895e3569f9206c39ce3c77636d1b45a1a1bd3a Signed-off-by: beierlm --- osm_mon/collector/vnf_collectors/openstack.py | 33 +++++++++--- .../vnf_collectors/test_openstack.py | 52 ++++++++++++++++--- 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/osm_mon/collector/vnf_collectors/openstack.py b/osm_mon/collector/vnf_collectors/openstack.py index 60b387c..1bb0fc8 100644 --- a/osm_mon/collector/vnf_collectors/openstack.py +++ b/osm_mon/collector/vnf_collectors/openstack.py @@ -19,16 +19,17 @@ # For those usages not covered by the Apache License, Version 2.0 please # contact: bdiaz@whitestack.com or glavado@whitestack.com ## -import logging from enum import Enum +import logging +import time from typing import List -import gnocchiclient.exceptions from ceilometerclient import client as ceilometer_client from ceilometerclient.exc import HTTPException +import gnocchiclient.exceptions from gnocchiclient.v1 import client as gnocchi_client -from keystoneclient.v3 import client as keystone_client from keystoneauth1.exceptions.catalog import EndpointNotFound +from keystoneclient.v3 import client as keystone_client from neutronclient.v2_0 import client as neutron_client from osm_mon.collector.metric import Metric @@ -38,6 +39,7 @@ from osm_mon.collector.vnf_metric import VnfMetric from osm_mon.core.common_db import CommonDbClient from osm_mon.core.config import Config + log = logging.getLogger(__name__) METRIC_MAPPINGS = { @@ -50,7 +52,15 @@ METRIC_MAPPINGS = { "packets_out_dropped": "network.incoming.packets.drop", "packets_received": "network.incoming.packets.rate", "packets_sent": "network.outgoing.packets.rate", - "cpu_utilization": "cpu_util", + "cpu_utilization": "cpu", +} + +METRIC_MULTIPLIERS = { + "cpu": 0.0000001 +} + +METRIC_AGGREGATORS = { + "cpu": "rate:mean" } INTERFACE_METRICS = ['packets_in_dropped', 'packets_out_dropped', 'packets_received', 'packets_sent'] @@ -212,11 +222,22 @@ class GnocchiBackend(OpenstackBackend): def _collect_instance_metric(self, openstack_metric_name, resource_id): value = None try: + aggregation = METRIC_AGGREGATORS.get(openstack_metric_name) + measures = self.client.metric.get_measures(openstack_metric_name, - resource_id=resource_id, - limit=1) + aggregation=aggregation, + start=time.time() - 1200, + resource_id=resource_id) + # measures[-1][0] is the time of the reporting interval + # measures[-1][1] is the durcation of the reporting interval + # measures[-1][2] is the value of the metric if measures: value = measures[-1][2] + if aggregation: + # If this is an aggregate, we need to divide the total over the reported time period. + value = value / measures[-1][1] + if openstack_metric_name in METRIC_MULTIPLIERS: + value = value * METRIC_MULTIPLIERS[openstack_metric_name] except gnocchiclient.exceptions.NotFound as e: log.debug("No metric %s found for instance %s: %s", openstack_metric_name, resource_id, e) diff --git a/osm_mon/tests/unit/collector/vnf_collectors/test_openstack.py b/osm_mon/tests/unit/collector/vnf_collectors/test_openstack.py index 5493ae7..1f2d06a 100644 --- a/osm_mon/tests/unit/collector/vnf_collectors/test_openstack.py +++ b/osm_mon/tests/unit/collector/vnf_collectors/test_openstack.py @@ -23,6 +23,8 @@ import datetime from unittest import TestCase, mock +import gnocchiclient + from osm_mon.collector.vnf_collectors.openstack import GnocchiBackend from osm_mon.core.config import Config @@ -37,7 +39,7 @@ class CollectorTest(TestCase): @mock.patch.object(GnocchiBackend, '_build_neutron_client') @mock.patch.object(GnocchiBackend, '_build_gnocchi_client') - def test_collect_gnocchi_instance(self, build_gnocchi_client, build_neutron_client): + def test_collect_gnocchi_rate_instance(self, build_gnocchi_client, _): mock_gnocchi_client = mock.Mock() mock_gnocchi_client.metric.get_measures.return_value = [(datetime.datetime(2019, 4, 12, 15, 43, tzinfo=datetime.timezone( @@ -46,14 +48,52 @@ class CollectorTest(TestCase): (datetime.datetime(2019, 4, 12, 15, 44, tzinfo=datetime.timezone( datetime.timedelta(0), - '+00:00')), 60.0, 0.0333070363)] + '+00:00')), 60.0, 600000000)] build_gnocchi_client.return_value = mock_gnocchi_client backend = GnocchiBackend({'_id': 'test_uuid'}) - value = backend._collect_instance_metric('cpu_utilization', 'test_resource_id') - self.assertEqual(value, 0.0333070363) - mock_gnocchi_client.metric.get_measures.assert_called_once_with('cpu_utilization', - limit=1, + value = backend._collect_instance_metric('cpu', 'test_resource_id') + self.assertEqual(value, 1.0) + mock_gnocchi_client.metric.get_measures.assert_called_once_with('cpu', + aggregation="rate:mean", + start=mock.ANY, + resource_id='test_resource_id') + + @mock.patch.object(GnocchiBackend, '_build_neutron_client') + @mock.patch.object(GnocchiBackend, '_build_gnocchi_client') + def test_collect_gnocchi_non_rate_instance(self, build_gnocchi_client, _): + mock_gnocchi_client = mock.Mock() + mock_gnocchi_client.metric.get_measures.return_value = [(datetime.datetime(2019, 4, 12, 15, 43, + tzinfo=datetime.timezone( + datetime.timedelta(0), + '+00:00')), 60.0, 0.0345442539), + (datetime.datetime(2019, 4, 12, 15, 44, + tzinfo=datetime.timezone( + datetime.timedelta(0), + '+00:00')), 60.0, 128)] + build_gnocchi_client.return_value = mock_gnocchi_client + + backend = GnocchiBackend({'_id': 'test_uuid'}) + value = backend._collect_instance_metric('memory.usage', 'test_resource_id') + self.assertEqual(value, 128) + mock_gnocchi_client.metric.get_measures.assert_called_once_with('memory.usage', + aggregation=None, + start=mock.ANY, + resource_id='test_resource_id') + + @mock.patch.object(GnocchiBackend, '_build_neutron_client') + @mock.patch.object(GnocchiBackend, '_build_gnocchi_client') + def test_collect_gnocchi_no_metric(self, build_gnocchi_client, _): + mock_gnocchi_client = mock.Mock() + mock_gnocchi_client.metric.get_measures.side_effect = gnocchiclient.exceptions.NotFound() + build_gnocchi_client.return_value = mock_gnocchi_client + + backend = GnocchiBackend({'_id': 'test_uuid'}) + value = backend._collect_instance_metric('memory.usage', 'test_resource_id') + self.assertIsNone(value) + mock_gnocchi_client.metric.get_measures.assert_called_once_with('memory.usage', + aggregation=None, + start=mock.ANY, resource_id='test_resource_id') @mock.patch.object(GnocchiBackend, '_build_neutron_client') -- 2.25.1 From 94fae15efc2cae8102e259ec4a3803eaa6736099 Mon Sep 17 00:00:00 2001 From: garciadeblas Date: Thu, 7 May 2020 14:16:22 +0000 Subject: [PATCH 03/16] VIO to use Openstack collector (gnocchi) if no vrops_site is provided Change-Id: I9118e63d9405ce7339dbd077aec7e93aa0e18f20 Signed-off-by: garciadeblas --- osm_mon/collector/service.py | 2 ++ .../tests/unit/collector/test_collector_service.py | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/osm_mon/collector/service.py b/osm_mon/collector/service.py index f329918..c04f548 100644 --- a/osm_mon/collector/service.py +++ b/osm_mon/collector/service.py @@ -139,4 +139,6 @@ class CollectorService: vim_type = vim_account['vim_type'] if 'config' in vim_account and 'vim_type' in vim_account['config']: vim_type = vim_account['config']['vim_type'].lower() + if vim_type == 'vio' and 'vrops_site' not in vim_account['config']: + vim_type = 'openstack' return vim_type diff --git a/osm_mon/tests/unit/collector/test_collector_service.py b/osm_mon/tests/unit/collector/test_collector_service.py index 61a288a..9b5f002 100644 --- a/osm_mon/tests/unit/collector/test_collector_service.py +++ b/osm_mon/tests/unit/collector/test_collector_service.py @@ -52,11 +52,21 @@ class CollectorServiceTest(TestCase): collector._collect_vim_metrics({}, 'test_vim_account_id') openstack_collect.assert_not_called() + @mock.patch.object(OpenstackCollector, "__init__", lambda *args, **kwargs: None) + @mock.patch.object(OpenstackCollector, "collect") + @mock.patch.object(CommonDbClient, "get_vim_account") + def test_init_vim_collector_and_collect_vio_with_openstack_collector(self, _get_vim_account, openstack_collect): + _get_vim_account.return_value = {'vim_type': 'openstack', 'config': {'vim_type': 'VIO'}} + collector = CollectorService(self.config) + collector._collect_vim_metrics({}, 'test_vim_account_id') + openstack_collect.assert_called_once_with({}) + @mock.patch.object(VIOCollector, "__init__", lambda *args, **kwargs: None) @mock.patch.object(VIOCollector, "collect") @mock.patch.object(CommonDbClient, "get_vim_account") - def test_init_vim_collector_and_collect_vio(self, _get_vim_account, vio_collect): - _get_vim_account.return_value = {'vim_type': 'openstack', 'config': {'vim_type': 'VIO'}} + def test_init_vim_collector_and_collect_vio_with_vrops_collector(self, _get_vim_account, vio_collect): + _get_vim_account.return_value = {'vim_type': 'openstack', + 'config': {'vim_type': 'VIO', 'vrops_site': 'https://vrops'}} collector = CollectorService(self.config) collector._collect_vim_metrics({}, 'test_vim_account_id') vio_collect.assert_called_once_with({}) -- 2.25.1 From 4509db85e33d7be00c12548a1d1d93cc94c6ebab Mon Sep 17 00:00:00 2001 From: bravof Date: Fri, 12 Jun 2020 11:10:15 -0400 Subject: [PATCH 04/16] fix(aiokafka): change aiokafka version to 0.6.0 Change-Id: Ie61046eb869c93019f78424fdc3d18faa70cbc57 Signed-off-by: bravof --- requirements.txt | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 29ee06a..d4eb273 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ # For those usages not covered by the Apache License, Version 2.0 please # contact: prithiv.mohan@intel.com or adrian.hoban@intel.com -aiokafka==0.4.* +aiokafka==0.6.0 requests==2.18.* python-keystoneclient==3.15.* six==1.11.* diff --git a/setup.py b/setup.py index 37a2566..3eeb9e5 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,7 @@ setup( packages=[_name], package_dir={_name: _name}, install_requires=[ - "aiokafka==0.4.*", + "aiokafka==0.6.0", "requests==2.18.*", "python-keystoneclient==3.15.*", "six==1.11.*", -- 2.25.1 From 881ff3b6660a1608f26712821ae7e22fdf913a70 Mon Sep 17 00:00:00 2001 From: Atul Agarwal Date: Wed, 17 Jun 2020 07:49:25 +0000 Subject: [PATCH 05/16] Bug 1086 fixed. Updated authentication mechanism Change-Id: I151a3082cf00279235446daf5aa590c183305657 Signed-off-by: Atul Agarwal --- .../vnf_collectors/vrops/vrops_helper.py | 27 +++++++++++-- .../vmware/test_vcd_collector.py | 15 +++++++ .../vmware/test_vio_collector.py | 12 ++++++ .../vmware/test_vrops_helper.py | 39 +++++++++++++++++++ .../vmware/vmware_mocks/vrops_token.json | 7 ++++ 5 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_token.json diff --git a/osm_mon/collector/vnf_collectors/vrops/vrops_helper.py b/osm_mon/collector/vnf_collectors/vrops/vrops_helper.py index 75819fc..39d3238 100644 --- a/osm_mon/collector/vnf_collectors/vrops/vrops_helper.py +++ b/osm_mon/collector/vnf_collectors/vrops/vrops_helper.py @@ -53,15 +53,32 @@ class vROPS_Helper(): self.vrops_user = vrops_user self.vrops_password = vrops_password + def get_vrops_token(self): + """Fetches token from vrops + """ + auth_url = '/suite-api/api/auth/token/acquire' + headers = {'Content-Type': 'application/json', 'Accept': 'application/json'} + req_body = {"username": self.vrops_user, "password": self.vrops_password} + resp = requests.post(self.vrops_site + auth_url, + json=req_body, verify=False, + headers=headers) + if resp.status_code != 200: + log.error("Failed to get token from vROPS: {} {}".format(resp.status_code, + resp.content)) + return None + + resp_data = json.loads(resp.content.decode('utf-8')) + return resp_data['token'] + def get_vm_resource_list_from_vrops(self): """ Find all known resource IDs in vROPs """ + auth_token = self.get_vrops_token() api_url = '/suite-api/api/resources?resourceKind=VirtualMachine' - headers = {'Accept': 'application/json'} + headers = {'Accept': 'application/json', 'Authorization': 'vRealizeOpsToken {}'.format(auth_token)} resource_list = [] resp = requests.get(self.vrops_site + api_url, - auth=(self.vrops_user, self.vrops_password), verify=False, headers=headers) if resp.status_code != 200: @@ -117,10 +134,12 @@ class vROPS_Helper(): # Now we can make a single call to vROPS to collect all relevant metrics for resources we need to monitor api_url = "/suite-api/api/resources/stats?IntervalType=MINUTES&IntervalCount=1"\ "&rollUpType=MAX¤tOnly=true{}{}".format(stats_key, resource_ids) - headers = {'Accept': 'application/json'} + + auth_token = self.get_vrops_token() + headers = {'Accept': 'application/json', 'Authorization': 'vRealizeOpsToken {}'.format(auth_token)} resp = requests.get(self.vrops_site + api_url, - auth=(self.vrops_user, self.vrops_password), verify=False, headers=headers) + verify=False, headers=headers) if resp.status_code != 200: log.error("Failed to get Metrics data from vROPS for {} {}".format(resp.status_code, diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vcd_collector.py b/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vcd_collector.py index 740de74..60c22a3 100644 --- a/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vcd_collector.py +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vcd_collector.py @@ -68,6 +68,9 @@ class CollectorTest(TestCase): self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') @@ -85,6 +88,9 @@ class CollectorTest(TestCase): mock_vm_moref_id.return_value = None self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='404.txt', status_code=404) @@ -95,6 +101,9 @@ class CollectorTest(TestCase): self.vnfd['vdu'][0]['monitoring-param'] = [] self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') @@ -108,6 +117,9 @@ class CollectorTest(TestCase): del self.vnfd['vdu'][0]['monitoring-param'] self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') @@ -122,6 +134,9 @@ class CollectorTest(TestCase): del self.vnfr['vdur'][1]['name'] self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vio_collector.py b/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vio_collector.py index 215bd53..81e6024 100644 --- a/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vio_collector.py +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vio_collector.py @@ -63,6 +63,9 @@ class CollectorTest(TestCase): ] self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') @@ -84,6 +87,9 @@ class CollectorTest(TestCase): self.vnfd['vdu'][0]['monitoring-param'] = [] self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') @@ -97,6 +103,9 @@ class CollectorTest(TestCase): del self.vnfd['vdu'][0]['monitoring-param'] self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') @@ -111,6 +120,9 @@ class CollectorTest(TestCase): del self.vnfr['vdur'][1]['name'] self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vrops_helper.py b/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vrops_helper.py index 956a19f..846f98b 100644 --- a/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vrops_helper.py +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vrops_helper.py @@ -40,6 +40,9 @@ class vROPS_Helper_Resource_List_Test(TestCase): def test_get_vm_resource_list_from_vrops(self): with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='vrops_resources.json') @@ -48,6 +51,9 @@ class vROPS_Helper_Resource_List_Test(TestCase): def test_get_vm_resource_list_from_vrops_http_404(self): with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='404.txt', status_code=404) @@ -56,6 +62,9 @@ class vROPS_Helper_Resource_List_Test(TestCase): def test_get_vm_resource_list_from_vrops_bad_json(self): with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', response_file='malformed.json') @@ -83,6 +92,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='vrops_multi.json') @@ -102,6 +114,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='vrops_multi.json') @@ -123,6 +138,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='vrops_multi.json') @@ -142,6 +160,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='vrops_multi.json') @@ -159,6 +180,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='vrops_multi.json') @@ -176,6 +200,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='OK.json') @@ -192,6 +219,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='vrops_multi.json') @@ -209,6 +239,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='404.txt', status_code=404) @@ -226,6 +259,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='404.txt') @@ -255,6 +291,9 @@ class vROPS_Helper_Get_Metrics_Test(TestCase): ] with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, method='POST', + url_pattern='/suite-api/api/auth/token/acquire', + response_file='vrops_token.json') mock_http_response(mock_requests, url_pattern='/suite-api/api/resources/stats.*', response_file='vrops_multi.json') diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_token.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_token.json new file mode 100644 index 0000000..59ea495 --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_token.json @@ -0,0 +1,7 @@ +{ + "_copyright_comment": "Copyright 2016-2019 VMware Inc. This file is part of ETSI OSM 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. For those usages not covered by the Apache License, Version 2.0 please contact: osslegalrouting@vmware.com", + "token": "8f868cca-27cc-43d6-a838-c5467e73ec45::77cea9b2-1e87-490e-b626-e878beeaa23b", + "validity": 1470421325035, + "expiresAt": "Friday, August 5, 2016 6:22:05 PM UTC", + "roles": [] +} -- 2.25.1 From c9ee37d46cde6000c5e964532ee5aa535fdf22b0 Mon Sep 17 00:00:00 2001 From: bravof Date: Fri, 19 Jun 2020 09:47:08 -0400 Subject: [PATCH 06/16] fix(postinst): wrong version in postinst file for aiokafka Change-Id: I5144150f6e41ff39820a9154407438364a219670 Signed-off-by: bravof --- debian/python3-osm-mon.postinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/python3-osm-mon.postinst b/debian/python3-osm-mon.postinst index ff08172..f7bc53b 100644 --- a/debian/python3-osm-mon.postinst +++ b/debian/python3-osm-mon.postinst @@ -23,7 +23,7 @@ ## echo "Installing python dependencies via pip..." -pip3 install aiokafka==0.4.* +pip3 install aiokafka==0.6.0 pip3 install requests==2.18.* pip3 install python-keystoneclient==3.15.* pip3 install six==1.11.* -- 2.25.1 From d9e56359b64a3934ea5eb7c18bc517c4fc9fa160 Mon Sep 17 00:00:00 2001 From: bravof Date: Thu, 25 Jun 2020 17:30:55 -0400 Subject: [PATCH 07/16] Bug 1106 : Kill processes still running after join call timeout reached, also timeouts added to nova and keystone clients. Join timeout increased from 10 to 20 Change-Id: I9fce3b4c4322d717a93207d9c34136ba75108a3e Signed-off-by: bravof --- osm_mon/collector/infra_collectors/base_osinfra.py | 4 ++-- osm_mon/collector/service.py | 5 ++++- osm_mon/collector/utils/openstack.py | 2 +- osm_mon/tests/unit/collector/utils/test_openstack.py | 6 +++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/osm_mon/collector/infra_collectors/base_osinfra.py b/osm_mon/collector/infra_collectors/base_osinfra.py index bce363c..050e525 100644 --- a/osm_mon/collector/infra_collectors/base_osinfra.py +++ b/osm_mon/collector/infra_collectors/base_osinfra.py @@ -100,8 +100,8 @@ class BaseOpenStackInfraCollector(BaseVimInfraCollector): def _build_keystone_client(self, vim_account: dict) -> keystone_client.Client: sess = OpenstackUtils.get_session(vim_account) - return keystone_client.Client(session=sess) + return keystone_client.Client(session=sess, timeout=10) def _build_nova_client(self, vim_account: dict) -> nova_client.Client: sess = OpenstackUtils.get_session(vim_account) - return nova_client.Client("2", session=sess) + return nova_client.Client("2", session=sess, timeout=10) diff --git a/osm_mon/collector/service.py b/osm_mon/collector/service.py index c04f548..7673aed 100644 --- a/osm_mon/collector/service.py +++ b/osm_mon/collector/service.py @@ -127,7 +127,10 @@ class CollectorService: processes.append(p) p.start() for process in processes: - process.join(timeout=10) + process.join(timeout=20) + for process in processes: + if process.is_alive(): + process.kill() metrics = [] while not self.queue.empty(): metrics.append(self.queue.get()) diff --git a/osm_mon/collector/utils/openstack.py b/osm_mon/collector/utils/openstack.py index 2ec85be..09c472c 100644 --- a/osm_mon/collector/utils/openstack.py +++ b/osm_mon/collector/utils/openstack.py @@ -49,4 +49,4 @@ class OpenstackUtils: project_name=creds['vim_tenant_name'], project_domain_name=project_domain_name, user_domain_name=user_domain_name) - return session.Session(auth=auth, verify=verify_ssl) + return session.Session(auth=auth, verify=verify_ssl, timeout=10) diff --git a/osm_mon/tests/unit/collector/utils/test_openstack.py b/osm_mon/tests/unit/collector/utils/test_openstack.py index 76adc55..7cfa4bf 100644 --- a/osm_mon/tests/unit/collector/utils/test_openstack.py +++ b/osm_mon/tests/unit/collector/utils/test_openstack.py @@ -43,7 +43,7 @@ class OpenstackUtilsTest(TestCase): OpenstackUtils.get_session(creds) mock_session.Session.assert_called_once_with( - auth=mock.ANY, verify=True) + auth=mock.ANY, verify=True, timeout=10) def test_session_with_insecure(self, mock_session): creds = { @@ -58,7 +58,7 @@ class OpenstackUtilsTest(TestCase): OpenstackUtils.get_session(creds) mock_session.Session.assert_called_once_with( - auth=mock.ANY, verify=False) + auth=mock.ANY, verify=False, timeout=10) def test_session_with_insecure_false(self, mock_session): creds = { @@ -72,4 +72,4 @@ class OpenstackUtilsTest(TestCase): } OpenstackUtils.get_session(creds) mock_session.Session.assert_called_once_with( - auth=mock.ANY, verify=True) + auth=mock.ANY, verify=True, timeout=10) -- 2.25.1 From 06ad698093d4e39b199ba466617bf8cef6df5c42 Mon Sep 17 00:00:00 2001 From: bravof Date: Wed, 19 Aug 2020 19:14:01 -0400 Subject: [PATCH 08/16] fix(processes): .terminate instead of .kill to finish misbehaving processes Change-Id: I68eba9c9da669242292ff93c656e1a54da9cf541 Signed-off-by: bravof --- osm_mon/collector/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osm_mon/collector/service.py b/osm_mon/collector/service.py index 7673aed..5452c66 100644 --- a/osm_mon/collector/service.py +++ b/osm_mon/collector/service.py @@ -130,7 +130,7 @@ class CollectorService: process.join(timeout=20) for process in processes: if process.is_alive(): - process.kill() + process.terminate() metrics = [] while not self.queue.empty(): metrics.append(self.queue.get()) -- 2.25.1 From cadfe2d274f1b7e178060ad993025ccd4dace94a Mon Sep 17 00:00:00 2001 From: Atul Date: Mon, 21 Sep 2020 14:44:02 +0000 Subject: [PATCH 09/16] Updated requirement.txt to point MON to N2VC tag v8.0.1 as n2vc.vnf module is missing in master branch of N2VC. Change-Id: I8b5a9355320171b0fc04f293717d5f981622455e Signed-off-by: Atul --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d4eb273..3f1c5bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,4 +33,4 @@ peewee-migrate==1.1.* python-novaclient==12.0.* python-neutronclient==5.1.* git+https://osm.etsi.org/gerrit/osm/common.git#egg=osm-common -git+https://osm.etsi.org/gerrit/osm/N2VC.git#egg=n2vc +git+https://osm.etsi.org/gerrit/osm/N2VC.git@v8.0.1#egg=n2vc -- 2.25.1 From 6a39cb03b404dfcd24cd26e45d741266db1df9bf Mon Sep 17 00:00:00 2001 From: David Garcia Date: Tue, 22 Sep 2020 11:29:01 +0200 Subject: [PATCH 10/16] Move from old N2VC to N2VCJujuConnector Change-Id: Ib8b545823eb803c7e31c1d5c8fd8afc6a39e07a8 Signed-off-by: David Garcia --- devops-stages/stage-test.sh | 2 +- osm_mon/collector/vnf_collectors/juju.py | 139 ++++++++++++++++------- requirements.txt | 2 +- tox.ini | 2 +- 4 files changed, 98 insertions(+), 47 deletions(-) diff --git a/devops-stages/stage-test.sh b/devops-stages/stage-test.sh index d588666..4ad4f08 100755 --- a/devops-stages/stage-test.sh +++ b/devops-stages/stage-test.sh @@ -23,4 +23,4 @@ #__date__ = "14/Sep/2017" #!/bin/bash -tox +tox --recreate diff --git a/osm_mon/collector/vnf_collectors/juju.py b/osm_mon/collector/vnf_collectors/juju.py index 1ca8bf5..ba17d65 100644 --- a/osm_mon/collector/vnf_collectors/juju.py +++ b/osm_mon/collector/vnf_collectors/juju.py @@ -23,7 +23,7 @@ import asyncio import logging from typing import List -from n2vc.vnf import N2VC +from n2vc.n2vc_juju_conn import N2VCJujuConnector from osm_mon.collector.metric import Metric from osm_mon.collector.vnf_collectors.base import BaseCollector @@ -40,86 +40,137 @@ class VCACollector(BaseCollector): super().__init__(config) self.common_db = CommonDbClient(config) self.loop = asyncio.get_event_loop() - self.n2vc = N2VC(server=config.get('vca', 'host'), - user=config.get('vca', 'user'), - secret=config.get('vca', 'secret'), - ca_cert=config.get('vca', 'cacert')) + host = config.get("vca", "host") + port = config.get("vca", "port") if "port" in config.conf["vca"] else 17070 + + # Backwards compatibility + if "cacert" in config.conf["vca"]: + ca_cert = config.conf["vca"].pop("cacert") + config.set("vca", "ca_cert", ca_cert) + + if "pubkey" in config.conf["vca"]: + public_key = config.conf["vca"].pop("pubkey") + config.set("vca", "public_key", public_key) + + if "apiproxy" in config.conf["vca"]: + api_proxy = config.conf["vca"].pop("apiproxy") + config.set("vca", "api_proxy", api_proxy) + + self.n2vc = N2VCJujuConnector( + db=self.common_db.common_db, + fs=object(), + log=log, + loop=self.loop, + url="{}:{}".format(host, port), + username=config.get("vca", "user"), + vca_config=config.conf["vca"], + on_update_db=None, + ) def collect(self, vnfr: dict) -> List[Metric]: - nsr_id = vnfr['nsr-id-ref'] - vnf_member_index = vnfr['member-vnf-index-ref'] - vnfd = self.common_db.get_vnfd(vnfr['vnfd-id']) + nsr_id = vnfr["nsr-id-ref"] + vnf_member_index = vnfr["member-vnf-index-ref"] + vnfd = self.common_db.get_vnfd(vnfr["vnfd-id"]) # Populate extra tags for metrics tags = {} - tags['ns_name'] = self.common_db.get_nsr(nsr_id)['name'] - if vnfr['_admin']['projects_read']: - tags['project_id'] = vnfr['_admin']['projects_read'][0] + tags["ns_name"] = self.common_db.get_nsr(nsr_id)["name"] + if vnfr["_admin"]["projects_read"]: + tags["project_id"] = vnfr["_admin"]["projects_read"][0] else: - tags['project_id'] = '' + tags["project_id"] = "" metrics = [] - for vdur in vnfr['vdur']: + for vdur in vnfr["vdur"]: # This avoids errors when vdur records have not been completely filled - if 'name' not in vdur: + if "name" not in vdur: continue - vdu = next( - filter(lambda vdu: vdu['id'] == vdur['vdu-id-ref'], vnfd['vdu']) - ) - if 'vdu-configuration' in vdu and 'metrics' in vdu['vdu-configuration']: + vdu = next(filter(lambda vdu: vdu["id"] == vdur["vdu-id-ref"], vnfd["vdu"])) + if "vdu-configuration" in vdu and "metrics" in vdu["vdu-configuration"]: try: - vca_deployment_info = self.get_vca_deployment_info(nsr_id, vnf_member_index, vdur['vdu-id-ref'], - vdur['count-index']) + vca_deployment_info = self.get_vca_deployment_info( + nsr_id, + vnf_member_index, + vdur["vdu-id-ref"], + vdur["count-index"], + ) except VcaDeploymentInfoNotFound as e: log.warning(repr(e)) continue - measures = self.loop.run_until_complete(self.n2vc.GetMetrics(vca_deployment_info['model'], - vca_deployment_info['application'])) - log.debug('Measures: %s', measures) + measures = self.loop.run_until_complete( + self.n2vc.get_metrics( + vca_deployment_info["model"], vca_deployment_info["application"] + ) + ) + log.debug("Measures: %s", measures) for measure_list in measures.values(): for measure in measure_list: log.debug("Measure: %s", measure) - metric = VnfMetric(nsr_id, vnf_member_index, vdur['name'], measure['key'], - float(measure['value']), tags) + metric = VnfMetric( + nsr_id, + vnf_member_index, + vdur["name"], + measure["key"], + float(measure["value"]), + tags, + ) metrics.append(metric) - if 'vnf-configuration' in vnfd and 'metrics' in vnfd['vnf-configuration']: + if "vnf-configuration" in vnfd and "metrics" in vnfd["vnf-configuration"]: try: - vca_deployment_info = self.get_vca_deployment_info(nsr_id, vnf_member_index) + vca_deployment_info = self.get_vca_deployment_info( + nsr_id, vnf_member_index + ) except VcaDeploymentInfoNotFound as e: log.warning(repr(e)) return metrics - measures = self.loop.run_until_complete(self.n2vc.GetMetrics(vca_deployment_info['model'], - vca_deployment_info['application'])) + measures = self.loop.run_until_complete( + self.n2vc.get_metrics( + vca_deployment_info["model"], vca_deployment_info["application"] + ) + ) # Search for Mgmt VDU name, needed to query Prometheus based on alarm tags # TODO: check a better way to look for Mgmt VDU - for vdur in vnfr['vdur']: - for interface in vdur['interfaces']: - if 'mgmt-vnf' in interface: - vdu_name = vdur['name'] + for vdur in vnfr["vdur"]: + for interface in vdur["interfaces"]: + if "mgmt-vnf" in interface: + vdu_name = vdur["name"] break - log.debug('Measures: %s', measures) + log.debug("Measures: %s", measures) for measure_list in measures.values(): for measure in measure_list: log.debug("Measure: %s", measure) - metric = VnfMetric(nsr_id, vnf_member_index, vdu_name, - measure['key'], float(measure['value']), tags) + metric = VnfMetric( + nsr_id, + vnf_member_index, + vdu_name, + measure["key"], + float(measure["value"]), + tags, + ) metrics.append(metric) return metrics - def get_vca_deployment_info(self, nsr_id, vnf_member_index, vdu_id=None, vdu_count=0): + def get_vca_deployment_info( + self, nsr_id, vnf_member_index, vdu_id=None, vdu_count=0 + ): nsr = self.common_db.get_nsr(nsr_id) for vca_deployment in nsr["_admin"]["deployed"]["VCA"]: if vca_deployment: if vdu_id is None: - if vca_deployment['member-vnf-index'] == vnf_member_index and vca_deployment['vdu_id'] is None: + if ( + vca_deployment["member-vnf-index"] == vnf_member_index + and vca_deployment["vdu_id"] is None + ): return vca_deployment else: - if vca_deployment['member-vnf-index'] == vnf_member_index and \ - vca_deployment['vdu_id'] == vdu_id and vca_deployment['vdu_count_index'] == vdu_count: + if ( + vca_deployment["member-vnf-index"] == vnf_member_index + and vca_deployment["vdu_id"] == vdu_id + and vca_deployment["vdu_count_index"] == vdu_count + ): return vca_deployment raise VcaDeploymentInfoNotFound( "VCA deployment info for nsr_id {}, index {}, vdu_id {} and vdu_count_index {} not found.".format( - nsr_id, - vnf_member_index, - vdu_id, - vdu_count)) + nsr_id, vnf_member_index, vdu_id, vdu_count + ) + ) diff --git a/requirements.txt b/requirements.txt index 3f1c5bd..d4eb273 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,4 +33,4 @@ peewee-migrate==1.1.* python-novaclient==12.0.* python-neutronclient==5.1.* git+https://osm.etsi.org/gerrit/osm/common.git#egg=osm-common -git+https://osm.etsi.org/gerrit/osm/N2VC.git@v8.0.1#egg=n2vc +git+https://osm.etsi.org/gerrit/osm/N2VC.git#egg=n2vc diff --git a/tox.ini b/tox.ini index f0619f7..efea4e6 100644 --- a/tox.ini +++ b/tox.ini @@ -76,6 +76,6 @@ commands = python3 setup.py --command-packages=stdeb.command bdist_deb # E123, E125 skipped as they are invalid PEP-8. max-line-length = 120 show-source = True -ignore = E123,E125,E241 +ignore = E123,E125,E241,W503 builtins = _ exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,devops_stages/*,.rst -- 2.25.1 From dda20d4e308af1afceb58839e93ccc4210c9f3fc Mon Sep 17 00:00:00 2001 From: David Garcia Date: Tue, 22 Sep 2020 11:36:48 +0200 Subject: [PATCH 11/16] Improve Config.get() function The .get is a bit confusing because apparently has the same behaviour as dict.get(), which returns None when the key doesn't exist. But that's not the case, because Config.get in this case is doing dict["key"], which returns a KeyError when the key does not exist Change-Id: Ief82eb1ae2e2fea60b8be60cae8610bf8605fb6f Signed-off-by: David Garcia --- osm_mon/core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osm_mon/core/config.py b/osm_mon/core/config.py index c4c3972..cd99ffc 100644 --- a/osm_mon/core/config.py +++ b/osm_mon/core/config.py @@ -48,7 +48,7 @@ class Config: def get(self, section, field=None): if not field: return self.conf[section] - return self.conf[section][field] + return self.conf[section].get(field) def set(self, section, field, value): if section not in self.conf: -- 2.25.1 From 4b6428e387a5374003f369dca19185248e71558d Mon Sep 17 00:00:00 2001 From: agarwalat Date: Fri, 10 Jul 2020 08:33:23 +0000 Subject: [PATCH 12/16] Bug 1133 fixed git add . Change-Id: I08dc2c76b85b61212662680ad0d54af76a9c48a4 Signed-off-by: agarwalat --- osm_mon/core/common_db.py | 5 +++++ osm_mon/dashboarder/service.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/osm_mon/core/common_db.py b/osm_mon/core/common_db.py index f15ae97..983d84d 100644 --- a/osm_mon/core/common_db.py +++ b/osm_mon/core/common_db.py @@ -62,6 +62,11 @@ class CommonDbClient: {"_id": vnfd_id}) return vnfd + def get_vnfd_by_id(self, vnfd_id: str): + vnfd = self.common_db.get_one("vnfds", + {"id": vnfd_id}) + return vnfd + def get_vnfd_by_name(self, vnfd_name: str): # TODO: optimize way of getting single VNFD in shared enviroments (RBAC) if self.common_db.get_list("vnfds", {"name": vnfd_name}): diff --git a/osm_mon/dashboarder/service.py b/osm_mon/dashboarder/service.py index 9f184d2..14ea0b9 100644 --- a/osm_mon/dashboarder/service.py +++ b/osm_mon/dashboarder/service.py @@ -69,7 +69,7 @@ class DashboarderService: constituent_vnfds = nsr['nsd']['constituent-vnfd'] for constituent_vnfd in constituent_vnfds: try: - vnfd = self.common_db.get_vnfd_by_name(constituent_vnfd['vnfd-id-ref']) + vnfd = self.common_db.get_vnfd_by_id(constituent_vnfd['vnfd-id-ref']) # If there are metrics, create dashboard (if exists) if 'monitoring-param' in vnfd: if nsr_id not in dashboard_uids: -- 2.25.1 From d5ce3b936ad31e9441d2cd978236a6278de28ef9 Mon Sep 17 00:00:00 2001 From: Vijay Nag B S Date: Tue, 29 Sep 2020 17:34:43 +0530 Subject: [PATCH 13/16] Support for replicaset connection (HA). Added replicaset field in MON config file. Change-Id: I7f54865a003774b4f344eb0b948796ab221d49d4 Signed-off-by: Vijay Nag B S --- osm_mon/core/mon.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/osm_mon/core/mon.yaml b/osm_mon/core/mon.yaml index e25760b..afaa8d2 100644 --- a/osm_mon/core/mon.yaml +++ b/osm_mon/core/mon.yaml @@ -29,6 +29,7 @@ database: uri: mongodb://mongo:27017 name: osm commonkey: changeme + replicaset: None message: driver: kafka -- 2.25.1 From 426a544c33bd005488d3f68bd525afa5894179c5 Mon Sep 17 00:00:00 2001 From: agarwalat Date: Fri, 16 Oct 2020 06:14:34 +0000 Subject: [PATCH 14/16] Added more logs for Bug 1258-CPU metrics not shown in Prometheus Change-Id: I96836587ac841a8d08506a1da37075e3200cd172 Signed-off-by: agarwalat --- osm_mon/collector/vnf_collectors/openstack.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osm_mon/collector/vnf_collectors/openstack.py b/osm_mon/collector/vnf_collectors/openstack.py index 1bb0fc8..bd2a617 100644 --- a/osm_mon/collector/vnf_collectors/openstack.py +++ b/osm_mon/collector/vnf_collectors/openstack.py @@ -123,25 +123,33 @@ class OpenstackCollector(BaseVimCollector): vdur['name'], vnf_member_index, nsr_id) continue try: + log.info("Collecting metric type: %s and metric_name: %s and resource_id %s and " + "interface_name: %s", metric_type, metric_name, resource_id, interface_name) value = self.backend.collect_metric(metric_type, openstack_metric_name, resource_id, interface_name) if value is not None: + log.info("value: %s", value) if interface_name: tags['interface'] = interface_name metric = VnfMetric(nsr_id, vnf_member_index, vdur['name'], metric_name, value, tags) metrics.append(metric) - except Exception: + else: + log.info("metric value is empty") + except Exception as e: log.exception("Error collecting metric %s for vdu %s" % (metric_name, vdur['name'])) + log.info("Error in metric collection: %s" % e) return metrics def _get_backend(self, vim_account: dict): try: ceilometer = CeilometerBackend(vim_account) ceilometer.client.capabilities.get() + log.info("Using ceilometer backend to collect metric") return ceilometer except (HTTPException, EndpointNotFound): gnocchi = GnocchiBackend(vim_account) gnocchi.client.metric.list(limit=1) + log.info("Using gnocchi backend to collect metric") return gnocchi def _get_metric_type(self, metric_name: str, interface_name: str) -> MetricType: -- 2.25.1 From ef8ee1eca6ac4b9aa4f04e96cf11fdfa56dcdfcf Mon Sep 17 00:00:00 2001 From: garciadeblas Date: Fri, 9 Oct 2020 15:30:03 +0000 Subject: [PATCH 15/16] Fix bug 1258: metrics not properly collected in some Openstacks Change-Id: I5d77e7882a784252217118deb447215a2eac8ae4 Signed-off-by: garciadeblas --- osm_mon/collector/vnf_collectors/openstack.py | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/osm_mon/collector/vnf_collectors/openstack.py b/osm_mon/collector/vnf_collectors/openstack.py index bd2a617..df0424b 100644 --- a/osm_mon/collector/vnf_collectors/openstack.py +++ b/osm_mon/collector/vnf_collectors/openstack.py @@ -232,17 +232,36 @@ class GnocchiBackend(OpenstackBackend): try: aggregation = METRIC_AGGREGATORS.get(openstack_metric_name) - measures = self.client.metric.get_measures(openstack_metric_name, - aggregation=aggregation, - start=time.time() - 1200, - resource_id=resource_id) - # measures[-1][0] is the time of the reporting interval - # measures[-1][1] is the durcation of the reporting interval - # measures[-1][2] is the value of the metric - if measures: - value = measures[-1][2] + try: + measures = self.client.metric.get_measures(openstack_metric_name, + aggregation=aggregation, + start=time.time() - 1200, + resource_id=resource_id) + if measures: + value = measures[-1][2] + except gnocchiclient.exceptions.NotFound as e: + # CPU metric in previous Openstack versions do not support rate:mean aggregation method + if openstack_metric_name == "cpu": + log.debug("No metric %s found for instance %s: %s", openstack_metric_name, resource_id, e) + log.debug("Retrying to get metric %s for instance %s without aggregation", + openstack_metric_name, resource_id) + measures = self.client.metric.get_measures(openstack_metric_name, + resource_id=resource_id, + limit=1) + else: + raise e + # measures[-1] is the last measure + # measures[-2] is the previous measure + # measures[x][2] is the value of the metric + if measures and len(measures) >= 2: + value = measures[-1][2] - measures[-2][2] + if value: + # measures[-1][0] is the time of the reporting interval + # measures[-1][1] is the duration of the reporting interval if aggregation: # If this is an aggregate, we need to divide the total over the reported time period. + # Even if the aggregation method is not supported by Openstack, the code will execute it + # because aggregation is specified in METRIC_AGGREGATORS value = value / measures[-1][1] if openstack_metric_name in METRIC_MULTIPLIERS: value = value * METRIC_MULTIPLIERS[openstack_metric_name] -- 2.25.1 From d0aa7e219cb06ddcab0716f63834e6e18f4b2228 Mon Sep 17 00:00:00 2001 From: vijaynag Date: Thu, 22 Oct 2020 14:22:03 +0200 Subject: [PATCH 16/16] Revert "Support for replicaset connection (HA). Added replicaset field in MON config file." This reverts commit d5ce3b936ad31e9441d2cd978236a6278de28ef9. Change-Id: Ic567b6f846021218ae05fde4ebff1e93eda72c0d Signed-off-by: Vijay Nag B S --- osm_mon/core/mon.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/osm_mon/core/mon.yaml b/osm_mon/core/mon.yaml index afaa8d2..e25760b 100644 --- a/osm_mon/core/mon.yaml +++ b/osm_mon/core/mon.yaml @@ -29,7 +29,6 @@ database: uri: mongodb://mongo:27017 name: osm commonkey: changeme - replicaset: None message: driver: kafka -- 2.25.1