2 # -*- coding: utf-8 -*-
3 # PYTHON_ARGCOMPLETE_OK
6 # Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
7 # This file is part of openmano
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
14 # http://www.apache.org/licenses/LICENSE-2.0
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
22 # For those usages not covered by the Apache License, Version 2.0 please
23 # contact with: nfvlabs@tid.es
27 openmano client used to interact with openmano-server (openmanod)
29 __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
30 __date__ = "$09-oct-2014 09:09:48$"
31 __version__ = "0.4.24-r534"
32 version_date = "Nov 2018"
34 from argcomplete.completers import FilesCompleter
42 #from jsonschema import validate as js_v, exceptions as js_e
44 class ArgumentParserError(Exception): pass
46 class OpenmanoCLIError(Exception): pass
48 class ThrowingArgumentParser(argparse.ArgumentParser):
49 def error(self, message):
50 print "Error: %s" %message
55 print "Type 'openmano -h' for help"
56 raise ArgumentParserError
60 print "OPENMANO_HOST: %s" %mano_host
61 print "OPENMANO_PORT: %s" %mano_port
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"
69 logger.debug("resolving WIM names")
71 mano_wim_name = "None"
73 mano_tenant_id = _get_item_uuid("tenants", mano_tenant)
74 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, mano_tenant_id)
75 mano_response = requests.get(URLrequest)
76 logger.debug("openmano response: %s", mano_response.text )
77 content = mano_response.json()
78 mano_tenant_name = content["tenant"]["name"]
79 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, mano_tenant_id, mano_datacenter)
80 mano_response = requests.get(URLrequest)
81 logger.debug("openmano response: %s", mano_response.text )
82 content = mano_response.json()
83 if "error" not in content:
84 mano_datacenter_id = content["datacenter"]["uuid"]
85 mano_datacenter_name = content["datacenter"]["name"]
88 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (
89 mano_host, mano_port, mano_tenant_id, mano_wim)
90 mano_response = requests.get(URLrequest)
91 logger.debug("openmano response: %s", mano_response.text)
92 content = mano_response.json()
93 if "error" not in content:
94 mano_wim_id = content["wim"]["uuid"]
95 mano_wim_name = content["wim"]["name"]
97 except OpenmanoCLIError:
99 print "OPENMANO_TENANT: %s" %mano_tenant
100 print " Id: %s" %mano_tenant_id
101 print " Name: %s" %mano_tenant_name
102 print "OPENMANO_DATACENTER: %s" %str (mano_datacenter)
103 print " Id: %s" %mano_datacenter_id
104 print " Name: %s" %mano_datacenter_name
106 print "OPENMANO_WIM: %s" %str (mano_wim)
107 print " Id: %s" %mano_wim_id
108 print " Name: %s" %mano_wim_name
111 print "OPENMANO_TENANT: %s" %mano_tenant
112 print "OPENMANO_DATACENTER: %s" %str (mano_datacenter)
114 print "OPENMANO_WIM: %s" %str (mano_wim)
116 def _print_verbose(mano_response, verbose_level=0):
117 content = mano_response.json()
118 result = 0 if mano_response.status_code==200 else mano_response.status_code
119 if type(content)!=dict or len(content)!=1:
120 #print "Non expected format output"
124 val=content.values()[0]
128 elif type(val) == list:
130 elif type(val)==dict:
133 #print "Non expected dict/list format output"
138 if verbose_level==None:
140 if verbose_level >= 3:
141 print yaml.safe_dump(content, indent=4, default_flow_style=False)
144 if mano_response.status_code == 200:
146 for content in content_list:
147 if "uuid" in content:
148 uuid = content['uuid']
149 elif "id" in content:
151 elif "vim_id" in content:
152 uuid = content['vim_id']
153 name = content.get('name');
158 myoutput = "{:38} {:20}".format(uuid, name)
159 if content.get("status"):
160 myoutput += " {:20}".format(content['status'])
161 elif "enabled" in content and not content["enabled"]:
162 myoutput += " enabled=False".ljust(20)
163 if verbose_level >=1:
164 if content.get('created_at'):
165 myoutput += " {:20}".format(content['created_at'])
166 if content.get('sdn_attached_ports'):
167 #myoutput += " " + str(content['sdn_attached_ports']).ljust(20)
168 myoutput += "\nsdn_attached_ports:\n" + yaml.safe_dump(content['sdn_attached_ports'], indent=4, default_flow_style=False)
169 if verbose_level >=2:
171 if content.get('type'):
172 myoutput += new_line + " Type: {:29}".format(content['type'])
174 if content.get('description'):
175 myoutput += new_line + " Description: {:20}".format(content['description'])
178 print content['error']['description']
181 def parser_json_yaml(file_name):
183 f = file(file_name, "r")
186 except Exception as e:
187 return (False, str(e))
190 if file_name[-5:]=='.yaml' or file_name[-4:]=='.yml' or (file_name[-5:]!='.json' and '\t' not in text):
192 config = yaml.load(text)
193 except yaml.YAMLError as exc:
195 if hasattr(exc, 'problem_mark'):
196 mark = exc.problem_mark
197 error_pos = " at line:%s column:%s" % (mark.line+1, mark.column+1)
198 return (False, "Error loading file '"+file_name+"' yaml format error" + error_pos)
201 config = json.loads(text)
202 except Exception as e:
203 return (False, "Error loading file '"+file_name+"' json format error " + str(e) )
207 def _load_file_or_yaml(content):
209 'content' can be or a yaml/json file or a text containing a yaml/json text format
210 This function autodetect, trying to load and parse the file,
211 if fails trying to parse the 'content' text
212 Returns the dictionary once parsed, or print an error and finish the program
214 #Check config file exists
215 if os.path.isfile(content):
216 r,payload = parser_json_yaml(content)
220 elif "{" in content or ":" in content:
222 payload = yaml.load(content)
223 except yaml.YAMLError as exc:
225 if hasattr(exc, 'problem_mark'):
226 mark = exc.problem_mark
227 error_pos = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
228 print "Error loading yaml/json text"+error_pos
231 print "'%s' is neither a valid file nor a yaml/json content" % content
235 def _get_item_uuid(item, item_name_id, tenant=None):
237 URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, tenant, item)
239 URLrequest = "http://%s:%s/openmano/%s" %(mano_host, mano_port, item)
240 mano_response = requests.get(URLrequest)
241 logger.debug("openmano response: %s", mano_response.text )
242 content = mano_response.json()
245 for i in content[item]:
246 if i["uuid"] == item_name_id:
248 if i["name"] == item_name_id:
251 if item_name_id.startswith("osm_id=") and i.get("osm_id") == item_name_id[7:]:
255 raise OpenmanoCLIError("No %s found with name/uuid '%s'" %(item[:-1], item_name_id))
257 raise OpenmanoCLIError("%d %s found with name '%s'. uuid must be used" %(found, item, item_name_id))
260 # def check_valid_uuid(uuid):
261 # id_schema = {"type" : "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
263 # js_v(uuid, id_schema)
265 # except js_e.ValidationError:
268 def _get_tenant(tenant_name_id = None):
269 if not tenant_name_id:
270 tenant_name_id = mano_tenant
272 raise OpenmanoCLIError("'OPENMANO_TENANT' environment variable is not set")
273 return _get_item_uuid("tenants", tenant_name_id)
275 def _get_datacenter(datacenter_name_id = None, tenant = "any"):
276 if not datacenter_name_id:
277 datacenter_name_id = mano_datacenter
278 if not datacenter_name_id:
279 raise OpenmanoCLIError("neither 'OPENMANO_DATACENTER' environment variable is set nor --datacenter option is used")
280 return _get_item_uuid("datacenters", datacenter_name_id, tenant)
283 def _get_wim(wim_name_id = None, tenant = "any"):
285 wim_name_id = mano_wim
287 raise OpenmanoCLIError("neither 'OPENMANO_WIM' environment variable is set nor --wim option is used")
288 return _get_item_uuid("wims", wim_name_id, tenant)
290 def vnf_create(args):
291 #print "vnf-create",args
292 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
293 tenant = _get_tenant()
294 myvnf = _load_file_or_yaml(args.file)
296 if "vnfd:vnfd-catalog" in myvnf or "vnfd-catalog" in myvnf:
299 vnfd_catalog = myvnf.get("vnfd:vnfd-catalog")
301 vnfd_catalog = myvnf.get("vnfd-catalog")
302 vnfds = vnfd_catalog.get("vnfd:vnfd")
304 vnfds = vnfd_catalog.get("vnfd")
306 vdu_list = vnfd.get("vdu")
312 vdu_list = vnfd.get("VNFC")
314 if args.name or args.description or args.image_path or args.image_name or args.image_checksum:
315 # TODO, change this for API v3
319 vnfd['name'] = args.name
321 vnfd['description'] = args.description
325 for image_path_ in args.image_path.split(","):
326 # print "image-path", image_path_
327 if api_version == "/v3":
328 if vdu_list[index].get("image"):
329 vdu_list[index]['image'] = image_path_
330 if "image-checksum" in vdu_list[index]:
331 del vdu_list[index]["image-checksum"]
332 else: # image name in volumes
333 vdu_list[index]["volumes"][0]["image"] = image_path_
334 if "image-checksum" in vdu_list[index]["volumes"][0]:
335 del vdu_list[index]["volumes"][0]["image-checksum"]
337 vdu_list[index]['VNFC image'] = image_path_
338 if "image name" in vdu_list[index]:
339 del vdu_list[index]["image name"]
340 if "image checksum" in vdu_list[index]:
341 del vdu_list[index]["image checksum"]
343 if args.image_name: # image name precedes if both are supplied
345 for image_name_ in args.image_name.split(","):
346 if api_version == "/v3":
347 if vdu_list[index].get("image"):
348 vdu_list[index]['image'] = image_name_
349 if "image-checksum" in vdu_list[index]:
350 del vdu_list[index]["image-checksum"]
351 if vdu_list[index].get("alternative-images"):
352 for a_image in vdu_list[index]["alternative-images"]:
353 a_image['image'] = image_name_
354 if "image-checksum" in a_image:
355 del a_image["image-checksum"]
356 else: # image name in volumes
357 vdu_list[index]["volumes"][0]["image"] = image_name_
358 if "image-checksum" in vdu_list[index]["volumes"][0]:
359 del vdu_list[index]["volumes"][0]["image-checksum"]
361 vdu_list[index]['image name'] = image_name_
362 if "VNFC image" in vdu_list[index]:
363 del vdu_list[index]["VNFC image"]
365 if args.image_checksum:
367 for image_checksum_ in args.image_checksum.split(","):
368 if api_version == "/v3":
369 if vdu_list[index].get("image"):
370 vdu_list[index]['image-checksum'] = image_checksum_
371 if vdu_list[index].get("alternative-images"):
372 for a_image in vdu_list[index]["alternative-images"]:
373 a_image['image-checksum'] = image_checksum_
374 else: # image name in volumes
375 vdu_list[index]["volumes"][0]["image-checksum"] = image_checksum_
377 vdu_list[index]['image checksum'] = image_checksum_
379 except (KeyError, TypeError), e:
380 if str(e) == 'vnf': error_pos= "missing field 'vnf'"
381 elif str(e) == 'name': error_pos= "missing field 'vnf':'name'"
382 elif str(e) == 'description': error_pos= "missing field 'vnf':'description'"
383 elif str(e) == 'VNFC': error_pos= "missing field 'vnf':'VNFC'"
384 elif str(e) == str(index): error_pos= "field 'vnf':'VNFC' must be an array"
385 elif str(e) == 'VNFC image': error_pos= "missing field 'vnf':'VNFC'['VNFC image']"
386 elif str(e) == 'image name': error_pos= "missing field 'vnf':'VNFC'['image name']"
387 elif str(e) == 'image checksum': error_pos= "missing field 'vnf':'VNFC'['image checksum']"
388 else: error_pos="wrong format"
389 print "Wrong VNF descriptor: " + error_pos
391 payload_req = json.dumps(myvnf)
395 URLrequest = "http://{}:{}/openmano{}/{}/{token}".format(mano_host, mano_port, api_version, tenant, token=token)
396 logger.debug("openmano request: %s", payload_req)
397 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
398 logger.debug("openmano response: %s", mano_response.text )
400 return _print_verbose(mano_response, args.verbose)
403 #print "vnf-list",args
407 tenant = _get_tenant()
409 toshow = _get_item_uuid("vnfs", args.name, tenant)
410 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, toshow)
412 URLrequest = "http://%s:%s/openmano/%s/vnfs" %(mano_host, mano_port, tenant)
413 mano_response = requests.get(URLrequest)
414 logger.debug("openmano response: %s", mano_response.text )
415 content = mano_response.json()
416 # print json.dumps(content, indent=4)
417 if args.verbose==None:
419 result = 0 if mano_response.status_code==200 else mano_response.status_code
420 if mano_response.status_code == 200:
422 if args.verbose >= 3:
423 print yaml.safe_dump(content, indent=4, default_flow_style=False)
425 if len(content['vnfs']) == 0:
426 print "No VNFs were found."
427 return 404 # HTTP_Not_Found
428 for vnf in content['vnfs']:
429 myoutput = "{:38} {:20}".format(vnf['uuid'], vnf['name'])
430 if vnf.get('osm_id') or args.verbose >= 1:
431 myoutput += " osm_id={:20}".format(vnf.get('osm_id'))
432 if args.verbose >= 1:
433 myoutput += " {}".format(vnf['created_at'])
435 if args.verbose >= 2:
436 print (" Description: {}".format(vnf['description']))
437 # print (" VNF descriptor file: {}".format(vnf['path']))
440 print yaml.safe_dump(content, indent=4, default_flow_style=False)
443 print ("{:38} {:20} osm_id={:20} {:20}".format(vnf['uuid'], vnf['name'], vnf.get('osm_id'),
445 print (" Description: {}".format(vnf['description']))
446 # print " VNF descriptor file: %s" %vnf['path']
448 for vm in vnf['VNFC']:
449 print (" {:20} osm_id={:20} {}".format(vm['name'], vm.get('osm_id'), vm['description']))
450 if len(vnf['nets']) > 0:
451 print (" Internal nets:")
452 for net in vnf['nets']:
453 print (" {:20} {}".format(net['name'], net['description']))
454 if len(vnf['external-connections']) > 0:
455 print (" External interfaces:")
456 for interface in vnf['external-connections']:
457 print (" {:20} {:20} {:20} {:14}".format(
458 interface['external_name'], interface['vm_name'],
459 interface['internal_name'],
460 interface.get('vpci') if interface.get('vpci') else ""))
462 print content['error']['description']
464 print yaml.safe_dump(content, indent=4, default_flow_style=False)
467 def vnf_delete(args):
468 #print "vnf-delete",args
472 tenant = _get_tenant()
473 todelete = _get_item_uuid("vnfs", args.name, tenant=tenant)
475 r = raw_input("Delete VNF %s (y/N)? " %(todelete))
476 if not (len(r)>0 and r[0].lower()=="y"):
478 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, todelete)
479 mano_response = requests.delete(URLrequest)
480 logger.debug("openmano response: %s", mano_response.text )
481 result = 0 if mano_response.status_code==200 else mano_response.status_code
482 content = mano_response.json()
483 #print json.dumps(content, indent=4)
484 if mano_response.status_code == 200:
485 print content['result']
487 print content['error']['description']
490 def scenario_create(args):
491 # print "scenario-create",args
492 tenant = _get_tenant()
493 headers_req = {'content-type': 'application/yaml'}
494 myscenario = _load_file_or_yaml(args.file)
495 if "nsd:nsd-catalog" in myscenario or "nsd-catalog" in myscenario:
498 nsd_catalog = myscenario.get("nsd:nsd-catalog")
500 nsd_catalog = myscenario.get("nsd-catalog")
501 nsds = nsd_catalog.get("nsd:nsd")
503 nsds = nsd_catalog.get("nsd")
508 if "scenario" in myscenario:
509 nsd = myscenario["scenario"]
512 # TODO modify for API v3
514 nsd['name'] = args.name
516 nsd['description'] = args.description
517 payload_req = yaml.safe_dump(myscenario, explicit_start=True, indent=4, default_flow_style=False, tags=False,
518 encoding='utf-8', allow_unicode=True)
521 URLrequest = "http://{host}:{port}/openmano{api}/{tenant}/{token}".format(
522 host=mano_host, port=mano_port, api=api_version, tenant=tenant, token=token)
523 logger.debug("openmano request: %s", payload_req)
524 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
525 logger.debug("openmano response: %s", mano_response.text )
526 return _print_verbose(mano_response, args.verbose)
528 def scenario_list(args):
529 #print "scenario-list",args
533 tenant = _get_tenant()
535 toshow = _get_item_uuid("scenarios", args.name, tenant)
536 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, toshow)
538 URLrequest = "http://%s:%s/openmano/%s/scenarios" %(mano_host, mano_port, tenant)
539 mano_response = requests.get(URLrequest)
540 logger.debug("openmano response: %s", mano_response.text )
541 content = mano_response.json()
542 #print json.dumps(content, indent=4)
543 if args.verbose==None:
546 result = 0 if mano_response.status_code==200 else mano_response.status_code
547 if mano_response.status_code == 200:
549 if args.verbose >= 3:
550 print yaml.safe_dump(content, indent=4, default_flow_style=False)
552 if len(content['scenarios']) == 0:
553 print "No scenarios were found."
554 return 404 #HTTP_Not_Found
555 for scenario in content['scenarios']:
556 myoutput = "{:38} {:20}".format(scenario['uuid'], scenario['name'])
557 if scenario.get('osm_id') or args.verbose >= 1:
558 myoutput += " osm_id={:20}".format(scenario.get('osm_id'))
559 if args.verbose >= 1:
560 myoutput += " {}".format(scenario['created_at'])
563 print (" Description: {}".format(scenario['description']))
566 print yaml.safe_dump(content, indent=4, default_flow_style=False)
568 scenario = content['scenario']
569 print ("{:38} {:20} osm_id={:20} {:20}".format(scenario['uuid'], scenario['name'], scenario.get('osm_id'),
570 scenario['created_at']))
571 print (" Description: {}".format(scenario['description']))
573 for vnf in scenario['vnfs']:
574 print (" {:38} {:20} vnf_index={} {}".format(vnf['vnf_id'], vnf['name'], vnf.get("member_vnf_index"),
576 if len(scenario['nets']) > 0:
578 for net in scenario['nets']:
579 description = net['description']
580 if not description: # if description does not exist, description is "-". Valid for external and internal nets.
583 if net.get('vim_id'):
584 vim_id = " vim_id=" + net["vim_id"]
587 external = " external"
588 print (" {:20} {:38} {:30}{}{}".format(net['name'], net['uuid'], description, vim_id, external))
590 print (content['error']['description'])
592 print yaml.safe_dump(content, indent=4, default_flow_style=False)
595 def scenario_delete(args):
596 #print "scenario-delete",args
600 tenant = _get_tenant()
601 todelete = _get_item_uuid("scenarios", args.name, tenant=tenant)
603 r = raw_input("Delete scenario %s (y/N)? " %(args.name))
604 if not (len(r)>0 and r[0].lower()=="y"):
606 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, todelete)
607 mano_response = requests.delete(URLrequest)
608 logger.debug("openmano response: %s", mano_response.text )
609 result = 0 if mano_response.status_code==200 else mano_response.status_code
610 content = mano_response.json()
611 #print json.dumps(content, indent=4)
612 if mano_response.status_code == 200:
613 print content['result']
615 print content['error']['description']
618 def scenario_deploy(args):
619 print "This command is deprecated, use 'openmano instance-scenario-create --scenario %s --name %s' instead!!!" % (args.scenario, args.name)
622 args.netmap_use = None
623 args.netmap_create = None
625 args.keypair_auto = None
626 return instance_create(args)
628 # #print "scenario-deploy",args
629 # headers_req = {'content-type': 'application/json'}
633 # actionCmd="reserve"
634 # action[actionCmd] = {}
635 # action[actionCmd]["instance_name"] = args.name
636 # if args.datacenter != None:
637 # action[actionCmd]["datacenter"] = args.datacenter
638 # elif mano_datacenter != None:
639 # action[actionCmd]["datacenter"] = mano_datacenter
641 # if args.description:
642 # action[actionCmd]["description"] = args.description
643 # payload_req = json.dumps(action, indent=4)
646 # URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, mano_tenant, args.scenario)
647 # logger.debug("openmano request: %s", payload_req)
648 # mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
649 # logger.debug("openmano response: %s", mano_response.text )
650 # if args.verbose==None:
653 # result = 0 if mano_response.status_code==200 else mano_response.status_code
654 # content = mano_response.json()
655 # #print json.dumps(content, indent=4)
656 # if args.verbose >= 3:
657 # print yaml.safe_dump(content, indent=4, default_flow_style=False)
660 # if mano_response.status_code == 200:
661 # myoutput = "%s %s" %(content['uuid'].ljust(38),content['name'].ljust(20))
662 # if args.verbose >=1:
663 # myoutput = "%s %s" %(myoutput, content['created_at'].ljust(20))
664 # if args.verbose >=2:
665 # myoutput = "%s %s %s" %(myoutput, content['description'].ljust(30))
668 # print "To check the status, run the following command:"
669 # print "openmano instance-scenario-list <instance_id>"
671 # print content['error']['description']
674 def scenario_verify(args):
675 #print "scenario-verify",args
676 tenant = _get_tenant()
677 headers_req = {'content-type': 'application/json'}
679 action["verify"] = {}
680 action["verify"]["instance_name"] = "scen-verify-return5"
681 payload_req = json.dumps(action, indent=4)
684 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, tenant, args.scenario)
685 logger.debug("openmano request: %s", payload_req)
686 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
687 logger.debug("openmano response: %s", mano_response.text )
689 result = 0 if mano_response.status_code==200 else mano_response.status_code
690 content = mano_response.json()
691 #print json.dumps(content, indent=4)
692 if mano_response.status_code == 200:
693 print content['result']
695 print content['error']['description']
698 def instance_create(args):
699 tenant = _get_tenant()
700 headers_req = {'content-type': 'application/yaml'}
701 myInstance={"instance": {}, "schema_version": "0.1"}
703 instance_dict = _load_file_or_yaml(args.file)
704 if "instance" not in instance_dict:
705 myInstance = {"instance": instance_dict, "schema_version": "0.1"}
707 myInstance = instance_dict
709 myInstance["instance"]['name'] = args.name
711 myInstance["instance"]['description'] = args.description
713 myInstance["instance"]['action'] = "reserve"
715 datacenter = myInstance["instance"].get("datacenter")
716 if args.datacenter != None:
717 datacenter = args.datacenter
718 myInstance["instance"]["datacenter"] = _get_datacenter(datacenter, tenant)
720 scenario = myInstance["instance"].get("scenario")
721 if args.scenario != None:
722 scenario = args.scenario
724 print "you must provide a scenario in the file descriptor or with --scenario"
726 if isinstance(scenario, str):
727 myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant)
729 if "networks" not in myInstance["instance"]:
730 myInstance["instance"]["networks"] = {}
731 for net in args.netmap_use:
732 net_comma_list = net.split(",")
733 for net_comma in net_comma_list:
734 net_tuple = net_comma.split("=")
735 if len(net_tuple) != 2:
736 print "error at netmap-use. Expected net-scenario=net-datacenter. (%s)?" % net_comma
738 net_scenario = net_tuple[0].strip()
739 net_datacenter = net_tuple[1].strip()
740 if net_scenario not in myInstance["instance"]["networks"]:
741 myInstance["instance"]["networks"][net_scenario] = {}
742 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
743 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
744 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-use"] = net_datacenter
745 if args.netmap_create:
746 if "networks" not in myInstance["instance"]:
747 myInstance["instance"]["networks"] = {}
748 for net in args.netmap_create:
749 net_comma_list = net.split(",")
750 for net_comma in net_comma_list:
751 net_tuple = net_comma.split("=")
752 if len(net_tuple) == 1:
753 net_scenario = net_tuple[0].strip()
754 net_datacenter = None
755 elif len(net_tuple) == 2:
756 net_scenario = net_tuple[0].strip()
757 net_datacenter = net_tuple[1].strip()
759 print "error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. (%s)?" % net_comma
761 if net_scenario not in myInstance["instance"]["networks"]:
762 myInstance["instance"]["networks"][net_scenario] = {}
763 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
764 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
765 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-create"] = net_datacenter
767 if "cloud-config" not in myInstance["instance"]:
768 myInstance["instance"]["cloud-config"] = {}
769 cloud_config = myInstance["instance"]["cloud-config"]
770 for key in args.keypair:
771 index = key.find(":")
773 if "key-pairs" not in cloud_config:
774 cloud_config["key-pairs"] = []
775 cloud_config["key-pairs"].append(key)
779 key_list = key_.split(",")
780 if "users" not in cloud_config:
781 cloud_config["users"] = []
782 cloud_config["users"].append({"name": user, "key-pairs": key_list })
783 if args.keypair_auto:
786 home = os.getenv("HOME")
787 user = os.getenv("USER")
788 files = os.listdir(home+'/.ssh')
790 if file[-4:] == ".pub":
791 with open(home+'/.ssh/'+file, 'r') as f:
792 keys.append(f.read())
794 print "Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh')
796 except Exception as e:
797 print "Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e))
800 if "cloud-config" not in myInstance["instance"]:
801 myInstance["instance"]["cloud-config"] = {}
802 cloud_config = myInstance["instance"]["cloud-config"]
803 if "key-pairs" not in cloud_config:
804 cloud_config["key-pairs"] = []
806 if "users" not in cloud_config:
807 cloud_config["users"] = []
808 cloud_config["users"].append({"name": user, "key-pairs": keys })
810 payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
811 logger.debug("openmano request: %s", payload_req)
812 URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant)
813 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
814 logger.debug("openmano response: %s", mano_response.text )
815 if args.verbose==None:
818 result = 0 if mano_response.status_code==200 else mano_response.status_code
819 content = mano_response.json()
820 #print json.dumps(content, indent=4)
821 if args.verbose >= 3:
822 print yaml.safe_dump(content, indent=4, default_flow_style=False)
825 if mano_response.status_code == 200:
826 myoutput = "{:38} {:20}".format(content['uuid'], content['name'])
828 myoutput = "{} {:20}".format(myoutput, content['created_at'])
830 myoutput = "{} {:30}".format(myoutput, content['description'])
833 print content['error']['description']
836 def instance_scenario_list(args):
837 #print "instance-scenario-list",args
841 tenant = _get_tenant()
843 toshow = _get_item_uuid("instances", args.name, tenant)
844 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, toshow)
846 URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant)
847 mano_response = requests.get(URLrequest)
848 logger.debug("openmano response: %s", mano_response.text )
849 content = mano_response.json()
850 #print json.dumps(content, indent=4)
851 if args.verbose==None:
854 result = 0 if mano_response.status_code==200 else mano_response.status_code
855 if mano_response.status_code == 200:
857 if args.verbose >= 3:
858 print yaml.safe_dump(content, indent=4, default_flow_style=False)
860 if len(content['instances']) == 0:
861 print "No scenario instances were found."
863 for instance in content['instances']:
864 myoutput = "{:38} {:20}".format(instance['uuid'], instance['name'])
866 myoutput = "{} {:20}".format(myoutput, instance['created_at'])
869 print "Description: %s" %instance['description']
872 print yaml.safe_dump(content, indent=4, default_flow_style=False)
875 print ("{:38} {:20} {:20}".format(instance['uuid'],instance['name'],instance['created_at']))
876 print ("Description: %s" %instance['description'])
877 print ("Template scenario id: {}".format(instance['scenario_id']))
878 print ("Template scenario name: {}".format(instance['scenario_name']))
879 print ("---------------------------------------")
880 print ("VNF instances: {}".format(len(instance['vnfs'])))
881 for vnf in instance['vnfs']:
882 #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))
883 print (" {:38} {:20} Template vnf id: {:38}".format(vnf['uuid'], vnf['vnf_name'], vnf['vnf_id']))
884 if len(instance['nets'])>0:
885 print "---------------------------------------"
886 print "Internal nets:"
887 for net in instance['nets']:
889 print (" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
890 print "---------------------------------------"
891 print "External nets:"
892 for net in instance['nets']:
893 if not net['created']:
894 print (" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
895 print ("---------------------------------------")
896 print ("VM instances:")
897 for vnf in instance['vnfs']:
898 for vm in vnf['vms']:
899 print (" {:38} {:20} {:20} {:12} VIM ID: {}".format(vm['uuid'], vnf['vnf_name'], vm['name'],
900 vm['status'], vm['vim_vm_id']))
902 print content['error']['description']
904 print yaml.safe_dump(content, indent=4, default_flow_style=False)
907 def instance_scenario_status(args):
908 print "instance-scenario-status"
911 def instance_scenario_delete(args):
915 tenant = _get_tenant()
916 todelete = _get_item_uuid("instances", args.name, tenant=tenant)
917 #print "instance-scenario-delete",args
919 r = raw_input("Delete scenario instance %s (y/N)? " %(args.name))
920 if not (len(r)>0 and r[0].lower()=="y"):
922 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, todelete)
923 mano_response = requests.delete(URLrequest)
924 logger.debug("openmano response: %s", mano_response.text )
925 result = 0 if mano_response.status_code==200 else mano_response.status_code
926 content = mano_response.json()
927 #print json.dumps(content, indent=4)
928 if mano_response.status_code == 200:
929 print content['result']
931 print content['error']['description']
934 def get_action(args):
936 tenant = _get_tenant()
939 if not args.instance:
942 instance_id =args.instance
945 action_id = "/" + args.id
946 URLrequest = "http://{}:{}/openmano/{}/instances/{}/action{}".format(mano_host, mano_port, tenant, instance_id,
948 mano_response = requests.get(URLrequest)
949 logger.debug("openmano response: %s", mano_response.text )
950 if args.verbose == None:
954 return _print_verbose(mano_response, args.verbose)
956 def instance_scenario_action(args):
957 #print "instance-scenario-action", args
958 tenant = _get_tenant()
959 toact = _get_item_uuid("instances", args.name, tenant=tenant)
961 action[ args.action ] = yaml.safe_load(args.param)
963 action["vnfs"] = args.vnf
965 action["vms"] = args.vm
967 headers_req = {'content-type': 'application/json'}
968 payload_req = json.dumps(action, indent=4)
969 URLrequest = "http://%s:%s/openmano/%s/instances/%s/action" %(mano_host, mano_port, tenant, toact)
970 logger.debug("openmano request: %s", payload_req)
971 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
972 logger.debug("openmano response: %s", mano_response.text )
973 result = 0 if mano_response.status_code==200 else mano_response.status_code
974 content = mano_response.json()
975 # print json.dumps(content, indent=4)
976 if mano_response.status_code == 200:
978 print yaml.safe_dump(content, indent=4, default_flow_style=False)
980 if "instance_action_id" in content:
981 print("instance_action_id={}".format(content["instance_action_id"]))
983 for uuid,c in content.iteritems():
984 print ("{:38} {:20} {:20}".format(uuid, c.get('name'), c.get('description')))
986 print content['error']['description']
990 def instance_vnf_list(args):
991 print "instance-vnf-list"
994 def instance_vnf_status(args):
995 print "instance-vnf-status"
998 def tenant_create(args):
999 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1000 tenant_dict={"name": args.name}
1001 if args.description!=None:
1002 tenant_dict["description"] = args.description
1003 payload_req = json.dumps( {"tenant": tenant_dict })
1007 URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port)
1008 logger.debug("openmano request: %s", payload_req)
1009 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1010 logger.debug("openmano response: %s", mano_response.text )
1011 return _print_verbose(mano_response, args.verbose)
1013 def tenant_list(args):
1014 #print "tenant-list",args
1016 toshow = _get_item_uuid("tenants", args.name)
1017 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, toshow)
1019 URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port)
1020 mano_response = requests.get(URLrequest)
1021 logger.debug("openmano response: %s", mano_response.text )
1022 if args.verbose==None:
1026 return _print_verbose(mano_response, args.verbose)
1028 def tenant_delete(args):
1029 #print "tenant-delete",args
1030 todelete = _get_item_uuid("tenants", args.name)
1032 r = raw_input("Delete tenant %s (y/N)? " %(args.name))
1033 if not (len(r)>0 and r[0].lower()=="y"):
1035 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, todelete)
1036 mano_response = requests.delete(URLrequest)
1037 logger.debug("openmano response: %s", mano_response.text )
1038 result = 0 if mano_response.status_code==200 else mano_response.status_code
1039 content = mano_response.json()
1040 #print json.dumps(content, indent=4)
1041 if mano_response.status_code == 200:
1042 print content['result']
1044 print content['error']['description']
1047 def datacenter_attach(args):
1048 tenant = _get_tenant()
1049 datacenter = _get_datacenter(args.name)
1050 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1053 if args.vim_tenant_id != None:
1054 datacenter_dict['vim_tenant'] = args.vim_tenant_id
1055 if args.vim_tenant_name != None:
1056 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
1057 if args.user != None:
1058 datacenter_dict['vim_username'] = args.user
1059 if args.password != None:
1060 datacenter_dict['vim_password'] = args.password
1061 if args.config!=None:
1062 datacenter_dict["config"] = _load_file_or_yaml(args.config)
1064 payload_req = json.dumps( {"datacenter": datacenter_dict })
1068 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter)
1069 logger.debug("openmano request: %s", payload_req)
1070 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1071 logger.debug("openmano response: %s", mano_response.text )
1072 result = _print_verbose(mano_response, args.verbose)
1073 #provide addional information if error
1074 if mano_response.status_code != 200:
1075 content = mano_response.json()
1076 if "already in use for 'name'" in content['error']['description'] and \
1077 "to database vim_tenants table" in content['error']['description']:
1078 print "Try to specify a different name with --vim-tenant-name"
1082 def datacenter_edit_vim_tenant(args):
1083 tenant = _get_tenant()
1084 datacenter = _get_datacenter(args.name)
1085 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1087 if not (args.vim_tenant_id or args.vim_tenant_name or args.user or args.password or args.config):
1088 raise OpenmanoCLIError("Error. At least one parameter must be updated.")
1090 datacenter_dict = {}
1091 if args.vim_tenant_id != None:
1092 datacenter_dict['vim_tenant'] = args.vim_tenant_id
1093 if args.vim_tenant_name != None:
1094 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
1095 if args.user != None:
1096 datacenter_dict['vim_username'] = args.user
1097 if args.password != None:
1098 datacenter_dict['vim_password'] = args.password
1099 if args.config != None:
1100 datacenter_dict["config"] = _load_file_or_yaml(args.config)
1101 payload_req = json.dumps({"datacenter": datacenter_dict})
1105 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" % (mano_host, mano_port, tenant, datacenter)
1106 logger.debug("openmano request: %s", payload_req)
1107 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1108 logger.debug("openmano response: %s", mano_response.text)
1109 result = _print_verbose(mano_response, args.verbose)
1113 def datacenter_detach(args):
1117 tenant = _get_tenant()
1118 datacenter = _get_datacenter(args.name, tenant)
1119 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1120 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter)
1121 mano_response = requests.delete(URLrequest, headers=headers_req)
1122 logger.debug("openmano response: %s", mano_response.text )
1123 content = mano_response.json()
1124 #print json.dumps(content, indent=4)
1125 result = 0 if mano_response.status_code==200 else mano_response.status_code
1126 if mano_response.status_code == 200:
1127 print content['result']
1129 print content['error']['description']
1132 def datacenter_create(args):
1133 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1134 datacenter_dict={"name": args.name, "vim_url": args.url}
1135 if args.description!=None:
1136 datacenter_dict["description"] = args.description
1138 datacenter_dict["type"] = args.type
1140 datacenter_dict["vim_url_admin"] = args.url_admin
1141 if args.config!=None:
1142 datacenter_dict["config"] = _load_file_or_yaml(args.config)
1143 if args.sdn_controller!=None:
1144 tenant = _get_tenant()
1145 sdn_controller = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1146 if not 'config' in datacenter_dict:
1147 datacenter_dict['config'] = {}
1148 datacenter_dict['config']['sdn-controller'] = sdn_controller
1149 payload_req = json.dumps( {"datacenter": datacenter_dict })
1153 URLrequest = "http://%s:%s/openmano/datacenters" %(mano_host, mano_port)
1154 logger.debug("openmano request: %s", payload_req)
1155 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1156 logger.debug("openmano response: %s", mano_response.text )
1157 return _print_verbose(mano_response, args.verbose)
1159 def datacenter_delete(args):
1160 #print "datacenter-delete",args
1161 todelete = _get_item_uuid("datacenters", args.name, "any")
1163 r = raw_input("Delete datacenter %s (y/N)? " %(args.name))
1164 if not (len(r)>0 and r[0].lower()=="y"):
1166 URLrequest = "http://%s:%s/openmano/datacenters/%s" %(mano_host, mano_port, todelete)
1167 mano_response = requests.delete(URLrequest)
1168 logger.debug("openmano response: %s", mano_response.text )
1169 result = 0 if mano_response.status_code==200 else mano_response.status_code
1170 content = mano_response.json()
1171 #print json.dumps(content, indent=4)
1172 if mano_response.status_code == 200:
1173 print content['result']
1175 print content['error']['description']
1179 def datacenter_list(args):
1180 #print "datacenter-list",args
1181 tenant='any' if args.all else _get_tenant()
1184 toshow = _get_item_uuid("datacenters", args.name, tenant)
1185 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, toshow)
1187 URLrequest = "http://%s:%s/openmano/%s/datacenters" %(mano_host, mano_port, tenant)
1188 mano_response = requests.get(URLrequest)
1189 logger.debug("openmano response: %s", mano_response.text )
1190 if args.verbose==None:
1194 return _print_verbose(mano_response, args.verbose)
1197 def datacenter_sdn_port_mapping_set(args):
1198 tenant = _get_tenant()
1199 datacenter = _get_datacenter(args.name, tenant)
1200 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1203 raise OpenmanoCLIError(
1204 "No yaml/json has been provided specifying the SDN port mapping")
1205 sdn_port_mapping = _load_file_or_yaml(args.file)
1206 payload_req = json.dumps({"sdn_port_mapping": sdn_port_mapping})
1209 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1210 mano_response = requests.get(URLrequest)
1211 logger.debug("openmano response: %s", mano_response.text)
1212 port_mapping = mano_response.json()
1213 if mano_response.status_code != 200:
1214 str(mano_response.json())
1215 raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
1216 if len(port_mapping["sdn_port_mapping"]["ports_mapping"]) > 0:
1218 r = raw_input("Datacenter %s already contains a port mapping. Overwrite? (y/N)? " % (datacenter))
1219 if not (len(r) > 0 and r[0].lower() == "y"):
1223 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1224 mano_response = requests.delete(URLrequest)
1225 logger.debug("openmano response: %s", mano_response.text)
1226 if mano_response.status_code != 200:
1227 return _print_verbose(mano_response, args.verbose)
1230 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1231 logger.debug("openmano request: %s", payload_req)
1232 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1233 logger.debug("openmano response: %s", mano_response.text)
1234 return _print_verbose(mano_response, args.verbose)
1237 def datacenter_sdn_port_mapping_list(args):
1238 tenant = _get_tenant()
1239 datacenter = _get_datacenter(args.name, tenant)
1241 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1242 mano_response = requests.get(URLrequest)
1243 logger.debug("openmano response: %s", mano_response.text)
1245 return _print_verbose(mano_response, 4)
1248 def datacenter_sdn_port_mapping_clear(args):
1249 tenant = _get_tenant()
1250 datacenter = _get_datacenter(args.name, tenant)
1253 r = raw_input("Clean SDN port mapping for datacenter %s (y/N)? " %(datacenter))
1254 if not (len(r) > 0 and r[0].lower() == "y"):
1257 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1258 mano_response = requests.delete(URLrequest)
1259 logger.debug("openmano response: %s", mano_response.text)
1261 return _print_verbose(mano_response, args.verbose)
1264 def sdn_controller_create(args):
1265 tenant = _get_tenant()
1266 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1269 if not args.ip: error_msg.append("'ip'")
1270 if not args.port: error_msg.append("'port'")
1271 if not args.dpid: error_msg.append("'dpid'")
1272 if not args.type: error_msg.append("'type'")
1274 raise OpenmanoCLIError("The following arguments are required: " + ",".join(error_msg))
1276 controller_dict = {}
1277 controller_dict['name'] = args.name
1278 controller_dict['ip'] = args.ip
1279 controller_dict['port'] = int(args.port)
1280 controller_dict['dpid'] = args.dpid
1281 controller_dict['type'] = args.type
1282 if args.description != None:
1283 controller_dict['description'] = args.description
1284 if args.user != None:
1285 controller_dict['user'] = args.user
1286 if args.password != None:
1287 controller_dict['password'] = args.password
1289 payload_req = json.dumps({"sdn_controller": controller_dict})
1293 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" % (mano_host, mano_port, tenant)
1294 logger.debug("openmano request: %s", payload_req)
1295 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1296 logger.debug("openmano response: %s", mano_response.text)
1297 result = _print_verbose(mano_response, args.verbose)
1301 def sdn_controller_edit(args):
1302 tenant = _get_tenant()
1303 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1304 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1306 controller_dict = {}
1308 controller_dict['name'] = args.new_name
1310 controller_dict['ip'] = args.ip
1312 controller_dict['port'] = int(args.port)
1314 controller_dict['dpid'] = args.dpid
1316 controller_dict['type'] = args.type
1317 if args.description:
1318 controller_dict['description'] = args.description
1320 controller_dict['user'] = args.user
1322 controller_dict['password'] = args.password
1324 if not controller_dict:
1325 raise OpenmanoCLIError("At least one parameter must be edited")
1328 r = raw_input("Update SDN controller {} (y/N)? ".format(args.name))
1329 if not (len(r) > 0 and r[0].lower() == "y"):
1332 payload_req = json.dumps({"sdn_controller": controller_dict})
1335 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" % (mano_host, mano_port, tenant, controller_uuid)
1336 logger.debug("openmano request: %s", payload_req)
1337 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1338 logger.debug("openmano response: %s", mano_response.text)
1339 result = _print_verbose(mano_response, args.verbose)
1343 def sdn_controller_list(args):
1344 tenant = _get_tenant()
1345 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1348 toshow = _get_item_uuid("sdn_controllers", args.name, tenant)
1349 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" %(mano_host, mano_port, tenant, toshow)
1351 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" %(mano_host, mano_port, tenant)
1353 mano_response = requests.get(URLrequest)
1354 logger.debug("openmano response: %s", mano_response.text )
1355 if args.verbose==None:
1360 # json.dumps(mano_response.json(), indent=4)
1361 return _print_verbose(mano_response, args.verbose)
1364 def sdn_controller_delete(args):
1365 tenant = _get_tenant()
1366 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1369 r = raw_input("Delete SDN controller %s (y/N)? " % (args.name))
1370 if not (len(r) > 0 and r[0].lower() == "y"):
1373 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" % (mano_host, mano_port, tenant, controller_uuid)
1374 mano_response = requests.delete(URLrequest)
1375 logger.debug("openmano response: %s", mano_response.text)
1376 return _print_verbose(mano_response, args.verbose)
1378 def vim_action(args):
1379 #print "datacenter-net-action",args
1380 tenant = _get_tenant()
1381 datacenter = _get_datacenter(args.datacenter, tenant)
1382 if args.verbose==None:
1384 if args.action=="list":
1385 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
1388 URLrequest += "/" + args.name
1389 mano_response = requests.get(URLrequest)
1390 logger.debug("openmano response: %s", mano_response.text )
1391 return _print_verbose(mano_response, args.verbose)
1392 elif args.action=="delete":
1393 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss/%s" %(mano_host, mano_port, tenant, datacenter, args.item, args.name)
1394 mano_response = requests.delete(URLrequest)
1395 logger.debug("openmano response: %s", mano_response.text )
1396 result = 0 if mano_response.status_code==200 else mano_response.status_code
1397 content = mano_response.json()
1398 #print json.dumps(content, indent=4)
1399 if mano_response.status_code == 200:
1400 print content['result']
1402 print content['error']['description']
1404 elif args.action=="create":
1405 headers_req = {'content-type': 'application/yaml'}
1407 create_dict = _load_file_or_yaml(args.file)
1408 if args.item not in create_dict:
1409 create_dict = {args.item: create_dict}
1411 create_dict = {args.item:{}}
1413 create_dict[args.item]['name'] = args.name
1414 #if args.description:
1415 # create_dict[args.item]['description'] = args.description
1416 if args.item=="network":
1418 create_dict[args.item]['bind_net'] = args.bind_net
1420 create_dict[args.item]['type'] = args.type
1422 create_dict[args.item]['shared'] = args.shared
1423 if "name" not in create_dict[args.item]:
1424 print "You must provide a name in the descriptor file or with the --name option"
1426 payload_req = yaml.safe_dump(create_dict, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
1427 logger.debug("openmano request: %s", payload_req)
1428 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
1429 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
1430 logger.debug("openmano response: %s", mano_response.text )
1431 if args.verbose==None:
1433 return _print_verbose(mano_response, args.verbose)
1436 def _get_items(item, item_name_id=None, datacenter=None, tenant=None):
1437 URLrequest = "http://%s:%s/openmano" %(mano_host, mano_port)
1439 URLrequest += "/" + tenant
1441 URLrequest += "/vim/" + datacenter
1443 URLrequest += "/" + item +"s"
1445 URLrequest += "/" + item_name_id
1446 mano_response = requests.get(URLrequest)
1447 logger.debug("openmano response: %s", mano_response.text )
1449 return mano_response
1452 def vim_net_sdn_attach(args):
1453 #Verify the network exists in the vim
1454 tenant = _get_tenant()
1455 datacenter = _get_datacenter(args.datacenter, tenant)
1456 result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
1457 content = yaml.load(result.content)
1458 if 'networks' in content:
1459 raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
1460 if 'error' in content:
1461 raise OpenmanoCLIError(yaml.safe_dump(content))
1462 network_uuid = content['network']['id']
1464 #Make call to attach the dataplane port to the SND network associated to the vim network
1465 headers_req = {'content-type': 'application/yaml'}
1466 payload_req = {'port': args.port}
1468 payload_req['vlan'] = int(args.vlan)
1470 payload_req['mac'] = args.mac
1472 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/attach" % (mano_host, mano_port, tenant, datacenter, network_uuid)
1473 logger.debug("openmano request: %s", payload_req)
1474 mano_response = requests.post(URLrequest, headers=headers_req, data=json.dumps(payload_req))
1475 logger.debug("openmano response: %s", mano_response.text)
1476 result = _print_verbose(mano_response, args.verbose)
1480 def vim_net_sdn_detach(args):
1481 if not args.all and not args.id:
1482 print "--all or --id must be used"
1485 # Verify the network exists in the vim
1486 tenant = _get_tenant()
1487 datacenter = _get_datacenter(args.datacenter, tenant)
1488 result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
1489 content = yaml.load(result.content)
1490 if 'networks' in content:
1491 raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
1492 if 'error' in content:
1493 raise OpenmanoCLIError(yaml.safe_dump(content))
1494 network_uuid = content['network']['id']
1497 r = raw_input("Confirm action' (y/N)? ")
1498 if len(r) == 0 or r[0].lower() != "y":
1502 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach/%s" % (
1503 mano_host, mano_port, tenant, datacenter, network_uuid, args.id)
1505 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach" % (
1506 mano_host, mano_port, tenant, datacenter, network_uuid)
1507 mano_response = requests.delete(URLrequest)
1508 logger.debug("openmano response: %s", mano_response.text)
1509 result = _print_verbose(mano_response, args.verbose)
1513 def datacenter_net_action(args):
1514 if args.action == "net-update":
1515 print "This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano datacenter-netmap-import' instead!!!"
1517 args.action = "netmap-delete"
1520 r = datacenter_netmap_action(args)
1523 args.action = "netmap-import"
1524 r = datacenter_netmap_action(args)
1527 if args.action == "net-edit":
1528 args.netmap = args.net
1530 elif args.action == "net-list":
1532 elif args.action == "net-delete":
1533 args.netmap = args.net
1536 args.action = "netmap" + args.action[3:]
1539 print "This command is deprecated, use 'openmano datacenter-%s' instead!!!" % args.action
1541 return datacenter_netmap_action(args)
1543 def datacenter_netmap_action(args):
1544 tenant = _get_tenant()
1545 datacenter = _get_datacenter(args.datacenter, tenant)
1546 #print "datacenter_netmap_action",args
1548 if args.verbose==None:
1550 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1551 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/netmaps" %(mano_host, mano_port, tenant, datacenter)
1553 if args.action=="netmap-list":
1555 URLrequest += "/" + args.netmap
1557 mano_response = requests.get(URLrequest)
1559 elif args.action=="netmap-delete":
1560 if args.netmap and args.all:
1561 print "you can not use a netmap name and the option --all at the same time"
1564 force_text= "Delete default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter)
1565 URLrequest += "/" + args.netmap
1567 force_text="Delete all default netmaps from datacenter '%s' (y/N)? " % (datacenter)
1569 print "you must specify a netmap name or the option --all"
1572 r = raw_input(force_text)
1573 if len(r)>0 and r[0].lower()=="y":
1577 mano_response = requests.delete(URLrequest, headers=headers_req)
1578 elif args.action=="netmap-import":
1580 r = raw_input("Create all the available networks from datacenter '%s' as default netmaps (y/N)? " % (datacenter))
1581 if len(r)>0 and r[0].lower()=="y":
1585 URLrequest += "/upload"
1586 mano_response = requests.post(URLrequest, headers=headers_req)
1587 elif args.action=="netmap-edit" or args.action=="netmap-create":
1589 payload = _load_file_or_yaml(args.file)
1592 if "netmap" not in payload:
1593 payload = {"netmap": payload}
1595 payload["netmap"]["name"] = args.name
1597 payload["netmap"]["vim_id"] = args.vim_id
1598 if args.action=="netmap-create" and args.vim_name:
1599 payload["netmap"]["vim_name"] = args.vim_name
1600 payload_req = json.dumps(payload)
1601 logger.debug("openmano request: %s", payload_req)
1603 if args.action=="netmap-edit" and not args.force:
1604 if len(payload["netmap"]) == 0:
1605 print "You must supply some parameter to edit"
1607 r = raw_input("Edit default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter))
1608 if len(r)>0 and r[0].lower()=="y":
1612 URLrequest += "/" + args.netmap
1613 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1614 else: #netmap-create
1615 if "vim_name" not in payload["netmap"] and "vim_id" not in payload["netmap"]:
1616 print "You must supply either --vim-id or --vim-name option; or include one of them in the file descriptor"
1618 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1620 logger.debug("openmano response: %s", mano_response.text )
1621 return _print_verbose(mano_response, args.verbose)
1624 def element_edit(args):
1625 element = _get_item_uuid(args.element, args.name)
1626 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1627 URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, args.element, element)
1628 payload=_load_file_or_yaml(args.file)
1629 if args.element[:-1] not in payload:
1630 payload = {args.element[:-1]: payload }
1631 payload_req = json.dumps(payload)
1634 if not args.force or (args.name==None and args.filer==None):
1635 r = raw_input(" Edit " + args.element[:-1] + " " + args.name + " (y/N)? ")
1636 if len(r)>0 and r[0].lower()=="y":
1640 logger.debug("openmano request: %s", payload_req)
1641 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1642 logger.debug("openmano response: %s", mano_response.text )
1643 if args.verbose==None:
1647 return _print_verbose(mano_response, args.verbose)
1650 def datacenter_edit(args):
1651 tenant = _get_tenant()
1652 element = _get_item_uuid('datacenters', args.name, tenant)
1653 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1654 URLrequest = "http://%s:%s/openmano/datacenters/%s" % (mano_host, mano_port, element)
1656 has_arguments = False
1657 if args.file != None:
1658 has_arguments = True
1659 payload = _load_file_or_yaml(args.file)
1663 if args.sdn_controller != None:
1664 has_arguments = True
1665 if not 'config' in payload:
1666 payload['config'] = {}
1667 if not 'sdn-controller' in payload['config']:
1668 payload['config']['sdn-controller'] = {}
1669 if args.sdn_controller == 'null':
1670 payload['config']['sdn-controller'] = None
1672 payload['config']['sdn-controller'] = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1674 if not has_arguments:
1675 raise OpenmanoCLIError("At least one argument must be provided to modify the datacenter")
1677 if 'datacenter' not in payload:
1678 payload = {'datacenter': payload}
1679 payload_req = json.dumps(payload)
1682 if not args.force or (args.name == None and args.filer == None):
1683 r = raw_input(" Edit datacenter " + args.name + " (y/N)? ")
1684 if len(r) > 0 and r[0].lower() == "y":
1688 logger.debug("openmano request: %s", payload_req)
1689 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1690 logger.debug("openmano response: %s", mano_response.text)
1691 if args.verbose == None:
1693 if args.name != None:
1695 return _print_verbose(mano_response, args.verbose)
1699 def wim_account_create(args):
1700 tenant = _get_tenant()
1701 wim = _get_wim(args.name)
1702 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1705 if args.account_name is not None:
1706 wim_dict['name'] = args.account_name
1707 if args.user is not None:
1708 wim_dict['user'] = args.user
1709 if args.password is not None:
1710 wim_dict['password'] = args.password
1711 if args.config is not None:
1712 wim_dict["config"] = _load_file_or_yaml(args.config)
1714 payload_req = json.dumps({"wim_account": wim_dict})
1716 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim)
1717 logger.debug("openmano request: %s", payload_req)
1718 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1719 logger.debug("openmano response: %s", mano_response.text)
1720 result = _print_verbose(mano_response, args.verbose)
1721 # provide addional information if error
1722 if mano_response.status_code != 200:
1723 content = mano_response.json()
1724 if "already in use for 'name'" in content['error']['description'] and \
1725 "to database wim_tenants table" in content['error']['description']:
1726 print "Try to specify a different name with --wim-tenant-name"
1730 def wim_account_delete(args):
1734 tenant = _get_tenant()
1735 wim = _get_wim(args.name, tenant)
1736 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1737 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim)
1738 mano_response = requests.delete(URLrequest, headers=headers_req)
1739 logger.debug("openmano response: %s", mano_response.text)
1740 content = mano_response.json()
1741 # print json.dumps(content, indent=4)
1742 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1743 if mano_response.status_code == 200:
1744 print content['result']
1746 print content['error']['description']
1750 def wim_account_edit(args):
1751 tenant = _get_tenant()
1752 wim = _get_wim(args.name)
1753 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1756 if not args.account_name:
1757 wim_dict['name'] = args.vim_tenant_name
1759 wim_dict['user'] = args.user
1760 if not args.password:
1761 wim_dict['password'] = args.password
1763 wim_dict["config"] = _load_file_or_yaml(args.config)
1765 payload_req = json.dumps({"wim_account": wim_dict})
1769 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim)
1770 logger.debug("openmano request: %s", payload_req)
1771 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1772 logger.debug("openmano response: %s", mano_response.text)
1773 result = _print_verbose(mano_response, args.verbose)
1774 # provide addional information if error
1775 if mano_response.status_code != 200:
1776 content = mano_response.json()
1777 if "already in use for 'name'" in content['error']['description'] and \
1778 "to database wim_tenants table" in content['error']['description']:
1779 print "Try to specify a different name with --wim-tenant-name"
1782 def wim_create(args):
1783 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1784 wim_dict = {"name": args.name, "wim_url": args.url}
1785 if args.description != None:
1786 wim_dict["description"] = args.description
1787 if args.type != None:
1788 wim_dict["type"] = args.type
1789 if args.config != None:
1790 wim_dict["config"] = _load_file_or_yaml(args.config)
1792 payload_req = json.dumps({"wim": wim_dict})
1794 URLrequest = "http://%s:%s/openmano/wims" % (mano_host, mano_port)
1795 logger.debug("openmano request: %s", payload_req)
1796 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1797 logger.debug("openmano response: %s", mano_response.text)
1798 return _print_verbose(mano_response, args.verbose)
1802 tenant = _get_tenant()
1803 element = _get_item_uuid('wims', args.name, tenant)
1804 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1805 URLrequest = "http://%s:%s/openmano/wims/%s" % (mano_host, mano_port, element)
1807 has_arguments = False
1808 if args.file != None:
1809 has_arguments = True
1810 payload = _load_file_or_yaml(args.file)
1814 if not has_arguments:
1815 raise OpenmanoCLIError("At least one argument must be provided to modify the wim")
1817 if 'wim' not in payload:
1818 payload = {'wim': payload}
1819 payload_req = json.dumps(payload)
1822 if not args.force or (args.name == None and args.filer == None):
1823 r = raw_input(" Edit wim " + args.name + " (y/N)? ")
1824 if len(r) > 0 and r[0].lower() == "y":
1828 logger.debug("openmano request: %s", payload_req)
1829 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1830 logger.debug("openmano response: %s", mano_response.text)
1831 if args.verbose == None:
1833 if args.name != None:
1835 return _print_verbose(mano_response, args.verbose)
1838 def wim_delete(args):
1839 # print "wim-delete",args
1840 todelete = _get_item_uuid("wims", args.name, "any")
1842 r = raw_input("Delete wim %s (y/N)? " % (args.name))
1843 if not (len(r) > 0 and r[0].lower() == "y"):
1845 URLrequest = "http://%s:%s/openmano/wims/%s" % (mano_host, mano_port, todelete)
1846 mano_response = requests.delete(URLrequest)
1847 logger.debug("openmano response: %s", mano_response.text)
1848 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1849 content = mano_response.json()
1850 # print json.dumps(content, indent=4)
1851 if mano_response.status_code == 200:
1852 print content['result']
1854 print content['error']['description']
1859 # print "wim-list",args
1860 tenant = 'any' if args.all else _get_tenant()
1863 toshow = _get_item_uuid("wims", args.name, tenant)
1864 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, toshow)
1866 URLrequest = "http://%s:%s/openmano/%s/wims" % (mano_host, mano_port, tenant)
1867 mano_response = requests.get(URLrequest)
1868 logger.debug("openmano response: %s", mano_response.text)
1869 if args.verbose == None:
1871 if args.name != None:
1873 return _print_verbose(mano_response, args.verbose)
1876 def wim_port_mapping_set(args):
1877 tenant = _get_tenant()
1878 wim = _get_wim(args.name, tenant)
1879 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1882 raise OpenmanoCLIError(
1883 "No yaml/json has been provided specifying the WIM port mapping")
1884 wim_port_mapping = _load_file_or_yaml(args.file)
1886 payload_req = json.dumps({"wim_port_mapping": wim_port_mapping})
1889 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1890 mano_response = requests.get(URLrequest)
1891 logger.debug("openmano response: %s", mano_response.text)
1892 port_mapping = mano_response.json()
1894 if mano_response.status_code != 200:
1895 str(mano_response.json())
1896 raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
1897 # TODO: check this if statement
1898 if len(port_mapping["wim_port_mapping"]) > 0:
1900 r = raw_input("WIM %s already contains a port mapping. Overwrite? (y/N)? " % (wim))
1901 if not (len(r) > 0 and r[0].lower() == "y"):
1905 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1906 mano_response = requests.delete(URLrequest)
1907 logger.debug("openmano response: %s", mano_response.text)
1908 if mano_response.status_code != 200:
1909 return _print_verbose(mano_response, args.verbose)
1912 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1913 logger.debug("openmano request: %s", payload_req)
1914 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1915 logger.debug("openmano response: %s", mano_response.text)
1916 return _print_verbose(mano_response, 4)
1919 def wim_port_mapping_list(args):
1920 tenant = _get_tenant()
1921 wim = _get_wim(args.name, tenant)
1923 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1924 mano_response = requests.get(URLrequest)
1925 logger.debug("openmano response: %s", mano_response.text)
1927 return _print_verbose(mano_response, 4)
1930 def wim_port_mapping_clear(args):
1931 tenant = _get_tenant()
1932 wim = _get_wim(args.name, tenant)
1935 r = raw_input("Clear WIM port mapping for wim %s (y/N)? " % (wim))
1936 if not (len(r) > 0 and r[0].lower() == "y"):
1939 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1940 mano_response = requests.delete(URLrequest)
1941 logger.debug("openmano response: %s", mano_response.text)
1942 content = mano_response.json()
1943 # print json.dumps(content, indent=4)
1944 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1945 if mano_response.status_code == 200:
1946 print content['result']
1948 print content['error']['description']
1953 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1954 URLrequest = "http://%s:%s/openmano/version" % (mano_host, mano_port)
1956 mano_response = requests.get(URLrequest, headers=headers_req)
1957 logger.debug("openmano response: %s", mano_response.text)
1958 print mano_response.text
1965 if __name__=="__main__":
1967 mano_tenant = os.getenv('OPENMANO_TENANT', None)
1968 mano_host = os.getenv('OPENMANO_HOST',"localhost")
1969 mano_port = os.getenv('OPENMANO_PORT',"9090")
1970 mano_datacenter = os.getenv('OPENMANO_DATACENTER',None)
1971 # WIM env variable for default WIM
1972 mano_wim = os.getenv('OPENMANO_WIM', None)
1974 main_parser = ThrowingArgumentParser(description='User program to interact with OPENMANO-SERVER (openmanod)')
1975 main_parser.add_argument('--version', action='version', help="get version of this client",
1976 version='%(prog)s client version ' + __version__ +
1977 " (Note: use '%(prog)s version' to get server version)")
1979 subparsers = main_parser.add_subparsers(help='commands')
1981 parent_parser = argparse.ArgumentParser(add_help=False)
1982 parent_parser.add_argument('--verbose', '-v', action='count', help="increase verbosity level. Use several times")
1983 parent_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
1985 config_parser = subparsers.add_parser('config', parents=[parent_parser], help="prints configuration values")
1986 config_parser.add_argument("-n", action="store_true", help="resolves tenant and datacenter names")
1987 config_parser.set_defaults(func=config)
1989 version_parser = subparsers.add_parser('version', parents=[parent_parser], help="get server version")
1990 version_parser.set_defaults(func=version)
1992 vnf_create_parser = subparsers.add_parser('vnf-create', parents=[parent_parser], help="adds a vnf into the catalogue")
1993 vnf_create_parser.add_argument("file", action="store", help="location of the JSON file describing the VNF").completer = FilesCompleter
1994 vnf_create_parser.add_argument("--name", action="store", help="name of the VNF (if it exists in the VNF descriptor, it is overwritten)")
1995 vnf_create_parser.add_argument("--description", action="store", help="description of the VNF (if it exists in the VNF descriptor, it is overwritten)")
1996 vnf_create_parser.add_argument("--image-path", action="store", help="change image path locations (overwritten)")
1997 vnf_create_parser.add_argument("--image-name", action="store", help="change image name (overwritten)")
1998 vnf_create_parser.add_argument("--image-checksum", action="store", help="change image checksum (overwritten)")
1999 vnf_create_parser.set_defaults(func=vnf_create)
2001 vnf_list_parser = subparsers.add_parser('vnf-list', parents=[parent_parser], help="lists information about a vnf")
2002 vnf_list_parser.add_argument("name", nargs='?', help="name of the VNF")
2003 vnf_list_parser.add_argument("-a", "--all", action="store_true", help="shows all vnfs, not only the owned or public ones")
2004 #vnf_list_parser.add_argument('--descriptor', help="prints the VNF descriptor", action="store_true")
2005 vnf_list_parser.set_defaults(func=vnf_list)
2007 vnf_delete_parser = subparsers.add_parser('vnf-delete', parents=[parent_parser], help="deletes a vnf from the catalogue")
2008 vnf_delete_parser.add_argument("name", action="store", help="name or uuid of the VNF to be deleted")
2009 vnf_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2010 vnf_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2011 vnf_delete_parser.set_defaults(func=vnf_delete)
2013 scenario_create_parser = subparsers.add_parser('scenario-create', parents=[parent_parser], help="adds a scenario into the OPENMANO DB")
2014 scenario_create_parser.add_argument("file", action="store", help="location of the YAML file describing the scenario").completer = FilesCompleter
2015 scenario_create_parser.add_argument("--name", action="store", help="name of the scenario (if it exists in the YAML scenario, it is overwritten)")
2016 scenario_create_parser.add_argument("--description", action="store", help="description of the scenario (if it exists in the YAML scenario, it is overwritten)")
2017 scenario_create_parser.set_defaults(func=scenario_create)
2019 scenario_list_parser = subparsers.add_parser('scenario-list', parents=[parent_parser], help="lists information about a scenario")
2020 scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario")
2021 #scenario_list_parser.add_argument('--descriptor', help="prints the scenario descriptor", action="store_true")
2022 scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all scenarios, not only the owned or public ones")
2023 scenario_list_parser.set_defaults(func=scenario_list)
2025 scenario_delete_parser = subparsers.add_parser('scenario-delete', parents=[parent_parser], help="deletes a scenario from the OPENMANO DB")
2026 scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario to be deleted")
2027 scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2028 scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2029 scenario_delete_parser.set_defaults(func=scenario_delete)
2031 scenario_deploy_parser = subparsers.add_parser('scenario-deploy', parents=[parent_parser], help="deploys a scenario")
2032 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be deployed")
2033 scenario_deploy_parser.add_argument("name", action="store", help="name of the instance")
2034 scenario_deploy_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
2035 scenario_deploy_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
2036 scenario_deploy_parser.add_argument("--description", action="store", help="description of the instance")
2037 scenario_deploy_parser.set_defaults(func=scenario_deploy)
2039 scenario_deploy_parser = subparsers.add_parser('scenario-verify', help="verifies if a scenario can be deployed (deploys it and deletes it)")
2040 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be verified")
2041 scenario_deploy_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
2042 scenario_deploy_parser.set_defaults(func=scenario_verify)
2044 instance_scenario_create_parser = subparsers.add_parser('instance-scenario-create', parents=[parent_parser], help="deploys a scenario")
2045 instance_scenario_create_parser.add_argument("file", nargs='?', help="descriptor of the instance. Must be a file or yaml/json text")
2046 instance_scenario_create_parser.add_argument("--scenario", action="store", help="name or uuid of the scenario to be deployed")
2047 instance_scenario_create_parser.add_argument("--name", action="store", help="name of the instance")
2048 instance_scenario_create_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
2049 instance_scenario_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
2050 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")
2051 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")
2052 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")
2053 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")
2054 instance_scenario_create_parser.add_argument("--description", action="store", help="description of the instance")
2055 instance_scenario_create_parser.set_defaults(func=instance_create)
2057 instance_scenario_list_parser = subparsers.add_parser('instance-scenario-list', parents=[parent_parser], help="lists information about a scenario instance")
2058 instance_scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario instance")
2059 instance_scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all instance-scenarios, not only the owned")
2060 instance_scenario_list_parser.set_defaults(func=instance_scenario_list)
2062 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)")
2063 instance_scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario instance to be deleted")
2064 instance_scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2065 instance_scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2066 instance_scenario_delete_parser.set_defaults(func=instance_scenario_delete)
2068 instance_scenario_action_parser = subparsers.add_parser('instance-scenario-action', parents=[parent_parser], help="invoke an action over part or the whole scenario instance")
2069 instance_scenario_action_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
2070 instance_scenario_action_parser.add_argument("action", action="store", type=str, \
2071 choices=["start","pause","resume","shutoff","shutdown","forceOff","rebuild","reboot", "console", "add_public_key","vdu-scaling"],\
2072 help="action to send")
2073 instance_scenario_action_parser.add_argument("param", nargs='?', help="addional param of the action. e.g. console: novnc; reboot: type; vdu-scaling: '[{vdu-id: xxx, type: create|delete, count: 1}]'")
2074 instance_scenario_action_parser.add_argument("--vnf", action="append", help="VNF to act on (can use several entries)")
2075 instance_scenario_action_parser.add_argument("--vm", action="append", help="VM to act on (can use several entries)")
2076 instance_scenario_action_parser.set_defaults(func=instance_scenario_action)
2078 action_parser = subparsers.add_parser('action-list', parents=[parent_parser], help="get action over an instance status")
2079 action_parser.add_argument("id", nargs='?', action="store", help="action id")
2080 action_parser.add_argument("--instance", action="store", help="fitler by this instance_id")
2081 action_parser.add_argument("--all", action="store", help="Not filter by tenant")
2082 action_parser.set_defaults(func=get_action)
2084 #instance_scenario_status_parser = subparsers.add_parser('instance-scenario-status', help="show the status of a scenario instance")
2085 #instance_scenario_status_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
2086 #instance_scenario_status_parser.set_defaults(func=instance_scenario_status)
2088 tenant_create_parser = subparsers.add_parser('tenant-create', parents=[parent_parser], help="creates a new tenant")
2089 tenant_create_parser.add_argument("name", action="store", help="name for the tenant")
2090 tenant_create_parser.add_argument("--description", action="store", help="description of the tenant")
2091 tenant_create_parser.set_defaults(func=tenant_create)
2093 tenant_delete_parser = subparsers.add_parser('tenant-delete', parents=[parent_parser], help="deletes a tenant from the catalogue")
2094 tenant_delete_parser.add_argument("name", action="store", help="name or uuid of the tenant to be deleted")
2095 tenant_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2096 tenant_delete_parser.set_defaults(func=tenant_delete)
2098 tenant_list_parser = subparsers.add_parser('tenant-list', parents=[parent_parser], help="lists information about a tenant")
2099 tenant_list_parser.add_argument("name", nargs='?', help="name or uuid of the tenant")
2100 tenant_list_parser.set_defaults(func=tenant_list)
2102 element_edit_parser = subparsers.add_parser('tenant-edit', parents=[parent_parser], help="edits one tenant")
2103 element_edit_parser.add_argument("name", help="name or uuid of the tenant")
2104 element_edit_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
2105 element_edit_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2106 element_edit_parser.set_defaults(func=element_edit, element='tenants')
2108 datacenter_create_parser = subparsers.add_parser('datacenter-create', parents=[parent_parser], help="creates a new datacenter")
2109 datacenter_create_parser.add_argument("name", action="store", help="name for the datacenter")
2110 datacenter_create_parser.add_argument("url", action="store", help="url for the datacenter")
2111 datacenter_create_parser.add_argument("--url_admin", action="store", help="url for administration for the datacenter")
2112 datacenter_create_parser.add_argument("--type", action="store", help="datacenter type: openstack or openvim (default)")
2113 datacenter_create_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
2114 datacenter_create_parser.add_argument("--description", action="store", help="description of the datacenter")
2115 datacenter_create_parser.add_argument("--sdn-controller", action="store", help="Name or uuid of the SDN controller to be used", dest='sdn_controller')
2116 datacenter_create_parser.set_defaults(func=datacenter_create)
2118 datacenter_delete_parser = subparsers.add_parser('datacenter-delete', parents=[parent_parser], help="deletes a datacenter from the catalogue")
2119 datacenter_delete_parser.add_argument("name", action="store", help="name or uuid of the datacenter to be deleted")
2120 datacenter_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2121 datacenter_delete_parser.set_defaults(func=datacenter_delete)
2123 datacenter_edit_parser = subparsers.add_parser('datacenter-edit', parents=[parent_parser], help="Edit datacenter")
2124 datacenter_edit_parser.add_argument("name", help="name or uuid of the datacenter")
2125 datacenter_edit_parser.add_argument("--file", help="json/yaml text or file with the changes").completer = FilesCompleter
2126 datacenter_edit_parser.add_argument("--sdn-controller", action="store",
2127 help="Name or uuid of the SDN controller to be used. Specify 'null' to clear entry", dest='sdn_controller')
2128 datacenter_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
2129 datacenter_edit_parser.set_defaults(func=datacenter_edit)
2131 datacenter_list_parser = subparsers.add_parser('datacenter-list', parents=[parent_parser], help="lists information about a datacenter")
2132 datacenter_list_parser.add_argument("name", nargs='?', help="name or uuid of the datacenter")
2133 datacenter_list_parser.add_argument("-a", "--all", action="store_true", help="shows all datacenters, not only datacenters attached to tenant")
2134 datacenter_list_parser.set_defaults(func=datacenter_list)
2136 datacenter_attach_parser = subparsers.add_parser('datacenter-attach', parents=[parent_parser], help="associates a datacenter to the operating tenant")
2137 datacenter_attach_parser.add_argument("name", help="name or uuid of the datacenter")
2138 datacenter_attach_parser.add_argument('--vim-tenant-id', action='store', help="specify a datacenter tenant to use. A new one is created by default")
2139 datacenter_attach_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
2140 datacenter_attach_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
2141 datacenter_attach_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
2142 datacenter_attach_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
2143 datacenter_attach_parser.set_defaults(func=datacenter_attach)
2145 datacenter_edit_vim_tenant_parser = subparsers.add_parser('datacenter-edit-vim-tenant', parents=[parent_parser],
2146 help="Edit the association of a datacenter to the operating tenant")
2147 datacenter_edit_vim_tenant_parser.add_argument("name", help="name or uuid of the datacenter")
2148 datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-id', action='store',
2149 help="specify a datacenter tenant to use. A new one is created by default")
2150 datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
2151 datacenter_edit_vim_tenant_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
2152 datacenter_edit_vim_tenant_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
2153 datacenter_edit_vim_tenant_parser.add_argument("--config", action="store",
2154 help="aditional configuration in json/yaml format")
2155 datacenter_edit_vim_tenant_parser.set_defaults(func=datacenter_edit_vim_tenant)
2157 datacenter_detach_parser = subparsers.add_parser('datacenter-detach', parents=[parent_parser], help="removes the association between a datacenter and the operating tenant")
2158 datacenter_detach_parser.add_argument("name", help="name or uuid of the datacenter")
2159 datacenter_detach_parser.add_argument("-a", "--all", action="store_true", help="removes all associations from this datacenter")
2160 datacenter_detach_parser.set_defaults(func=datacenter_detach)
2162 #=======================datacenter_sdn_port_mapping_xxx section=======================
2163 #datacenter_sdn_port_mapping_set
2164 datacenter_sdn_port_mapping_set_parser = subparsers.add_parser('datacenter-sdn-port-mapping-set',
2165 parents=[parent_parser],
2166 help="Load a file with the mapping of physical ports "
2167 "and the ports of the dataplaneswitch controlled "
2169 datacenter_sdn_port_mapping_set_parser.add_argument("name", action="store", help="specifies the datacenter")
2170 datacenter_sdn_port_mapping_set_parser.add_argument("file",
2171 help="json/yaml text or file with the port mapping").completer = FilesCompleter
2172 datacenter_sdn_port_mapping_set_parser.add_argument("-f", "--force", action="store_true",
2173 help="forces overwriting without asking")
2174 datacenter_sdn_port_mapping_set_parser.set_defaults(func=datacenter_sdn_port_mapping_set)
2176 #datacenter_sdn_port_mapping_list
2177 datacenter_sdn_port_mapping_list_parser = subparsers.add_parser('datacenter-sdn-port-mapping-list',
2178 parents=[parent_parser],
2179 help="Show the SDN port mapping in a datacenter")
2180 datacenter_sdn_port_mapping_list_parser.add_argument("name", action="store", help="specifies the datacenter")
2181 datacenter_sdn_port_mapping_list_parser.set_defaults(func=datacenter_sdn_port_mapping_list)
2183 # datacenter_sdn_port_mapping_clear
2184 datacenter_sdn_port_mapping_clear_parser = subparsers.add_parser('datacenter-sdn-port-mapping-clear',
2185 parents=[parent_parser],
2186 help="Clean the the SDN port mapping in a datacenter")
2187 datacenter_sdn_port_mapping_clear_parser.add_argument("name", action="store",
2188 help="specifies the datacenter")
2189 datacenter_sdn_port_mapping_clear_parser.add_argument("-f", "--force", action="store_true",
2190 help="forces clearing without asking")
2191 datacenter_sdn_port_mapping_clear_parser.set_defaults(func=datacenter_sdn_port_mapping_clear)
2192 # =======================
2194 # =======================sdn_controller_xxx section=======================
2195 # sdn_controller_create
2196 sdn_controller_create_parser = subparsers.add_parser('sdn-controller-create', parents=[parent_parser],
2197 help="Creates an SDN controller entity within RO")
2198 sdn_controller_create_parser.add_argument("name", help="name of the SDN controller")
2199 sdn_controller_create_parser.add_argument("--description", action="store", help="description of the SDN controller")
2200 sdn_controller_create_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
2201 sdn_controller_create_parser.add_argument("--port", action="store", help="Port of the SDN controller")
2202 sdn_controller_create_parser.add_argument("--dpid", action="store",
2203 help="DPID of the dataplane switch controlled by this SDN controller")
2204 sdn_controller_create_parser.add_argument("--type", action="store",
2205 help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
2206 sdn_controller_create_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
2207 sdn_controller_create_parser.add_argument("--passwd", action="store", dest='password',
2208 help="password credentials for the SDN controller")
2209 sdn_controller_create_parser.set_defaults(func=sdn_controller_create)
2211 # sdn_controller_edit
2212 sdn_controller_edit_parser = subparsers.add_parser('sdn-controller-edit', parents=[parent_parser],
2213 help="Update one or more options of a SDN controller")
2214 sdn_controller_edit_parser.add_argument("name", help="name or uuid of the SDN controller", )
2215 sdn_controller_edit_parser.add_argument("--name", action="store", help="Update the name of the SDN controller",
2217 sdn_controller_edit_parser.add_argument("--description", action="store", help="description of the SDN controller")
2218 sdn_controller_edit_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
2219 sdn_controller_edit_parser.add_argument("--port", action="store", help="Port of the SDN controller")
2220 sdn_controller_edit_parser.add_argument("--dpid", action="store",
2221 help="DPID of the dataplane switch controlled by this SDN controller")
2222 sdn_controller_edit_parser.add_argument("--type", action="store",
2223 help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
2224 sdn_controller_edit_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
2225 sdn_controller_edit_parser.add_argument("--password", action="store",
2226 help="password credentials for the SDN controller", dest='password')
2227 sdn_controller_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
2228 #TODO: include option --file
2229 sdn_controller_edit_parser.set_defaults(func=sdn_controller_edit)
2231 #sdn_controller_list
2232 sdn_controller_list_parser = subparsers.add_parser('sdn-controller-list',
2233 parents=[parent_parser],
2234 help="List the SDN controllers")
2235 sdn_controller_list_parser.add_argument("name", nargs='?', help="name or uuid of the SDN controller")
2236 sdn_controller_list_parser.set_defaults(func=sdn_controller_list)
2238 # sdn_controller_delete
2239 sdn_controller_delete_parser = subparsers.add_parser('sdn-controller-delete',
2240 parents=[parent_parser],
2241 help="Delete the the SDN controller")
2242 sdn_controller_delete_parser.add_argument("name", help="name or uuid of the SDN controller")
2243 sdn_controller_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2244 sdn_controller_delete_parser.set_defaults(func=sdn_controller_delete)
2245 # =======================
2247 # WIM ======================= WIM section==================
2250 wim_create_parser = subparsers.add_parser('wim-create',
2251 parents=[parent_parser], help="creates a new wim")
2252 wim_create_parser.add_argument("name", action="store",
2253 help="name for the wim")
2254 wim_create_parser.add_argument("url", action="store",
2255 help="url for the wim")
2256 wim_create_parser.add_argument("--type", action="store",
2257 help="wim type: tapi, onos, dynpac or odl (default)")
2258 wim_create_parser.add_argument("--config", action="store",
2259 help="additional configuration in json/yaml format")
2260 wim_create_parser.add_argument("--description", action="store",
2261 help="description of the wim")
2262 wim_create_parser.set_defaults(func=wim_create)
2265 wim_delete_parser = subparsers.add_parser('wim-delete',
2266 parents=[parent_parser], help="deletes a wim from the catalogue")
2267 wim_delete_parser.add_argument("name", action="store",
2268 help="name or uuid of the wim to be deleted")
2269 wim_delete_parser.add_argument("-f", "--force", action="store_true",
2270 help="forces deletion without asking")
2271 wim_delete_parser.set_defaults(func=wim_delete)
2274 wim_edit_parser = subparsers.add_parser('wim-edit',
2275 parents=[parent_parser], help="edits a wim")
2276 wim_edit_parser.add_argument("name", help="name or uuid of the wim")
2277 wim_edit_parser.add_argument("--file",
2278 help="json/yaml text or file with the changes")\
2279 .completer = FilesCompleter
2280 wim_edit_parser.add_argument("-f", "--force", action="store_true",
2281 help="do not prompt for confirmation")
2282 wim_edit_parser.set_defaults(func=wim_edit)
2285 wim_list_parser = subparsers.add_parser('wim-list',
2286 parents=[parent_parser],
2287 help="lists information about registered wims")
2288 wim_list_parser.add_argument("name", nargs='?',
2289 help="name or uuid of the wim")
2290 wim_list_parser.add_argument("-a", "--all", action="store_true",
2291 help="shows all wims, not only wims attached to tenant")
2292 wim_list_parser.set_defaults(func=wim_list)
2294 # WIM account create
2295 wim_attach_parser = subparsers.add_parser('wim-account-create', parents=
2296 [parent_parser], help="associates a wim account to the operating tenant")
2297 wim_attach_parser.add_argument("name", help="name or uuid of the wim")
2298 wim_attach_parser.add_argument('--account-name', action='store',
2299 help="specify a name for the wim account.")
2300 wim_attach_parser.add_argument("--user", action="store",
2301 help="user credentials for the wim account")
2302 wim_attach_parser.add_argument("--password", action="store",
2303 help="password credentials for the wim account")
2304 wim_attach_parser.add_argument("--config", action="store",
2305 help="additional configuration in json/yaml format")
2306 wim_attach_parser.set_defaults(func=wim_account_create)
2308 # WIM account delete
2309 wim_detach_parser = subparsers.add_parser('wim-account-delete',
2310 parents=[parent_parser],
2311 help="removes the association "
2312 "between a wim account and the operating tenant")
2313 wim_detach_parser.add_argument("name", help="name or uuid of the wim")
2314 wim_detach_parser.add_argument("-a", "--all", action="store_true",
2315 help="removes all associations from this wim")
2316 wim_detach_parser.add_argument("-f", "--force", action="store_true",
2317 help="forces delete without asking")
2318 wim_detach_parser.set_defaults(func=wim_account_delete)
2321 wim_attach_edit_parser = subparsers.add_parser('wim-account-edit', parents=
2322 [parent_parser], help="modifies the association of a wim account to the operating tenant")
2323 wim_attach_edit_parser.add_argument("name", help="name or uuid of the wim")
2324 wim_attach_edit_parser.add_argument('--account-name', action='store',
2325 help="specify a name for the wim account.")
2326 wim_attach_edit_parser.add_argument("--user", action="store",
2327 help="user credentials for the wim account")
2328 wim_attach_edit_parser.add_argument("--password", action="store",
2329 help="password credentials for the wim account")
2330 wim_attach_edit_parser.add_argument("--config", action="store",
2331 help="additional configuration in json/yaml format")
2332 wim_attach_edit_parser.set_defaults(func=wim_account_edit)
2334 # WIM port mapping set
2335 wim_port_mapping_set_parser = subparsers.add_parser('wim-port-mapping-set',
2336 parents=[parent_parser],
2337 help="Load a file with the mappings "
2338 "of ports of a WAN switch that is "
2339 "connected to a PoP and the ports "
2340 "of the switch controlled by the PoP")
2341 wim_port_mapping_set_parser.add_argument("name", action="store",
2342 help="specifies the wim")
2343 wim_port_mapping_set_parser.add_argument("file",
2344 help="json/yaml text or file with the wim port mapping")\
2345 .completer = FilesCompleter
2346 wim_port_mapping_set_parser.add_argument("-f", "--force",
2347 action="store_true", help="forces overwriting without asking")
2348 wim_port_mapping_set_parser.set_defaults(func=wim_port_mapping_set)
2350 # WIM port mapping list
2351 wim_port_mapping_list_parser = subparsers.add_parser('wim-port-mapping-list',
2352 parents=[parent_parser], help="Show the port mappings for a wim")
2353 wim_port_mapping_list_parser.add_argument("name", action="store",
2354 help="specifies the wim")
2355 wim_port_mapping_list_parser.set_defaults(func=wim_port_mapping_list)
2357 # WIM port mapping clear
2358 wim_port_mapping_clear_parser = subparsers.add_parser('wim-port-mapping-clear',
2359 parents=[parent_parser], help="Clean the port mapping in a wim")
2360 wim_port_mapping_clear_parser.add_argument("name", action="store",
2361 help="specifies the wim")
2362 wim_port_mapping_clear_parser.add_argument("-f", "--force",
2363 action="store_true",
2364 help="forces clearing without asking")
2365 wim_port_mapping_clear_parser.set_defaults(func=wim_port_mapping_clear)
2367 # =======================================================
2369 action_dict={'net-update': 'retrieves external networks from datacenter',
2370 'net-edit': 'edits an external network',
2371 'net-delete': 'deletes an external network',
2372 'net-list': 'lists external networks from a datacenter'
2374 for item in action_dict:
2375 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
2376 datacenter_action_parser.add_argument("datacenter", help="name or uuid of the datacenter")
2377 if item=='net-edit' or item=='net-delete':
2378 datacenter_action_parser.add_argument("net", help="name or uuid of the datacenter net")
2379 if item=='net-edit':
2380 datacenter_action_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
2381 if item!='net-list':
2382 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2383 datacenter_action_parser.set_defaults(func=datacenter_net_action, action=item)
2386 action_dict={'netmap-import': 'create network senario netmap base on the datacenter networks',
2387 'netmap-create': 'create a new network senario netmap',
2388 'netmap-edit': 'edit name of a network senario netmap',
2389 'netmap-delete': 'deletes a network scenario netmap (--all for clearing all)',
2390 'netmap-list': 'list/show network scenario netmaps'
2392 for item in action_dict:
2393 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
2394 datacenter_action_parser.add_argument("--datacenter", help="name or uuid of the datacenter")
2395 #if item=='net-add':
2396 # datacenter_action_parser.add_argument("net", help="name of the network")
2397 if item=='netmap-delete':
2398 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to delete")
2399 datacenter_action_parser.add_argument("--all", action="store_true", help="delete all netmap of this datacenter")
2400 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2401 if item=='netmap-edit':
2402 datacenter_action_parser.add_argument("netmap", help="name or uuid of the datacenter netmap do edit")
2403 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file with the changes").completer = FilesCompleter
2404 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap")
2405 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
2406 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2407 if item=='netmap-list':
2408 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to show")
2409 if item=='netmap-create':
2410 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file descriptor with the changes").completer = FilesCompleter
2411 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap, by default same as vim-name")
2412 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
2413 datacenter_action_parser.add_argument('--vim-name', action='store', help="specify vim network name")
2414 if item=='netmap-import':
2415 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2416 datacenter_action_parser.set_defaults(func=datacenter_netmap_action, action=item)
2418 # =======================vim_net_sdn_xxx section=======================
2419 # vim_net_sdn_attach
2420 vim_net_sdn_attach_parser = subparsers.add_parser('vim-net-sdn-attach',
2421 parents=[parent_parser],
2422 help="Specify the port to access to an external network using SDN")
2423 vim_net_sdn_attach_parser.add_argument("vim_net", action="store",
2424 help="Name/id of the network in the vim that will be used to connect to the external network")
2425 vim_net_sdn_attach_parser.add_argument("port", action="store", help="Specifies the port in the dataplane switch to access to the external network")
2426 vim_net_sdn_attach_parser.add_argument("--vlan", action="store", help="Specifies the vlan (if any) to use in the defined port")
2427 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")
2428 vim_net_sdn_attach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2429 vim_net_sdn_attach_parser.set_defaults(func=vim_net_sdn_attach)
2431 # vim_net_sdn_detach
2432 vim_net_sdn_detach_parser = subparsers.add_parser('vim-net-sdn-detach',
2433 parents=[parent_parser],
2434 help="Remove the port information to access to an external network using SDN")
2436 vim_net_sdn_detach_parser.add_argument("vim_net", action="store", help="Name/id of the vim network")
2437 vim_net_sdn_detach_parser.add_argument("--id", action="store",help="Specify the uuid of the external ports from this network to be detached")
2438 vim_net_sdn_detach_parser.add_argument("--all", action="store_true", help="Detach all external ports from this network")
2439 vim_net_sdn_detach_parser.add_argument("-f", "--force", action="store_true", help="forces clearing without asking")
2440 vim_net_sdn_detach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2441 vim_net_sdn_detach_parser.set_defaults(func=vim_net_sdn_detach)
2442 # =======================
2444 for item in ("network", "tenant", "image"):
2446 command_name = 'vim-net'
2448 command_name = 'vim-'+item
2449 vim_item_list_parser = subparsers.add_parser(command_name + '-list', parents=[parent_parser], help="list the vim " + item + "s")
2450 vim_item_list_parser.add_argument("name", nargs='?', help="name or uuid of the " + item + "s")
2451 vim_item_list_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2452 vim_item_list_parser.set_defaults(func=vim_action, item=item, action="list")
2454 vim_item_del_parser = subparsers.add_parser(command_name + '-delete', parents=[parent_parser], help="list the vim " + item + "s")
2455 vim_item_del_parser.add_argument("name", help="name or uuid of the " + item + "s")
2456 vim_item_del_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2457 vim_item_del_parser.set_defaults(func=vim_action, item=item, action="delete")
2459 if item == "network" or item == "tenant":
2460 vim_item_create_parser = subparsers.add_parser(command_name + '-create', parents=[parent_parser], help="create a "+item+" at vim")
2461 vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the %s. Must be a file or yaml/json text" % item).completer = FilesCompleter
2462 vim_item_create_parser.add_argument("--name", action="store", help="name of the %s" % item )
2463 vim_item_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2465 vim_item_create_parser.add_argument("--type", action="store", help="type of network, data, ptp, bridge")
2466 vim_item_create_parser.add_argument("--shared", action="store_true", help="Private or shared")
2467 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>'")
2469 vim_item_create_parser.add_argument("--description", action="store", help="description of the %s" % item)
2470 vim_item_create_parser.set_defaults(func=vim_action, item=item, action="create")
2472 argcomplete.autocomplete(main_parser)
2475 args = main_parser.parse_args()
2477 level = logging.CRITICAL
2478 streamformat = "%(asctime)s %(name)s %(levelname)s: %(message)s"
2479 if "debug" in args and args.debug:
2480 level = logging.DEBUG
2481 logging.basicConfig(format=streamformat, level= level)
2482 logger = logging.getLogger('mano')
2483 logger.setLevel(level)
2484 result = args.func(args)
2487 #for some reason it fails if call exit inside try instance. Need to call exit at the end !?
2488 except (requests.exceptions.ConnectionError):
2489 print "Connection error: not possible to contact OPENMANO-SERVER (openmanod)"
2491 except (KeyboardInterrupt):
2492 print 'Exiting openmano'
2494 except (SystemExit, ArgumentParserError):
2496 except OpenmanoCLIError as e: