Adding project_id label to Prometheus Infra metrics
[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['org_password'] = self.common_db.decrypt_vim_password(vim_account_info['vim_password'],
96 vim_account_info['schema_version'],
97 vim_account_id)
98 vim_account['vim_uuid'] = vim_account_info['_id']
99 vim_account['project_id'] = vim_account_info['_admin']['projects_read'][0]
100
101 vim_config = vim_account_info['config']
102 vim_account['admin_username'] = vim_config['admin_username']
103 vim_account['admin_password'] = self.common_db.decrypt_vim_password(vim_config['admin_password'],
104 vim_account_info['schema_version'],
105 vim_account_id)
106
107 if vim_config['orgname'] is not None:
108 vim_account['orgname'] = vim_config['orgname']
109
110 return vim_account
111
112 def check_vim_status(self):
113 try:
114 client = self.connect_vim_as_admin()
115 if client._session:
116 org_list = client.get_org_list()
117 for org in org_list.Org:
118 if org.get('name') == self.org_name:
119 org_uuid = org.get('href').split('/')[-1]
120
121 url = '{}/api/org/{}'.format(self.vcloud_site, org_uuid)
122
123 headers = {'Accept': 'application/*+xml;version=' + API_VERSION,
124 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
125
126 response = requests.get(url=url,
127 headers=headers,
128 verify=False)
129
130 if response.status_code != requests.codes.ok: # pylint: disable=no-member
131 log.info("check_vim_status(): failed to get org details")
132 else:
133 org_details = XmlElementTree.fromstring(response.content)
134 vdc_list = {}
135 for child in org_details:
136 if 'type' in child.attrib:
137 if child.attrib['type'] == 'application/vnd.vmware.vcloud.vdc+xml':
138 vdc_list[child.attrib['href'].split("/")[-1:][0]] = child.attrib['name']
139
140 if vdc_list:
141 return True
142 else:
143 return False
144 except Exception as e:
145 log.info("Exception occured while checking vim status {}".format(str(e)))
146
147 def check_vm_status(self, vapp_id):
148 try:
149 client = self.connect_vim_as_admin()
150 if client._session:
151 url = '{}/api/vApp/vapp-{}'.format(self.vcloud_site, vapp_id)
152
153 headers = {'Accept': 'application/*+xml;version=' + API_VERSION,
154 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
155
156 response = requests.get(url=url,
157 headers=headers,
158 verify=False)
159
160 if response.status_code != requests.codes.ok: # pylint: disable=no-member
161 log.info("check_vm_status(): failed to get vApp details")
162 else:
163 vapp_details = XmlElementTree.fromstring(response.content)
164 vm_list = []
165 for child in vapp_details:
166 if child.tag.split("}")[1] == 'Children':
167 for item in child.getchildren():
168 vm_list.append(item.attrib)
169 return vm_list
170 except Exception as e:
171 log.info("Exception occured while checking vim status {}".format(str(e)))
172
173 def collect(self) -> List[Metric]:
174 metrics = []
175 vim_status = self.check_vim_status()
176 vim_account_id = self.vim_account_id
177 vim_project_id = self.vim_project_id
178 vim_tags = {
179 'vim_account_id': vim_account_id,
180 'project_id': vim_project_id
181 }
182 vim_status_metric = Metric(vim_tags, 'vim_status', vim_status)
183 metrics.append(vim_status_metric)
184 vnfrs = self.common_db.get_vnfrs(vim_account_id=vim_account_id)
185 for vnfr in vnfrs:
186 nsr_id = vnfr['nsr-id-ref']
187 ns_name = self.common_db.get_nsr(nsr_id)['name']
188 vnf_member_index = vnfr['member-vnf-index-ref']
189 vnfr_project_id = vnfr['_admin']['projects_read'][0]
190 for vdur in vnfr['vdur']:
191 resource_uuid = vdur['vim-id']
192 tags = {
193 'vim_account_id': self.vim_account_id,
194 'resource_uuid': resource_uuid,
195 'nsr_id': nsr_id,
196 'ns_name': ns_name,
197 'vnf_member_index': vnf_member_index,
198 'vdur_name': vdur['name'],
199 'project_id': vnfr_project_id
200 }
201 try:
202 vm_list = self.check_vm_status(resource_uuid)
203 for vm in vm_list:
204 if vm['status'] == '4' and vm['deployed'] == 'true':
205 vm_status = 1
206 else:
207 vm_status = 0
208 vm_status_metric = Metric(tags, 'vm_status', vm_status)
209 except Exception:
210 log.exception("VM status is not OK!")
211 vm_status_metric = Metric(tags, 'vm_status', 0)
212 metrics.append(vm_status_metric)
213 return metrics