Fixes double decryption
[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 from xml.etree import ElementTree as XmlElementTree
27
28 import requests
29 from pyvcloud.vcd.client import BasicLoginCredentials
30 from pyvcloud.vcd.client import Client
31
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
37 log = logging.getLogger(__name__)
38 API_VERSION = '27.0'
39
40
41 class VMwareInfraCollector(BaseVimInfraCollector):
42
43 def __init__(self, config: Config, vim_account_id: str):
44 super().__init__(config, vim_account_id)
45 self.vim_account_id = vim_account_id
46 self.common_db = CommonDbClient(config)
47 vim_account = self.get_vim_account(vim_account_id)
48 self.vcloud_site = vim_account['vim_url']
49 self.admin_username = vim_account['admin_username']
50 self.admin_password = vim_account['admin_password']
51 self.vim_uuid = vim_account['vim_uuid']
52 self.org_name = vim_account['orgname']
53 self.vim_project_id = vim_account['project_id']
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_highest_supported_version()
74 client.set_credentials(BasicLoginCredentials(admin_user, org,
75 admin_passwd))
76 return client
77
78 except Exception as e:
79 log.info("Can't connect to a vCloud director as: {} with exception {}".format(admin_user, e))
80
81 def get_vim_account(self, vim_account_id: str):
82 """
83 Method to get VIM account details by its ID
84 arg - VIM ID
85 return - dict with vim account details
86 """
87 vim_account = {}
88 vim_account_info = self.common_db.get_vim_account(vim_account_id)
89
90 vim_account['name'] = vim_account_info['name']
91 vim_account['vim_tenant_name'] = vim_account_info['vim_tenant_name']
92 vim_account['vim_type'] = vim_account_info['vim_type']
93 vim_account['vim_url'] = vim_account_info['vim_url']
94 vim_account['org_user'] = vim_account_info['vim_user']
95 vim_account['vim_uuid'] = vim_account_info['_id']
96 vim_account['project_id'] = vim_account_info['_admin']['projects_read'][0]
97
98 vim_config = vim_account_info['config']
99 vim_account['admin_username'] = vim_config['admin_username']
100 vim_account['admin_password'] = vim_config['admin_password']
101
102 if vim_config['orgname'] is not None:
103 vim_account['orgname'] = vim_config['orgname']
104
105 return vim_account
106
107 def check_vim_status(self):
108 try:
109 client = self.connect_vim_as_admin()
110 if client._session:
111 org_list = client.get_org_list()
112 for org in org_list.Org:
113 if org.get('name') == self.org_name:
114 org_uuid = org.get('href').split('/')[-1]
115
116 url = '{}/api/org/{}'.format(self.vcloud_site, org_uuid)
117
118 headers = {'Accept': 'application/*+xml;version=' + API_VERSION,
119 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
120
121 response = requests.get(url=url,
122 headers=headers,
123 verify=False)
124
125 if response.status_code != requests.codes.ok: # pylint: disable=no-member
126 log.info("check_vim_status(): failed to get org details")
127 else:
128 org_details = XmlElementTree.fromstring(response.content)
129 vdc_list = {}
130 for child in org_details:
131 if 'type' in child.attrib:
132 if child.attrib['type'] == 'application/vnd.vmware.vcloud.vdc+xml':
133 vdc_list[child.attrib['href'].split("/")[-1:][0]] = child.attrib['name']
134
135 if vdc_list:
136 return True
137 else:
138 return False
139 except Exception as e:
140 log.info("Exception occured while checking vim status {}".format(str(e)))
141
142 def check_vm_status(self, vapp_id):
143 try:
144 client = self.connect_vim_as_admin()
145 if client._session:
146 url = '{}/api/vApp/vapp-{}'.format(self.vcloud_site, vapp_id)
147
148 headers = {'Accept': 'application/*+xml;version=' + API_VERSION,
149 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
150
151 response = requests.get(url=url,
152 headers=headers,
153 verify=False)
154
155 if response.status_code != requests.codes.ok: # pylint: disable=no-member
156 log.info("check_vm_status(): failed to get vApp details")
157 else:
158 vapp_details = XmlElementTree.fromstring(response.content)
159 vm_list = []
160 for child in vapp_details:
161 if child.tag.split("}")[1] == 'Children':
162 for item in child.getchildren():
163 vm_list.append(item.attrib)
164 return vm_list
165 except Exception as e:
166 log.info("Exception occured while checking vim status {}".format(str(e)))
167
168 def collect(self) -> List[Metric]:
169 metrics = []
170 vim_status = self.check_vim_status()
171 vim_account_id = self.vim_account_id
172 vim_project_id = self.vim_project_id
173 vim_tags = {
174 'vim_account_id': vim_account_id,
175 'project_id': vim_project_id
176 }
177 vim_status_metric = Metric(vim_tags, 'vim_status', vim_status)
178 metrics.append(vim_status_metric)
179 vnfrs = self.common_db.get_vnfrs(vim_account_id=vim_account_id)
180 for vnfr in vnfrs:
181 nsr_id = vnfr['nsr-id-ref']
182 ns_name = self.common_db.get_nsr(nsr_id)['name']
183 vnf_member_index = vnfr['member-vnf-index-ref']
184 vnfr_project_id = vnfr['_admin']['projects_read'][0]
185 for vdur in vnfr['vdur']:
186 resource_uuid = vdur['vim-id']
187 tags = {
188 'vim_account_id': self.vim_account_id,
189 'resource_uuid': resource_uuid,
190 'nsr_id': nsr_id,
191 'ns_name': ns_name,
192 'vnf_member_index': vnf_member_index,
193 'vdur_name': vdur['name'],
194 'project_id': vnfr_project_id
195 }
196 try:
197 vm_list = self.check_vm_status(resource_uuid)
198 for vm in vm_list:
199 if vm['status'] == '4' and vm['deployed'] == 'true':
200 vm_status = 1
201 else:
202 vm_status = 0
203 vm_status_metric = Metric(tags, 'vm_status', vm_status)
204 except Exception:
205 log.exception("VM status is not OK!")
206 vm_status_metric = Metric(tags, 'vm_status', 0)
207 metrics.append(vm_status_metric)
208 return metrics