1 # -*- coding: utf-8 -*-
4 # Copyright 2016-2019 VMware Inc.
5 # This file is part of ETSI OSM
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
12 # http://www.apache.org/licenses/LICENSE-2.0
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
20 # For those usages not covered by the Apache License, Version 2.0 please
21 # contact: osslegalrouting@vmware.com
25 from typing
import List
26 from xml
.etree
import ElementTree
as XmlElementTree
29 from pyvcloud
.vcd
.client
import BasicLoginCredentials
30 from pyvcloud
.vcd
.client
import Client
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
37 log
= logging
.getLogger(__name__
)
41 class VMwareInfraCollector(BaseVimInfraCollector
):
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']
54 def connect_vim_as_admin(self
):
55 """ Method connect as pvdc admin user to vCloud director.
56 There are certain action that can be done only by provider vdc admin user.
57 Organization creation / provider network creation etc.
60 The return client object that letter can be used to connect to vcloud direct as admin for provider vdc
63 log
.info("Logging into vCD org as admin.")
67 host
= self
.vcloud_site
68 admin_user
= self
.admin_username
69 admin_passwd
= self
.admin_password
71 client
= Client(host
, verify_ssl_certs
=False)
72 client
.set_highest_supported_version()
73 client
.set_credentials(BasicLoginCredentials(admin_user
, org
,
77 except Exception as e
:
78 log
.info("Can't connect to a vCloud director as: {} with exception {}".format(admin_user
, e
))
80 def get_vim_account(self
, vim_account_id
: str):
82 Method to get VIM account details by its ID
84 return - dict with vim account details
87 vim_account_info
= self
.common_db
.get_vim_account(vim_account_id
)
89 vim_account
['name'] = vim_account_info
['name']
90 vim_account
['vim_tenant_name'] = vim_account_info
['vim_tenant_name']
91 vim_account
['vim_type'] = vim_account_info
['vim_type']
92 vim_account
['vim_url'] = vim_account_info
['vim_url']
93 vim_account
['org_user'] = vim_account_info
['vim_user']
94 vim_account
['org_password'] = self
.common_db
.decrypt_vim_password(vim_account_info
['vim_password'],
95 vim_account_info
['schema_version'],
97 vim_account
['vim_uuid'] = vim_account_info
['_id']
99 vim_config
= vim_account_info
['config']
100 vim_account
['admin_username'] = vim_config
['admin_username']
101 vim_account
['admin_password'] = self
.common_db
.decrypt_vim_password(vim_config
['admin_password'],
102 vim_account_info
['schema_version'],
105 if vim_config
['orgname'] is not None:
106 vim_account
['orgname'] = vim_config
['orgname']
110 def check_vim_status(self
):
112 client
= self
.connect_vim_as_admin()
114 org_list
= client
.get_org_list()
115 for org
in org_list
.Org
:
116 if org
.get('name') == self
.org_name
:
117 org_uuid
= org
.get('href').split('/')[-1]
119 url
= '{}/api/org/{}'.format(self
.vcloud_site
, org_uuid
)
121 headers
= {'Accept': 'application/*+xml;version=' + API_VERSION
,
122 'x-vcloud-authorization': client
._session
.headers
['x-vcloud-authorization']}
124 response
= requests
.get(url
=url
,
128 if response
.status_code
!= requests
.codes
.ok
: # pylint: disable=no-member
129 log
.info("check_vim_status(): failed to get org details")
131 org_details
= XmlElementTree
.fromstring(response
.content
)
133 for child
in org_details
:
134 if 'type' in child
.attrib
:
135 if child
.attrib
['type'] == 'application/vnd.vmware.vcloud.vdc+xml':
136 vdc_list
[child
.attrib
['href'].split("/")[-1:][0]] = child
.attrib
['name']
142 except Exception as e
:
143 log
.info("Exception occured while checking vim status {}".format(str(e
)))
145 def check_vm_status(self
, vapp_id
):
147 client
= self
.connect_vim_as_admin()
149 url
= '{}/api/vApp/vapp-{}'.format(self
.vcloud_site
, vapp_id
)
151 headers
= {'Accept': 'application/*+xml;version=' + API_VERSION
,
152 'x-vcloud-authorization': client
._session
.headers
['x-vcloud-authorization']}
154 response
= requests
.get(url
=url
,
158 if response
.status_code
!= requests
.codes
.ok
: # pylint: disable=no-member
159 log
.info("check_vm_status(): failed to get vApp details")
161 vapp_details
= XmlElementTree
.fromstring(response
.content
)
163 for child
in vapp_details
:
164 if child
.tag
.split("}")[1] == 'Children':
165 for item
in child
.getchildren():
166 vm_list
.append(item
.attrib
)
168 except Exception as e
:
169 log
.info("Exception occured while checking vim status {}".format(str(e
)))
171 def collect(self
) -> List
[Metric
]:
173 vim_status
= self
.check_vim_status()
174 vim_status_metric
= Metric({'vim_account_id': self
.vim_account_id
}, 'vim_status', vim_status
)
175 metrics
.append(vim_status_metric
)
176 vnfrs
= self
.common_db
.get_vnfrs(vim_account_id
=self
.vim_account_id
)
178 nsr_id
= vnfr
['nsr-id-ref']
179 vnf_member_index
= vnfr
['member-vnf-index-ref']
180 for vdur
in vnfr
['vdur']:
181 resource_uuid
= vdur
['vim-id']
183 'vim_account_id': self
.vim_account_id
,
184 'resource_uuid': resource_uuid
,
186 'vnf_member_index': vnf_member_index
,
187 'vdur_name': vdur
['name']
190 vm_list
= self
.check_vm_status(resource_uuid
)
192 if vm
['status'] == '4' and vm
['deployed'] == 'true':
196 vm_status_metric
= Metric(tags
, 'vm_status', vm_status
)
198 log
.exception("VM status is not OK!")
199 vm_status_metric
= Metric(tags
, 'vm_status', 0)
200 metrics
.append(vm_status_metric
)