blob: 4583a651718362436b2c3f315ea47a6cb59f1e74 [file] [log] [blame]
bayramov49e192d2016-10-04 21:11:07 +04001#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3##
4# This file is standalone vmware vcloud director util
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18#
19# For those usages not covered by the Apache License, Version 2.0 please
20# contact with: mbayramov@vmware.com
21##
22
23"""
24
25Standalone application that leverage openmano vmware connector work with vCloud director rest api.
26
27 - Provides capability to create and delete VDC for specific organization.
28 - Create, delete and manage network for specific VDC
29 - List deployed VM's , VAPPs, VDSs, Organization
30 - View detail information about VM / Vapp , Organization etc
31 - Operate with images upload / boot / power on etc
32
33 Usage example.
34
35 List organization created in vCloud director
36 vmwarecli.py -u admin -p qwerty123 -c 172.16.254.206 -U Administrator -P qwerty123 -o test -v TEF list org
37
38 List VDC for particular organization
39 vmwarecli.py -u admin -p qwerty123 -c 172.16.254.206 -U Administrator -P qwerty123 -o test -v TEF list vdc
40
41 Upload image
42 python vmwarerecli.py image upload /Users/spyroot/Developer/Openmano/Ro/vnfs/cirros/cirros.ovf
43
44 Boot Image
45 python vmwarerecli.py -u admin -p qwerty123 -c 172.16.254.206 -o test -v TEF image boot cirros cirros
46
47 View vApp
48 python vmwarerecli.py -u admin -p qwerty123 -c 172.16.254.206 -o test -v TEF view vapp 90bd2b4e-f782-46cf-b5e2-c3817dcf6633 -u
49
50 List VMS
51 python vmwarerecli.py -u admin -p qwerty123 -c 172.16.254.206 -o test -v TEF list vms
52
53 List VDC in OSM format
54 python vmwarerecli.py -u admin -p qwerty123 -c 172.16.254.206 -o test -v TEF list vdc -o
55
56Mustaafa Bayramov
57mbayramov@vmware.com
58"""
59import os
60import argparse
61import traceback
62import uuid
63
64from xml.etree import ElementTree as ET
65
66import sys
67from pyvcloud import Http
68
69import logging
Adam Israel8e3ce872018-01-08 18:43:40 +000070import vimconn
bayramov49e192d2016-10-04 21:11:07 +040071import time
72import uuid
73import urllib3
74import requests
75
Adam Israel8e3ce872018-01-08 18:43:40 +000076from vimconn_vmware import vimconnector
bayramov49e192d2016-10-04 21:11:07 +040077from requests.packages.urllib3.exceptions import InsecureRequestWarning
78from prettytable import PrettyTable
79
80requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
81
82__author__ = "Mustafa Bayramov"
83__date__ = "$16-Sep-2016 11:09:29$"
84
85
86# TODO move to main vim
87def delete_network_action(vca=None, network_uuid=None):
88 """
89 Method leverages vCloud director and query network based on network uuid
90
91 Args:
92 vca - is active VCA connection.
93 network_uuid - is a network uuid
94
95 Returns:
96 The return XML respond
97 """
98
99 if vca is None or network_uuid is None:
100 return None
101
102 url_list = [vca.host, '/api/admin/network/', network_uuid]
103 vm_list_rest_call = ''.join(url_list)
104
105 if not (not vca.vcloud_session or not vca.vcloud_session.organization):
106 response = Http.get(url=vm_list_rest_call,
107 headers=vca.vcloud_session.get_vcloud_headers(),
108 verify=vca.verify,
109 logger=vca.logger)
110 if response.status_code == requests.codes.ok:
Adam Israel8e3ce872018-01-08 18:43:40 +0000111 print response.content
bayramov49e192d2016-10-04 21:11:07 +0400112 return response.content
113
114 return None
115
116
117def print_vapp(vapp_dict=None):
118 """ Method takes vapp_dict and print in tabular format
119
120 Args:
121 vapp_dict: container vapp object.
122
123 Returns:
124 The return nothing
125 """
126
127 # following key available to print
128 # {'status': 'POWERED_OFF', 'storageProfileName': '*', 'hardwareVersion': '7', 'vmToolsVersion': '0',
129 # 'memoryMB': '384',
130 # 'href': 'https://172.16.254.206/api/vAppTemplate/vm-129e22e8-08dc-4cb6-8358-25f635e65d3b',
131 # 'isBusy': 'false', 'isDeployed': 'false', 'isInMaintenanceMode': 'false', 'isVAppTemplate': 'true',
132 # 'networkName': 'nat', 'isDeleted': 'false', 'catalogName': 'Cirros',
133 # 'containerName': 'Cirros Template', # 'container':
134 # 'https://172.16.254.206/api/vAppTemplate/vappTemplate-b966453d-c361-4505-9e38-ccef45815e5d',
135 # 'name': 'Cirros', 'pvdcHighestSupportedHardwareVersion': '11', 'isPublished': 'false',
136 # 'numberOfCpus': '1', 'vdc': 'https://172.16.254.206/api/vdc/a5056f85-418c-4bfd-8041-adb0f48be9d9',
137 # 'guestOs': 'Other (32-bit)', 'isVdcEnabled': 'true'}
138
139 if vapp_dict is None:
140 return
141
142 vm_table = PrettyTable(['vm uuid',
143 'vapp name',
144 'vapp uuid',
145 'network name',
146 'storage name',
147 'vcpu', 'memory', 'hw ver','deployed','status'])
148 for k in vapp_dict:
149 entry = []
150 entry.append(k)
151 entry.append(vapp_dict[k]['containerName'])
152 # vm-b1f5cd4c-2239-4c89-8fdc-a41ff18e0d61
153 entry.append(vapp_dict[k]['container'].split('/')[-1:][0][5:])
154 entry.append(vapp_dict[k]['networkName'])
155 entry.append(vapp_dict[k]['storageProfileName'])
156 entry.append(vapp_dict[k]['numberOfCpus'])
157 entry.append(vapp_dict[k]['memoryMB'])
158 entry.append(vapp_dict[k]['pvdcHighestSupportedHardwareVersion'])
159 entry.append(vapp_dict[k]['isDeployed'])
160 entry.append(vapp_dict[k]['status'])
161
162 vm_table.add_row(entry)
163
Adam Israel8e3ce872018-01-08 18:43:40 +0000164 print vm_table
bayramov49e192d2016-10-04 21:11:07 +0400165
166
167def print_org(org_dict=None):
168 """ Method takes vapp_dict and print in tabular format
169
170 Args:
171 org_dict: dictionary of organization where key is org uuid.
172
173 Returns:
174 The return nothing
175 """
176
177 if org_dict is None:
178 return
179
180 org_table = PrettyTable(['org uuid', 'name'])
181 for k in org_dict:
182 entry = [k, org_dict[k]]
183 org_table.add_row(entry)
184
Adam Israel8e3ce872018-01-08 18:43:40 +0000185 print org_table
bayramov49e192d2016-10-04 21:11:07 +0400186
187
188def print_vm_list(vm_dict=None):
189 """ Method takes vapp_dict and print in tabular format
190
191 Args:
192 vm_dict: dictionary of organization where key is org uuid.
193
194 Returns:
195 The return nothing
196 """
197 if vm_dict is None:
198 return
199
200 vm_table = PrettyTable(
201 ['vm uuid', 'vm name', 'vapp uuid', 'vdc uuid', 'network name', 'is deployed', 'vcpu', 'memory', 'status'])
202
203 try:
204 for k in vm_dict:
205 entry = []
206 entry.append(k)
207 entry.append(vm_dict[k]['name'])
208 entry.append(vm_dict[k]['container'].split('/')[-1:][0][5:])
209 entry.append(vm_dict[k]['vdc'].split('/')[-1:][0])
210 entry.append(vm_dict[k]['networkName'])
211 entry.append(vm_dict[k]['isDeployed'])
212 entry.append(vm_dict[k]['numberOfCpus'])
213 entry.append(vm_dict[k]['memoryMB'])
214 entry.append(vm_dict[k]['status'])
215 vm_table.add_row(entry)
Adam Israel8e3ce872018-01-08 18:43:40 +0000216 print vm_table
bayramov49e192d2016-10-04 21:11:07 +0400217 except KeyError:
218 logger.error("wrong key {}".format(KeyError.message))
219 pass
220
221
222def print_vdc_list(org_dict=None):
223 """ Method takes vapp_dict and print in tabular format
224
225 Args:
226 org_dict: dictionary of organization where key is org uuid.
227
228 Returns:
229 The return nothing
230 """
231 if org_dict is None:
232 return
233 try:
234 vdcs_dict = {}
Adam Israel8e3ce872018-01-08 18:43:40 +0000235 if org_dict.has_key('vdcs'):
bayramov49e192d2016-10-04 21:11:07 +0400236 vdcs_dict = org_dict['vdcs']
237 vdc_table = PrettyTable(['vdc uuid', 'vdc name'])
238 for k in vdcs_dict:
239 entry = [k, vdcs_dict[k]]
240 vdc_table.add_row(entry)
241
Adam Israel8e3ce872018-01-08 18:43:40 +0000242 print vdc_table
bayramov49e192d2016-10-04 21:11:07 +0400243 except KeyError:
244 logger.error("wrong key {}".format(KeyError.message))
245 logger.logger.debug(traceback.format_exc())
246
247
248def print_network_list(org_dict=None):
249 """ Method print network list.
250
251 Args:
252 org_dict: dictionary of organization that contain key networks with a list of all
253 network for for specific VDC
254
255 Returns:
256 The return nothing
257 """
258 if org_dict is None:
259 return
260 try:
261 network_dict = {}
Adam Israel8e3ce872018-01-08 18:43:40 +0000262 if org_dict.has_key('networks'):
bayramov49e192d2016-10-04 21:11:07 +0400263 network_dict = org_dict['networks']
264 network_table = PrettyTable(['network uuid', 'network name'])
265 for k in network_dict:
266 entry = [k, network_dict[k]]
267 network_table.add_row(entry)
268
Adam Israel8e3ce872018-01-08 18:43:40 +0000269 print network_table
bayramov49e192d2016-10-04 21:11:07 +0400270
271 except KeyError:
272 logger.error("wrong key {}".format(KeyError.message))
273 logger.logger.debug(traceback.format_exc())
274
275
276def print_org_details(org_dict=None):
277 """ Method takes vapp_dict and print in tabular format
278
279 Args:
280 org_dict: dictionary of organization where key is org uuid.
281
282 Returns:
283 The return nothing
284 """
285 if org_dict is None:
286 return
287 try:
288 catalogs_dict = {}
289
290 print_vdc_list(org_dict=org_dict)
291 print_network_list(org_dict=org_dict)
292
Adam Israel8e3ce872018-01-08 18:43:40 +0000293 if org_dict.has_key('catalogs'):
bayramov49e192d2016-10-04 21:11:07 +0400294 catalogs_dict = org_dict['catalogs']
295
296 catalog_table = PrettyTable(['catalog uuid', 'catalog name'])
297 for k in catalogs_dict:
298 entry = [k, catalogs_dict[k]]
299 catalog_table.add_row(entry)
300
Adam Israel8e3ce872018-01-08 18:43:40 +0000301 print catalog_table
bayramov49e192d2016-10-04 21:11:07 +0400302
303 except KeyError:
304 logger.error("wrong key {}".format(KeyError.message))
305 logger.logger.debug(traceback.format_exc())
306
307
308def delete_actions(vim=None, action=None, namespace=None):
309 if action == 'network' or namespace.action == 'network':
310 logger.debug("Requesting delete for network {}".format(namespace.network_name))
311 network_uuid = namespace.network_name
312 # if request name based we need find UUID
313 # TODO optimize it or move to external function
314 if not namespace.uuid:
315 org_dict = vim.get_org_list()
316 for org in org_dict:
317 org_net = vim.get_org(org)['networks']
318 for network in org_net:
319 if org_net[network] == namespace.network_name:
320 network_uuid = network
321
322 vim.delete_network_action(network_uuid=network_uuid)
323
324
325def list_actions(vim=None, action=None, namespace=None):
326 """ Method provide list object from VDC action
327
328 Args:
329 vim - is vcloud director vim connector.
330 action - is action for list ( vdc / org etc)
331 namespace - must contain VDC / Org information.
332
333 Returns:
334 The return nothing
335 """
336
337 org_id = None
338 myorgs = vim.get_org_list()
339 for org in myorgs:
340 if myorgs[org] == namespace.vcdorg:
341 org_id = org
342 break
343 else:
344 print(" Invalid organization.")
345 return
346
347 if action == 'vms' or namespace.action == 'vms':
348 vm_dict = vim.get_vm_list(vdc_name=namespace.vcdvdc)
349 print_vm_list(vm_dict=vm_dict)
350 elif action == 'vapps' or namespace.action == 'vapps':
351 vapp_dict = vim.get_vapp_list(vdc_name=namespace.vcdvdc)
352 print_vapp(vapp_dict=vapp_dict)
353 elif action == 'networks' or namespace.action == 'networks':
354 if namespace.osm:
355 osm_print(vim.get_network_list(filter_dict={}))
356 else:
357 print_network_list(vim.get_org(org_uuid=org_id))
358 elif action == 'vdc' or namespace.action == 'vdc':
359 if namespace.osm:
360 osm_print(vim.get_tenant_list(filter_dict=None))
361 else:
362 print_vdc_list(vim.get_org(org_uuid=org_id))
363 elif action == 'org' or namespace.action == 'org':
364 print_org(org_dict=vim.get_org_list())
365 else:
366 return None
367
368
369def print_network_details(network_dict=None):
370 try:
Adam Israel8e3ce872018-01-08 18:43:40 +0000371 network_table = PrettyTable(network_dict.keys())
372 entry = [network_dict.values()]
bayramov49e192d2016-10-04 21:11:07 +0400373 network_table.add_row(entry[0])
Adam Israel8e3ce872018-01-08 18:43:40 +0000374 print network_table
bayramov49e192d2016-10-04 21:11:07 +0400375 except KeyError:
376 logger.error("wrong key {}".format(KeyError.message))
377 logger.logger.debug(traceback.format_exc())
378
379
380def osm_print(generic_dict=None):
381
382 try:
383 for element in generic_dict:
Adam Israel8e3ce872018-01-08 18:43:40 +0000384 table = PrettyTable(element.keys())
385 entry = [element.values()]
bayramov49e192d2016-10-04 21:11:07 +0400386 table.add_row(entry[0])
Adam Israel8e3ce872018-01-08 18:43:40 +0000387 print table
bayramov49e192d2016-10-04 21:11:07 +0400388 except KeyError:
389 logger.error("wrong key {}".format(KeyError.message))
390 logger.logger.debug(traceback.format_exc())
391
392
393def view_actions(vim=None, action=None, namespace=None):
394 org_id = None
395 orgs = vim.get_org_list()
396 for org in orgs:
397 if orgs[org] == namespace.vcdorg:
398 org_id = org
399 break
400 else:
401 print(" Invalid organization.")
402 return
403
404 myorg = vim.get_org(org_uuid=org_id)
405
406 # view org
407 if action == 'org' or namespace.action == 'org':
408 org_id = None
409 orgs = vim.get_org_list()
410 if namespace.uuid:
411 if namespace.org_name in orgs:
412 org_id = namespace.org_name
413 else:
414 # we need find UUID based on name provided
415 for org in orgs:
416 if orgs[org] == namespace.org_name:
417 org_id = org
418 break
419
420 logger.debug("Requesting view for orgs {}".format(org_id))
421 print_org_details(vim.get_org(org_uuid=org_id))
422
423 # view vapp action
424 if action == 'vapp' or namespace.action == 'vapp':
425 if namespace.vapp_name is not None and namespace.uuid:
426 logger.debug("Requesting vapp {} for vdc {}".format(namespace.vapp_name, namespace.vcdvdc))
427 vapp_dict = {}
428 vapp_uuid = namespace.vapp_name
429 # if request based on just name we need get UUID
430 if not namespace.uuid:
431 vapp_uuid = vim.get_vappid(vdc=namespace.vcdvdc, vapp_name=namespace.vapp_name)
432 if vapp_uuid is None:
Adam Israel8e3ce872018-01-08 18:43:40 +0000433 print("Can't find vapp by given name {}".format(namespace.vapp_name))
bayramov49e192d2016-10-04 21:11:07 +0400434 return
435
Adam Israel8e3ce872018-01-08 18:43:40 +0000436 print " namespace {}".format(namespace)
bayramov49e192d2016-10-04 21:11:07 +0400437 if vapp_dict is not None and namespace.osm:
438 vm_info_dict = vim.get_vminstance(vim_vm_uuid=vapp_uuid)
Adam Israel8e3ce872018-01-08 18:43:40 +0000439 print vm_info_dict
bayramov49e192d2016-10-04 21:11:07 +0400440 if vapp_dict is not None and namespace.osm != True:
441 vapp_dict = vim.get_vapp(vdc_name=namespace.vcdvdc, vapp_name=vapp_uuid, isuuid=True)
442 print_vapp(vapp_dict=vapp_dict)
443
444 # view network
445 if action == 'network' or namespace.action == 'network':
446 logger.debug("Requesting view for network {}".format(namespace.network_name))
447 network_uuid = namespace.network_name
448 # if request name based we need find UUID
449 # TODO optimize it or move to external function
450 if not namespace.uuid:
Adam Israel8e3ce872018-01-08 18:43:40 +0000451 if not myorg.has_key('networks'):
452 print("Network {} is undefined in vcloud director for org {} vdc {}".format(namespace.network_name,
bayramov49e192d2016-10-04 21:11:07 +0400453 vim.name,
Adam Israel8e3ce872018-01-08 18:43:40 +0000454 vim.tenant_name))
bayramov49e192d2016-10-04 21:11:07 +0400455 return
456
457 my_org_net = myorg['networks']
458 for network in my_org_net:
459 if my_org_net[network] == namespace.network_name:
460 network_uuid = network
461 break
462
Adam Israel8e3ce872018-01-08 18:43:40 +0000463 print print_network_details(network_dict=vim.get_vcd_network(network_uuid=network_uuid))
bayramov49e192d2016-10-04 21:11:07 +0400464
465
466def create_actions(vim=None, action=None, namespace=None):
467 """Method gets provider vdc view from vcloud director
468
469 Args:
470 vim - is Cloud director vim connector
471 action - action for create ( network / vdc etc)
472
473 Returns:
474 The return xml content of respond or None
475 """
476 if action == 'network' or namespace.action == 'network':
477 logger.debug("Creating a network in vcloud director".format(namespace.network_name))
478 network_uuid = vim.create_network(namespace.network_name)
479 if network_uuid is not None:
Adam Israel8e3ce872018-01-08 18:43:40 +0000480 print ("Crated new network {} and uuid: {}".format(namespace.network_name, network_uuid))
bayramov49e192d2016-10-04 21:11:07 +0400481 else:
Adam Israel8e3ce872018-01-08 18:43:40 +0000482 print ("Failed create a new network {}".format(namespace.network_name))
bayramov49e192d2016-10-04 21:11:07 +0400483 elif action == 'vdc' or namespace.action == 'vdc':
484 logger.debug("Creating a new vdc in vcloud director.".format(namespace.vdc_name))
485 vdc_uuid = vim.create_vdc(namespace.vdc_name)
486 if vdc_uuid is not None:
Adam Israel8e3ce872018-01-08 18:43:40 +0000487 print ("Crated new vdc {} and uuid: {}".format(namespace.vdc_name, vdc_uuid))
bayramov49e192d2016-10-04 21:11:07 +0400488 else:
Adam Israel8e3ce872018-01-08 18:43:40 +0000489 print ("Failed create a new vdc {}".format(namespace.vdc_name))
bayramov49e192d2016-10-04 21:11:07 +0400490 else:
491 return None
492
493
494def validate_uuid4(uuid_string):
495 """Function validate that string contain valid uuid4
496
497 Args:
498 uuid_string - valid UUID string
499
500 Returns:
501 The return true if string contain valid UUID format
502 """
503 try:
504 val = uuid.UUID(uuid_string, version=4)
505 except ValueError:
506 return False
507 return True
508
509
510def upload_image(vim=None, image_file=None):
511 """Function upload image to vcloud director
512
513 Args:
514 image_file - valid UUID string
515
516 Returns:
517 The return true if image uploaded correctly
518 """
519 try:
520 catalog_uuid = vim.get_image_id_from_path(path=image_file, progress=True)
521 if catalog_uuid is not None and validate_uuid4(catalog_uuid):
Adam Israel8e3ce872018-01-08 18:43:40 +0000522 print("Image uploaded and uuid {}".format(catalog_uuid))
bayramov49e192d2016-10-04 21:11:07 +0400523 return True
524 except vimconn.vimconnException as upload_exception:
Adam Israel8e3ce872018-01-08 18:43:40 +0000525 print("Failed uploaded {} image".format(image_file))
526 print("Error Reason: {}".format(upload_exception.message))
bayramov49e192d2016-10-04 21:11:07 +0400527 return False
528
529
530def boot_image(vim=None, image_name=None, vm_name=None):
531 """ Function boot image that resided in vcloud director.
532 The image name can be UUID of name.
533
534 Args:
535 vim - vim connector
536 image_name - image identified by UUID or text string.
537 vm_name - vmname
538
539
540 Returns:
541 The return true if image uploaded correctly
542 """
543
544 vim_catalog = None
545 try:
546 catalogs = vim.vca.get_catalogs()
547 if not validate_uuid4(image_name):
548 vim_catalog = vim.get_catalogid(catalog_name=image_name, catalogs=catalogs)
549 if vim_catalog is None:
550 return None
551 else:
552 vim_catalog = vim.get_catalogid(catalog_name=image_name, catalogs=catalogs)
553 if vim_catalog is None:
554 return None
555
Adam Israel8e3ce872018-01-08 18:43:40 +0000556 print (" Booting {} image id {} ".format(vm_name, vim_catalog))
bayramov49e192d2016-10-04 21:11:07 +0400557 vm_uuid = vim.new_vminstance(name=vm_name, image_id=vim_catalog)
558 if vm_uuid is not None and validate_uuid4(vm_uuid):
Adam Israel8e3ce872018-01-08 18:43:40 +0000559 print("Image booted and vm uuid {}".format(vm_uuid))
bayramov49e192d2016-10-04 21:11:07 +0400560 vapp_dict = vim.get_vapp(vdc_name=namespace.vcdvdc, vapp_name=vm_uuid, isuuid=True)
561 if vapp_dict is not None:
562 print_vapp(vapp_dict=vapp_dict)
563 return True
564 except vimconn.vimconnNotFoundException as notFound:
Adam Israel8e3ce872018-01-08 18:43:40 +0000565 print("Failed boot {} image".format(image_name))
566 print(notFound.message)
bayramov49e192d2016-10-04 21:11:07 +0400567 except vimconn.vimconnException as vimconError:
Adam Israel8e3ce872018-01-08 18:43:40 +0000568 print("Failed boot {} image".format(image_name))
569 print(vimconError.message)
bayramov49e192d2016-10-04 21:11:07 +0400570 except:
Adam Israel8e3ce872018-01-08 18:43:40 +0000571 print("Failed boot {} image".format(image_name))
bayramov49e192d2016-10-04 21:11:07 +0400572
573
574 return False
575
576
577def image_action(vim=None, action=None, namespace=None):
578 """ Function present set of action to manipulate with image.
579 - upload image
580 - boot image.
581 - delete image ( not yet done )
582
583 Args:
584 vim - vcloud director connector
585 action - string (upload/boot etc)
586 namespace - contain other attributes image name etc
587
588 Returns:
589 The return nothing
590 """
591
592 if action == 'upload' or namespace.action == 'upload':
593 upload_image(vim=vim, image_file=namespace.image)
594 elif action == 'boot' or namespace.action == 'boot':
595 boot_image(vim=vim, image_name=namespace.image, vm_name=namespace.vmname)
596 else:
597 return None
598
599
600def vmwarecli(command=None, action=None, namespace=None):
601 logger.debug("Namespace {}".format(namespace))
602 urllib3.disable_warnings()
603
604 vcduser = None
605 vcdpasword = None
606 vcdhost = None
607 vcdorg = None
608
609 if hasattr(__builtins__, 'raw_input'):
610 input = raw_input
611
612 if namespace.vcdvdc is None:
613 while True:
Adam Israel8e3ce872018-01-08 18:43:40 +0000614 vcduser = input("Enter vcd username: ")
bayramov49e192d2016-10-04 21:11:07 +0400615 if vcduser is not None and len(vcduser) > 0:
616 break
617 else:
618 vcduser = namespace.vcduser
619
620 if namespace.vcdpassword is None:
621 while True:
Adam Israel8e3ce872018-01-08 18:43:40 +0000622 vcdpasword = input("Please enter vcd password: ")
bayramov49e192d2016-10-04 21:11:07 +0400623 if vcdpasword is not None and len(vcdpasword) > 0:
624 break
625 else:
626 vcdpasword = namespace.vcdpassword
627
628 if namespace.vcdhost is None:
629 while True:
Adam Israel8e3ce872018-01-08 18:43:40 +0000630 vcdhost = input("Please enter vcd host name or ip: ")
bayramov49e192d2016-10-04 21:11:07 +0400631 if vcdhost is not None and len(vcdhost) > 0:
632 break
633 else:
634 vcdhost = namespace.vcdhost
635
636 if namespace.vcdorg is None:
637 while True:
Adam Israel8e3ce872018-01-08 18:43:40 +0000638 vcdorg = input("Please enter vcd organization name: ")
bayramov49e192d2016-10-04 21:11:07 +0400639 if vcdorg is not None and len(vcdorg) > 0:
640 break
641 else:
642 vcdorg = namespace.vcdorg
643
644 try:
645 vim = vimconnector(uuid=None,
646 name=vcdorg,
647 tenant_id=None,
648 tenant_name=namespace.vcdvdc,
649 url=vcdhost,
650 url_admin=vcdhost,
651 user=vcduser,
652 passwd=vcdpasword,
653 log_level="DEBUG",
654 config={'admin_username': namespace.vcdamdin, 'admin_password': namespace.vcdadminpassword})
655 vim.vca = vim.connect()
656
657 except vimconn.vimconnConnectionException:
658 print("Failed connect to vcloud director. Please check credential and hostname.")
659 return
660
661 # list
662 if command == 'list' or namespace.command == 'list':
663 logger.debug("Client requested list action")
664 # route request to list actions
665 list_actions(vim=vim, action=action, namespace=namespace)
666
667 # view action
668 if command == 'view' or namespace.command == 'view':
669 logger.debug("Client requested view action")
670 view_actions(vim=vim, action=action, namespace=namespace)
671
672 # delete action
673 if command == 'delete' or namespace.command == 'delete':
674 logger.debug("Client requested delete action")
675 delete_actions(vim=vim, action=action, namespace=namespace)
676
677 # create action
678 if command == 'create' or namespace.command == 'create':
679 logger.debug("Client requested create action")
680 create_actions(vim=vim, action=action, namespace=namespace)
681
682 # image action
683 if command == 'image' or namespace.command == 'image':
684 logger.debug("Client requested create action")
685 image_action(vim=vim, action=action, namespace=namespace)
686
687
688if __name__ == '__main__':
689 defaults = {'vcdvdc': 'default',
690 'vcduser': 'admin',
691 'vcdpassword': 'admin',
692 'vcdhost': 'https://localhost',
693 'vcdorg': 'default',
694 'debug': 'INFO'}
695
696 parser = argparse.ArgumentParser()
697 parser.add_argument('-u', '--vcduser', help='vcloud director username', type=str)
698 parser.add_argument('-p', '--vcdpassword', help='vcloud director password', type=str)
699 parser.add_argument('-U', '--vcdamdin', help='vcloud director password', type=str)
700 parser.add_argument('-P', '--vcdadminpassword', help='vcloud director password', type=str)
701 parser.add_argument('-c', '--vcdhost', help='vcloud director host', type=str)
702 parser.add_argument('-o', '--vcdorg', help='vcloud director org', type=str)
703 parser.add_argument('-v', '--vcdvdc', help='vcloud director vdc', type=str)
704 parser.add_argument('-d', '--debug', help='debug level', type=int)
705
706 parser_subparsers = parser.add_subparsers(help='commands', dest='command')
707 sub = parser_subparsers.add_parser('list', help='List objects (VMs, vApps, networks)')
708 sub_subparsers = sub.add_subparsers(dest='action')
709
710 list_vms = sub_subparsers.add_parser('vms', help='list - all vm deployed in vCloud director')
711 list_vapps = sub_subparsers.add_parser('vapps', help='list - all vapps deployed in vCloud director')
712 list_network = sub_subparsers.add_parser('networks', help='list - all networks deployed')
713 list_network.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
714
715 #list vdc
716 list_vdc = sub_subparsers.add_parser('vdc', help='list - list all vdc for organization accessible to you')
717 list_vdc.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
718
719 list_org = sub_subparsers.add_parser('org', help='list - list of organizations accessible to you.')
720
721 create_sub = parser_subparsers.add_parser('create')
722 create_sub_subparsers = create_sub.add_subparsers(dest='action')
723 create_vms = create_sub_subparsers.add_parser('vms')
724 create_vapp = create_sub_subparsers.add_parser('vapp')
725 create_vapp.add_argument('uuid')
726
727 # add network
728 create_network = create_sub_subparsers.add_parser('network')
729 create_network.add_argument('network_name', action='store', help='create a network for a vdc')
730
731 # add VDC
732 create_vdc = create_sub_subparsers.add_parser('vdc')
733 create_vdc.add_argument('vdc_name', action='store', help='create a new VDC for org')
734
735 delete_sub = parser_subparsers.add_parser('delete')
736 del_sub_subparsers = delete_sub.add_subparsers(dest='action')
737 del_vms = del_sub_subparsers.add_parser('vms')
738 del_vapp = del_sub_subparsers.add_parser('vapp')
739 del_vapp.add_argument('uuid', help='view vapp based on UUID')
740
741 # delete network
742 del_network = del_sub_subparsers.add_parser('network')
743 del_network.add_argument('network_name', action='store',
744 help='- delete network for vcloud director by provided name')
745 del_network.add_argument('-u', '--uuid', default=False, action='store_true',
746 help='delete network for vcloud director by provided uuid')
747
748 # delete vdc
749 del_vdc = del_sub_subparsers.add_parser('vdc')
750
751 view_sub = parser_subparsers.add_parser('view')
752 view_sub_subparsers = view_sub.add_subparsers(dest='action')
753
754 view_vms_parser = view_sub_subparsers.add_parser('vms')
755 view_vms_parser.add_argument('uuid', default=False, action='store_true',
756 help='- View VM for specific uuid in vcloud director')
757 view_vms_parser.add_argument('name', default=False, action='store_true',
758 help='- View VM for specific vapp name in vcloud director')
759
760 # view vapp
761 view_vapp_parser = view_sub_subparsers.add_parser('vapp')
762 view_vapp_parser.add_argument('vapp_name', action='store',
763 help='- view vapp for specific vapp name in vcloud director')
764 view_vapp_parser.add_argument('-u', '--uuid', default=False, action='store_true', help='view vapp based on uuid')
765 view_vapp_parser.add_argument('-o', '--osm', default=False, action='store_true', help='provide view in OSM format')
766
767 # view network
768 view_network = view_sub_subparsers.add_parser('network')
769 view_network.add_argument('network_name', action='store',
770 help='- view network for specific network name in vcloud director')
771 view_network.add_argument('-u', '--uuid', default=False, action='store_true', help='view network based on uuid')
772
773 # view VDC command and actions
774 view_vdc = view_sub_subparsers.add_parser('vdc')
775 view_vdc.add_argument('vdc_name', action='store',
776 help='- View VDC based and action based on provided vdc uuid')
777 view_vdc.add_argument('-u', '--uuid', default=False, action='store_true', help='view vdc based on uuid')
778
779 # view organization command and actions
780 view_org = view_sub_subparsers.add_parser('org')
781 view_org.add_argument('org_name', action='store',
782 help='- View VDC based and action based on provided vdc uuid')
783 view_org.add_argument('-u', '--uuid', default=False, action='store_true', help='view org based on uuid')
784
785 # upload image action
786 image_sub = parser_subparsers.add_parser('image')
787 image_subparsers = image_sub.add_subparsers(dest='action')
788 upload_parser = image_subparsers.add_parser('upload')
789 upload_parser.add_argument('image', default=False, action='store', help='- valid path to OVF image ')
790 upload_parser.add_argument('catalog', default=False, action='store_true', help='- catalog name')
791
792 # boot vm action
793 boot_parser = image_subparsers.add_parser('boot')
794 boot_parser.add_argument('image', default=False, action='store', help='- Image name')
795 boot_parser.add_argument('vmname', default=False, action='store', help='- VM name')
796 boot_parser.add_argument('-u', '--uuid', default=False, action='store_true', help='view org based on uuid')
797
798 namespace = parser.parse_args()
799 # put command_line args to mapping
Adam Israel8e3ce872018-01-08 18:43:40 +0000800 command_line_args = {k: v for k, v in vars(namespace).items() if v}
bayramov49e192d2016-10-04 21:11:07 +0400801
802 d = defaults.copy()
803 d.update(os.environ)
804 d.update(command_line_args)
805
806 logger = logging.getLogger('mano.vim.vmware')
807 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
808 ch = logging.StreamHandler()
809 ch.setLevel(str.upper(d['debug']))
810 ch.setFormatter(formatter)
811 logger.addHandler(ch)
812 logger.setLevel(getattr(logging, str.upper(d['debug'])))
813 logger.info(
814 "Connecting {} username: {} org: {} vdc: {} ".format(d['vcdhost'], d['vcduser'], d['vcdorg'], d['vcdvdc']))
815
816 logger.debug("command: \"{}\" actio: \"{}\"".format(d['command'], d['action']))
817
818 # main entry point.
819 vmwarecli(namespace=namespace)