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

1# -*- coding: utf-8 -*- 

2 

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## 

23 

24# pylint: disable=E1101 

25 

26import logging 

27from typing import List 

28from lxml import etree as XmlElementTree 

29 

30import requests 

31from pyvcloud.vcd.client import BasicLoginCredentials 

32from pyvcloud.vcd.client import Client 

33 

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 

38 

39log = logging.getLogger(__name__) 

40API_VERSION = "27.0" 

41 

42 

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) 

56 

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. 

61 

62 Returns: 

63 The return client object that letter can be used to connect to vcloud direct as admin for provider vdc 

64 """ 

65 

66 log.info("Logging into vCD org as admin.") 

67 

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 

78 

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 ) 

85 

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) 

94 

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"] = "" 

105 

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"] 

109 

110 if vim_config["orgname"] is not None: 

111 vim_account["orgname"] = vim_config["orgname"] 

112 

113 return vim_account 

114 

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] 

124 

125 url = "{}/api/org/{}".format(self.vcloud_site, org_uuid) 

126 

127 headers = { 

128 "Accept": "application/*+xml;version=" + API_VERSION, 

129 "x-vcloud-authorization": client._session.headers[ 

130 "x-vcloud-authorization" 

131 ], 

132 } 

133 

134 response = requests.get( 

135 url=url, headers=headers, verify=self.verify_ssl 

136 ) 

137 

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"] 

154 

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))) 

161 

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) 

167 

168 headers = { 

169 "Accept": "application/*+xml;version=" + API_VERSION, 

170 "x-vcloud-authorization": client._session.headers[ 

171 "x-vcloud-authorization" 

172 ], 

173 } 

174 

175 response = requests.get( 

176 url=url, headers=headers, verify=self.verify_ssl 

177 ) 

178 

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))) 

193 

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