Coverage for osm_mon/collector/infra_collectors/vmware.py: 14%
135 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-05-06 19:04 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-05-06 19:04 +0000
1# -*- coding: utf-8 -*-
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##
24# pylint: disable=E1101
26import logging
27from typing import List
28from lxml import etree as XmlElementTree
30import requests
31from pyvcloud.vcd.client import BasicLoginCredentials
32from pyvcloud.vcd.client import Client
34from osm_mon.collector.infra_collectors.base_vim import BaseVimInfraCollector
35from osm_mon.collector.metric import Metric
36from osm_mon.core.common_db import CommonDbClient
37from osm_mon.core.config import Config
39log = logging.getLogger(__name__)
40API_VERSION = "27.0"
43class VMwareInfraCollector(BaseVimInfraCollector):
44 def __init__(self, config: Config, vim_account_id: str):
45 super().__init__(config, vim_account_id)
46 self.vim_account_id = vim_account_id
47 self.common_db = CommonDbClient(config)
48 vim_account = self.get_vim_account(vim_account_id)
49 self.vcloud_site = vim_account["vim_url"]
50 self.admin_username = vim_account["admin_username"]
51 self.admin_password = vim_account["admin_password"]
52 self.vim_uuid = vim_account["vim_uuid"]
53 self.org_name = vim_account["orgname"]
54 self.vim_project_id = vim_account["project_id"]
55 self.verify_ssl = vim_account.get("insecure", False)
57 def connect_vim_as_admin(self):
58 """Method connect as pvdc admin user to vCloud director.
59 There are certain action that can be done only by provider vdc admin user.
60 Organization creation / provider network creation etc.
62 Returns:
63 The return client object that letter can be used to connect to vcloud direct as admin for provider vdc
64 """
66 log.info("Logging into vCD org as admin.")
68 admin_user = None
69 try:
70 host = self.vcloud_site
71 admin_user = self.admin_username
72 admin_passwd = self.admin_password
73 org = "System"
74 client = Client(host, verify_ssl_certs=self.verify_ssl)
75 client.set_highest_supported_version()
76 client.set_credentials(BasicLoginCredentials(admin_user, org, admin_passwd))
77 return client
79 except Exception as e:
80 log.info(
81 "Can't connect to a vCloud director as: {} with exception {}".format(
82 admin_user, e
83 )
84 )
86 def get_vim_account(self, vim_account_id: str):
87 """
88 Method to get VIM account details by its ID
89 arg - VIM ID
90 return - dict with vim account details
91 """
92 vim_account = {}
93 vim_account_info = self.common_db.get_vim_account(vim_account_id)
95 vim_account["name"] = vim_account_info["name"]
96 vim_account["vim_tenant_name"] = vim_account_info["vim_tenant_name"]
97 vim_account["vim_type"] = vim_account_info["vim_type"]
98 vim_account["vim_url"] = vim_account_info["vim_url"]
99 vim_account["org_user"] = vim_account_info["vim_user"]
100 vim_account["vim_uuid"] = vim_account_info["_id"]
101 if vim_account_info["_admin"]["projects_read"]:
102 vim_account["project_id"] = vim_account_info["_admin"]["projects_read"][0]
103 else:
104 vim_account["project_id"] = ""
106 vim_config = vim_account_info["config"]
107 vim_account["admin_username"] = vim_config["admin_username"]
108 vim_account["admin_password"] = vim_config["admin_password"]
110 if vim_config["orgname"] is not None:
111 vim_account["orgname"] = vim_config["orgname"]
113 return vim_account
115 def check_vim_status(self):
116 try:
117 client = self.connect_vim_as_admin()
118 if client._session:
119 org_list = client.get_org_list()
120 org_uuid = ""
121 for org in org_list.Org:
122 if org.get("name") == self.org_name:
123 org_uuid = org.get("href").split("/")[-1]
125 url = "{}/api/org/{}".format(self.vcloud_site, org_uuid)
127 headers = {
128 "Accept": "application/*+xml;version=" + API_VERSION,
129 "x-vcloud-authorization": client._session.headers[
130 "x-vcloud-authorization"
131 ],
132 }
134 response = requests.get(
135 url=url, headers=headers, verify=self.verify_ssl
136 )
138 if (
139 response.status_code != requests.codes.ok
140 ): # pylint: disable=no-member
141 log.info("check_vim_status(): failed to get org details")
142 else:
143 org_details = XmlElementTree.fromstring(response.content)
144 vdc_list = {}
145 for child in org_details:
146 if "type" in child.attrib:
147 if (
148 child.attrib["type"]
149 == "application/vnd.vmware.vcloud.vdc+xml"
150 ):
151 vdc_list[
152 child.attrib["href"].split("/")[-1:][0]
153 ] = child.attrib["name"]
155 if vdc_list:
156 return True
157 else:
158 return False
159 except Exception as e:
160 log.info("Exception occured while checking vim status {}".format(str(e)))
162 def check_vm_status(self, vapp_id):
163 try:
164 client = self.connect_vim_as_admin()
165 if client._session:
166 url = "{}/api/vApp/vapp-{}".format(self.vcloud_site, vapp_id)
168 headers = {
169 "Accept": "application/*+xml;version=" + API_VERSION,
170 "x-vcloud-authorization": client._session.headers[
171 "x-vcloud-authorization"
172 ],
173 }
175 response = requests.get(
176 url=url, headers=headers, verify=self.verify_ssl
177 )
179 if (
180 response.status_code != requests.codes.ok
181 ): # pylint: disable=no-member
182 log.info("check_vm_status(): failed to get vApp details")
183 else:
184 vapp_details = XmlElementTree.fromstring(response.content)
185 vm_list = []
186 for child in vapp_details:
187 if child.tag.split("}")[1] == "Children":
188 for item in child.getchildren():
189 vm_list.append(item.attrib)
190 return vm_list
191 except Exception as e:
192 log.info("Exception occured while checking vim status {}".format(str(e)))
194 def collect(self) -> List[Metric]:
195 metrics = []
196 vim_status = self.check_vim_status()
197 vim_account_id = self.vim_account_id
198 vim_project_id = self.vim_project_id
199 vim_tags = {"vim_account_id": vim_account_id, "project_id": vim_project_id}
200 vim_status_metric = Metric(vim_tags, "vim_status", vim_status)
201 metrics.append(vim_status_metric)
202 vnfrs = self.common_db.get_vnfrs(vim_account_id=vim_account_id)
203 if self.conf.get("collector", "vm_infra_metrics"):
204 vm_infra_metrics_enabled = str(
205 self.conf.get("collector", "vm_infra_metrics")
206 ).lower() in ("yes", "true", "1")
207 else:
208 vm_infra_metrics_enabled = True
209 if vm_infra_metrics_enabled:
210 for vnfr in vnfrs:
211 nsr_id = vnfr["nsr-id-ref"]
212 ns_name = self.common_db.get_nsr(nsr_id)["name"]
213 vnf_member_index = vnfr["member-vnf-index-ref"]
214 if vnfr["_admin"]["projects_read"]:
215 vnfr_project_id = vnfr["_admin"]["projects_read"][0]
216 else:
217 vnfr_project_id = ""
218 for vdur in vnfr["vdur"]:
219 resource_uuid = vdur["vim-id"]
220 tags = {
221 "vim_account_id": self.vim_account_id,
222 "resource_uuid": resource_uuid,
223 "nsr_id": nsr_id,
224 "ns_name": ns_name,
225 "vnf_member_index": vnf_member_index,
226 "vdur_name": vdur["name"],
227 "project_id": vnfr_project_id,
228 }
229 try:
230 vm_list = self.check_vm_status(resource_uuid)
231 for vm in vm_list:
232 if vm["status"] == "4" and vm["deployed"] == "true":
233 vm_status = 1
234 else:
235 vm_status = 0
236 vm_status_metric = Metric(tags, "vm_status", vm_status)
237 except Exception:
238 log.exception("VM status is not OK!")
239 vm_status_metric = Metric(tags, "vm_status", 0)
240 metrics.append(vm_status_metric)
241 return metrics