From: beierl Date: Thu, 25 Jul 2019 17:05:58 +0000 (-0400) Subject: Fixes VIO collection X-Git-Tag: v7.0.0rc1~29 X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FMON.git;a=commitdiff_plain;h=7233ad262f6c5436c713784a443596c0aa919b04 Fixes VIO collection Extract common vROPS code from vmware and vio collectors. Add unit test coverage. Remove unused code. Improved vROPS collection to ask for current values only instead of a date range. Reduces number of calls to vROPS by asking for all metrics for all VDUs at once. BUG 796 Change-Id: I00ecd70c6d25f7c8982cbc633a28ab6f1ceb8cd6 Signed-off-by: beierl --- diff --git a/osm_mon/collector/vnf_collectors/vio.py b/osm_mon/collector/vnf_collectors/vio.py index 0d481ea..84cebe0 100644 --- a/osm_mon/collector/vnf_collectors/vio.py +++ b/osm_mon/collector/vnf_collectors/vio.py @@ -23,190 +23,61 @@ import json import logging -import re -import time -import traceback - -import requests -import six -from keystoneauth1 import session -from keystoneauth1.identity import v3 -from novaclient import client as nClient from osm_mon.collector.utils.collector import CollectorUtils from osm_mon.collector.vnf_collectors.base_vim import BaseVimCollector -from osm_mon.collector.vnf_metric import VnfMetric from osm_mon.core.common_db import CommonDbClient from osm_mon.core.config import Config -from osm_mon.core.database import VimCredentialsRepository, VimCredentials +from osm_mon.collector.vnf_collectors.vrops.vrops_helper import vROPS_Helper log = logging.getLogger(__name__) -PERIOD_MSEC = {'HR': 3600000, - 'DAY': 86400000, - 'WEEK': 604800000, - 'MONTH': 2678400000, - 'YEAR': 31536000000} - -METRIC_MAPPINGS = { - "average_memory_utilization": "mem|usage_average", - "cpu_utilization": "cpu|usage_average", - "read_latency_0": "virtualDisk:scsi0:0|totalReadLatency_average", - "write_latency_0": "virtualDisk:scsi0:0|totalWriteLatency_average", - "read_latency_1": "virtualDisk:scsi0:1|totalReadLatency_average", - "write_latency_1": "virtualDisk:scsi0:1|totalWriteLatency_average", - "packets_dropped_0": "net:4000|dropped", - "packets_dropped_1": "net:4001|dropped", - "packets_dropped_2": "net:4002|dropped", - "packets_received": "net:Aggregate of all instances|packetsRxPerSec", - "packets_sent": "net:Aggregate of all instances|packetsTxPerSec", -} - class VIOCollector(BaseVimCollector): def __init__(self, config: Config, vim_account_id: str): super().__init__(config, vim_account_id) self.common_db = CommonDbClient(config) - vim_account_info = CollectorUtils.get_credentials(vim_account_id) - cfg = json.loads(vim_account_info.config) - self.vrops_site = cfg['vrops_site'] - self.vrops_user = cfg['vrops_user'] - self.vrops_password = cfg['vrops_password'] - self.client = self.connect_client(vim_account_id) - - def connect_client(self, vim_account_id: str): - vim_account_details = VimCredentialsRepository.get(VimCredentials.uuid == vim_account_id) - verify_ssl = CollectorUtils.is_verify_ssl(vim_account_details) - auth = v3.Password(auth_url=vim_account_details.url, - username=vim_account_details.user, - password=vim_account_details.password, - project_name=vim_account_details.tenant_name, - project_domain_id='default', - user_domain_id='default') - sess = session.Session(auth=auth, verify=verify_ssl) - client = nClient.Client('2.1', session=sess, endpoint_type=None) - return client - - def _get_resource_uuid(self, nsr_id, vnf_member_index, vdur_name) -> str: - vdur = self.common_db.get_vdur(nsr_id, vnf_member_index, vdur_name) - return vdur['vim-id'] - - def get_vm_name_and_id(self, resource_uuid): - """ Method to find vm name and id using resource_uuid - """ - server = self.client.servers.find(id=resource_uuid) - name = server.to_dict()['name'] - _id = server.to_dict()['id'] - return name, _id + cfg = self.get_vim_account(vim_account_id) + self.vrops = vROPS_Helper(vrops_site=cfg['vrops_site'], + vrops_user=cfg['vrops_user'], + vrops_password=cfg['vrops_password']) - def get_vm_resource_id(self, name, _id): - """ Find resource ID in vROPs - """ - api_url = '/suite-api/api/resources?resourceKind=VirtualMachine' - headers = {'Accept': 'application/json'} - - resp = requests.get(self.vrops_site + api_url, - auth=(self.vrops_user, self.vrops_password), - verify=False, headers=headers) - - if resp.status_code != 200: - log.error("Failed to get resource details for{} {} {}".format(name, - resp.status_code, - resp.content)) - return None - - vm_resource_id = None - try: - resp_data = json.loads(resp.content.decode('utf-8')) - if resp_data.get('resourceList') is not None: - resource_list = resp_data.get('resourceList') - for resource in resource_list: - if resource.get('resourceKey') is not None: - m = re.match(r"(.*?)\s\((.*?)\)", resource['resourceKey']['name']) - if m: - v_name = m.group(1) - v_id = m.group(2) - if name == v_name and _id == v_id: - vm_resource_id = resource['identifier'] - log.info("Found VM resource ID: {} for vm: {}".format(vm_resource_id, - v_name)) - - except Exception as exp: - log.info("get_vm_resource_id: Error in parsing {}\n{}".format(exp, traceback.format_exc())) - - return vm_resource_id + def get_vim_account(self, vim_account_id: str): + vim_account_info = CollectorUtils.get_credentials(vim_account_id) + return json.loads(vim_account_info.config) def collect(self, vnfr: dict): - nsr_id = vnfr['nsr-id-ref'] - vnf_member_index = vnfr['member-vnf-index-ref'] vnfd = self.common_db.get_vnfd(vnfr['vnfd-id']) - metrics = [] + vdu_mappings = {} + + # Fetch the list of all known resources from vROPS. + resource_list = self.vrops.get_vm_resource_list_from_vrops() + for vdur in vnfr['vdur']: # This avoids errors when vdur records have not been completely filled if 'name' not in vdur: continue + vdu = next( filter(lambda vdu: vdu['id'] == vdur['vdu-id-ref'], vnfd['vdu']) - ) - if 'monitoring-param' in vdu: - for param in vdu['monitoring-param']: - metric_name = param['nfvi-metric'] - vrops_metric_name = METRIC_MAPPINGS[metric_name] - resource_uuid = self._get_resource_uuid(nsr_id, vnf_member_index, vdur['name']) - - name, _id = self.get_vm_name_and_id(resource_uuid) - if name and _id is not None: - resource_id = self.get_vm_resource_id(name, _id) - else: - return - try: - end_time = int(round(time.time() * 1000)) - time_diff = PERIOD_MSEC['YEAR'] - begin_time = end_time - time_diff - - api_url = "/suite-api/api/resources/{}/stats?statKey={}&begin={}&end={}".format( - resource_id, vrops_metric_name, str(begin_time), str(end_time)) - - headers = {'Accept': 'application/json'} - - resp = requests.get(self.vrops_site + api_url, - auth=(self.vrops_user, self.vrops_password), verify=False, headers=headers - ) - - if resp.status_code != 200: - log.info("Failed to get Metrics data from vROPS for {} {} {}".format(vrops_metric_name, - resp.status_code, - resp.content)) - return - - metrics_data = {} - m_data = json.loads(resp.content.decode('utf-8')) - - for resp_key, resp_val in six.iteritems(m_data): - if resp_key == 'values': - data = m_data['values'][0] - for data_k, data_v in six.iteritems(data): - if data_k == 'stat-list': - stat_list = data_v - for stat_list_k, stat_list_v in six.iteritems(stat_list): - for stat_keys, stat_vals in six.iteritems(stat_list_v[0]): - if stat_keys == 'timestamps': - metrics_data['time_series'] = stat_list_v[0]['timestamps'] - if stat_keys == 'data': - metrics_data['metrics_series'] = stat_list_v[0]['data'] - - if metrics_data: - metric = VnfMetric(nsr_id, - vnf_member_index, - vdur['name'], - metric_name, - metrics_data['metrics_series'][-1]) - - metrics.append(metric) - - except Exception as e: - log.debug("No metric found: %s", e) - pass + if 'monitoring-param' not in vdu: + continue - return metrics + vim_id = vdur['vim-id'] + vdu_mappings[vim_id] = {'name': vdur['name']} + + # Map the vROPS instance id to the vim-id so we can look it up. + for resource in resource_list: + for resourceIdentifier in resource['resourceKey']['resourceIdentifiers']: + if resourceIdentifier['identifierType']['name'] == 'VMEntityInstanceUUID': + if resourceIdentifier['value'] != vim_id: + continue + vdu_mappings[vim_id]['vrops_id'] = resource['identifier'] + + if len(vdu_mappings) != 0: + return self.vrops.get_metrics(vdu_mappings=vdu_mappings, + monitoring_params=vdu['monitoring-param'], + vnfr=vnfr) + else: + return [] diff --git a/osm_mon/collector/vnf_collectors/vmware.py b/osm_mon/collector/vnf_collectors/vmware.py index e79ce06..329d61d 100644 --- a/osm_mon/collector/vnf_collectors/vmware.py +++ b/osm_mon/collector/vnf_collectors/vmware.py @@ -23,7 +23,6 @@ import json import logging -import time import traceback from xml.etree import ElementTree as XmlElementTree @@ -33,106 +32,26 @@ from pyvcloud.vcd.client import Client from osm_mon.collector.utils.collector import CollectorUtils from osm_mon.collector.vnf_collectors.base_vim import BaseVimCollector -from osm_mon.collector.vnf_metric import VnfMetric from osm_mon.core.common_db import CommonDbClient from osm_mon.core.config import Config +from osm_mon.collector.vnf_collectors.vrops.vrops_helper import vROPS_Helper log = logging.getLogger(__name__) API_VERSION = '27.0' -TEN_MINUTES = 600000 - -# Ref: https://docs.vmware.com/en/vRealize-Operations-Manager/7.0/vrealize-operations-manager-70-reference-guide.pdf -# Potential metrics of interest -# "cpu|capacity_contentionPct" -# "cpu|corecount_provisioned" -# "cpu|costopPct" -# "cpu|demandmhz" -# "cpu|demandPct" -# "cpu|effective_limit" -# "cpu|iowaitPct" -# "cpu|readyPct" -# "cpu|swapwaitPct" -# "cpu|usage_average" -# "cpu|usagemhz_average" -# "cpu|usagemhz_average_mtd" -# "cpu|vm_capacity_provisioned" -# "cpu|workload" -# "guestfilesystem|percentage_total" -# "guestfilesystem|usage_total" -# "mem|consumedPct" -# "mem|guest_usage" -# "mem|host_contentionPct" -# "mem|reservation_used" -# "mem|swapinRate_average" -# "mem|swapoutRate_average" -# "mem|swapped_average" -# "mem|usage_average" -# "net:Aggregate of all instances|droppedPct" -# "net|broadcastTx_summation" -# "net|droppedTx_summation" -# "net|multicastTx_summation" -# "net|pnicBytesRx_average" -# "net|pnicBytesTx_average" -# "net|received_average" -# "net|transmitted_average" -# "net|usage_average" -# "virtualDisk:Aggregate of all instances|commandsAveraged_average" -# "virtualDisk:Aggregate of all instances|numberReadAveraged_average" -# "virtualDisk:Aggregate of all instances|numberWriteAveraged_average" -# "virtualDisk:Aggregate of all instances|totalLatency" -# "virtualDisk:Aggregate of all instances|totalReadLatency_average" -# "virtualDisk:Aggregate of all instances|totalWriteLatency_average" -# "virtualDisk:Aggregate of all instances|usage" -# "virtualDisk:Aggregate of all instances|vDiskOIO" -# "virtualDisk|read_average" -# "virtualDisk|write_average" - -METRIC_MAPPINGS = { - # Percent guest operating system active memory - "average_memory_utilization": "mem|usage_average", - # Percentage of CPU that was used out of all the CPU that was allocated - "cpu_utilization": "cpu|usage_average", - # KB/s of data read in the performance interval - "disk_read_bytes": "virtualDisk|read_average", - # Average of read commands per second during the collection interval. - "disk_read_ops": "virtualDisk:aggregate of all instances|numberReadAveraged_average", - # KB/s of data written in the performance interval - "disk_write_bytes": "virtualDisk|write_average", - # Average of write commands per second during the collection interval. - "disk_write_ops": "virtualDisk:aggregate of all instances|numberWriteAveraged_average", - # "packets_in_dropped": "net|droppedRx_summation", # Not supported by vROPS - # Transmitted packets dropped in the collection interval - "packets_out_dropped": "net|droppedTx_summation", - # Bytes received in the performance interval - "packets_received": "net|received_average", - # Packets transmitted in the performance interval - "packets_sent": "net|transmitted_average", -} - -# If the unit from vROPS does not align with the expected value. multiply by the specified amount to ensure -# the correct unit is returned. -METRIC_MULTIPLIERS = { - "disk_read_bytes": 1024, - "disk_write_bytes": 1024, - "packets_received": 1024, - "packets_sent": 1024 -} - class VMwareCollector(BaseVimCollector): def __init__(self, config: Config, vim_account_id: str): super().__init__(config, vim_account_id) self.common_db = CommonDbClient(config) vim_account = self.get_vim_account(vim_account_id) - self.vrops_site = vim_account['vrops_site'] - self.vrops_user = vim_account['vrops_user'] - self.vrops_password = vim_account['vrops_password'] self.vcloud_site = vim_account['vim_url'] self.admin_username = vim_account['admin_username'] self.admin_password = vim_account['admin_password'] - self.vim_uuid = vim_account['vim_uuid'] + self.vrops = vROPS_Helper(vrops_site=vim_account['vrops_site'], + vrops_user=vim_account['vrops_user'], + vrops_password=vim_account['vrops_password']) def connect_as_admin(self): """ Method connect as pvdc admin user to vCloud director. @@ -143,7 +62,7 @@ class VMwareCollector(BaseVimCollector): The return client object that letter can be used to connect to vcloud direct as admin for provider vdc """ - log.info("Logging into vCD org as admin.") + log.debug("Logging into vCD org as admin.") admin_user = None try: @@ -158,11 +77,7 @@ class VMwareCollector(BaseVimCollector): return client except Exception as e: - log.info("Can't connect to a vCloud director as: {} with exception {}".format(admin_user, e)) - - def _get_resource_uuid(self, nsr_id, vnf_member_index, vdur_name) -> str: - vdur = self.common_db.get_vdur(nsr_id, vnf_member_index, vdur_name) - return vdur['vim-id'] + log.error("Can't connect to a vCloud director as: {} with exception {}".format(admin_user, e)) def get_vim_account(self, vim_account_id: str): """ @@ -173,13 +88,7 @@ class VMwareCollector(BaseVimCollector): vim_account = {} vim_account_info = CollectorUtils.get_credentials(vim_account_id) - vim_account['name'] = vim_account_info.name - vim_account['vim_tenant_name'] = vim_account_info.tenant_name - vim_account['vim_type'] = vim_account_info.type vim_account['vim_url'] = vim_account_info.url - vim_account['org_user'] = vim_account_info.user - vim_account['org_password'] = vim_account_info.password - vim_account['vim_uuid'] = vim_account_info.uuid vim_config = json.loads(vim_account_info.config) vim_account['admin_username'] = vim_config['admin_username'] @@ -187,22 +96,6 @@ class VMwareCollector(BaseVimCollector): vim_account['vrops_site'] = vim_config['vrops_site'] vim_account['vrops_user'] = vim_config['vrops_user'] vim_account['vrops_password'] = vim_config['vrops_password'] - vim_account['vcenter_ip'] = vim_config['vcenter_ip'] - vim_account['vcenter_port'] = vim_config['vcenter_port'] - vim_account['vcenter_user'] = vim_config['vcenter_user'] - vim_account['vcenter_password'] = vim_config['vcenter_password'] - - if vim_config['nsx_manager'] is not None: - vim_account['nsx_manager'] = vim_config['nsx_manager'] - - if vim_config['nsx_user'] is not None: - vim_account['nsx_user'] = vim_config['nsx_user'] - - if vim_config['nsx_password'] is not None: - vim_account['nsx_password'] = vim_config['nsx_password'] - - if vim_config['orgname'] is not None: - vim_account['orgname'] = vim_config['orgname'] return vim_account @@ -219,12 +112,14 @@ class VMwareCollector(BaseVimCollector): if vm_details and "vm_vcenter_info" in vm_details: vm_moref_id = vm_details["vm_vcenter_info"].get("vm_moref_id", None) - - log.info("Found vm_moref_id: {} for vApp UUID: {}".format(vm_moref_id, vapp_uuid)) - return vm_moref_id + log.debug("Found vm_moref_id: {} for vApp UUID: {}".format(vm_moref_id, vapp_uuid)) + else: + log.error("Failed to find vm_moref_id from vApp UUID: {}".format(vapp_uuid)) except Exception as exp: - log.info("Error occurred while getting VM moref ID for VM : {}\n{}".format(exp, traceback.format_exc())) + log.warning("Error occurred while getting VM moref ID for VM: {}\n{}".format(exp, traceback.format_exc())) + + return vm_moref_id def get_vapp_details_rest(self, vapp_uuid=None): """ @@ -278,137 +173,49 @@ class VMwareCollector(BaseVimCollector): parsed_respond["vm_vcenter_info"] = vm_vcenter_info except Exception as exp: - log.info("Error occurred for getting vApp details: {}\n{}".format(exp, - traceback.format_exc()) - ) + log.warning("Error occurred for getting vApp details: {}\n{}".format(exp, + traceback.format_exc())) return parsed_respond - def get_vm_resource_id(self, vm_moref_id): - """ Find resource ID in vROPs using vm_moref_id - """ - if vm_moref_id is None: - return None - - api_url = '/suite-api/api/resources?resourceKind=VirtualMachine' - headers = {'Accept': 'application/json'} - - resp = requests.get(self.vrops_site + api_url, - auth=(self.vrops_user, self.vrops_password), - verify=False, headers=headers) - - if resp.status_code != 200: - log.error("Failed to get resource details for{} {} {}".format(vm_moref_id, - resp.status_code, - resp.content)) - return None - - vm_resource_id = None - try: - resp_data = json.loads(resp.content.decode('utf-8')) - if resp_data.get('resourceList') is not None: - resource_list = resp_data.get('resourceList') - for resource in resource_list: - if resource.get('resourceKey') is not None: - resource_details = resource['resourceKey'] - if resource_details.get('resourceIdentifiers') is not None: - resource_identifiers = resource_details['resourceIdentifiers'] - for resource_identifier in resource_identifiers: - if resource_identifier['identifierType']['name'] == 'VMEntityObjectID': - if resource_identifier.get('value') is not None and \ - resource_identifier['value'] == vm_moref_id: - vm_resource_id = resource['identifier'] - log.info("Found VM resource ID: {} for vm_moref_id: {}".format(vm_resource_id, - vm_moref_id)) - - except Exception as exp: - log.info("get_vm_resource_id: Error in parsing {}\n{}".format(exp, traceback.format_exc())) - - return vm_resource_id - def collect(self, vnfr: dict): - nsr_id = vnfr['nsr-id-ref'] - vnf_member_index = vnfr['member-vnf-index-ref'] vnfd = self.common_db.get_vnfd(vnfr['vnfd-id']) - metrics = [] + vdu_mappings = {} + + # Fetch the list of all known resources from vROPS. + resource_list = self.vrops.get_vm_resource_list_from_vrops() + for vdur in vnfr['vdur']: # This avoids errors when vdur records have not been completely filled if 'name' not in vdur: continue vdu = next( filter(lambda vdu: vdu['id'] == vdur['vdu-id-ref'], vnfd['vdu']) - ) if 'monitoring-param' not in vdu: continue - resource_uuid = self._get_resource_uuid(nsr_id, vnf_member_index, vdur['name']) - + resource_uuid = vdur['vim-id'] # Find vm_moref_id from vApp uuid in vCD - vm_moref_id = self.get_vm_moref_id(resource_uuid) - if vm_moref_id is None: - log.debug("Failed to find vm morefid for vApp in vCD: {}".format(resource_uuid)) - continue - - # Based on vm_moref_id, find VM's corresponding resource_id in vROPs - resource_id = self.get_vm_resource_id(vm_moref_id) - if resource_id is None: - log.debug("Failed to find resource in vROPs: {}".format(resource_uuid)) + vim_id = self.get_vm_moref_id(resource_uuid) + if vim_id is None: + log.debug("Failed to find vROPS ID for vApp in vCD: {}".format(resource_uuid)) continue - stat_key = "" - monitoring_params = [] - for metric_entry in vdu['monitoring-param']: - metric_name = metric_entry['nfvi-metric'] - if metric_name not in METRIC_MAPPINGS: - log.debug("Metric {} not supported, ignoring".format(metric_name)) - continue - monitoring_params.append(metric_name) - vrops_metric_name = METRIC_MAPPINGS[metric_name] - stat_key = "{}&statKey={}".format(stat_key, vrops_metric_name) - - try: - end_time = int(round(time.time() * 1000)) - begin_time = end_time - TEN_MINUTES - - api_url = "/suite-api/api/resources/stats?resourceId={}&begin={}&end={}{}".format( - resource_id, str(begin_time), str(end_time), stat_key) - headers = {'Accept': 'application/json'} - - resp = requests.get(self.vrops_site + api_url, - auth=(self.vrops_user, self.vrops_password), verify=False, headers=headers - ) - - if resp.status_code != 200: - log.info("Failed to get Metrics data from vROPS for {} {} {}".format(vdur.name, - resp.status_code, - resp.content)) - continue - - m_data = json.loads(resp.content.decode('utf-8')) - - stat_list = m_data['values'][0]['stat-list']['stat'] - for item in stat_list: - reported_metric = item['statKey']['key'] - if reported_metric not in METRIC_MAPPINGS.values(): - continue - - metric_name = list(METRIC_MAPPINGS.keys())[list(METRIC_MAPPINGS.values()). - index(reported_metric)] - if metric_name in monitoring_params: - metric_value = item['data'][-1] - if metric_name in METRIC_MULTIPLIERS: - metric_value *= METRIC_MULTIPLIERS[metric_name] - metric = VnfMetric(nsr_id, - vnf_member_index, - vdur['name'], - metric_name, - metric_value) - - metrics.append(metric) - - except Exception as e: - log.debug("No metric found for {}: %s".format(vdur['name']), e) - pass - return metrics + vdu_mappings[vim_id] = {'name': vdur['name']} + + # Map the vROPS instance id to the vim-id so we can look it up. + for resource in resource_list: + for resourceIdentifier in resource['resourceKey']['resourceIdentifiers']: + if resourceIdentifier['identifierType']['name'] == 'VMEntityObjectID': + if resourceIdentifier['value'] != vim_id: + continue + vdu_mappings[vim_id]['vrops_id'] = resource['identifier'] + + if len(vdu_mappings) != 0: + return self.vrops.get_metrics(vdu_mappings=vdu_mappings, + monitoring_params=vdu['monitoring-param'], + vnfr=vnfr) + else: + return [] diff --git a/osm_mon/collector/vnf_collectors/vrops/__init__.py b/osm_mon/collector/vnf_collectors/vrops/__init__.py new file mode 100644 index 0000000..30d864e --- /dev/null +++ b/osm_mon/collector/vnf_collectors/vrops/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# # +# 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 +# # diff --git a/osm_mon/collector/vnf_collectors/vrops/metrics.py b/osm_mon/collector/vnf_collectors/vrops/metrics.py new file mode 100644 index 0000000..d4bd69f --- /dev/null +++ b/osm_mon/collector/vnf_collectors/vrops/metrics.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- + +# # +# 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 +# # + +# Ref: https://docs.vmware.com/en/vRealize-Operations-Manager/7.0/vrealize-operations-manager-70-reference-guide.pdf +# Potential metrics of interest +# "cpu|capacity_contentionPct" +# "cpu|corecount_provisioned" +# "cpu|costopPct" +# "cpu|demandmhz" +# "cpu|demandPct" +# "cpu|effective_limit" +# "cpu|iowaitPct" +# "cpu|readyPct" +# "cpu|swapwaitPct" +# "cpu|usage_average" +# "cpu|usagemhz_average" +# "cpu|usagemhz_average_mtd" +# "cpu|vm_capacity_provisioned" +# "cpu|workload" +# "guestfilesystem|percentage_total" +# "guestfilesystem|usage_total" +# "mem|consumedPct" +# "mem|guest_usage" +# "mem|host_contentionPct" +# "mem|reservation_used" +# "mem|swapinRate_average" +# "mem|swapoutRate_average" +# "mem|swapped_average" +# "mem|usage_average" +# "net:Aggregate of all instances|droppedPct" +# "net|broadcastTx_summation" +# "net|droppedTx_summation" +# "net|multicastTx_summation" +# "net|pnicBytesRx_average" +# "net|pnicBytesTx_average" +# "net|received_average" +# "net|transmitted_average" +# "net|usage_average" +# "virtualDisk:Aggregate of all instances|commandsAveraged_average" +# "virtualDisk:Aggregate of all instances|numberReadAveraged_average" +# "virtualDisk:Aggregate of all instances|numberWriteAveraged_average" +# "virtualDisk:Aggregate of all instances|totalLatency" +# "virtualDisk:Aggregate of all instances|totalReadLatency_average" +# "virtualDisk:Aggregate of all instances|totalWriteLatency_average" +# "virtualDisk:Aggregate of all instances|usage" +# "virtualDisk:Aggregate of all instances|vDiskOIO" +# "virtualDisk|read_average" +# "virtualDisk|write_average" + +METRIC_MAPPINGS = { + # Percent guest operating system active memory. + "average_memory_utilization": "mem|usage_average", + # Percentage of CPU that was used out of all the CPU that was allocated. + "cpu_utilization": "cpu|usage_average", + # KB/s of data read in the performance interval + "disk_read_bytes": "virtualDisk|read_average", + # Average of read commands per second during the collection interval. + "disk_read_ops": "virtualDisk:aggregate of all instances|numberReadAveraged_average", + # KB/s of data written in the performance interval. + "disk_write_bytes": "virtualDisk|write_average", + # Average of write commands per second during the collection interval. + "disk_write_ops": "virtualDisk:aggregate of all instances|numberWriteAveraged_average", + # Not supported by vROPS, will always return 0. + "packets_in_dropped": "net|droppedRx_summation", + # Transmitted packets dropped in the collection interval. + "packets_out_dropped": "net|droppedTx_summation", + # Bytes received in the performance interval. + "packets_received": "net|received_average", + # Packets transmitted in the performance interval. + "packets_sent": "net|transmitted_average", +} diff --git a/osm_mon/collector/vnf_collectors/vrops/vrops_helper.py b/osm_mon/collector/vnf_collectors/vrops/vrops_helper.py new file mode 100644 index 0000000..430cf86 --- /dev/null +++ b/osm_mon/collector/vnf_collectors/vrops/vrops_helper.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- + +# # +# 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 +# # + +import logging +import json +import requests +import traceback + +from osm_mon.collector.vnf_metric import VnfMetric +from osm_mon.collector.vnf_collectors.vrops.metrics import METRIC_MAPPINGS +import copy + +log = logging.getLogger(__name__) + + +# If the unit from vROPS does not align with the expected value. multiply by the specified amount to ensure +# the correct unit is returned. +METRIC_MULTIPLIERS = { + "disk_read_bytes": 1024, + "disk_write_bytes": 1024, + "packets_received": 1024, + "packets_sent": 1024 +} + + +class vROPS_Helper(): + + def __init__(self, + vrops_site='https://vrops', + vrops_user='', + vrops_password=''): + self.vrops_site = vrops_site + self.vrops_user = vrops_user + self.vrops_password = vrops_password + + def get_vm_resource_list_from_vrops(self): + """ Find all known resource IDs in vROPs + """ + api_url = '/suite-api/api/resources?resourceKind=VirtualMachine' + headers = {'Accept': 'application/json'} + 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: + log.error("Failed to get resource list from vROPS: {} {}".format(resp.status_code, + resp.content)) + return resource_list + + try: + resp_data = json.loads(resp.content.decode('utf-8')) + if resp_data.get('resourceList') is not None: + resource_list = resp_data.get('resourceList') + + except Exception as exp: + log.error("get_vm_resource_id: Error in parsing {}\n{}".format(exp, traceback.format_exc())) + + return resource_list + + def get_metrics(self, + vdu_mappings={}, + monitoring_params={}, + vnfr=None): + + monitoring_keys = {} + # Collect the names of all the metrics we need to query + for metric_entry in monitoring_params: + metric_name = metric_entry['nfvi-metric'] + if metric_name not in METRIC_MAPPINGS: + log.debug("Metric {} not supported, ignoring".format(metric_name)) + continue + monitoring_keys[metric_name] = METRIC_MAPPINGS[metric_name] + + metrics = [] + # Make a query for only the stats we have been asked for + stats_key = "" + for stat in monitoring_keys.values(): + stats_key += "&statKey={}".format(stat) + + # And only ask for the resource ids that we are interested in + resource_ids = "" + sanitized_vdu_mappings = copy.deepcopy(vdu_mappings) + for key in vdu_mappings.keys(): + vdu = vdu_mappings[key] + if 'vrops_id' not in vdu: + log.info("Could not find vROPS id for vdu {}".format(vdu)) + del sanitized_vdu_mappings[key] + continue + resource_ids += "&resourceId={}".format(vdu['vrops_id']) + vdu_mappings = sanitized_vdu_mappings + + try: + + # 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'} + + resp = requests.get(self.vrops_site + api_url, + auth=(self.vrops_user, self.vrops_password), verify=False, headers=headers) + + if resp.status_code != 200: + log.error("Failed to get Metrics data from vROPS for {} {}".format(resp.status_code, + resp.content)) + return metrics + + m_data = json.loads(resp.content.decode('utf-8')) + if 'values' not in m_data: + return metrics + + statistics = m_data['values'] + for vdu_stat in statistics: + vrops_id = vdu_stat['resourceId'] + vdu_name = None + for vdu in vdu_mappings.values(): + if vdu['vrops_id'] == vrops_id: + vdu_name = vdu['name'] + if vdu_name is None: + continue + for item in vdu_stat['stat-list']['stat']: + reported_metric = item['statKey']['key'] + if reported_metric not in METRIC_MAPPINGS.values(): + continue + + # Convert the vROPS metric name back to OSM key + metric_name = list(METRIC_MAPPINGS.keys())[list(METRIC_MAPPINGS.values()). + index(reported_metric)] + if metric_name in monitoring_keys.keys(): + metric_value = item['data'][-1] + if metric_name in METRIC_MULTIPLIERS: + metric_value *= METRIC_MULTIPLIERS[metric_name] + metric = VnfMetric(vnfr['nsr-id-ref'], + vnfr['member-vnf-index-ref'], + vdu_name, + metric_name, + metric_value) + + metrics.append(metric) + + except Exception as exp: + log.error("Exception while parsing metrics data from vROPS {}\n{}".format(exp, traceback.format_exc())) + + return metrics diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/mock_http.py b/osm_mon/tests/unit/collector/vnf_collectors/vmware/mock_http.py new file mode 100644 index 0000000..36ee361 --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/mock_http.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2019 VMware +# ************************************************************* + +# This file is part of OSM Monitoring module +# All Rights Reserved to VMware + +# 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: mbeierl@vmware.com +# # + +import os +import re + + +def mock_http_response(mocker, method='GET', site='https://vrops', url_pattern='', response_file='OK', + status_code=200, exception=None): + '''Helper function to load a canned response from a file.''' + with open(os.path.join(os.path.dirname(__file__), 'vmware_mocks', + '%s' % response_file), 'r') as f: + response = f.read() + + matcher = re.compile(site + url_pattern) + if exception is None: + mocker.register_uri(method, matcher, text=response, status_code=status_code) + else: + mocker.register_uri(method, matcher, exc=exception) diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/mock_vcd.py b/osm_mon/tests/unit/collector/vnf_collectors/vmware/mock_vcd.py deleted file mode 100644 index 6938873..0000000 --- a/osm_mon/tests/unit/collector/vnf_collectors/vmware/mock_vcd.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2019 VMware -# ************************************************************* - -# This file is part of OSM Monitoring module -# All Rights Reserved to VMware - -# 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: mbeierl@vmware.com -# # - -import os -import re - - -def mock_vdc_response(mocker, method='GET', site='https://vrops', url_pattern='', response_file='OK'): - '''Helper function to load a canned response from a file.''' - with open(os.path.join(os.path.dirname(__file__), 'vcd_mocks', - '%s' % response_file), 'r') as f: - response = f.read() - - matcher = re.compile(site + url_pattern) - mocker.register_uri(method, matcher, text=response) diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/osm_mocks/VNFD.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/osm_mocks/VNFD.json index ed34789..12105a4 100644 --- a/osm_mon/tests/unit/collector/vnf_collectors/vmware/osm_mocks/VNFD.json +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/osm_mocks/VNFD.json @@ -1,63 +1,164 @@ { + "_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", "_admin": { - "created": 1561567611.6193357, - "modified": 1561567611.6193357, + "created": 1562374395.5216513, + "modified": 1562374395.5216513, "onboardingState": "ONBOARDED", "operationalState": "ENABLED", "projects_read": [ - "admin" + "775be778-0f51-495a-b865-a23ab20a080f" ], "projects_write": [ - "admin" + "775be778-0f51-495a-b865-a23ab20a080f" ], "storage": { "descriptor": "cirros_vnf/cirros_vdu_alarm_vnfd.yaml", - "folder": "9d116df6-6fa7-4a5b-b284-a67f554c1261", + "folder": "cb0da948-7bce-474d-bbcb-6bfce545d397", "fs": "local", "path": "/app/storage/", "pkg-dir": "cirros_vnf", - "zipfile": "cirros_vdu_alarm_vnfd.tar.gz" + "zipfile": "package.tar.gz" }, "type": "vnfd", "usageState": "NOT_IN_USE", "userDefinedData": { } }, - "_id": "9d116df6-6fa7-4a5b-b284-a67f554c1261", + "_id": "cb0da948-7bce-474d-bbcb-6bfce545d397", "connection-point": [ { "name": "eth0", "type": "VPORT" } ], - "description": "Simple VNF example with a cirros and a VNF alarm", - "id": "cirros_vdu_alarm_vnf", - "logo": "cirros-64.png", + "description": "Simple Ubuntu VNF with metric collectors and scaling group", + "id": "ubuntu_vdu_alarm_vnf", + "logo": "ubuntu-64.png", "mgmt-interface": { "cp": "eth0" }, "monitoring-param": [ { "aggregation-type": "AVERAGE", - "id": "cirros_vnf_cpu_util", - "name": "cirros_vnf_cpu_util", + "id": "ubuntu_vnf_cpu_util", + "name": "ubuntu_vnf_cpu_util", "vdu-monitoring-param": { - "vdu-monitoring-param-ref": "cirros_vnfd-VM_cpu_util", - "vdu-ref": "cirros_vnfd-VM" + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_cpu_util", + "vdu-ref": "ubuntu_vnfd-VM" } }, { "aggregation-type": "AVERAGE", - "id": "cirros_vnf_average_memory_utilization", - "name": "cirros_vnf_average_memory_utilization", + "id": "ubuntu_vnf_average_memory_utilization", + "name": "ubuntu_vnf_average_memory_utilization", "vdu-monitoring-param": { - "vdu-monitoring-param-ref": "cirros_vnfd-VM_average_memory_utilization", - "vdu-ref": "cirros_vnfd-VM" + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_average_memory_utilization", + "vdu-ref": "ubuntu_vnfd-VM" } + }, + { + "aggregation-type": "AVERAGE", + "id": "ubuntu_vnf_disk_read_ops", + "name": "ubuntu_vnf_disk_read_ops", + "vdu-monitoring-param": { + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_disk_read_ops", + "vdu-ref": "ubuntu_vnfd-VM" + } + }, + { + "aggregation-type": "AVERAGE", + "id": "ubuntu_vnf_disk_write_ops", + "name": "ubuntu_vnf_disk_write_ops", + "vdu-monitoring-param": { + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_disk_write_ops", + "vdu-ref": "ubuntu_vnfd-VM" + } + }, + { + "aggregation-type": "AVERAGE", + "id": "ubuntu_vnf_disk_read_bytes", + "name": "ubuntu_vnf_disk_read_bytes", + "vdu-monitoring-param": { + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_disk_read_bytes", + "vdu-ref": "ubuntu_vnfd-VM" + } + }, + { + "aggregation-type": "AVERAGE", + "id": "ubuntu_vnf_disk_write_bytes", + "name": "ubuntu_vnf_disk_write_bytes", + "vdu-monitoring-param": { + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_disk_write_bytes", + "vdu-ref": "ubuntu_vnfd-VM" + } + }, + { + "aggregation-type": "AVERAGE", + "id": "ubuntu_vnf_packets_in_dropped", + "name": "ubuntu_vnf_packets_in_dropped", + "vdu-monitoring-param": { + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_packets_in_dropped", + "vdu-ref": "ubuntu_vnfd-VM" + } + }, + { + "aggregation-type": "AVERAGE", + "id": "ubuntu_vnf_packets_out_dropped", + "name": "ubuntu_vnf_packets_out_dropped", + "vdu-monitoring-param": { + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_packets_out_dropped", + "vdu-ref": "ubuntu_vnfd-VM" + } + }, + { + "aggregation-type": "AVERAGE", + "id": "ubuntu_vnf_packets_received", + "name": "ubuntu_vnf_packets_received", + "vdu-monitoring-param": { + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_packets_received", + "vdu-ref": "ubuntu_vnfd-VM" + } + }, + { + "aggregation-type": "AVERAGE", + "id": "ubuntu_vnf_packets_sent", + "name": "ubuntu_vnf_packets_sent", + "vdu-monitoring-param": { + "vdu-monitoring-param-ref": "ubuntu_vnfd-VM_packets_sent", + "vdu-ref": "ubuntu_vnfd-VM" + } + } + ], + "name": "ubuntu_vdu_alarm_vnf", + "scaling-group-descriptor": [ + { + "min-instance-count": 0, + "name": "cpu_autoscaling_descriptor", + "scaling-policy": [ + { + "cooldown-time": 120, + "name": "cpu_scaling_policy", + "scaling-criteria": [ + { + "name": "cpu_autoscaling_criteria", + "scale-in-relational-operation": "LT", + "scale-in-threshold": "20.0000000000", + "scale-out-relational-operation": "GT", + "scale-out-threshold": "80.0000000000", + "vnf-monitoring-param-ref": "ubuntu_vnf_cpu_util" + } + ], + "scaling-type": "automatic" + } + ], + "vdu": [ + { + "vdu-id-ref": "ubuntu_vnfd-VM" + } + ] } ], - "name": "cirros_vdu_alarm_vnf", - "short-name": "cirros_vdu_alarm_vnf", + "short-name": "ubuntu_vdu_alarm_vnf", "vdu": [ { "alarm": [ @@ -82,12 +183,12 @@ "alarm-id": "alarm-1", "operation": "LT", "value": "20.0000", - "vnf-monitoring-param-ref": "cirros_vnf_cpu_util" + "vnf-monitoring-param-ref": "ubuntu_vnf_cpu_util" } ], "count": "1", - "description": "cirros_vnfd-VM", - "id": "cirros_vnfd-VM", + "description": "ubuntu_vnfd-VM", + "id": "ubuntu_vnfd-VM", "image": "ubuntu", "interface": [ { @@ -102,19 +203,51 @@ ], "monitoring-param": [ { - "id": "cirros_vnfd-VM_cpu_util", + "id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization" }, { - "id": "cirros_vnfd-VM_average_memory_utilization", + "id": "ubuntu_vnfd-VM_average_memory_utilization", "nfvi-metric": "average_memory_utilization" + }, + { + "id": "ubuntu_vnfd-VM_disk_read_ops", + "nfvi-metric": "disk_read_ops" + }, + { + "id": "ubuntu_vnfd-VM_disk_write_ops", + "nfvi-metric": "disk_write_ops" + }, + { + "id": "ubuntu_vnfd-VM_disk_read_bytes", + "nfvi-metric": "disk_read_bytes" + }, + { + "id": "ubuntu_vnfd-VM_disk_write_bytes", + "nfvi-metric": "disk_write_bytes" + }, + { + "id": "ubuntu_vnfd-VM_packets_in_dropped", + "nfvi-metric": "packets_in_dropped" + }, + { + "id": "ubuntu_vnfd-VM_packets_out_dropped", + "nfvi-metric": "packets_out_dropped" + }, + { + "id": "ubuntu_vnfd-VM_packets_received", + "nfvi-metric": "packets_received" + }, + { + "id": "ubuntu_vnfd-VM_packets_sent", + "nfvi-metric": "packets_sent" } ], - "name": "cirros_vnfd-VM", + "name": "ubuntu_vnfd-VM", "vm-flavor": { - "memory-mb": "256", - "storage-gb": "2", - "vcpu-count": 1 + "memory-mb": "4096", + "storage-gb": "20", + "vcpu-count": 4 } } ], diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/osm_mocks/VNFR.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/osm_mocks/VNFR.json index 332949b..2583c8e 100644 --- a/osm_mon/tests/unit/collector/vnf_collectors/vmware/osm_mocks/VNFR.json +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/osm_mocks/VNFR.json @@ -1,15 +1,16 @@ { + "_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", "_admin": { - "created": 1561569715.5365124, - "modified": 1561569715.5365124, + "created": 1563297813.7205596, + "modified": 1563297813.7205596, "projects_read": [ - "admin" + "775be778-0f51-495a-b865-a23ab20a080f" ], "projects_write": [ - "admin" + "775be778-0f51-495a-b865-a23ab20a080f" ] }, - "_id": "c222366b-4e67-47e8-a3a5-d602ef9f953f", + "_id": "a3ec20d6-a47d-4459-ac17-65391424856b", "additionalParamsForVnf": null, "connection-point": [ { @@ -18,35 +19,56 @@ "name": "eth0" } ], - "created-time": 1561569715.5344007, - "id": "c222366b-4e67-47e8-a3a5-d602ef9f953f", - "ip-address": "172.21.6.212", + "created-time": 1563297813.7185328, + "id": "a3ec20d6-a47d-4459-ac17-65391424856b", + "ip-address": "172.21.6.152", "member-vnf-index-ref": "1", - "nsr-id-ref": "66300531-3fb2-43e2-a988-51a1afd9a8f2", + "nsr-id-ref": "5915fddf-519a-4235-b18a-41997d76bca0", "vdur": [ { - "_id": "ddb46f3c-d586-4a8e-80c3-87a74d0a3b37", + "_id": "66f70869-8c11-48b6-bd48-95312832ea67", "count-index": 0, "interfaces": [ { - "ip-address": "172.21.6.212", - "mac-address": "00:50:56:03:01:79", + "ip-address": "172.21.6.152", + "mac-address": "fa:16:3e:d2:22:5d", "mgmt-vnf": true, "name": "eth0", - "ns-vld-id": "cirros_nsd_vld1" + "ns-vld-id": "ubuntu_nsd_vld1" } ], "internal-connection-point": [ ], - "ip-address": "172.21.6.212", - "name": "mb-cirros-1-cirros_vnfd-VM-1", + "ip-address": "172.21.6.152", + "name": "vmware-scaling-1-ubuntu_vnfd-VM-1", "status": "ACTIVE", - "status-detailed": "ACTIVE", - "vdu-id-ref": "cirros_vnfd-VM", - "vim-id": "962e29e7-e0b0-4253-b3ef-88df7971f12e" + "status-detailed": null, + "vdu-id-ref": "ubuntu_vnfd-VM", + "vim-id": "VMWARE-UUID-VM-1" + }, + { + "_id": "a1e81bfc-5ded-4a72-9e26-6e1a5f91902a", + "count-index": 1, + "interfaces": [ + { + "ip-address": "172.21.6.163", + "mac-address": "fa:16:3e:b8:9e:7c", + "mgmt-vnf": true, + "name": "eth0", + "ns-vld-id": "ubuntu_nsd_vld1" + } + ], + "internal-connection-point": [ + ], + "ip-address": "172.21.6.163", + "name": "vmware-scaling-1-ubuntu_vnfd-VM-2", + "status": "ACTIVE", + "status-detailed": null, + "vdu-id-ref": "ubuntu_vnfd-VM", + "vim-id": "VMWARE-UUID-VM-2" } ], - "vim-account-id": "43d176fd-dc6d-4fb0-acf3-faf03b1d2589", - "vnfd-id": "9d116df6-6fa7-4a5b-b284-a67f554c1261", - "vnfd-ref": "cirros_vdu_alarm_vnf" + "vim-account-id": "1fc05d6c-2b8b-483e-8d59-f65d658ccfc1", + "vnfd-id": "cb0da948-7bce-474d-bbcb-6bfce545d397", + "vnfd-ref": "ubuntu_vdu_alarm_vnf" } 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 19d1496..740de74 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 @@ -22,7 +22,7 @@ from osm_mon.collector.vnf_collectors.vmware import VMwareCollector from osm_mon.core.config import Config -from osm_mon.tests.unit.collector.vnf_collectors.vmware.mock_vcd import mock_vdc_response +from osm_mon.tests.unit.collector.vnf_collectors.vmware.mock_http import mock_http_response from unittest import TestCase, mock import json @@ -32,14 +32,12 @@ import requests_mock VIM_ACCOUNT = {"vrops_site": "https://vrops", "vrops_user": "", "vrops_password": "", - "vim_url": "", + "vim_url": "https://vcd", "admin_username": "", "admin_password": "", "vim_uuid": ""} -@mock.patch.object(VMwareCollector, 'get_vm_resource_id', - spec_set=True, autospec=True) @mock.patch.object(VMwareCollector, 'get_vm_moref_id', spec_set=True, autospec=True) class CollectorTest(TestCase): @@ -60,101 +58,168 @@ class CollectorTest(TestCase): def tearDown(self): super().tearDown() - def test_collect_cpu_and_memory(self, mock_vm_moref_id, mock_vm_resource_id): + def test_collect_cpu_and_memory(self, mock_vm_moref_id): - mock_vm_moref_id.return_value = "moref" - mock_vm_resource_id.return_value = "resource" + mock_vm_moref_id.return_value = "VMWARE-OID-VM-1" + self.vnfd['vdu'][0]['monitoring-param'] = [ + {"id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization"}, + {"id": "ubuntu_vnfd-VM_average_memory_utilization", "nfvi-metric": "average_memory_utilization"} + ] self.mock_db.return_value.get_vnfd.return_value = self.vnfd with requests_mock.Mocker() as mock_requests: - mock_vdc_response(mock_requests, - url_pattern='/suite-api/api/resources/stats.*', - response_file='vrops_multi.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') metrics = self.collector.collect(self.vnfr) - self.assertEqual(len(metrics), 2, "Number of metrics returned") - self.assertEqual(metrics[0].name, "cpu_utilization", "First metric name") - self.assertEqual(metrics[1].name, "average_memory_utilization", "Second metric name") - self.assertEqual(metrics[0].value, 100.0, "CPU metric value") - self.assertEqual(metrics[1].value, 20.515941619873047, "Memory metric value") - - def test_collect_one_metric_only(self, mock_vm_moref_id, mock_vm_resource_id): - - mock_vm_moref_id.return_value = "moref" - mock_vm_resource_id.return_value = "resource" - - self.vnfd['vdu'][0]['monitoring-param'] = [ - {'id': 'cirros_vnfd-VM_cpu_util', 'nfvi-metric': 'cpu_utilization'}, - ] + self.assertEqual(len(metrics), 2, "Number of metrics returned") + self.assertEqual(metrics[0].name, "cpu_utilization", "First metric name") + self.assertEqual(metrics[0].value, 100.0, "CPU metric value") + self.assertEqual(metrics[1].name, "average_memory_utilization", "Second metric name") + self.assertEqual(metrics[1].value, 20.515941619873047, "Memory metric value") + + def test_collect_no_moref(self, mock_vm_moref_id): + 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_vdc_response(mock_requests, - url_pattern='/suite-api/api/resources/stats.*', - response_file='vrops_multi.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='404.txt', status_code=404) metrics = self.collector.collect(self.vnfr) - self.assertEqual(len(metrics), 1, "Number of metrics returned") - self.assertEqual(metrics[0].name, "cpu_utilization", "First metric name") - self.assertEqual(metrics[0].value, 100.0, "CPU metric value") + self.assertEqual(len(metrics), 0, "Number of metrics returned") - def test_collect_adjusted_metric(self, mock_vm_moref_id, mock_vm_resource_id): - - mock_vm_moref_id.return_value = "moref" - mock_vm_resource_id.return_value = "resource" + def test_collect_no_monitoring_param(self, _): + 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, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + metrics = self.collector.collect(self.vnfr) + self.assertEqual(len(metrics), 0, "Number of metrics returned") - self.vnfd['vdu'][0]['monitoring-param'] = [ - {'id': 'cirros_vnfd-VM_cpu_util', 'nfvi-metric': 'disk_read_bytes'}, - ] + def test_collect_empty_monitoring_param(self, _): + 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, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + metrics = self.collector.collect(self.vnfr) + self.assertEqual(len(metrics), 0, "Number of metrics returned") + def test_collect_no_name(self, _): + del self.vnfr['vdur'][0]['name'] + 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_vdc_response(mock_requests, - url_pattern='/suite-api/api/resources/stats.*', - response_file='vrops_multi.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') metrics = self.collector.collect(self.vnfr) - self.assertEqual(len(metrics), 1, "Number of metrics returned") - self.assertEqual(metrics[0].name, "disk_read_bytes", "First metric name") - self.assertEqual(metrics[0].value, 10240.0, "Disk read bytes (not KB/s)") + self.assertEqual(len(metrics), 0, "Number of metrics returned") - def test_collect_not_provided_metric(self, mock_vm_moref_id, mock_vm_resource_id): - mock_vm_moref_id.return_value = "moref" - mock_vm_resource_id.return_value = "resource" +class VApp_Details_Test(TestCase): - self.vnfd['vdu'][0]['monitoring-param'] = [ - {'id': 'cirros_vnfd-VM_packets_sent', 'nfvi-metric': 'packets_sent'}, - ] - self.mock_db.return_value.get_vnfd.return_value = self.vnfd + @mock.patch.object(VMwareCollector, 'get_vim_account', + spec_set=True, autospec=True) + @mock.patch('osm_mon.collector.vnf_collectors.vmware.CommonDbClient') + def setUp(self, mock_db, mock_get_vim_account): + super().setUp() + self.mock_db = mock_db + mock_get_vim_account.return_value = VIM_ACCOUNT + self.collector = VMwareCollector(Config(), "9de6df67-b820-48c3-bcae-ee4838c5c5f4") + + def tearDown(self): + super().tearDown() + @mock.patch('osm_mon.collector.vnf_collectors.vmware.Client') + def test_get_vapp_details(self, mock_vcd_client): + mock_vcd_client.return_value._session.headers = {'x-vcloud-authorization': ''} with requests_mock.Mocker() as mock_requests: - mock_vdc_response(mock_requests, - url_pattern='/suite-api/api/resources/stats.*', - response_file='OK.json') - metrics = self.collector.collect(self.vnfr) - self.assertEqual(len(metrics), 0, "Number of metrics returned") + mock_http_response(mock_requests, + site='https://vcd', + url_pattern='/api/vApp/.*', + response_file='vcd_vapp_response.xml') + response = self.collector.get_vapp_details_rest('') + self.assertDictContainsSubset({'vm_vcenter_info': {'vm_moref_id': 'vm-4055'}}, + response, 'Managed object reference id incorrect') + + def test_no_admin_connect(self): + response = self.collector.get_vapp_details_rest('') + self.assertDictEqual(response, {}, 'Failed to connect should return empty dictionary') + + def test_no_id(self): + response = self.collector.get_vapp_details_rest() + self.assertDictEqual(response, {}, 'No id supplied should return empty dictionary') + + @mock.patch('osm_mon.collector.vnf_collectors.vmware.Client') + def test_get_vapp_details_404(self, mock_vcd_client): + mock_vcd_client.return_value._session.headers = {'x-vcloud-authorization': ''} + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + site='https://vcd', + url_pattern='/api/vApp/.*', + response_file='404.txt', status_code=404) + response = self.collector.get_vapp_details_rest('') + self.assertDictEqual(response, {}, 'HTTP error should return empty dictionary') + + @mock.patch('osm_mon.collector.vnf_collectors.vmware.Client') + def test_get_vapp_details_xml_parse_error(self, mock_vcd_client): + mock_vcd_client.return_value._session.headers = {'x-vcloud-authorization': ''} + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + site='https://vcd', + url_pattern='/api/vApp/.*', + response_file='404.txt') + response = self.collector.get_vapp_details_rest('') + self.assertDictEqual(response, {}, 'XML parse error should return empty dictionary') - def test_collect_unkown_metric(self, mock_vm_moref_id, mock_vm_resource_id): - mock_vm_moref_id.return_value = "moref" - mock_vm_resource_id.return_value = "resource" +class Get_VM_Moref_Test(TestCase): - self.vnfd['vdu'][0]['monitoring-param'] = [ - {'id': 'cirros_vnfd-Unknown_Metric', 'nfvi-metric': 'unknown'}, - ] - self.mock_db.return_value.get_vnfd.return_value = self.vnfd + @mock.patch.object(VMwareCollector, 'get_vim_account', + spec_set=True, autospec=True) + @mock.patch('osm_mon.collector.vnf_collectors.vmware.CommonDbClient') + def setUp(self, mock_db, mock_get_vim_account): + super().setUp() + self.mock_db = mock_db + mock_get_vim_account.return_value = VIM_ACCOUNT + self.collector = VMwareCollector(Config(), "9de6df67-b820-48c3-bcae-ee4838c5c5f4") - with requests_mock.Mocker() as mock_requests: - mock_vdc_response(mock_requests, - url_pattern='/suite-api/api/resources/stats.*', - response_file='vrops_multi.json') - metrics = self.collector.collect(self.vnfr) - self.assertEqual(len(metrics), 0, "Number of metrics returned") + def tearDown(self): + super().tearDown() - def test_collect_vrops_error(self, mock_vm_moref_id, mock_vm_resource_id): + @mock.patch.object(VMwareCollector, 'get_vapp_details_rest', + spec_set=True, autospec=True) + def test_get_vm_moref_id(self, mock_vapp_details): + mock_vapp_details.return_value = {'vm_vcenter_info': {'vm_moref_id': 'vm-4055'}} + response = self.collector.get_vm_moref_id('1234') + self.assertEqual(response, 'vm-4055', 'Did not fetch correct ref id from dictionary') - mock_vm_moref_id.return_value = "moref" - mock_vm_resource_id.return_value = "resource" - self.mock_db.return_value.get_vnfd.return_value = self.vnfd + @mock.patch.object(VMwareCollector, 'get_vapp_details_rest', + spec_set=True, autospec=True) + def test_get_vm_moref_bad_content(self, mock_vapp_details): + mock_vapp_details.return_value = {} + response = self.collector.get_vm_moref_id('1234') + self.assertEqual(response, None, 'Error fetching vapp details should return None') - with requests_mock.Mocker(): - metrics = self.collector.collect(self.vnfr) - self.assertEqual(len(metrics), 0, "Number of metrics returned") + @mock.patch.object(VMwareCollector, 'get_vapp_details_rest', + spec_set=True, autospec=True) + def test_get_vm_moref_has_exception(self, mock_vapp_details): + mock_vapp_details.side_effect = Exception('Testing') + response = self.collector.get_vm_moref_id('1234') + self.assertEqual(response, None, 'Exception while fetching vapp details should return None') 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 new file mode 100644 index 0000000..215bd53 --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vio_collector.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +# # +# 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 +# # + +from osm_mon.collector.vnf_collectors.vio import VIOCollector +from osm_mon.core.config import Config +from osm_mon.tests.unit.collector.vnf_collectors.vmware.mock_http import mock_http_response +from unittest import TestCase, mock + +import json +import os +import requests_mock + +VIM_ACCOUNT = {"vrops_site": "https://vrops", + "vrops_user": "", + "vrops_password": "", + "vim_url": "", + "admin_username": "", + "admin_password": "", + "vim_uuid": ""} + + +class CollectorTest(TestCase): + + @mock.patch.object(VIOCollector, 'get_vim_account', + spec_set=True, autospec=True) + @mock.patch('osm_mon.collector.vnf_collectors.vio.CommonDbClient') + def setUp(self, mock_db, mock_get_vim_account): + super().setUp() + self.mock_db = mock_db + mock_get_vim_account.return_value = VIM_ACCOUNT + self.collector = VIOCollector(Config(), "9de6df67-b820-48c3-bcae-ee4838c5c5f4") + with open(os.path.join(os.path.dirname(__file__), 'osm_mocks', 'VNFR.json'), 'r') as f: + self.vnfr = json.load(f) + with open(os.path.join(os.path.dirname(__file__), 'osm_mocks', 'VNFD.json'), 'r') as f: + self.vnfd = json.load(f) + + def tearDown(self): + super().tearDown() + + def test_collect_cpu_and_memory(self): + self.vnfd['vdu'][0]['monitoring-param'] = [ + {"id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization"}, + {"id": "ubuntu_vnfd-VM_average_memory_utilization", "nfvi-metric": "average_memory_utilization"} + ] + self.mock_db.return_value.get_vnfd.return_value = self.vnfd + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + metrics = self.collector.collect(self.vnfr) + self.assertEqual(len(metrics), 4, "Number of metrics returned") + self.assertEqual(metrics[0].name, "cpu_utilization", "First metric name") + self.assertEqual(metrics[0].value, 100.0, "CPU metric value") + self.assertEqual(metrics[1].name, "average_memory_utilization", "Second metric name") + self.assertEqual(metrics[1].value, 20.515941619873047, "Memory metric value") + self.assertEqual(metrics[2].name, "cpu_utilization", "First metric name") + self.assertEqual(metrics[2].value, 0.05400000140070915, "CPU metric value") + self.assertEqual(metrics[3].name, "average_memory_utilization", "Second metric name") + self.assertEqual(metrics[3].value, 15.23439884185791, "Memory metric value") + + def test_collect_no_monitoring_param(self): + 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, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + metrics = self.collector.collect(self.vnfr) + self.assertEqual(len(metrics), 0, "Number of metrics returned") + + def test_collect_empty_monitoring_param(self): + 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, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + metrics = self.collector.collect(self.vnfr) + self.assertEqual(len(metrics), 0, "Number of metrics returned") + + def test_collect_no_name(self): + del self.vnfr['vdur'][0]['name'] + 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, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + metrics = self.collector.collect(self.vnfr) + self.assertEqual(len(metrics), 0, "Number of metrics returned") 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 new file mode 100644 index 0000000..956a19f --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/test_vrops_helper.py @@ -0,0 +1,263 @@ +# -*- coding: utf-8 -*- +# # +# 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 +# # + +from osm_mon.collector.vnf_collectors.vrops.vrops_helper import vROPS_Helper +from osm_mon.tests.unit.collector.vnf_collectors.vmware.mock_http import mock_http_response +from unittest import TestCase + +import json +import os +import requests_mock + + +class vROPS_Helper_Resource_List_Test(TestCase): + + def setUp(self): + super().setUp() + self.vrops = vROPS_Helper() + + def tearDown(self): + super().tearDown() + + def test_get_vm_resource_list_from_vrops(self): + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='vrops_resources.json') + resource_list = self.vrops.get_vm_resource_list_from_vrops() + self.assertEqual(len(resource_list), 3, "List of resources from canned vrops_resources.json") + + def test_get_vm_resource_list_from_vrops_http_404(self): + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='404.txt', status_code=404) + resource_list = self.vrops.get_vm_resource_list_from_vrops() + self.assertEqual(len(resource_list), 0, "Should return an empty list") + + def test_get_vm_resource_list_from_vrops_bad_json(self): + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources\\?resourceKind=VirtualMachine', + response_file='malformed.json') + resource_list = self.vrops.get_vm_resource_list_from_vrops() + self.assertEqual(len(resource_list), 0, "Should return an empty list") + + +class vROPS_Helper_Get_Metrics_Test(TestCase): + + def setUp(self): + super().setUp() + self.vrops = vROPS_Helper() + with open(os.path.join(os.path.dirname(__file__), 'osm_mocks', 'VNFR.json'), 'r') as f: + self.vnfr = json.load(f) + + def tearDown(self): + super().tearDown() + + def test_collect_one_metric_only(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', + 'vrops_id': 'VROPS-UUID-1'}} + monitoring_params = [ + {"id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization"}, + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + self.assertEqual(len(metrics), 1, "Number of metrics returned") + self.assertEqual(metrics[0].name, "cpu_utilization", "First metric name") + self.assertEqual(metrics[0].value, 100.0, "CPU metric value") + + def test_collect_cpu_and_memory(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', + 'vrops_id': 'VROPS-UUID-1'}} + monitoring_params = [ + {"id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization"}, + {"id": "ubuntu_vnfd-VM_average_memory_utilization", "nfvi-metric": "average_memory_utilization"} + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), 2, "Number of metrics returned") + self.assertEqual(metrics[0].name, "cpu_utilization", "First metric name") + self.assertEqual(metrics[0].value, 100.0, "CPU metric value") + self.assertEqual(metrics[1].name, "average_memory_utilization", "Second metric name") + self.assertEqual(metrics[1].value, 20.515941619873047, "Memory metric value") + + def test_collect_adjusted_metric(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', + 'vrops_id': 'VROPS-UUID-1'}} + monitoring_params = [ + {'id': 'ubuntu_vnfd-VM_cpu_util', 'nfvi-metric': 'disk_read_bytes'} + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), 1, "Number of metrics returned") + self.assertEqual(metrics[0].name, "disk_read_bytes", "First metric name") + self.assertEqual(metrics[0].value, 10240.0, "Disk read bytes (not KB/s)") + + def test_collect_not_provided_metric(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', + 'vrops_id': 'VROPS-UUID-1'}} + monitoring_params = [ + {'id': 'cirros_vnfd-VM_packets_sent', 'nfvi-metric': 'packets_in_dropped'}, + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), 0, "Number of metrics returned") + + def test_collect_unkown_metric(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', + 'vrops_id': 'VROPS-UUID-1'}} + monitoring_params = [ + {'id': 'cirros_vnfd-Unknown_Metric', 'nfvi-metric': 'unknown'}, + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), 0, "Number of metrics returned") + + def test_collect_vrops_no_data(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', + 'vrops_id': 'VROPS-UUID-1'}} + monitoring_params = [ + {"id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization"}, + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='OK.json') + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), 0, "Number of metrics returned") + + def test_collect_vrops_unknown_vim_id(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2'}} + monitoring_params = [ + {"id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization"}, + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), 0, "Number of metrics returned") + + def test_collect_vrops_http_error(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', + 'vrops_id': 'VROPS-UUID-1'}} + monitoring_params = [ + {"id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization"}, + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='404.txt', status_code=404) + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), 0, "Number of metrics returned") + + def test_collect_vrops_json_parse_error(self): + vdu_mappings = {'VMWARE-OID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', + 'vrops_id': 'VROPS-UUID-1'}} + monitoring_params = [ + {"id": "ubuntu_vnfd-VM_cpu_util", "nfvi-metric": "cpu_utilization"}, + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='404.txt') + + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), 0, "Number of metrics returned") + + def test_collect_multi_vdu(self): + vdu_mappings = {'VMWARE-UUID-VM-1': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-1', 'vrops_id': 'VROPS-UUID-1'}, + 'VMWARE-UUID-VM-2': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', 'vrops_id': 'VROPS-UUID-2'}, + 'VMWARE-UUID-VM-3': + {'name': 'vmware-scaling-1-ubuntu_vnfd-VM-2', 'vrops_id': 'VROPS-UUID-3'} + } + monitoring_params = [ + {'id': 'ubuntu_vnfd-VM_cpu_util', 'nfvi-metric': 'cpu_utilization'}, + {'id': 'ubuntu_vnfd-VM_average_memory_utilization', 'nfvi-metric': 'average_memory_utilization'}, + {'id': 'ubuntu_vnfd-VM_disk_read_ops', 'nfvi-metric': 'disk_read_ops'}, + {'id': 'ubuntu_vnfd-VM_disk_write_ops', 'nfvi-metric': 'disk_write_ops'}, + {'id': 'ubuntu_vnfd-VM_disk_read_bytes', 'nfvi-metric': 'disk_read_bytes'}, + {'id': 'ubuntu_vnfd-VM_disk_write_bytes', 'nfvi-metric': 'disk_write_bytes'}, + {'id': 'ubuntu_vnfd-VM_packets_out_dropped', 'nfvi-metric': 'packets_out_dropped'}, + {'id': 'ubuntu_vnfd-VM_packets_received', 'nfvi-metric': 'packets_received'}, + {'id': 'ubuntu_vnfd-VM_packets_sent', 'nfvi-metric': 'packets_sent'} + ] + + with requests_mock.Mocker() as mock_requests: + mock_http_response(mock_requests, + url_pattern='/suite-api/api/resources/stats.*', + response_file='vrops_multi.json') + metrics = self.vrops.get_metrics(vdu_mappings, monitoring_params, self.vnfr) + + self.assertEqual(len(metrics), len(monitoring_params) * len(vdu_mappings), "Number of metrics returned") diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vcd_mocks/OK.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vcd_mocks/OK.json deleted file mode 100644 index 0967ef4..0000000 --- a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vcd_mocks/OK.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vcd_mocks/vrops_multi.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vcd_mocks/vrops_multi.json deleted file mode 100644 index 95b0305..0000000 --- a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vcd_mocks/vrops_multi.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "values": [ - { - "resourceId": "a761f4ae-40a3-4696-ae37-ee447ed421c3", - "stat-list": { - "stat": [ - { - "data": [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "virtualDisk:aggregate of all instances|totalReadLatency_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 1.1373332738876343, - 1.1440000534057617, - 1.1239999532699585, - 100.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "cpu|usage_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 6.0, - 6.066666603088379, - 6.133333206176758, - 6.066666603088379 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "virtualDisk:aggregate of all instances|numberWriteAveraged_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "virtualDisk:aggregate of all instances|numberReadAveraged_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "net|droppedTx_summation" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 10.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "virtualDisk|read_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "net|transmitted_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 20.491540908813477, - 20.505388259887695, - 20.517423629760742, - 20.515941619873047 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "mem|usage_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "virtualDisk:aggregate of all instances|totalWriteLatency_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 46.266666412353516, - 46.599998474121094, - 46.93333435058594, - 46.86666488647461 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "virtualDisk|write_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "net|received_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - }, - { - "data": [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - "intervalUnit": { - "quantifier": 1 - }, - "statKey": { - "key": "net:vmnic5|transmitted_average" - }, - "timestamps": [ - 1561744712552, - 1561744772549, - 1561744832548, - 1561744892557 - ] - } - ] - } - } - ] -} diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/404.txt b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/404.txt new file mode 100644 index 0000000..4e38daa --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/404.txt @@ -0,0 +1,20 @@ +404 NOT FOUND + + 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 diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/OK.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/OK.json new file mode 100644 index 0000000..cad20b3 --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/OK.json @@ -0,0 +1,3 @@ +{ + "_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" +} diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/malformed.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/malformed.json new file mode 100644 index 0000000..9b3bf23 --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/malformed.json @@ -0,0 +1,22 @@ +{ + This is not valid JSON + + 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 +} diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vcd_vapp_response.xml b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vcd_vapp_response.xml new file mode 100644 index 0000000..5b1fd54 --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vcd_vapp_response.xml @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + Vapp instantiation + + Lease settings section + + 604800 + 172800 + 2019-07-31T21:22:09.915Z + + + VApp startup section + + + + + The list of logical networks + + + + + + The configuration parameters for logical networks + + + + + + dvportgroup-956 + DV_PORTGROUP + + + + + + + + true + 172.21.6.130 + 255.255.255.128 + 25 + 172.21.6.10 + corp.local + true + + +172.21.6.175 +172.21.6.198 + + + + + + bridged + false + + true + + + + Snapshot information section + + 2019-07-24T21:20:41.929Z + + + + false + false + + + + + + + vm-4055 + VIRTUAL_MACHINE + + + + datastore-936 + DATASTORE + + + + datastore-936 + DATASTORE + + + + host-13 + HOST + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Virtual hardware requirements + + + + + + + + + + + + + + + Virtual Hardware Family + + 0 + + + + + + ubuntu + vmx-14 + + + 00:50:56:03:01:86 + 0 + + true + + + + + vnf-mgmt + + Vmxnet3 ethernet adapter on "vnf-mgmt" + Network adapter 0 + + 1 + + + + + + + VMXNET3 + 10 + + + + + + 0 + + + + + + + + + SCSI Controller + SCSI Controller 0 + + 2 + + + + + + + lsilogic + 6 + + + + + + + 0 + + + + + + + + Hard disk + Hard disk 1 + + + 2000 + + + + 2 + + + + 17 + 17179869184 + byte + + + + 0 + + + + + + + + + SATA Controller + SATA Controller 0 + + 3 + + + + + + + vmware.sata.ahci + 20 + + + + + + + 0 + + false + + + + + + CD/DVD Drive + CD/DVD Drive 1 + + + 16000 + + + + 3 + + + + 15 + + + + + + + + hertz * 10^6 + + + + + + + Number of Virtual CPUs + 1 virtual CPU(s) + + 4 + + + + + + 0 + + 3 + 1 + + 1000 + 1 + + + + + + byte * 2^20 + + + + + + + Memory Size + 1024 MB of memory + + 5 + + + + + + 0 + + 4 + 1024 + + 10240 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Specifies the operating system installed + Ubuntu Linux (64-bit) + + + + Specifies the available VM network connections + 0 + + 0 + 172.21.6.214 + true + 00:50:56:03:01:86 + DHCP + VMXNET3 + + + + + Specifies Guest OS Customization Settings + true + false + a1022e38-05e9-404d-b6ff-d6b896cec1bc + false + false + false + true + false + 0 + false + ubuntu-001 + + + + + + Specifies Runtime info + + + + Snapshot information section + + 2019-07-24T21:20:47.602Z + ubuntu + + + VMware ESXi + 6.7.0 + VMware, Inc. + en + + + + + + + + + + + + + + + + + + + + false + false + + + + + 0 + false + + + + diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_multi.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_multi.json new file mode 100644 index 0000000..e11179f --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_multi.json @@ -0,0 +1,1490 @@ +{ + "_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", + "values": [ + { + "resourceId": "VROPS-UUID-1", + "stat-list": { + "stat": [ + { + "data": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:aggregate of all instances|totalReadLatency_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 1.1373332738876343, + 1.1440000534057617, + 1.1239999532699585, + 100.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "cpu|usage_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 6.0, + 6.066666603088379, + 6.133333206176758, + 6.066666603088379 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:aggregate of all instances|numberWriteAveraged_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:aggregate of all instances|numberReadAveraged_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|droppedTx_summation" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 10.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk|read_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|transmitted_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 20.491540908813477, + 20.505388259887695, + 20.517423629760742, + 20.515941619873047 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "mem|usage_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:aggregate of all instances|totalWriteLatency_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 46.266666412353516, + 46.599998474121094, + 46.93333435058594, + 46.86666488647461 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk|write_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|received_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic5|transmitted_average" + }, + "timestamps": [ + 1561744712552, + 1561744772549, + 1561744832548, + 1561744892557 + ] + } + ] + } + }, + { + "resourceId": "VROPS-UUID-2", + "stat-list": { + "stat": [ + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic4|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic0|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic9|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic5|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.05400000140070915, + 0.05533333495259285, + 0.05400000140070915 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "cpu|usage_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic9|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:scsi0:0|read_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:aggregate of all instances|numberWriteAveraged_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic6|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic1|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:scsi0:0|write_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic2|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic7|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:aggregate of all instances|numberReadAveraged_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic2|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:4000|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic7|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic8|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic0|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|droppedTx_summation" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic5|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk|read_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic3|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic3|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 15.234436988830566, + 15.23439884185791, + 15.23439884185791 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "mem|usage_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk|write_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:4000|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:4000|droppedTx_summation" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic8|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic1|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic4|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic6|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + } + ] + } + }, + { + "resourceId": "VROPS-UUID-3", + "stat-list": { + "stat": [ + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic4|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic0|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic9|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic5|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0560000017285347, + 0.05400000140070915, + 0.052666667848825455 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "cpu|usage_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic9|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:scsi0:0|read_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:aggregate of all instances|numberWriteAveraged_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic6|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic1|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:scsi0:0|write_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic2|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic7|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk:aggregate of all instances|numberReadAveraged_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic2|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:4000|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic7|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic8|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic0|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|droppedTx_summation" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic5|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk|read_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic3|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic3|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 15.244717597961426, + 15.244698524475098, + 15.24467945098877 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "mem|usage_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "virtualDisk|write_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:4000|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:4000|droppedTx_summation" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic8|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic1|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic4|received_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + }, + { + "data": [ + 0.0, + 0.0, + 0.0 + ], + "intervalUnit": { + "quantifier": 1 + }, + "statKey": { + "key": "net:vmnic6|transmitted_average" + }, + "timestamps": [ + 1563301072756, + 1563301132765, + 1563301192756 + ] + } + ] + } + } + ] +} diff --git a/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_resources.json b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_resources.json new file mode 100644 index 0000000..1165740 --- /dev/null +++ b/osm_mon/tests/unit/collector/vnf_collectors/vmware/vmware_mocks/vrops_resources.json @@ -0,0 +1,447 @@ +{ + "_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", + "links": [ + { + "href": "/suite-api/api/resources?resourceKind=VirtualMachine&page=0&pageSize=1000", + "name": "current", + "rel": "SELF" + }, + { + "href": "/suite-api/api/resources?resourceKind=VirtualMachine&page=0&pageSize=1000", + "name": "first", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources?resourceKind=VirtualMachine&page=0&pageSize=1000", + "name": "last", + "rel": "RELATED" + } + ], + "pageInfo": { + "page": 0, + "pageSize": 1000, + "totalCount": 130 + }, + "resourceList": [ + { + "badges": [ + { + "color": "GREEN", + "score": 0.0, + "type": "RISK" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "CAPACITY_REMAINING" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "EFFICIENCY" + }, + { + "color": "GREEN", + "score": 0.0, + "type": "WORKLOAD" + }, + { + "color": "GREEN", + "score": 366.0, + "type": "TIME_REMAINING" + }, + { + "color": "GREY", + "score": -1.0, + "type": "COMPLIANCE" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "HEALTH" + } + ], + "creationTime": 1559557138756, + "dtEnabled": true, + "identifier": "VROPS-UUID-1", + "links": [ + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "linkToSelf", + "rel": "SELF" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/relationships", + "name": "relationsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/properties", + "name": "propertiesOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/alerts?resourceId=01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "alertsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/symptoms?resourceId=01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "symptomsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/statkeys", + "name": "statKeysOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/stats/latest", + "name": "latestStatsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/properties", + "name": "latestPropertiesOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/credentials/", + "name": "credentialsOfResource", + "rel": "RELATED" + } + ], + "relatedResources": [ + ], + "resourceHealth": "GREEN", + "resourceHealthValue": 100.0, + "resourceKey": { + "adapterKindKey": "VMWARE", + "name": "52a28e3c-4e5b-4408-b8e3-7755a4222774-vc-HNILML", + "resourceIdentifiers": [ + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": false, + "name": "VMEntityInstanceUUID" + }, + "value": "VMWARE-UUID-VM-1" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": false, + "name": "VMEntityName" + }, + "value": "52a28e3c-4e5b-4408-b8e3-7755a4222774-vc-HNILML" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": true, + "name": "VMEntityObjectID" + }, + "value": "VMWARE-OID-VM-1" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": true, + "name": "VMEntityVCID" + }, + "value": "1ec8501f-dce7-4e0b-8f8b-19ba7060d33c" + } + ], + "resourceKindKey": "VirtualMachine" + }, + "resourceStatusStates": [ + { + "adapterInstanceId": "fcf7ba35-72f0-4d36-a12d-45a0c4065e17", + "resourceState": "STARTED", + "resourceStatus": "DATA_RECEIVING", + "statusMessage": "" + } + ] + }, + { + "badges": [ + { + "color": "GREEN", + "score": 0.0, + "type": "RISK" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "CAPACITY_REMAINING" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "EFFICIENCY" + }, + { + "color": "GREEN", + "score": 0.0, + "type": "WORKLOAD" + }, + { + "color": "GREEN", + "score": 366.0, + "type": "TIME_REMAINING" + }, + { + "color": "GREY", + "score": -1.0, + "type": "COMPLIANCE" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "HEALTH" + } + ], + "creationTime": 1559557138756, + "dtEnabled": true, + "identifier": "VROPS-UUID-2", + "links": [ + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "linkToSelf", + "rel": "SELF" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/relationships", + "name": "relationsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/properties", + "name": "propertiesOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/alerts?resourceId=01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "alertsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/symptoms?resourceId=01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "symptomsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/statkeys", + "name": "statKeysOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/stats/latest", + "name": "latestStatsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/properties", + "name": "latestPropertiesOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/credentials/", + "name": "credentialsOfResource", + "rel": "RELATED" + } + ], + "relatedResources": [ + ], + "resourceHealth": "GREEN", + "resourceHealthValue": 100.0, + "resourceKey": { + "adapterKindKey": "VMWARE", + "name": "52a28e3c-4e5b-4408-b8e3-7755a4222774-vc-HNILML", + "resourceIdentifiers": [ + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": false, + "name": "VMEntityInstanceUUID" + }, + "value": "VMWARE-UUID-VM-2" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": false, + "name": "VMEntityName" + }, + "value": "52a28e3c-4e5b-4408-b8e3-7755a4222774-vc-HNILML" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": true, + "name": "VMEntityObjectID" + }, + "value": "VMWARE-OID-VM-2" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": true, + "name": "VMEntityVCID" + }, + "value": "1ec8501f-dce7-4e0b-8f8b-19ba7060d33c" + } + ], + "resourceKindKey": "VirtualMachine" + }, + "resourceStatusStates": [ + { + "adapterInstanceId": "fcf7ba35-72f0-4d36-a12d-45a0c4065e17", + "resourceState": "STARTED", + "resourceStatus": "DATA_RECEIVING", + "statusMessage": "" + } + ] + }, + { + "badges": [ + { + "color": "GREEN", + "score": 0.0, + "type": "RISK" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "CAPACITY_REMAINING" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "EFFICIENCY" + }, + { + "color": "GREEN", + "score": 0.0, + "type": "WORKLOAD" + }, + { + "color": "GREEN", + "score": 366.0, + "type": "TIME_REMAINING" + }, + { + "color": "GREY", + "score": -1.0, + "type": "COMPLIANCE" + }, + { + "color": "GREEN", + "score": 100.0, + "type": "HEALTH" + } + ], + "creationTime": 1559557138756, + "dtEnabled": true, + "identifier": "VROPS-UUID-3", + "links": [ + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "linkToSelf", + "rel": "SELF" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/relationships", + "name": "relationsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/properties", + "name": "propertiesOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/alerts?resourceId=01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "alertsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/symptoms?resourceId=01ffd926-f8eb-4153-bb59-4d3da4ce7982", + "name": "symptomsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/statkeys", + "name": "statKeysOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/stats/latest", + "name": "latestStatsOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/resources/01ffd926-f8eb-4153-bb59-4d3da4ce7982/properties", + "name": "latestPropertiesOfResource", + "rel": "RELATED" + }, + { + "href": "/suite-api/api/credentials/", + "name": "credentialsOfResource", + "rel": "RELATED" + } + ], + "relatedResources": [ + ], + "resourceHealth": "GREEN", + "resourceHealthValue": 100.0, + "resourceKey": { + "adapterKindKey": "VMWARE", + "name": "52a28e3c-4e5b-4408-b8e3-7755a4222774-vc-HNILML", + "resourceIdentifiers": [ + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": false, + "name": "VMEntityInstanceUUID" + }, + "value": "VMWARE-UUID-VM-3" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": false, + "name": "VMEntityName" + }, + "value": "52a28e3c-4e5b-4408-b8e3-7755a4222774-vc-HNILML" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": true, + "name": "VMEntityObjectID" + }, + "value": "VMWARE-OID-VM-3" + }, + { + "identifierType": { + "dataType": "STRING", + "isPartOfUniqueness": true, + "name": "VMEntityVCID" + }, + "value": "1ec8501f-dce7-4e0b-8f8b-19ba7060d33c" + } + ], + "resourceKindKey": "VirtualMachine" + }, + "resourceStatusStates": [ + { + "adapterInstanceId": "fcf7ba35-72f0-4d36-a12d-45a0c4065e17", + "resourceState": "STARTED", + "resourceStatus": "DATA_RECEIVING", + "statusMessage": "" + } + ] + } + ] +}