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
26 from xml
.etree
import ElementTree
as XmlElementTree
29 from pyvcloud
.vcd
.client
import BasicLoginCredentials
30 from pyvcloud
.vcd
.client
import Client
32 from osm_mon
.collector
.vnf_collectors
.base_vim
import BaseVimCollector
33 from osm_mon
.collector
.vnf_collectors
.vrops
.vrops_helper
import vROPS_Helper
34 from osm_mon
.core
.common_db
import CommonDbClient
35 from osm_mon
.core
.config
import Config
37 log
= logging
.getLogger(__name__
)
42 class VMwareCollector(BaseVimCollector
):
43 def __init__(self
, config
: Config
, vim_account_id
: str, vim_session
: object):
44 super().__init
__(config
, vim_account_id
)
45 self
.common_db
= CommonDbClient(config
)
46 vim_account
= self
.get_vim_account(vim_account_id
)
47 self
.vcloud_site
= vim_account
["vim_url"]
48 self
.admin_username
= vim_account
["admin_username"]
49 self
.admin_password
= vim_account
["admin_password"]
50 self
.vrops
= vROPS_Helper(
51 vrops_site
=vim_account
["vrops_site"],
52 vrops_user
=vim_account
["vrops_user"],
53 vrops_password
=vim_account
["vrops_password"],
56 def connect_as_admin(self
):
57 """Method connect as pvdc admin user to vCloud director.
58 There are certain action that can be done only by provider vdc admin user.
59 Organization creation / provider network creation etc.
62 The return client object that letter can be used to connect to vcloud direct as admin for provider vdc
65 log
.debug("Logging into vCD org as admin.")
69 host
= self
.vcloud_site
70 admin_user
= self
.admin_username
71 admin_passwd
= self
.admin_password
73 client
= Client(host
, verify_ssl_certs
=False)
74 client
.set_highest_supported_version()
75 client
.set_credentials(BasicLoginCredentials(admin_user
, org
, admin_passwd
))
78 except Exception as e
:
80 "Can't connect to a vCloud director as: {} with exception {}".format(
85 def get_vim_account(self
, vim_account_id
: str):
87 Method to get VIM account details by its ID
89 return - dict with vim account details
92 vim_account_info
= self
.common_db
.get_vim_account(vim_account_id
)
94 vim_account
["vim_url"] = vim_account_info
["vim_url"]
96 vim_config
= vim_account_info
["config"]
97 vim_account
["admin_username"] = vim_config
["admin_username"]
98 vim_account
["admin_password"] = vim_config
["admin_password"]
99 vim_account
["vrops_site"] = vim_config
["vrops_site"]
100 vim_account
["vrops_user"] = vim_config
["vrops_user"]
101 vim_account
["vrops_password"] = vim_config
["vrops_password"]
105 def get_vm_moref_id(self
, vapp_uuid
):
107 Method to get the moref_id of given VM
114 vm_details
= self
.get_vapp_details_rest(vapp_uuid
)
116 if vm_details
and "vm_vcenter_info" in vm_details
:
117 vm_moref_id
= vm_details
["vm_vcenter_info"].get("vm_moref_id", None)
119 "Found vm_moref_id: {} for vApp UUID: {}".format(
120 vm_moref_id
, vapp_uuid
125 "Failed to find vm_moref_id from vApp UUID: {}".format(
130 except Exception as exp
:
132 "Error occurred while getting VM moref ID for VM: {}\n{}".format(
133 exp
, traceback
.format_exc()
139 def get_vapp_details_rest(self
, vapp_uuid
=None):
141 Method retrieve vapp detail from vCloud director
142 vapp_uuid - is vapp identifier.
143 Returns - VM MOref ID or return None
147 if vapp_uuid
is None:
148 return parsed_respond
150 vca
= self
.connect_as_admin()
153 log
.error("Failed to connect to vCD")
154 return parsed_respond
156 url_list
= [self
.vcloud_site
, "/api/vApp/vapp-", vapp_uuid
]
157 get_vapp_restcall
= "".join(url_list
)
161 "Accept": "application/*+xml;version=" + API_VERSION
,
162 "x-vcloud-authorization": vca
._session
.headers
[
163 "x-vcloud-authorization"
166 response
= requests
.get(get_vapp_restcall
, headers
=headers
, verify
=False)
168 if response
.status_code
!= 200:
170 "REST API call {} failed. Return status code {}".format(
171 get_vapp_restcall
, response
.content
174 return parsed_respond
177 xmlroot_respond
= XmlElementTree
.fromstring(response
.content
)
180 "vm": "http://www.vmware.com/vcloud/v1.5",
181 "vmext": "http://www.vmware.com/vcloud/extension/v1.5",
182 "xmlns": "http://www.vmware.com/vcloud/v1.5",
185 # parse children section for other attrib
186 children_section
= xmlroot_respond
.find("vm:Children/", namespaces
)
187 if children_section
is not None:
188 vCloud_extension_section
= children_section
.find(
189 "xmlns:VCloudExtension", namespaces
191 if vCloud_extension_section
is not None:
193 vim_info
= vCloud_extension_section
.find(
194 "vmext:VmVimInfo", namespaces
196 vmext
= vim_info
.find("vmext:VmVimObjectRef", namespaces
)
197 if vmext
is not None:
198 vm_vcenter_info
["vm_moref_id"] = vmext
.find(
199 "vmext:MoRef", namespaces
201 parsed_respond
["vm_vcenter_info"] = vm_vcenter_info
203 except Exception as exp
:
205 "Error occurred for getting vApp details: {}\n{}".format(
206 exp
, traceback
.format_exc()
210 return parsed_respond
212 def collect(self
, vnfr
: dict):
213 vnfd
= self
.common_db
.get_vnfd(vnfr
["vnfd-id"])
216 # Populate extra tags for metrics
217 nsr_id
= vnfr
["nsr-id-ref"]
219 tags
["ns_name"] = self
.common_db
.get_nsr(nsr_id
)["name"]
220 if vnfr
["_admin"]["projects_read"]:
221 tags
["project_id"] = vnfr
["_admin"]["projects_read"][0]
223 tags
["project_id"] = ""
225 # Fetch the list of all known resources from vROPS.
226 resource_list
= self
.vrops
.get_vm_resource_list_from_vrops()
228 for vdur
in vnfr
["vdur"]:
229 # This avoids errors when vdur records have not been completely filled
230 if "name" not in vdur
:
232 vdu
= next(filter(lambda vdu
: vdu
["id"] == vdur
["vdu-id-ref"], vnfd
["vdu"]))
234 if "monitoring-parameter" not in vdu
:
237 resource_uuid
= vdur
["vim-id"]
238 # Find vm_moref_id from vApp uuid in vCD
239 vim_id
= self
.get_vm_moref_id(resource_uuid
)
242 "Failed to find vROPS ID for vApp in vCD: {}".format(resource_uuid
)
246 vdu_mappings
[vim_id
] = {"name": vdur
["name"]}
248 # Map the vROPS instance id to the vim-id so we can look it up.
249 for resource
in resource_list
:
250 for resourceIdentifier
in resource
["resourceKey"][
251 "resourceIdentifiers"
254 resourceIdentifier
["identifierType"]["name"]
255 == "VMEntityObjectID"
257 if resourceIdentifier
["value"] != vim_id
:
259 vdu_mappings
[vim_id
]["vrops_id"] = resource
["identifier"]
261 if len(vdu_mappings
) != 0:
262 return self
.vrops
.get_metrics(
263 vdu_mappings
=vdu_mappings
,
264 monitoring_params
=vdu
["monitoring-parameter"],