Fix pylint issues appeared with version 3.2.0 of pylint
[osm/MON.git] / osm_mon / collector / vnf_collectors / vrops / vrops_helper.py
1 # -*- coding: utf-8 -*-
2
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 # #
23
24 import logging
25 import json
26 import requests
27 import traceback
28
29 from osm_mon.collector.vnf_metric import VnfMetric
30 from osm_mon.collector.vnf_collectors.vrops.metrics import METRIC_MAPPINGS
31 import copy
32
33 log = logging.getLogger(__name__)
34
35
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.
38 METRIC_MULTIPLIERS = {
39 "disk_read_bytes": 1024,
40 "disk_write_bytes": 1024,
41 "packets_received": 1024,
42 "packets_sent": 1024,
43 }
44
45
46 class 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
58
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
77
78 resp_data = json.loads(resp.content.decode("utf-8"))
79 return resp_data["token"]
80
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 = []
90
91 resp = requests.get(
92 self.vrops_site + api_url, verify=self.verify_ssl, headers=headers
93 )
94
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
102
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")
107
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 )
114
115 return resource_list
116
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]
126
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)
132
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
144
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&currentOnly=true{}{}".format(stats_key, resource_ids)
150 )
151
152 auth_token = self.get_vrops_token()
153 headers = {
154 "Accept": "application/json",
155 "Authorization": "vRealizeOpsToken {}".format(auth_token),
156 }
157
158 resp = requests.get(
159 self.vrops_site + api_url, verify=self.verify_ssl, headers=headers
160 )
161
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
169
170 m_data = json.loads(resp.content.decode("utf-8"))
171 if "values" not in m_data:
172 return metrics
173
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
187
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 )
204
205 metrics.append(metric)
206
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 )
213
214 return metrics