blob: 157765616208eb9376eae9a73a4d82b4d9480ba6 [file] [log] [blame]
tierno7edb6752016-03-21 17:37:52 +01001#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# PYTHON_ARGCOMPLETE_OK
4
5##
tierno92021022018-09-12 16:29:23 +02006# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
tierno7edb6752016-03-21 17:37:52 +01007# This file is part of openmano
8# All Rights Reserved.
9#
10# Licensed under the Apache License, Version 2.0 (the "License"); you may
11# not use this file except in compliance with the License. You may obtain
12# a copy of the License at
13#
14# http://www.apache.org/licenses/LICENSE-2.0
15#
16# Unless required by applicable law or agreed to in writing, software
17# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19# License for the specific language governing permissions and limitations
20# under the License.
21#
22# For those usages not covered by the Apache License, Version 2.0 please
23# contact with: nfvlabs@tid.es
24##
25
tierno20df3bb2017-07-07 14:31:00 +020026"""
Anderson Bravalheri0446cd52018-08-17 15:26:19 +010027openmano client used to interact with openmano-server (openmanod)
tierno20df3bb2017-07-07 14:31:00 +020028"""
tierno72a08d72017-05-25 13:12:30 +020029__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
30__date__ = "$09-oct-2014 09:09:48$"
tierno7fe82642018-11-26 14:14:51 +000031__version__ = "0.4.24-r534"
32version_date = "Nov 2018"
tierno7edb6752016-03-21 17:37:52 +010033
34from argcomplete.completers import FilesCompleter
35import os
36import argparse
37import argcomplete
38import requests
39import json
40import yaml
41import logging
42#from jsonschema import validate as js_v, exceptions as js_e
43
44class ArgumentParserError(Exception): pass
45
46class OpenmanoCLIError(Exception): pass
47
48class ThrowingArgumentParser(argparse.ArgumentParser):
49 def error(self, message):
50 print "Error: %s" %message
51 print
52 self.print_usage()
53 #self.print_help()
54 print
55 print "Type 'openmano -h' for help"
56 raise ArgumentParserError
57
58
59def config(args):
60 print "OPENMANO_HOST: %s" %mano_host
61 print "OPENMANO_PORT: %s" %mano_port
garciadeblas0e9fd832016-07-08 15:20:18 +020062 if args.n:
63 logger.debug("resolving tenant and datacenter names")
64 mano_tenant_id = "None"
65 mano_tenant_name = "None"
66 mano_datacenter_id = "None"
67 mano_datacenter_name = "None"
Anderson Bravalheri0446cd52018-08-17 15:26:19 +010068 # WIM additions
69 logger.debug("resolving WIM names")
70 mano_wim_id = "None"
71 mano_wim_name = "None"
garciadeblas0e9fd832016-07-08 15:20:18 +020072 try:
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"]
Anderson Bravalheri0446cd52018-08-17 15:26:19 +010086
87 # WIM
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"]
96
garciadeblas0e9fd832016-07-08 15:20:18 +020097 except OpenmanoCLIError:
98 pass
99 print "OPENMANO_TENANT: %s" %mano_tenant
100 print " Id: %s" %mano_tenant_id
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100101 print " Name: %s" %mano_tenant_name
garciadeblas0e9fd832016-07-08 15:20:18 +0200102 print "OPENMANO_DATACENTER: %s" %str (mano_datacenter)
103 print " Id: %s" %mano_datacenter_id
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100104 print " Name: %s" %mano_datacenter_name
105 # WIM
106 print "OPENMANO_WIM: %s" %str (mano_wim)
107 print " Id: %s" %mano_wim_id
108 print " Name: %s" %mano_wim_name
109
garciadeblas0e9fd832016-07-08 15:20:18 +0200110 else:
111 print "OPENMANO_TENANT: %s" %mano_tenant
112 print "OPENMANO_DATACENTER: %s" %str (mano_datacenter)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100113 # WIM
114 print "OPENMANO_WIM: %s" %str (mano_wim)
tierno7edb6752016-03-21 17:37:52 +0100115
116def _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"
121 print str(content)
122 return result
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100123
tierno7edb6752016-03-21 17:37:52 +0100124 val=content.values()[0]
125 if type(val)==str:
126 print val
127 return result
128 elif type(val) == list:
129 content_list = val
130 elif type(val)==dict:
131 content_list = [val]
132 else:
133 #print "Non expected dict/list format output"
134 print str(content)
135 return result
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100136
tierno7edb6752016-03-21 17:37:52 +0100137 #print content_list
138 if verbose_level==None:
139 verbose_level=0
140 if verbose_level >= 3:
141 print yaml.safe_dump(content, indent=4, default_flow_style=False)
142 return result
143
144 if mano_response.status_code == 200:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +0100145 uuid = None
tierno7edb6752016-03-21 17:37:52 +0100146 for content in content_list:
147 if "uuid" in content:
148 uuid = content['uuid']
149 elif "id" in content:
150 uuid = content['id']
151 elif "vim_id" in content:
152 uuid = content['vim_id']
tierno250954a2017-01-31 14:25:57 +0100153 name = content.get('name');
154 if not uuid:
155 uuid = ""
156 if not name:
157 name = ""
tiernoa15c4b92017-10-05 12:41:44 +0200158 myoutput = "{:38} {:20}".format(uuid, name)
tierno250954a2017-01-31 14:25:57 +0100159 if content.get("status"):
tiernoa15c4b92017-10-05 12:41:44 +0200160 myoutput += " {:20}".format(content['status'])
tierno7edb6752016-03-21 17:37:52 +0100161 elif "enabled" in content and not content["enabled"]:
162 myoutput += " enabled=False".ljust(20)
163 if verbose_level >=1:
tierno250954a2017-01-31 14:25:57 +0100164 if content.get('created_at'):
tiernoa15c4b92017-10-05 12:41:44 +0200165 myoutput += " {:20}".format(content['created_at'])
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +0200166 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)
tierno7edb6752016-03-21 17:37:52 +0100169 if verbose_level >=2:
170 new_line='\n'
tierno250954a2017-01-31 14:25:57 +0100171 if content.get('type'):
tiernoa15c4b92017-10-05 12:41:44 +0200172 myoutput += new_line + " Type: {:29}".format(content['type'])
tierno7edb6752016-03-21 17:37:52 +0100173 new_line=''
tierno250954a2017-01-31 14:25:57 +0100174 if content.get('description'):
tiernoa15c4b92017-10-05 12:41:44 +0200175 myoutput += new_line + " Description: {:20}".format(content['description'])
tierno7edb6752016-03-21 17:37:52 +0100176 print myoutput
177 else:
178 print content['error']['description']
179 return result
180
181def parser_json_yaml(file_name):
182 try:
183 f = file(file_name, "r")
184 text = f.read()
185 f.close()
186 except Exception as e:
187 return (False, str(e))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100188
tierno7edb6752016-03-21 17:37:52 +0100189 #Read and parse file
190 if file_name[-5:]=='.yaml' or file_name[-4:]=='.yml' or (file_name[-5:]!='.json' and '\t' not in text):
191 try:
192 config = yaml.load(text)
193 except yaml.YAMLError as exc:
194 error_pos = ""
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)
199 else: #json
200 try:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100201 config = json.loads(text)
tierno7edb6752016-03-21 17:37:52 +0100202 except Exception as e:
203 return (False, "Error loading file '"+file_name+"' json format error " + str(e) )
204
205 return True, config
206
207def _load_file_or_yaml(content):
208 '''
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
213 '''
214 #Check config file exists
215 if os.path.isfile(content):
216 r,payload = parser_json_yaml(content)
217 if not r:
218 print payload
219 exit(-1)
220 elif "{" in content or ":" in content:
221 try:
222 payload = yaml.load(content)
223 except yaml.YAMLError as exc:
224 error_pos = ""
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
229 exit (-1)
230 else:
231 print "'%s' is neither a valid file nor a yaml/json content" % content
232 exit(-1)
233 return payload
234
235def _get_item_uuid(item, item_name_id, tenant=None):
236 if tenant:
237 URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, tenant, item)
238 else:
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()
243 #print content
244 found = 0
245 for i in content[item]:
246 if i["uuid"] == item_name_id:
247 return item_name_id
248 if i["name"] == item_name_id:
249 uuid = i["uuid"]
250 found += 1
tiernof1ba57e2017-09-07 12:23:19 +0200251 if item_name_id.startswith("osm_id=") and i.get("osm_id") == item_name_id[7:]:
252 uuid = i["uuid"]
253 found += 1
tierno7edb6752016-03-21 17:37:52 +0100254 if found == 0:
255 raise OpenmanoCLIError("No %s found with name/uuid '%s'" %(item[:-1], item_name_id))
256 elif found > 1:
257 raise OpenmanoCLIError("%d %s found with name '%s'. uuid must be used" %(found, item, item_name_id))
258 return uuid
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100259#
tierno7edb6752016-03-21 17:37:52 +0100260# 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}$"}
262# try:
263# js_v(uuid, id_schema)
264# return True
265# except js_e.ValidationError:
266# return False
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100267
tierno7edb6752016-03-21 17:37:52 +0100268def _get_tenant(tenant_name_id = None):
269 if not tenant_name_id:
270 tenant_name_id = mano_tenant
271 if not mano_tenant:
272 raise OpenmanoCLIError("'OPENMANO_TENANT' environment variable is not set")
273 return _get_item_uuid("tenants", tenant_name_id)
274
275def _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)
281
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100282# WIM
283def _get_wim(wim_name_id = None, tenant = "any"):
284 if not wim_name_id:
285 wim_name_id = mano_wim
286 if not wim_name_id:
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)
289
tierno7edb6752016-03-21 17:37:52 +0100290def 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)
tiernof1ba57e2017-09-07 12:23:19 +0200295 api_version = ""
296 if "vnfd:vnfd-catalog" in myvnf or "vnfd-catalog" in myvnf:
297 api_version = "/v3"
298 token = "vnfd"
299 vnfd_catalog = myvnf.get("vnfd:vnfd-catalog")
300 if not vnfd_catalog:
301 vnfd_catalog = myvnf.get("vnfd-catalog")
302 vnfds = vnfd_catalog.get("vnfd:vnfd")
303 if not vnfds:
304 vnfds = vnfd_catalog.get("vnfd")
305 vnfd = vnfds[0]
gcalvino319b8a52018-11-05 15:33:23 +0100306 vdu_list = vnfd.get("vdu")
tiernof1ba57e2017-09-07 12:23:19 +0200307
308 else: # old API
309 api_version = ""
310 token = "vnfs"
311 vnfd = myvnf['vnf']
gcalvino319b8a52018-11-05 15:33:23 +0100312 vdu_list = vnfd.get("VNFC")
tierno7edb6752016-03-21 17:37:52 +0100313
garciadeblas14480452017-01-10 13:08:07 +0100314 if args.name or args.description or args.image_path or args.image_name or args.image_checksum:
tiernof1ba57e2017-09-07 12:23:19 +0200315 # TODO, change this for API v3
316 # print args.name
tierno7edb6752016-03-21 17:37:52 +0100317 try:
318 if args.name:
tiernof1ba57e2017-09-07 12:23:19 +0200319 vnfd['name'] = args.name
tierno7edb6752016-03-21 17:37:52 +0100320 if args.description:
tiernof1ba57e2017-09-07 12:23:19 +0200321 vnfd['description'] = args.description
gcalvino319b8a52018-11-05 15:33:23 +0100322 if vdu_list:
323 if args.image_path:
324 index = 0
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"]
336 else:
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"]
342 index += 1
343 if args.image_name: # image name precedes if both are supplied
344 index = 0
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"]
360 else:
361 vdu_list[index]['image name'] = image_name_
362 if "VNFC image" in vdu_list[index]:
363 del vdu_list[index]["VNFC image"]
364 index += 1
365 if args.image_checksum:
366 index = 0
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_
376 else:
377 vdu_list[index]['image checksum'] = image_checksum_
378 index += 1
tierno7edb6752016-03-21 17:37:52 +0100379 except (KeyError, TypeError), e:
tiernof1ba57e2017-09-07 12:23:19 +0200380 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']"
tierno7edb6752016-03-21 17:37:52 +0100388 else: error_pos="wrong format"
389 print "Wrong VNF descriptor: " + error_pos
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100390 return -1
tierno7edb6752016-03-21 17:37:52 +0100391 payload_req = json.dumps(myvnf)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100392
tierno7edb6752016-03-21 17:37:52 +0100393 #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100394
tiernof1ba57e2017-09-07 12:23:19 +0200395 URLrequest = "http://{}:{}/openmano{}/{}/{token}".format(mano_host, mano_port, api_version, tenant, token=token)
tierno7edb6752016-03-21 17:37:52 +0100396 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 )
399
400 return _print_verbose(mano_response, args.verbose)
401
402def vnf_list(args):
403 #print "vnf-list",args
404 if args.all:
405 tenant = "any"
406 else:
407 tenant = _get_tenant()
408 if args.name:
409 toshow = _get_item_uuid("vnfs", args.name, tenant)
410 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, toshow)
411 else:
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()
tiernof1ba57e2017-09-07 12:23:19 +0200416 # print json.dumps(content, indent=4)
tierno7edb6752016-03-21 17:37:52 +0100417 if args.verbose==None:
418 args.verbose=0
419 result = 0 if mano_response.status_code==200 else mano_response.status_code
420 if mano_response.status_code == 200:
421 if not args.name:
422 if args.verbose >= 3:
423 print yaml.safe_dump(content, indent=4, default_flow_style=False)
424 return result
425 if len(content['vnfs']) == 0:
426 print "No VNFs were found."
tiernof1ba57e2017-09-07 12:23:19 +0200427 return 404 # HTTP_Not_Found
tierno7edb6752016-03-21 17:37:52 +0100428 for vnf in content['vnfs']:
tiernof1ba57e2017-09-07 12:23:19 +0200429 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'])
434 print (myoutput)
435 if args.verbose >= 2:
436 print (" Description: {}".format(vnf['description']))
437 # print (" VNF descriptor file: {}".format(vnf['path']))
tierno7edb6752016-03-21 17:37:52 +0100438 else:
439 if args.verbose:
440 print yaml.safe_dump(content, indent=4, default_flow_style=False)
441 return result
442 vnf = content['vnf']
tiernof1ba57e2017-09-07 12:23:19 +0200443 print ("{:38} {:20} osm_id={:20} {:20}".format(vnf['uuid'], vnf['name'], vnf.get('osm_id'),
444 vnf['created_at']))
445 print (" Description: {}".format(vnf['description']))
446 # print " VNF descriptor file: %s" %vnf['path']
447 print (" VMs:")
tierno7edb6752016-03-21 17:37:52 +0100448 for vm in vnf['VNFC']:
tiernof1ba57e2017-09-07 12:23:19 +0200449 print (" {:20} osm_id={:20} {}".format(vm['name'], vm.get('osm_id'), vm['description']))
450 if len(vnf['nets']) > 0:
451 print (" Internal nets:")
tierno7edb6752016-03-21 17:37:52 +0100452 for net in vnf['nets']:
tiernof1ba57e2017-09-07 12:23:19 +0200453 print (" {:20} {}".format(net['name'], net['description']))
454 if len(vnf['external-connections']) > 0:
455 print (" External interfaces:")
tierno7edb6752016-03-21 17:37:52 +0100456 for interface in vnf['external-connections']:
tiernof1ba57e2017-09-07 12:23:19 +0200457 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 ""))
tierno7edb6752016-03-21 17:37:52 +0100461 else:
462 print content['error']['description']
463 if args.verbose:
464 print yaml.safe_dump(content, indent=4, default_flow_style=False)
465 return result
466
467def vnf_delete(args):
468 #print "vnf-delete",args
469 if args.all:
470 tenant = "any"
471 else:
472 tenant = _get_tenant()
473 todelete = _get_item_uuid("vnfs", args.name, tenant=tenant)
474 if not args.force:
475 r = raw_input("Delete VNF %s (y/N)? " %(todelete))
476 if not (len(r)>0 and r[0].lower()=="y"):
477 return 0
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']
486 else:
487 print content['error']['description']
488 return result
489
490def scenario_create(args):
tiernof1ba57e2017-09-07 12:23:19 +0200491 # print "scenario-create",args
tierno7edb6752016-03-21 17:37:52 +0100492 tenant = _get_tenant()
493 headers_req = {'content-type': 'application/yaml'}
494 myscenario = _load_file_or_yaml(args.file)
tiernof1ba57e2017-09-07 12:23:19 +0200495 if "nsd:nsd-catalog" in myscenario or "nsd-catalog" in myscenario:
496 api_version = "/v3"
497 token = "nsd"
498 nsd_catalog = myscenario.get("nsd:nsd-catalog")
499 if not nsd_catalog:
500 nsd_catalog = myscenario.get("nsd-catalog")
501 nsds = nsd_catalog.get("nsd:nsd")
502 if not nsds:
503 nsds = nsd_catalog.get("nsd")
504 nsd = nsds[0]
505 else: # API<v3
506 api_version = ""
507 token = "scenarios"
508 if "scenario" in myscenario:
509 nsd = myscenario["scenario"]
510 else:
511 nsd = myscenario
512 # TODO modify for API v3
tierno7edb6752016-03-21 17:37:52 +0100513 if args.name:
tiernof1ba57e2017-09-07 12:23:19 +0200514 nsd['name'] = args.name
tierno7edb6752016-03-21 17:37:52 +0100515 if args.description:
tiernof1ba57e2017-09-07 12:23:19 +0200516 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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100519
tiernof1ba57e2017-09-07 12:23:19 +0200520 # print payload_req
521 URLrequest = "http://{host}:{port}/openmano{api}/{tenant}/{token}".format(
522 host=mano_host, port=mano_port, api=api_version, tenant=tenant, token=token)
tierno7edb6752016-03-21 17:37:52 +0100523 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)
527
528def scenario_list(args):
529 #print "scenario-list",args
530 if args.all:
531 tenant = "any"
532 else:
533 tenant = _get_tenant()
534 if args.name:
535 toshow = _get_item_uuid("scenarios", args.name, tenant)
536 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, toshow)
537 else:
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:
544 args.verbose=0
545
546 result = 0 if mano_response.status_code==200 else mano_response.status_code
547 if mano_response.status_code == 200:
548 if not args.name:
549 if args.verbose >= 3:
550 print yaml.safe_dump(content, indent=4, default_flow_style=False)
551 return result
552 if len(content['scenarios']) == 0:
553 print "No scenarios were found."
554 return 404 #HTTP_Not_Found
555 for scenario in content['scenarios']:
tiernof1ba57e2017-09-07 12:23:19 +0200556 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'])
561 print (myoutput)
tierno7edb6752016-03-21 17:37:52 +0100562 if args.verbose >=2:
tiernof1ba57e2017-09-07 12:23:19 +0200563 print (" Description: {}".format(scenario['description']))
tierno7edb6752016-03-21 17:37:52 +0100564 else:
565 if args.verbose:
566 print yaml.safe_dump(content, indent=4, default_flow_style=False)
567 return result
568 scenario = content['scenario']
tiernof1ba57e2017-09-07 12:23:19 +0200569 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']))
572 print (" VNFs:")
tierno7edb6752016-03-21 17:37:52 +0100573 for vnf in scenario['vnfs']:
tiernof1ba57e2017-09-07 12:23:19 +0200574 print (" {:38} {:20} vnf_index={} {}".format(vnf['vnf_id'], vnf['name'], vnf.get("member_vnf_index"),
575 vnf['description']))
576 if len(scenario['nets']) > 0:
577 print (" nets:")
tierno7edb6752016-03-21 17:37:52 +0100578 for net in scenario['nets']:
tiernof1ba57e2017-09-07 12:23:19 +0200579 description = net['description']
580 if not description: # if description does not exist, description is "-". Valid for external and internal nets.
581 description = '-'
582 vim_id = ""
583 if net.get('vim_id'):
584 vim_id = " vim_id=" + net["vim_id"]
585 external = ""
586 if net["external"]:
587 external = " external"
588 print (" {:20} {:38} {:30}{}{}".format(net['name'], net['uuid'], description, vim_id, external))
tierno7edb6752016-03-21 17:37:52 +0100589 else:
tiernof1ba57e2017-09-07 12:23:19 +0200590 print (content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100591 if args.verbose:
592 print yaml.safe_dump(content, indent=4, default_flow_style=False)
593 return result
594
595def scenario_delete(args):
596 #print "scenario-delete",args
597 if args.all:
598 tenant = "any"
599 else:
600 tenant = _get_tenant()
601 todelete = _get_item_uuid("scenarios", args.name, tenant=tenant)
602 if not args.force:
603 r = raw_input("Delete scenario %s (y/N)? " %(args.name))
604 if not (len(r)>0 and r[0].lower()=="y"):
605 return 0
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']
614 else:
615 print content['error']['description']
616 return result
617
618def scenario_deploy(args):
619 print "This command is deprecated, use 'openmano instance-scenario-create --scenario %s --name %s' instead!!!" % (args.scenario, args.name)
620 print
621 args.file = None
622 args.netmap_use = None
623 args.netmap_create = None
tiernobe41e222016-09-02 15:16:13 +0200624 args.keypair = None
625 args.keypair_auto = None
tierno7edb6752016-03-21 17:37:52 +0100626 return instance_create(args)
627
628# #print "scenario-deploy",args
629# headers_req = {'content-type': 'application/json'}
630# action = {}
631# actionCmd="start"
632# if args.nostart:
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
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100640#
tierno7edb6752016-03-21 17:37:52 +0100641# if args.description:
642# action[actionCmd]["description"] = args.description
643# payload_req = json.dumps(action, indent=4)
644# #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100645#
tierno7edb6752016-03-21 17:37:52 +0100646# 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:
651# args.verbose=0
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100652#
tierno7edb6752016-03-21 17:37:52 +0100653# 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)
658# return result
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100659#
tierno7edb6752016-03-21 17:37:52 +0100660# 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))
666# print myoutput
667# print ""
668# print "To check the status, run the following command:"
669# print "openmano instance-scenario-list <instance_id>"
670# else:
671# print content['error']['description']
672# return result
673
674def scenario_verify(args):
675 #print "scenario-verify",args
tierno72a08d72017-05-25 13:12:30 +0200676 tenant = _get_tenant()
tierno7edb6752016-03-21 17:37:52 +0100677 headers_req = {'content-type': 'application/json'}
678 action = {}
679 action["verify"] = {}
680 action["verify"]["instance_name"] = "scen-verify-return5"
681 payload_req = json.dumps(action, indent=4)
682 #print payload_req
683
tierno72a08d72017-05-25 13:12:30 +0200684 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, tenant, args.scenario)
tierno7edb6752016-03-21 17:37:52 +0100685 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 )
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100688
tierno7edb6752016-03-21 17:37:52 +0100689 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']
694 else:
695 print content['error']['description']
696 return result
697
698def instance_create(args):
699 tenant = _get_tenant()
700 headers_req = {'content-type': 'application/yaml'}
701 myInstance={"instance": {}, "schema_version": "0.1"}
702 if args.file:
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"}
706 else:
707 myInstance = instance_dict
708 if args.name:
709 myInstance["instance"]['name'] = args.name
710 if args.description:
711 myInstance["instance"]['description'] = args.description
712 if args.nostart:
713 myInstance["instance"]['action'] = "reserve"
714 #datacenter
715 datacenter = myInstance["instance"].get("datacenter")
716 if args.datacenter != None:
717 datacenter = args.datacenter
718 myInstance["instance"]["datacenter"] = _get_datacenter(datacenter, tenant)
719 #scenario
720 scenario = myInstance["instance"].get("scenario")
721 if args.scenario != None:
722 scenario = args.scenario
723 if not scenario:
garciadeblased746032017-01-05 11:58:41 +0100724 print "you must provide a scenario in the file descriptor or with --scenario"
tierno7edb6752016-03-21 17:37:52 +0100725 return -1
tierno7fe82642018-11-26 14:14:51 +0000726 if isinstance(scenario, str):
727 myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant)
tierno7edb6752016-03-21 17:37:52 +0100728 if args.netmap_use:
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
737 return
738 net_scenario = net_tuple[0].strip()
739 net_datacenter = net_tuple[1].strip()
740 if net_scenario not in myInstance["instance"]["networks"]:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100741 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200742 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
tierno7edb6752016-03-21 17:37:52 +0100745 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()
758 else:
759 print "error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. (%s)?" % net_comma
760 return
761 if net_scenario not in myInstance["instance"]["networks"]:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100762 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200763 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
tiernoa4e1a6e2016-08-31 14:19:40 +0200766 if args.keypair:
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(":")
772 if index<0:
773 if "key-pairs" not in cloud_config:
774 cloud_config["key-pairs"] = []
775 cloud_config["key-pairs"].append(key)
776 else:
777 user = key[:index]
778 key_ = key[index+1:]
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:
784 try:
785 keys=[]
786 home = os.getenv("HOME")
787 user = os.getenv("USER")
788 files = os.listdir(home+'/.ssh')
789 for file in files:
790 if file[-4:] == ".pub":
791 with open(home+'/.ssh/'+file, 'r') as f:
792 keys.append(f.read())
793 if not keys:
794 print "Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh')
795 return 1
796 except Exception as e:
797 print "Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e))
798 return 1
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100799
tiernoa4e1a6e2016-08-31 14:19:40 +0200800 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"] = []
805 if user:
806 if "users" not in cloud_config:
807 cloud_config["users"] = []
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100808 cloud_config["users"].append({"name": user, "key-pairs": keys })
809
tierno7edb6752016-03-21 17:37:52 +0100810 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:
816 args.verbose=0
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100817
tierno7edb6752016-03-21 17:37:52 +0100818 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)
823 return result
824
825 if mano_response.status_code == 200:
tiernoa15c4b92017-10-05 12:41:44 +0200826 myoutput = "{:38} {:20}".format(content['uuid'], content['name'])
tierno7edb6752016-03-21 17:37:52 +0100827 if args.verbose >=1:
tiernoa15c4b92017-10-05 12:41:44 +0200828 myoutput = "{} {:20}".format(myoutput, content['created_at'])
tierno7edb6752016-03-21 17:37:52 +0100829 if args.verbose >=2:
tiernoa15c4b92017-10-05 12:41:44 +0200830 myoutput = "{} {:30}".format(myoutput, content['description'])
tierno7edb6752016-03-21 17:37:52 +0100831 print myoutput
832 else:
833 print content['error']['description']
834 return result
835
836def instance_scenario_list(args):
837 #print "instance-scenario-list",args
838 if args.all:
839 tenant = "any"
840 else:
841 tenant = _get_tenant()
842 if args.name:
843 toshow = _get_item_uuid("instances", args.name, tenant)
844 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, toshow)
845 else:
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:
852 args.verbose=0
853
854 result = 0 if mano_response.status_code==200 else mano_response.status_code
855 if mano_response.status_code == 200:
856 if not args.name:
857 if args.verbose >= 3:
858 print yaml.safe_dump(content, indent=4, default_flow_style=False)
859 return result
860 if len(content['instances']) == 0:
861 print "No scenario instances were found."
862 return result
863 for instance in content['instances']:
tiernoa15c4b92017-10-05 12:41:44 +0200864 myoutput = "{:38} {:20}".format(instance['uuid'], instance['name'])
tierno7edb6752016-03-21 17:37:52 +0100865 if args.verbose >=1:
tiernoa15c4b92017-10-05 12:41:44 +0200866 myoutput = "{} {:20}".format(myoutput, instance['created_at'])
tierno7edb6752016-03-21 17:37:52 +0100867 print myoutput
868 if args.verbose >=2:
869 print "Description: %s" %instance['description']
870 else:
871 if args.verbose:
872 print yaml.safe_dump(content, indent=4, default_flow_style=False)
873 return result
874 instance = content
tiernoa15c4b92017-10-05 12:41:44 +0200875 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'])))
tierno7edb6752016-03-21 17:37:52 +0100881 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))
tiernoa15c4b92017-10-05 12:41:44 +0200883 print (" {:38} {:20} Template vnf id: {:38}".format(vnf['uuid'], vnf['vnf_name'], vnf['vnf_id']))
tierno7edb6752016-03-21 17:37:52 +0100884 if len(instance['nets'])>0:
885 print "---------------------------------------"
886 print "Internal nets:"
887 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000888 if net['created']:
tiernoa15c4b92017-10-05 12:41:44 +0200889 print (" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
tierno7edb6752016-03-21 17:37:52 +0100890 print "---------------------------------------"
891 print "External nets:"
892 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000893 if not net['created']:
tiernoa15c4b92017-10-05 12:41:44 +0200894 print (" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
895 print ("---------------------------------------")
896 print ("VM instances:")
tierno7edb6752016-03-21 17:37:52 +0100897 for vnf in instance['vnfs']:
898 for vm in vnf['vms']:
tiernoa15c4b92017-10-05 12:41:44 +0200899 print (" {:38} {:20} {:20} {:12} VIM ID: {}".format(vm['uuid'], vnf['vnf_name'], vm['name'],
900 vm['status'], vm['vim_vm_id']))
tierno7edb6752016-03-21 17:37:52 +0100901 else:
902 print content['error']['description']
903 if args.verbose:
904 print yaml.safe_dump(content, indent=4, default_flow_style=False)
905 return result
906
907def instance_scenario_status(args):
908 print "instance-scenario-status"
909 return 0
910
911def instance_scenario_delete(args):
912 if args.all:
913 tenant = "any"
914 else:
915 tenant = _get_tenant()
916 todelete = _get_item_uuid("instances", args.name, tenant=tenant)
917 #print "instance-scenario-delete",args
918 if not args.force:
919 r = raw_input("Delete scenario instance %s (y/N)? " %(args.name))
920 if not (len(r)>0 and r[0].lower()=="y"):
921 return
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']
930 else:
931 print content['error']['description']
932 return result
933
tierno868220c2017-09-26 00:11:05 +0200934def get_action(args):
935 if not args.all:
936 tenant = _get_tenant()
937 else:
938 tenant = "any"
939 if not args.instance:
940 instance_id = "any"
941 else:
942 instance_id =args.instance
943 action_id = ""
944 if args.id:
945 action_id = "/" + args.id
946 URLrequest = "http://{}:{}/openmano/{}/instances/{}/action{}".format(mano_host, mano_port, tenant, instance_id,
947 action_id)
948 mano_response = requests.get(URLrequest)
949 logger.debug("openmano response: %s", mano_response.text )
950 if args.verbose == None:
951 args.verbose = 0
952 if args.id != None:
953 args.verbose += 1
954 return _print_verbose(mano_response, args.verbose)
955
tierno7edb6752016-03-21 17:37:52 +0100956def instance_scenario_action(args):
957 #print "instance-scenario-action", args
958 tenant = _get_tenant()
959 toact = _get_item_uuid("instances", args.name, tenant=tenant)
960 action={}
tiernofc5f80b2018-05-29 16:00:43 +0200961 action[ args.action ] = yaml.safe_load(args.param)
tierno7edb6752016-03-21 17:37:52 +0100962 if args.vnf:
963 action["vnfs"] = args.vnf
964 if args.vm:
965 action["vms"] = args.vm
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100966
tierno7edb6752016-03-21 17:37:52 +0100967 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()
tiernofc5f80b2018-05-29 16:00:43 +0200975 # print json.dumps(content, indent=4)
tierno7edb6752016-03-21 17:37:52 +0100976 if mano_response.status_code == 200:
977 if args.verbose:
978 print yaml.safe_dump(content, indent=4, default_flow_style=False)
979 return result
tiernofc5f80b2018-05-29 16:00:43 +0200980 if "instance_action_id" in content:
981 print("instance_action_id={}".format(content["instance_action_id"]))
982 else:
983 for uuid,c in content.iteritems():
984 print ("{:38} {:20} {:20}".format(uuid, c.get('name'), c.get('description')))
tierno7edb6752016-03-21 17:37:52 +0100985 else:
986 print content['error']['description']
987 return result
988
989
990def instance_vnf_list(args):
991 print "instance-vnf-list"
992 return 0
993
994def instance_vnf_status(args):
995 print "instance-vnf-status"
996 return 0
997
998def tenant_create(args):
999 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1000 tenant_dict={"name": args.name}
1001 if args.description!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001002 tenant_dict["description"] = args.description
tierno7edb6752016-03-21 17:37:52 +01001003 payload_req = json.dumps( {"tenant": tenant_dict })
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001004
tierno7edb6752016-03-21 17:37:52 +01001005 #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001006
tierno7edb6752016-03-21 17:37:52 +01001007 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)
1012
1013def tenant_list(args):
1014 #print "tenant-list",args
1015 if args.name:
tierno392f2852016-05-13 12:28:55 +02001016 toshow = _get_item_uuid("tenants", args.name)
tierno7edb6752016-03-21 17:37:52 +01001017 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, toshow)
1018 else:
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:
1023 args.verbose=0
1024 if args.name!=None:
1025 args.verbose += 1
1026 return _print_verbose(mano_response, args.verbose)
1027
1028def tenant_delete(args):
1029 #print "tenant-delete",args
1030 todelete = _get_item_uuid("tenants", args.name)
1031 if not args.force:
1032 r = raw_input("Delete tenant %s (y/N)? " %(args.name))
1033 if not (len(r)>0 and r[0].lower()=="y"):
1034 return 0
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']
1043 else:
1044 print content['error']['description']
1045 return result
1046
1047def datacenter_attach(args):
1048 tenant = _get_tenant()
1049 datacenter = _get_datacenter(args.name)
1050 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001051
tierno7edb6752016-03-21 17:37:52 +01001052 datacenter_dict={}
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
tierno8008c3a2016-10-13 15:34:28 +00001061 if args.config!=None:
1062 datacenter_dict["config"] = _load_file_or_yaml(args.config)
gcalvinoc62cfa52017-10-05 18:21:25 +02001063
tierno7edb6752016-03-21 17:37:52 +01001064 payload_req = json.dumps( {"datacenter": datacenter_dict })
gcalvinoc62cfa52017-10-05 18:21:25 +02001065
tierno7edb6752016-03-21 17:37:52 +01001066 #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001067
tierno7edb6752016-03-21 17:37:52 +01001068 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"
1079 return result
1080
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001081
1082def 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'}
1086
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.")
1089
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})
1102
1103 # print payload_req
1104
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)
1110
1111 return result
1112
tierno7edb6752016-03-21 17:37:52 +01001113def datacenter_detach(args):
1114 if args.all:
1115 tenant = "any"
1116 else:
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']
1128 else:
1129 print content['error']['description']
1130 return result
1131
1132def 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:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001136 datacenter_dict["description"] = args.description
tierno7edb6752016-03-21 17:37:52 +01001137 if args.type!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001138 datacenter_dict["type"] = args.type
tierno7edb6752016-03-21 17:37:52 +01001139 if args.url!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001140 datacenter_dict["vim_url_admin"] = args.url_admin
tierno7edb6752016-03-21 17:37:52 +01001141 if args.config!=None:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001142 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
tierno7edb6752016-03-21 17:37:52 +01001149 payload_req = json.dumps( {"datacenter": datacenter_dict })
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001150
tierno7edb6752016-03-21 17:37:52 +01001151 #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001152
tierno7edb6752016-03-21 17:37:52 +01001153 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)
1158
1159def datacenter_delete(args):
1160 #print "datacenter-delete",args
1161 todelete = _get_item_uuid("datacenters", args.name, "any")
1162 if not args.force:
1163 r = raw_input("Delete datacenter %s (y/N)? " %(args.name))
1164 if not (len(r)>0 and r[0].lower()=="y"):
1165 return 0
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']
1174 else:
1175 print content['error']['description']
1176 return result
1177
tierno20df3bb2017-07-07 14:31:00 +02001178
tierno7edb6752016-03-21 17:37:52 +01001179def datacenter_list(args):
1180 #print "datacenter-list",args
1181 tenant='any' if args.all else _get_tenant()
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001182
tierno7edb6752016-03-21 17:37:52 +01001183 if args.name:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001184 toshow = _get_item_uuid("datacenters", args.name, tenant)
tierno7edb6752016-03-21 17:37:52 +01001185 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, toshow)
1186 else:
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:
1191 args.verbose=0
1192 if args.name!=None:
1193 args.verbose += 1
1194 return _print_verbose(mano_response, args.verbose)
1195
tierno20df3bb2017-07-07 14:31:00 +02001196
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001197def 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'}
1201
1202 if not args.file:
1203 raise OpenmanoCLIError(
1204 "No yaml/json has been provided specifying the SDN port mapping")
tierno20df3bb2017-07-07 14:31:00 +02001205 sdn_port_mapping = _load_file_or_yaml(args.file)
1206 payload_req = json.dumps({"sdn_port_mapping": sdn_port_mapping})
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001207
tierno20df3bb2017-07-07 14:31:00 +02001208 # read
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())
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001215 raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001216 if len(port_mapping["sdn_port_mapping"]["ports_mapping"]) > 0:
1217 if not args.force:
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"):
1220 return 0
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001221
tierno20df3bb2017-07-07 14:31:00 +02001222 # clear
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)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001228
tierno20df3bb2017-07-07 14:31:00 +02001229 # set
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001230 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)
tierno20df3bb2017-07-07 14:31:00 +02001234 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001235
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001236
1237def datacenter_sdn_port_mapping_list(args):
1238 tenant = _get_tenant()
1239 datacenter = _get_datacenter(args.name, tenant)
1240
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)
1244
tierno20df3bb2017-07-07 14:31:00 +02001245 return _print_verbose(mano_response, 4)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001246
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001247
1248def datacenter_sdn_port_mapping_clear(args):
1249 tenant = _get_tenant()
1250 datacenter = _get_datacenter(args.name, tenant)
1251
1252 if not args.force:
1253 r = raw_input("Clean SDN port mapping for datacenter %s (y/N)? " %(datacenter))
tierno20df3bb2017-07-07 14:31:00 +02001254 if not (len(r) > 0 and r[0].lower() == "y"):
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001255 return 0
1256
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)
1260
tierno20df3bb2017-07-07 14:31:00 +02001261 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001262
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001263
1264def sdn_controller_create(args):
1265 tenant = _get_tenant()
1266 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1267
tierno8fe7a492017-07-11 13:50:04 +02001268 error_msg=[]
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'")
1273 if error_msg:
1274 raise OpenmanoCLIError("The following arguments are required: " + ",".join(error_msg))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001275
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
1288
1289 payload_req = json.dumps({"sdn_controller": controller_dict})
1290
1291 # print payload_req
1292
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)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001298 return result
1299
tierno20df3bb2017-07-07 14:31:00 +02001300
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001301def 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'}
1305
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001306 controller_dict = {}
tierno20df3bb2017-07-07 14:31:00 +02001307 if args.new_name:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001308 controller_dict['name'] = args.new_name
tierno20df3bb2017-07-07 14:31:00 +02001309 if args.ip:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001310 controller_dict['ip'] = args.ip
tierno20df3bb2017-07-07 14:31:00 +02001311 if args.port:
Pablo Montes Morenob12711f2017-04-06 11:54:34 +02001312 controller_dict['port'] = int(args.port)
tierno20df3bb2017-07-07 14:31:00 +02001313 if args.dpid:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001314 controller_dict['dpid'] = args.dpid
tierno20df3bb2017-07-07 14:31:00 +02001315 if args.type:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001316 controller_dict['type'] = args.type
tierno20df3bb2017-07-07 14:31:00 +02001317 if args.description:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001318 controller_dict['description'] = args.description
tierno20df3bb2017-07-07 14:31:00 +02001319 if args.user:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001320 controller_dict['user'] = args.user
tierno20df3bb2017-07-07 14:31:00 +02001321 if args.password:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001322 controller_dict['password'] = args.password
1323
tierno20df3bb2017-07-07 14:31:00 +02001324 if not controller_dict:
1325 raise OpenmanoCLIError("At least one parameter must be edited")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001326
tierno20df3bb2017-07-07 14:31:00 +02001327 if not args.force:
1328 r = raw_input("Update SDN controller {} (y/N)? ".format(args.name))
1329 if not (len(r) > 0 and r[0].lower() == "y"):
1330 return 0
1331
1332 payload_req = json.dumps({"sdn_controller": controller_dict})
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001333 # print payload_req
1334
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)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001340 return result
1341
tierno20df3bb2017-07-07 14:31:00 +02001342
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001343def sdn_controller_list(args):
1344 tenant = _get_tenant()
1345 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1346
1347 if args.name:
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)
1350 else:
1351 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" %(mano_host, mano_port, tenant)
1352 #print URLrequest
1353 mano_response = requests.get(URLrequest)
1354 logger.debug("openmano response: %s", mano_response.text )
1355 if args.verbose==None:
1356 args.verbose=0
1357 if args.name!=None:
1358 args.verbose += 1
1359
tierno20df3bb2017-07-07 14:31:00 +02001360 # json.dumps(mano_response.json(), indent=4)
1361 return _print_verbose(mano_response, args.verbose)
1362
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001363
1364def sdn_controller_delete(args):
1365 tenant = _get_tenant()
1366 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1367
1368 if not args.force:
1369 r = raw_input("Delete SDN controller %s (y/N)? " % (args.name))
1370 if not (len(r) > 0 and r[0].lower() == "y"):
1371 return 0
1372
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)
tierno20df3bb2017-07-07 14:31:00 +02001376 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001377
tierno7edb6752016-03-21 17:37:52 +01001378def 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:
1383 args.verbose=0
1384 if args.action=="list":
1385 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
1386 if args.name!=None:
1387 args.verbose += 1
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']
1401 else:
1402 print content['error']['description']
1403 return result
1404 elif args.action=="create":
1405 headers_req = {'content-type': 'application/yaml'}
1406 if args.file:
1407 create_dict = _load_file_or_yaml(args.file)
1408 if args.item not in create_dict:
1409 create_dict = {args.item: create_dict}
1410 else:
1411 create_dict = {args.item:{}}
1412 if args.name:
1413 create_dict[args.item]['name'] = args.name
1414 #if args.description:
1415 # create_dict[args.item]['description'] = args.description
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001416 if args.item=="network":
tierno7edb6752016-03-21 17:37:52 +01001417 if args.bind_net:
1418 create_dict[args.item]['bind_net'] = args.bind_net
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001419 if args.type:
1420 create_dict[args.item]['type'] = args.type
tierno7edb6752016-03-21 17:37:52 +01001421 if args.shared:
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"
1425 return
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)
tierno72a08d72017-05-25 13:12:30 +02001428 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
tierno7edb6752016-03-21 17:37:52 +01001429 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:
1432 args.verbose=0
1433 return _print_verbose(mano_response, args.verbose)
1434
tierno20df3bb2017-07-07 14:31:00 +02001435
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001436def _get_items(item, item_name_id=None, datacenter=None, tenant=None):
1437 URLrequest = "http://%s:%s/openmano" %(mano_host, mano_port)
1438 if tenant:
1439 URLrequest += "/" + tenant
1440 if datacenter:
1441 URLrequest += "/vim/" + datacenter
1442 if item:
1443 URLrequest += "/" + item +"s"
1444 if item_name_id:
1445 URLrequest += "/" + item_name_id
1446 mano_response = requests.get(URLrequest)
1447 logger.debug("openmano response: %s", mano_response.text )
1448
1449 return mano_response
1450
tierno20df3bb2017-07-07 14:31:00 +02001451
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001452def 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']
1463
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}
1467 if args.vlan:
1468 payload_req['vlan'] = int(args.vlan)
1469 if args.mac:
1470 payload_req['mac'] = args.mac
1471
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)
tierno20df3bb2017-07-07 14:31:00 +02001477 return result
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001478
1479
1480def vim_net_sdn_detach(args):
1481 if not args.all and not args.id:
1482 print "--all or --id must be used"
1483 return 1
1484
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']
1495
1496 if not args.force:
1497 r = raw_input("Confirm action' (y/N)? ")
1498 if len(r) == 0 or r[0].lower() != "y":
1499 return 0
1500
1501 if args.id:
1502 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach/%s" % (
1503 mano_host, mano_port, tenant, datacenter, network_uuid, args.id)
1504 else:
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)
tierno20df3bb2017-07-07 14:31:00 +02001510 return result
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001511
tierno7edb6752016-03-21 17:37:52 +01001512
1513def datacenter_net_action(args):
1514 if args.action == "net-update":
tierno5acf7202016-08-29 14:28:13 +02001515 print "This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano datacenter-netmap-import' instead!!!"
tierno7edb6752016-03-21 17:37:52 +01001516 print
1517 args.action = "netmap-delete"
1518 args.netmap = None
1519 args.all = True
1520 r = datacenter_netmap_action(args)
1521 if r == 0:
1522 args.force = True
tierno5acf7202016-08-29 14:28:13 +02001523 args.action = "netmap-import"
tierno7edb6752016-03-21 17:37:52 +01001524 r = datacenter_netmap_action(args)
1525 return r
1526
1527 if args.action == "net-edit":
1528 args.netmap = args.net
1529 args.name = None
1530 elif args.action == "net-list":
1531 args.netmap = None
1532 elif args.action == "net-delete":
1533 args.netmap = args.net
1534 args.all = False
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001535
tierno7edb6752016-03-21 17:37:52 +01001536 args.action = "netmap" + args.action[3:]
1537 args.vim_name=None
1538 args.vim_id=None
1539 print "This command is deprecated, use 'openmano datacenter-%s' instead!!!" % args.action
1540 print
1541 return datacenter_netmap_action(args)
1542
1543def datacenter_netmap_action(args):
1544 tenant = _get_tenant()
1545 datacenter = _get_datacenter(args.datacenter, tenant)
1546 #print "datacenter_netmap_action",args
1547 payload_req = None
1548 if args.verbose==None:
1549 args.verbose=0
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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001552
tierno7edb6752016-03-21 17:37:52 +01001553 if args.action=="netmap-list":
1554 if args.netmap:
1555 URLrequest += "/" + args.netmap
1556 args.verbose += 1
1557 mano_response = requests.get(URLrequest)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001558
tierno7edb6752016-03-21 17:37:52 +01001559 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"
1562 return 1
1563 if args.netmap:
1564 force_text= "Delete default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter)
1565 URLrequest += "/" + args.netmap
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001566 elif args.all:
tierno7edb6752016-03-21 17:37:52 +01001567 force_text="Delete all default netmaps from datacenter '%s' (y/N)? " % (datacenter)
1568 else:
tiernoae4a8d12016-07-08 12:30:39 +02001569 print "you must specify a netmap name or the option --all"
tierno7edb6752016-03-21 17:37:52 +01001570 return 1
1571 if not args.force:
1572 r = raw_input(force_text)
1573 if len(r)>0 and r[0].lower()=="y":
1574 pass
1575 else:
1576 return 0
1577 mano_response = requests.delete(URLrequest, headers=headers_req)
tierno5acf7202016-08-29 14:28:13 +02001578 elif args.action=="netmap-import":
tierno7edb6752016-03-21 17:37:52 +01001579 if not args.force:
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":
1582 pass
1583 else:
1584 return 0
1585 URLrequest += "/upload"
1586 mano_response = requests.post(URLrequest, headers=headers_req)
1587 elif args.action=="netmap-edit" or args.action=="netmap-create":
1588 if args.file:
1589 payload = _load_file_or_yaml(args.file)
1590 else:
1591 payload = {}
1592 if "netmap" not in payload:
1593 payload = {"netmap": payload}
1594 if args.name:
1595 payload["netmap"]["name"] = args.name
1596 if args.vim_id:
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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001602
tierno7edb6752016-03-21 17:37:52 +01001603 if args.action=="netmap-edit" and not args.force:
1604 if len(payload["netmap"]) == 0:
1605 print "You must supply some parameter to edit"
1606 return 1
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":
1609 pass
1610 else:
1611 return 0
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"
1617 return 1
1618 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1619
1620 logger.debug("openmano response: %s", mano_response.text )
1621 return _print_verbose(mano_response, args.verbose)
1622
tierno20df3bb2017-07-07 14:31:00 +02001623
tierno7edb6752016-03-21 17:37:52 +01001624def 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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001632
tierno7edb6752016-03-21 17:37:52 +01001633 #print payload_req
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":
1637 pass
1638 else:
1639 return 0
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:
1644 args.verbose=0
1645 if args.name!=None:
1646 args.verbose += 1
1647 return _print_verbose(mano_response, args.verbose)
1648
1649
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001650def 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)
1655
1656 has_arguments = False
1657 if args.file != None:
1658 has_arguments = True
1659 payload = _load_file_or_yaml(args.file)
1660 else:
1661 payload = {}
1662
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
1671 else:
1672 payload['config']['sdn-controller'] = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1673
1674 if not has_arguments:
1675 raise OpenmanoCLIError("At least one argument must be provided to modify the datacenter")
1676
1677 if 'datacenter' not in payload:
1678 payload = {'datacenter': payload}
1679 payload_req = json.dumps(payload)
1680
1681 # print payload_req
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":
1685 pass
1686 else:
1687 return 0
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:
1692 args.verbose = 0
1693 if args.name != None:
1694 args.verbose += 1
1695 return _print_verbose(mano_response, args.verbose)
1696
tierno20df3bb2017-07-07 14:31:00 +02001697
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001698# WIM
1699def wim_account_create(args):
1700 tenant = _get_tenant()
1701 wim = _get_wim(args.name)
1702 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1703
1704 wim_dict = {}
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)
1713
1714 payload_req = json.dumps({"wim_account": wim_dict})
1715
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"
1727 return result
1728
1729
1730def wim_account_delete(args):
1731 if args.all:
1732 tenant = "any"
1733 else:
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']
1745 else:
1746 print content['error']['description']
1747 return result
1748
1749
1750def wim_account_edit(args):
1751 tenant = _get_tenant()
1752 wim = _get_wim(args.name)
1753 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1754
1755 wim_dict = {}
1756 if not args.account_name:
1757 wim_dict['name'] = args.vim_tenant_name
1758 if not args.user:
1759 wim_dict['user'] = args.user
1760 if not args.password:
1761 wim_dict['password'] = args.password
1762 if not args.config:
1763 wim_dict["config"] = _load_file_or_yaml(args.config)
1764
1765 payload_req = json.dumps({"wim_account": wim_dict})
1766
1767 # print payload_req
1768
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"
1780 return result
1781
1782def 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)
1791
1792 payload_req = json.dumps({"wim": wim_dict})
1793
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)
1799
1800
1801def wim_edit(args):
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)
1806
1807 has_arguments = False
1808 if args.file != None:
1809 has_arguments = True
1810 payload = _load_file_or_yaml(args.file)
1811 else:
1812 payload = {}
1813
1814 if not has_arguments:
1815 raise OpenmanoCLIError("At least one argument must be provided to modify the wim")
1816
1817 if 'wim' not in payload:
1818 payload = {'wim': payload}
1819 payload_req = json.dumps(payload)
1820
1821 # print payload_req
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":
1825 pass
1826 else:
1827 return 0
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:
1832 args.verbose = 0
1833 if args.name != None:
1834 args.verbose += 1
1835 return _print_verbose(mano_response, args.verbose)
1836
1837
1838def wim_delete(args):
1839 # print "wim-delete",args
1840 todelete = _get_item_uuid("wims", args.name, "any")
1841 if not args.force:
1842 r = raw_input("Delete wim %s (y/N)? " % (args.name))
1843 if not (len(r) > 0 and r[0].lower() == "y"):
1844 return 0
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']
1853 else:
1854 print content['error']['description']
1855 return result
1856
1857
1858def wim_list(args):
1859 # print "wim-list",args
1860 tenant = 'any' if args.all else _get_tenant()
1861
1862 if args.name:
1863 toshow = _get_item_uuid("wims", args.name, tenant)
1864 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, toshow)
1865 else:
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:
1870 args.verbose = 0
1871 if args.name != None:
1872 args.verbose += 1
1873 return _print_verbose(mano_response, args.verbose)
1874
1875
1876def 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'}
1880
1881 if not args.file:
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)
1885
1886 payload_req = json.dumps({"wim_port_mapping": wim_port_mapping})
1887
1888 # read
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()
1893
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:
1899 if not args.force:
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"):
1902 return 0
1903
1904 # clear
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)
1910
1911 # set
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)
1917
1918
1919def wim_port_mapping_list(args):
1920 tenant = _get_tenant()
1921 wim = _get_wim(args.name, tenant)
1922
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)
1926
1927 return _print_verbose(mano_response, 4)
1928
1929
1930def wim_port_mapping_clear(args):
1931 tenant = _get_tenant()
1932 wim = _get_wim(args.name, tenant)
1933
1934 if not args.force:
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"):
1937 return 0
1938
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']
1947 else:
1948 print content['error']['description']
1949 return result
1950
1951
tierno6ddeded2017-05-16 15:40:26 +02001952def version(args):
1953 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1954 URLrequest = "http://%s:%s/openmano/version" % (mano_host, mano_port)
1955
1956 mano_response = requests.get(URLrequest, headers=headers_req)
1957 logger.debug("openmano response: %s", mano_response.text)
1958 print mano_response.text
1959
1960
tierno7edb6752016-03-21 17:37:52 +01001961global mano_host
1962global mano_port
1963global mano_tenant
1964
1965if __name__=="__main__":
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001966
tierno7edb6752016-03-21 17:37:52 +01001967 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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001971 # WIM env variable for default WIM
1972 mano_wim = os.getenv('OPENMANO_WIM', None)
1973
tierno7edb6752016-03-21 17:37:52 +01001974 main_parser = ThrowingArgumentParser(description='User program to interact with OPENMANO-SERVER (openmanod)')
tierno6ddeded2017-05-16 15:40:26 +02001975 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)")
1978
tierno7edb6752016-03-21 17:37:52 +01001979 subparsers = main_parser.add_subparsers(help='commands')
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001980
tierno7edb6752016-03-21 17:37:52 +01001981 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")
1984
garciadeblas0e9fd832016-07-08 15:20:18 +02001985 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)
1988
tierno6ddeded2017-05-16 15:40:26 +02001989 version_parser = subparsers.add_parser('version', parents=[parent_parser], help="get server version")
1990 version_parser.set_defaults(func=version)
1991
tierno7edb6752016-03-21 17:37:52 +01001992 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)")
garciadeblas14480452017-01-10 13:08:07 +01001997 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)")
tierno7edb6752016-03-21 17:37:52 +01001999 vnf_create_parser.set_defaults(func=vnf_create)
2000
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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002006
tierno7edb6752016-03-21 17:37:52 +01002007 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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002012
tierno7edb6752016-03-21 17:37:52 +01002013 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)
2018
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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002024
tierno7edb6752016-03-21 17:37:52 +01002025 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)
2030
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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002038
tierno7edb6752016-03-21 17:37:52 +01002039 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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002043
tierno7edb6752016-03-21 17:37:52 +01002044 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")
tiernoa4e1a6e2016-08-31 14:19:40 +02002052 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")
tierno7edb6752016-03-21 17:37:52 +01002054 instance_scenario_create_parser.add_argument("--description", action="store", help="description of the instance")
2055 instance_scenario_create_parser.set_defaults(func=instance_create)
2056
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)
2061
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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002067
tierno7edb6752016-03-21 17:37:52 +01002068 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, \
tiernofc5f80b2018-05-29 16:00:43 +02002071 choices=["start","pause","resume","shutoff","shutdown","forceOff","rebuild","reboot", "console", "add_public_key","vdu-scaling"],\
tierno7edb6752016-03-21 17:37:52 +01002072 help="action to send")
tiernofc5f80b2018-05-29 16:00:43 +02002073 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}]'")
tierno7edb6752016-03-21 17:37:52 +01002074 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)
2077
tierno868220c2017-09-26 00:11:05 +02002078 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)
2083
tierno7edb6752016-03-21 17:37:52 +01002084 #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)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002087
tierno7edb6752016-03-21 17:37:52 +01002088 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)
2092
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)
2097
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)
2101
tierno161c24b2017-05-16 15:45:56 +02002102 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')
tierno7edb6752016-03-21 17:37:52 +01002107
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")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002115 datacenter_create_parser.add_argument("--sdn-controller", action="store", help="Name or uuid of the SDN controller to be used", dest='sdn_controller')
tierno7edb6752016-03-21 17:37:52 +01002116 datacenter_create_parser.set_defaults(func=datacenter_create)
2117
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)
2122
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002123 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)
2130
tierno7edb6752016-03-21 17:37:52 +01002131 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)
2135
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")
tierno8008c3a2016-10-13 15:34:28 +00002142 datacenter_attach_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
tierno7edb6752016-03-21 17:37:52 +01002143 datacenter_attach_parser.set_defaults(func=datacenter_attach)
2144
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002145 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)
2156
tierno7edb6752016-03-21 17:37:52 +01002157 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)
2161
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002162 #=======================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 "
2168 "by a datacenter")
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)
2175
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)
2182
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 # =======================
2193
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)
2210
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",
2216 dest='new_name')
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)
2230
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)
2237
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 # =======================
tierno7edb6752016-03-21 17:37:52 +01002246
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002247 # WIM ======================= WIM section==================
2248
2249 # WIM create
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 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)
2263
2264 # WIM delete
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)
2272
2273 # WIM edit
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)
2283
2284 # WIM list
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)
2293
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)
2307
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)
2319
2320 # WIM account edit
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)
2333
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)
2349
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)
2356
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)
2366
2367 # =======================================================
2368
tierno7edb6752016-03-21 17:37:52 +01002369 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'
2373 }
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)
2384
2385
tierno5acf7202016-08-29 14:28:13 +02002386 action_dict={'netmap-import': 'create network senario netmap base on the datacenter networks',
tierno7edb6752016-03-21 17:37:52 +01002387 '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'
2391 }
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")
tierno5acf7202016-08-29 14:28:13 +02002414 if item=='netmap-import':
tierno7edb6752016-03-21 17:37:52 +01002415 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)
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002417
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)
2430
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")
2435
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 # =======================
2443
tierno4540ea52017-01-18 17:44:32 +01002444 for item in ("network", "tenant", "image"):
tierno7edb6752016-03-21 17:37:52 +01002445 if item=="network":
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002446 command_name = 'vim-net'
tierno7edb6752016-03-21 17:37:52 +01002447 else:
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002448 command_name = 'vim-'+item
2449 vim_item_list_parser = subparsers.add_parser(command_name + '-list', parents=[parent_parser], help="list the vim " + item + "s")
tierno7edb6752016-03-21 17:37:52 +01002450 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")
2453
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002454 vim_item_del_parser = subparsers.add_parser(command_name + '-delete', parents=[parent_parser], help="list the vim " + item + "s")
tierno7edb6752016-03-21 17:37:52 +01002455 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")
2458
tierno4540ea52017-01-18 17:44:32 +01002459 if item == "network" or item == "tenant":
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002460 vim_item_create_parser = subparsers.add_parser(command_name + '-create', parents=[parent_parser], help="create a "+item+" at vim")
tierno4540ea52017-01-18 17:44:32 +01002461 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")
2464 if item=="network":
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>'")
2468 else:
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")
tierno7edb6752016-03-21 17:37:52 +01002471
2472 argcomplete.autocomplete(main_parser)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002473
tierno7edb6752016-03-21 17:37:52 +01002474 try:
2475 args = main_parser.parse_args()
2476 #logging info
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)
2485 if result == None:
2486 result = 0
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)"
2490 result = -2
2491 except (KeyboardInterrupt):
2492 print 'Exiting openmano'
2493 result = -3
2494 except (SystemExit, ArgumentParserError):
2495 result = -4
2496 except OpenmanoCLIError as e:
2497 print str(e)
2498 result = -5
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002499
tierno7edb6752016-03-21 17:37:52 +01002500 #print result
2501 exit(result)
2502