1 # -*- coding: utf-8 -*-
4 # Copyright 2016-2019 VMware Inc.
5 # This file is part of ETSI OSM
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
12 # http://www.apache.org/licenses/LICENSE-2.0
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
20 # For those usages not covered by the Apache License, Version 2.0 please
21 # contact: osslegalrouting@vmware.com
29 from osm_mon
.collector
.vnf_metric
import VnfMetric
30 from osm_mon
.collector
.vnf_collectors
.vrops
.metrics
import METRIC_MAPPINGS
33 log
= 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.
38 METRIC_MULTIPLIERS
= {
39 "disk_read_bytes": 1024,
40 "disk_write_bytes": 1024,
41 "packets_received": 1024,
49 vrops_site
="https://vrops",
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
}
65 self
.vrops_site
+ auth_url
,
67 verify
=self
.verify_ssl
,
70 if resp
.status_code
!= 200:
72 "Failed to get token from vROPS: {} {}".format(
73 resp
.status_code
, resp
.content
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"
86 "Accept": "application/json",
87 "Authorization": "vRealizeOpsToken {}".format(auth_token
),
92 self
.vrops_site
+ api_url
, verify
=self
.verify_ssl
, headers
=headers
95 if resp
.status_code
!= 200:
97 "Failed to get resource list from vROPS: {} {}".format(
98 resp
.status_code
, resp
.content
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
:
110 "get_vm_resource_id: Error in parsing {}\n{}".format(
111 exp
, traceback
.format_exc()
117 def get_metrics(self
, vdu_mappings
={}, monitoring_params
={}, vnfr
=None, tags
={}):
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
))
125 monitoring_keys
[metric_name
] = METRIC_MAPPINGS
[metric_name
]
128 # Make a query for only the stats we have been asked for
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
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
]
142 resource_ids
+= "&resourceId={}".format(vdu
["vrops_id"])
143 vdu_mappings
= sanitized_vdu_mappings
146 # Now we can make a single call to vROPS to collect all relevant metrics for resources we need to monitor
148 "/suite-api/api/resources/stats?IntervalType=MINUTES&IntervalCount=1"
149 "&rollUpType=MAX¤tOnly=true{}{}".format(stats_key
, resource_ids
)
152 auth_token
= self
.get_vrops_token()
154 "Accept": "application/json",
155 "Authorization": "vRealizeOpsToken {}".format(auth_token
),
159 self
.vrops_site
+ api_url
, verify
=self
.verify_ssl
, headers
=headers
162 if resp
.status_code
!= 200:
164 "Failed to get Metrics data from vROPS for {} {}".format(
165 resp
.status_code
, resp
.content
170 m_data
= json
.loads(resp
.content
.decode("utf-8"))
171 if "values" not in m_data
:
174 statistics
= m_data
["values"]
175 for vdu_stat
in statistics
:
176 vrops_id
= vdu_stat
["resourceId"]
178 for vdu
in vdu_mappings
.values():
179 if vdu
["vrops_id"] == vrops_id
:
180 vdu_name
= vdu
["name"]
183 for item
in vdu_stat
["stat-list"]["stat"]:
184 reported_metric
= item
["statKey"]["key"]
185 if reported_metric
not in METRIC_MAPPINGS
.values():
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
)
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
]
198 vnfr
["member-vnf-index-ref"],
205 metrics
.append(metric
)
207 except Exception as exp
:
209 "Exception while parsing metrics data from vROPS {}\n{}".format(
210 exp
, traceback
.format_exc()