blob: c332cdb63147e7bc836c9fbbe436351d8bb8c399 [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:
bayramov163f1ae2016-09-28 17:16:55 +0400530 vim - vim connector
531 image_name - image identified by UUID or text string.
532 vm_name - vmname
533
bayramovb6ffe792016-09-28 11:50:56 +0400534
535 Returns:
536 The return true if image uploaded correctly
537 """
538
539 vim_catalog = None
540 try:
541 catalogs = vim.vca.get_catalogs()
542 if not validate_uuid4(image_name):
543 vim_catalog = vim.get_catalogid(catalog_name=image_name, catalogs=catalogs)
544 if vim_catalog is None:
545 return None
546 else:
547 vim_catalog = vim.get_catalogid(catalog_name=image_name, catalogs=catalogs)
548 if vim_catalog is None:
549 return None
550
551 vm_uuid = vim.new_vminstance(name=vm_name, image_id=vim_catalog)
552 if vm_uuid is not None and validate_uuid4(vm_uuid):
553 print("Image booted and vm uuid {}".format(vm_uuid))
554 vapp_dict = vim.get_vapp(vdc_name=namespace.vcdvdc, vapp_name=vm_uuid, isuuid=True)
555 if vapp_dict is not None:
556 print_vapp(vapp_dict=vapp_dict)
557 return True
558 except:
559 print("Failed uploaded {} image".format(image_name))
560
561
562def image_action(vim=None, action=None, namespace=None):
563 """ Function present set of action to manipulate with image.
564 - upload image
565 - boot image.
566 - delete image ( not yet done )
567
568 Args:
569 vim - vcloud director connector
570 action - string (upload/boot etc)
571 namespace - contain other attributes image name etc
572
573 Returns:
574 The return nothing
575 """
576
577 if action == 'upload' or namespace.action == 'upload':
578 upload_image(vim=vim, image_file=namespace.image)
579 elif action == 'boot' or namespace.action == 'boot':
580 boot_image(vim=vim, image_name=namespace.image, vm_name=namespace.vmname)
581 else:
582 return None
583
584
585def vmwarecli(command=None, action=None, namespace=None):
bayramova09cf382016-09-28 04:13:46 +0400586 logger.debug("Namespace {}".format(namespace))
bayramov6c0e3d42016-09-27 03:03:32 -0700587 urllib3.disable_warnings()
bayramov6c0e3d42016-09-27 03:03:32 -0700588
bayramovb6ffe792016-09-28 11:50:56 +0400589 vcduser = None
590 vcdpasword = None
591 vcdhost = None
592 vcdorg = None
593
594 if hasattr(__builtins__, 'raw_input'):
595 input = raw_input
596
597 if namespace.vcdvdc is None:
598 while True:
599 vcduser = input("Enter vcd username: ")
600 if vcduser is not None and len(vcduser) > 0:
601 break
602 else:
603 vcduser = namespace.vcduser
604
bayramova09cf382016-09-28 04:13:46 +0400605 if namespace.vcdpassword is None:
bayramovb6ffe792016-09-28 11:50:56 +0400606 while True:
607 vcdpasword = input("Please enter vcd password: ")
608 if vcdpasword is not None and len(vcdpasword) > 0:
609 break
bayramova09cf382016-09-28 04:13:46 +0400610 else:
611 vcdpasword = namespace.vcdpassword
bayramovb6ffe792016-09-28 11:50:56 +0400612
613 if namespace.vcdhost is None:
614 while True:
615 vcdhost = input("Please enter vcd host name or ip: ")
616 if vcdhost is not None and len(vcdhost) > 0:
617 break
618 else:
619 vcdhost = namespace.vcdhost
620
621 if namespace.vcdorg is None:
622 while True:
623 vcdorg = input("Please enter vcd organization name: ")
624 if vcdorg is not None and len(vcdorg) > 0:
625 break
626 else:
627 vcdorg = namespace.vcdorg
628
629 try:
630 vim = vimconnector(uuid=None,
631 name=vcdorg,
632 tenant_id=None,
633 tenant_name=namespace.vcdvdc,
634 url=vcdhost,
635 url_admin=vcdhost,
636 user=vcduser,
637 passwd=vcdpasword,
638 log_level="DEBUG",
639 config={'admin_username': namespace.vcdamdin, 'admin_password': namespace.vcdadminpassword})
640 vim.vca = vim.connect()
641 except vimconn.vimconnConnectionException:
642 print("Failed connect to vcloud director. Please check credential and hostname.")
643 return
bayramov6c0e3d42016-09-27 03:03:32 -0700644
645 # list
646 if command == 'list' or namespace.command == 'list':
647 logger.debug("Client requested list action")
648 # route request to list actions
649 list_actions(vim=vim, action=action, namespace=namespace)
650
651 # view action
652 if command == 'view' or namespace.command == 'view':
653 logger.debug("Client requested view action")
654 view_actions(vim=vim, action=action, namespace=namespace)
655
656 # delete action
657 if command == 'delete' or namespace.command == 'delete':
658 logger.debug("Client requested delete action")
659 delete_actions(vim=vim, action=action, namespace=namespace)
660
661 # create action
662 if command == 'create' or namespace.command == 'create':
663 logger.debug("Client requested create action")
664 create_actions(vim=vim, action=action, namespace=namespace)
665
bayramovb6ffe792016-09-28 11:50:56 +0400666 # image action
667 if command == 'image' or namespace.command == 'image':
668 logger.debug("Client requested create action")
669 image_action(vim=vim, action=action, namespace=namespace)
670
bayramov6c0e3d42016-09-27 03:03:32 -0700671
bayramov6c0e3d42016-09-27 03:03:32 -0700672if __name__ == '__main__':
673 defaults = {'vcdvdc': 'default',
674 'vcduser': 'admin',
675 'vcdpassword': 'admin',
676 'vcdhost': 'https://localhost',
677 'vcdorg': 'default',
678 'debug': 'INFO'}
679
680 parser = argparse.ArgumentParser()
681 parser.add_argument('-u', '--vcduser', help='vcloud director username', type=str)
682 parser.add_argument('-p', '--vcdpassword', help='vcloud director password', type=str)
bayramova09cf382016-09-28 04:13:46 +0400683 parser.add_argument('-U', '--vcdamdin', help='vcloud director password', type=str)
684 parser.add_argument('-P', '--vcdadminpassword', help='vcloud director password', type=str)
bayramov6c0e3d42016-09-27 03:03:32 -0700685 parser.add_argument('-c', '--vcdhost', help='vcloud director host', type=str)
686 parser.add_argument('-o', '--vcdorg', help='vcloud director org', type=str)
687 parser.add_argument('-v', '--vcdvdc', help='vcloud director vdc', type=str)
688 parser.add_argument('-d', '--debug', help='debug level', type=int)
689
690 parser_subparsers = parser.add_subparsers(help='commands', dest='command')
691 sub = parser_subparsers.add_parser('list', help='List objects (VMs, vApps, networks)')
692 sub_subparsers = sub.add_subparsers(dest='action')
bayramovb6ffe792016-09-28 11:50:56 +0400693
694 list_vms = sub_subparsers.add_parser('vms', help='list - all vm deployed in vCloud director')
695 list_vapps = sub_subparsers.add_parser('vapps', help='list - all vapps deployed in vCloud director')
696 list_network = sub_subparsers.add_parser('networks', help='list - all networks deployed')
697 list_network.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
698
699 #list vdc
700 list_vdc = sub_subparsers.add_parser('vdc', help='list - list all vdc for organization accessible to you')
701 list_vdc.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
702
703 list_org = sub_subparsers.add_parser('org', help='list - list of organizations accessible to you.')
bayramov6c0e3d42016-09-27 03:03:32 -0700704
705 create_sub = parser_subparsers.add_parser('create')
706 create_sub_subparsers = create_sub.add_subparsers(dest='action')
707 create_vms = create_sub_subparsers.add_parser('vms')
708 create_vapp = create_sub_subparsers.add_parser('vapp')
709 create_vapp.add_argument('uuid')
710
711 # add network
712 create_network = create_sub_subparsers.add_parser('network')
713 create_network.add_argument('network_name', action='store', help='create a network for a vdc')
714
715 # add VDC
716 create_vdc = create_sub_subparsers.add_parser('vdc')
717 create_vdc.add_argument('vdc_name', action='store', help='create a new VDC for org')
718
719 delete_sub = parser_subparsers.add_parser('delete')
720 del_sub_subparsers = delete_sub.add_subparsers(dest='action')
721 del_vms = del_sub_subparsers.add_parser('vms')
722 del_vapp = del_sub_subparsers.add_parser('vapp')
723 del_vapp.add_argument('uuid', help='view vapp based on UUID')
724
725 # delete network
726 del_network = del_sub_subparsers.add_parser('network')
727 del_network.add_argument('network_name', action='store',
728 help='- delete network for vcloud director by provided name')
729 del_network.add_argument('-u', '--uuid', default=False, action='store_true',
730 help='delete network for vcloud director by provided uuid')
731
732 # delete vdc
733 del_vdc = del_sub_subparsers.add_parser('vdc')
734
735 view_sub = parser_subparsers.add_parser('view')
736 view_sub_subparsers = view_sub.add_subparsers(dest='action')
737
738 view_vms_parser = view_sub_subparsers.add_parser('vms')
739 view_vms_parser.add_argument('uuid', default=False, action='store_true',
740 help='- View VM for specific uuid in vcloud director')
741 view_vms_parser.add_argument('name', default=False, action='store_true',
742 help='- View VM for specific vapp name in vcloud director')
743
744 # view vapp
745 view_vapp_parser = view_sub_subparsers.add_parser('vapp')
746 view_vapp_parser.add_argument('vapp_name', action='store',
747 help='- view vapp for specific vapp name in vcloud director')
748 view_vapp_parser.add_argument('-u', '--uuid', default=False, action='store_true', help='view vapp based on uuid')
749
750 # view network
751 view_network = view_sub_subparsers.add_parser('network')
752 view_network.add_argument('network_name', action='store',
753 help='- view network for specific network name in vcloud director')
754 view_network.add_argument('-u', '--uuid', default=False, action='store_true', help='view network based on uuid')
755
756 # view VDC command and actions
757 view_vdc = view_sub_subparsers.add_parser('vdc')
758 view_vdc.add_argument('vdc_name', action='store',
759 help='- View VDC based and action based on provided vdc uuid')
760 view_vdc.add_argument('-u', '--uuid', default=False, action='store_true', help='view vdc based on uuid')
761
762 # view organization command and actions
763 view_org = view_sub_subparsers.add_parser('org')
764 view_org.add_argument('org_name', action='store',
765 help='- View VDC based and action based on provided vdc uuid')
766 view_org.add_argument('-u', '--uuid', default=False, action='store_true', help='view org based on uuid')
767
bayramovb6ffe792016-09-28 11:50:56 +0400768 # upload image action
769 image_sub = parser_subparsers.add_parser('image')
770 image_subparsers = image_sub.add_subparsers(dest='action')
771 upload_parser = image_subparsers.add_parser('upload')
772 upload_parser.add_argument('image', default=False, action='store', help='- valid path to OVF image ')
773 upload_parser.add_argument('catalog', default=False, action='store_true', help='- catalog name')
774
775 # boot vm action
776 boot_parser = image_subparsers.add_parser('boot')
777 boot_parser.add_argument('image', default=False, action='store', help='- Image name')
778 boot_parser.add_argument('vmname', default=False, action='store', help='- VM name')
779 boot_parser.add_argument('-u', '--uuid', default=False, action='store_true', help='view org based on uuid')
bayramov6c0e3d42016-09-27 03:03:32 -0700780
781 namespace = parser.parse_args()
782 # put command_line args to mapping
783 command_line_args = {k: v for k, v in vars(namespace).items() if v}
784
785 d = defaults.copy()
786 d.update(os.environ)
787 d.update(command_line_args)
788
789 logger = logging.getLogger('mano.vim.vmware')
790 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
791 ch = logging.StreamHandler()
792 ch.setLevel(str.upper(d['debug']))
793 ch.setFormatter(formatter)
794 logger.addHandler(ch)
795 logger.setLevel(getattr(logging, str.upper(d['debug'])))
796 logger.info(
797 "Connecting {} username: {} org: {} vdc: {} ".format(d['vcdhost'], d['vcduser'], d['vcdorg'], d['vcdvdc']))
798
799 logger.debug("command: \"{}\" actio: \"{}\"".format(d['command'], d['action']))
bayramova09cf382016-09-28 04:13:46 +0400800
801 # main entry point.
bayramov6c0e3d42016-09-27 03:03:32 -0700802 vmwarecli(namespace=namespace)