blob: c34d831f3e24c7ed7cbdc067d5de0493934b1eef [file] [log] [blame]
tierno7edb6752016-03-21 17:37:52 +01001#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# PYTHON_ARGCOMPLETE_OK
4
5##
6# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
7# This file is part of openmano
8# All Rights Reserved.
9#
10# Licensed under the Apache License, Version 2.0 (the "License"); you may
11# not use this file except in compliance with the License. You may obtain
12# a copy of the License at
13#
14# http://www.apache.org/licenses/LICENSE-2.0
15#
16# Unless required by applicable law or agreed to in writing, software
17# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19# License for the specific language governing permissions and limitations
20# under the License.
21#
22# For those usages not covered by the Apache License, Version 2.0 please
23# contact with: nfvlabs@tid.es
24##
25
26'''
27openmano client used to interact with openmano-server (openmanod)
28'''
29__author__="Alfonso Tierno, Gerardo Garcia"
30__date__ ="$09-oct-2014 09:09:48$"
tierno933fea52017-01-23 13:07:09 +010031__version__="0.4.11-r517"
tierno941551b2017-01-12 18:26:26 +010032version_date="Jan 2017"
tierno7edb6752016-03-21 17:37:52 +010033
34from argcomplete.completers import FilesCompleter
35import os
36import argparse
37import argcomplete
38import requests
39import json
40import yaml
41import logging
42#from jsonschema import validate as js_v, exceptions as js_e
43
44class ArgumentParserError(Exception): pass
45
46class OpenmanoCLIError(Exception): pass
47
48class ThrowingArgumentParser(argparse.ArgumentParser):
49 def error(self, message):
50 print "Error: %s" %message
51 print
52 self.print_usage()
53 #self.print_help()
54 print
55 print "Type 'openmano -h' for help"
56 raise ArgumentParserError
57
58
59def config(args):
60 print "OPENMANO_HOST: %s" %mano_host
61 print "OPENMANO_PORT: %s" %mano_port
garciadeblas0e9fd832016-07-08 15:20:18 +020062 if args.n:
63 logger.debug("resolving tenant and datacenter names")
64 mano_tenant_id = "None"
65 mano_tenant_name = "None"
66 mano_datacenter_id = "None"
67 mano_datacenter_name = "None"
68 try:
69 mano_tenant_id = _get_item_uuid("tenants", mano_tenant)
70 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, mano_tenant_id)
71 mano_response = requests.get(URLrequest)
72 logger.debug("openmano response: %s", mano_response.text )
73 content = mano_response.json()
74 mano_tenant_name = content["tenant"]["name"]
75 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, mano_tenant_id, mano_datacenter)
76 mano_response = requests.get(URLrequest)
77 logger.debug("openmano response: %s", mano_response.text )
78 content = mano_response.json()
79 if "error" not in content:
80 mano_datacenter_id = content["datacenter"]["uuid"]
81 mano_datacenter_name = content["datacenter"]["name"]
82 except OpenmanoCLIError:
83 pass
84 print "OPENMANO_TENANT: %s" %mano_tenant
85 print " Id: %s" %mano_tenant_id
86 print " Name: %s" %mano_tenant_name
87 print "OPENMANO_DATACENTER: %s" %str (mano_datacenter)
88 print " Id: %s" %mano_datacenter_id
89 print " Name: %s" %mano_datacenter_name
90 else:
91 print "OPENMANO_TENANT: %s" %mano_tenant
92 print "OPENMANO_DATACENTER: %s" %str (mano_datacenter)
tierno7edb6752016-03-21 17:37:52 +010093
94def _print_verbose(mano_response, verbose_level=0):
95 content = mano_response.json()
96 result = 0 if mano_response.status_code==200 else mano_response.status_code
97 if type(content)!=dict or len(content)!=1:
98 #print "Non expected format output"
99 print str(content)
100 return result
101
102 val=content.values()[0]
103 if type(val)==str:
104 print val
105 return result
106 elif type(val) == list:
107 content_list = val
108 elif type(val)==dict:
109 content_list = [val]
110 else:
111 #print "Non expected dict/list format output"
112 print str(content)
113 return result
114
115 #print content_list
116 if verbose_level==None:
117 verbose_level=0
118 if verbose_level >= 3:
119 print yaml.safe_dump(content, indent=4, default_flow_style=False)
120 return result
121
122 if mano_response.status_code == 200:
123 for content in content_list:
124 if "uuid" in content:
125 uuid = content['uuid']
126 elif "id" in content:
127 uuid = content['id']
128 elif "vim_id" in content:
129 uuid = content['vim_id']
tierno250954a2017-01-31 14:25:57 +0100130 name = content.get('name');
131 if not uuid:
132 uuid = ""
133 if not name:
134 name = ""
135 myoutput = "%s %s" %(uuid.ljust(38),name.ljust(20))
136 if content.get("status"):
tierno7edb6752016-03-21 17:37:52 +0100137 myoutput += " " + content['status'].ljust(20)
138 elif "enabled" in content and not content["enabled"]:
139 myoutput += " enabled=False".ljust(20)
140 if verbose_level >=1:
tierno250954a2017-01-31 14:25:57 +0100141 if content.get('created_at'):
142 myoutput += " " + content['created_at'].ljust(20)
tierno7edb6752016-03-21 17:37:52 +0100143 if verbose_level >=2:
144 new_line='\n'
tierno250954a2017-01-31 14:25:57 +0100145 if content.get('type'):
tierno7edb6752016-03-21 17:37:52 +0100146 myoutput += new_line + " Type: " + content['type'].ljust(29)
147 new_line=''
tierno250954a2017-01-31 14:25:57 +0100148 if content.get('description'):
tierno7edb6752016-03-21 17:37:52 +0100149 myoutput += new_line + " Description: " + content['description'].ljust(20)
150 print myoutput
151 else:
152 print content['error']['description']
153 return result
154
155def parser_json_yaml(file_name):
156 try:
157 f = file(file_name, "r")
158 text = f.read()
159 f.close()
160 except Exception as e:
161 return (False, str(e))
162
163 #Read and parse file
164 if file_name[-5:]=='.yaml' or file_name[-4:]=='.yml' or (file_name[-5:]!='.json' and '\t' not in text):
165 try:
166 config = yaml.load(text)
167 except yaml.YAMLError as exc:
168 error_pos = ""
169 if hasattr(exc, 'problem_mark'):
170 mark = exc.problem_mark
171 error_pos = " at line:%s column:%s" % (mark.line+1, mark.column+1)
172 return (False, "Error loading file '"+file_name+"' yaml format error" + error_pos)
173 else: #json
174 try:
175 config = json.loads(text)
176 except Exception as e:
177 return (False, "Error loading file '"+file_name+"' json format error " + str(e) )
178
179 return True, config
180
181def _load_file_or_yaml(content):
182 '''
183 'content' can be or a yaml/json file or a text containing a yaml/json text format
184 This function autodetect, trying to load and parse the file,
185 if fails trying to parse the 'content' text
186 Returns the dictionary once parsed, or print an error and finish the program
187 '''
188 #Check config file exists
189 if os.path.isfile(content):
190 r,payload = parser_json_yaml(content)
191 if not r:
192 print payload
193 exit(-1)
194 elif "{" in content or ":" in content:
195 try:
196 payload = yaml.load(content)
197 except yaml.YAMLError as exc:
198 error_pos = ""
199 if hasattr(exc, 'problem_mark'):
200 mark = exc.problem_mark
201 error_pos = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
202 print "Error loading yaml/json text"+error_pos
203 exit (-1)
204 else:
205 print "'%s' is neither a valid file nor a yaml/json content" % content
206 exit(-1)
207 return payload
208
209def _get_item_uuid(item, item_name_id, tenant=None):
210 if tenant:
211 URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, tenant, item)
212 else:
213 URLrequest = "http://%s:%s/openmano/%s" %(mano_host, mano_port, item)
214 mano_response = requests.get(URLrequest)
215 logger.debug("openmano response: %s", mano_response.text )
216 content = mano_response.json()
217 #print content
218 found = 0
219 for i in content[item]:
220 if i["uuid"] == item_name_id:
221 return item_name_id
222 if i["name"] == item_name_id:
223 uuid = i["uuid"]
224 found += 1
225 if found == 0:
226 raise OpenmanoCLIError("No %s found with name/uuid '%s'" %(item[:-1], item_name_id))
227 elif found > 1:
228 raise OpenmanoCLIError("%d %s found with name '%s'. uuid must be used" %(found, item, item_name_id))
229 return uuid
230#
231# def check_valid_uuid(uuid):
232# id_schema = {"type" : "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
233# try:
234# js_v(uuid, id_schema)
235# return True
236# except js_e.ValidationError:
237# return False
238
239def _get_tenant(tenant_name_id = None):
240 if not tenant_name_id:
241 tenant_name_id = mano_tenant
242 if not mano_tenant:
243 raise OpenmanoCLIError("'OPENMANO_TENANT' environment variable is not set")
244 return _get_item_uuid("tenants", tenant_name_id)
245
246def _get_datacenter(datacenter_name_id = None, tenant = "any"):
247 if not datacenter_name_id:
248 datacenter_name_id = mano_datacenter
249 if not datacenter_name_id:
250 raise OpenmanoCLIError("neither 'OPENMANO_DATACENTER' environment variable is set nor --datacenter option is used")
251 return _get_item_uuid("datacenters", datacenter_name_id, tenant)
252
253def vnf_create(args):
254 #print "vnf-create",args
255 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
256 tenant = _get_tenant()
257 myvnf = _load_file_or_yaml(args.file)
258
garciadeblas14480452017-01-10 13:08:07 +0100259 if args.name or args.description or args.image_path or args.image_name or args.image_checksum:
tierno7edb6752016-03-21 17:37:52 +0100260 #print args.name
261 try:
262 if args.name:
263 myvnf['vnf']['name'] = args.name
264 if args.description:
265 myvnf['vnf']['description'] = args.description
266 if args.image_path:
267 index=0
268 for image_path_ in args.image_path.split(","):
269 #print "image-path", image_path_
270 myvnf['vnf']['VNFC'][index]['VNFC image']=image_path_
tierno941551b2017-01-12 18:26:26 +0100271 if "image name" in myvnf['vnf']['VNFC'][index]:
272 del myvnf['vnf']['VNFC'][index]["image name"]
273 if "image checksum" in myvnf['vnf']['VNFC'][index]:
274 del myvnf['vnf']['VNFC'][index]["image checksum"]
tierno7edb6752016-03-21 17:37:52 +0100275 index=index+1
tierno941551b2017-01-12 18:26:26 +0100276 if args.image_name: #image name precedes if both are supplied
garciadeblas14480452017-01-10 13:08:07 +0100277 index=0
278 for image_name_ in args.image_name.split(","):
279 myvnf['vnf']['VNFC'][index]['image name']=image_name_
tierno941551b2017-01-12 18:26:26 +0100280 if "VNFC image" in myvnf['vnf']['VNFC'][index]:
281 del myvnf['vnf']['VNFC'][index]["VNFC image"]
garciadeblas14480452017-01-10 13:08:07 +0100282 index=index+1
283 if args.image_checksum:
284 index=0
285 for image_checksum_ in args.image_checksum.split(","):
286 myvnf['vnf']['VNFC'][index]['image checksum']=image_checksum_
287 index=index+1
tierno7edb6752016-03-21 17:37:52 +0100288 except (KeyError, TypeError), e:
289 if str(e)=='vnf': error_pos= "missing field 'vnf'"
290 elif str(e)=='name': error_pos= "missing field 'vnf':'name'"
291 elif str(e)=='description': error_pos= "missing field 'vnf':'description'"
292 elif str(e)=='VNFC': error_pos= "missing field 'vnf':'VNFC'"
293 elif str(e)==str(index): error_pos= "field 'vnf':'VNFC' must be an array"
294 elif str(e)=='VNFC image': error_pos= "missing field 'vnf':'VNFC'['VNFC image']"
garciadeblas14480452017-01-10 13:08:07 +0100295 elif str(e)=='image name': error_pos= "missing field 'vnf':'VNFC'['image name']"
296 elif str(e)=='image checksum': error_pos= "missing field 'vnf':'VNFC'['image checksum']"
tierno7edb6752016-03-21 17:37:52 +0100297 else: error_pos="wrong format"
298 print "Wrong VNF descriptor: " + error_pos
299 return -1
300 payload_req = json.dumps(myvnf)
301
302 #print payload_req
303
304 URLrequest = "http://%s:%s/openmano/%s/vnfs" %(mano_host, mano_port, tenant)
305 logger.debug("openmano request: %s", payload_req)
306 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
307 logger.debug("openmano response: %s", mano_response.text )
308
309 return _print_verbose(mano_response, args.verbose)
310
311def vnf_list(args):
312 #print "vnf-list",args
313 if args.all:
314 tenant = "any"
315 else:
316 tenant = _get_tenant()
317 if args.name:
318 toshow = _get_item_uuid("vnfs", args.name, tenant)
319 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, toshow)
320 else:
321 URLrequest = "http://%s:%s/openmano/%s/vnfs" %(mano_host, mano_port, tenant)
322 mano_response = requests.get(URLrequest)
323 logger.debug("openmano response: %s", mano_response.text )
324 content = mano_response.json()
325 #print json.dumps(content, indent=4)
326 if args.verbose==None:
327 args.verbose=0
328 result = 0 if mano_response.status_code==200 else mano_response.status_code
329 if mano_response.status_code == 200:
330 if not args.name:
331 if args.verbose >= 3:
332 print yaml.safe_dump(content, indent=4, default_flow_style=False)
333 return result
334 if len(content['vnfs']) == 0:
335 print "No VNFs were found."
336 return 404 #HTTP_Not_Found
337 for vnf in content['vnfs']:
338 myoutput = "%s %s" %(vnf['uuid'].ljust(38),vnf['name'].ljust(20))
339 if args.verbose >=1:
340 myoutput = "%s %s" %(myoutput, vnf['created_at'].ljust(20))
341 print myoutput
342 if args.verbose >=2:
343 print " Description: %s" %vnf['description']
344 print " VNF descriptor file: %s" %vnf['path']
345 else:
346 if args.verbose:
347 print yaml.safe_dump(content, indent=4, default_flow_style=False)
348 return result
349 vnf = content['vnf']
350 print "%s %s %s" %(vnf['uuid'].ljust(38),vnf['name'].ljust(20), vnf['created_at'].ljust(20))
351 print " Description: %s" %vnf['description']
352 #print " VNF descriptor file: %s" %vnf['path']
353 print " VMs:"
354 for vm in vnf['VNFC']:
355 #print " %s %s %s" %(vm['name'].ljust(20), vm['uuid'].ljust(38), vm['description'].ljust(30))
356 print " %s %s" %(vm['name'].ljust(20), vm['description'])
357 if len(vnf['nets'])>0:
358 print " Internal nets:"
359 for net in vnf['nets']:
360 print " %s %s" %(net['name'].ljust(20), net['description'])
361 if len(vnf['external-connections'])>0:
362 print " External interfaces:"
363 for interface in vnf['external-connections']:
364 print " %s %s %s %s" %(interface['external_name'].ljust(20), interface['vm_name'].ljust(20), interface['internal_name'].ljust(20), \
tierno933fea52017-01-23 13:07:09 +0100365 interface.get('vpci',"").ljust(14))
tierno7edb6752016-03-21 17:37:52 +0100366 else:
367 print content['error']['description']
368 if args.verbose:
369 print yaml.safe_dump(content, indent=4, default_flow_style=False)
370 return result
371
372def vnf_delete(args):
373 #print "vnf-delete",args
374 if args.all:
375 tenant = "any"
376 else:
377 tenant = _get_tenant()
378 todelete = _get_item_uuid("vnfs", args.name, tenant=tenant)
379 if not args.force:
380 r = raw_input("Delete VNF %s (y/N)? " %(todelete))
381 if not (len(r)>0 and r[0].lower()=="y"):
382 return 0
383 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, todelete)
384 mano_response = requests.delete(URLrequest)
385 logger.debug("openmano response: %s", mano_response.text )
386 result = 0 if mano_response.status_code==200 else mano_response.status_code
387 content = mano_response.json()
388 #print json.dumps(content, indent=4)
389 if mano_response.status_code == 200:
390 print content['result']
391 else:
392 print content['error']['description']
393 return result
394
395def scenario_create(args):
396 #print "scenario-create",args
397 tenant = _get_tenant()
398 headers_req = {'content-type': 'application/yaml'}
399 myscenario = _load_file_or_yaml(args.file)
400
401 if args.name:
402 myscenario['name'] = args.name
403 if args.description:
404 myscenario['description'] = args.description
405 payload_req = yaml.safe_dump(myscenario, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
406
407 #print payload_req
408
409 URLrequest = "http://%s:%s/openmano/%s/scenarios" %(mano_host, mano_port, tenant)
410 logger.debug("openmano request: %s", payload_req)
411 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
412 logger.debug("openmano response: %s", mano_response.text )
413 return _print_verbose(mano_response, args.verbose)
414
415def scenario_list(args):
416 #print "scenario-list",args
417 if args.all:
418 tenant = "any"
419 else:
420 tenant = _get_tenant()
421 if args.name:
422 toshow = _get_item_uuid("scenarios", args.name, tenant)
423 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, toshow)
424 else:
425 URLrequest = "http://%s:%s/openmano/%s/scenarios" %(mano_host, mano_port, tenant)
426 mano_response = requests.get(URLrequest)
427 logger.debug("openmano response: %s", mano_response.text )
428 content = mano_response.json()
429 #print json.dumps(content, indent=4)
430 if args.verbose==None:
431 args.verbose=0
432
433 result = 0 if mano_response.status_code==200 else mano_response.status_code
434 if mano_response.status_code == 200:
435 if not args.name:
436 if args.verbose >= 3:
437 print yaml.safe_dump(content, indent=4, default_flow_style=False)
438 return result
439 if len(content['scenarios']) == 0:
440 print "No scenarios were found."
441 return 404 #HTTP_Not_Found
442 for scenario in content['scenarios']:
443 myoutput = "%s %s" %(scenario['uuid'].ljust(38),scenario['name'].ljust(20))
444 if args.verbose >=1:
445 myoutput = "%s %s" %(myoutput, scenario['created_at'].ljust(20))
446 print myoutput
447 if args.verbose >=2:
448 print " Description: %s" %scenario['description']
449 else:
450 if args.verbose:
451 print yaml.safe_dump(content, indent=4, default_flow_style=False)
452 return result
453 scenario = content['scenario']
454 myoutput = "%s %s %s" %(scenario['uuid'].ljust(38),scenario['name'].ljust(20), scenario['created_at'].ljust(20))
455 print myoutput
456 print " Description: %s" %scenario['description']
457 print " VNFs:"
458 for vnf in scenario['vnfs']:
459 print " %s %s %s" %(vnf['name'].ljust(20), vnf['vnf_id'].ljust(38), vnf['description'])
460 if len(scenario['nets'])>0:
461 print " Internal nets:"
462 for net in scenario['nets']:
463 if net['description'] is None: #if description does not exist, description is "-". Valid for external and internal nets.
464 net['description'] = '-'
465 if not net['external']:
466 print " %s %s %s" %(net['name'].ljust(20), net['uuid'].ljust(38), net['description'].ljust(30))
467 print " External nets:"
468 for net in scenario['nets']:
469 if net['external']:
470 print " %s %s %s vim-id:%s" %(net['name'].ljust(20), net['uuid'].ljust(38), net['description'].ljust(30), net['vim_id'])
471 else:
472 print content['error']['description']
473 if args.verbose:
474 print yaml.safe_dump(content, indent=4, default_flow_style=False)
475 return result
476
477def scenario_delete(args):
478 #print "scenario-delete",args
479 if args.all:
480 tenant = "any"
481 else:
482 tenant = _get_tenant()
483 todelete = _get_item_uuid("scenarios", args.name, tenant=tenant)
484 if not args.force:
485 r = raw_input("Delete scenario %s (y/N)? " %(args.name))
486 if not (len(r)>0 and r[0].lower()=="y"):
487 return 0
488 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, todelete)
489 mano_response = requests.delete(URLrequest)
490 logger.debug("openmano response: %s", mano_response.text )
491 result = 0 if mano_response.status_code==200 else mano_response.status_code
492 content = mano_response.json()
493 #print json.dumps(content, indent=4)
494 if mano_response.status_code == 200:
495 print content['result']
496 else:
497 print content['error']['description']
498 return result
499
500def scenario_deploy(args):
501 print "This command is deprecated, use 'openmano instance-scenario-create --scenario %s --name %s' instead!!!" % (args.scenario, args.name)
502 print
503 args.file = None
504 args.netmap_use = None
505 args.netmap_create = None
tiernobe41e222016-09-02 15:16:13 +0200506 args.keypair = None
507 args.keypair_auto = None
tierno7edb6752016-03-21 17:37:52 +0100508 return instance_create(args)
509
510# #print "scenario-deploy",args
511# headers_req = {'content-type': 'application/json'}
512# action = {}
513# actionCmd="start"
514# if args.nostart:
515# actionCmd="reserve"
516# action[actionCmd] = {}
517# action[actionCmd]["instance_name"] = args.name
518# if args.datacenter != None:
519# action[actionCmd]["datacenter"] = args.datacenter
520# elif mano_datacenter != None:
521# action[actionCmd]["datacenter"] = mano_datacenter
522#
523# if args.description:
524# action[actionCmd]["description"] = args.description
525# payload_req = json.dumps(action, indent=4)
526# #print payload_req
527#
528# URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, mano_tenant, args.scenario)
529# logger.debug("openmano request: %s", payload_req)
530# mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
531# logger.debug("openmano response: %s", mano_response.text )
532# if args.verbose==None:
533# args.verbose=0
534#
535# result = 0 if mano_response.status_code==200 else mano_response.status_code
536# content = mano_response.json()
537# #print json.dumps(content, indent=4)
538# if args.verbose >= 3:
539# print yaml.safe_dump(content, indent=4, default_flow_style=False)
540# return result
541#
542# if mano_response.status_code == 200:
543# myoutput = "%s %s" %(content['uuid'].ljust(38),content['name'].ljust(20))
544# if args.verbose >=1:
545# myoutput = "%s %s" %(myoutput, content['created_at'].ljust(20))
546# if args.verbose >=2:
547# myoutput = "%s %s %s" %(myoutput, content['description'].ljust(30))
548# print myoutput
549# print ""
550# print "To check the status, run the following command:"
551# print "openmano instance-scenario-list <instance_id>"
552# else:
553# print content['error']['description']
554# return result
555
556def scenario_verify(args):
557 #print "scenario-verify",args
558 headers_req = {'content-type': 'application/json'}
559 action = {}
560 action["verify"] = {}
561 action["verify"]["instance_name"] = "scen-verify-return5"
562 payload_req = json.dumps(action, indent=4)
563 #print payload_req
564
565 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, mano_tenant, args.scenario)
566 logger.debug("openmano request: %s", payload_req)
567 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
568 logger.debug("openmano response: %s", mano_response.text )
569
570 result = 0 if mano_response.status_code==200 else mano_response.status_code
571 content = mano_response.json()
572 #print json.dumps(content, indent=4)
573 if mano_response.status_code == 200:
574 print content['result']
575 else:
576 print content['error']['description']
577 return result
578
579def instance_create(args):
580 tenant = _get_tenant()
581 headers_req = {'content-type': 'application/yaml'}
582 myInstance={"instance": {}, "schema_version": "0.1"}
583 if args.file:
584 instance_dict = _load_file_or_yaml(args.file)
585 if "instance" not in instance_dict:
586 myInstance = {"instance": instance_dict, "schema_version": "0.1"}
587 else:
588 myInstance = instance_dict
589 if args.name:
590 myInstance["instance"]['name'] = args.name
591 if args.description:
592 myInstance["instance"]['description'] = args.description
593 if args.nostart:
594 myInstance["instance"]['action'] = "reserve"
595 #datacenter
596 datacenter = myInstance["instance"].get("datacenter")
597 if args.datacenter != None:
598 datacenter = args.datacenter
599 myInstance["instance"]["datacenter"] = _get_datacenter(datacenter, tenant)
600 #scenario
601 scenario = myInstance["instance"].get("scenario")
602 if args.scenario != None:
603 scenario = args.scenario
604 if not scenario:
garciadeblased746032017-01-05 11:58:41 +0100605 print "you must provide a scenario in the file descriptor or with --scenario"
tierno7edb6752016-03-21 17:37:52 +0100606 return -1
607 myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant)
608 if args.netmap_use:
609 if "networks" not in myInstance["instance"]:
610 myInstance["instance"]["networks"] = {}
611 for net in args.netmap_use:
612 net_comma_list = net.split(",")
613 for net_comma in net_comma_list:
614 net_tuple = net_comma.split("=")
615 if len(net_tuple) != 2:
616 print "error at netmap-use. Expected net-scenario=net-datacenter. (%s)?" % net_comma
617 return
618 net_scenario = net_tuple[0].strip()
619 net_datacenter = net_tuple[1].strip()
620 if net_scenario not in myInstance["instance"]["networks"]:
621 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200622 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
623 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
624 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-use"] = net_datacenter
tierno7edb6752016-03-21 17:37:52 +0100625 if args.netmap_create:
626 if "networks" not in myInstance["instance"]:
627 myInstance["instance"]["networks"] = {}
628 for net in args.netmap_create:
629 net_comma_list = net.split(",")
630 for net_comma in net_comma_list:
631 net_tuple = net_comma.split("=")
632 if len(net_tuple) == 1:
633 net_scenario = net_tuple[0].strip()
634 net_datacenter = None
635 elif len(net_tuple) == 2:
636 net_scenario = net_tuple[0].strip()
637 net_datacenter = net_tuple[1].strip()
638 else:
639 print "error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. (%s)?" % net_comma
640 return
641 if net_scenario not in myInstance["instance"]["networks"]:
642 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200643 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
644 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
645 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-create"] = net_datacenter
tiernoa4e1a6e2016-08-31 14:19:40 +0200646 if args.keypair:
647 if "cloud-config" not in myInstance["instance"]:
648 myInstance["instance"]["cloud-config"] = {}
649 cloud_config = myInstance["instance"]["cloud-config"]
650 for key in args.keypair:
651 index = key.find(":")
652 if index<0:
653 if "key-pairs" not in cloud_config:
654 cloud_config["key-pairs"] = []
655 cloud_config["key-pairs"].append(key)
656 else:
657 user = key[:index]
658 key_ = key[index+1:]
659 key_list = key_.split(",")
660 if "users" not in cloud_config:
661 cloud_config["users"] = []
662 cloud_config["users"].append({"name": user, "key-pairs": key_list })
663 if args.keypair_auto:
664 try:
665 keys=[]
666 home = os.getenv("HOME")
667 user = os.getenv("USER")
668 files = os.listdir(home+'/.ssh')
669 for file in files:
670 if file[-4:] == ".pub":
671 with open(home+'/.ssh/'+file, 'r') as f:
672 keys.append(f.read())
673 if not keys:
674 print "Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh')
675 return 1
676 except Exception as e:
677 print "Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e))
678 return 1
679
680 if "cloud-config" not in myInstance["instance"]:
681 myInstance["instance"]["cloud-config"] = {}
682 cloud_config = myInstance["instance"]["cloud-config"]
683 if "key-pairs" not in cloud_config:
684 cloud_config["key-pairs"] = []
685 if user:
686 if "users" not in cloud_config:
687 cloud_config["users"] = []
688 cloud_config["users"].append({"name": user, "key-pairs": keys })
tierno7edb6752016-03-21 17:37:52 +0100689
690 payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
691 logger.debug("openmano request: %s", payload_req)
692 URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant)
693 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
694 logger.debug("openmano response: %s", mano_response.text )
695 if args.verbose==None:
696 args.verbose=0
697
698 result = 0 if mano_response.status_code==200 else mano_response.status_code
699 content = mano_response.json()
700 #print json.dumps(content, indent=4)
701 if args.verbose >= 3:
702 print yaml.safe_dump(content, indent=4, default_flow_style=False)
703 return result
704
705 if mano_response.status_code == 200:
706 myoutput = "%s %s" %(content['uuid'].ljust(38),content['name'].ljust(20))
707 if args.verbose >=1:
708 myoutput = "%s %s" %(myoutput, content['created_at'].ljust(20))
709 if args.verbose >=2:
710 myoutput = "%s %s %s" %(myoutput, content['description'].ljust(30))
711 print myoutput
712 else:
713 print content['error']['description']
714 return result
715
716def instance_scenario_list(args):
717 #print "instance-scenario-list",args
718 if args.all:
719 tenant = "any"
720 else:
721 tenant = _get_tenant()
722 if args.name:
723 toshow = _get_item_uuid("instances", args.name, tenant)
724 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, toshow)
725 else:
726 URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant)
727 mano_response = requests.get(URLrequest)
728 logger.debug("openmano response: %s", mano_response.text )
729 content = mano_response.json()
730 #print json.dumps(content, indent=4)
731 if args.verbose==None:
732 args.verbose=0
733
734 result = 0 if mano_response.status_code==200 else mano_response.status_code
735 if mano_response.status_code == 200:
736 if not args.name:
737 if args.verbose >= 3:
738 print yaml.safe_dump(content, indent=4, default_flow_style=False)
739 return result
740 if len(content['instances']) == 0:
741 print "No scenario instances were found."
742 return result
743 for instance in content['instances']:
744 myoutput = "%s %s" %(instance['uuid'].ljust(38),instance['name'].ljust(20))
745 if args.verbose >=1:
746 myoutput = "%s %s" %(myoutput, instance['created_at'].ljust(20))
747 print myoutput
748 if args.verbose >=2:
749 print "Description: %s" %instance['description']
750 else:
751 if args.verbose:
752 print yaml.safe_dump(content, indent=4, default_flow_style=False)
753 return result
754 instance = content
755 print "%s %s %s" %(instance['uuid'].ljust(38),instance['name'].ljust(20),instance['created_at'].ljust(20))
756 print "Description: %s" %instance['description']
757 print "Template scenario id: %s" %instance['scenario_id']
758 print "Template scenario name: %s" %instance['scenario_name']
759 print "---------------------------------------"
760 print "VNF instances: %d" %len(instance['vnfs'])
761 for vnf in instance['vnfs']:
762 #print " %s %s Template vnf name: %s Template vnf id: %s" %(vnf['uuid'].ljust(38), vnf['name'].ljust(20), vnf['vnf_name'].ljust(20), vnf['vnf_id'].ljust(38))
763 print " %s %s Template vnf id: %s" %(vnf['uuid'].ljust(38), vnf['vnf_name'].ljust(20), vnf['vnf_id'].ljust(38))
764 if len(instance['nets'])>0:
765 print "---------------------------------------"
766 print "Internal nets:"
767 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000768 if net['created']:
tierno7edb6752016-03-21 17:37:52 +0100769 print " %s %s VIM ID: %s" %(net['uuid'].ljust(38), net['status'].ljust(12), net['vim_net_id'])
770 print "---------------------------------------"
771 print "External nets:"
772 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000773 if not net['created']:
tierno7edb6752016-03-21 17:37:52 +0100774 print " %s %s VIM ID: %s" %(net['uuid'].ljust(38), net['status'].ljust(12), net['vim_net_id'])
775 print "---------------------------------------"
776 print "VM instances:"
777 for vnf in instance['vnfs']:
778 for vm in vnf['vms']:
779 print " %s %s %s %s VIM ID: %s" %(vm['uuid'].ljust(38), vnf['vnf_name'].ljust(20), vm['name'].ljust(20), vm['status'].ljust(12), vm['vim_vm_id'])
780 else:
781 print content['error']['description']
782 if args.verbose:
783 print yaml.safe_dump(content, indent=4, default_flow_style=False)
784 return result
785
786def instance_scenario_status(args):
787 print "instance-scenario-status"
788 return 0
789
790def instance_scenario_delete(args):
791 if args.all:
792 tenant = "any"
793 else:
794 tenant = _get_tenant()
795 todelete = _get_item_uuid("instances", args.name, tenant=tenant)
796 #print "instance-scenario-delete",args
797 if not args.force:
798 r = raw_input("Delete scenario instance %s (y/N)? " %(args.name))
799 if not (len(r)>0 and r[0].lower()=="y"):
800 return
801 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, todelete)
802 mano_response = requests.delete(URLrequest)
803 logger.debug("openmano response: %s", mano_response.text )
804 result = 0 if mano_response.status_code==200 else mano_response.status_code
805 content = mano_response.json()
806 #print json.dumps(content, indent=4)
807 if mano_response.status_code == 200:
808 print content['result']
809 else:
810 print content['error']['description']
811 return result
812
813def instance_scenario_action(args):
814 #print "instance-scenario-action", args
815 tenant = _get_tenant()
816 toact = _get_item_uuid("instances", args.name, tenant=tenant)
817 action={}
818 action[ args.action ] = args.param
819 if args.vnf:
820 action["vnfs"] = args.vnf
821 if args.vm:
822 action["vms"] = args.vm
823
824 headers_req = {'content-type': 'application/json'}
825 payload_req = json.dumps(action, indent=4)
826 URLrequest = "http://%s:%s/openmano/%s/instances/%s/action" %(mano_host, mano_port, tenant, toact)
827 logger.debug("openmano request: %s", payload_req)
828 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
829 logger.debug("openmano response: %s", mano_response.text )
830 result = 0 if mano_response.status_code==200 else mano_response.status_code
831 content = mano_response.json()
832 #print json.dumps(content, indent=4)
833 if mano_response.status_code == 200:
834 if args.verbose:
835 print yaml.safe_dump(content, indent=4, default_flow_style=False)
836 return result
837 for uuid,c in content.iteritems():
838 print "%s %s %s" %(uuid.ljust(38), c['name'].ljust(20),c['description'].ljust(20))
839 else:
840 print content['error']['description']
841 return result
842
843
844def instance_vnf_list(args):
845 print "instance-vnf-list"
846 return 0
847
848def instance_vnf_status(args):
849 print "instance-vnf-status"
850 return 0
851
852def tenant_create(args):
853 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
854 tenant_dict={"name": args.name}
855 if args.description!=None:
856 tenant_dict["description"] = args.description
857 payload_req = json.dumps( {"tenant": tenant_dict })
858
859 #print payload_req
860
861 URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port)
862 logger.debug("openmano request: %s", payload_req)
863 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
864 logger.debug("openmano response: %s", mano_response.text )
865 return _print_verbose(mano_response, args.verbose)
866
867def tenant_list(args):
868 #print "tenant-list",args
869 if args.name:
tierno392f2852016-05-13 12:28:55 +0200870 toshow = _get_item_uuid("tenants", args.name)
tierno7edb6752016-03-21 17:37:52 +0100871 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, toshow)
872 else:
873 URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port)
874 mano_response = requests.get(URLrequest)
875 logger.debug("openmano response: %s", mano_response.text )
876 if args.verbose==None:
877 args.verbose=0
878 if args.name!=None:
879 args.verbose += 1
880 return _print_verbose(mano_response, args.verbose)
881
882def tenant_delete(args):
883 #print "tenant-delete",args
884 todelete = _get_item_uuid("tenants", args.name)
885 if not args.force:
886 r = raw_input("Delete tenant %s (y/N)? " %(args.name))
887 if not (len(r)>0 and r[0].lower()=="y"):
888 return 0
889 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, todelete)
890 mano_response = requests.delete(URLrequest)
891 logger.debug("openmano response: %s", mano_response.text )
892 result = 0 if mano_response.status_code==200 else mano_response.status_code
893 content = mano_response.json()
894 #print json.dumps(content, indent=4)
895 if mano_response.status_code == 200:
896 print content['result']
897 else:
898 print content['error']['description']
899 return result
900
901def datacenter_attach(args):
902 tenant = _get_tenant()
903 datacenter = _get_datacenter(args.name)
904 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
905
906 datacenter_dict={}
907 if args.vim_tenant_id != None:
908 datacenter_dict['vim_tenant'] = args.vim_tenant_id
909 if args.vim_tenant_name != None:
910 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
911 if args.user != None:
912 datacenter_dict['vim_username'] = args.user
913 if args.password != None:
914 datacenter_dict['vim_password'] = args.password
tierno8008c3a2016-10-13 15:34:28 +0000915 if args.config!=None:
916 datacenter_dict["config"] = _load_file_or_yaml(args.config)
tierno7edb6752016-03-21 17:37:52 +0100917 payload_req = json.dumps( {"datacenter": datacenter_dict })
918
919 #print payload_req
920
921 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter)
922 logger.debug("openmano request: %s", payload_req)
923 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
924 logger.debug("openmano response: %s", mano_response.text )
925 result = _print_verbose(mano_response, args.verbose)
926 #provide addional information if error
927 if mano_response.status_code != 200:
928 content = mano_response.json()
929 if "already in use for 'name'" in content['error']['description'] and \
930 "to database vim_tenants table" in content['error']['description']:
931 print "Try to specify a different name with --vim-tenant-name"
932 return result
933
934def datacenter_detach(args):
935 if args.all:
936 tenant = "any"
937 else:
938 tenant = _get_tenant()
939 datacenter = _get_datacenter(args.name, tenant)
940 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
941 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter)
942 mano_response = requests.delete(URLrequest, headers=headers_req)
943 logger.debug("openmano response: %s", mano_response.text )
944 content = mano_response.json()
945 #print json.dumps(content, indent=4)
946 result = 0 if mano_response.status_code==200 else mano_response.status_code
947 if mano_response.status_code == 200:
948 print content['result']
949 else:
950 print content['error']['description']
951 return result
952
953def datacenter_create(args):
954 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
955 datacenter_dict={"name": args.name, "vim_url": args.url}
956 if args.description!=None:
957 datacenter_dict["description"] = args.description
958 if args.type!=None:
959 datacenter_dict["type"] = args.type
960 if args.url!=None:
961 datacenter_dict["vim_url_admin"] = args.url_admin
962 if args.config!=None:
963 datacenter_dict["config"] = _load_file_or_yaml(args.config)
964 payload_req = json.dumps( {"datacenter": datacenter_dict })
965
966 #print payload_req
967
968 URLrequest = "http://%s:%s/openmano/datacenters" %(mano_host, mano_port)
969 logger.debug("openmano request: %s", payload_req)
970 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
971 logger.debug("openmano response: %s", mano_response.text )
972 return _print_verbose(mano_response, args.verbose)
973
974def datacenter_delete(args):
975 #print "datacenter-delete",args
976 todelete = _get_item_uuid("datacenters", args.name, "any")
977 if not args.force:
978 r = raw_input("Delete datacenter %s (y/N)? " %(args.name))
979 if not (len(r)>0 and r[0].lower()=="y"):
980 return 0
981 URLrequest = "http://%s:%s/openmano/datacenters/%s" %(mano_host, mano_port, todelete)
982 mano_response = requests.delete(URLrequest)
983 logger.debug("openmano response: %s", mano_response.text )
984 result = 0 if mano_response.status_code==200 else mano_response.status_code
985 content = mano_response.json()
986 #print json.dumps(content, indent=4)
987 if mano_response.status_code == 200:
988 print content['result']
989 else:
990 print content['error']['description']
991 return result
992
993def datacenter_list(args):
994 #print "datacenter-list",args
995 tenant='any' if args.all else _get_tenant()
996
997 if args.name:
998 toshow = _get_item_uuid("datacenters", args.name, tenant)
999 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, toshow)
1000 else:
1001 URLrequest = "http://%s:%s/openmano/%s/datacenters" %(mano_host, mano_port, tenant)
1002 mano_response = requests.get(URLrequest)
1003 logger.debug("openmano response: %s", mano_response.text )
1004 if args.verbose==None:
1005 args.verbose=0
1006 if args.name!=None:
1007 args.verbose += 1
1008 return _print_verbose(mano_response, args.verbose)
1009
1010def vim_action(args):
1011 #print "datacenter-net-action",args
1012 tenant = _get_tenant()
1013 datacenter = _get_datacenter(args.datacenter, tenant)
1014 if args.verbose==None:
1015 args.verbose=0
1016 if args.action=="list":
1017 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
1018 if args.name!=None:
1019 args.verbose += 1
1020 URLrequest += "/" + args.name
1021 mano_response = requests.get(URLrequest)
1022 logger.debug("openmano response: %s", mano_response.text )
1023 return _print_verbose(mano_response, args.verbose)
1024 elif args.action=="delete":
1025 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss/%s" %(mano_host, mano_port, tenant, datacenter, args.item, args.name)
1026 mano_response = requests.delete(URLrequest)
1027 logger.debug("openmano response: %s", mano_response.text )
1028 result = 0 if mano_response.status_code==200 else mano_response.status_code
1029 content = mano_response.json()
1030 #print json.dumps(content, indent=4)
1031 if mano_response.status_code == 200:
1032 print content['result']
1033 else:
1034 print content['error']['description']
1035 return result
1036 elif args.action=="create":
1037 headers_req = {'content-type': 'application/yaml'}
1038 if args.file:
1039 create_dict = _load_file_or_yaml(args.file)
1040 if args.item not in create_dict:
1041 create_dict = {args.item: create_dict}
1042 else:
1043 create_dict = {args.item:{}}
1044 if args.name:
1045 create_dict[args.item]['name'] = args.name
1046 #if args.description:
1047 # create_dict[args.item]['description'] = args.description
1048 if args.item=="vim-net":
1049 if args.bind_net:
1050 create_dict[args.item]['bind_net'] = args.bind_net
1051 if args.bind_type:
1052 create_dict[args.item]['bind_type'] = args.bind_type
1053 if args.shared:
1054 create_dict[args.item]['shared'] = args.shared
1055 if "name" not in create_dict[args.item]:
1056 print "You must provide a name in the descriptor file or with the --name option"
1057 return
1058 payload_req = yaml.safe_dump(create_dict, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
1059 logger.debug("openmano request: %s", payload_req)
1060 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, mano_tenant, datacenter, args.item)
1061 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
1062 logger.debug("openmano response: %s", mano_response.text )
1063 if args.verbose==None:
1064 args.verbose=0
1065 return _print_verbose(mano_response, args.verbose)
1066
1067
1068def datacenter_net_action(args):
1069 if args.action == "net-update":
tierno5acf7202016-08-29 14:28:13 +02001070 print "This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano datacenter-netmap-import' instead!!!"
tierno7edb6752016-03-21 17:37:52 +01001071 print
1072 args.action = "netmap-delete"
1073 args.netmap = None
1074 args.all = True
1075 r = datacenter_netmap_action(args)
1076 if r == 0:
1077 args.force = True
tierno5acf7202016-08-29 14:28:13 +02001078 args.action = "netmap-import"
tierno7edb6752016-03-21 17:37:52 +01001079 r = datacenter_netmap_action(args)
1080 return r
1081
1082 if args.action == "net-edit":
1083 args.netmap = args.net
1084 args.name = None
1085 elif args.action == "net-list":
1086 args.netmap = None
1087 elif args.action == "net-delete":
1088 args.netmap = args.net
1089 args.all = False
1090
1091 args.action = "netmap" + args.action[3:]
1092 args.vim_name=None
1093 args.vim_id=None
1094 print "This command is deprecated, use 'openmano datacenter-%s' instead!!!" % args.action
1095 print
1096 return datacenter_netmap_action(args)
1097
1098def datacenter_netmap_action(args):
1099 tenant = _get_tenant()
1100 datacenter = _get_datacenter(args.datacenter, tenant)
1101 #print "datacenter_netmap_action",args
1102 payload_req = None
1103 if args.verbose==None:
1104 args.verbose=0
1105 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1106 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/netmaps" %(mano_host, mano_port, tenant, datacenter)
1107
1108 if args.action=="netmap-list":
1109 if args.netmap:
1110 URLrequest += "/" + args.netmap
1111 args.verbose += 1
1112 mano_response = requests.get(URLrequest)
1113
1114 elif args.action=="netmap-delete":
1115 if args.netmap and args.all:
1116 print "you can not use a netmap name and the option --all at the same time"
1117 return 1
1118 if args.netmap:
1119 force_text= "Delete default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter)
1120 URLrequest += "/" + args.netmap
1121 elif args.all:
1122 force_text="Delete all default netmaps from datacenter '%s' (y/N)? " % (datacenter)
1123 else:
tiernoae4a8d12016-07-08 12:30:39 +02001124 print "you must specify a netmap name or the option --all"
tierno7edb6752016-03-21 17:37:52 +01001125 return 1
1126 if not args.force:
1127 r = raw_input(force_text)
1128 if len(r)>0 and r[0].lower()=="y":
1129 pass
1130 else:
1131 return 0
1132 mano_response = requests.delete(URLrequest, headers=headers_req)
tierno5acf7202016-08-29 14:28:13 +02001133 elif args.action=="netmap-import":
tierno7edb6752016-03-21 17:37:52 +01001134 if not args.force:
1135 r = raw_input("Create all the available networks from datacenter '%s' as default netmaps (y/N)? " % (datacenter))
1136 if len(r)>0 and r[0].lower()=="y":
1137 pass
1138 else:
1139 return 0
1140 URLrequest += "/upload"
1141 mano_response = requests.post(URLrequest, headers=headers_req)
1142 elif args.action=="netmap-edit" or args.action=="netmap-create":
1143 if args.file:
1144 payload = _load_file_or_yaml(args.file)
1145 else:
1146 payload = {}
1147 if "netmap" not in payload:
1148 payload = {"netmap": payload}
1149 if args.name:
1150 payload["netmap"]["name"] = args.name
1151 if args.vim_id:
1152 payload["netmap"]["vim_id"] = args.vim_id
1153 if args.action=="netmap-create" and args.vim_name:
1154 payload["netmap"]["vim_name"] = args.vim_name
1155 payload_req = json.dumps(payload)
1156 logger.debug("openmano request: %s", payload_req)
1157
1158 if args.action=="netmap-edit" and not args.force:
1159 if len(payload["netmap"]) == 0:
1160 print "You must supply some parameter to edit"
1161 return 1
1162 r = raw_input("Edit default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter))
1163 if len(r)>0 and r[0].lower()=="y":
1164 pass
1165 else:
1166 return 0
1167 URLrequest += "/" + args.netmap
1168 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1169 else: #netmap-create
1170 if "vim_name" not in payload["netmap"] and "vim_id" not in payload["netmap"]:
1171 print "You must supply either --vim-id or --vim-name option; or include one of them in the file descriptor"
1172 return 1
1173 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1174
1175 logger.debug("openmano response: %s", mano_response.text )
1176 return _print_verbose(mano_response, args.verbose)
1177
1178def element_edit(args):
1179 element = _get_item_uuid(args.element, args.name)
1180 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1181 URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, args.element, element)
1182 payload=_load_file_or_yaml(args.file)
1183 if args.element[:-1] not in payload:
1184 payload = {args.element[:-1]: payload }
1185 payload_req = json.dumps(payload)
1186
1187 #print payload_req
1188 if not args.force or (args.name==None and args.filer==None):
1189 r = raw_input(" Edit " + args.element[:-1] + " " + args.name + " (y/N)? ")
1190 if len(r)>0 and r[0].lower()=="y":
1191 pass
1192 else:
1193 return 0
1194 logger.debug("openmano request: %s", payload_req)
1195 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1196 logger.debug("openmano response: %s", mano_response.text )
1197 if args.verbose==None:
1198 args.verbose=0
1199 if args.name!=None:
1200 args.verbose += 1
1201 return _print_verbose(mano_response, args.verbose)
1202
1203
1204global mano_host
1205global mano_port
1206global mano_tenant
1207
1208if __name__=="__main__":
1209
1210 mano_tenant = os.getenv('OPENMANO_TENANT', None)
1211 mano_host = os.getenv('OPENMANO_HOST',"localhost")
1212 mano_port = os.getenv('OPENMANO_PORT',"9090")
1213 mano_datacenter = os.getenv('OPENMANO_DATACENTER',None)
1214
1215 main_parser = ThrowingArgumentParser(description='User program to interact with OPENMANO-SERVER (openmanod)')
1216 main_parser.add_argument('--version', action='version', version='%(prog)s ' + __version__ )
1217
1218 subparsers = main_parser.add_subparsers(help='commands')
1219
tierno7edb6752016-03-21 17:37:52 +01001220 parent_parser = argparse.ArgumentParser(add_help=False)
1221 parent_parser.add_argument('--verbose', '-v', action='count', help="increase verbosity level. Use several times")
1222 parent_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
1223
garciadeblas0e9fd832016-07-08 15:20:18 +02001224 config_parser = subparsers.add_parser('config', parents=[parent_parser], help="prints configuration values")
1225 config_parser.add_argument("-n", action="store_true", help="resolves tenant and datacenter names")
1226 config_parser.set_defaults(func=config)
1227
tierno7edb6752016-03-21 17:37:52 +01001228 vnf_create_parser = subparsers.add_parser('vnf-create', parents=[parent_parser], help="adds a vnf into the catalogue")
1229 vnf_create_parser.add_argument("file", action="store", help="location of the JSON file describing the VNF").completer = FilesCompleter
1230 vnf_create_parser.add_argument("--name", action="store", help="name of the VNF (if it exists in the VNF descriptor, it is overwritten)")
1231 vnf_create_parser.add_argument("--description", action="store", help="description of the VNF (if it exists in the VNF descriptor, it is overwritten)")
1232 vnf_create_parser.add_argument("--image-path", action="store", help="change image path locations (overwritten)")
garciadeblas14480452017-01-10 13:08:07 +01001233 vnf_create_parser.add_argument("--image-name", action="store", help="change image name (overwritten)")
1234 vnf_create_parser.add_argument("--image-checksum", action="store", help="change image checksum (overwritten)")
tierno7edb6752016-03-21 17:37:52 +01001235 vnf_create_parser.set_defaults(func=vnf_create)
1236
1237 vnf_list_parser = subparsers.add_parser('vnf-list', parents=[parent_parser], help="lists information about a vnf")
1238 vnf_list_parser.add_argument("name", nargs='?', help="name of the VNF")
1239 vnf_list_parser.add_argument("-a", "--all", action="store_true", help="shows all vnfs, not only the owned or public ones")
1240 #vnf_list_parser.add_argument('--descriptor', help="prints the VNF descriptor", action="store_true")
1241 vnf_list_parser.set_defaults(func=vnf_list)
1242
1243 vnf_delete_parser = subparsers.add_parser('vnf-delete', parents=[parent_parser], help="deletes a vnf from the catalogue")
1244 vnf_delete_parser.add_argument("name", action="store", help="name or uuid of the VNF to be deleted")
1245 vnf_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1246 vnf_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
1247 vnf_delete_parser.set_defaults(func=vnf_delete)
1248
1249 scenario_create_parser = subparsers.add_parser('scenario-create', parents=[parent_parser], help="adds a scenario into the OPENMANO DB")
1250 scenario_create_parser.add_argument("file", action="store", help="location of the YAML file describing the scenario").completer = FilesCompleter
1251 scenario_create_parser.add_argument("--name", action="store", help="name of the scenario (if it exists in the YAML scenario, it is overwritten)")
1252 scenario_create_parser.add_argument("--description", action="store", help="description of the scenario (if it exists in the YAML scenario, it is overwritten)")
1253 scenario_create_parser.set_defaults(func=scenario_create)
1254
1255 scenario_list_parser = subparsers.add_parser('scenario-list', parents=[parent_parser], help="lists information about a scenario")
1256 scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario")
1257 #scenario_list_parser.add_argument('--descriptor', help="prints the scenario descriptor", action="store_true")
1258 scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all scenarios, not only the owned or public ones")
1259 scenario_list_parser.set_defaults(func=scenario_list)
1260
1261 scenario_delete_parser = subparsers.add_parser('scenario-delete', parents=[parent_parser], help="deletes a scenario from the OPENMANO DB")
1262 scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario to be deleted")
1263 scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1264 scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
1265 scenario_delete_parser.set_defaults(func=scenario_delete)
1266
1267 scenario_deploy_parser = subparsers.add_parser('scenario-deploy', parents=[parent_parser], help="deploys a scenario")
1268 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be deployed")
1269 scenario_deploy_parser.add_argument("name", action="store", help="name of the instance")
1270 scenario_deploy_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
1271 scenario_deploy_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
1272 scenario_deploy_parser.add_argument("--description", action="store", help="description of the instance")
1273 scenario_deploy_parser.set_defaults(func=scenario_deploy)
1274
1275 scenario_deploy_parser = subparsers.add_parser('scenario-verify', help="verifies if a scenario can be deployed (deploys it and deletes it)")
1276 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be verified")
1277 scenario_deploy_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
1278 scenario_deploy_parser.set_defaults(func=scenario_verify)
1279
1280 instance_scenario_create_parser = subparsers.add_parser('instance-scenario-create', parents=[parent_parser], help="deploys a scenario")
1281 instance_scenario_create_parser.add_argument("file", nargs='?', help="descriptor of the instance. Must be a file or yaml/json text")
1282 instance_scenario_create_parser.add_argument("--scenario", action="store", help="name or uuid of the scenario to be deployed")
1283 instance_scenario_create_parser.add_argument("--name", action="store", help="name of the instance")
1284 instance_scenario_create_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
1285 instance_scenario_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
1286 instance_scenario_create_parser.add_argument("--netmap-use", action="append", type=str, dest="netmap_use", help="indicates a datacenter network to map a scenario network 'scenario-network=datacenter-network'. Can be used several times")
1287 instance_scenario_create_parser.add_argument("--netmap-create", action="append", type=str, dest="netmap_create", help="the scenario network must be created at datacenter 'scenario-network[=datacenter-network-name]' . Can be used several times")
tiernoa4e1a6e2016-08-31 14:19:40 +02001288 instance_scenario_create_parser.add_argument("--keypair", action="append", type=str, dest="keypair", help="public key for ssh access. Format '[user:]key1[,key2...]'. Can be used several times")
1289 instance_scenario_create_parser.add_argument("--keypair-auto", action="store_true", dest="keypair_auto", help="Inject the user ssh-keys found at $HOME/.ssh directory")
tierno7edb6752016-03-21 17:37:52 +01001290 instance_scenario_create_parser.add_argument("--description", action="store", help="description of the instance")
1291 instance_scenario_create_parser.set_defaults(func=instance_create)
1292
1293 instance_scenario_list_parser = subparsers.add_parser('instance-scenario-list', parents=[parent_parser], help="lists information about a scenario instance")
1294 instance_scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario instance")
1295 instance_scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all instance-scenarios, not only the owned")
1296 instance_scenario_list_parser.set_defaults(func=instance_scenario_list)
1297
1298 instance_scenario_delete_parser = subparsers.add_parser('instance-scenario-delete', parents=[parent_parser], help="deletes a scenario instance (and deletes all VM and net instances in VIM)")
1299 instance_scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario instance to be deleted")
1300 instance_scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1301 instance_scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
1302 instance_scenario_delete_parser.set_defaults(func=instance_scenario_delete)
1303
1304 instance_scenario_action_parser = subparsers.add_parser('instance-scenario-action', parents=[parent_parser], help="invoke an action over part or the whole scenario instance")
1305 instance_scenario_action_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
1306 instance_scenario_action_parser.add_argument("action", action="store", type=str, \
1307 choices=["start","pause","resume","shutoff","shutdown","forceOff","rebuild","reboot", "console"],\
1308 help="action to send")
1309 instance_scenario_action_parser.add_argument("param", nargs='?', help="addional param of the action. e.g. console type (novnc, ...), reboot type (TODO)")
1310 instance_scenario_action_parser.add_argument("--vnf", action="append", help="VNF to act on (can use several entries)")
1311 instance_scenario_action_parser.add_argument("--vm", action="append", help="VM to act on (can use several entries)")
1312 instance_scenario_action_parser.set_defaults(func=instance_scenario_action)
1313
1314 #instance_scenario_status_parser = subparsers.add_parser('instance-scenario-status', help="show the status of a scenario instance")
1315 #instance_scenario_status_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
1316 #instance_scenario_status_parser.set_defaults(func=instance_scenario_status)
1317
1318 tenant_create_parser = subparsers.add_parser('tenant-create', parents=[parent_parser], help="creates a new tenant")
1319 tenant_create_parser.add_argument("name", action="store", help="name for the tenant")
1320 tenant_create_parser.add_argument("--description", action="store", help="description of the tenant")
1321 tenant_create_parser.set_defaults(func=tenant_create)
1322
1323 tenant_delete_parser = subparsers.add_parser('tenant-delete', parents=[parent_parser], help="deletes a tenant from the catalogue")
1324 tenant_delete_parser.add_argument("name", action="store", help="name or uuid of the tenant to be deleted")
1325 tenant_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1326 tenant_delete_parser.set_defaults(func=tenant_delete)
1327
1328 tenant_list_parser = subparsers.add_parser('tenant-list', parents=[parent_parser], help="lists information about a tenant")
1329 tenant_list_parser.add_argument("name", nargs='?', help="name or uuid of the tenant")
1330 tenant_list_parser.set_defaults(func=tenant_list)
1331
1332 item_list=('tenant','datacenter') #put tenant before so that help appear in order
1333 for item in item_list:
1334 element_edit_parser = subparsers.add_parser(item+'-edit', parents=[parent_parser], help="edits one "+item)
1335 element_edit_parser.add_argument("name", help="name or uuid of the "+item)
1336 element_edit_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
1337 element_edit_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1338 element_edit_parser.set_defaults(func=element_edit, element=item + 's')
1339
1340 datacenter_create_parser = subparsers.add_parser('datacenter-create', parents=[parent_parser], help="creates a new datacenter")
1341 datacenter_create_parser.add_argument("name", action="store", help="name for the datacenter")
1342 datacenter_create_parser.add_argument("url", action="store", help="url for the datacenter")
1343 datacenter_create_parser.add_argument("--url_admin", action="store", help="url for administration for the datacenter")
1344 datacenter_create_parser.add_argument("--type", action="store", help="datacenter type: openstack or openvim (default)")
1345 datacenter_create_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
1346 datacenter_create_parser.add_argument("--description", action="store", help="description of the datacenter")
1347 datacenter_create_parser.set_defaults(func=datacenter_create)
1348
1349 datacenter_delete_parser = subparsers.add_parser('datacenter-delete', parents=[parent_parser], help="deletes a datacenter from the catalogue")
1350 datacenter_delete_parser.add_argument("name", action="store", help="name or uuid of the datacenter to be deleted")
1351 datacenter_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1352 datacenter_delete_parser.set_defaults(func=datacenter_delete)
1353
1354 datacenter_list_parser = subparsers.add_parser('datacenter-list', parents=[parent_parser], help="lists information about a datacenter")
1355 datacenter_list_parser.add_argument("name", nargs='?', help="name or uuid of the datacenter")
1356 datacenter_list_parser.add_argument("-a", "--all", action="store_true", help="shows all datacenters, not only datacenters attached to tenant")
1357 datacenter_list_parser.set_defaults(func=datacenter_list)
1358
1359 datacenter_attach_parser = subparsers.add_parser('datacenter-attach', parents=[parent_parser], help="associates a datacenter to the operating tenant")
1360 datacenter_attach_parser.add_argument("name", help="name or uuid of the datacenter")
1361 datacenter_attach_parser.add_argument('--vim-tenant-id', action='store', help="specify a datacenter tenant to use. A new one is created by default")
1362 datacenter_attach_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
1363 datacenter_attach_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
1364 datacenter_attach_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
tierno8008c3a2016-10-13 15:34:28 +00001365 datacenter_attach_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
tierno7edb6752016-03-21 17:37:52 +01001366 datacenter_attach_parser.set_defaults(func=datacenter_attach)
1367
1368 datacenter_detach_parser = subparsers.add_parser('datacenter-detach', parents=[parent_parser], help="removes the association between a datacenter and the operating tenant")
1369 datacenter_detach_parser.add_argument("name", help="name or uuid of the datacenter")
1370 datacenter_detach_parser.add_argument("-a", "--all", action="store_true", help="removes all associations from this datacenter")
1371 datacenter_detach_parser.set_defaults(func=datacenter_detach)
1372
1373
1374 action_dict={'net-update': 'retrieves external networks from datacenter',
1375 'net-edit': 'edits an external network',
1376 'net-delete': 'deletes an external network',
1377 'net-list': 'lists external networks from a datacenter'
1378 }
1379 for item in action_dict:
1380 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
1381 datacenter_action_parser.add_argument("datacenter", help="name or uuid of the datacenter")
1382 if item=='net-edit' or item=='net-delete':
1383 datacenter_action_parser.add_argument("net", help="name or uuid of the datacenter net")
1384 if item=='net-edit':
1385 datacenter_action_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
1386 if item!='net-list':
1387 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1388 datacenter_action_parser.set_defaults(func=datacenter_net_action, action=item)
1389
1390
tierno5acf7202016-08-29 14:28:13 +02001391 action_dict={'netmap-import': 'create network senario netmap base on the datacenter networks',
tierno7edb6752016-03-21 17:37:52 +01001392 'netmap-create': 'create a new network senario netmap',
1393 'netmap-edit': 'edit name of a network senario netmap',
1394 'netmap-delete': 'deletes a network scenario netmap (--all for clearing all)',
1395 'netmap-list': 'list/show network scenario netmaps'
1396 }
1397 for item in action_dict:
1398 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
1399 datacenter_action_parser.add_argument("--datacenter", help="name or uuid of the datacenter")
1400 #if item=='net-add':
1401 # datacenter_action_parser.add_argument("net", help="name of the network")
1402 if item=='netmap-delete':
1403 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to delete")
1404 datacenter_action_parser.add_argument("--all", action="store_true", help="delete all netmap of this datacenter")
1405 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1406 if item=='netmap-edit':
1407 datacenter_action_parser.add_argument("netmap", help="name or uuid of the datacenter netmap do edit")
1408 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file with the changes").completer = FilesCompleter
1409 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap")
1410 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
1411 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1412 if item=='netmap-list':
1413 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to show")
1414 if item=='netmap-create':
1415 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file descriptor with the changes").completer = FilesCompleter
1416 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap, by default same as vim-name")
1417 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
1418 datacenter_action_parser.add_argument('--vim-name', action='store', help="specify vim network name")
tierno5acf7202016-08-29 14:28:13 +02001419 if item=='netmap-import':
tierno7edb6752016-03-21 17:37:52 +01001420 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1421 datacenter_action_parser.set_defaults(func=datacenter_netmap_action, action=item)
1422
tierno4540ea52017-01-18 17:44:32 +01001423 for item in ("network", "tenant", "image"):
tierno7edb6752016-03-21 17:37:52 +01001424 if item=="network":
1425 commnad_name = 'vim-net'
1426 else:
1427 commnad_name = 'vim-'+item
1428 vim_item_list_parser = subparsers.add_parser(commnad_name + '-list', parents=[parent_parser], help="list the vim " + item + "s")
1429 vim_item_list_parser.add_argument("name", nargs='?', help="name or uuid of the " + item + "s")
1430 vim_item_list_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
1431 vim_item_list_parser.set_defaults(func=vim_action, item=item, action="list")
1432
1433 vim_item_del_parser = subparsers.add_parser(commnad_name + '-delete', parents=[parent_parser], help="list the vim " + item + "s")
1434 vim_item_del_parser.add_argument("name", help="name or uuid of the " + item + "s")
1435 vim_item_del_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
1436 vim_item_del_parser.set_defaults(func=vim_action, item=item, action="delete")
1437
tierno4540ea52017-01-18 17:44:32 +01001438 if item == "network" or item == "tenant":
1439 vim_item_create_parser = subparsers.add_parser(commnad_name + '-create', parents=[parent_parser], help="create a "+item+" at vim")
1440 vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the %s. Must be a file or yaml/json text" % item).completer = FilesCompleter
1441 vim_item_create_parser.add_argument("--name", action="store", help="name of the %s" % item )
1442 vim_item_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
1443 if item=="network":
1444 vim_item_create_parser.add_argument("--type", action="store", help="type of network, data, ptp, bridge")
1445 vim_item_create_parser.add_argument("--shared", action="store_true", help="Private or shared")
1446 vim_item_create_parser.add_argument("--bind-net", action="store", help="For openvim datacenter type, net to be bind to, for vlan type, use sufix ':<vlan_tag>'")
1447 else:
1448 vim_item_create_parser.add_argument("--description", action="store", help="description of the %s" % item)
1449 vim_item_create_parser.set_defaults(func=vim_action, item=item, action="create")
tierno7edb6752016-03-21 17:37:52 +01001450
1451 argcomplete.autocomplete(main_parser)
1452
1453 try:
1454 args = main_parser.parse_args()
1455 #logging info
1456 level = logging.CRITICAL
1457 streamformat = "%(asctime)s %(name)s %(levelname)s: %(message)s"
1458 if "debug" in args and args.debug:
1459 level = logging.DEBUG
1460 logging.basicConfig(format=streamformat, level= level)
1461 logger = logging.getLogger('mano')
1462 logger.setLevel(level)
1463 result = args.func(args)
1464 if result == None:
1465 result = 0
1466 #for some reason it fails if call exit inside try instance. Need to call exit at the end !?
1467 except (requests.exceptions.ConnectionError):
1468 print "Connection error: not possible to contact OPENMANO-SERVER (openmanod)"
1469 result = -2
1470 except (KeyboardInterrupt):
1471 print 'Exiting openmano'
1472 result = -3
1473 except (SystemExit, ArgumentParserError):
1474 result = -4
1475 except OpenmanoCLIError as e:
1476 print str(e)
1477 result = -5
1478
1479 #print result
1480 exit(result)
1481