blob: ec588a98546b3997d22e64c0679959bddcc75252 [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
tierno20df3bb2017-07-07 14:31:00 +020026"""
tierno7edb6752016-03-21 17:37:52 +010027openmano client used to interact with openmano-server (openmanod)
tierno20df3bb2017-07-07 14:31:00 +020028"""
tierno72a08d72017-05-25 13:12:30 +020029__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
30__date__ = "$09-oct-2014 09:09:48$"
tierno20df3bb2017-07-07 14:31:00 +020031__version__ = "0.4.15-r525"
32version_date = "Jul 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:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +0100123 uuid = None
tierno7edb6752016-03-21 17:37:52 +0100124 for content in content_list:
125 if "uuid" in content:
126 uuid = content['uuid']
127 elif "id" in content:
128 uuid = content['id']
129 elif "vim_id" in content:
130 uuid = content['vim_id']
tierno250954a2017-01-31 14:25:57 +0100131 name = content.get('name');
132 if not uuid:
133 uuid = ""
134 if not name:
135 name = ""
136 myoutput = "%s %s" %(uuid.ljust(38),name.ljust(20))
137 if content.get("status"):
tierno7edb6752016-03-21 17:37:52 +0100138 myoutput += " " + content['status'].ljust(20)
139 elif "enabled" in content and not content["enabled"]:
140 myoutput += " enabled=False".ljust(20)
141 if verbose_level >=1:
tierno250954a2017-01-31 14:25:57 +0100142 if content.get('created_at'):
143 myoutput += " " + content['created_at'].ljust(20)
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +0200144 if content.get('sdn_attached_ports'):
145 #myoutput += " " + str(content['sdn_attached_ports']).ljust(20)
146 myoutput += "\nsdn_attached_ports:\n" + yaml.safe_dump(content['sdn_attached_ports'], indent=4, default_flow_style=False)
tierno7edb6752016-03-21 17:37:52 +0100147 if verbose_level >=2:
148 new_line='\n'
tierno250954a2017-01-31 14:25:57 +0100149 if content.get('type'):
tierno7edb6752016-03-21 17:37:52 +0100150 myoutput += new_line + " Type: " + content['type'].ljust(29)
151 new_line=''
tierno250954a2017-01-31 14:25:57 +0100152 if content.get('description'):
tierno7edb6752016-03-21 17:37:52 +0100153 myoutput += new_line + " Description: " + content['description'].ljust(20)
154 print myoutput
155 else:
156 print content['error']['description']
157 return result
158
159def parser_json_yaml(file_name):
160 try:
161 f = file(file_name, "r")
162 text = f.read()
163 f.close()
164 except Exception as e:
165 return (False, str(e))
166
167 #Read and parse file
168 if file_name[-5:]=='.yaml' or file_name[-4:]=='.yml' or (file_name[-5:]!='.json' and '\t' not in text):
169 try:
170 config = yaml.load(text)
171 except yaml.YAMLError as exc:
172 error_pos = ""
173 if hasattr(exc, 'problem_mark'):
174 mark = exc.problem_mark
175 error_pos = " at line:%s column:%s" % (mark.line+1, mark.column+1)
176 return (False, "Error loading file '"+file_name+"' yaml format error" + error_pos)
177 else: #json
178 try:
179 config = json.loads(text)
180 except Exception as e:
181 return (False, "Error loading file '"+file_name+"' json format error " + str(e) )
182
183 return True, config
184
185def _load_file_or_yaml(content):
186 '''
187 'content' can be or a yaml/json file or a text containing a yaml/json text format
188 This function autodetect, trying to load and parse the file,
189 if fails trying to parse the 'content' text
190 Returns the dictionary once parsed, or print an error and finish the program
191 '''
192 #Check config file exists
193 if os.path.isfile(content):
194 r,payload = parser_json_yaml(content)
195 if not r:
196 print payload
197 exit(-1)
198 elif "{" in content or ":" in content:
199 try:
200 payload = yaml.load(content)
201 except yaml.YAMLError as exc:
202 error_pos = ""
203 if hasattr(exc, 'problem_mark'):
204 mark = exc.problem_mark
205 error_pos = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
206 print "Error loading yaml/json text"+error_pos
207 exit (-1)
208 else:
209 print "'%s' is neither a valid file nor a yaml/json content" % content
210 exit(-1)
211 return payload
212
213def _get_item_uuid(item, item_name_id, tenant=None):
214 if tenant:
215 URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, tenant, item)
216 else:
217 URLrequest = "http://%s:%s/openmano/%s" %(mano_host, mano_port, item)
218 mano_response = requests.get(URLrequest)
219 logger.debug("openmano response: %s", mano_response.text )
220 content = mano_response.json()
221 #print content
222 found = 0
223 for i in content[item]:
224 if i["uuid"] == item_name_id:
225 return item_name_id
226 if i["name"] == item_name_id:
227 uuid = i["uuid"]
228 found += 1
229 if found == 0:
230 raise OpenmanoCLIError("No %s found with name/uuid '%s'" %(item[:-1], item_name_id))
231 elif found > 1:
232 raise OpenmanoCLIError("%d %s found with name '%s'. uuid must be used" %(found, item, item_name_id))
233 return uuid
234#
235# def check_valid_uuid(uuid):
236# id_schema = {"type" : "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
237# try:
238# js_v(uuid, id_schema)
239# return True
240# except js_e.ValidationError:
241# return False
242
243def _get_tenant(tenant_name_id = None):
244 if not tenant_name_id:
245 tenant_name_id = mano_tenant
246 if not mano_tenant:
247 raise OpenmanoCLIError("'OPENMANO_TENANT' environment variable is not set")
248 return _get_item_uuid("tenants", tenant_name_id)
249
250def _get_datacenter(datacenter_name_id = None, tenant = "any"):
251 if not datacenter_name_id:
252 datacenter_name_id = mano_datacenter
253 if not datacenter_name_id:
254 raise OpenmanoCLIError("neither 'OPENMANO_DATACENTER' environment variable is set nor --datacenter option is used")
255 return _get_item_uuid("datacenters", datacenter_name_id, tenant)
256
257def vnf_create(args):
258 #print "vnf-create",args
259 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
260 tenant = _get_tenant()
261 myvnf = _load_file_or_yaml(args.file)
262
garciadeblas14480452017-01-10 13:08:07 +0100263 if args.name or args.description or args.image_path or args.image_name or args.image_checksum:
tierno7edb6752016-03-21 17:37:52 +0100264 #print args.name
265 try:
266 if args.name:
267 myvnf['vnf']['name'] = args.name
268 if args.description:
269 myvnf['vnf']['description'] = args.description
270 if args.image_path:
271 index=0
272 for image_path_ in args.image_path.split(","):
273 #print "image-path", image_path_
274 myvnf['vnf']['VNFC'][index]['VNFC image']=image_path_
tierno941551b2017-01-12 18:26:26 +0100275 if "image name" in myvnf['vnf']['VNFC'][index]:
276 del myvnf['vnf']['VNFC'][index]["image name"]
277 if "image checksum" in myvnf['vnf']['VNFC'][index]:
278 del myvnf['vnf']['VNFC'][index]["image checksum"]
tierno7edb6752016-03-21 17:37:52 +0100279 index=index+1
tierno941551b2017-01-12 18:26:26 +0100280 if args.image_name: #image name precedes if both are supplied
garciadeblas14480452017-01-10 13:08:07 +0100281 index=0
282 for image_name_ in args.image_name.split(","):
283 myvnf['vnf']['VNFC'][index]['image name']=image_name_
tierno941551b2017-01-12 18:26:26 +0100284 if "VNFC image" in myvnf['vnf']['VNFC'][index]:
285 del myvnf['vnf']['VNFC'][index]["VNFC image"]
garciadeblas14480452017-01-10 13:08:07 +0100286 index=index+1
287 if args.image_checksum:
288 index=0
289 for image_checksum_ in args.image_checksum.split(","):
290 myvnf['vnf']['VNFC'][index]['image checksum']=image_checksum_
291 index=index+1
tierno7edb6752016-03-21 17:37:52 +0100292 except (KeyError, TypeError), e:
293 if str(e)=='vnf': error_pos= "missing field 'vnf'"
294 elif str(e)=='name': error_pos= "missing field 'vnf':'name'"
295 elif str(e)=='description': error_pos= "missing field 'vnf':'description'"
296 elif str(e)=='VNFC': error_pos= "missing field 'vnf':'VNFC'"
297 elif str(e)==str(index): error_pos= "field 'vnf':'VNFC' must be an array"
298 elif str(e)=='VNFC image': error_pos= "missing field 'vnf':'VNFC'['VNFC image']"
garciadeblas14480452017-01-10 13:08:07 +0100299 elif str(e)=='image name': error_pos= "missing field 'vnf':'VNFC'['image name']"
300 elif str(e)=='image checksum': error_pos= "missing field 'vnf':'VNFC'['image checksum']"
tierno7edb6752016-03-21 17:37:52 +0100301 else: error_pos="wrong format"
302 print "Wrong VNF descriptor: " + error_pos
303 return -1
304 payload_req = json.dumps(myvnf)
305
306 #print payload_req
307
308 URLrequest = "http://%s:%s/openmano/%s/vnfs" %(mano_host, mano_port, tenant)
309 logger.debug("openmano request: %s", payload_req)
310 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
311 logger.debug("openmano response: %s", mano_response.text )
312
313 return _print_verbose(mano_response, args.verbose)
314
315def vnf_list(args):
316 #print "vnf-list",args
317 if args.all:
318 tenant = "any"
319 else:
320 tenant = _get_tenant()
321 if args.name:
322 toshow = _get_item_uuid("vnfs", args.name, tenant)
323 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, toshow)
324 else:
325 URLrequest = "http://%s:%s/openmano/%s/vnfs" %(mano_host, mano_port, tenant)
326 mano_response = requests.get(URLrequest)
327 logger.debug("openmano response: %s", mano_response.text )
328 content = mano_response.json()
329 #print json.dumps(content, indent=4)
330 if args.verbose==None:
331 args.verbose=0
332 result = 0 if mano_response.status_code==200 else mano_response.status_code
333 if mano_response.status_code == 200:
334 if not args.name:
335 if args.verbose >= 3:
336 print yaml.safe_dump(content, indent=4, default_flow_style=False)
337 return result
338 if len(content['vnfs']) == 0:
339 print "No VNFs were found."
340 return 404 #HTTP_Not_Found
341 for vnf in content['vnfs']:
342 myoutput = "%s %s" %(vnf['uuid'].ljust(38),vnf['name'].ljust(20))
343 if args.verbose >=1:
344 myoutput = "%s %s" %(myoutput, vnf['created_at'].ljust(20))
345 print myoutput
346 if args.verbose >=2:
347 print " Description: %s" %vnf['description']
348 print " VNF descriptor file: %s" %vnf['path']
349 else:
350 if args.verbose:
351 print yaml.safe_dump(content, indent=4, default_flow_style=False)
352 return result
353 vnf = content['vnf']
354 print "%s %s %s" %(vnf['uuid'].ljust(38),vnf['name'].ljust(20), vnf['created_at'].ljust(20))
355 print " Description: %s" %vnf['description']
356 #print " VNF descriptor file: %s" %vnf['path']
357 print " VMs:"
358 for vm in vnf['VNFC']:
359 #print " %s %s %s" %(vm['name'].ljust(20), vm['uuid'].ljust(38), vm['description'].ljust(30))
360 print " %s %s" %(vm['name'].ljust(20), vm['description'])
361 if len(vnf['nets'])>0:
362 print " Internal nets:"
363 for net in vnf['nets']:
364 print " %s %s" %(net['name'].ljust(20), net['description'])
365 if len(vnf['external-connections'])>0:
366 print " External interfaces:"
367 for interface in vnf['external-connections']:
368 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 +0100369 interface.get('vpci',"").ljust(14))
tierno7edb6752016-03-21 17:37:52 +0100370 else:
371 print content['error']['description']
372 if args.verbose:
373 print yaml.safe_dump(content, indent=4, default_flow_style=False)
374 return result
375
376def vnf_delete(args):
377 #print "vnf-delete",args
378 if args.all:
379 tenant = "any"
380 else:
381 tenant = _get_tenant()
382 todelete = _get_item_uuid("vnfs", args.name, tenant=tenant)
383 if not args.force:
384 r = raw_input("Delete VNF %s (y/N)? " %(todelete))
385 if not (len(r)>0 and r[0].lower()=="y"):
386 return 0
387 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, todelete)
388 mano_response = requests.delete(URLrequest)
389 logger.debug("openmano response: %s", mano_response.text )
390 result = 0 if mano_response.status_code==200 else mano_response.status_code
391 content = mano_response.json()
392 #print json.dumps(content, indent=4)
393 if mano_response.status_code == 200:
394 print content['result']
395 else:
396 print content['error']['description']
397 return result
398
399def scenario_create(args):
400 #print "scenario-create",args
401 tenant = _get_tenant()
402 headers_req = {'content-type': 'application/yaml'}
403 myscenario = _load_file_or_yaml(args.file)
404
405 if args.name:
406 myscenario['name'] = args.name
407 if args.description:
408 myscenario['description'] = args.description
409 payload_req = yaml.safe_dump(myscenario, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
410
411 #print payload_req
412
413 URLrequest = "http://%s:%s/openmano/%s/scenarios" %(mano_host, mano_port, tenant)
414 logger.debug("openmano request: %s", payload_req)
415 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
416 logger.debug("openmano response: %s", mano_response.text )
417 return _print_verbose(mano_response, args.verbose)
418
419def scenario_list(args):
420 #print "scenario-list",args
421 if args.all:
422 tenant = "any"
423 else:
424 tenant = _get_tenant()
425 if args.name:
426 toshow = _get_item_uuid("scenarios", args.name, tenant)
427 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, toshow)
428 else:
429 URLrequest = "http://%s:%s/openmano/%s/scenarios" %(mano_host, mano_port, tenant)
430 mano_response = requests.get(URLrequest)
431 logger.debug("openmano response: %s", mano_response.text )
432 content = mano_response.json()
433 #print json.dumps(content, indent=4)
434 if args.verbose==None:
435 args.verbose=0
436
437 result = 0 if mano_response.status_code==200 else mano_response.status_code
438 if mano_response.status_code == 200:
439 if not args.name:
440 if args.verbose >= 3:
441 print yaml.safe_dump(content, indent=4, default_flow_style=False)
442 return result
443 if len(content['scenarios']) == 0:
444 print "No scenarios were found."
445 return 404 #HTTP_Not_Found
446 for scenario in content['scenarios']:
447 myoutput = "%s %s" %(scenario['uuid'].ljust(38),scenario['name'].ljust(20))
448 if args.verbose >=1:
449 myoutput = "%s %s" %(myoutput, scenario['created_at'].ljust(20))
450 print myoutput
451 if args.verbose >=2:
452 print " Description: %s" %scenario['description']
453 else:
454 if args.verbose:
455 print yaml.safe_dump(content, indent=4, default_flow_style=False)
456 return result
457 scenario = content['scenario']
458 myoutput = "%s %s %s" %(scenario['uuid'].ljust(38),scenario['name'].ljust(20), scenario['created_at'].ljust(20))
459 print myoutput
460 print " Description: %s" %scenario['description']
461 print " VNFs:"
462 for vnf in scenario['vnfs']:
463 print " %s %s %s" %(vnf['name'].ljust(20), vnf['vnf_id'].ljust(38), vnf['description'])
464 if len(scenario['nets'])>0:
465 print " Internal nets:"
466 for net in scenario['nets']:
467 if net['description'] is None: #if description does not exist, description is "-". Valid for external and internal nets.
468 net['description'] = '-'
469 if not net['external']:
470 print " %s %s %s" %(net['name'].ljust(20), net['uuid'].ljust(38), net['description'].ljust(30))
471 print " External nets:"
472 for net in scenario['nets']:
473 if net['external']:
474 print " %s %s %s vim-id:%s" %(net['name'].ljust(20), net['uuid'].ljust(38), net['description'].ljust(30), net['vim_id'])
475 else:
476 print content['error']['description']
477 if args.verbose:
478 print yaml.safe_dump(content, indent=4, default_flow_style=False)
479 return result
480
481def scenario_delete(args):
482 #print "scenario-delete",args
483 if args.all:
484 tenant = "any"
485 else:
486 tenant = _get_tenant()
487 todelete = _get_item_uuid("scenarios", args.name, tenant=tenant)
488 if not args.force:
489 r = raw_input("Delete scenario %s (y/N)? " %(args.name))
490 if not (len(r)>0 and r[0].lower()=="y"):
491 return 0
492 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, todelete)
493 mano_response = requests.delete(URLrequest)
494 logger.debug("openmano response: %s", mano_response.text )
495 result = 0 if mano_response.status_code==200 else mano_response.status_code
496 content = mano_response.json()
497 #print json.dumps(content, indent=4)
498 if mano_response.status_code == 200:
499 print content['result']
500 else:
501 print content['error']['description']
502 return result
503
504def scenario_deploy(args):
505 print "This command is deprecated, use 'openmano instance-scenario-create --scenario %s --name %s' instead!!!" % (args.scenario, args.name)
506 print
507 args.file = None
508 args.netmap_use = None
509 args.netmap_create = None
tiernobe41e222016-09-02 15:16:13 +0200510 args.keypair = None
511 args.keypair_auto = None
tierno7edb6752016-03-21 17:37:52 +0100512 return instance_create(args)
513
514# #print "scenario-deploy",args
515# headers_req = {'content-type': 'application/json'}
516# action = {}
517# actionCmd="start"
518# if args.nostart:
519# actionCmd="reserve"
520# action[actionCmd] = {}
521# action[actionCmd]["instance_name"] = args.name
522# if args.datacenter != None:
523# action[actionCmd]["datacenter"] = args.datacenter
524# elif mano_datacenter != None:
525# action[actionCmd]["datacenter"] = mano_datacenter
526#
527# if args.description:
528# action[actionCmd]["description"] = args.description
529# payload_req = json.dumps(action, indent=4)
530# #print payload_req
531#
532# URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, mano_tenant, args.scenario)
533# logger.debug("openmano request: %s", payload_req)
534# mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
535# logger.debug("openmano response: %s", mano_response.text )
536# if args.verbose==None:
537# args.verbose=0
538#
539# result = 0 if mano_response.status_code==200 else mano_response.status_code
540# content = mano_response.json()
541# #print json.dumps(content, indent=4)
542# if args.verbose >= 3:
543# print yaml.safe_dump(content, indent=4, default_flow_style=False)
544# return result
545#
546# if mano_response.status_code == 200:
547# myoutput = "%s %s" %(content['uuid'].ljust(38),content['name'].ljust(20))
548# if args.verbose >=1:
549# myoutput = "%s %s" %(myoutput, content['created_at'].ljust(20))
550# if args.verbose >=2:
551# myoutput = "%s %s %s" %(myoutput, content['description'].ljust(30))
552# print myoutput
553# print ""
554# print "To check the status, run the following command:"
555# print "openmano instance-scenario-list <instance_id>"
556# else:
557# print content['error']['description']
558# return result
559
560def scenario_verify(args):
561 #print "scenario-verify",args
tierno72a08d72017-05-25 13:12:30 +0200562 tenant = _get_tenant()
tierno7edb6752016-03-21 17:37:52 +0100563 headers_req = {'content-type': 'application/json'}
564 action = {}
565 action["verify"] = {}
566 action["verify"]["instance_name"] = "scen-verify-return5"
567 payload_req = json.dumps(action, indent=4)
568 #print payload_req
569
tierno72a08d72017-05-25 13:12:30 +0200570 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, tenant, args.scenario)
tierno7edb6752016-03-21 17:37:52 +0100571 logger.debug("openmano request: %s", payload_req)
572 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
573 logger.debug("openmano response: %s", mano_response.text )
574
575 result = 0 if mano_response.status_code==200 else mano_response.status_code
576 content = mano_response.json()
577 #print json.dumps(content, indent=4)
578 if mano_response.status_code == 200:
579 print content['result']
580 else:
581 print content['error']['description']
582 return result
583
584def instance_create(args):
585 tenant = _get_tenant()
586 headers_req = {'content-type': 'application/yaml'}
587 myInstance={"instance": {}, "schema_version": "0.1"}
588 if args.file:
589 instance_dict = _load_file_or_yaml(args.file)
590 if "instance" not in instance_dict:
591 myInstance = {"instance": instance_dict, "schema_version": "0.1"}
592 else:
593 myInstance = instance_dict
594 if args.name:
595 myInstance["instance"]['name'] = args.name
596 if args.description:
597 myInstance["instance"]['description'] = args.description
598 if args.nostart:
599 myInstance["instance"]['action'] = "reserve"
600 #datacenter
601 datacenter = myInstance["instance"].get("datacenter")
602 if args.datacenter != None:
603 datacenter = args.datacenter
604 myInstance["instance"]["datacenter"] = _get_datacenter(datacenter, tenant)
605 #scenario
606 scenario = myInstance["instance"].get("scenario")
607 if args.scenario != None:
608 scenario = args.scenario
609 if not scenario:
garciadeblased746032017-01-05 11:58:41 +0100610 print "you must provide a scenario in the file descriptor or with --scenario"
tierno7edb6752016-03-21 17:37:52 +0100611 return -1
612 myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant)
613 if args.netmap_use:
614 if "networks" not in myInstance["instance"]:
615 myInstance["instance"]["networks"] = {}
616 for net in args.netmap_use:
617 net_comma_list = net.split(",")
618 for net_comma in net_comma_list:
619 net_tuple = net_comma.split("=")
620 if len(net_tuple) != 2:
621 print "error at netmap-use. Expected net-scenario=net-datacenter. (%s)?" % net_comma
622 return
623 net_scenario = net_tuple[0].strip()
624 net_datacenter = net_tuple[1].strip()
625 if net_scenario not in myInstance["instance"]["networks"]:
626 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200627 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
628 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
629 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-use"] = net_datacenter
tierno7edb6752016-03-21 17:37:52 +0100630 if args.netmap_create:
631 if "networks" not in myInstance["instance"]:
632 myInstance["instance"]["networks"] = {}
633 for net in args.netmap_create:
634 net_comma_list = net.split(",")
635 for net_comma in net_comma_list:
636 net_tuple = net_comma.split("=")
637 if len(net_tuple) == 1:
638 net_scenario = net_tuple[0].strip()
639 net_datacenter = None
640 elif len(net_tuple) == 2:
641 net_scenario = net_tuple[0].strip()
642 net_datacenter = net_tuple[1].strip()
643 else:
644 print "error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. (%s)?" % net_comma
645 return
646 if net_scenario not in myInstance["instance"]["networks"]:
647 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200648 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
649 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
650 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-create"] = net_datacenter
tiernoa4e1a6e2016-08-31 14:19:40 +0200651 if args.keypair:
652 if "cloud-config" not in myInstance["instance"]:
653 myInstance["instance"]["cloud-config"] = {}
654 cloud_config = myInstance["instance"]["cloud-config"]
655 for key in args.keypair:
656 index = key.find(":")
657 if index<0:
658 if "key-pairs" not in cloud_config:
659 cloud_config["key-pairs"] = []
660 cloud_config["key-pairs"].append(key)
661 else:
662 user = key[:index]
663 key_ = key[index+1:]
664 key_list = key_.split(",")
665 if "users" not in cloud_config:
666 cloud_config["users"] = []
667 cloud_config["users"].append({"name": user, "key-pairs": key_list })
668 if args.keypair_auto:
669 try:
670 keys=[]
671 home = os.getenv("HOME")
672 user = os.getenv("USER")
673 files = os.listdir(home+'/.ssh')
674 for file in files:
675 if file[-4:] == ".pub":
676 with open(home+'/.ssh/'+file, 'r') as f:
677 keys.append(f.read())
678 if not keys:
679 print "Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh')
680 return 1
681 except Exception as e:
682 print "Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e))
683 return 1
684
685 if "cloud-config" not in myInstance["instance"]:
686 myInstance["instance"]["cloud-config"] = {}
687 cloud_config = myInstance["instance"]["cloud-config"]
688 if "key-pairs" not in cloud_config:
689 cloud_config["key-pairs"] = []
690 if user:
691 if "users" not in cloud_config:
692 cloud_config["users"] = []
693 cloud_config["users"].append({"name": user, "key-pairs": keys })
tierno7edb6752016-03-21 17:37:52 +0100694
695 payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
696 logger.debug("openmano request: %s", payload_req)
697 URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant)
698 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
699 logger.debug("openmano response: %s", mano_response.text )
700 if args.verbose==None:
701 args.verbose=0
702
703 result = 0 if mano_response.status_code==200 else mano_response.status_code
704 content = mano_response.json()
705 #print json.dumps(content, indent=4)
706 if args.verbose >= 3:
707 print yaml.safe_dump(content, indent=4, default_flow_style=False)
708 return result
709
710 if mano_response.status_code == 200:
711 myoutput = "%s %s" %(content['uuid'].ljust(38),content['name'].ljust(20))
712 if args.verbose >=1:
713 myoutput = "%s %s" %(myoutput, content['created_at'].ljust(20))
714 if args.verbose >=2:
715 myoutput = "%s %s %s" %(myoutput, content['description'].ljust(30))
716 print myoutput
717 else:
718 print content['error']['description']
719 return result
720
721def instance_scenario_list(args):
722 #print "instance-scenario-list",args
723 if args.all:
724 tenant = "any"
725 else:
726 tenant = _get_tenant()
727 if args.name:
728 toshow = _get_item_uuid("instances", args.name, tenant)
729 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, toshow)
730 else:
731 URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant)
732 mano_response = requests.get(URLrequest)
733 logger.debug("openmano response: %s", mano_response.text )
734 content = mano_response.json()
735 #print json.dumps(content, indent=4)
736 if args.verbose==None:
737 args.verbose=0
738
739 result = 0 if mano_response.status_code==200 else mano_response.status_code
740 if mano_response.status_code == 200:
741 if not args.name:
742 if args.verbose >= 3:
743 print yaml.safe_dump(content, indent=4, default_flow_style=False)
744 return result
745 if len(content['instances']) == 0:
746 print "No scenario instances were found."
747 return result
748 for instance in content['instances']:
749 myoutput = "%s %s" %(instance['uuid'].ljust(38),instance['name'].ljust(20))
750 if args.verbose >=1:
751 myoutput = "%s %s" %(myoutput, instance['created_at'].ljust(20))
752 print myoutput
753 if args.verbose >=2:
754 print "Description: %s" %instance['description']
755 else:
756 if args.verbose:
757 print yaml.safe_dump(content, indent=4, default_flow_style=False)
758 return result
759 instance = content
760 print "%s %s %s" %(instance['uuid'].ljust(38),instance['name'].ljust(20),instance['created_at'].ljust(20))
761 print "Description: %s" %instance['description']
762 print "Template scenario id: %s" %instance['scenario_id']
763 print "Template scenario name: %s" %instance['scenario_name']
764 print "---------------------------------------"
765 print "VNF instances: %d" %len(instance['vnfs'])
766 for vnf in instance['vnfs']:
767 #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))
768 print " %s %s Template vnf id: %s" %(vnf['uuid'].ljust(38), vnf['vnf_name'].ljust(20), vnf['vnf_id'].ljust(38))
769 if len(instance['nets'])>0:
770 print "---------------------------------------"
771 print "Internal nets:"
772 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000773 if 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 "External nets:"
777 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000778 if not net['created']:
tierno7edb6752016-03-21 17:37:52 +0100779 print " %s %s VIM ID: %s" %(net['uuid'].ljust(38), net['status'].ljust(12), net['vim_net_id'])
780 print "---------------------------------------"
781 print "VM instances:"
782 for vnf in instance['vnfs']:
783 for vm in vnf['vms']:
784 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'])
785 else:
786 print content['error']['description']
787 if args.verbose:
788 print yaml.safe_dump(content, indent=4, default_flow_style=False)
789 return result
790
791def instance_scenario_status(args):
792 print "instance-scenario-status"
793 return 0
794
795def instance_scenario_delete(args):
796 if args.all:
797 tenant = "any"
798 else:
799 tenant = _get_tenant()
800 todelete = _get_item_uuid("instances", args.name, tenant=tenant)
801 #print "instance-scenario-delete",args
802 if not args.force:
803 r = raw_input("Delete scenario instance %s (y/N)? " %(args.name))
804 if not (len(r)>0 and r[0].lower()=="y"):
805 return
806 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, todelete)
807 mano_response = requests.delete(URLrequest)
808 logger.debug("openmano response: %s", mano_response.text )
809 result = 0 if mano_response.status_code==200 else mano_response.status_code
810 content = mano_response.json()
811 #print json.dumps(content, indent=4)
812 if mano_response.status_code == 200:
813 print content['result']
814 else:
815 print content['error']['description']
816 return result
817
818def instance_scenario_action(args):
819 #print "instance-scenario-action", args
820 tenant = _get_tenant()
821 toact = _get_item_uuid("instances", args.name, tenant=tenant)
822 action={}
823 action[ args.action ] = args.param
824 if args.vnf:
825 action["vnfs"] = args.vnf
826 if args.vm:
827 action["vms"] = args.vm
828
829 headers_req = {'content-type': 'application/json'}
830 payload_req = json.dumps(action, indent=4)
831 URLrequest = "http://%s:%s/openmano/%s/instances/%s/action" %(mano_host, mano_port, tenant, toact)
832 logger.debug("openmano request: %s", payload_req)
833 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
834 logger.debug("openmano response: %s", mano_response.text )
835 result = 0 if mano_response.status_code==200 else mano_response.status_code
836 content = mano_response.json()
837 #print json.dumps(content, indent=4)
838 if mano_response.status_code == 200:
839 if args.verbose:
840 print yaml.safe_dump(content, indent=4, default_flow_style=False)
841 return result
842 for uuid,c in content.iteritems():
843 print "%s %s %s" %(uuid.ljust(38), c['name'].ljust(20),c['description'].ljust(20))
844 else:
845 print content['error']['description']
846 return result
847
848
849def instance_vnf_list(args):
850 print "instance-vnf-list"
851 return 0
852
853def instance_vnf_status(args):
854 print "instance-vnf-status"
855 return 0
856
857def tenant_create(args):
858 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
859 tenant_dict={"name": args.name}
860 if args.description!=None:
861 tenant_dict["description"] = args.description
862 payload_req = json.dumps( {"tenant": tenant_dict })
863
864 #print payload_req
865
866 URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port)
867 logger.debug("openmano request: %s", payload_req)
868 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
869 logger.debug("openmano response: %s", mano_response.text )
870 return _print_verbose(mano_response, args.verbose)
871
872def tenant_list(args):
873 #print "tenant-list",args
874 if args.name:
tierno392f2852016-05-13 12:28:55 +0200875 toshow = _get_item_uuid("tenants", args.name)
tierno7edb6752016-03-21 17:37:52 +0100876 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, toshow)
877 else:
878 URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port)
879 mano_response = requests.get(URLrequest)
880 logger.debug("openmano response: %s", mano_response.text )
881 if args.verbose==None:
882 args.verbose=0
883 if args.name!=None:
884 args.verbose += 1
885 return _print_verbose(mano_response, args.verbose)
886
887def tenant_delete(args):
888 #print "tenant-delete",args
889 todelete = _get_item_uuid("tenants", args.name)
890 if not args.force:
891 r = raw_input("Delete tenant %s (y/N)? " %(args.name))
892 if not (len(r)>0 and r[0].lower()=="y"):
893 return 0
894 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, todelete)
895 mano_response = requests.delete(URLrequest)
896 logger.debug("openmano response: %s", mano_response.text )
897 result = 0 if mano_response.status_code==200 else mano_response.status_code
898 content = mano_response.json()
899 #print json.dumps(content, indent=4)
900 if mano_response.status_code == 200:
901 print content['result']
902 else:
903 print content['error']['description']
904 return result
905
906def datacenter_attach(args):
907 tenant = _get_tenant()
908 datacenter = _get_datacenter(args.name)
909 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
910
911 datacenter_dict={}
912 if args.vim_tenant_id != None:
913 datacenter_dict['vim_tenant'] = args.vim_tenant_id
914 if args.vim_tenant_name != None:
915 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
916 if args.user != None:
917 datacenter_dict['vim_username'] = args.user
918 if args.password != None:
919 datacenter_dict['vim_password'] = args.password
tierno8008c3a2016-10-13 15:34:28 +0000920 if args.config!=None:
921 datacenter_dict["config"] = _load_file_or_yaml(args.config)
tierno7edb6752016-03-21 17:37:52 +0100922 payload_req = json.dumps( {"datacenter": datacenter_dict })
923
924 #print payload_req
925
926 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter)
927 logger.debug("openmano request: %s", payload_req)
928 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
929 logger.debug("openmano response: %s", mano_response.text )
930 result = _print_verbose(mano_response, args.verbose)
931 #provide addional information if error
932 if mano_response.status_code != 200:
933 content = mano_response.json()
934 if "already in use for 'name'" in content['error']['description'] and \
935 "to database vim_tenants table" in content['error']['description']:
936 print "Try to specify a different name with --vim-tenant-name"
937 return result
938
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +0100939
940def datacenter_edit_vim_tenant(args):
941 tenant = _get_tenant()
942 datacenter = _get_datacenter(args.name)
943 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
944
945 if not (args.vim_tenant_id or args.vim_tenant_name or args.user or args.password or args.config):
946 raise OpenmanoCLIError("Error. At least one parameter must be updated.")
947
948 datacenter_dict = {}
949 if args.vim_tenant_id != None:
950 datacenter_dict['vim_tenant'] = args.vim_tenant_id
951 if args.vim_tenant_name != None:
952 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
953 if args.user != None:
954 datacenter_dict['vim_username'] = args.user
955 if args.password != None:
956 datacenter_dict['vim_password'] = args.password
957 if args.config != None:
958 datacenter_dict["config"] = _load_file_or_yaml(args.config)
959 payload_req = json.dumps({"datacenter": datacenter_dict})
960
961 # print payload_req
962
963 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" % (mano_host, mano_port, tenant, datacenter)
964 logger.debug("openmano request: %s", payload_req)
965 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
966 logger.debug("openmano response: %s", mano_response.text)
967 result = _print_verbose(mano_response, args.verbose)
968
969 return result
970
tierno7edb6752016-03-21 17:37:52 +0100971def datacenter_detach(args):
972 if args.all:
973 tenant = "any"
974 else:
975 tenant = _get_tenant()
976 datacenter = _get_datacenter(args.name, tenant)
977 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
978 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter)
979 mano_response = requests.delete(URLrequest, headers=headers_req)
980 logger.debug("openmano response: %s", mano_response.text )
981 content = mano_response.json()
982 #print json.dumps(content, indent=4)
983 result = 0 if mano_response.status_code==200 else mano_response.status_code
984 if mano_response.status_code == 200:
985 print content['result']
986 else:
987 print content['error']['description']
988 return result
989
990def datacenter_create(args):
991 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
992 datacenter_dict={"name": args.name, "vim_url": args.url}
993 if args.description!=None:
994 datacenter_dict["description"] = args.description
995 if args.type!=None:
996 datacenter_dict["type"] = args.type
997 if args.url!=None:
998 datacenter_dict["vim_url_admin"] = args.url_admin
999 if args.config!=None:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001000 datacenter_dict["config"] = _load_file_or_yaml(args.config)
1001 if args.sdn_controller!=None:
1002 tenant = _get_tenant()
1003 sdn_controller = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1004 if not 'config' in datacenter_dict:
1005 datacenter_dict['config'] = {}
1006 datacenter_dict['config']['sdn-controller'] = sdn_controller
tierno7edb6752016-03-21 17:37:52 +01001007 payload_req = json.dumps( {"datacenter": datacenter_dict })
1008
1009 #print payload_req
1010
1011 URLrequest = "http://%s:%s/openmano/datacenters" %(mano_host, mano_port)
1012 logger.debug("openmano request: %s", payload_req)
1013 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1014 logger.debug("openmano response: %s", mano_response.text )
1015 return _print_verbose(mano_response, args.verbose)
1016
1017def datacenter_delete(args):
1018 #print "datacenter-delete",args
1019 todelete = _get_item_uuid("datacenters", args.name, "any")
1020 if not args.force:
1021 r = raw_input("Delete datacenter %s (y/N)? " %(args.name))
1022 if not (len(r)>0 and r[0].lower()=="y"):
1023 return 0
1024 URLrequest = "http://%s:%s/openmano/datacenters/%s" %(mano_host, mano_port, todelete)
1025 mano_response = requests.delete(URLrequest)
1026 logger.debug("openmano response: %s", mano_response.text )
1027 result = 0 if mano_response.status_code==200 else mano_response.status_code
1028 content = mano_response.json()
1029 #print json.dumps(content, indent=4)
1030 if mano_response.status_code == 200:
1031 print content['result']
1032 else:
1033 print content['error']['description']
1034 return result
1035
tierno20df3bb2017-07-07 14:31:00 +02001036
tierno7edb6752016-03-21 17:37:52 +01001037def datacenter_list(args):
1038 #print "datacenter-list",args
1039 tenant='any' if args.all else _get_tenant()
1040
1041 if args.name:
1042 toshow = _get_item_uuid("datacenters", args.name, tenant)
1043 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, toshow)
1044 else:
1045 URLrequest = "http://%s:%s/openmano/%s/datacenters" %(mano_host, mano_port, tenant)
1046 mano_response = requests.get(URLrequest)
1047 logger.debug("openmano response: %s", mano_response.text )
1048 if args.verbose==None:
1049 args.verbose=0
1050 if args.name!=None:
1051 args.verbose += 1
1052 return _print_verbose(mano_response, args.verbose)
1053
tierno20df3bb2017-07-07 14:31:00 +02001054
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001055def datacenter_sdn_port_mapping_set(args):
1056 tenant = _get_tenant()
1057 datacenter = _get_datacenter(args.name, tenant)
1058 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1059
1060 if not args.file:
1061 raise OpenmanoCLIError(
1062 "No yaml/json has been provided specifying the SDN port mapping")
tierno20df3bb2017-07-07 14:31:00 +02001063 sdn_port_mapping = _load_file_or_yaml(args.file)
1064 payload_req = json.dumps({"sdn_port_mapping": sdn_port_mapping})
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001065
tierno20df3bb2017-07-07 14:31:00 +02001066 # read
1067 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1068 mano_response = requests.get(URLrequest)
1069 logger.debug("openmano response: %s", mano_response.text)
1070 port_mapping = mano_response.json()
1071 if mano_response.status_code != 200:
1072 str(mano_response.json())
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001073 raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001074 if len(port_mapping["sdn_port_mapping"]["ports_mapping"]) > 0:
1075 if not args.force:
1076 r = raw_input("Datacenter %s already contains a port mapping. Overwrite? (y/N)? " % (datacenter))
1077 if not (len(r) > 0 and r[0].lower() == "y"):
1078 return 0
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001079
tierno20df3bb2017-07-07 14:31:00 +02001080 # clear
1081 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1082 mano_response = requests.delete(URLrequest)
1083 logger.debug("openmano response: %s", mano_response.text)
1084 if mano_response.status_code != 200:
1085 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001086
tierno20df3bb2017-07-07 14:31:00 +02001087 # set
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001088 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1089 logger.debug("openmano request: %s", payload_req)
1090 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1091 logger.debug("openmano response: %s", mano_response.text)
tierno20df3bb2017-07-07 14:31:00 +02001092 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001093
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001094
1095def datacenter_sdn_port_mapping_list(args):
1096 tenant = _get_tenant()
1097 datacenter = _get_datacenter(args.name, tenant)
1098
1099 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1100 mano_response = requests.get(URLrequest)
1101 logger.debug("openmano response: %s", mano_response.text)
1102
tierno20df3bb2017-07-07 14:31:00 +02001103 return _print_verbose(mano_response, 4)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001104
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001105
1106def datacenter_sdn_port_mapping_clear(args):
1107 tenant = _get_tenant()
1108 datacenter = _get_datacenter(args.name, tenant)
1109
1110 if not args.force:
1111 r = raw_input("Clean SDN port mapping for datacenter %s (y/N)? " %(datacenter))
tierno20df3bb2017-07-07 14:31:00 +02001112 if not (len(r) > 0 and r[0].lower() == "y"):
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001113 return 0
1114
1115 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1116 mano_response = requests.delete(URLrequest)
1117 logger.debug("openmano response: %s", mano_response.text)
1118
tierno20df3bb2017-07-07 14:31:00 +02001119 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001120
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001121
1122def sdn_controller_create(args):
1123 tenant = _get_tenant()
1124 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1125
tierno8fe7a492017-07-11 13:50:04 +02001126 error_msg=[]
1127 if not args.ip: error_msg.append("'ip'")
1128 if not args.port: error_msg.append("'port'")
1129 if not args.dpid: error_msg.append("'dpid'")
1130 if not args.type: error_msg.append("'type'")
1131 if error_msg:
1132 raise OpenmanoCLIError("The following arguments are required: " + ",".join(error_msg))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001133
1134 controller_dict = {}
1135 controller_dict['name'] = args.name
1136 controller_dict['ip'] = args.ip
1137 controller_dict['port'] = int(args.port)
1138 controller_dict['dpid'] = args.dpid
1139 controller_dict['type'] = args.type
1140 if args.description != None:
1141 controller_dict['description'] = args.description
1142 if args.user != None:
1143 controller_dict['user'] = args.user
1144 if args.password != None:
1145 controller_dict['password'] = args.password
1146
1147 payload_req = json.dumps({"sdn_controller": controller_dict})
1148
1149 # print payload_req
1150
1151 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" % (mano_host, mano_port, tenant)
1152 logger.debug("openmano request: %s", payload_req)
1153 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1154 logger.debug("openmano response: %s", mano_response.text)
1155 result = _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001156 return result
1157
tierno20df3bb2017-07-07 14:31:00 +02001158
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001159def sdn_controller_edit(args):
1160 tenant = _get_tenant()
1161 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1162 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1163
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001164 controller_dict = {}
tierno20df3bb2017-07-07 14:31:00 +02001165 if args.new_name:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001166 controller_dict['name'] = args.new_name
tierno20df3bb2017-07-07 14:31:00 +02001167 if args.ip:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001168 controller_dict['ip'] = args.ip
tierno20df3bb2017-07-07 14:31:00 +02001169 if args.port:
Pablo Montes Morenob12711f2017-04-06 11:54:34 +02001170 controller_dict['port'] = int(args.port)
tierno20df3bb2017-07-07 14:31:00 +02001171 if args.dpid:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001172 controller_dict['dpid'] = args.dpid
tierno20df3bb2017-07-07 14:31:00 +02001173 if args.type:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001174 controller_dict['type'] = args.type
tierno20df3bb2017-07-07 14:31:00 +02001175 if args.description:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001176 controller_dict['description'] = args.description
tierno20df3bb2017-07-07 14:31:00 +02001177 if args.user:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001178 controller_dict['user'] = args.user
tierno20df3bb2017-07-07 14:31:00 +02001179 if args.password:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001180 controller_dict['password'] = args.password
1181
tierno20df3bb2017-07-07 14:31:00 +02001182 if not controller_dict:
1183 raise OpenmanoCLIError("At least one parameter must be edited")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001184
tierno20df3bb2017-07-07 14:31:00 +02001185 if not args.force:
1186 r = raw_input("Update SDN controller {} (y/N)? ".format(args.name))
1187 if not (len(r) > 0 and r[0].lower() == "y"):
1188 return 0
1189
1190 payload_req = json.dumps({"sdn_controller": controller_dict})
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001191 # print payload_req
1192
1193 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" % (mano_host, mano_port, tenant, controller_uuid)
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 result = _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001198 return result
1199
tierno20df3bb2017-07-07 14:31:00 +02001200
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001201def sdn_controller_list(args):
1202 tenant = _get_tenant()
1203 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1204
1205 if args.name:
1206 toshow = _get_item_uuid("sdn_controllers", args.name, tenant)
1207 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" %(mano_host, mano_port, tenant, toshow)
1208 else:
1209 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" %(mano_host, mano_port, tenant)
1210 #print URLrequest
1211 mano_response = requests.get(URLrequest)
1212 logger.debug("openmano response: %s", mano_response.text )
1213 if args.verbose==None:
1214 args.verbose=0
1215 if args.name!=None:
1216 args.verbose += 1
1217
tierno20df3bb2017-07-07 14:31:00 +02001218 # json.dumps(mano_response.json(), indent=4)
1219 return _print_verbose(mano_response, args.verbose)
1220
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001221
1222def sdn_controller_delete(args):
1223 tenant = _get_tenant()
1224 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1225
1226 if not args.force:
1227 r = raw_input("Delete SDN controller %s (y/N)? " % (args.name))
1228 if not (len(r) > 0 and r[0].lower() == "y"):
1229 return 0
1230
1231 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" % (mano_host, mano_port, tenant, controller_uuid)
1232 mano_response = requests.delete(URLrequest)
1233 logger.debug("openmano response: %s", mano_response.text)
tierno20df3bb2017-07-07 14:31:00 +02001234 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001235
tierno7edb6752016-03-21 17:37:52 +01001236def vim_action(args):
1237 #print "datacenter-net-action",args
1238 tenant = _get_tenant()
1239 datacenter = _get_datacenter(args.datacenter, tenant)
1240 if args.verbose==None:
1241 args.verbose=0
1242 if args.action=="list":
1243 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
1244 if args.name!=None:
1245 args.verbose += 1
1246 URLrequest += "/" + args.name
1247 mano_response = requests.get(URLrequest)
1248 logger.debug("openmano response: %s", mano_response.text )
1249 return _print_verbose(mano_response, args.verbose)
1250 elif args.action=="delete":
1251 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss/%s" %(mano_host, mano_port, tenant, datacenter, args.item, args.name)
1252 mano_response = requests.delete(URLrequest)
1253 logger.debug("openmano response: %s", mano_response.text )
1254 result = 0 if mano_response.status_code==200 else mano_response.status_code
1255 content = mano_response.json()
1256 #print json.dumps(content, indent=4)
1257 if mano_response.status_code == 200:
1258 print content['result']
1259 else:
1260 print content['error']['description']
1261 return result
1262 elif args.action=="create":
1263 headers_req = {'content-type': 'application/yaml'}
1264 if args.file:
1265 create_dict = _load_file_or_yaml(args.file)
1266 if args.item not in create_dict:
1267 create_dict = {args.item: create_dict}
1268 else:
1269 create_dict = {args.item:{}}
1270 if args.name:
1271 create_dict[args.item]['name'] = args.name
1272 #if args.description:
1273 # create_dict[args.item]['description'] = args.description
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001274 if args.item=="network":
tierno7edb6752016-03-21 17:37:52 +01001275 if args.bind_net:
1276 create_dict[args.item]['bind_net'] = args.bind_net
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001277 if args.type:
1278 create_dict[args.item]['type'] = args.type
tierno7edb6752016-03-21 17:37:52 +01001279 if args.shared:
1280 create_dict[args.item]['shared'] = args.shared
1281 if "name" not in create_dict[args.item]:
1282 print "You must provide a name in the descriptor file or with the --name option"
1283 return
1284 payload_req = yaml.safe_dump(create_dict, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
1285 logger.debug("openmano request: %s", payload_req)
tierno72a08d72017-05-25 13:12:30 +02001286 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
tierno7edb6752016-03-21 17:37:52 +01001287 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
1288 logger.debug("openmano response: %s", mano_response.text )
1289 if args.verbose==None:
1290 args.verbose=0
1291 return _print_verbose(mano_response, args.verbose)
1292
tierno20df3bb2017-07-07 14:31:00 +02001293
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001294def _get_items(item, item_name_id=None, datacenter=None, tenant=None):
1295 URLrequest = "http://%s:%s/openmano" %(mano_host, mano_port)
1296 if tenant:
1297 URLrequest += "/" + tenant
1298 if datacenter:
1299 URLrequest += "/vim/" + datacenter
1300 if item:
1301 URLrequest += "/" + item +"s"
1302 if item_name_id:
1303 URLrequest += "/" + item_name_id
1304 mano_response = requests.get(URLrequest)
1305 logger.debug("openmano response: %s", mano_response.text )
1306
1307 return mano_response
1308
tierno20df3bb2017-07-07 14:31:00 +02001309
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001310def vim_net_sdn_attach(args):
1311 #Verify the network exists in the vim
1312 tenant = _get_tenant()
1313 datacenter = _get_datacenter(args.datacenter, tenant)
1314 result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
1315 content = yaml.load(result.content)
1316 if 'networks' in content:
1317 raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
1318 if 'error' in content:
1319 raise OpenmanoCLIError(yaml.safe_dump(content))
1320 network_uuid = content['network']['id']
1321
1322 #Make call to attach the dataplane port to the SND network associated to the vim network
1323 headers_req = {'content-type': 'application/yaml'}
1324 payload_req = {'port': args.port}
1325 if args.vlan:
1326 payload_req['vlan'] = int(args.vlan)
1327 if args.mac:
1328 payload_req['mac'] = args.mac
1329
1330 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/attach" % (mano_host, mano_port, tenant, datacenter, network_uuid)
1331 logger.debug("openmano request: %s", payload_req)
1332 mano_response = requests.post(URLrequest, headers=headers_req, data=json.dumps(payload_req))
1333 logger.debug("openmano response: %s", mano_response.text)
1334 result = _print_verbose(mano_response, args.verbose)
tierno20df3bb2017-07-07 14:31:00 +02001335 return result
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001336
1337
1338def vim_net_sdn_detach(args):
1339 if not args.all and not args.id:
1340 print "--all or --id must be used"
1341 return 1
1342
1343 # Verify the network exists in the vim
1344 tenant = _get_tenant()
1345 datacenter = _get_datacenter(args.datacenter, tenant)
1346 result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
1347 content = yaml.load(result.content)
1348 if 'networks' in content:
1349 raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
1350 if 'error' in content:
1351 raise OpenmanoCLIError(yaml.safe_dump(content))
1352 network_uuid = content['network']['id']
1353
1354 if not args.force:
1355 r = raw_input("Confirm action' (y/N)? ")
1356 if len(r) == 0 or r[0].lower() != "y":
1357 return 0
1358
1359 if args.id:
1360 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach/%s" % (
1361 mano_host, mano_port, tenant, datacenter, network_uuid, args.id)
1362 else:
1363 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach" % (
1364 mano_host, mano_port, tenant, datacenter, network_uuid)
1365 mano_response = requests.delete(URLrequest)
1366 logger.debug("openmano response: %s", mano_response.text)
1367 result = _print_verbose(mano_response, args.verbose)
tierno20df3bb2017-07-07 14:31:00 +02001368 return result
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001369
tierno7edb6752016-03-21 17:37:52 +01001370
1371def datacenter_net_action(args):
1372 if args.action == "net-update":
tierno5acf7202016-08-29 14:28:13 +02001373 print "This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano datacenter-netmap-import' instead!!!"
tierno7edb6752016-03-21 17:37:52 +01001374 print
1375 args.action = "netmap-delete"
1376 args.netmap = None
1377 args.all = True
1378 r = datacenter_netmap_action(args)
1379 if r == 0:
1380 args.force = True
tierno5acf7202016-08-29 14:28:13 +02001381 args.action = "netmap-import"
tierno7edb6752016-03-21 17:37:52 +01001382 r = datacenter_netmap_action(args)
1383 return r
1384
1385 if args.action == "net-edit":
1386 args.netmap = args.net
1387 args.name = None
1388 elif args.action == "net-list":
1389 args.netmap = None
1390 elif args.action == "net-delete":
1391 args.netmap = args.net
1392 args.all = False
1393
1394 args.action = "netmap" + args.action[3:]
1395 args.vim_name=None
1396 args.vim_id=None
1397 print "This command is deprecated, use 'openmano datacenter-%s' instead!!!" % args.action
1398 print
1399 return datacenter_netmap_action(args)
1400
1401def datacenter_netmap_action(args):
1402 tenant = _get_tenant()
1403 datacenter = _get_datacenter(args.datacenter, tenant)
1404 #print "datacenter_netmap_action",args
1405 payload_req = None
1406 if args.verbose==None:
1407 args.verbose=0
1408 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1409 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/netmaps" %(mano_host, mano_port, tenant, datacenter)
1410
1411 if args.action=="netmap-list":
1412 if args.netmap:
1413 URLrequest += "/" + args.netmap
1414 args.verbose += 1
1415 mano_response = requests.get(URLrequest)
1416
1417 elif args.action=="netmap-delete":
1418 if args.netmap and args.all:
1419 print "you can not use a netmap name and the option --all at the same time"
1420 return 1
1421 if args.netmap:
1422 force_text= "Delete default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter)
1423 URLrequest += "/" + args.netmap
1424 elif args.all:
1425 force_text="Delete all default netmaps from datacenter '%s' (y/N)? " % (datacenter)
1426 else:
tiernoae4a8d12016-07-08 12:30:39 +02001427 print "you must specify a netmap name or the option --all"
tierno7edb6752016-03-21 17:37:52 +01001428 return 1
1429 if not args.force:
1430 r = raw_input(force_text)
1431 if len(r)>0 and r[0].lower()=="y":
1432 pass
1433 else:
1434 return 0
1435 mano_response = requests.delete(URLrequest, headers=headers_req)
tierno5acf7202016-08-29 14:28:13 +02001436 elif args.action=="netmap-import":
tierno7edb6752016-03-21 17:37:52 +01001437 if not args.force:
1438 r = raw_input("Create all the available networks from datacenter '%s' as default netmaps (y/N)? " % (datacenter))
1439 if len(r)>0 and r[0].lower()=="y":
1440 pass
1441 else:
1442 return 0
1443 URLrequest += "/upload"
1444 mano_response = requests.post(URLrequest, headers=headers_req)
1445 elif args.action=="netmap-edit" or args.action=="netmap-create":
1446 if args.file:
1447 payload = _load_file_or_yaml(args.file)
1448 else:
1449 payload = {}
1450 if "netmap" not in payload:
1451 payload = {"netmap": payload}
1452 if args.name:
1453 payload["netmap"]["name"] = args.name
1454 if args.vim_id:
1455 payload["netmap"]["vim_id"] = args.vim_id
1456 if args.action=="netmap-create" and args.vim_name:
1457 payload["netmap"]["vim_name"] = args.vim_name
1458 payload_req = json.dumps(payload)
1459 logger.debug("openmano request: %s", payload_req)
1460
1461 if args.action=="netmap-edit" and not args.force:
1462 if len(payload["netmap"]) == 0:
1463 print "You must supply some parameter to edit"
1464 return 1
1465 r = raw_input("Edit default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter))
1466 if len(r)>0 and r[0].lower()=="y":
1467 pass
1468 else:
1469 return 0
1470 URLrequest += "/" + args.netmap
1471 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1472 else: #netmap-create
1473 if "vim_name" not in payload["netmap"] and "vim_id" not in payload["netmap"]:
1474 print "You must supply either --vim-id or --vim-name option; or include one of them in the file descriptor"
1475 return 1
1476 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1477
1478 logger.debug("openmano response: %s", mano_response.text )
1479 return _print_verbose(mano_response, args.verbose)
1480
tierno20df3bb2017-07-07 14:31:00 +02001481
tierno7edb6752016-03-21 17:37:52 +01001482def element_edit(args):
1483 element = _get_item_uuid(args.element, args.name)
1484 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1485 URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, args.element, element)
1486 payload=_load_file_or_yaml(args.file)
1487 if args.element[:-1] not in payload:
1488 payload = {args.element[:-1]: payload }
1489 payload_req = json.dumps(payload)
1490
1491 #print payload_req
1492 if not args.force or (args.name==None and args.filer==None):
1493 r = raw_input(" Edit " + args.element[:-1] + " " + args.name + " (y/N)? ")
1494 if len(r)>0 and r[0].lower()=="y":
1495 pass
1496 else:
1497 return 0
1498 logger.debug("openmano request: %s", payload_req)
1499 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1500 logger.debug("openmano response: %s", mano_response.text )
1501 if args.verbose==None:
1502 args.verbose=0
1503 if args.name!=None:
1504 args.verbose += 1
1505 return _print_verbose(mano_response, args.verbose)
1506
1507
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001508def datacenter_edit(args):
1509 tenant = _get_tenant()
1510 element = _get_item_uuid('datacenters', args.name, tenant)
1511 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1512 URLrequest = "http://%s:%s/openmano/datacenters/%s" % (mano_host, mano_port, element)
1513
1514 has_arguments = False
1515 if args.file != None:
1516 has_arguments = True
1517 payload = _load_file_or_yaml(args.file)
1518 else:
1519 payload = {}
1520
1521 if args.sdn_controller != None:
1522 has_arguments = True
1523 if not 'config' in payload:
1524 payload['config'] = {}
1525 if not 'sdn-controller' in payload['config']:
1526 payload['config']['sdn-controller'] = {}
1527 if args.sdn_controller == 'null':
1528 payload['config']['sdn-controller'] = None
1529 else:
1530 payload['config']['sdn-controller'] = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1531
1532 if not has_arguments:
1533 raise OpenmanoCLIError("At least one argument must be provided to modify the datacenter")
1534
1535 if 'datacenter' not in payload:
1536 payload = {'datacenter': payload}
1537 payload_req = json.dumps(payload)
1538
1539 # print payload_req
1540 if not args.force or (args.name == None and args.filer == None):
1541 r = raw_input(" Edit datacenter " + args.name + " (y/N)? ")
1542 if len(r) > 0 and r[0].lower() == "y":
1543 pass
1544 else:
1545 return 0
1546 logger.debug("openmano request: %s", payload_req)
1547 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1548 logger.debug("openmano response: %s", mano_response.text)
1549 if args.verbose == None:
1550 args.verbose = 0
1551 if args.name != None:
1552 args.verbose += 1
1553 return _print_verbose(mano_response, args.verbose)
1554
tierno20df3bb2017-07-07 14:31:00 +02001555
tierno6ddeded2017-05-16 15:40:26 +02001556def version(args):
1557 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1558 URLrequest = "http://%s:%s/openmano/version" % (mano_host, mano_port)
1559
1560 mano_response = requests.get(URLrequest, headers=headers_req)
1561 logger.debug("openmano response: %s", mano_response.text)
1562 print mano_response.text
1563
1564
tierno7edb6752016-03-21 17:37:52 +01001565global mano_host
1566global mano_port
1567global mano_tenant
1568
1569if __name__=="__main__":
1570
1571 mano_tenant = os.getenv('OPENMANO_TENANT', None)
1572 mano_host = os.getenv('OPENMANO_HOST',"localhost")
1573 mano_port = os.getenv('OPENMANO_PORT',"9090")
1574 mano_datacenter = os.getenv('OPENMANO_DATACENTER',None)
1575
1576 main_parser = ThrowingArgumentParser(description='User program to interact with OPENMANO-SERVER (openmanod)')
tierno6ddeded2017-05-16 15:40:26 +02001577 main_parser.add_argument('--version', action='version', help="get version of this client",
1578 version='%(prog)s client version ' + __version__ +
1579 " (Note: use '%(prog)s version' to get server version)")
1580
tierno7edb6752016-03-21 17:37:52 +01001581 subparsers = main_parser.add_subparsers(help='commands')
1582
tierno7edb6752016-03-21 17:37:52 +01001583 parent_parser = argparse.ArgumentParser(add_help=False)
1584 parent_parser.add_argument('--verbose', '-v', action='count', help="increase verbosity level. Use several times")
1585 parent_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
1586
garciadeblas0e9fd832016-07-08 15:20:18 +02001587 config_parser = subparsers.add_parser('config', parents=[parent_parser], help="prints configuration values")
1588 config_parser.add_argument("-n", action="store_true", help="resolves tenant and datacenter names")
1589 config_parser.set_defaults(func=config)
1590
tierno6ddeded2017-05-16 15:40:26 +02001591 version_parser = subparsers.add_parser('version', parents=[parent_parser], help="get server version")
1592 version_parser.set_defaults(func=version)
1593
tierno7edb6752016-03-21 17:37:52 +01001594 vnf_create_parser = subparsers.add_parser('vnf-create', parents=[parent_parser], help="adds a vnf into the catalogue")
1595 vnf_create_parser.add_argument("file", action="store", help="location of the JSON file describing the VNF").completer = FilesCompleter
1596 vnf_create_parser.add_argument("--name", action="store", help="name of the VNF (if it exists in the VNF descriptor, it is overwritten)")
1597 vnf_create_parser.add_argument("--description", action="store", help="description of the VNF (if it exists in the VNF descriptor, it is overwritten)")
1598 vnf_create_parser.add_argument("--image-path", action="store", help="change image path locations (overwritten)")
garciadeblas14480452017-01-10 13:08:07 +01001599 vnf_create_parser.add_argument("--image-name", action="store", help="change image name (overwritten)")
1600 vnf_create_parser.add_argument("--image-checksum", action="store", help="change image checksum (overwritten)")
tierno7edb6752016-03-21 17:37:52 +01001601 vnf_create_parser.set_defaults(func=vnf_create)
1602
1603 vnf_list_parser = subparsers.add_parser('vnf-list', parents=[parent_parser], help="lists information about a vnf")
1604 vnf_list_parser.add_argument("name", nargs='?', help="name of the VNF")
1605 vnf_list_parser.add_argument("-a", "--all", action="store_true", help="shows all vnfs, not only the owned or public ones")
1606 #vnf_list_parser.add_argument('--descriptor', help="prints the VNF descriptor", action="store_true")
1607 vnf_list_parser.set_defaults(func=vnf_list)
1608
1609 vnf_delete_parser = subparsers.add_parser('vnf-delete', parents=[parent_parser], help="deletes a vnf from the catalogue")
1610 vnf_delete_parser.add_argument("name", action="store", help="name or uuid of the VNF to be deleted")
1611 vnf_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1612 vnf_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
1613 vnf_delete_parser.set_defaults(func=vnf_delete)
1614
1615 scenario_create_parser = subparsers.add_parser('scenario-create', parents=[parent_parser], help="adds a scenario into the OPENMANO DB")
1616 scenario_create_parser.add_argument("file", action="store", help="location of the YAML file describing the scenario").completer = FilesCompleter
1617 scenario_create_parser.add_argument("--name", action="store", help="name of the scenario (if it exists in the YAML scenario, it is overwritten)")
1618 scenario_create_parser.add_argument("--description", action="store", help="description of the scenario (if it exists in the YAML scenario, it is overwritten)")
1619 scenario_create_parser.set_defaults(func=scenario_create)
1620
1621 scenario_list_parser = subparsers.add_parser('scenario-list', parents=[parent_parser], help="lists information about a scenario")
1622 scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario")
1623 #scenario_list_parser.add_argument('--descriptor', help="prints the scenario descriptor", action="store_true")
1624 scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all scenarios, not only the owned or public ones")
1625 scenario_list_parser.set_defaults(func=scenario_list)
1626
1627 scenario_delete_parser = subparsers.add_parser('scenario-delete', parents=[parent_parser], help="deletes a scenario from the OPENMANO DB")
1628 scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario to be deleted")
1629 scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1630 scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
1631 scenario_delete_parser.set_defaults(func=scenario_delete)
1632
1633 scenario_deploy_parser = subparsers.add_parser('scenario-deploy', parents=[parent_parser], help="deploys a scenario")
1634 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be deployed")
1635 scenario_deploy_parser.add_argument("name", action="store", help="name of the instance")
1636 scenario_deploy_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
1637 scenario_deploy_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
1638 scenario_deploy_parser.add_argument("--description", action="store", help="description of the instance")
1639 scenario_deploy_parser.set_defaults(func=scenario_deploy)
1640
1641 scenario_deploy_parser = subparsers.add_parser('scenario-verify', help="verifies if a scenario can be deployed (deploys it and deletes it)")
1642 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be verified")
1643 scenario_deploy_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
1644 scenario_deploy_parser.set_defaults(func=scenario_verify)
1645
1646 instance_scenario_create_parser = subparsers.add_parser('instance-scenario-create', parents=[parent_parser], help="deploys a scenario")
1647 instance_scenario_create_parser.add_argument("file", nargs='?', help="descriptor of the instance. Must be a file or yaml/json text")
1648 instance_scenario_create_parser.add_argument("--scenario", action="store", help="name or uuid of the scenario to be deployed")
1649 instance_scenario_create_parser.add_argument("--name", action="store", help="name of the instance")
1650 instance_scenario_create_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
1651 instance_scenario_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
1652 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")
1653 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 +02001654 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")
1655 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 +01001656 instance_scenario_create_parser.add_argument("--description", action="store", help="description of the instance")
1657 instance_scenario_create_parser.set_defaults(func=instance_create)
1658
1659 instance_scenario_list_parser = subparsers.add_parser('instance-scenario-list', parents=[parent_parser], help="lists information about a scenario instance")
1660 instance_scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario instance")
1661 instance_scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all instance-scenarios, not only the owned")
1662 instance_scenario_list_parser.set_defaults(func=instance_scenario_list)
1663
1664 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)")
1665 instance_scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario instance to be deleted")
1666 instance_scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1667 instance_scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
1668 instance_scenario_delete_parser.set_defaults(func=instance_scenario_delete)
1669
1670 instance_scenario_action_parser = subparsers.add_parser('instance-scenario-action', parents=[parent_parser], help="invoke an action over part or the whole scenario instance")
1671 instance_scenario_action_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
1672 instance_scenario_action_parser.add_argument("action", action="store", type=str, \
1673 choices=["start","pause","resume","shutoff","shutdown","forceOff","rebuild","reboot", "console"],\
1674 help="action to send")
1675 instance_scenario_action_parser.add_argument("param", nargs='?', help="addional param of the action. e.g. console type (novnc, ...), reboot type (TODO)")
1676 instance_scenario_action_parser.add_argument("--vnf", action="append", help="VNF to act on (can use several entries)")
1677 instance_scenario_action_parser.add_argument("--vm", action="append", help="VM to act on (can use several entries)")
1678 instance_scenario_action_parser.set_defaults(func=instance_scenario_action)
1679
1680 #instance_scenario_status_parser = subparsers.add_parser('instance-scenario-status', help="show the status of a scenario instance")
1681 #instance_scenario_status_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
1682 #instance_scenario_status_parser.set_defaults(func=instance_scenario_status)
1683
1684 tenant_create_parser = subparsers.add_parser('tenant-create', parents=[parent_parser], help="creates a new tenant")
1685 tenant_create_parser.add_argument("name", action="store", help="name for the tenant")
1686 tenant_create_parser.add_argument("--description", action="store", help="description of the tenant")
1687 tenant_create_parser.set_defaults(func=tenant_create)
1688
1689 tenant_delete_parser = subparsers.add_parser('tenant-delete', parents=[parent_parser], help="deletes a tenant from the catalogue")
1690 tenant_delete_parser.add_argument("name", action="store", help="name or uuid of the tenant to be deleted")
1691 tenant_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1692 tenant_delete_parser.set_defaults(func=tenant_delete)
1693
1694 tenant_list_parser = subparsers.add_parser('tenant-list', parents=[parent_parser], help="lists information about a tenant")
1695 tenant_list_parser.add_argument("name", nargs='?', help="name or uuid of the tenant")
1696 tenant_list_parser.set_defaults(func=tenant_list)
1697
tierno161c24b2017-05-16 15:45:56 +02001698 element_edit_parser = subparsers.add_parser('tenant-edit', parents=[parent_parser], help="edits one tenant")
1699 element_edit_parser.add_argument("name", help="name or uuid of the tenant")
1700 element_edit_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
1701 element_edit_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1702 element_edit_parser.set_defaults(func=element_edit, element='tenants')
tierno7edb6752016-03-21 17:37:52 +01001703
1704 datacenter_create_parser = subparsers.add_parser('datacenter-create', parents=[parent_parser], help="creates a new datacenter")
1705 datacenter_create_parser.add_argument("name", action="store", help="name for the datacenter")
1706 datacenter_create_parser.add_argument("url", action="store", help="url for the datacenter")
1707 datacenter_create_parser.add_argument("--url_admin", action="store", help="url for administration for the datacenter")
1708 datacenter_create_parser.add_argument("--type", action="store", help="datacenter type: openstack or openvim (default)")
1709 datacenter_create_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
1710 datacenter_create_parser.add_argument("--description", action="store", help="description of the datacenter")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001711 datacenter_create_parser.add_argument("--sdn-controller", action="store", help="Name or uuid of the SDN controller to be used", dest='sdn_controller')
tierno7edb6752016-03-21 17:37:52 +01001712 datacenter_create_parser.set_defaults(func=datacenter_create)
1713
1714 datacenter_delete_parser = subparsers.add_parser('datacenter-delete', parents=[parent_parser], help="deletes a datacenter from the catalogue")
1715 datacenter_delete_parser.add_argument("name", action="store", help="name or uuid of the datacenter to be deleted")
1716 datacenter_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1717 datacenter_delete_parser.set_defaults(func=datacenter_delete)
1718
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001719 datacenter_edit_parser = subparsers.add_parser('datacenter-edit', parents=[parent_parser], help="Edit datacenter")
1720 datacenter_edit_parser.add_argument("name", help="name or uuid of the datacenter")
1721 datacenter_edit_parser.add_argument("--file", help="json/yaml text or file with the changes").completer = FilesCompleter
1722 datacenter_edit_parser.add_argument("--sdn-controller", action="store",
1723 help="Name or uuid of the SDN controller to be used. Specify 'null' to clear entry", dest='sdn_controller')
1724 datacenter_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
1725 datacenter_edit_parser.set_defaults(func=datacenter_edit)
1726
tierno7edb6752016-03-21 17:37:52 +01001727 datacenter_list_parser = subparsers.add_parser('datacenter-list', parents=[parent_parser], help="lists information about a datacenter")
1728 datacenter_list_parser.add_argument("name", nargs='?', help="name or uuid of the datacenter")
1729 datacenter_list_parser.add_argument("-a", "--all", action="store_true", help="shows all datacenters, not only datacenters attached to tenant")
1730 datacenter_list_parser.set_defaults(func=datacenter_list)
1731
1732 datacenter_attach_parser = subparsers.add_parser('datacenter-attach', parents=[parent_parser], help="associates a datacenter to the operating tenant")
1733 datacenter_attach_parser.add_argument("name", help="name or uuid of the datacenter")
1734 datacenter_attach_parser.add_argument('--vim-tenant-id', action='store', help="specify a datacenter tenant to use. A new one is created by default")
1735 datacenter_attach_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
1736 datacenter_attach_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
1737 datacenter_attach_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
tierno8008c3a2016-10-13 15:34:28 +00001738 datacenter_attach_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
tierno7edb6752016-03-21 17:37:52 +01001739 datacenter_attach_parser.set_defaults(func=datacenter_attach)
1740
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001741 datacenter_edit_vim_tenant_parser = subparsers.add_parser('datacenter-edit-vim-tenant', parents=[parent_parser],
1742 help="Edit the association of a datacenter to the operating tenant")
1743 datacenter_edit_vim_tenant_parser.add_argument("name", help="name or uuid of the datacenter")
1744 datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-id', action='store',
1745 help="specify a datacenter tenant to use. A new one is created by default")
1746 datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
1747 datacenter_edit_vim_tenant_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
1748 datacenter_edit_vim_tenant_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
1749 datacenter_edit_vim_tenant_parser.add_argument("--config", action="store",
1750 help="aditional configuration in json/yaml format")
1751 datacenter_edit_vim_tenant_parser.set_defaults(func=datacenter_edit_vim_tenant)
1752
tierno7edb6752016-03-21 17:37:52 +01001753 datacenter_detach_parser = subparsers.add_parser('datacenter-detach', parents=[parent_parser], help="removes the association between a datacenter and the operating tenant")
1754 datacenter_detach_parser.add_argument("name", help="name or uuid of the datacenter")
1755 datacenter_detach_parser.add_argument("-a", "--all", action="store_true", help="removes all associations from this datacenter")
1756 datacenter_detach_parser.set_defaults(func=datacenter_detach)
1757
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001758 #=======================datacenter_sdn_port_mapping_xxx section=======================
1759 #datacenter_sdn_port_mapping_set
1760 datacenter_sdn_port_mapping_set_parser = subparsers.add_parser('datacenter-sdn-port-mapping-set',
1761 parents=[parent_parser],
1762 help="Load a file with the mapping of physical ports "
1763 "and the ports of the dataplaneswitch controlled "
1764 "by a datacenter")
1765 datacenter_sdn_port_mapping_set_parser.add_argument("name", action="store", help="specifies the datacenter")
1766 datacenter_sdn_port_mapping_set_parser.add_argument("file",
1767 help="json/yaml text or file with the port mapping").completer = FilesCompleter
1768 datacenter_sdn_port_mapping_set_parser.add_argument("-f", "--force", action="store_true",
1769 help="forces overwriting without asking")
1770 datacenter_sdn_port_mapping_set_parser.set_defaults(func=datacenter_sdn_port_mapping_set)
1771
1772 #datacenter_sdn_port_mapping_list
1773 datacenter_sdn_port_mapping_list_parser = subparsers.add_parser('datacenter-sdn-port-mapping-list',
1774 parents=[parent_parser],
1775 help="Show the SDN port mapping in a datacenter")
1776 datacenter_sdn_port_mapping_list_parser.add_argument("name", action="store", help="specifies the datacenter")
1777 datacenter_sdn_port_mapping_list_parser.set_defaults(func=datacenter_sdn_port_mapping_list)
1778
1779 # datacenter_sdn_port_mapping_clear
1780 datacenter_sdn_port_mapping_clear_parser = subparsers.add_parser('datacenter-sdn-port-mapping-clear',
1781 parents=[parent_parser],
1782 help="Clean the the SDN port mapping in a datacenter")
1783 datacenter_sdn_port_mapping_clear_parser.add_argument("name", action="store",
1784 help="specifies the datacenter")
1785 datacenter_sdn_port_mapping_clear_parser.add_argument("-f", "--force", action="store_true",
1786 help="forces clearing without asking")
1787 datacenter_sdn_port_mapping_clear_parser.set_defaults(func=datacenter_sdn_port_mapping_clear)
1788 # =======================
1789
1790 # =======================sdn_controller_xxx section=======================
1791 # sdn_controller_create
1792 sdn_controller_create_parser = subparsers.add_parser('sdn-controller-create', parents=[parent_parser],
1793 help="Creates an SDN controller entity within RO")
1794 sdn_controller_create_parser.add_argument("name", help="name of the SDN controller")
1795 sdn_controller_create_parser.add_argument("--description", action="store", help="description of the SDN controller")
1796 sdn_controller_create_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
1797 sdn_controller_create_parser.add_argument("--port", action="store", help="Port of the SDN controller")
1798 sdn_controller_create_parser.add_argument("--dpid", action="store",
1799 help="DPID of the dataplane switch controlled by this SDN controller")
1800 sdn_controller_create_parser.add_argument("--type", action="store",
1801 help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
1802 sdn_controller_create_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
1803 sdn_controller_create_parser.add_argument("--passwd", action="store", dest='password',
1804 help="password credentials for the SDN controller")
1805 sdn_controller_create_parser.set_defaults(func=sdn_controller_create)
1806
1807 # sdn_controller_edit
1808 sdn_controller_edit_parser = subparsers.add_parser('sdn-controller-edit', parents=[parent_parser],
1809 help="Update one or more options of a SDN controller")
1810 sdn_controller_edit_parser.add_argument("name", help="name or uuid of the SDN controller", )
1811 sdn_controller_edit_parser.add_argument("--name", action="store", help="Update the name of the SDN controller",
1812 dest='new_name')
1813 sdn_controller_edit_parser.add_argument("--description", action="store", help="description of the SDN controller")
1814 sdn_controller_edit_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
1815 sdn_controller_edit_parser.add_argument("--port", action="store", help="Port of the SDN controller")
1816 sdn_controller_edit_parser.add_argument("--dpid", action="store",
1817 help="DPID of the dataplane switch controlled by this SDN controller")
1818 sdn_controller_edit_parser.add_argument("--type", action="store",
1819 help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
1820 sdn_controller_edit_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
1821 sdn_controller_edit_parser.add_argument("--password", action="store",
1822 help="password credentials for the SDN controller", dest='password')
1823 sdn_controller_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
1824 #TODO: include option --file
1825 sdn_controller_edit_parser.set_defaults(func=sdn_controller_edit)
1826
1827 #sdn_controller_list
1828 sdn_controller_list_parser = subparsers.add_parser('sdn-controller-list',
1829 parents=[parent_parser],
1830 help="List the SDN controllers")
1831 sdn_controller_list_parser.add_argument("name", nargs='?', help="name or uuid of the SDN controller")
1832 sdn_controller_list_parser.set_defaults(func=sdn_controller_list)
1833
1834 # sdn_controller_delete
1835 sdn_controller_delete_parser = subparsers.add_parser('sdn-controller-delete',
1836 parents=[parent_parser],
1837 help="Delete the the SDN controller")
1838 sdn_controller_delete_parser.add_argument("name", help="name or uuid of the SDN controller")
1839 sdn_controller_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
1840 sdn_controller_delete_parser.set_defaults(func=sdn_controller_delete)
1841 # =======================
tierno7edb6752016-03-21 17:37:52 +01001842
1843 action_dict={'net-update': 'retrieves external networks from datacenter',
1844 'net-edit': 'edits an external network',
1845 'net-delete': 'deletes an external network',
1846 'net-list': 'lists external networks from a datacenter'
1847 }
1848 for item in action_dict:
1849 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
1850 datacenter_action_parser.add_argument("datacenter", help="name or uuid of the datacenter")
1851 if item=='net-edit' or item=='net-delete':
1852 datacenter_action_parser.add_argument("net", help="name or uuid of the datacenter net")
1853 if item=='net-edit':
1854 datacenter_action_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
1855 if item!='net-list':
1856 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1857 datacenter_action_parser.set_defaults(func=datacenter_net_action, action=item)
1858
1859
tierno5acf7202016-08-29 14:28:13 +02001860 action_dict={'netmap-import': 'create network senario netmap base on the datacenter networks',
tierno7edb6752016-03-21 17:37:52 +01001861 'netmap-create': 'create a new network senario netmap',
1862 'netmap-edit': 'edit name of a network senario netmap',
1863 'netmap-delete': 'deletes a network scenario netmap (--all for clearing all)',
1864 'netmap-list': 'list/show network scenario netmaps'
1865 }
1866 for item in action_dict:
1867 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
1868 datacenter_action_parser.add_argument("--datacenter", help="name or uuid of the datacenter")
1869 #if item=='net-add':
1870 # datacenter_action_parser.add_argument("net", help="name of the network")
1871 if item=='netmap-delete':
1872 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to delete")
1873 datacenter_action_parser.add_argument("--all", action="store_true", help="delete all netmap of this datacenter")
1874 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1875 if item=='netmap-edit':
1876 datacenter_action_parser.add_argument("netmap", help="name or uuid of the datacenter netmap do edit")
1877 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file with the changes").completer = FilesCompleter
1878 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap")
1879 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
1880 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1881 if item=='netmap-list':
1882 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to show")
1883 if item=='netmap-create':
1884 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file descriptor with the changes").completer = FilesCompleter
1885 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap, by default same as vim-name")
1886 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
1887 datacenter_action_parser.add_argument('--vim-name', action='store', help="specify vim network name")
tierno5acf7202016-08-29 14:28:13 +02001888 if item=='netmap-import':
tierno7edb6752016-03-21 17:37:52 +01001889 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
1890 datacenter_action_parser.set_defaults(func=datacenter_netmap_action, action=item)
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001891
1892 # =======================vim_net_sdn_xxx section=======================
1893 # vim_net_sdn_attach
1894 vim_net_sdn_attach_parser = subparsers.add_parser('vim-net-sdn-attach',
1895 parents=[parent_parser],
1896 help="Specify the port to access to an external network using SDN")
1897 vim_net_sdn_attach_parser.add_argument("vim_net", action="store",
1898 help="Name/id of the network in the vim that will be used to connect to the external network")
1899 vim_net_sdn_attach_parser.add_argument("port", action="store", help="Specifies the port in the dataplane switch to access to the external network")
1900 vim_net_sdn_attach_parser.add_argument("--vlan", action="store", help="Specifies the vlan (if any) to use in the defined port")
1901 vim_net_sdn_attach_parser.add_argument("--mac", action="store", help="Specifies the MAC (if known) of the physical device that will be reachable by this external port")
1902 vim_net_sdn_attach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
1903 vim_net_sdn_attach_parser.set_defaults(func=vim_net_sdn_attach)
1904
1905 # vim_net_sdn_detach
1906 vim_net_sdn_detach_parser = subparsers.add_parser('vim-net-sdn-detach',
1907 parents=[parent_parser],
1908 help="Remove the port information to access to an external network using SDN")
1909
1910 vim_net_sdn_detach_parser.add_argument("vim_net", action="store", help="Name/id of the vim network")
1911 vim_net_sdn_detach_parser.add_argument("--id", action="store",help="Specify the uuid of the external ports from this network to be detached")
1912 vim_net_sdn_detach_parser.add_argument("--all", action="store_true", help="Detach all external ports from this network")
1913 vim_net_sdn_detach_parser.add_argument("-f", "--force", action="store_true", help="forces clearing without asking")
1914 vim_net_sdn_detach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
1915 vim_net_sdn_detach_parser.set_defaults(func=vim_net_sdn_detach)
1916 # =======================
1917
tierno4540ea52017-01-18 17:44:32 +01001918 for item in ("network", "tenant", "image"):
tierno7edb6752016-03-21 17:37:52 +01001919 if item=="network":
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001920 command_name = 'vim-net'
tierno7edb6752016-03-21 17:37:52 +01001921 else:
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001922 command_name = 'vim-'+item
1923 vim_item_list_parser = subparsers.add_parser(command_name + '-list', parents=[parent_parser], help="list the vim " + item + "s")
tierno7edb6752016-03-21 17:37:52 +01001924 vim_item_list_parser.add_argument("name", nargs='?', help="name or uuid of the " + item + "s")
1925 vim_item_list_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
1926 vim_item_list_parser.set_defaults(func=vim_action, item=item, action="list")
1927
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001928 vim_item_del_parser = subparsers.add_parser(command_name + '-delete', parents=[parent_parser], help="list the vim " + item + "s")
tierno7edb6752016-03-21 17:37:52 +01001929 vim_item_del_parser.add_argument("name", help="name or uuid of the " + item + "s")
1930 vim_item_del_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
1931 vim_item_del_parser.set_defaults(func=vim_action, item=item, action="delete")
1932
tierno4540ea52017-01-18 17:44:32 +01001933 if item == "network" or item == "tenant":
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001934 vim_item_create_parser = subparsers.add_parser(command_name + '-create', parents=[parent_parser], help="create a "+item+" at vim")
tierno4540ea52017-01-18 17:44:32 +01001935 vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the %s. Must be a file or yaml/json text" % item).completer = FilesCompleter
1936 vim_item_create_parser.add_argument("--name", action="store", help="name of the %s" % item )
1937 vim_item_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
1938 if item=="network":
1939 vim_item_create_parser.add_argument("--type", action="store", help="type of network, data, ptp, bridge")
1940 vim_item_create_parser.add_argument("--shared", action="store_true", help="Private or shared")
1941 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>'")
1942 else:
1943 vim_item_create_parser.add_argument("--description", action="store", help="description of the %s" % item)
1944 vim_item_create_parser.set_defaults(func=vim_action, item=item, action="create")
tierno7edb6752016-03-21 17:37:52 +01001945
1946 argcomplete.autocomplete(main_parser)
1947
1948 try:
1949 args = main_parser.parse_args()
1950 #logging info
1951 level = logging.CRITICAL
1952 streamformat = "%(asctime)s %(name)s %(levelname)s: %(message)s"
1953 if "debug" in args and args.debug:
1954 level = logging.DEBUG
1955 logging.basicConfig(format=streamformat, level= level)
1956 logger = logging.getLogger('mano')
1957 logger.setLevel(level)
1958 result = args.func(args)
1959 if result == None:
1960 result = 0
1961 #for some reason it fails if call exit inside try instance. Need to call exit at the end !?
1962 except (requests.exceptions.ConnectionError):
1963 print "Connection error: not possible to contact OPENMANO-SERVER (openmanod)"
1964 result = -2
1965 except (KeyboardInterrupt):
1966 print 'Exiting openmano'
1967 result = -3
1968 except (SystemExit, ArgumentParserError):
1969 result = -4
1970 except OpenmanoCLIError as e:
1971 print str(e)
1972 result = -5
1973
1974 #print result
1975 exit(result)
1976