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,
47 def __init__(self
, vrops_site
="https://vrops", vrops_user
="", vrops_password
=""):
48 self
.vrops_site
= vrops_site
49 self
.vrops_user
= vrops_user
50 self
.vrops_password
= vrops_password
52 def get_vrops_token(self
):
53 """Fetches token from vrops"""
54 auth_url
= "/suite-api/api/auth/token/acquire"
55 headers
= {"Content-Type": "application/json", "Accept": "application/json"}
56 req_body
= {"username": self
.vrops_user
, "password": self
.vrops_password
}
58 self
.vrops_site
+ auth_url
, json
=req_body
, verify
=False, headers
=headers
60 if resp
.status_code
!= 200:
62 "Failed to get token from vROPS: {} {}".format(
63 resp
.status_code
, resp
.content
68 resp_data
= json
.loads(resp
.content
.decode("utf-8"))
69 return resp_data
["token"]
71 def get_vm_resource_list_from_vrops(self
):
72 """Find all known resource IDs in vROPs"""
73 auth_token
= self
.get_vrops_token()
74 api_url
= "/suite-api/api/resources?resourceKind=VirtualMachine"
76 "Accept": "application/json",
77 "Authorization": "vRealizeOpsToken {}".format(auth_token
),
81 resp
= requests
.get(self
.vrops_site
+ api_url
, verify
=False, headers
=headers
)
83 if resp
.status_code
!= 200:
85 "Failed to get resource list from vROPS: {} {}".format(
86 resp
.status_code
, resp
.content
92 resp_data
= json
.loads(resp
.content
.decode("utf-8"))
93 if resp_data
.get("resourceList") is not None:
94 resource_list
= resp_data
.get("resourceList")
96 except Exception as exp
:
98 "get_vm_resource_id: Error in parsing {}\n{}".format(
99 exp
, traceback
.format_exc()
105 def get_metrics(self
, vdu_mappings
={}, monitoring_params
={}, vnfr
=None, tags
={}):
108 # Collect the names of all the metrics we need to query
109 for metric_entry
in monitoring_params
:
110 metric_name
= metric_entry
["performance-metric"]
111 if metric_name
not in METRIC_MAPPINGS
:
112 log
.debug("Metric {} not supported, ignoring".format(metric_name
))
114 monitoring_keys
[metric_name
] = METRIC_MAPPINGS
[metric_name
]
117 # Make a query for only the stats we have been asked for
119 for stat
in monitoring_keys
.values():
120 stats_key
+= "&statKey={}".format(stat
)
122 # And only ask for the resource ids that we are interested in
124 sanitized_vdu_mappings
= copy
.deepcopy(vdu_mappings
)
125 for key
in vdu_mappings
.keys():
126 vdu
= vdu_mappings
[key
]
127 if "vrops_id" not in vdu
:
128 log
.info("Could not find vROPS id for vdu {}".format(vdu
))
129 del sanitized_vdu_mappings
[key
]
131 resource_ids
+= "&resourceId={}".format(vdu
["vrops_id"])
132 vdu_mappings
= sanitized_vdu_mappings
136 # Now we can make a single call to vROPS to collect all relevant metrics for resources we need to monitor
138 "/suite-api/api/resources/stats?IntervalType=MINUTES&IntervalCount=1"
139 "&rollUpType=MAX¤tOnly=true{}{}".format(stats_key
, resource_ids
)
142 auth_token
= self
.get_vrops_token()
144 "Accept": "application/json",
145 "Authorization": "vRealizeOpsToken {}".format(auth_token
),
149 self
.vrops_site
+ api_url
, verify
=False, headers
=headers
152 if resp
.status_code
!= 200:
154 "Failed to get Metrics data from vROPS for {} {}".format(
155 resp
.status_code
, resp
.content
160 m_data
= json
.loads(resp
.content
.decode("utf-8"))
161 if "values" not in m_data
:
164 statistics
= m_data
["values"]
165 for vdu_stat
in statistics
:
166 vrops_id
= vdu_stat
["resourceId"]
168 for vdu
in vdu_mappings
.values():
169 if vdu
["vrops_id"] == vrops_id
:
170 vdu_name
= vdu
["name"]
173 for item
in vdu_stat
["stat-list"]["stat"]:
174 reported_metric
= item
["statKey"]["key"]
175 if reported_metric
not in METRIC_MAPPINGS
.values():
178 # Convert the vROPS metric name back to OSM key
179 metric_name
= list(METRIC_MAPPINGS
.keys())[
180 list(METRIC_MAPPINGS
.values()).index(reported_metric
)
182 if metric_name
in monitoring_keys
.keys():
183 metric_value
= item
["data"][-1]
184 if metric_name
in METRIC_MULTIPLIERS
:
185 metric_value
*= METRIC_MULTIPLIERS
[metric_name
]
188 vnfr
["member-vnf-index-ref"],
195 metrics
.append(metric
)
197 except Exception as exp
:
199 "Exception while parsing metrics data from vROPS {}\n{}".format(
200 exp
, traceback
.format_exc()