blob: 547abf96a7f206bb4a91cb80b2d07a61ec64962c [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
65from pyvcloud import Http
bayramov6c0e3d42016-09-27 03:03:32 -070066
67import logging
bayramov6c0e3d42016-09-27 03:03:32 -070068import vimconn
69import time
70import uuid
bayramov6c0e3d42016-09-27 03:03:32 -070071import urllib3
72import requests
73
74from vimconn_vmware import vimconnector
75from requests.packages.urllib3.exceptions import InsecureRequestWarning
76from prettytable import PrettyTable
bayramov6c0e3d42016-09-27 03:03:32 -070077
78requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
79
80__author__ = "Mustafa Bayramov"
81__date__ = "$16-Sep-2016 11:09:29$"
82
83
bayramovb6ffe792016-09-28 11:50:56 +040084# TODO move to main vim
bayramov6c0e3d42016-09-27 03:03:32 -070085def delete_network_action(vca=None, network_uuid=None):
86 """
87 Method leverages vCloud director and query network based on network uuid
88
89 Args:
90 vca - is active VCA connection.
91 network_uuid - is a network uuid
92
93 Returns:
94 The return XML respond
95 """
96
97 if vca is None or network_uuid is None:
98 return None
99
100 url_list = [vca.host, '/api/admin/network/', network_uuid]
101 vm_list_rest_call = ''.join(url_list)
102
103 if not (not vca.vcloud_session or not vca.vcloud_session.organization):
104 response = Http.get(url=vm_list_rest_call,
105 headers=vca.vcloud_session.get_vcloud_headers(),
106 verify=vca.verify,
107 logger=vca.logger)
108 if response.status_code == requests.codes.ok:
109 print response.content
110 return response.content
111
112 return None
113
114
115def print_vapp(vapp_dict=None):
116 """ Method takes vapp_dict and print in tabular format
117
118 Args:
119 vapp_dict: container vapp object.
120
121 Returns:
122 The return nothing
123 """
124
125 # following key available to print
bayramov6c0e3d42016-09-27 03:03:32 -0700126 # {'status': 'POWERED_OFF', 'storageProfileName': '*', 'hardwareVersion': '7', 'vmToolsVersion': '0',
127 # 'memoryMB': '384',
128 # 'href': 'https://172.16.254.206/api/vAppTemplate/vm-129e22e8-08dc-4cb6-8358-25f635e65d3b',
129 # 'isBusy': 'false', 'isDeployed': 'false', 'isInMaintenanceMode': 'false', 'isVAppTemplate': 'true',
130 # 'networkName': 'nat', 'isDeleted': 'false', 'catalogName': 'Cirros',
bayramovb6ffe792016-09-28 11:50:56 +0400131 # 'containerName': 'Cirros Template', # 'container':
132 # 'https://172.16.254.206/api/vAppTemplate/vappTemplate-b966453d-c361-4505-9e38-ccef45815e5d',
bayramov6c0e3d42016-09-27 03:03:32 -0700133 # 'name': 'Cirros', 'pvdcHighestSupportedHardwareVersion': '11', 'isPublished': 'false',
134 # 'numberOfCpus': '1', 'vdc': 'https://172.16.254.206/api/vdc/a5056f85-418c-4bfd-8041-adb0f48be9d9',
135 # 'guestOs': 'Other (32-bit)', 'isVdcEnabled': 'true'}
136
137 if vapp_dict is None:
138 return
139
bayramovb6ffe792016-09-28 11:50:56 +0400140 vm_table = PrettyTable(['vm uuid',
bayramov6c0e3d42016-09-27 03:03:32 -0700141 'vapp name',
bayramovb6ffe792016-09-28 11:50:56 +0400142 'vapp uuid',
bayramov6c0e3d42016-09-27 03:03:32 -0700143 'network name',
bayramovb6ffe792016-09-28 11:50:56 +0400144 'storage name',
145 'vcpu', 'memory', 'hw ver','deployed','status'])
bayramov6c0e3d42016-09-27 03:03:32 -0700146 for k in vapp_dict:
147 entry = []
148 entry.append(k)
149 entry.append(vapp_dict[k]['containerName'])
bayramovb6ffe792016-09-28 11:50:56 +0400150 # vm-b1f5cd4c-2239-4c89-8fdc-a41ff18e0d61
151 entry.append(vapp_dict[k]['container'].split('/')[-1:][0][5:])
bayramov6c0e3d42016-09-27 03:03:32 -0700152 entry.append(vapp_dict[k]['networkName'])
bayramov6c0e3d42016-09-27 03:03:32 -0700153 entry.append(vapp_dict[k]['storageProfileName'])
154 entry.append(vapp_dict[k]['numberOfCpus'])
155 entry.append(vapp_dict[k]['memoryMB'])
156 entry.append(vapp_dict[k]['pvdcHighestSupportedHardwareVersion'])
bayramovb6ffe792016-09-28 11:50:56 +0400157 entry.append(vapp_dict[k]['isDeployed'])
158 entry.append(vapp_dict[k]['status'])
bayramov6c0e3d42016-09-27 03:03:32 -0700159
160 vm_table.add_row(entry)
161
162 print vm_table
163
164
165def print_org(org_dict=None):
166 """ Method takes vapp_dict and print in tabular format
167
168 Args:
169 org_dict: dictionary of organization where key is org uuid.
170
171 Returns:
172 The return nothing
173 """
174
175 if org_dict is None:
176 return
177
178 org_table = PrettyTable(['org uuid', 'name'])
179 for k in org_dict:
180 entry = [k, org_dict[k]]
181 org_table.add_row(entry)
182
183 print org_table
184
185
186def print_vm_list(vm_dict=None):
187 """ Method takes vapp_dict and print in tabular format
188
189 Args:
bayramovb6ffe792016-09-28 11:50:56 +0400190 vm_dict: dictionary of organization where key is org uuid.
bayramov6c0e3d42016-09-27 03:03:32 -0700191
192 Returns:
193 The return nothing
194 """
195 if vm_dict is None:
196 return
197
198 vm_table = PrettyTable(
199 ['vm uuid', 'vm name', 'vapp uuid', 'vdc uuid', 'network name', 'is deployed', 'vcpu', 'memory', 'status'])
200
201 try:
202 for k in vm_dict:
203 entry = []
204 entry.append(k)
205 entry.append(vm_dict[k]['name'])
206 entry.append(vm_dict[k]['container'].split('/')[-1:][0][5:])
207 entry.append(vm_dict[k]['vdc'].split('/')[-1:][0])
208 entry.append(vm_dict[k]['networkName'])
209 entry.append(vm_dict[k]['isDeployed'])
210 entry.append(vm_dict[k]['numberOfCpus'])
211 entry.append(vm_dict[k]['memoryMB'])
212 entry.append(vm_dict[k]['status'])
213 vm_table.add_row(entry)
214 print vm_table
215 except KeyError:
216 logger.error("wrong key {}".format(KeyError.message))
217 pass
218
219
bayramovb6ffe792016-09-28 11:50:56 +0400220def print_vdc_list(org_dict=None):
221 """ Method takes vapp_dict and print in tabular format
222
223 Args:
224 org_dict: dictionary of organization where key is org uuid.
225
226 Returns:
227 The return nothing
228 """
229 if org_dict is None:
230 return
231 try:
232 vdcs_dict = {}
233 if org_dict.has_key('vdcs'):
234 vdcs_dict = org_dict['vdcs']
235 vdc_table = PrettyTable(['vdc uuid', 'vdc name'])
236 for k in vdcs_dict:
237 entry = [k, vdcs_dict[k]]
238 vdc_table.add_row(entry)
239
240 print vdc_table
241 except KeyError:
242 logger.error("wrong key {}".format(KeyError.message))
243 logger.logger.debug(traceback.format_exc())
244
245
246def print_network_list(org_dict=None):
247 """ Method print network list.
248
249 Args:
250 org_dict: dictionary of organization that contain key networks with a list of all
251 network for for specific VDC
252
253 Returns:
254 The return nothing
255 """
256 if org_dict is None:
257 return
258 try:
259 network_dict = {}
260 if org_dict.has_key('networks'):
261 network_dict = org_dict['networks']
262 network_table = PrettyTable(['network uuid', 'network name'])
263 for k in network_dict:
264 entry = [k, network_dict[k]]
265 network_table.add_row(entry)
266
267 print network_table
268
269 except KeyError:
270 logger.error("wrong key {}".format(KeyError.message))
271 logger.logger.debug(traceback.format_exc())
272
273
bayramov6c0e3d42016-09-27 03:03:32 -0700274def print_org_details(org_dict=None):
275 """ Method takes vapp_dict and print in tabular format
276
277 Args:
278 org_dict: dictionary of organization where key is org uuid.
279
280 Returns:
281 The return nothing
282 """
283 if org_dict is None:
284 return
285 try:
bayramov6c0e3d42016-09-27 03:03:32 -0700286 catalogs_dict = {}
bayramov6c0e3d42016-09-27 03:03:32 -0700287
bayramovb6ffe792016-09-28 11:50:56 +0400288 print_vdc_list(org_dict=org_dict)
289 print_network_list(org_dict=org_dict)
bayramov6c0e3d42016-09-27 03:03:32 -0700290
291 if org_dict.has_key('catalogs'):
292 catalogs_dict = org_dict['catalogs']
293
bayramov6c0e3d42016-09-27 03:03:32 -0700294 catalog_table = PrettyTable(['catalog uuid', 'catalog name'])
295 for k in catalogs_dict:
296 entry = [k, catalogs_dict[k]]
297 catalog_table.add_row(entry)
298
bayramov6c0e3d42016-09-27 03:03:32 -0700299 print catalog_table
300
301 except KeyError:
302 logger.error("wrong key {}".format(KeyError.message))
303 logger.logger.debug(traceback.format_exc())
304
305
306def delete_actions(vim=None, action=None, namespace=None):
307 if action == 'network' or namespace.action == 'network':
308 logger.debug("Requesting delete for network {}".format(namespace.network_name))
309 network_uuid = namespace.network_name
310 # if request name based we need find UUID
311 # TODO optimize it or move to external function
312 if not namespace.uuid:
313 org_dict = vim.get_org_list()
314 for org in org_dict:
315 org_net = vim.get_org(org)['networks']
316 for network in org_net:
317 if org_net[network] == namespace.network_name:
318 network_uuid = network
319
320 vim.delete_network_action(network_uuid=network_uuid)
321
322
323def list_actions(vim=None, action=None, namespace=None):
bayramovb6ffe792016-09-28 11:50:56 +0400324 """ Method provide list object from VDC action
325
326 Args:
327 vim - is vcloud director vim connector.
328 action - is action for list ( vdc / org etc)
329 namespace - must contain VDC / Org information.
330
331 Returns:
332 The return nothing
333 """
334
335 org_id = None
336 myorgs = vim.get_org_list()
337 for org in myorgs:
338 if myorgs[org] == namespace.vcdorg:
339 org_id = org
340 break
341 else:
342 print(" Invalid organization.")
343 return
344
bayramov6c0e3d42016-09-27 03:03:32 -0700345 if action == 'vms' or namespace.action == 'vms':
346 vm_dict = vim.get_vm_list(vdc_name=namespace.vcdvdc)
347 print_vm_list(vm_dict=vm_dict)
348 elif action == 'vapps' or namespace.action == 'vapps':
349 vapp_dict = vim.get_vapp_list(vdc_name=namespace.vcdvdc)
350 print_vapp(vapp_dict=vapp_dict)
351 elif action == 'networks' or namespace.action == 'networks':
bayramovb6ffe792016-09-28 11:50:56 +0400352 if namespace.osm:
353 osm_print(vim.get_network_list(filter_dict={}))
354 else:
355 print_network_list(vim.get_org(org_uuid=org_id))
bayramov6c0e3d42016-09-27 03:03:32 -0700356 elif action == 'vdc' or namespace.action == 'vdc':
bayramovb6ffe792016-09-28 11:50:56 +0400357 if namespace.osm:
358 osm_print(vim.get_tenant_list(filter_dict=None))
359 else:
360 print_vdc_list(vim.get_org(org_uuid=org_id))
bayramov6c0e3d42016-09-27 03:03:32 -0700361 elif action == 'org' or namespace.action == 'org':
bayramov6c0e3d42016-09-27 03:03:32 -0700362 print_org(org_dict=vim.get_org_list())
363 else:
364 return None
365
366
bayramovb6ffe792016-09-28 11:50:56 +0400367def print_network_details(network_dict=None):
368 try:
369 network_table = PrettyTable(network_dict.keys())
370 entry = [network_dict.values()]
371 network_table.add_row(entry[0])
372 print network_table
373 except KeyError:
374 logger.error("wrong key {}".format(KeyError.message))
375 logger.logger.debug(traceback.format_exc())
376
377
378def osm_print(generic_dict=None):
379
380 try:
381 for element in generic_dict:
382 table = PrettyTable(element.keys())
383 entry = [element.values()]
384 table.add_row(entry[0])
385 print table
386 except KeyError:
387 logger.error("wrong key {}".format(KeyError.message))
388 logger.logger.debug(traceback.format_exc())
389
390
bayramov6c0e3d42016-09-27 03:03:32 -0700391def view_actions(vim=None, action=None, namespace=None):
bayramovb6ffe792016-09-28 11:50:56 +0400392 org_id = None
393 orgs = vim.get_org_list()
394 for org in orgs:
395 if orgs[org] == namespace.vcdorg:
396 org_id = org
397 break
398 else:
399 print(" Invalid organization.")
400 return
401
402 myorg = vim.get_org(org_uuid=org_id)
403
bayramov6c0e3d42016-09-27 03:03:32 -0700404 # view org
405 if action == 'org' or namespace.action == 'org':
406 org_id = None
407 orgs = vim.get_org_list()
408 if namespace.uuid:
409 if namespace.org_name in orgs:
410 org_id = namespace.org_name
411 else:
412 # we need find UUID based on name provided
413 for org in orgs:
414 if orgs[org] == namespace.org_name:
415 org_id = org
416 break
417
418 logger.debug("Requesting view for orgs {}".format(org_id))
419 print_org_details(vim.get_org(org_uuid=org_id))
420
421 # view vapp action
422 if action == 'vapp' or namespace.action == 'vapp':
bayramovb6ffe792016-09-28 11:50:56 +0400423 print namespace.vapp_name
424 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
bayramovb6ffe792016-09-28 11:50:56 +0400435 vapp_dict = vim.get_vapp(vdc_name=namespace.vcdvdc, vapp_name=vapp_uuid, isuuid=True)
436 if vapp_dict is not None:
437 print_vapp(vapp_dict=vapp_dict)
bayramov6c0e3d42016-09-27 03:03:32 -0700438
439 # view network
440 if action == 'network' or namespace.action == 'network':
441 logger.debug("Requesting view for network {}".format(namespace.network_name))
442 network_uuid = namespace.network_name
443 # if request name based we need find UUID
444 # TODO optimize it or move to external function
445 if not namespace.uuid:
bayramovb6ffe792016-09-28 11:50:56 +0400446 if not myorg.has_key('networks'):
447 print("Network {} is undefined in vcloud director for org {} vdc {}".format(namespace.network_name,
448 vim.name,
449 vim.tenant_name))
450 return
bayramov6c0e3d42016-09-27 03:03:32 -0700451
bayramovb6ffe792016-09-28 11:50:56 +0400452 my_org_net = myorg['networks']
453 for network in my_org_net:
454 if my_org_net[network] == namespace.network_name:
455 network_uuid = network
456 break
457
458 print print_network_details(network_dict=vim.get_vcd_network(network_uuid=network_uuid))
bayramov6c0e3d42016-09-27 03:03:32 -0700459
460
461def create_actions(vim=None, action=None, namespace=None):
462 """Method gets provider vdc view from vcloud director
463
464 Args:
465 vim - is Cloud director vim connector
466 action - action for create ( network / vdc etc)
467
468 Returns:
469 The return xml content of respond or None
470 """
471 if action == 'network' or namespace.action == 'network':
472 logger.debug("Creating a network in vcloud director".format(namespace.network_name))
473 network_uuid = vim.create_network(namespace.network_name)
474 if network_uuid is not None:
475 print ("Crated new network {} and uuid: {}".format(namespace.network_name, network_uuid))
476 else:
477 print ("Failed create a new network {}".format(namespace.network_name))
478 elif action == 'vdc' or namespace.action == 'vdc':
479 logger.debug("Creating a new vdc in vcloud director.".format(namespace.vdc_name))
480 vdc_uuid = vim.create_vdc(namespace.vdc_name)
481 if vdc_uuid is not None:
482 print ("Crated new vdc {} and uuid: {}".format(namespace.vdc_name, vdc_uuid))
483 else:
484 print ("Failed create a new vdc {}".format(namespace.vdc_name))
485 else:
486 return None
487
488
bayramovb6ffe792016-09-28 11:50:56 +0400489def validate_uuid4(uuid_string):
490 """Function validate that string contain valid uuid4
bayramov6c0e3d42016-09-27 03:03:32 -0700491
bayramovb6ffe792016-09-28 11:50:56 +0400492 Args:
493 uuid_string - valid UUID string
494
495 Returns:
496 The return true if string contain valid UUID format
497 """
498 try:
499 val = uuid.UUID(uuid_string, version=4)
500 except ValueError:
501 return False
502 return True
503
504
505def upload_image(vim=None, image_file=None):
506 """Function upload image to vcloud director
507
508 Args:
509 image_file - valid UUID string
510
511 Returns:
512 The return true if image uploaded correctly
513 """
514 try:
515 catalog_uuid = vim.get_image_id_from_path(path=image_file)
516 if catalog_uuid is not None and validate_uuid4(catalog_uuid):
517 print("Image uploaded and uuid {}".format(catalog_uuid))
518 return True
519 except:
520 print("Failed uploaded {} image".format(image_file))
521
522 return False
523
524
525def boot_image(vim=None, image_name=None, vm_name=None):
526 """ Function boot image that resided in vcloud director.
527 The image name can be UUID of name.
528
529 Args:
530 image_name - image identified by UUID or text string.
531 vm_name
532
533 Returns:
534 The return true if image uploaded correctly
535 """
536
537 vim_catalog = None
538 try:
539 catalogs = vim.vca.get_catalogs()
540 if not validate_uuid4(image_name):
541 vim_catalog = vim.get_catalogid(catalog_name=image_name, catalogs=catalogs)
542 if vim_catalog is None:
543 return None
544 else:
545 vim_catalog = vim.get_catalogid(catalog_name=image_name, catalogs=catalogs)
546 if vim_catalog is None:
547 return None
548
549 vm_uuid = vim.new_vminstance(name=vm_name, image_id=vim_catalog)
550 if vm_uuid is not None and validate_uuid4(vm_uuid):
551 print("Image booted and vm uuid {}".format(vm_uuid))
552 vapp_dict = vim.get_vapp(vdc_name=namespace.vcdvdc, vapp_name=vm_uuid, isuuid=True)
553 if vapp_dict is not None:
554 print_vapp(vapp_dict=vapp_dict)
555 return True
556 except:
557 print("Failed uploaded {} image".format(image_name))
558
559
560def image_action(vim=None, action=None, namespace=None):
561 """ Function present set of action to manipulate with image.
562 - upload image
563 - boot image.
564 - delete image ( not yet done )
565
566 Args:
567 vim - vcloud director connector
568 action - string (upload/boot etc)
569 namespace - contain other attributes image name etc
570
571 Returns:
572 The return nothing
573 """
574
575 if action == 'upload' or namespace.action == 'upload':
576 upload_image(vim=vim, image_file=namespace.image)
577 elif action == 'boot' or namespace.action == 'boot':
578 boot_image(vim=vim, image_name=namespace.image, vm_name=namespace.vmname)
579 else:
580 return None
581
582
583def vmwarecli(command=None, action=None, namespace=None):
bayramova09cf382016-09-28 04:13:46 +0400584 logger.debug("Namespace {}".format(namespace))
bayramov6c0e3d42016-09-27 03:03:32 -0700585 urllib3.disable_warnings()
bayramov6c0e3d42016-09-27 03:03:32 -0700586
bayramovb6ffe792016-09-28 11:50:56 +0400587 vcduser = None
588 vcdpasword = None
589 vcdhost = None
590 vcdorg = None
591
592 if hasattr(__builtins__, 'raw_input'):
593 input = raw_input
594
595 if namespace.vcdvdc is None:
596 while True:
597 vcduser = input("Enter vcd username: ")
598 if vcduser is not None and len(vcduser) > 0:
599 break
600 else:
601 vcduser = namespace.vcduser
602
bayramova09cf382016-09-28 04:13:46 +0400603 if namespace.vcdpassword is None:
bayramovb6ffe792016-09-28 11:50:56 +0400604 while True:
605 vcdpasword = input("Please enter vcd password: ")
606 if vcdpasword is not None and len(vcdpasword) > 0:
607 break
bayramova09cf382016-09-28 04:13:46 +0400608 else:
609 vcdpasword = namespace.vcdpassword
bayramovb6ffe792016-09-28 11:50:56 +0400610
611 if namespace.vcdhost is None:
612 while True:
613 vcdhost = input("Please enter vcd host name or ip: ")
614 if vcdhost is not None and len(vcdhost) > 0:
615 break
616 else:
617 vcdhost = namespace.vcdhost
618
619 if namespace.vcdorg is None:
620 while True:
621 vcdorg = input("Please enter vcd organization name: ")
622 if vcdorg is not None and len(vcdorg) > 0:
623 break
624 else:
625 vcdorg = namespace.vcdorg
626
627 try:
628 vim = vimconnector(uuid=None,
629 name=vcdorg,
630 tenant_id=None,
631 tenant_name=namespace.vcdvdc,
632 url=vcdhost,
633 url_admin=vcdhost,
634 user=vcduser,
635 passwd=vcdpasword,
636 log_level="DEBUG",
637 config={'admin_username': namespace.vcdamdin, 'admin_password': namespace.vcdadminpassword})
638 vim.vca = vim.connect()
639 except vimconn.vimconnConnectionException:
640 print("Failed connect to vcloud director. Please check credential and hostname.")
641 return
bayramov6c0e3d42016-09-27 03:03:32 -0700642
643 # list
644 if command == 'list' or namespace.command == 'list':
645 logger.debug("Client requested list action")
646 # route request to list actions
647 list_actions(vim=vim, action=action, namespace=namespace)
648
649 # view action
650 if command == 'view' or namespace.command == 'view':
651 logger.debug("Client requested view action")
652 view_actions(vim=vim, action=action, namespace=namespace)
653
654 # delete action
655 if command == 'delete' or namespace.command == 'delete':
656 logger.debug("Client requested delete action")
657 delete_actions(vim=vim, action=action, namespace=namespace)
658
659 # create action
660 if command == 'create' or namespace.command == 'create':
661 logger.debug("Client requested create action")
662 create_actions(vim=vim, action=action, namespace=namespace)
663
bayramovb6ffe792016-09-28 11:50:56 +0400664 # image action
665 if command == 'image' or namespace.command == 'image':
666 logger.debug("Client requested create action")
667 image_action(vim=vim, action=action, namespace=namespace)
668
bayramov6c0e3d42016-09-27 03:03:32 -0700669
bayramov6c0e3d42016-09-27 03:03:32 -0700670if __name__ == '__main__':
671 defaults = {'vcdvdc': 'default',
672 'vcduser': 'admin',
673 'vcdpassword': 'admin',
674 'vcdhost': 'https://localhost',
675 'vcdorg': 'default',
676 'debug': 'INFO'}
677
678 parser = argparse.ArgumentParser()
679 parser.add_argument('-u', '--vcduser', help='vcloud director username', type=str)
680 parser.add_argument('-p', '--vcdpassword', help='vcloud director password', type=str)
bayramova09cf382016-09-28 04:13:46 +0400681 parser.add_argument('-U', '--vcdamdin', help='vcloud director password', type=str)
682 parser.add_argument('-P', '--vcdadminpassword', help='vcloud director password', type=str)
bayramov6c0e3d42016-09-27 03:03:32 -0700683 parser.add_argument('-c', '--vcdhost', help='vcloud director host', type=str)
684 parser.add_argument('-o', '--vcdorg', help='vcloud director org', type=str)
685 parser.add_argument('-v', '--vcdvdc', help='vcloud director vdc', type=str)
686 parser.add_argument('-d', '--debug', help='debug level', type=int)
687
688 parser_subparsers = parser.add_subparsers(help='commands', dest='command')
689 sub = parser_subparsers.add_parser('list', help='List objects (VMs, vApps, networks)')
690 sub_subparsers = sub.add_subparsers(dest='action')
bayramovb6ffe792016-09-28 11:50:56 +0400691
692 list_vms = sub_subparsers.add_parser('vms', help='list - all vm deployed in vCloud director')
693 list_vapps = sub_subparsers.add_parser('vapps', help='list - all vapps deployed in vCloud director')
694 list_network = sub_subparsers.add_parser('networks', help='list - all networks deployed')
695 list_network.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
696
697 #list vdc
698 list_vdc = sub_subparsers.add_parser('vdc', help='list - list all vdc for organization accessible to you')
699 list_vdc.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
700
701 list_org = sub_subparsers.add_parser('org', help='list - list of organizations accessible to you.')
bayramov6c0e3d42016-09-27 03:03:32 -0700702
703 create_sub = parser_subparsers.add_parser('create')
704 create_sub_subparsers = create_sub.add_subparsers(dest='action')
705 create_vms = create_sub_subparsers.add_parser('vms')
706 create_vapp = create_sub_subparsers.add_parser('vapp')
707 create_vapp.add_argument('uuid')
708
709 # add network
710 create_network = create_sub_subparsers.add_parser('network')
711 create_network.add_argument('network_name', action='store', help='create a network for a vdc')
712
713 # add VDC
714 create_vdc = create_sub_subparsers.add_parser('vdc')
715 create_vdc.add_argument('vdc_name', action='store', help='create a new VDC for org')
716
717 delete_sub = parser_subparsers.add_parser('delete')
718 del_sub_subparsers = delete_sub.add_subparsers(dest='action')
719 del_vms = del_sub_subparsers.add_parser('vms')
720 del_vapp = del_sub_subparsers.add_parser('vapp')
721 del_vapp.add_argument('uuid', help='view vapp based on UUID')
722
723 # delete network
724 del_network = del_sub_subparsers.add_parser('network')
725 del_network.add_argument('network_name', action='store',
726 help='- delete network for vcloud director by provided name')
727 del_network.add_argument('-u', '--uuid', default=False, action='store_true',
728 help='delete network for vcloud director by provided uuid')
729
730 # delete vdc
731 del_vdc = del_sub_subparsers.add_parser('vdc')
732
733 view_sub = parser_subparsers.add_parser('view')
734 view_sub_subparsers = view_sub.add_subparsers(dest='action')
735
736 view_vms_parser = view_sub_subparsers.add_parser('vms')
737 view_vms_parser.add_argument('uuid', default=False, action='store_true',
738 help='- View VM for specific uuid in vcloud director')
739 view_vms_parser.add_argument('name', default=False, action='store_true',
740 help='- View VM for specific vapp name in vcloud director')
741
742 # view vapp
743 view_vapp_parser = view_sub_subparsers.add_parser('vapp')
744 view_vapp_parser.add_argument('vapp_name', action='store',
745 help='- view vapp for specific vapp name in vcloud director')
746 view_vapp_parser.add_argument('-u', '--uuid', default=False, action='store_true', help='view vapp based on uuid')
747
748 # view network
749 view_network = view_sub_subparsers.add_parser('network')
750 view_network.add_argument('network_name', action='store',
751 help='- view network for specific network name in vcloud director')
752 view_network.add_argument('-u', '--uuid', default=False, action='store_true', help='view network based on uuid')
753
754 # view VDC command and actions
755 view_vdc = view_sub_subparsers.add_parser('vdc')
756 view_vdc.add_argument('vdc_name', action='store',
757 help='- View VDC based and action based on provided vdc uuid')
758 view_vdc.add_argument('-u', '--uuid', default=False, action='store_true', help='view vdc based on uuid')
759
760 # view organization command and actions
761 view_org = view_sub_subparsers.add_parser('org')
762 view_org.add_argument('org_name', action='store',
763 help='- View VDC based and action based on provided vdc uuid')
764 view_org.add_argument('-u', '--uuid', default=False, action='store_true', help='view org based on uuid')
765
bayramovb6ffe792016-09-28 11:50:56 +0400766 # upload image action
767 image_sub = parser_subparsers.add_parser('image')
768 image_subparsers = image_sub.add_subparsers(dest='action')
769 upload_parser = image_subparsers.add_parser('upload')
770 upload_parser.add_argument('image', default=False, action='store', help='- valid path to OVF image ')
771 upload_parser.add_argument('catalog', default=False, action='store_true', help='- catalog name')
772
773 # boot vm action
774 boot_parser = image_subparsers.add_parser('boot')
775 boot_parser.add_argument('image', default=False, action='store', help='- Image name')
776 boot_parser.add_argument('vmname', default=False, action='store', help='- VM name')
777 boot_parser.add_argument('-u', '--uuid', default=False, action='store_true', help='view org based on uuid')
bayramov6c0e3d42016-09-27 03:03:32 -0700778
779 namespace = parser.parse_args()
780 # put command_line args to mapping
781 command_line_args = {k: v for k, v in vars(namespace).items() if v}
782
783 d = defaults.copy()
784 d.update(os.environ)
785 d.update(command_line_args)
786
787 logger = logging.getLogger('mano.vim.vmware')
788 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
789 ch = logging.StreamHandler()
790 ch.setLevel(str.upper(d['debug']))
791 ch.setFormatter(formatter)
792 logger.addHandler(ch)
793 logger.setLevel(getattr(logging, str.upper(d['debug'])))
794 logger.info(
795 "Connecting {} username: {} org: {} vdc: {} ".format(d['vcdhost'], d['vcduser'], d['vcdorg'], d['vcdvdc']))
796
797 logger.debug("command: \"{}\" actio: \"{}\"".format(d['command'], d['action']))
bayramova09cf382016-09-28 04:13:46 +0400798
799 # main entry point.
bayramov6c0e3d42016-09-27 03:03:32 -0700800 vmwarecli(namespace=namespace)