206083a17a9b1eee5a084add9803b438efb11bfa
[osm/MON.git] / osm_mon / collector / infra_collectors / vmware.py
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 import logging
25 from typing import List
26
27 from xml.etree import ElementTree as XmlElementTree
28 from pyvcloud.vcd.client import BasicLoginCredentials
29 from pyvcloud.vcd.client import Client
30
31 from osm_mon.collector.utils import CollectorUtils
32 from osm_mon.collector.infra_collectors.base_vim import BaseVimInfraCollector
33 from osm_mon.collector.metric import Metric
34 from osm_mon.core.common_db import CommonDbClient
35 from osm_mon.core.config import Config
36 import requests
37 import json
38
39 log = logging.getLogger(__name__)
40 API_VERSION = '27.0'
41
42
43 class VMwareInfraCollector(BaseVimInfraCollector):
44
45 def __init__(self, config: Config, vim_account_id: str):
46 super().__init__(config, vim_account_id)
47 self.vim_account_id = vim_account_id
48 self.common_db = CommonDbClient(config)
49 vim_account = self.get_vim_account(vim_account_id)
50 self.vcloud_site = vim_account['vim_url']
51 self.admin_username = vim_account['admin_username']
52 self.admin_password = vim_account['admin_password']
53 self.vim_uuid = vim_account['vim_uuid']
54 self.org_name = vim_account['orgname']
55
56 def connect_vim_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.
60
61 Returns:
62 The return client object that letter can be used to connect to vcloud direct as admin for provider vdc
63 """
64
65 log.info("Logging into vCD org as admin.")
66
67 admin_user = None
68 try:
69 host = self.vcloud_site
70 admin_user = self.admin_username
71 admin_passwd = self.admin_password
72 org = 'System'
73 client = Client(host, verify_ssl_certs=False)
74 client.set_highest_supported_version()
75 client.set_credentials(BasicLoginCredentials(admin_user, org,
76 admin_passwd))
77 return client
78
79 except Exception as e:
80 log.info("Can't connect to a vCloud director as: {} with exception {}".format(admin_user, e))
81
82 def get_vim_account(self, vim_account_id: str):
83 """
84 Method to get VIM account details by its ID
85 arg - VIM ID
86 return - dict with vim account details
87 """
88 vim_account = {}
89 vim_account_info = CollectorUtils.get_credentials(vim_account_id)
90
91 vim_account['name'] = vim_account_info.name
92 vim_account['vim_tenant_name'] = vim_account_info.tenant_name
93 vim_account['vim_type'] = vim_account_info.type
94 vim_account['vim_url'] = vim_account_info.url
95 vim_account['org_user'] = vim_account_info.user
96 vim_account['org_password'] = vim_account_info.password
97 vim_account['vim_uuid'] = vim_account_info.uuid
98
99 vim_config = json.loads(vim_account_info.config)
100 vim_account['admin_username'] = vim_config['admin_username']
101 vim_account['admin_password'] = vim_config['admin_password']
102
103 if vim_config['orgname'] is not None:
104 vim_account['orgname'] = vim_config['orgname']
105
106 return vim_account
107
108 def check_vim_status(self):
109 try:
110 client = self.connect_vim_as_admin()
111 if client._session:
112 org_list = client.get_org_list()
113 for org in org_list.Org:
114 if org.get('name') == self.org_name:
115 org_uuid = org.get('href').split('/')[-1]
116
117 url = '{}/api/org/{}'.format(self.vcloud_site, org_uuid)
118
119 headers = {'Accept': 'application/*+xml;version=' + API_VERSION,
120 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
121
122 response = requests.get(url=url,
123 headers=headers,
124 verify=False)
125
126 if response.status_code != requests.codes.ok: # pylint: disable=no-member
127 log.info("check_vim_status(): failed to get org details")
128 else:
129 org_details = XmlElementTree.fromstring(response.content)
130 vdc_list = {}
131 for child in org_details:
132 if 'type' in child.attrib:
133 if child.attrib['type'] == 'application/vnd.vmware.vcloud.vdc+xml':
134 vdc_list[child.attrib['href'].split("/")[-1:][0]] = child.attrib['name']
135
136 if vdc_list:
137 return True
138 else:
139 return False
140 except Exception as e:
141 log.info("Exception occured while checking vim status {}".format(str(e)))
142
143 def check_vm_status(self, vapp_id):
144 try:
145 client = self.connect_vim_as_admin()
146 if client._session:
147 url = '{}/api/vApp/vapp-{}'.format(self.vcloud_site, vapp_id)
148
149 headers = {'Accept': 'application/*+xml;version=' + API_VERSION,
150 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
151
152 response = requests.get(url=url,
153 headers=headers,
154 verify=False)
155
156 if response.status_code != requests.codes.ok: # pylint: disable=no-member
157 log.info("check_vm_status(): failed to get vApp details")
158 else:
159 vapp_details = XmlElementTree.fromstring(response.content)
160 vm_list = []
161 for child in vapp_details:
162 if child.tag.split("}")[1] == 'Children':
163 for item in child.getchildren():
164 vm_list.append(item.attrib)
165 return vm_list
166 except Exception as e:
167 log.info("Exception occured while checking vim status {}".format(str(e)))
168
169 def collect(self) -> List[Metric]:
170 metrics = []
171 vim_status = self.check_vim_status()
172 vim_status_metric = Metric({'vim_account_id': self.vim_account_id}, 'vim_status', vim_status)
173 metrics.append(vim_status_metric)
174 vnfrs = self.common_db.get_vnfrs(vim_account_id=self.vim_account_id)
175 for vnfr in vnfrs:
176 nsr_id = vnfr['nsr-id-ref']
177 vnf_member_index = vnfr['member-vnf-index-ref']
178 for vdur in vnfr['vdur']:
179 resource_uuid = vdur['vim-id']
180 tags = {
181 'vim_account_id': self.vim_account_id,
182 'resource_uuid': resource_uuid,
183 'nsr_id': nsr_id,
184 'vnf_member_index': vnf_member_index,
185 'vdur_name': vdur['name']
186 }
187 try:
188 vm_list = self.check_vm_status(resource_uuid)
189 for vm in vm_list:
190 if vm['status'] == '4' and vm['deployed'] == 'true':
191 vm_status = 1
192 else:
193 vm_status = 0
194 vm_status_metric = Metric(tags, 'vm_status', vm_status)
195 except Exception:
196 log.exception("VM status is not OK!")
197 vm_status_metric = Metric(tags, 'vm_status', 0)
198 metrics.append(vm_status_metric)
199 return metrics