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',
52 self
.vrops_site
= vrops_site
53 self
.vrops_user
= vrops_user
54 self
.vrops_password
= vrops_password
56 def get_vrops_token(self
):
57 """Fetches token from vrops
59 auth_url
= '/suite-api/api/auth/token/acquire'
60 headers
= {'Content-Type': 'application/json', 'Accept': 'application/json'}
61 req_body
= {"username": self
.vrops_user
, "password": self
.vrops_password
}
62 resp
= requests
.post(self
.vrops_site
+ auth_url
,
63 json
=req_body
, verify
=False,
65 if resp
.status_code
!= 200:
66 log
.error("Failed to get token from vROPS: {} {}".format(resp
.status_code
,
70 resp_data
= json
.loads(resp
.content
.decode('utf-8'))
71 return resp_data
['token']
73 def get_vm_resource_list_from_vrops(self
):
74 """ Find all known resource IDs in vROPs
76 auth_token
= self
.get_vrops_token()
77 api_url
= '/suite-api/api/resources?resourceKind=VirtualMachine'
78 headers
= {'Accept': 'application/json', 'Authorization': 'vRealizeOpsToken {}'.format(auth_token
)}
81 resp
= requests
.get(self
.vrops_site
+ api_url
,
82 verify
=False, headers
=headers
)
84 if resp
.status_code
!= 200:
85 log
.error("Failed to get resource list from vROPS: {} {}".format(resp
.status_code
,
90 resp_data
= json
.loads(resp
.content
.decode('utf-8'))
91 if resp_data
.get('resourceList') is not None:
92 resource_list
= resp_data
.get('resourceList')
94 except Exception as exp
:
95 log
.error("get_vm_resource_id: Error in parsing {}\n{}".format(exp
, traceback
.format_exc()))
101 monitoring_params
={},
106 # Collect the names of all the metrics we need to query
107 for metric_entry
in monitoring_params
:
108 metric_name
= metric_entry
['performance-metric']
109 if metric_name
not in METRIC_MAPPINGS
:
110 log
.debug("Metric {} not supported, ignoring".format(metric_name
))
112 monitoring_keys
[metric_name
] = METRIC_MAPPINGS
[metric_name
]
115 # Make a query for only the stats we have been asked for
117 for stat
in monitoring_keys
.values():
118 stats_key
+= "&statKey={}".format(stat
)
120 # And only ask for the resource ids that we are interested in
122 sanitized_vdu_mappings
= copy
.deepcopy(vdu_mappings
)
123 for key
in vdu_mappings
.keys():
124 vdu
= vdu_mappings
[key
]
125 if 'vrops_id' not in vdu
:
126 log
.info("Could not find vROPS id for vdu {}".format(vdu
))
127 del sanitized_vdu_mappings
[key
]
129 resource_ids
+= "&resourceId={}".format(vdu
['vrops_id'])
130 vdu_mappings
= sanitized_vdu_mappings
134 # Now we can make a single call to vROPS to collect all relevant metrics for resources we need to monitor
135 api_url
= "/suite-api/api/resources/stats?IntervalType=MINUTES&IntervalCount=1"\
136 "&rollUpType=MAX¤tOnly=true{}{}".format(stats_key
, resource_ids
)
138 auth_token
= self
.get_vrops_token()
139 headers
= {'Accept': 'application/json', 'Authorization': 'vRealizeOpsToken {}'.format(auth_token
)}
141 resp
= requests
.get(self
.vrops_site
+ api_url
,
142 verify
=False, headers
=headers
)
144 if resp
.status_code
!= 200:
145 log
.error("Failed to get Metrics data from vROPS for {} {}".format(resp
.status_code
,
149 m_data
= json
.loads(resp
.content
.decode('utf-8'))
150 if 'values' not in m_data
:
153 statistics
= m_data
['values']
154 for vdu_stat
in statistics
:
155 vrops_id
= vdu_stat
['resourceId']
157 for vdu
in vdu_mappings
.values():
158 if vdu
['vrops_id'] == vrops_id
:
159 vdu_name
= vdu
['name']
162 for item
in vdu_stat
['stat-list']['stat']:
163 reported_metric
= item
['statKey']['key']
164 if reported_metric
not in METRIC_MAPPINGS
.values():
167 # Convert the vROPS metric name back to OSM key
168 metric_name
= list(METRIC_MAPPINGS
.keys())[list(METRIC_MAPPINGS
.values()).
169 index(reported_metric
)]
170 if metric_name
in monitoring_keys
.keys():
171 metric_value
= item
['data'][-1]
172 if metric_name
in METRIC_MULTIPLIERS
:
173 metric_value
*= METRIC_MULTIPLIERS
[metric_name
]
174 metric
= VnfMetric(vnfr
['nsr-id-ref'],
175 vnfr
['member-vnf-index-ref'],
182 metrics
.append(metric
)
184 except Exception as exp
:
185 log
.error("Exception while parsing metrics data from vROPS {}\n{}".format(exp
, traceback
.format_exc()))