blob: acd4240b367ef3f43bcd74eed8e10955b587e2a2 [file] [log] [blame]
bayramov6c0e3d42016-09-27 03:03:32 -07001# -*- coding: utf-8 -*-
2##
3# This file is standalone vmware vcloud director util
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17#
18# For those usages not covered by the Apache License, Version 2.0 please
19# contact with: mbayramov@vmware.com
20##
21
bayramovb6ffe792016-09-28 11:50:56 +040022"""
bayramov6c0e3d42016-09-27 03:03:32 -070023
bayramovb6ffe792016-09-28 11:50:56 +040024Standalone application that leverage openmano vmware connector work with vCloud director rest api.
bayramov6c0e3d42016-09-27 03:03:32 -070025
bayramovb6ffe792016-09-28 11:50:56 +040026 - Provides capability to create and delete VDC for specific organization.
27 - Create, delete and manage network for specific VDC
28 - List deployed VM's , VAPPs, VDSs, Organization
29 - View detail information about VM / Vapp , Organization etc
30 - Operate with images upload / boot / power on etc
31
32 Usage example.
33
34 List organization created in vCloud director
35 vmwarecli.py -u admin -p qwerty123 -c 172.16.254.206 -U Administrator -P qwerty123 -o test -v TEF list org
36
37 List VDC for particular organization
38 vmwarecli.py -u admin -p qwerty123 -c 172.16.254.206 -U Administrator -P qwerty123 -o test -v TEF list vdc
39
40 Upload image
41 python vmwarerecli.py image upload /Users/spyroot/Developer/Openmano/Ro/vnfs/cirros/cirros.ovf
42
43 Boot Image
44 python vmwarerecli.py -u admin -p qwerty123 -c 172.16.254.206 -o test -v TEF image boot cirros cirros
45
46 View vApp
47 python vmwarerecli.py -u admin -p qwerty123 -c 172.16.254.206 -o test -v TEF view vapp 90bd2b4e-f782-46cf-b5e2-c3817dcf6633 -u
48
49 List VMS
50 python vmwarerecli.py -u admin -p qwerty123 -c 172.16.254.206 -o test -v TEF list vms
51
52 List VDC in OSM format
53 python vmwarerecli.py -u admin -p qwerty123 -c 172.16.254.206 -o test -v TEF list vdc -o
54
55Mustaafa Bayramov
bayramov6c0e3d42016-09-27 03:03:32 -070056mbayramov@vmware.com
bayramovb6ffe792016-09-28 11:50:56 +040057"""
bayramov6c0e3d42016-09-27 03:03:32 -070058import os
bayramov6c0e3d42016-09-27 03:03:32 -070059import argparse
60import traceback
bayramovb6ffe792016-09-28 11:50:56 +040061import uuid
bayramov6c0e3d42016-09-27 03:03:32 -070062
63from xml.etree import ElementTree as ET
64
bayramovfe3f3c92016-10-04 07:53:41 +040065import sys
bayramov6c0e3d42016-09-27 03:03:32 -070066from pyvcloud import Http
bayramov6c0e3d42016-09-27 03:03:32 -070067
68import logging
bayramov6c0e3d42016-09-27 03:03:32 -070069import vimconn
70import time
71import uuid
bayramov6c0e3d42016-09-27 03:03:32 -070072import urllib3
73import requests
74
75from vimconn_vmware import vimconnector
76from requests.packages.urllib3.exceptions import InsecureRequestWarning
77from prettytable import PrettyTable
bayramov6c0e3d42016-09-27 03:03:32 -070078
79requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
80
81__author__ = "Mustafa Bayramov"
82__date__ = "$16-Sep-2016 11:09:29$"
83
84
bayramovb6ffe792016-09-28 11:50:56 +040085# TODO move to main vim
bayramov6c0e3d42016-09-27 03:03:32 -070086def delete_network_action(vca=None, network_uuid=None):
87 """
88 Method leverages vCloud director and query network based on network uuid
89
90 Args:
91 vca - is active VCA connection.
92 network_uuid - is a network uuid
93
94 Returns:
95 The return XML respond
96 """
97
98 if vca is None or network_uuid is None:
99 return None
100
101 url_list = [vca.host, '/api/admin/network/', network_uuid]
102 vm_list_rest_call = ''.join(url_list)
103
104 if not (not vca.vcloud_session or not vca.vcloud_session.organization):
105 response = Http.get(url=vm_list_rest_call,
106 headers=vca.vcloud_session.get_vcloud_headers(),
107 verify=vca.verify,
108 logger=vca.logger)
109 if response.status_code == requests.codes.ok:
110 print response.content
111 return response.content
112
113 return None
114
115
116def print_vapp(vapp_dict=None):
117 """ Method takes vapp_dict and print in tabular format
118
119 Args:
120 vapp_dict: container vapp object.
121
122 Returns:
123 The return nothing
124 """
125
126 # following key available to print
bayramov6c0e3d42016-09-27 03:03:32 -0700127 # {'status': 'POWERED_OFF', 'storageProfileName': '*', 'hardwareVersion': '7', 'vmToolsVersion': '0',
128 # 'memoryMB': '384',
129 # 'href': 'https://172.16.254.206/api/vAppTemplate/vm-129e22e8-08dc-4cb6-8358-25f635e65d3b',
130 # 'isBusy': 'false', 'isDeployed': 'false', 'isInMaintenanceMode': 'false', 'isVAppTemplate': 'true',
131 # 'networkName': 'nat', 'isDeleted': 'false', 'catalogName': 'Cirros',
bayramovb6ffe792016-09-28 11:50:56 +0400132 # 'containerName': 'Cirros Template', # 'container':
133 # 'https://172.16.254.206/api/vAppTemplate/vappTemplate-b966453d-c361-4505-9e38-ccef45815e5d',
bayramov6c0e3d42016-09-27 03:03:32 -0700134 # 'name': 'Cirros', 'pvdcHighestSupportedHardwareVersion': '11', 'isPublished': 'false',
135 # 'numberOfCpus': '1', 'vdc': 'https://172.16.254.206/api/vdc/a5056f85-418c-4bfd-8041-adb0f48be9d9',
136 # 'guestOs': 'Other (32-bit)', 'isVdcEnabled': 'true'}
137
138 if vapp_dict is None:
139 return
140
bayramovb6ffe792016-09-28 11:50:56 +0400141 vm_table = PrettyTable(['vm uuid',
bayramov6c0e3d42016-09-27 03:03:32 -0700142 'vapp name',
bayramovb6ffe792016-09-28 11:50:56 +0400143 'vapp uuid',
bayramov6c0e3d42016-09-27 03:03:32 -0700144 'network name',
bayramovb6ffe792016-09-28 11:50:56 +0400145 'storage name',
146 'vcpu', 'memory', 'hw ver','deployed','status'])
bayramov6c0e3d42016-09-27 03:03:32 -0700147 for k in vapp_dict:
148 entry = []
149 entry.append(k)
150 entry.append(vapp_dict[k]['containerName'])
bayramovb6ffe792016-09-28 11:50:56 +0400151 # vm-b1f5cd4c-2239-4c89-8fdc-a41ff18e0d61
152 entry.append(vapp_dict[k]['container'].split('/')[-1:][0][5:])
bayramov6c0e3d42016-09-27 03:03:32 -0700153 entry.append(vapp_dict[k]['networkName'])
bayramov6c0e3d42016-09-27 03:03:32 -0700154 entry.append(vapp_dict[k]['storageProfileName'])
155 entry.append(vapp_dict[k]['numberOfCpus'])
156 entry.append(vapp_dict[k]['memoryMB'])
157 entry.append(vapp_dict[k]['pvdcHighestSupportedHardwareVersion'])
bayramovb6ffe792016-09-28 11:50:56 +0400158 entry.append(vapp_dict[k]['isDeployed'])
159 entry.append(vapp_dict[k]['status'])
bayramov6c0e3d42016-09-27 03:03:32 -0700160
161 vm_table.add_row(entry)
162
163 print vm_table
164
165
166def print_org(org_dict=None):
167 """ Method takes vapp_dict and print in tabular format
168
169 Args:
170 org_dict: dictionary of organization where key is org uuid.
171
172 Returns:
173 The return nothing
174 """
175
176 if org_dict is None:
177 return
178
179 org_table = PrettyTable(['org uuid', 'name'])
180 for k in org_dict:
181 entry = [k, org_dict[k]]
182 org_table.add_row(entry)
183
184 print org_table
185
186
187def print_vm_list(vm_dict=None):
188 """ Method takes vapp_dict and print in tabular format
189
190 Args:
bayramovb6ffe792016-09-28 11:50:56 +0400191 vm_dict: dictionary of organization where key is org uuid.
bayramov6c0e3d42016-09-27 03:03:32 -0700192
193 Returns:
194 The return nothing
195 """
196 if vm_dict is None:
197 return
198
199 vm_table = PrettyTable(
200 ['vm uuid', 'vm name', 'vapp uuid', 'vdc uuid', 'network name', 'is deployed', 'vcpu', 'memory', 'status'])
201
202 try:
203 for k in vm_dict:
204 entry = []
205 entry.append(k)
206 entry.append(vm_dict[k]['name'])
207 entry.append(vm_dict[k]['container'].split('/')[-1:][0][5:])
208 entry.append(vm_dict[k]['vdc'].split('/')[-1:][0])
209 entry.append(vm_dict[k]['networkName'])
210 entry.append(vm_dict[k]['isDeployed'])
211 entry.append(vm_dict[k]['numberOfCpus'])
212 entry.append(vm_dict[k]['memoryMB'])
213 entry.append(vm_dict[k]['status'])
214 vm_table.add_row(entry)
215 print vm_table
216 except KeyError:
217 logger.error("wrong key {}".format(KeyError.message))
218 pass
219
220
bayramovb6ffe792016-09-28 11:50:56 +0400221def print_vdc_list(org_dict=None):
222 """ Method takes vapp_dict and print in tabular format
223
224 Args:
225 org_dict: dictionary of organization where key is org uuid.
226
227 Returns:
228 The return nothing
229 """
230 if org_dict is None:
231 return
232 try:
233 vdcs_dict = {}
234 if org_dict.has_key('vdcs'):
235 vdcs_dict = org_dict['vdcs']
236 vdc_table = PrettyTable(['vdc uuid', 'vdc name'])
237 for k in vdcs_dict:
238 entry = [k, vdcs_dict[k]]
239 vdc_table.add_row(entry)
240
241 print vdc_table
242 except KeyError:
243 logger.error("wrong key {}".format(KeyError.message))
244 logger.logger.debug(traceback.format_exc())
245
246
247def print_network_list(org_dict=None):
248 """ Method print network list.
249
250 Args:
251 org_dict: dictionary of organization that contain key networks with a list of all
252 network for for specific VDC
253
254 Returns:
255 The return nothing
256 """
257 if org_dict is None:
258 return
259 try:
260 network_dict = {}
261 if org_dict.has_key('networks'):
262 network_dict = org_dict['networks']
263 network_table = PrettyTable(['network uuid', 'network name'])
264 for k in network_dict:
265 entry = [k, network_dict[k]]
266 network_table.add_row(entry)
267
268 print network_table
269
270 except KeyError:
271 logger.error("wrong key {}".format(KeyError.message))
272 logger.logger.debug(traceback.format_exc())
273
274
bayramov6c0e3d42016-09-27 03:03:32 -0700275def print_org_details(org_dict=None):
276 """ Method takes vapp_dict and print in tabular format
277
278 Args:
279 org_dict: dictionary of organization where key is org uuid.
280
281 Returns:
282 The return nothing
283 """
284 if org_dict is None:
285 return
286 try:
bayramov6c0e3d42016-09-27 03:03:32 -0700287 catalogs_dict = {}
bayramov6c0e3d42016-09-27 03:03:32 -0700288
bayramovb6ffe792016-09-28 11:50:56 +0400289 print_vdc_list(org_dict=org_dict)
290 print_network_list(org_dict=org_dict)
bayramov6c0e3d42016-09-27 03:03:32 -0700291
292 if org_dict.has_key('catalogs'):
293 catalogs_dict = org_dict['catalogs']
294
bayramov6c0e3d42016-09-27 03:03:32 -0700295 catalog_table = PrettyTable(['catalog uuid', 'catalog name'])
296 for k in catalogs_dict:
297 entry = [k, catalogs_dict[k]]
298 catalog_table.add_row(entry)
299
bayramov6c0e3d42016-09-27 03:03:32 -0700300 print catalog_table
301
302 except KeyError:
303 logger.error("wrong key {}".format(KeyError.message))
304 logger.logger.debug(traceback.format_exc())
305
306
307def delete_actions(vim=None, action=None, namespace=None):
308 if action == 'network' or namespace.action == 'network':
309 logger.debug("Requesting delete for network {}".format(namespace.network_name))
310 network_uuid = namespace.network_name
311 # if request name based we need find UUID
312 # TODO optimize it or move to external function
313 if not namespace.uuid:
314 org_dict = vim.get_org_list()
315 for org in org_dict:
316 org_net = vim.get_org(org)['networks']
317 for network in org_net:
318 if org_net[network] == namespace.network_name:
319 network_uuid = network
320
321 vim.delete_network_action(network_uuid=network_uuid)
322
323
324def list_actions(vim=None, action=None, namespace=None):
bayramovb6ffe792016-09-28 11:50:56 +0400325 """ Method provide list object from VDC action
326
327 Args:
328 vim - is vcloud director vim connector.
329 action - is action for list ( vdc / org etc)
330 namespace - must contain VDC / Org information.
331
332 Returns:
333 The return nothing
334 """
335
336 org_id = None
337 myorgs = vim.get_org_list()
338 for org in myorgs:
339 if myorgs[org] == namespace.vcdorg:
340 org_id = org
341 break
342 else:
343 print(" Invalid organization.")
344 return
345
bayramov6c0e3d42016-09-27 03:03:32 -0700346 if action == 'vms' or namespace.action == 'vms':
347 vm_dict = vim.get_vm_list(vdc_name=namespace.vcdvdc)
348 print_vm_list(vm_dict=vm_dict)
349 elif action == 'vapps' or namespace.action == 'vapps':
350 vapp_dict = vim.get_vapp_list(vdc_name=namespace.vcdvdc)
351 print_vapp(vapp_dict=vapp_dict)
352 elif action == 'networks' or namespace.action == 'networks':
bayramovb6ffe792016-09-28 11:50:56 +0400353 if namespace.osm:
354 osm_print(vim.get_network_list(filter_dict={}))
355 else:
356 print_network_list(vim.get_org(org_uuid=org_id))
bayramov6c0e3d42016-09-27 03:03:32 -0700357 elif action == 'vdc' or namespace.action == 'vdc':
bayramovb6ffe792016-09-28 11:50:56 +0400358 if namespace.osm:
359 osm_print(vim.get_tenant_list(filter_dict=None))
360 else:
361 print_vdc_list(vim.get_org(org_uuid=org_id))
bayramov6c0e3d42016-09-27 03:03:32 -0700362 elif action == 'org' or namespace.action == 'org':
bayramov6c0e3d42016-09-27 03:03:32 -0700363 print_org(org_dict=vim.get_org_list())
364 else:
365 return None
366
367
bayramovb6ffe792016-09-28 11:50:56 +0400368def print_network_details(network_dict=None):
369 try:
370 network_table = PrettyTable(network_dict.keys())
371 entry = [network_dict.values()]
372 network_table.add_row(entry[0])
373 print network_table
374 except KeyError:
375 logger.error("wrong key {}".format(KeyError.message))
376 logger.logger.debug(traceback.format_exc())
377
378
379def osm_print(generic_dict=None):
380
381 try:
382 for element in generic_dict:
383 table = PrettyTable(element.keys())
384 entry = [element.values()]
385 table.add_row(entry[0])
386 print table
387 except KeyError:
388 logger.error("wrong key {}".format(KeyError.message))
389 logger.logger.debug(traceback.format_exc())
390
391
bayramov6c0e3d42016-09-27 03:03:32 -0700392def view_actions(vim=None, action=None, namespace=None):
bayramovb6ffe792016-09-28 11:50:56 +0400393 org_id = None
394 orgs = vim.get_org_list()
395 for org in orgs:
396 if orgs[org] == namespace.vcdorg:
397 org_id = org
398 break
399 else:
400 print(" Invalid organization.")
401 return
402
403 myorg = vim.get_org(org_uuid=org_id)
404
bayramov6c0e3d42016-09-27 03:03:32 -0700405 # view org
406 if action == 'org' or namespace.action == 'org':
407 org_id = None
408 orgs = vim.get_org_list()
409 if namespace.uuid:
410 if namespace.org_name in orgs:
411 org_id = namespace.org_name
412 else:
413 # we need find UUID based on name provided
414 for org in orgs:
415 if orgs[org] == namespace.org_name:
416 org_id = org
417 break
418
419 logger.debug("Requesting view for orgs {}".format(org_id))
420 print_org_details(vim.get_org(org_uuid=org_id))
421
422 # view vapp action
423 if action == 'vapp' or namespace.action == 'vapp':
bayramovb6ffe792016-09-28 11:50:56 +0400424 if namespace.vapp_name is not None and namespace.uuid:
bayramov6c0e3d42016-09-27 03:03:32 -0700425 logger.debug("Requesting vapp {} for vdc {}".format(namespace.vapp_name, namespace.vcdvdc))
bayramov6c0e3d42016-09-27 03:03:32 -0700426 vapp_dict = {}
bayramovb6ffe792016-09-28 11:50:56 +0400427 vapp_uuid = namespace.vapp_name
bayramov6c0e3d42016-09-27 03:03:32 -0700428 # if request based on just name we need get UUID
429 if not namespace.uuid:
bayramovb6ffe792016-09-28 11:50:56 +0400430 vapp_uuid = vim.get_vappid(vdc=namespace.vcdvdc, vapp_name=namespace.vapp_name)
431 if vapp_uuid is None:
432 print("Can't find vapp by given name {}".format(namespace.vapp_name))
433 return
bayramov6c0e3d42016-09-27 03:03:32 -0700434
bayramovfe3f3c92016-10-04 07:53:41 +0400435 print " namespace {}".format(namespace)
436 if vapp_dict is not None and namespace.osm:
437 vm_info_dict = vim.get_vminstance(vim_vm_uuid=vapp_uuid)
438 print vm_info_dict
439 if vapp_dict is not None and namespace.osm != True:
440 vapp_dict = vim.get_vapp(vdc_name=namespace.vcdvdc, vapp_name=vapp_uuid, isuuid=True)
bayramovb6ffe792016-09-28 11:50:56 +0400441 print_vapp(vapp_dict=vapp_dict)
bayramov6c0e3d42016-09-27 03:03:32 -0700442
443 # view network
444 if action == 'network' or namespace.action == 'network':
445 logger.debug("Requesting view for network {}".format(namespace.network_name))
446 network_uuid = namespace.network_name
447 # if request name based we need find UUID
448 # TODO optimize it or move to external function
449 if not namespace.uuid:
bayramovb6ffe792016-09-28 11:50:56 +0400450 if not myorg.has_key('networks'):
451 print("Network {} is undefined in vcloud director for org {} vdc {}".format(namespace.network_name,
452 vim.name,
453 vim.tenant_name))
454 return
bayramov6c0e3d42016-09-27 03:03:32 -0700455
bayramovb6ffe792016-09-28 11:50:56 +0400456 my_org_net = myorg['networks']
457 for network in my_org_net:
458 if my_org_net[network] == namespace.network_name:
459 network_uuid = network
460 break
461
462 print print_network_details(network_dict=vim.get_vcd_network(network_uuid=network_uuid))
bayramov6c0e3d42016-09-27 03:03:32 -0700463
464
465def create_actions(vim=None, action=None, namespace=None):
466 """Method gets provider vdc view from vcloud director
467
468 Args:
469 vim - is Cloud director vim connector
470 action - action for create ( network / vdc etc)
471
472 Returns:
473 The return xml content of respond or None
474 """
475 if action == 'network' or namespace.action == 'network':
476 logger.debug("Creating a network in vcloud director".format(namespace.network_name))
477 network_uuid = vim.create_network(namespace.network_name)
478 if network_uuid is not None:
479 print ("Crated new network {} and uuid: {}".format(namespace.network_name, network_uuid))
480 else:
481 print ("Failed create a new network {}".format(namespace.network_name))
482 elif action == 'vdc' or namespace.action == 'vdc':
483 logger.debug("Creating a new vdc in vcloud director.".format(namespace.vdc_name))
484 vdc_uuid = vim.create_vdc(namespace.vdc_name)
485 if vdc_uuid is not None:
486 print ("Crated new vdc {} and uuid: {}".format(namespace.vdc_name, vdc_uuid))
487 else:
488 print ("Failed create a new vdc {}".format(namespace.vdc_name))
489 else:
490 return None
491
492
bayramovb6ffe792016-09-28 11:50:56 +0400493def validate_uuid4(uuid_string):
494 """Function validate that string contain valid uuid4
bayramov6c0e3d42016-09-27 03:03:32 -0700495
bayramovb6ffe792016-09-28 11:50:56 +0400496 Args:
497 uuid_string - valid UUID string
498
499 Returns:
500 The return true if string contain valid UUID format
501 """
502 try:
503 val = uuid.UUID(uuid_string, version=4)
504 except ValueError:
505 return False
506 return True
507
508
509def upload_image(vim=None, image_file=None):
510 """Function upload image to vcloud director
511
512 Args:
513 image_file - valid UUID string
514
515 Returns:
516 The return true if image uploaded correctly
517 """
518 try:
bayramovfe3f3c92016-10-04 07:53:41 +0400519 catalog_uuid = vim.get_image_id_from_path(path=image_file, progress=True)
bayramovb6ffe792016-09-28 11:50:56 +0400520 if catalog_uuid is not None and validate_uuid4(catalog_uuid):
521 print("Image uploaded and uuid {}".format(catalog_uuid))
522 return True
bayramovfe3f3c92016-10-04 07:53:41 +0400523 except vimconn.vimconnException as upload_exception:
bayramovb6ffe792016-09-28 11:50:56 +0400524 print("Failed uploaded {} image".format(image_file))
bayramovfe3f3c92016-10-04 07:53:41 +0400525 print("Error Reason: {}".format(upload_exception.message))
bayramovb6ffe792016-09-28 11:50:56 +0400526 return False
527
528
529def boot_image(vim=None, image_name=None, vm_name=None):
530 """ Function boot image that resided in vcloud director.
531 The image name can be UUID of name.
532
533 Args:
bayramov163f1ae2016-09-28 17:16:55 +0400534 vim - vim connector
535 image_name - image identified by UUID or text string.
536 vm_name - vmname
537
bayramovb6ffe792016-09-28 11:50:56 +0400538
539 Returns:
540 The return true if image uploaded correctly
541 """
542
543 vim_catalog = None
544 try:
545 catalogs = vim.vca.get_catalogs()
546 if not validate_uuid4(image_name):
547 vim_catalog = vim.get_catalogid(catalog_name=image_name, catalogs=catalogs)
548 if vim_catalog is None:
549 return None
550 else:
551 vim_catalog = vim.get_catalogid(catalog_name=image_name, catalogs=catalogs)
552 if vim_catalog is None:
553 return None
554
bayramov5761ad12016-10-04 09:00:30 +0400555 print (" Booting {} image id {} ".format(vm_name, vim_catalog))
bayramovb6ffe792016-09-28 11:50:56 +0400556 vm_uuid = vim.new_vminstance(name=vm_name, image_id=vim_catalog)
557 if vm_uuid is not None and validate_uuid4(vm_uuid):
558 print("Image booted and vm uuid {}".format(vm_uuid))
559 vapp_dict = vim.get_vapp(vdc_name=namespace.vcdvdc, vapp_name=vm_uuid, isuuid=True)
560 if vapp_dict is not None:
561 print_vapp(vapp_dict=vapp_dict)
562 return True
bayramov5761ad12016-10-04 09:00:30 +0400563 except vimconn.vimconnNotFoundException as notFound:
564 print("Failed boot {} image".format(image_name))
565 print(notFound.message)
566 except vimconn.vimconnException as vimconError:
567 print("Failed boot {} image".format(image_name))
568 print(vimconError.message)
bayramovb6ffe792016-09-28 11:50:56 +0400569 except:
bayramov5761ad12016-10-04 09:00:30 +0400570 print("Failed boot {} image".format(image_name))
bayramovb6ffe792016-09-28 11:50:56 +0400571
bayramov5761ad12016-10-04 09:00:30 +0400572
573 return False
bayramovfe3f3c92016-10-04 07:53:41 +0400574
bayramovb6ffe792016-09-28 11:50:56 +0400575
576def image_action(vim=None, action=None, namespace=None):
577 """ Function present set of action to manipulate with image.
578 - upload image
579 - boot image.
580 - delete image ( not yet done )
581
582 Args:
583 vim - vcloud director connector
584 action - string (upload/boot etc)
585 namespace - contain other attributes image name etc
586
587 Returns:
588 The return nothing
589 """
590
591 if action == 'upload' or namespace.action == 'upload':
592 upload_image(vim=vim, image_file=namespace.image)
593 elif action == 'boot' or namespace.action == 'boot':
594 boot_image(vim=vim, image_name=namespace.image, vm_name=namespace.vmname)
595 else:
596 return None
597
598
599def vmwarecli(command=None, action=None, namespace=None):
bayramova09cf382016-09-28 04:13:46 +0400600 logger.debug("Namespace {}".format(namespace))
bayramov6c0e3d42016-09-27 03:03:32 -0700601 urllib3.disable_warnings()
bayramov6c0e3d42016-09-27 03:03:32 -0700602
bayramovb6ffe792016-09-28 11:50:56 +0400603 vcduser = None
604 vcdpasword = None
605 vcdhost = None
606 vcdorg = None
607
608 if hasattr(__builtins__, 'raw_input'):
609 input = raw_input
610
611 if namespace.vcdvdc is None:
612 while True:
613 vcduser = input("Enter vcd username: ")
614 if vcduser is not None and len(vcduser) > 0:
615 break
616 else:
617 vcduser = namespace.vcduser
618
bayramova09cf382016-09-28 04:13:46 +0400619 if namespace.vcdpassword is None:
bayramovb6ffe792016-09-28 11:50:56 +0400620 while True:
621 vcdpasword = input("Please enter vcd password: ")
622 if vcdpasword is not None and len(vcdpasword) > 0:
623 break
bayramova09cf382016-09-28 04:13:46 +0400624 else:
625 vcdpasword = namespace.vcdpassword
bayramovb6ffe792016-09-28 11:50:56 +0400626
627 if namespace.vcdhost is None:
628 while True:
629 vcdhost = input("Please enter vcd host name or ip: ")
630 if vcdhost is not None and len(vcdhost) > 0:
631 break
632 else:
633 vcdhost = namespace.vcdhost
634
635 if namespace.vcdorg is None:
636 while True:
637 vcdorg = input("Please enter vcd organization name: ")
638 if vcdorg is not None and len(vcdorg) > 0:
639 break
640 else:
641 vcdorg = namespace.vcdorg
642
643 try:
644 vim = vimconnector(uuid=None,
645 name=vcdorg,
646 tenant_id=None,
647 tenant_name=namespace.vcdvdc,
648 url=vcdhost,
649 url_admin=vcdhost,
650 user=vcduser,
651 passwd=vcdpasword,
652 log_level="DEBUG",
653 config={'admin_username': namespace.vcdamdin, 'admin_password': namespace.vcdadminpassword})
654 vim.vca = vim.connect()
bayramovfe3f3c92016-10-04 07:53:41 +0400655
bayramovb6ffe792016-09-28 11:50:56 +0400656 except vimconn.vimconnConnectionException:
657 print("Failed connect to vcloud director. Please check credential and hostname.")
658 return
bayramov6c0e3d42016-09-27 03:03:32 -0700659
660 # list
661 if command == 'list' or namespace.command == 'list':
662 logger.debug("Client requested list action")
663 # route request to list actions
664 list_actions(vim=vim, action=action, namespace=namespace)
665
666 # view action
667 if command == 'view' or namespace.command == 'view':
668 logger.debug("Client requested view action")
669 view_actions(vim=vim, action=action, namespace=namespace)
670
671 # delete action
672 if command == 'delete' or namespace.command == 'delete':
673 logger.debug("Client requested delete action")
674 delete_actions(vim=vim, action=action, namespace=namespace)
675
676 # create action
677 if command == 'create' or namespace.command == 'create':
678 logger.debug("Client requested create action")
679 create_actions(vim=vim, action=action, namespace=namespace)
680
bayramovb6ffe792016-09-28 11:50:56 +0400681 # image action
682 if command == 'image' or namespace.command == 'image':
683 logger.debug("Client requested create action")
684 image_action(vim=vim, action=action, namespace=namespace)
685
bayramov6c0e3d42016-09-27 03:03:32 -0700686
bayramov6c0e3d42016-09-27 03:03:32 -0700687if __name__ == '__main__':
688 defaults = {'vcdvdc': 'default',
689 'vcduser': 'admin',
690 'vcdpassword': 'admin',
691 'vcdhost': 'https://localhost',
692 'vcdorg': 'default',
693 'debug': 'INFO'}
694
695 parser = argparse.ArgumentParser()
696 parser.add_argument('-u', '--vcduser', help='vcloud director username', type=str)
697 parser.add_argument('-p', '--vcdpassword', help='vcloud director password', type=str)
bayramova09cf382016-09-28 04:13:46 +0400698 parser.add_argument('-U', '--vcdamdin', help='vcloud director password', type=str)
699 parser.add_argument('-P', '--vcdadminpassword', help='vcloud director password', type=str)
bayramov6c0e3d42016-09-27 03:03:32 -0700700 parser.add_argument('-c', '--vcdhost', help='vcloud director host', type=str)
701 parser.add_argument('-o', '--vcdorg', help='vcloud director org', type=str)
702 parser.add_argument('-v', '--vcdvdc', help='vcloud director vdc', type=str)
703 parser.add_argument('-d', '--debug', help='debug level', type=int)
704
705 parser_subparsers = parser.add_subparsers(help='commands', dest='command')
706 sub = parser_subparsers.add_parser('list', help='List objects (VMs, vApps, networks)')
707 sub_subparsers = sub.add_subparsers(dest='action')
bayramovb6ffe792016-09-28 11:50:56 +0400708
709 list_vms = sub_subparsers.add_parser('vms', help='list - all vm deployed in vCloud director')
710 list_vapps = sub_subparsers.add_parser('vapps', help='list - all vapps deployed in vCloud director')
711 list_network = sub_subparsers.add_parser('networks', help='list - all networks deployed')
712 list_network.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
713
714 #list vdc
715 list_vdc = sub_subparsers.add_parser('vdc', help='list - list all vdc for organization accessible to you')
716 list_vdc.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
717
718 list_org = sub_subparsers.add_parser('org', help='list - list of organizations accessible to you.')
bayramov6c0e3d42016-09-27 03:03:32 -0700719
720 create_sub = parser_subparsers.add_parser('create')
721 create_sub_subparsers = create_sub.add_subparsers(dest='action')
722 create_vms = create_sub_subparsers.add_parser('vms')
723 create_vapp = create_sub_subparsers.add_parser('vapp')
724 create_vapp.add_argument('uuid')
725
726 # add network
727 create_network = create_sub_subparsers.add_parser('network')
728 create_network.add_argument('network_name', action='store', help='create a network for a vdc')
729
730 # add VDC
731 create_vdc = create_sub_subparsers.add_parser('vdc')
732 create_vdc.add_argument('vdc_name', action='store', help='create a new VDC for org')
733
734 delete_sub = parser_subparsers.add_parser('delete')
735 del_sub_subparsers = delete_sub.add_subparsers(dest='action')
736 del_vms = del_sub_subparsers.add_parser('vms')
737 del_vapp = del_sub_subparsers.add_parser('vapp')
738 del_vapp.add_argument('uuid', help='view vapp based on UUID')
739
740 # delete network
741 del_network = del_sub_subparsers.add_parser('network')
742 del_network.add_argument('network_name', action='store',
743 help='- delete network for vcloud director by provided name')
744 del_network.add_argument('-u', '--uuid', default=False, action='store_true',
745 help='delete network for vcloud director by provided uuid')
746
747 # delete vdc
748 del_vdc = del_sub_subparsers.add_parser('vdc')
749
750 view_sub = parser_subparsers.add_parser('view')
751 view_sub_subparsers = view_sub.add_subparsers(dest='action')
752
753 view_vms_parser = view_sub_subparsers.add_parser('vms')
754 view_vms_parser.add_argument('uuid', default=False, action='store_true',
755 help='- View VM for specific uuid in vcloud director')
756 view_vms_parser.add_argument('name', default=False, action='store_true',
757 help='- View VM for specific vapp name in vcloud director')
758
759 # view vapp
760 view_vapp_parser = view_sub_subparsers.add_parser('vapp')
761 view_vapp_parser.add_argument('vapp_name', action='store',
762 help='- view vapp for specific vapp name in vcloud director')
763 view_vapp_parser.add_argument('-u', '--uuid', default=False, action='store_true', help='view vapp based on uuid')
bayramovfe3f3c92016-10-04 07:53:41 +0400764 view_vapp_parser.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
bayramov6c0e3d42016-09-27 03:03:32 -0700765
766 # view network
767 view_network = view_sub_subparsers.add_parser('network')
768 view_network.add_argument('network_name', action='store',
769 help='- view network for specific network name in vcloud director')
770 view_network.add_argument('-u', '--uuid', default=False, action='store_true', help='view network based on uuid')
771
772 # view VDC command and actions
773 view_vdc = view_sub_subparsers.add_parser('vdc')
774 view_vdc.add_argument('vdc_name', action='store',
775 help='- View VDC based and action based on provided vdc uuid')
776 view_vdc.add_argument('-u', '--uuid', default=False, action='store_true', help='view vdc based on uuid')
777
778 # view organization command and actions
779 view_org = view_sub_subparsers.add_parser('org')
780 view_org.add_argument('org_name', action='store',
781 help='- View VDC based and action based on provided vdc uuid')
782 view_org.add_argument('-u', '--uuid', default=False, action='store_true', help='view org based on uuid')
783
bayramovb6ffe792016-09-28 11:50:56 +0400784 # upload image action
785 image_sub = parser_subparsers.add_parser('image')
786 image_subparsers = image_sub.add_subparsers(dest='action')
787 upload_parser = image_subparsers.add_parser('upload')
788 upload_parser.add_argument('image', default=False, action='store', help='- valid path to OVF image ')
789 upload_parser.add_argument('catalog', default=False, action='store_true', help='- catalog name')
790
791 # boot vm action
792 boot_parser = image_subparsers.add_parser('boot')
793 boot_parser.add_argument('image', default=False, action='store', help='- Image name')
794 boot_parser.add_argument('vmname', default=False, action='store', help='- VM name')
795 boot_parser.add_argument('-u', '--uuid', default=False, action='store_true', help='view org based on uuid')
bayramov6c0e3d42016-09-27 03:03:32 -0700796
797 namespace = parser.parse_args()
798 # put command_line args to mapping
799 command_line_args = {k: v for k, v in vars(namespace).items() if v}
800
801 d = defaults.copy()
802 d.update(os.environ)
803 d.update(command_line_args)
804
805 logger = logging.getLogger('mano.vim.vmware')
806 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
807 ch = logging.StreamHandler()
808 ch.setLevel(str.upper(d['debug']))
809 ch.setFormatter(formatter)
810 logger.addHandler(ch)
811 logger.setLevel(getattr(logging, str.upper(d['debug'])))
812 logger.info(
813 "Connecting {} username: {} org: {} vdc: {} ".format(d['vcdhost'], d['vcduser'], d['vcdorg'], d['vcdvdc']))
814
815 logger.debug("command: \"{}\" actio: \"{}\"".format(d['command'], d['action']))
bayramova09cf382016-09-28 04:13:46 +0400816
817 # main entry point.
bayramov6c0e3d42016-09-27 03:03:32 -0700818 vmwarecli(namespace=namespace)