Coverage for osm_mon/collector/vnf_collectors/vrops/vrops_helper.py: 98%
97 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-05-06 19:04 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-05-06 19:04 +0000
1# -*- coding: utf-8 -*-
3# #
4# Copyright 2016-2019 VMware Inc.
5# This file is part of ETSI OSM
6# All Rights Reserved.
7#
8# Licensed under the Apache License, Version 2.0 (the "License"); you may
9# not use this file except in compliance with the License. You may obtain
10# a copy of the License at
11#
12# http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing, software
15# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17# License for the specific language governing permissions and limitations
18# under the License.
19#
20# For those usages not covered by the Apache License, Version 2.0 please
21# contact: osslegalrouting@vmware.com
22# #
24import logging
25import json
26import requests
27import traceback
29from osm_mon.collector.vnf_metric import VnfMetric
30from osm_mon.collector.vnf_collectors.vrops.metrics import METRIC_MAPPINGS
31import copy
33log = logging.getLogger(__name__)
36# If the unit from vROPS does not align with the expected value. multiply by the specified amount to ensure
37# the correct unit is returned.
38METRIC_MULTIPLIERS = {
39 "disk_read_bytes": 1024,
40 "disk_write_bytes": 1024,
41 "packets_received": 1024,
42 "packets_sent": 1024,
43}
46class vROPS_Helper:
47 def __init__(
48 self,
49 vrops_site="https://vrops",
50 vrops_user="",
51 vrops_password="",
52 verify_ssl=False,
53 ):
54 self.vrops_site = vrops_site
55 self.vrops_user = vrops_user
56 self.vrops_password = vrops_password
57 self.verify_ssl = verify_ssl
59 def get_vrops_token(self):
60 """Fetches token from vrops"""
61 auth_url = "/suite-api/api/auth/token/acquire"
62 headers = {"Content-Type": "application/json", "Accept": "application/json"}
63 req_body = {"username": self.vrops_user, "password": self.vrops_password}
64 resp = requests.post(
65 self.vrops_site + auth_url,
66 json=req_body,
67 verify=self.verify_ssl,
68 headers=headers,
69 )
70 if resp.status_code != 200:
71 log.error(
72 "Failed to get token from vROPS: {} {}".format(
73 resp.status_code, resp.content
74 )
75 )
76 return None
78 resp_data = json.loads(resp.content.decode("utf-8"))
79 return resp_data["token"]
81 def get_vm_resource_list_from_vrops(self):
82 """Find all known resource IDs in vROPs"""
83 auth_token = self.get_vrops_token()
84 api_url = "/suite-api/api/resources?resourceKind=VirtualMachine"
85 headers = {
86 "Accept": "application/json",
87 "Authorization": "vRealizeOpsToken {}".format(auth_token),
88 }
89 resource_list = []
91 resp = requests.get(
92 self.vrops_site + api_url, verify=self.verify_ssl, headers=headers
93 )
95 if resp.status_code != 200:
96 log.error(
97 "Failed to get resource list from vROPS: {} {}".format(
98 resp.status_code, resp.content
99 )
100 )
101 return resource_list
103 try:
104 resp_data = json.loads(resp.content.decode("utf-8"))
105 if resp_data.get("resourceList") is not None:
106 resource_list = resp_data.get("resourceList")
108 except Exception as exp:
109 log.error(
110 "get_vm_resource_id: Error in parsing {}\n{}".format(
111 exp, traceback.format_exc()
112 )
113 )
115 return resource_list
117 def get_metrics(self, vdu_mappings={}, monitoring_params={}, vnfr=None, tags={}):
118 monitoring_keys = {}
119 # Collect the names of all the metrics we need to query
120 for metric_entry in monitoring_params:
121 metric_name = metric_entry["performance-metric"]
122 if metric_name not in METRIC_MAPPINGS:
123 log.debug("Metric {} not supported, ignoring".format(metric_name))
124 continue
125 monitoring_keys[metric_name] = METRIC_MAPPINGS[metric_name]
127 metrics = []
128 # Make a query for only the stats we have been asked for
129 stats_key = ""
130 for stat in monitoring_keys.values():
131 stats_key += "&statKey={}".format(stat)
133 # And only ask for the resource ids that we are interested in
134 resource_ids = ""
135 sanitized_vdu_mappings = copy.deepcopy(vdu_mappings)
136 for key in vdu_mappings.keys():
137 vdu = vdu_mappings[key]
138 if "vrops_id" not in vdu:
139 log.info("Could not find vROPS id for vdu {}".format(vdu))
140 del sanitized_vdu_mappings[key]
141 continue
142 resource_ids += "&resourceId={}".format(vdu["vrops_id"])
143 vdu_mappings = sanitized_vdu_mappings
145 try:
146 # Now we can make a single call to vROPS to collect all relevant metrics for resources we need to monitor
147 api_url = (
148 "/suite-api/api/resources/stats?IntervalType=MINUTES&IntervalCount=1"
149 "&rollUpType=MAX¤tOnly=true{}{}".format(stats_key, resource_ids)
150 )
152 auth_token = self.get_vrops_token()
153 headers = {
154 "Accept": "application/json",
155 "Authorization": "vRealizeOpsToken {}".format(auth_token),
156 }
158 resp = requests.get(
159 self.vrops_site + api_url, verify=self.verify_ssl, headers=headers
160 )
162 if resp.status_code != 200:
163 log.error(
164 "Failed to get Metrics data from vROPS for {} {}".format(
165 resp.status_code, resp.content
166 )
167 )
168 return metrics
170 m_data = json.loads(resp.content.decode("utf-8"))
171 if "values" not in m_data:
172 return metrics
174 statistics = m_data["values"]
175 for vdu_stat in statistics:
176 vrops_id = vdu_stat["resourceId"]
177 vdu_name = None
178 for vdu in vdu_mappings.values():
179 if vdu["vrops_id"] == vrops_id:
180 vdu_name = vdu["name"]
181 if vdu_name is None:
182 continue
183 for item in vdu_stat["stat-list"]["stat"]:
184 reported_metric = item["statKey"]["key"]
185 if reported_metric not in METRIC_MAPPINGS.values():
186 continue
188 # Convert the vROPS metric name back to OSM key
189 metric_name = list(METRIC_MAPPINGS.keys())[
190 list(METRIC_MAPPINGS.values()).index(reported_metric)
191 ]
192 if metric_name in monitoring_keys.keys():
193 metric_value = item["data"][-1]
194 if metric_name in METRIC_MULTIPLIERS:
195 metric_value *= METRIC_MULTIPLIERS[metric_name]
196 metric = VnfMetric(
197 vnfr["nsr-id-ref"],
198 vnfr["member-vnf-index-ref"],
199 vdu_name,
200 metric_name,
201 metric_value,
202 tags,
203 )
205 metrics.append(metric)
207 except Exception as exp:
208 log.error(
209 "Exception while parsing metrics data from vROPS {}\n{}".format(
210 exp, traceback.format_exc()
211 )
212 )
214 return metrics