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