blob: 98ea191eef3b19e378540afe7cfc855dae4ea58b [file] [log] [blame]
tierno7edb6752016-03-21 17:37:52 +01001#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# PYTHON_ARGCOMPLETE_OK
4
5##
6# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
7# This file is part of openmano
8# All Rights Reserved.
9#
10# Licensed under the Apache License, Version 2.0 (the "License"); you may
11# not use this file except in compliance with the License. You may obtain
12# a copy of the License at
13#
14# http://www.apache.org/licenses/LICENSE-2.0
15#
16# Unless required by applicable law or agreed to in writing, software
17# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19# License for the specific language governing permissions and limitations
20# under the License.
21#
22# For those usages not covered by the Apache License, Version 2.0 please
23# contact with: nfvlabs@tid.es
24##
25
tierno20df3bb2017-07-07 14:31:00 +020026"""
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$"
tiernofc5f80b2018-05-29 16:00:43 +020031__version__ = "0.4.23-r533"
32version_date = "May 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]
306 vdu_list = vnfd["vdu"]
307
308 else: # old API
309 api_version = ""
310 token = "vnfs"
311 vnfd = myvnf['vnf']
312 vdu_list = vnfd["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
tierno7edb6752016-03-21 17:37:52 +0100322 if args.image_path:
tiernof1ba57e2017-09-07 12:23:19 +0200323 index = 0
tierno7edb6752016-03-21 17:37:52 +0100324 for image_path_ in args.image_path.split(","):
tiernof1ba57e2017-09-07 12:23:19 +0200325 # print "image-path", image_path_
326 if api_version == "/v3":
327 if vdu_list[index].get("image"):
328 vdu_list[index]['image'] = image_path_
329 if "image-checksum" in vdu_list[index]:
330 del vdu_list[index]["image-checksum"]
331 else: # image name in volumes
332 vdu_list[index]["volumes"][0]["image"] = image_path_
333 if "image-checksum" in vdu_list[index]["volumes"][0]:
334 del vdu_list[index]["volumes"][0]["image-checksum"]
335 else:
336 vdu_list[index]['VNFC image'] = image_path_
337 if "image name" in vdu_list[index]:
338 del vdu_list[index]["image name"]
339 if "image checksum" in vdu_list[index]:
340 del vdu_list[index]["image checksum"]
341 index += 1
342 if args.image_name: # image name precedes if both are supplied
343 index = 0
garciadeblas14480452017-01-10 13:08:07 +0100344 for image_name_ in args.image_name.split(","):
tiernof1ba57e2017-09-07 12:23:19 +0200345 if api_version == "/v3":
346 if vdu_list[index].get("image"):
347 vdu_list[index]['image'] = image_name_
348 if "image-checksum" in vdu_list[index]:
349 del vdu_list[index]["image-checksum"]
tierno16e3dd42018-04-24 12:52:40 +0200350 if vdu_list[index].get("alternative-images"):
351 for a_image in vdu_list[index]["alternative-images"]:
352 a_image['image'] = image_name_
353 if "image-checksum" in a_image:
354 del a_image["image-checksum"]
tiernof1ba57e2017-09-07 12:23:19 +0200355 else: # image name in volumes
356 vdu_list[index]["volumes"][0]["image"] = image_name_
357 if "image-checksum" in vdu_list[index]["volumes"][0]:
358 del vdu_list[index]["volumes"][0]["image-checksum"]
359 else:
360 vdu_list[index]['image name'] = image_name_
361 if "VNFC image" in vdu_list[index]:
362 del vdu_list[index]["VNFC image"]
363 index += 1
garciadeblas14480452017-01-10 13:08:07 +0100364 if args.image_checksum:
tiernof1ba57e2017-09-07 12:23:19 +0200365 index = 0
garciadeblas14480452017-01-10 13:08:07 +0100366 for image_checksum_ in args.image_checksum.split(","):
tiernof1ba57e2017-09-07 12:23:19 +0200367 if api_version == "/v3":
368 if vdu_list[index].get("image"):
369 vdu_list[index]['image-checksum'] = image_checksum_
tierno16e3dd42018-04-24 12:52:40 +0200370 if vdu_list[index].get("alternative-images"):
371 for a_image in vdu_list[index]["alternative-images"]:
372 a_image['image-checksum'] = image_checksum_
tiernof1ba57e2017-09-07 12:23:19 +0200373 else: # image name in volumes
374 vdu_list[index]["volumes"][0]["image-checksum"] = image_checksum_
375 else:
376 vdu_list[index]['image checksum'] = image_checksum_
377 index += 1
tierno7edb6752016-03-21 17:37:52 +0100378 except (KeyError, TypeError), e:
tiernof1ba57e2017-09-07 12:23:19 +0200379 if str(e) == 'vnf': error_pos= "missing field 'vnf'"
380 elif str(e) == 'name': error_pos= "missing field 'vnf':'name'"
381 elif str(e) == 'description': error_pos= "missing field 'vnf':'description'"
382 elif str(e) == 'VNFC': error_pos= "missing field 'vnf':'VNFC'"
383 elif str(e) == str(index): error_pos= "field 'vnf':'VNFC' must be an array"
384 elif str(e) == 'VNFC image': error_pos= "missing field 'vnf':'VNFC'['VNFC image']"
385 elif str(e) == 'image name': error_pos= "missing field 'vnf':'VNFC'['image name']"
386 elif str(e) == 'image checksum': error_pos= "missing field 'vnf':'VNFC'['image checksum']"
tierno7edb6752016-03-21 17:37:52 +0100387 else: error_pos="wrong format"
388 print "Wrong VNF descriptor: " + error_pos
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100389 return -1
tierno7edb6752016-03-21 17:37:52 +0100390 payload_req = json.dumps(myvnf)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100391
tierno7edb6752016-03-21 17:37:52 +0100392 #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100393
tiernof1ba57e2017-09-07 12:23:19 +0200394 URLrequest = "http://{}:{}/openmano{}/{}/{token}".format(mano_host, mano_port, api_version, tenant, token=token)
tierno7edb6752016-03-21 17:37:52 +0100395 logger.debug("openmano request: %s", payload_req)
396 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
397 logger.debug("openmano response: %s", mano_response.text )
398
399 return _print_verbose(mano_response, args.verbose)
400
401def vnf_list(args):
402 #print "vnf-list",args
403 if args.all:
404 tenant = "any"
405 else:
406 tenant = _get_tenant()
407 if args.name:
408 toshow = _get_item_uuid("vnfs", args.name, tenant)
409 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, toshow)
410 else:
411 URLrequest = "http://%s:%s/openmano/%s/vnfs" %(mano_host, mano_port, tenant)
412 mano_response = requests.get(URLrequest)
413 logger.debug("openmano response: %s", mano_response.text )
414 content = mano_response.json()
tiernof1ba57e2017-09-07 12:23:19 +0200415 # print json.dumps(content, indent=4)
tierno7edb6752016-03-21 17:37:52 +0100416 if args.verbose==None:
417 args.verbose=0
418 result = 0 if mano_response.status_code==200 else mano_response.status_code
419 if mano_response.status_code == 200:
420 if not args.name:
421 if args.verbose >= 3:
422 print yaml.safe_dump(content, indent=4, default_flow_style=False)
423 return result
424 if len(content['vnfs']) == 0:
425 print "No VNFs were found."
tiernof1ba57e2017-09-07 12:23:19 +0200426 return 404 # HTTP_Not_Found
tierno7edb6752016-03-21 17:37:52 +0100427 for vnf in content['vnfs']:
tiernof1ba57e2017-09-07 12:23:19 +0200428 myoutput = "{:38} {:20}".format(vnf['uuid'], vnf['name'])
429 if vnf.get('osm_id') or args.verbose >= 1:
430 myoutput += " osm_id={:20}".format(vnf.get('osm_id'))
431 if args.verbose >= 1:
432 myoutput += " {}".format(vnf['created_at'])
433 print (myoutput)
434 if args.verbose >= 2:
435 print (" Description: {}".format(vnf['description']))
436 # print (" VNF descriptor file: {}".format(vnf['path']))
tierno7edb6752016-03-21 17:37:52 +0100437 else:
438 if args.verbose:
439 print yaml.safe_dump(content, indent=4, default_flow_style=False)
440 return result
441 vnf = content['vnf']
tiernof1ba57e2017-09-07 12:23:19 +0200442 print ("{:38} {:20} osm_id={:20} {:20}".format(vnf['uuid'], vnf['name'], vnf.get('osm_id'),
443 vnf['created_at']))
444 print (" Description: {}".format(vnf['description']))
445 # print " VNF descriptor file: %s" %vnf['path']
446 print (" VMs:")
tierno7edb6752016-03-21 17:37:52 +0100447 for vm in vnf['VNFC']:
tiernof1ba57e2017-09-07 12:23:19 +0200448 print (" {:20} osm_id={:20} {}".format(vm['name'], vm.get('osm_id'), vm['description']))
449 if len(vnf['nets']) > 0:
450 print (" Internal nets:")
tierno7edb6752016-03-21 17:37:52 +0100451 for net in vnf['nets']:
tiernof1ba57e2017-09-07 12:23:19 +0200452 print (" {:20} {}".format(net['name'], net['description']))
453 if len(vnf['external-connections']) > 0:
454 print (" External interfaces:")
tierno7edb6752016-03-21 17:37:52 +0100455 for interface in vnf['external-connections']:
tiernof1ba57e2017-09-07 12:23:19 +0200456 print (" {:20} {:20} {:20} {:14}".format(
457 interface['external_name'], interface['vm_name'],
458 interface['internal_name'],
459 interface.get('vpci') if interface.get('vpci') else ""))
tierno7edb6752016-03-21 17:37:52 +0100460 else:
461 print content['error']['description']
462 if args.verbose:
463 print yaml.safe_dump(content, indent=4, default_flow_style=False)
464 return result
465
466def vnf_delete(args):
467 #print "vnf-delete",args
468 if args.all:
469 tenant = "any"
470 else:
471 tenant = _get_tenant()
472 todelete = _get_item_uuid("vnfs", args.name, tenant=tenant)
473 if not args.force:
474 r = raw_input("Delete VNF %s (y/N)? " %(todelete))
475 if not (len(r)>0 and r[0].lower()=="y"):
476 return 0
477 URLrequest = "http://%s:%s/openmano/%s/vnfs/%s" %(mano_host, mano_port, tenant, todelete)
478 mano_response = requests.delete(URLrequest)
479 logger.debug("openmano response: %s", mano_response.text )
480 result = 0 if mano_response.status_code==200 else mano_response.status_code
481 content = mano_response.json()
482 #print json.dumps(content, indent=4)
483 if mano_response.status_code == 200:
484 print content['result']
485 else:
486 print content['error']['description']
487 return result
488
489def scenario_create(args):
tiernof1ba57e2017-09-07 12:23:19 +0200490 # print "scenario-create",args
tierno7edb6752016-03-21 17:37:52 +0100491 tenant = _get_tenant()
492 headers_req = {'content-type': 'application/yaml'}
493 myscenario = _load_file_or_yaml(args.file)
tiernof1ba57e2017-09-07 12:23:19 +0200494 if "nsd:nsd-catalog" in myscenario or "nsd-catalog" in myscenario:
495 api_version = "/v3"
496 token = "nsd"
497 nsd_catalog = myscenario.get("nsd:nsd-catalog")
498 if not nsd_catalog:
499 nsd_catalog = myscenario.get("nsd-catalog")
500 nsds = nsd_catalog.get("nsd:nsd")
501 if not nsds:
502 nsds = nsd_catalog.get("nsd")
503 nsd = nsds[0]
504 else: # API<v3
505 api_version = ""
506 token = "scenarios"
507 if "scenario" in myscenario:
508 nsd = myscenario["scenario"]
509 else:
510 nsd = myscenario
511 # TODO modify for API v3
tierno7edb6752016-03-21 17:37:52 +0100512 if args.name:
tiernof1ba57e2017-09-07 12:23:19 +0200513 nsd['name'] = args.name
tierno7edb6752016-03-21 17:37:52 +0100514 if args.description:
tiernof1ba57e2017-09-07 12:23:19 +0200515 nsd['description'] = args.description
516 payload_req = yaml.safe_dump(myscenario, explicit_start=True, indent=4, default_flow_style=False, tags=False,
517 encoding='utf-8', allow_unicode=True)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100518
tiernof1ba57e2017-09-07 12:23:19 +0200519 # print payload_req
520 URLrequest = "http://{host}:{port}/openmano{api}/{tenant}/{token}".format(
521 host=mano_host, port=mano_port, api=api_version, tenant=tenant, token=token)
tierno7edb6752016-03-21 17:37:52 +0100522 logger.debug("openmano request: %s", payload_req)
523 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
524 logger.debug("openmano response: %s", mano_response.text )
525 return _print_verbose(mano_response, args.verbose)
526
527def scenario_list(args):
528 #print "scenario-list",args
529 if args.all:
530 tenant = "any"
531 else:
532 tenant = _get_tenant()
533 if args.name:
534 toshow = _get_item_uuid("scenarios", args.name, tenant)
535 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, toshow)
536 else:
537 URLrequest = "http://%s:%s/openmano/%s/scenarios" %(mano_host, mano_port, tenant)
538 mano_response = requests.get(URLrequest)
539 logger.debug("openmano response: %s", mano_response.text )
540 content = mano_response.json()
541 #print json.dumps(content, indent=4)
542 if args.verbose==None:
543 args.verbose=0
544
545 result = 0 if mano_response.status_code==200 else mano_response.status_code
546 if mano_response.status_code == 200:
547 if not args.name:
548 if args.verbose >= 3:
549 print yaml.safe_dump(content, indent=4, default_flow_style=False)
550 return result
551 if len(content['scenarios']) == 0:
552 print "No scenarios were found."
553 return 404 #HTTP_Not_Found
554 for scenario in content['scenarios']:
tiernof1ba57e2017-09-07 12:23:19 +0200555 myoutput = "{:38} {:20}".format(scenario['uuid'], scenario['name'])
556 if scenario.get('osm_id') or args.verbose >= 1:
557 myoutput += " osm_id={:20}".format(scenario.get('osm_id'))
558 if args.verbose >= 1:
559 myoutput += " {}".format(scenario['created_at'])
560 print (myoutput)
tierno7edb6752016-03-21 17:37:52 +0100561 if args.verbose >=2:
tiernof1ba57e2017-09-07 12:23:19 +0200562 print (" Description: {}".format(scenario['description']))
tierno7edb6752016-03-21 17:37:52 +0100563 else:
564 if args.verbose:
565 print yaml.safe_dump(content, indent=4, default_flow_style=False)
566 return result
567 scenario = content['scenario']
tiernof1ba57e2017-09-07 12:23:19 +0200568 print ("{:38} {:20} osm_id={:20} {:20}".format(scenario['uuid'], scenario['name'], scenario.get('osm_id'),
569 scenario['created_at']))
570 print (" Description: {}".format(scenario['description']))
571 print (" VNFs:")
tierno7edb6752016-03-21 17:37:52 +0100572 for vnf in scenario['vnfs']:
tiernof1ba57e2017-09-07 12:23:19 +0200573 print (" {:38} {:20} vnf_index={} {}".format(vnf['vnf_id'], vnf['name'], vnf.get("member_vnf_index"),
574 vnf['description']))
575 if len(scenario['nets']) > 0:
576 print (" nets:")
tierno7edb6752016-03-21 17:37:52 +0100577 for net in scenario['nets']:
tiernof1ba57e2017-09-07 12:23:19 +0200578 description = net['description']
579 if not description: # if description does not exist, description is "-". Valid for external and internal nets.
580 description = '-'
581 vim_id = ""
582 if net.get('vim_id'):
583 vim_id = " vim_id=" + net["vim_id"]
584 external = ""
585 if net["external"]:
586 external = " external"
587 print (" {:20} {:38} {:30}{}{}".format(net['name'], net['uuid'], description, vim_id, external))
tierno7edb6752016-03-21 17:37:52 +0100588 else:
tiernof1ba57e2017-09-07 12:23:19 +0200589 print (content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100590 if args.verbose:
591 print yaml.safe_dump(content, indent=4, default_flow_style=False)
592 return result
593
594def scenario_delete(args):
595 #print "scenario-delete",args
596 if args.all:
597 tenant = "any"
598 else:
599 tenant = _get_tenant()
600 todelete = _get_item_uuid("scenarios", args.name, tenant=tenant)
601 if not args.force:
602 r = raw_input("Delete scenario %s (y/N)? " %(args.name))
603 if not (len(r)>0 and r[0].lower()=="y"):
604 return 0
605 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s" %(mano_host, mano_port, tenant, todelete)
606 mano_response = requests.delete(URLrequest)
607 logger.debug("openmano response: %s", mano_response.text )
608 result = 0 if mano_response.status_code==200 else mano_response.status_code
609 content = mano_response.json()
610 #print json.dumps(content, indent=4)
611 if mano_response.status_code == 200:
612 print content['result']
613 else:
614 print content['error']['description']
615 return result
616
617def scenario_deploy(args):
618 print "This command is deprecated, use 'openmano instance-scenario-create --scenario %s --name %s' instead!!!" % (args.scenario, args.name)
619 print
620 args.file = None
621 args.netmap_use = None
622 args.netmap_create = None
tiernobe41e222016-09-02 15:16:13 +0200623 args.keypair = None
624 args.keypair_auto = None
tierno7edb6752016-03-21 17:37:52 +0100625 return instance_create(args)
626
627# #print "scenario-deploy",args
628# headers_req = {'content-type': 'application/json'}
629# action = {}
630# actionCmd="start"
631# if args.nostart:
632# actionCmd="reserve"
633# action[actionCmd] = {}
634# action[actionCmd]["instance_name"] = args.name
635# if args.datacenter != None:
636# action[actionCmd]["datacenter"] = args.datacenter
637# elif mano_datacenter != None:
638# action[actionCmd]["datacenter"] = mano_datacenter
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100639#
tierno7edb6752016-03-21 17:37:52 +0100640# if args.description:
641# action[actionCmd]["description"] = args.description
642# payload_req = json.dumps(action, indent=4)
643# #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100644#
tierno7edb6752016-03-21 17:37:52 +0100645# URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, mano_tenant, args.scenario)
646# logger.debug("openmano request: %s", payload_req)
647# mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
648# logger.debug("openmano response: %s", mano_response.text )
649# if args.verbose==None:
650# args.verbose=0
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100651#
tierno7edb6752016-03-21 17:37:52 +0100652# result = 0 if mano_response.status_code==200 else mano_response.status_code
653# content = mano_response.json()
654# #print json.dumps(content, indent=4)
655# if args.verbose >= 3:
656# print yaml.safe_dump(content, indent=4, default_flow_style=False)
657# return result
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100658#
tierno7edb6752016-03-21 17:37:52 +0100659# if mano_response.status_code == 200:
660# myoutput = "%s %s" %(content['uuid'].ljust(38),content['name'].ljust(20))
661# if args.verbose >=1:
662# myoutput = "%s %s" %(myoutput, content['created_at'].ljust(20))
663# if args.verbose >=2:
664# myoutput = "%s %s %s" %(myoutput, content['description'].ljust(30))
665# print myoutput
666# print ""
667# print "To check the status, run the following command:"
668# print "openmano instance-scenario-list <instance_id>"
669# else:
670# print content['error']['description']
671# return result
672
673def scenario_verify(args):
674 #print "scenario-verify",args
tierno72a08d72017-05-25 13:12:30 +0200675 tenant = _get_tenant()
tierno7edb6752016-03-21 17:37:52 +0100676 headers_req = {'content-type': 'application/json'}
677 action = {}
678 action["verify"] = {}
679 action["verify"]["instance_name"] = "scen-verify-return5"
680 payload_req = json.dumps(action, indent=4)
681 #print payload_req
682
tierno72a08d72017-05-25 13:12:30 +0200683 URLrequest = "http://%s:%s/openmano/%s/scenarios/%s/action" %(mano_host, mano_port, tenant, args.scenario)
tierno7edb6752016-03-21 17:37:52 +0100684 logger.debug("openmano request: %s", payload_req)
685 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
686 logger.debug("openmano response: %s", mano_response.text )
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100687
tierno7edb6752016-03-21 17:37:52 +0100688 result = 0 if mano_response.status_code==200 else mano_response.status_code
689 content = mano_response.json()
690 #print json.dumps(content, indent=4)
691 if mano_response.status_code == 200:
692 print content['result']
693 else:
694 print content['error']['description']
695 return result
696
697def instance_create(args):
698 tenant = _get_tenant()
699 headers_req = {'content-type': 'application/yaml'}
700 myInstance={"instance": {}, "schema_version": "0.1"}
701 if args.file:
702 instance_dict = _load_file_or_yaml(args.file)
703 if "instance" not in instance_dict:
704 myInstance = {"instance": instance_dict, "schema_version": "0.1"}
705 else:
706 myInstance = instance_dict
707 if args.name:
708 myInstance["instance"]['name'] = args.name
709 if args.description:
710 myInstance["instance"]['description'] = args.description
711 if args.nostart:
712 myInstance["instance"]['action'] = "reserve"
713 #datacenter
714 datacenter = myInstance["instance"].get("datacenter")
715 if args.datacenter != None:
716 datacenter = args.datacenter
717 myInstance["instance"]["datacenter"] = _get_datacenter(datacenter, tenant)
718 #scenario
719 scenario = myInstance["instance"].get("scenario")
720 if args.scenario != None:
721 scenario = args.scenario
722 if not scenario:
garciadeblased746032017-01-05 11:58:41 +0100723 print "you must provide a scenario in the file descriptor or with --scenario"
tierno7edb6752016-03-21 17:37:52 +0100724 return -1
725 myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant)
726 if args.netmap_use:
727 if "networks" not in myInstance["instance"]:
728 myInstance["instance"]["networks"] = {}
729 for net in args.netmap_use:
730 net_comma_list = net.split(",")
731 for net_comma in net_comma_list:
732 net_tuple = net_comma.split("=")
733 if len(net_tuple) != 2:
734 print "error at netmap-use. Expected net-scenario=net-datacenter. (%s)?" % net_comma
735 return
736 net_scenario = net_tuple[0].strip()
737 net_datacenter = net_tuple[1].strip()
738 if net_scenario not in myInstance["instance"]["networks"]:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100739 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200740 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
741 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
742 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-use"] = net_datacenter
tierno7edb6752016-03-21 17:37:52 +0100743 if args.netmap_create:
744 if "networks" not in myInstance["instance"]:
745 myInstance["instance"]["networks"] = {}
746 for net in args.netmap_create:
747 net_comma_list = net.split(",")
748 for net_comma in net_comma_list:
749 net_tuple = net_comma.split("=")
750 if len(net_tuple) == 1:
751 net_scenario = net_tuple[0].strip()
752 net_datacenter = None
753 elif len(net_tuple) == 2:
754 net_scenario = net_tuple[0].strip()
755 net_datacenter = net_tuple[1].strip()
756 else:
757 print "error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. (%s)?" % net_comma
758 return
759 if net_scenario not in myInstance["instance"]["networks"]:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100760 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200761 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
762 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
763 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-create"] = net_datacenter
tiernoa4e1a6e2016-08-31 14:19:40 +0200764 if args.keypair:
765 if "cloud-config" not in myInstance["instance"]:
766 myInstance["instance"]["cloud-config"] = {}
767 cloud_config = myInstance["instance"]["cloud-config"]
768 for key in args.keypair:
769 index = key.find(":")
770 if index<0:
771 if "key-pairs" not in cloud_config:
772 cloud_config["key-pairs"] = []
773 cloud_config["key-pairs"].append(key)
774 else:
775 user = key[:index]
776 key_ = key[index+1:]
777 key_list = key_.split(",")
778 if "users" not in cloud_config:
779 cloud_config["users"] = []
780 cloud_config["users"].append({"name": user, "key-pairs": key_list })
781 if args.keypair_auto:
782 try:
783 keys=[]
784 home = os.getenv("HOME")
785 user = os.getenv("USER")
786 files = os.listdir(home+'/.ssh')
787 for file in files:
788 if file[-4:] == ".pub":
789 with open(home+'/.ssh/'+file, 'r') as f:
790 keys.append(f.read())
791 if not keys:
792 print "Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh')
793 return 1
794 except Exception as e:
795 print "Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e))
796 return 1
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100797
tiernoa4e1a6e2016-08-31 14:19:40 +0200798 if "cloud-config" not in myInstance["instance"]:
799 myInstance["instance"]["cloud-config"] = {}
800 cloud_config = myInstance["instance"]["cloud-config"]
801 if "key-pairs" not in cloud_config:
802 cloud_config["key-pairs"] = []
803 if user:
804 if "users" not in cloud_config:
805 cloud_config["users"] = []
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100806 cloud_config["users"].append({"name": user, "key-pairs": keys })
807
tierno7edb6752016-03-21 17:37:52 +0100808 payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
809 logger.debug("openmano request: %s", payload_req)
810 URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant)
811 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
812 logger.debug("openmano response: %s", mano_response.text )
813 if args.verbose==None:
814 args.verbose=0
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100815
tierno7edb6752016-03-21 17:37:52 +0100816 result = 0 if mano_response.status_code==200 else mano_response.status_code
817 content = mano_response.json()
818 #print json.dumps(content, indent=4)
819 if args.verbose >= 3:
820 print yaml.safe_dump(content, indent=4, default_flow_style=False)
821 return result
822
823 if mano_response.status_code == 200:
tiernoa15c4b92017-10-05 12:41:44 +0200824 myoutput = "{:38} {:20}".format(content['uuid'], content['name'])
tierno7edb6752016-03-21 17:37:52 +0100825 if args.verbose >=1:
tiernoa15c4b92017-10-05 12:41:44 +0200826 myoutput = "{} {:20}".format(myoutput, content['created_at'])
tierno7edb6752016-03-21 17:37:52 +0100827 if args.verbose >=2:
tiernoa15c4b92017-10-05 12:41:44 +0200828 myoutput = "{} {:30}".format(myoutput, content['description'])
tierno7edb6752016-03-21 17:37:52 +0100829 print myoutput
830 else:
831 print content['error']['description']
832 return result
833
834def instance_scenario_list(args):
835 #print "instance-scenario-list",args
836 if args.all:
837 tenant = "any"
838 else:
839 tenant = _get_tenant()
840 if args.name:
841 toshow = _get_item_uuid("instances", args.name, tenant)
842 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, toshow)
843 else:
844 URLrequest = "http://%s:%s/openmano/%s/instances" %(mano_host, mano_port, tenant)
845 mano_response = requests.get(URLrequest)
846 logger.debug("openmano response: %s", mano_response.text )
847 content = mano_response.json()
848 #print json.dumps(content, indent=4)
849 if args.verbose==None:
850 args.verbose=0
851
852 result = 0 if mano_response.status_code==200 else mano_response.status_code
853 if mano_response.status_code == 200:
854 if not args.name:
855 if args.verbose >= 3:
856 print yaml.safe_dump(content, indent=4, default_flow_style=False)
857 return result
858 if len(content['instances']) == 0:
859 print "No scenario instances were found."
860 return result
861 for instance in content['instances']:
tiernoa15c4b92017-10-05 12:41:44 +0200862 myoutput = "{:38} {:20}".format(instance['uuid'], instance['name'])
tierno7edb6752016-03-21 17:37:52 +0100863 if args.verbose >=1:
tiernoa15c4b92017-10-05 12:41:44 +0200864 myoutput = "{} {:20}".format(myoutput, instance['created_at'])
tierno7edb6752016-03-21 17:37:52 +0100865 print myoutput
866 if args.verbose >=2:
867 print "Description: %s" %instance['description']
868 else:
869 if args.verbose:
870 print yaml.safe_dump(content, indent=4, default_flow_style=False)
871 return result
872 instance = content
tiernoa15c4b92017-10-05 12:41:44 +0200873 print ("{:38} {:20} {:20}".format(instance['uuid'],instance['name'],instance['created_at']))
874 print ("Description: %s" %instance['description'])
875 print ("Template scenario id: {}".format(instance['scenario_id']))
876 print ("Template scenario name: {}".format(instance['scenario_name']))
877 print ("---------------------------------------")
878 print ("VNF instances: {}".format(len(instance['vnfs'])))
tierno7edb6752016-03-21 17:37:52 +0100879 for vnf in instance['vnfs']:
880 #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 +0200881 print (" {:38} {:20} Template vnf id: {:38}".format(vnf['uuid'], vnf['vnf_name'], vnf['vnf_id']))
tierno7edb6752016-03-21 17:37:52 +0100882 if len(instance['nets'])>0:
883 print "---------------------------------------"
884 print "Internal nets:"
885 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000886 if net['created']:
tiernoa15c4b92017-10-05 12:41:44 +0200887 print (" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
tierno7edb6752016-03-21 17:37:52 +0100888 print "---------------------------------------"
889 print "External nets:"
890 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000891 if not net['created']:
tiernoa15c4b92017-10-05 12:41:44 +0200892 print (" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
893 print ("---------------------------------------")
894 print ("VM instances:")
tierno7edb6752016-03-21 17:37:52 +0100895 for vnf in instance['vnfs']:
896 for vm in vnf['vms']:
tiernoa15c4b92017-10-05 12:41:44 +0200897 print (" {:38} {:20} {:20} {:12} VIM ID: {}".format(vm['uuid'], vnf['vnf_name'], vm['name'],
898 vm['status'], vm['vim_vm_id']))
tierno7edb6752016-03-21 17:37:52 +0100899 else:
900 print content['error']['description']
901 if args.verbose:
902 print yaml.safe_dump(content, indent=4, default_flow_style=False)
903 return result
904
905def instance_scenario_status(args):
906 print "instance-scenario-status"
907 return 0
908
909def instance_scenario_delete(args):
910 if args.all:
911 tenant = "any"
912 else:
913 tenant = _get_tenant()
914 todelete = _get_item_uuid("instances", args.name, tenant=tenant)
915 #print "instance-scenario-delete",args
916 if not args.force:
917 r = raw_input("Delete scenario instance %s (y/N)? " %(args.name))
918 if not (len(r)>0 and r[0].lower()=="y"):
919 return
920 URLrequest = "http://%s:%s/openmano/%s/instances/%s" %(mano_host, mano_port, tenant, todelete)
921 mano_response = requests.delete(URLrequest)
922 logger.debug("openmano response: %s", mano_response.text )
923 result = 0 if mano_response.status_code==200 else mano_response.status_code
924 content = mano_response.json()
925 #print json.dumps(content, indent=4)
926 if mano_response.status_code == 200:
927 print content['result']
928 else:
929 print content['error']['description']
930 return result
931
tierno868220c2017-09-26 00:11:05 +0200932def get_action(args):
933 if not args.all:
934 tenant = _get_tenant()
935 else:
936 tenant = "any"
937 if not args.instance:
938 instance_id = "any"
939 else:
940 instance_id =args.instance
941 action_id = ""
942 if args.id:
943 action_id = "/" + args.id
944 URLrequest = "http://{}:{}/openmano/{}/instances/{}/action{}".format(mano_host, mano_port, tenant, instance_id,
945 action_id)
946 mano_response = requests.get(URLrequest)
947 logger.debug("openmano response: %s", mano_response.text )
948 if args.verbose == None:
949 args.verbose = 0
950 if args.id != None:
951 args.verbose += 1
952 return _print_verbose(mano_response, args.verbose)
953
tierno7edb6752016-03-21 17:37:52 +0100954def instance_scenario_action(args):
955 #print "instance-scenario-action", args
956 tenant = _get_tenant()
957 toact = _get_item_uuid("instances", args.name, tenant=tenant)
958 action={}
tiernofc5f80b2018-05-29 16:00:43 +0200959 action[ args.action ] = yaml.safe_load(args.param)
tierno7edb6752016-03-21 17:37:52 +0100960 if args.vnf:
961 action["vnfs"] = args.vnf
962 if args.vm:
963 action["vms"] = args.vm
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100964
tierno7edb6752016-03-21 17:37:52 +0100965 headers_req = {'content-type': 'application/json'}
966 payload_req = json.dumps(action, indent=4)
967 URLrequest = "http://%s:%s/openmano/%s/instances/%s/action" %(mano_host, mano_port, tenant, toact)
968 logger.debug("openmano request: %s", payload_req)
969 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
970 logger.debug("openmano response: %s", mano_response.text )
971 result = 0 if mano_response.status_code==200 else mano_response.status_code
972 content = mano_response.json()
tiernofc5f80b2018-05-29 16:00:43 +0200973 # print json.dumps(content, indent=4)
tierno7edb6752016-03-21 17:37:52 +0100974 if mano_response.status_code == 200:
975 if args.verbose:
976 print yaml.safe_dump(content, indent=4, default_flow_style=False)
977 return result
tiernofc5f80b2018-05-29 16:00:43 +0200978 if "instance_action_id" in content:
979 print("instance_action_id={}".format(content["instance_action_id"]))
980 else:
981 for uuid,c in content.iteritems():
982 print ("{:38} {:20} {:20}".format(uuid, c.get('name'), c.get('description')))
tierno7edb6752016-03-21 17:37:52 +0100983 else:
984 print content['error']['description']
985 return result
986
987
988def instance_vnf_list(args):
989 print "instance-vnf-list"
990 return 0
991
992def instance_vnf_status(args):
993 print "instance-vnf-status"
994 return 0
995
996def tenant_create(args):
997 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
998 tenant_dict={"name": args.name}
999 if args.description!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001000 tenant_dict["description"] = args.description
tierno7edb6752016-03-21 17:37:52 +01001001 payload_req = json.dumps( {"tenant": tenant_dict })
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001002
tierno7edb6752016-03-21 17:37:52 +01001003 #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001004
tierno7edb6752016-03-21 17:37:52 +01001005 URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port)
1006 logger.debug("openmano request: %s", payload_req)
1007 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1008 logger.debug("openmano response: %s", mano_response.text )
1009 return _print_verbose(mano_response, args.verbose)
1010
1011def tenant_list(args):
1012 #print "tenant-list",args
1013 if args.name:
tierno392f2852016-05-13 12:28:55 +02001014 toshow = _get_item_uuid("tenants", args.name)
tierno7edb6752016-03-21 17:37:52 +01001015 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, toshow)
1016 else:
1017 URLrequest = "http://%s:%s/openmano/tenants" %(mano_host, mano_port)
1018 mano_response = requests.get(URLrequest)
1019 logger.debug("openmano response: %s", mano_response.text )
1020 if args.verbose==None:
1021 args.verbose=0
1022 if args.name!=None:
1023 args.verbose += 1
1024 return _print_verbose(mano_response, args.verbose)
1025
1026def tenant_delete(args):
1027 #print "tenant-delete",args
1028 todelete = _get_item_uuid("tenants", args.name)
1029 if not args.force:
1030 r = raw_input("Delete tenant %s (y/N)? " %(args.name))
1031 if not (len(r)>0 and r[0].lower()=="y"):
1032 return 0
1033 URLrequest = "http://%s:%s/openmano/tenants/%s" %(mano_host, mano_port, todelete)
1034 mano_response = requests.delete(URLrequest)
1035 logger.debug("openmano response: %s", mano_response.text )
1036 result = 0 if mano_response.status_code==200 else mano_response.status_code
1037 content = mano_response.json()
1038 #print json.dumps(content, indent=4)
1039 if mano_response.status_code == 200:
1040 print content['result']
1041 else:
1042 print content['error']['description']
1043 return result
1044
1045def datacenter_attach(args):
1046 tenant = _get_tenant()
1047 datacenter = _get_datacenter(args.name)
1048 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001049
tierno7edb6752016-03-21 17:37:52 +01001050 datacenter_dict={}
1051 if args.vim_tenant_id != None:
1052 datacenter_dict['vim_tenant'] = args.vim_tenant_id
1053 if args.vim_tenant_name != None:
1054 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
1055 if args.user != None:
1056 datacenter_dict['vim_username'] = args.user
1057 if args.password != None:
1058 datacenter_dict['vim_password'] = args.password
tierno8008c3a2016-10-13 15:34:28 +00001059 if args.config!=None:
1060 datacenter_dict["config"] = _load_file_or_yaml(args.config)
gcalvinoc62cfa52017-10-05 18:21:25 +02001061
tierno7edb6752016-03-21 17:37:52 +01001062 payload_req = json.dumps( {"datacenter": datacenter_dict })
gcalvinoc62cfa52017-10-05 18:21:25 +02001063
tierno7edb6752016-03-21 17:37:52 +01001064 #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001065
tierno7edb6752016-03-21 17:37:52 +01001066 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter)
1067 logger.debug("openmano request: %s", payload_req)
1068 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1069 logger.debug("openmano response: %s", mano_response.text )
1070 result = _print_verbose(mano_response, args.verbose)
1071 #provide addional information if error
1072 if mano_response.status_code != 200:
1073 content = mano_response.json()
1074 if "already in use for 'name'" in content['error']['description'] and \
1075 "to database vim_tenants table" in content['error']['description']:
1076 print "Try to specify a different name with --vim-tenant-name"
1077 return result
1078
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001079
1080def datacenter_edit_vim_tenant(args):
1081 tenant = _get_tenant()
1082 datacenter = _get_datacenter(args.name)
1083 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1084
1085 if not (args.vim_tenant_id or args.vim_tenant_name or args.user or args.password or args.config):
1086 raise OpenmanoCLIError("Error. At least one parameter must be updated.")
1087
1088 datacenter_dict = {}
1089 if args.vim_tenant_id != None:
1090 datacenter_dict['vim_tenant'] = args.vim_tenant_id
1091 if args.vim_tenant_name != None:
1092 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
1093 if args.user != None:
1094 datacenter_dict['vim_username'] = args.user
1095 if args.password != None:
1096 datacenter_dict['vim_password'] = args.password
1097 if args.config != None:
1098 datacenter_dict["config"] = _load_file_or_yaml(args.config)
1099 payload_req = json.dumps({"datacenter": datacenter_dict})
1100
1101 # print payload_req
1102
1103 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" % (mano_host, mano_port, tenant, datacenter)
1104 logger.debug("openmano request: %s", payload_req)
1105 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1106 logger.debug("openmano response: %s", mano_response.text)
1107 result = _print_verbose(mano_response, args.verbose)
1108
1109 return result
1110
tierno7edb6752016-03-21 17:37:52 +01001111def datacenter_detach(args):
1112 if args.all:
1113 tenant = "any"
1114 else:
1115 tenant = _get_tenant()
1116 datacenter = _get_datacenter(args.name, tenant)
1117 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1118 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, datacenter)
1119 mano_response = requests.delete(URLrequest, headers=headers_req)
1120 logger.debug("openmano response: %s", mano_response.text )
1121 content = mano_response.json()
1122 #print json.dumps(content, indent=4)
1123 result = 0 if mano_response.status_code==200 else mano_response.status_code
1124 if mano_response.status_code == 200:
1125 print content['result']
1126 else:
1127 print content['error']['description']
1128 return result
1129
1130def datacenter_create(args):
1131 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1132 datacenter_dict={"name": args.name, "vim_url": args.url}
1133 if args.description!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001134 datacenter_dict["description"] = args.description
tierno7edb6752016-03-21 17:37:52 +01001135 if args.type!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001136 datacenter_dict["type"] = args.type
tierno7edb6752016-03-21 17:37:52 +01001137 if args.url!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001138 datacenter_dict["vim_url_admin"] = args.url_admin
tierno7edb6752016-03-21 17:37:52 +01001139 if args.config!=None:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001140 datacenter_dict["config"] = _load_file_or_yaml(args.config)
1141 if args.sdn_controller!=None:
1142 tenant = _get_tenant()
1143 sdn_controller = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1144 if not 'config' in datacenter_dict:
1145 datacenter_dict['config'] = {}
1146 datacenter_dict['config']['sdn-controller'] = sdn_controller
tierno7edb6752016-03-21 17:37:52 +01001147 payload_req = json.dumps( {"datacenter": datacenter_dict })
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001148
tierno7edb6752016-03-21 17:37:52 +01001149 #print payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001150
tierno7edb6752016-03-21 17:37:52 +01001151 URLrequest = "http://%s:%s/openmano/datacenters" %(mano_host, mano_port)
1152 logger.debug("openmano request: %s", payload_req)
1153 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1154 logger.debug("openmano response: %s", mano_response.text )
1155 return _print_verbose(mano_response, args.verbose)
1156
1157def datacenter_delete(args):
1158 #print "datacenter-delete",args
1159 todelete = _get_item_uuid("datacenters", args.name, "any")
1160 if not args.force:
1161 r = raw_input("Delete datacenter %s (y/N)? " %(args.name))
1162 if not (len(r)>0 and r[0].lower()=="y"):
1163 return 0
1164 URLrequest = "http://%s:%s/openmano/datacenters/%s" %(mano_host, mano_port, todelete)
1165 mano_response = requests.delete(URLrequest)
1166 logger.debug("openmano response: %s", mano_response.text )
1167 result = 0 if mano_response.status_code==200 else mano_response.status_code
1168 content = mano_response.json()
1169 #print json.dumps(content, indent=4)
1170 if mano_response.status_code == 200:
1171 print content['result']
1172 else:
1173 print content['error']['description']
1174 return result
1175
tierno20df3bb2017-07-07 14:31:00 +02001176
tierno7edb6752016-03-21 17:37:52 +01001177def datacenter_list(args):
1178 #print "datacenter-list",args
1179 tenant='any' if args.all else _get_tenant()
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001180
tierno7edb6752016-03-21 17:37:52 +01001181 if args.name:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001182 toshow = _get_item_uuid("datacenters", args.name, tenant)
tierno7edb6752016-03-21 17:37:52 +01001183 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s" %(mano_host, mano_port, tenant, toshow)
1184 else:
1185 URLrequest = "http://%s:%s/openmano/%s/datacenters" %(mano_host, mano_port, tenant)
1186 mano_response = requests.get(URLrequest)
1187 logger.debug("openmano response: %s", mano_response.text )
1188 if args.verbose==None:
1189 args.verbose=0
1190 if args.name!=None:
1191 args.verbose += 1
1192 return _print_verbose(mano_response, args.verbose)
1193
tierno20df3bb2017-07-07 14:31:00 +02001194
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001195def datacenter_sdn_port_mapping_set(args):
1196 tenant = _get_tenant()
1197 datacenter = _get_datacenter(args.name, tenant)
1198 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1199
1200 if not args.file:
1201 raise OpenmanoCLIError(
1202 "No yaml/json has been provided specifying the SDN port mapping")
tierno20df3bb2017-07-07 14:31:00 +02001203 sdn_port_mapping = _load_file_or_yaml(args.file)
1204 payload_req = json.dumps({"sdn_port_mapping": sdn_port_mapping})
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001205
tierno20df3bb2017-07-07 14:31:00 +02001206 # read
1207 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1208 mano_response = requests.get(URLrequest)
1209 logger.debug("openmano response: %s", mano_response.text)
1210 port_mapping = mano_response.json()
1211 if mano_response.status_code != 200:
1212 str(mano_response.json())
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001213 raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001214 if len(port_mapping["sdn_port_mapping"]["ports_mapping"]) > 0:
1215 if not args.force:
1216 r = raw_input("Datacenter %s already contains a port mapping. Overwrite? (y/N)? " % (datacenter))
1217 if not (len(r) > 0 and r[0].lower() == "y"):
1218 return 0
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001219
tierno20df3bb2017-07-07 14:31:00 +02001220 # clear
1221 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1222 mano_response = requests.delete(URLrequest)
1223 logger.debug("openmano response: %s", mano_response.text)
1224 if mano_response.status_code != 200:
1225 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001226
tierno20df3bb2017-07-07 14:31:00 +02001227 # set
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001228 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1229 logger.debug("openmano request: %s", payload_req)
1230 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1231 logger.debug("openmano response: %s", mano_response.text)
tierno20df3bb2017-07-07 14:31:00 +02001232 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001233
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001234
1235def datacenter_sdn_port_mapping_list(args):
1236 tenant = _get_tenant()
1237 datacenter = _get_datacenter(args.name, tenant)
1238
1239 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1240 mano_response = requests.get(URLrequest)
1241 logger.debug("openmano response: %s", mano_response.text)
1242
tierno20df3bb2017-07-07 14:31:00 +02001243 return _print_verbose(mano_response, 4)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001244
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001245
1246def datacenter_sdn_port_mapping_clear(args):
1247 tenant = _get_tenant()
1248 datacenter = _get_datacenter(args.name, tenant)
1249
1250 if not args.force:
1251 r = raw_input("Clean SDN port mapping for datacenter %s (y/N)? " %(datacenter))
tierno20df3bb2017-07-07 14:31:00 +02001252 if not (len(r) > 0 and r[0].lower() == "y"):
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001253 return 0
1254
1255 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/sdn_mapping" % (mano_host, mano_port, tenant, datacenter)
1256 mano_response = requests.delete(URLrequest)
1257 logger.debug("openmano response: %s", mano_response.text)
1258
tierno20df3bb2017-07-07 14:31:00 +02001259 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001260
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001261
1262def sdn_controller_create(args):
1263 tenant = _get_tenant()
1264 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1265
tierno8fe7a492017-07-11 13:50:04 +02001266 error_msg=[]
1267 if not args.ip: error_msg.append("'ip'")
1268 if not args.port: error_msg.append("'port'")
1269 if not args.dpid: error_msg.append("'dpid'")
1270 if not args.type: error_msg.append("'type'")
1271 if error_msg:
1272 raise OpenmanoCLIError("The following arguments are required: " + ",".join(error_msg))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001273
1274 controller_dict = {}
1275 controller_dict['name'] = args.name
1276 controller_dict['ip'] = args.ip
1277 controller_dict['port'] = int(args.port)
1278 controller_dict['dpid'] = args.dpid
1279 controller_dict['type'] = args.type
1280 if args.description != None:
1281 controller_dict['description'] = args.description
1282 if args.user != None:
1283 controller_dict['user'] = args.user
1284 if args.password != None:
1285 controller_dict['password'] = args.password
1286
1287 payload_req = json.dumps({"sdn_controller": controller_dict})
1288
1289 # print payload_req
1290
1291 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" % (mano_host, mano_port, tenant)
1292 logger.debug("openmano request: %s", payload_req)
1293 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1294 logger.debug("openmano response: %s", mano_response.text)
1295 result = _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001296 return result
1297
tierno20df3bb2017-07-07 14:31:00 +02001298
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001299def sdn_controller_edit(args):
1300 tenant = _get_tenant()
1301 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1302 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1303
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001304 controller_dict = {}
tierno20df3bb2017-07-07 14:31:00 +02001305 if args.new_name:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001306 controller_dict['name'] = args.new_name
tierno20df3bb2017-07-07 14:31:00 +02001307 if args.ip:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001308 controller_dict['ip'] = args.ip
tierno20df3bb2017-07-07 14:31:00 +02001309 if args.port:
Pablo Montes Morenob12711f2017-04-06 11:54:34 +02001310 controller_dict['port'] = int(args.port)
tierno20df3bb2017-07-07 14:31:00 +02001311 if args.dpid:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001312 controller_dict['dpid'] = args.dpid
tierno20df3bb2017-07-07 14:31:00 +02001313 if args.type:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001314 controller_dict['type'] = args.type
tierno20df3bb2017-07-07 14:31:00 +02001315 if args.description:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001316 controller_dict['description'] = args.description
tierno20df3bb2017-07-07 14:31:00 +02001317 if args.user:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001318 controller_dict['user'] = args.user
tierno20df3bb2017-07-07 14:31:00 +02001319 if args.password:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001320 controller_dict['password'] = args.password
1321
tierno20df3bb2017-07-07 14:31:00 +02001322 if not controller_dict:
1323 raise OpenmanoCLIError("At least one parameter must be edited")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001324
tierno20df3bb2017-07-07 14:31:00 +02001325 if not args.force:
1326 r = raw_input("Update SDN controller {} (y/N)? ".format(args.name))
1327 if not (len(r) > 0 and r[0].lower() == "y"):
1328 return 0
1329
1330 payload_req = json.dumps({"sdn_controller": controller_dict})
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001331 # print payload_req
1332
1333 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" % (mano_host, mano_port, tenant, controller_uuid)
1334 logger.debug("openmano request: %s", payload_req)
1335 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1336 logger.debug("openmano response: %s", mano_response.text)
1337 result = _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001338 return result
1339
tierno20df3bb2017-07-07 14:31:00 +02001340
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001341def sdn_controller_list(args):
1342 tenant = _get_tenant()
1343 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1344
1345 if args.name:
1346 toshow = _get_item_uuid("sdn_controllers", args.name, tenant)
1347 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" %(mano_host, mano_port, tenant, toshow)
1348 else:
1349 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers" %(mano_host, mano_port, tenant)
1350 #print URLrequest
1351 mano_response = requests.get(URLrequest)
1352 logger.debug("openmano response: %s", mano_response.text )
1353 if args.verbose==None:
1354 args.verbose=0
1355 if args.name!=None:
1356 args.verbose += 1
1357
tierno20df3bb2017-07-07 14:31:00 +02001358 # json.dumps(mano_response.json(), indent=4)
1359 return _print_verbose(mano_response, args.verbose)
1360
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001361
1362def sdn_controller_delete(args):
1363 tenant = _get_tenant()
1364 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1365
1366 if not args.force:
1367 r = raw_input("Delete SDN controller %s (y/N)? " % (args.name))
1368 if not (len(r) > 0 and r[0].lower() == "y"):
1369 return 0
1370
1371 URLrequest = "http://%s:%s/openmano/%s/sdn_controllers/%s" % (mano_host, mano_port, tenant, controller_uuid)
1372 mano_response = requests.delete(URLrequest)
1373 logger.debug("openmano response: %s", mano_response.text)
tierno20df3bb2017-07-07 14:31:00 +02001374 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001375
tierno7edb6752016-03-21 17:37:52 +01001376def vim_action(args):
1377 #print "datacenter-net-action",args
1378 tenant = _get_tenant()
1379 datacenter = _get_datacenter(args.datacenter, tenant)
1380 if args.verbose==None:
1381 args.verbose=0
1382 if args.action=="list":
1383 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
1384 if args.name!=None:
1385 args.verbose += 1
1386 URLrequest += "/" + args.name
1387 mano_response = requests.get(URLrequest)
1388 logger.debug("openmano response: %s", mano_response.text )
1389 return _print_verbose(mano_response, args.verbose)
1390 elif args.action=="delete":
1391 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss/%s" %(mano_host, mano_port, tenant, datacenter, args.item, args.name)
1392 mano_response = requests.delete(URLrequest)
1393 logger.debug("openmano response: %s", mano_response.text )
1394 result = 0 if mano_response.status_code==200 else mano_response.status_code
1395 content = mano_response.json()
1396 #print json.dumps(content, indent=4)
1397 if mano_response.status_code == 200:
1398 print content['result']
1399 else:
1400 print content['error']['description']
1401 return result
1402 elif args.action=="create":
1403 headers_req = {'content-type': 'application/yaml'}
1404 if args.file:
1405 create_dict = _load_file_or_yaml(args.file)
1406 if args.item not in create_dict:
1407 create_dict = {args.item: create_dict}
1408 else:
1409 create_dict = {args.item:{}}
1410 if args.name:
1411 create_dict[args.item]['name'] = args.name
1412 #if args.description:
1413 # create_dict[args.item]['description'] = args.description
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001414 if args.item=="network":
tierno7edb6752016-03-21 17:37:52 +01001415 if args.bind_net:
1416 create_dict[args.item]['bind_net'] = args.bind_net
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001417 if args.type:
1418 create_dict[args.item]['type'] = args.type
tierno7edb6752016-03-21 17:37:52 +01001419 if args.shared:
1420 create_dict[args.item]['shared'] = args.shared
1421 if "name" not in create_dict[args.item]:
1422 print "You must provide a name in the descriptor file or with the --name option"
1423 return
1424 payload_req = yaml.safe_dump(create_dict, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
1425 logger.debug("openmano request: %s", payload_req)
tierno72a08d72017-05-25 13:12:30 +02001426 URLrequest = "http://%s:%s/openmano/%s/vim/%s/%ss" %(mano_host, mano_port, tenant, datacenter, args.item)
tierno7edb6752016-03-21 17:37:52 +01001427 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
1428 logger.debug("openmano response: %s", mano_response.text )
1429 if args.verbose==None:
1430 args.verbose=0
1431 return _print_verbose(mano_response, args.verbose)
1432
tierno20df3bb2017-07-07 14:31:00 +02001433
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001434def _get_items(item, item_name_id=None, datacenter=None, tenant=None):
1435 URLrequest = "http://%s:%s/openmano" %(mano_host, mano_port)
1436 if tenant:
1437 URLrequest += "/" + tenant
1438 if datacenter:
1439 URLrequest += "/vim/" + datacenter
1440 if item:
1441 URLrequest += "/" + item +"s"
1442 if item_name_id:
1443 URLrequest += "/" + item_name_id
1444 mano_response = requests.get(URLrequest)
1445 logger.debug("openmano response: %s", mano_response.text )
1446
1447 return mano_response
1448
tierno20df3bb2017-07-07 14:31:00 +02001449
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001450def vim_net_sdn_attach(args):
1451 #Verify the network exists in the vim
1452 tenant = _get_tenant()
1453 datacenter = _get_datacenter(args.datacenter, tenant)
1454 result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
1455 content = yaml.load(result.content)
1456 if 'networks' in content:
1457 raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
1458 if 'error' in content:
1459 raise OpenmanoCLIError(yaml.safe_dump(content))
1460 network_uuid = content['network']['id']
1461
1462 #Make call to attach the dataplane port to the SND network associated to the vim network
1463 headers_req = {'content-type': 'application/yaml'}
1464 payload_req = {'port': args.port}
1465 if args.vlan:
1466 payload_req['vlan'] = int(args.vlan)
1467 if args.mac:
1468 payload_req['mac'] = args.mac
1469
1470 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/attach" % (mano_host, mano_port, tenant, datacenter, network_uuid)
1471 logger.debug("openmano request: %s", payload_req)
1472 mano_response = requests.post(URLrequest, headers=headers_req, data=json.dumps(payload_req))
1473 logger.debug("openmano response: %s", mano_response.text)
1474 result = _print_verbose(mano_response, args.verbose)
tierno20df3bb2017-07-07 14:31:00 +02001475 return result
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001476
1477
1478def vim_net_sdn_detach(args):
1479 if not args.all and not args.id:
1480 print "--all or --id must be used"
1481 return 1
1482
1483 # Verify the network exists in the vim
1484 tenant = _get_tenant()
1485 datacenter = _get_datacenter(args.datacenter, tenant)
1486 result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
1487 content = yaml.load(result.content)
1488 if 'networks' in content:
1489 raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
1490 if 'error' in content:
1491 raise OpenmanoCLIError(yaml.safe_dump(content))
1492 network_uuid = content['network']['id']
1493
1494 if not args.force:
1495 r = raw_input("Confirm action' (y/N)? ")
1496 if len(r) == 0 or r[0].lower() != "y":
1497 return 0
1498
1499 if args.id:
1500 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach/%s" % (
1501 mano_host, mano_port, tenant, datacenter, network_uuid, args.id)
1502 else:
1503 URLrequest = "http://%s:%s/openmano/%s/vim/%s/network/%s/detach" % (
1504 mano_host, mano_port, tenant, datacenter, network_uuid)
1505 mano_response = requests.delete(URLrequest)
1506 logger.debug("openmano response: %s", mano_response.text)
1507 result = _print_verbose(mano_response, args.verbose)
tierno20df3bb2017-07-07 14:31:00 +02001508 return result
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001509
tierno7edb6752016-03-21 17:37:52 +01001510
1511def datacenter_net_action(args):
1512 if args.action == "net-update":
tierno5acf7202016-08-29 14:28:13 +02001513 print "This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano datacenter-netmap-import' instead!!!"
tierno7edb6752016-03-21 17:37:52 +01001514 print
1515 args.action = "netmap-delete"
1516 args.netmap = None
1517 args.all = True
1518 r = datacenter_netmap_action(args)
1519 if r == 0:
1520 args.force = True
tierno5acf7202016-08-29 14:28:13 +02001521 args.action = "netmap-import"
tierno7edb6752016-03-21 17:37:52 +01001522 r = datacenter_netmap_action(args)
1523 return r
1524
1525 if args.action == "net-edit":
1526 args.netmap = args.net
1527 args.name = None
1528 elif args.action == "net-list":
1529 args.netmap = None
1530 elif args.action == "net-delete":
1531 args.netmap = args.net
1532 args.all = False
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001533
tierno7edb6752016-03-21 17:37:52 +01001534 args.action = "netmap" + args.action[3:]
1535 args.vim_name=None
1536 args.vim_id=None
1537 print "This command is deprecated, use 'openmano datacenter-%s' instead!!!" % args.action
1538 print
1539 return datacenter_netmap_action(args)
1540
1541def datacenter_netmap_action(args):
1542 tenant = _get_tenant()
1543 datacenter = _get_datacenter(args.datacenter, tenant)
1544 #print "datacenter_netmap_action",args
1545 payload_req = None
1546 if args.verbose==None:
1547 args.verbose=0
1548 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1549 URLrequest = "http://%s:%s/openmano/%s/datacenters/%s/netmaps" %(mano_host, mano_port, tenant, datacenter)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001550
tierno7edb6752016-03-21 17:37:52 +01001551 if args.action=="netmap-list":
1552 if args.netmap:
1553 URLrequest += "/" + args.netmap
1554 args.verbose += 1
1555 mano_response = requests.get(URLrequest)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001556
tierno7edb6752016-03-21 17:37:52 +01001557 elif args.action=="netmap-delete":
1558 if args.netmap and args.all:
1559 print "you can not use a netmap name and the option --all at the same time"
1560 return 1
1561 if args.netmap:
1562 force_text= "Delete default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter)
1563 URLrequest += "/" + args.netmap
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001564 elif args.all:
tierno7edb6752016-03-21 17:37:52 +01001565 force_text="Delete all default netmaps from datacenter '%s' (y/N)? " % (datacenter)
1566 else:
tiernoae4a8d12016-07-08 12:30:39 +02001567 print "you must specify a netmap name or the option --all"
tierno7edb6752016-03-21 17:37:52 +01001568 return 1
1569 if not args.force:
1570 r = raw_input(force_text)
1571 if len(r)>0 and r[0].lower()=="y":
1572 pass
1573 else:
1574 return 0
1575 mano_response = requests.delete(URLrequest, headers=headers_req)
tierno5acf7202016-08-29 14:28:13 +02001576 elif args.action=="netmap-import":
tierno7edb6752016-03-21 17:37:52 +01001577 if not args.force:
1578 r = raw_input("Create all the available networks from datacenter '%s' as default netmaps (y/N)? " % (datacenter))
1579 if len(r)>0 and r[0].lower()=="y":
1580 pass
1581 else:
1582 return 0
1583 URLrequest += "/upload"
1584 mano_response = requests.post(URLrequest, headers=headers_req)
1585 elif args.action=="netmap-edit" or args.action=="netmap-create":
1586 if args.file:
1587 payload = _load_file_or_yaml(args.file)
1588 else:
1589 payload = {}
1590 if "netmap" not in payload:
1591 payload = {"netmap": payload}
1592 if args.name:
1593 payload["netmap"]["name"] = args.name
1594 if args.vim_id:
1595 payload["netmap"]["vim_id"] = args.vim_id
1596 if args.action=="netmap-create" and args.vim_name:
1597 payload["netmap"]["vim_name"] = args.vim_name
1598 payload_req = json.dumps(payload)
1599 logger.debug("openmano request: %s", payload_req)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001600
tierno7edb6752016-03-21 17:37:52 +01001601 if args.action=="netmap-edit" and not args.force:
1602 if len(payload["netmap"]) == 0:
1603 print "You must supply some parameter to edit"
1604 return 1
1605 r = raw_input("Edit default netmap '%s' from datacenter '%s' (y/N)? " % (args.netmap, datacenter))
1606 if len(r)>0 and r[0].lower()=="y":
1607 pass
1608 else:
1609 return 0
1610 URLrequest += "/" + args.netmap
1611 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1612 else: #netmap-create
1613 if "vim_name" not in payload["netmap"] and "vim_id" not in payload["netmap"]:
1614 print "You must supply either --vim-id or --vim-name option; or include one of them in the file descriptor"
1615 return 1
1616 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1617
1618 logger.debug("openmano response: %s", mano_response.text )
1619 return _print_verbose(mano_response, args.verbose)
1620
tierno20df3bb2017-07-07 14:31:00 +02001621
tierno7edb6752016-03-21 17:37:52 +01001622def element_edit(args):
1623 element = _get_item_uuid(args.element, args.name)
1624 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1625 URLrequest = "http://%s:%s/openmano/%s/%s" %(mano_host, mano_port, args.element, element)
1626 payload=_load_file_or_yaml(args.file)
1627 if args.element[:-1] not in payload:
1628 payload = {args.element[:-1]: payload }
1629 payload_req = json.dumps(payload)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001630
tierno7edb6752016-03-21 17:37:52 +01001631 #print payload_req
1632 if not args.force or (args.name==None and args.filer==None):
1633 r = raw_input(" Edit " + args.element[:-1] + " " + args.name + " (y/N)? ")
1634 if len(r)>0 and r[0].lower()=="y":
1635 pass
1636 else:
1637 return 0
1638 logger.debug("openmano request: %s", payload_req)
1639 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1640 logger.debug("openmano response: %s", mano_response.text )
1641 if args.verbose==None:
1642 args.verbose=0
1643 if args.name!=None:
1644 args.verbose += 1
1645 return _print_verbose(mano_response, args.verbose)
1646
1647
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001648def datacenter_edit(args):
1649 tenant = _get_tenant()
1650 element = _get_item_uuid('datacenters', args.name, tenant)
1651 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1652 URLrequest = "http://%s:%s/openmano/datacenters/%s" % (mano_host, mano_port, element)
1653
1654 has_arguments = False
1655 if args.file != None:
1656 has_arguments = True
1657 payload = _load_file_or_yaml(args.file)
1658 else:
1659 payload = {}
1660
1661 if args.sdn_controller != None:
1662 has_arguments = True
1663 if not 'config' in payload:
1664 payload['config'] = {}
1665 if not 'sdn-controller' in payload['config']:
1666 payload['config']['sdn-controller'] = {}
1667 if args.sdn_controller == 'null':
1668 payload['config']['sdn-controller'] = None
1669 else:
1670 payload['config']['sdn-controller'] = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1671
1672 if not has_arguments:
1673 raise OpenmanoCLIError("At least one argument must be provided to modify the datacenter")
1674
1675 if 'datacenter' not in payload:
1676 payload = {'datacenter': payload}
1677 payload_req = json.dumps(payload)
1678
1679 # print payload_req
1680 if not args.force or (args.name == None and args.filer == None):
1681 r = raw_input(" Edit datacenter " + args.name + " (y/N)? ")
1682 if len(r) > 0 and r[0].lower() == "y":
1683 pass
1684 else:
1685 return 0
1686 logger.debug("openmano request: %s", payload_req)
1687 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1688 logger.debug("openmano response: %s", mano_response.text)
1689 if args.verbose == None:
1690 args.verbose = 0
1691 if args.name != None:
1692 args.verbose += 1
1693 return _print_verbose(mano_response, args.verbose)
1694
tierno20df3bb2017-07-07 14:31:00 +02001695
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001696# WIM
1697def wim_account_create(args):
1698 tenant = _get_tenant()
1699 wim = _get_wim(args.name)
1700 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1701
1702 wim_dict = {}
1703 if args.account_name is not None:
1704 wim_dict['name'] = args.account_name
1705 if args.user is not None:
1706 wim_dict['user'] = args.user
1707 if args.password is not None:
1708 wim_dict['password'] = args.password
1709 if args.config is not None:
1710 wim_dict["config"] = _load_file_or_yaml(args.config)
1711
1712 payload_req = json.dumps({"wim_account": wim_dict})
1713
1714 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim)
1715 logger.debug("openmano request: %s", payload_req)
1716 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1717 logger.debug("openmano response: %s", mano_response.text)
1718 result = _print_verbose(mano_response, args.verbose)
1719 # provide addional information if error
1720 if mano_response.status_code != 200:
1721 content = mano_response.json()
1722 if "already in use for 'name'" in content['error']['description'] and \
1723 "to database wim_tenants table" in content['error']['description']:
1724 print "Try to specify a different name with --wim-tenant-name"
1725 return result
1726
1727
1728def wim_account_delete(args):
1729 if args.all:
1730 tenant = "any"
1731 else:
1732 tenant = _get_tenant()
1733 wim = _get_wim(args.name, tenant)
1734 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1735 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim)
1736 mano_response = requests.delete(URLrequest, headers=headers_req)
1737 logger.debug("openmano response: %s", mano_response.text)
1738 content = mano_response.json()
1739 # print json.dumps(content, indent=4)
1740 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1741 if mano_response.status_code == 200:
1742 print content['result']
1743 else:
1744 print content['error']['description']
1745 return result
1746
1747
1748def wim_account_edit(args):
1749 tenant = _get_tenant()
1750 wim = _get_wim(args.name)
1751 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1752
1753 wim_dict = {}
1754 if not args.account_name:
1755 wim_dict['name'] = args.vim_tenant_name
1756 if not args.user:
1757 wim_dict['user'] = args.user
1758 if not args.password:
1759 wim_dict['password'] = args.password
1760 if not args.config:
1761 wim_dict["config"] = _load_file_or_yaml(args.config)
1762
1763 payload_req = json.dumps({"wim_account": wim_dict})
1764
1765 # print payload_req
1766
1767 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, wim)
1768 logger.debug("openmano request: %s", payload_req)
1769 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1770 logger.debug("openmano response: %s", mano_response.text)
1771 result = _print_verbose(mano_response, args.verbose)
1772 # provide addional information if error
1773 if mano_response.status_code != 200:
1774 content = mano_response.json()
1775 if "already in use for 'name'" in content['error']['description'] and \
1776 "to database wim_tenants table" in content['error']['description']:
1777 print "Try to specify a different name with --wim-tenant-name"
1778 return result
1779
1780def wim_create(args):
1781 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1782 wim_dict = {"name": args.name, "wim_url": args.url}
1783 if args.description != None:
1784 wim_dict["description"] = args.description
1785 if args.type != None:
1786 wim_dict["type"] = args.type
1787 if args.config != None:
1788 wim_dict["config"] = _load_file_or_yaml(args.config)
1789
1790 payload_req = json.dumps({"wim": wim_dict})
1791
1792 URLrequest = "http://%s:%s/openmano/wims" % (mano_host, mano_port)
1793 logger.debug("openmano request: %s", payload_req)
1794 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1795 logger.debug("openmano response: %s", mano_response.text)
1796 return _print_verbose(mano_response, args.verbose)
1797
1798
1799def wim_edit(args):
1800 tenant = _get_tenant()
1801 element = _get_item_uuid('wims', args.name, tenant)
1802 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1803 URLrequest = "http://%s:%s/openmano/wims/%s" % (mano_host, mano_port, element)
1804
1805 has_arguments = False
1806 if args.file != None:
1807 has_arguments = True
1808 payload = _load_file_or_yaml(args.file)
1809 else:
1810 payload = {}
1811
1812 if not has_arguments:
1813 raise OpenmanoCLIError("At least one argument must be provided to modify the wim")
1814
1815 if 'wim' not in payload:
1816 payload = {'wim': payload}
1817 payload_req = json.dumps(payload)
1818
1819 # print payload_req
1820 if not args.force or (args.name == None and args.filer == None):
1821 r = raw_input(" Edit wim " + args.name + " (y/N)? ")
1822 if len(r) > 0 and r[0].lower() == "y":
1823 pass
1824 else:
1825 return 0
1826 logger.debug("openmano request: %s", payload_req)
1827 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1828 logger.debug("openmano response: %s", mano_response.text)
1829 if args.verbose == None:
1830 args.verbose = 0
1831 if args.name != None:
1832 args.verbose += 1
1833 return _print_verbose(mano_response, args.verbose)
1834
1835
1836def wim_delete(args):
1837 # print "wim-delete",args
1838 todelete = _get_item_uuid("wims", args.name, "any")
1839 if not args.force:
1840 r = raw_input("Delete wim %s (y/N)? " % (args.name))
1841 if not (len(r) > 0 and r[0].lower() == "y"):
1842 return 0
1843 URLrequest = "http://%s:%s/openmano/wims/%s" % (mano_host, mano_port, todelete)
1844 mano_response = requests.delete(URLrequest)
1845 logger.debug("openmano response: %s", mano_response.text)
1846 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1847 content = mano_response.json()
1848 # print json.dumps(content, indent=4)
1849 if mano_response.status_code == 200:
1850 print content['result']
1851 else:
1852 print content['error']['description']
1853 return result
1854
1855
1856def wim_list(args):
1857 # print "wim-list",args
1858 tenant = 'any' if args.all else _get_tenant()
1859
1860 if args.name:
1861 toshow = _get_item_uuid("wims", args.name, tenant)
1862 URLrequest = "http://%s:%s/openmano/%s/wims/%s" % (mano_host, mano_port, tenant, toshow)
1863 else:
1864 URLrequest = "http://%s:%s/openmano/%s/wims" % (mano_host, mano_port, tenant)
1865 mano_response = requests.get(URLrequest)
1866 logger.debug("openmano response: %s", mano_response.text)
1867 if args.verbose == None:
1868 args.verbose = 0
1869 if args.name != None:
1870 args.verbose += 1
1871 return _print_verbose(mano_response, args.verbose)
1872
1873
1874def wim_port_mapping_set(args):
1875 tenant = _get_tenant()
1876 wim = _get_wim(args.name, tenant)
1877 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1878
1879 if not args.file:
1880 raise OpenmanoCLIError(
1881 "No yaml/json has been provided specifying the WIM port mapping")
1882 wim_port_mapping = _load_file_or_yaml(args.file)
1883
1884 payload_req = json.dumps({"wim_port_mapping": wim_port_mapping})
1885
1886 # read
1887 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1888 mano_response = requests.get(URLrequest)
1889 logger.debug("openmano response: %s", mano_response.text)
1890 port_mapping = mano_response.json()
1891
1892 if mano_response.status_code != 200:
1893 str(mano_response.json())
1894 raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
1895 # TODO: check this if statement
1896 if len(port_mapping["wim_port_mapping"]) > 0:
1897 if not args.force:
1898 r = raw_input("WIM %s already contains a port mapping. Overwrite? (y/N)? " % (wim))
1899 if not (len(r) > 0 and r[0].lower() == "y"):
1900 return 0
1901
1902 # clear
1903 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1904 mano_response = requests.delete(URLrequest)
1905 logger.debug("openmano response: %s", mano_response.text)
1906 if mano_response.status_code != 200:
1907 return _print_verbose(mano_response, args.verbose)
1908
1909 # set
1910 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1911 logger.debug("openmano request: %s", payload_req)
1912 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1913 logger.debug("openmano response: %s", mano_response.text)
1914 return _print_verbose(mano_response, 4)
1915
1916
1917def wim_port_mapping_list(args):
1918 tenant = _get_tenant()
1919 wim = _get_wim(args.name, tenant)
1920
1921 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1922 mano_response = requests.get(URLrequest)
1923 logger.debug("openmano response: %s", mano_response.text)
1924
1925 return _print_verbose(mano_response, 4)
1926
1927
1928def wim_port_mapping_clear(args):
1929 tenant = _get_tenant()
1930 wim = _get_wim(args.name, tenant)
1931
1932 if not args.force:
1933 r = raw_input("Clear WIM port mapping for wim %s (y/N)? " % (wim))
1934 if not (len(r) > 0 and r[0].lower() == "y"):
1935 return 0
1936
1937 URLrequest = "http://%s:%s/openmano/%s/wims/%s/port_mapping" % (mano_host, mano_port, tenant, wim)
1938 mano_response = requests.delete(URLrequest)
1939 logger.debug("openmano response: %s", mano_response.text)
1940 content = mano_response.json()
1941 # print json.dumps(content, indent=4)
1942 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1943 if mano_response.status_code == 200:
1944 print content['result']
1945 else:
1946 print content['error']['description']
1947 return result
1948
1949
tierno6ddeded2017-05-16 15:40:26 +02001950def version(args):
1951 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1952 URLrequest = "http://%s:%s/openmano/version" % (mano_host, mano_port)
1953
1954 mano_response = requests.get(URLrequest, headers=headers_req)
1955 logger.debug("openmano response: %s", mano_response.text)
1956 print mano_response.text
1957
1958
tierno7edb6752016-03-21 17:37:52 +01001959global mano_host
1960global mano_port
1961global mano_tenant
1962
1963if __name__=="__main__":
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001964
tierno7edb6752016-03-21 17:37:52 +01001965 mano_tenant = os.getenv('OPENMANO_TENANT', None)
1966 mano_host = os.getenv('OPENMANO_HOST',"localhost")
1967 mano_port = os.getenv('OPENMANO_PORT',"9090")
1968 mano_datacenter = os.getenv('OPENMANO_DATACENTER',None)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001969 # WIM env variable for default WIM
1970 mano_wim = os.getenv('OPENMANO_WIM', None)
1971
tierno7edb6752016-03-21 17:37:52 +01001972 main_parser = ThrowingArgumentParser(description='User program to interact with OPENMANO-SERVER (openmanod)')
tierno6ddeded2017-05-16 15:40:26 +02001973 main_parser.add_argument('--version', action='version', help="get version of this client",
1974 version='%(prog)s client version ' + __version__ +
1975 " (Note: use '%(prog)s version' to get server version)")
1976
tierno7edb6752016-03-21 17:37:52 +01001977 subparsers = main_parser.add_subparsers(help='commands')
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001978
tierno7edb6752016-03-21 17:37:52 +01001979 parent_parser = argparse.ArgumentParser(add_help=False)
1980 parent_parser.add_argument('--verbose', '-v', action='count', help="increase verbosity level. Use several times")
1981 parent_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
1982
garciadeblas0e9fd832016-07-08 15:20:18 +02001983 config_parser = subparsers.add_parser('config', parents=[parent_parser], help="prints configuration values")
1984 config_parser.add_argument("-n", action="store_true", help="resolves tenant and datacenter names")
1985 config_parser.set_defaults(func=config)
1986
tierno6ddeded2017-05-16 15:40:26 +02001987 version_parser = subparsers.add_parser('version', parents=[parent_parser], help="get server version")
1988 version_parser.set_defaults(func=version)
1989
tierno7edb6752016-03-21 17:37:52 +01001990 vnf_create_parser = subparsers.add_parser('vnf-create', parents=[parent_parser], help="adds a vnf into the catalogue")
1991 vnf_create_parser.add_argument("file", action="store", help="location of the JSON file describing the VNF").completer = FilesCompleter
1992 vnf_create_parser.add_argument("--name", action="store", help="name of the VNF (if it exists in the VNF descriptor, it is overwritten)")
1993 vnf_create_parser.add_argument("--description", action="store", help="description of the VNF (if it exists in the VNF descriptor, it is overwritten)")
1994 vnf_create_parser.add_argument("--image-path", action="store", help="change image path locations (overwritten)")
garciadeblas14480452017-01-10 13:08:07 +01001995 vnf_create_parser.add_argument("--image-name", action="store", help="change image name (overwritten)")
1996 vnf_create_parser.add_argument("--image-checksum", action="store", help="change image checksum (overwritten)")
tierno7edb6752016-03-21 17:37:52 +01001997 vnf_create_parser.set_defaults(func=vnf_create)
1998
1999 vnf_list_parser = subparsers.add_parser('vnf-list', parents=[parent_parser], help="lists information about a vnf")
2000 vnf_list_parser.add_argument("name", nargs='?', help="name of the VNF")
2001 vnf_list_parser.add_argument("-a", "--all", action="store_true", help="shows all vnfs, not only the owned or public ones")
2002 #vnf_list_parser.add_argument('--descriptor', help="prints the VNF descriptor", action="store_true")
2003 vnf_list_parser.set_defaults(func=vnf_list)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002004
tierno7edb6752016-03-21 17:37:52 +01002005 vnf_delete_parser = subparsers.add_parser('vnf-delete', parents=[parent_parser], help="deletes a vnf from the catalogue")
2006 vnf_delete_parser.add_argument("name", action="store", help="name or uuid of the VNF to be deleted")
2007 vnf_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2008 vnf_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2009 vnf_delete_parser.set_defaults(func=vnf_delete)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002010
tierno7edb6752016-03-21 17:37:52 +01002011 scenario_create_parser = subparsers.add_parser('scenario-create', parents=[parent_parser], help="adds a scenario into the OPENMANO DB")
2012 scenario_create_parser.add_argument("file", action="store", help="location of the YAML file describing the scenario").completer = FilesCompleter
2013 scenario_create_parser.add_argument("--name", action="store", help="name of the scenario (if it exists in the YAML scenario, it is overwritten)")
2014 scenario_create_parser.add_argument("--description", action="store", help="description of the scenario (if it exists in the YAML scenario, it is overwritten)")
2015 scenario_create_parser.set_defaults(func=scenario_create)
2016
2017 scenario_list_parser = subparsers.add_parser('scenario-list', parents=[parent_parser], help="lists information about a scenario")
2018 scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario")
2019 #scenario_list_parser.add_argument('--descriptor', help="prints the scenario descriptor", action="store_true")
2020 scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all scenarios, not only the owned or public ones")
2021 scenario_list_parser.set_defaults(func=scenario_list)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002022
tierno7edb6752016-03-21 17:37:52 +01002023 scenario_delete_parser = subparsers.add_parser('scenario-delete', parents=[parent_parser], help="deletes a scenario from the OPENMANO DB")
2024 scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario to be deleted")
2025 scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2026 scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2027 scenario_delete_parser.set_defaults(func=scenario_delete)
2028
2029 scenario_deploy_parser = subparsers.add_parser('scenario-deploy', parents=[parent_parser], help="deploys a scenario")
2030 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be deployed")
2031 scenario_deploy_parser.add_argument("name", action="store", help="name of the instance")
2032 scenario_deploy_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
2033 scenario_deploy_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
2034 scenario_deploy_parser.add_argument("--description", action="store", help="description of the instance")
2035 scenario_deploy_parser.set_defaults(func=scenario_deploy)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002036
tierno7edb6752016-03-21 17:37:52 +01002037 scenario_deploy_parser = subparsers.add_parser('scenario-verify', help="verifies if a scenario can be deployed (deploys it and deletes it)")
2038 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be verified")
2039 scenario_deploy_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
2040 scenario_deploy_parser.set_defaults(func=scenario_verify)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002041
tierno7edb6752016-03-21 17:37:52 +01002042 instance_scenario_create_parser = subparsers.add_parser('instance-scenario-create', parents=[parent_parser], help="deploys a scenario")
2043 instance_scenario_create_parser.add_argument("file", nargs='?', help="descriptor of the instance. Must be a file or yaml/json text")
2044 instance_scenario_create_parser.add_argument("--scenario", action="store", help="name or uuid of the scenario to be deployed")
2045 instance_scenario_create_parser.add_argument("--name", action="store", help="name of the instance")
2046 instance_scenario_create_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
2047 instance_scenario_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
2048 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")
2049 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 +02002050 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")
2051 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 +01002052 instance_scenario_create_parser.add_argument("--description", action="store", help="description of the instance")
2053 instance_scenario_create_parser.set_defaults(func=instance_create)
2054
2055 instance_scenario_list_parser = subparsers.add_parser('instance-scenario-list', parents=[parent_parser], help="lists information about a scenario instance")
2056 instance_scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario instance")
2057 instance_scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all instance-scenarios, not only the owned")
2058 instance_scenario_list_parser.set_defaults(func=instance_scenario_list)
2059
2060 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)")
2061 instance_scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario instance to be deleted")
2062 instance_scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2063 instance_scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2064 instance_scenario_delete_parser.set_defaults(func=instance_scenario_delete)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002065
tierno7edb6752016-03-21 17:37:52 +01002066 instance_scenario_action_parser = subparsers.add_parser('instance-scenario-action', parents=[parent_parser], help="invoke an action over part or the whole scenario instance")
2067 instance_scenario_action_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
2068 instance_scenario_action_parser.add_argument("action", action="store", type=str, \
tiernofc5f80b2018-05-29 16:00:43 +02002069 choices=["start","pause","resume","shutoff","shutdown","forceOff","rebuild","reboot", "console", "add_public_key","vdu-scaling"],\
tierno7edb6752016-03-21 17:37:52 +01002070 help="action to send")
tiernofc5f80b2018-05-29 16:00:43 +02002071 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 +01002072 instance_scenario_action_parser.add_argument("--vnf", action="append", help="VNF to act on (can use several entries)")
2073 instance_scenario_action_parser.add_argument("--vm", action="append", help="VM to act on (can use several entries)")
2074 instance_scenario_action_parser.set_defaults(func=instance_scenario_action)
2075
tierno868220c2017-09-26 00:11:05 +02002076 action_parser = subparsers.add_parser('action-list', parents=[parent_parser], help="get action over an instance status")
2077 action_parser.add_argument("id", nargs='?', action="store", help="action id")
2078 action_parser.add_argument("--instance", action="store", help="fitler by this instance_id")
2079 action_parser.add_argument("--all", action="store", help="Not filter by tenant")
2080 action_parser.set_defaults(func=get_action)
2081
tierno7edb6752016-03-21 17:37:52 +01002082 #instance_scenario_status_parser = subparsers.add_parser('instance-scenario-status', help="show the status of a scenario instance")
2083 #instance_scenario_status_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
2084 #instance_scenario_status_parser.set_defaults(func=instance_scenario_status)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002085
tierno7edb6752016-03-21 17:37:52 +01002086 tenant_create_parser = subparsers.add_parser('tenant-create', parents=[parent_parser], help="creates a new tenant")
2087 tenant_create_parser.add_argument("name", action="store", help="name for the tenant")
2088 tenant_create_parser.add_argument("--description", action="store", help="description of the tenant")
2089 tenant_create_parser.set_defaults(func=tenant_create)
2090
2091 tenant_delete_parser = subparsers.add_parser('tenant-delete', parents=[parent_parser], help="deletes a tenant from the catalogue")
2092 tenant_delete_parser.add_argument("name", action="store", help="name or uuid of the tenant to be deleted")
2093 tenant_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2094 tenant_delete_parser.set_defaults(func=tenant_delete)
2095
2096 tenant_list_parser = subparsers.add_parser('tenant-list', parents=[parent_parser], help="lists information about a tenant")
2097 tenant_list_parser.add_argument("name", nargs='?', help="name or uuid of the tenant")
2098 tenant_list_parser.set_defaults(func=tenant_list)
2099
tierno161c24b2017-05-16 15:45:56 +02002100 element_edit_parser = subparsers.add_parser('tenant-edit', parents=[parent_parser], help="edits one tenant")
2101 element_edit_parser.add_argument("name", help="name or uuid of the tenant")
2102 element_edit_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
2103 element_edit_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2104 element_edit_parser.set_defaults(func=element_edit, element='tenants')
tierno7edb6752016-03-21 17:37:52 +01002105
2106 datacenter_create_parser = subparsers.add_parser('datacenter-create', parents=[parent_parser], help="creates a new datacenter")
2107 datacenter_create_parser.add_argument("name", action="store", help="name for the datacenter")
2108 datacenter_create_parser.add_argument("url", action="store", help="url for the datacenter")
2109 datacenter_create_parser.add_argument("--url_admin", action="store", help="url for administration for the datacenter")
2110 datacenter_create_parser.add_argument("--type", action="store", help="datacenter type: openstack or openvim (default)")
2111 datacenter_create_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
2112 datacenter_create_parser.add_argument("--description", action="store", help="description of the datacenter")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002113 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 +01002114 datacenter_create_parser.set_defaults(func=datacenter_create)
2115
2116 datacenter_delete_parser = subparsers.add_parser('datacenter-delete', parents=[parent_parser], help="deletes a datacenter from the catalogue")
2117 datacenter_delete_parser.add_argument("name", action="store", help="name or uuid of the datacenter to be deleted")
2118 datacenter_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2119 datacenter_delete_parser.set_defaults(func=datacenter_delete)
2120
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002121 datacenter_edit_parser = subparsers.add_parser('datacenter-edit', parents=[parent_parser], help="Edit datacenter")
2122 datacenter_edit_parser.add_argument("name", help="name or uuid of the datacenter")
2123 datacenter_edit_parser.add_argument("--file", help="json/yaml text or file with the changes").completer = FilesCompleter
2124 datacenter_edit_parser.add_argument("--sdn-controller", action="store",
2125 help="Name or uuid of the SDN controller to be used. Specify 'null' to clear entry", dest='sdn_controller')
2126 datacenter_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
2127 datacenter_edit_parser.set_defaults(func=datacenter_edit)
2128
tierno7edb6752016-03-21 17:37:52 +01002129 datacenter_list_parser = subparsers.add_parser('datacenter-list', parents=[parent_parser], help="lists information about a datacenter")
2130 datacenter_list_parser.add_argument("name", nargs='?', help="name or uuid of the datacenter")
2131 datacenter_list_parser.add_argument("-a", "--all", action="store_true", help="shows all datacenters, not only datacenters attached to tenant")
2132 datacenter_list_parser.set_defaults(func=datacenter_list)
2133
2134 datacenter_attach_parser = subparsers.add_parser('datacenter-attach', parents=[parent_parser], help="associates a datacenter to the operating tenant")
2135 datacenter_attach_parser.add_argument("name", help="name or uuid of the datacenter")
2136 datacenter_attach_parser.add_argument('--vim-tenant-id', action='store', help="specify a datacenter tenant to use. A new one is created by default")
2137 datacenter_attach_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
2138 datacenter_attach_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
2139 datacenter_attach_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
tierno8008c3a2016-10-13 15:34:28 +00002140 datacenter_attach_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
tierno7edb6752016-03-21 17:37:52 +01002141 datacenter_attach_parser.set_defaults(func=datacenter_attach)
2142
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002143 datacenter_edit_vim_tenant_parser = subparsers.add_parser('datacenter-edit-vim-tenant', parents=[parent_parser],
2144 help="Edit the association of a datacenter to the operating tenant")
2145 datacenter_edit_vim_tenant_parser.add_argument("name", help="name or uuid of the datacenter")
2146 datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-id', action='store',
2147 help="specify a datacenter tenant to use. A new one is created by default")
2148 datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
2149 datacenter_edit_vim_tenant_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
2150 datacenter_edit_vim_tenant_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
2151 datacenter_edit_vim_tenant_parser.add_argument("--config", action="store",
2152 help="aditional configuration in json/yaml format")
2153 datacenter_edit_vim_tenant_parser.set_defaults(func=datacenter_edit_vim_tenant)
2154
tierno7edb6752016-03-21 17:37:52 +01002155 datacenter_detach_parser = subparsers.add_parser('datacenter-detach', parents=[parent_parser], help="removes the association between a datacenter and the operating tenant")
2156 datacenter_detach_parser.add_argument("name", help="name or uuid of the datacenter")
2157 datacenter_detach_parser.add_argument("-a", "--all", action="store_true", help="removes all associations from this datacenter")
2158 datacenter_detach_parser.set_defaults(func=datacenter_detach)
2159
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002160 #=======================datacenter_sdn_port_mapping_xxx section=======================
2161 #datacenter_sdn_port_mapping_set
2162 datacenter_sdn_port_mapping_set_parser = subparsers.add_parser('datacenter-sdn-port-mapping-set',
2163 parents=[parent_parser],
2164 help="Load a file with the mapping of physical ports "
2165 "and the ports of the dataplaneswitch controlled "
2166 "by a datacenter")
2167 datacenter_sdn_port_mapping_set_parser.add_argument("name", action="store", help="specifies the datacenter")
2168 datacenter_sdn_port_mapping_set_parser.add_argument("file",
2169 help="json/yaml text or file with the port mapping").completer = FilesCompleter
2170 datacenter_sdn_port_mapping_set_parser.add_argument("-f", "--force", action="store_true",
2171 help="forces overwriting without asking")
2172 datacenter_sdn_port_mapping_set_parser.set_defaults(func=datacenter_sdn_port_mapping_set)
2173
2174 #datacenter_sdn_port_mapping_list
2175 datacenter_sdn_port_mapping_list_parser = subparsers.add_parser('datacenter-sdn-port-mapping-list',
2176 parents=[parent_parser],
2177 help="Show the SDN port mapping in a datacenter")
2178 datacenter_sdn_port_mapping_list_parser.add_argument("name", action="store", help="specifies the datacenter")
2179 datacenter_sdn_port_mapping_list_parser.set_defaults(func=datacenter_sdn_port_mapping_list)
2180
2181 # datacenter_sdn_port_mapping_clear
2182 datacenter_sdn_port_mapping_clear_parser = subparsers.add_parser('datacenter-sdn-port-mapping-clear',
2183 parents=[parent_parser],
2184 help="Clean the the SDN port mapping in a datacenter")
2185 datacenter_sdn_port_mapping_clear_parser.add_argument("name", action="store",
2186 help="specifies the datacenter")
2187 datacenter_sdn_port_mapping_clear_parser.add_argument("-f", "--force", action="store_true",
2188 help="forces clearing without asking")
2189 datacenter_sdn_port_mapping_clear_parser.set_defaults(func=datacenter_sdn_port_mapping_clear)
2190 # =======================
2191
2192 # =======================sdn_controller_xxx section=======================
2193 # sdn_controller_create
2194 sdn_controller_create_parser = subparsers.add_parser('sdn-controller-create', parents=[parent_parser],
2195 help="Creates an SDN controller entity within RO")
2196 sdn_controller_create_parser.add_argument("name", help="name of the SDN controller")
2197 sdn_controller_create_parser.add_argument("--description", action="store", help="description of the SDN controller")
2198 sdn_controller_create_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
2199 sdn_controller_create_parser.add_argument("--port", action="store", help="Port of the SDN controller")
2200 sdn_controller_create_parser.add_argument("--dpid", action="store",
2201 help="DPID of the dataplane switch controlled by this SDN controller")
2202 sdn_controller_create_parser.add_argument("--type", action="store",
2203 help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
2204 sdn_controller_create_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
2205 sdn_controller_create_parser.add_argument("--passwd", action="store", dest='password',
2206 help="password credentials for the SDN controller")
2207 sdn_controller_create_parser.set_defaults(func=sdn_controller_create)
2208
2209 # sdn_controller_edit
2210 sdn_controller_edit_parser = subparsers.add_parser('sdn-controller-edit', parents=[parent_parser],
2211 help="Update one or more options of a SDN controller")
2212 sdn_controller_edit_parser.add_argument("name", help="name or uuid of the SDN controller", )
2213 sdn_controller_edit_parser.add_argument("--name", action="store", help="Update the name of the SDN controller",
2214 dest='new_name')
2215 sdn_controller_edit_parser.add_argument("--description", action="store", help="description of the SDN controller")
2216 sdn_controller_edit_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
2217 sdn_controller_edit_parser.add_argument("--port", action="store", help="Port of the SDN controller")
2218 sdn_controller_edit_parser.add_argument("--dpid", action="store",
2219 help="DPID of the dataplane switch controlled by this SDN controller")
2220 sdn_controller_edit_parser.add_argument("--type", action="store",
2221 help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
2222 sdn_controller_edit_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
2223 sdn_controller_edit_parser.add_argument("--password", action="store",
2224 help="password credentials for the SDN controller", dest='password')
2225 sdn_controller_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
2226 #TODO: include option --file
2227 sdn_controller_edit_parser.set_defaults(func=sdn_controller_edit)
2228
2229 #sdn_controller_list
2230 sdn_controller_list_parser = subparsers.add_parser('sdn-controller-list',
2231 parents=[parent_parser],
2232 help="List the SDN controllers")
2233 sdn_controller_list_parser.add_argument("name", nargs='?', help="name or uuid of the SDN controller")
2234 sdn_controller_list_parser.set_defaults(func=sdn_controller_list)
2235
2236 # sdn_controller_delete
2237 sdn_controller_delete_parser = subparsers.add_parser('sdn-controller-delete',
2238 parents=[parent_parser],
2239 help="Delete the the SDN controller")
2240 sdn_controller_delete_parser.add_argument("name", help="name or uuid of the SDN controller")
2241 sdn_controller_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2242 sdn_controller_delete_parser.set_defaults(func=sdn_controller_delete)
2243 # =======================
tierno7edb6752016-03-21 17:37:52 +01002244
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002245 # WIM ======================= WIM section==================
2246
2247 # WIM create
2248 wim_create_parser = subparsers.add_parser('wim-create',
2249 parents=[parent_parser], help="creates a new wim")
2250 wim_create_parser.add_argument("name", action="store",
2251 help="name for the wim")
2252 wim_create_parser.add_argument("url", action="store",
2253 help="url for the wim")
2254 wim_create_parser.add_argument("--type", action="store",
2255 help="wim type: tapi, onos or odl (default)")
2256 wim_create_parser.add_argument("--config", action="store",
2257 help="additional configuration in json/yaml format")
2258 wim_create_parser.add_argument("--description", action="store",
2259 help="description of the wim")
2260 wim_create_parser.set_defaults(func=wim_create)
2261
2262 # WIM delete
2263 wim_delete_parser = subparsers.add_parser('wim-delete',
2264 parents=[parent_parser], help="deletes a wim from the catalogue")
2265 wim_delete_parser.add_argument("name", action="store",
2266 help="name or uuid of the wim to be deleted")
2267 wim_delete_parser.add_argument("-f", "--force", action="store_true",
2268 help="forces deletion without asking")
2269 wim_delete_parser.set_defaults(func=wim_delete)
2270
2271 # WIM edit
2272 wim_edit_parser = subparsers.add_parser('wim-edit',
2273 parents=[parent_parser], help="edits a wim")
2274 wim_edit_parser.add_argument("name", help="name or uuid of the wim")
2275 wim_edit_parser.add_argument("--file",
2276 help="json/yaml text or file with the changes")\
2277 .completer = FilesCompleter
2278 wim_edit_parser.add_argument("-f", "--force", action="store_true",
2279 help="do not prompt for confirmation")
2280 wim_edit_parser.set_defaults(func=wim_edit)
2281
2282 # WIM list
2283 wim_list_parser = subparsers.add_parser('wim-list',
2284 parents=[parent_parser],
2285 help="lists information about registered wims")
2286 wim_list_parser.add_argument("name", nargs='?',
2287 help="name or uuid of the wim")
2288 wim_list_parser.add_argument("-a", "--all", action="store_true",
2289 help="shows all wims, not only wims attached to tenant")
2290 wim_list_parser.set_defaults(func=wim_list)
2291
2292 # WIM account create
2293 wim_attach_parser = subparsers.add_parser('wim-account-create', parents=
2294 [parent_parser], help="associates a wim account to the operating tenant")
2295 wim_attach_parser.add_argument("name", help="name or uuid of the wim")
2296 wim_attach_parser.add_argument('--account-name', action='store',
2297 help="specify a name for the wim account.")
2298 wim_attach_parser.add_argument("--user", action="store",
2299 help="user credentials for the wim account")
2300 wim_attach_parser.add_argument("--password", action="store",
2301 help="password credentials for the wim account")
2302 wim_attach_parser.add_argument("--config", action="store",
2303 help="additional configuration in json/yaml format")
2304 wim_attach_parser.set_defaults(func=wim_account_create)
2305
2306 # WIM account delete
2307 wim_detach_parser = subparsers.add_parser('wim-account-delete',
2308 parents=[parent_parser],
2309 help="removes the association "
2310 "between a wim account and the operating tenant")
2311 wim_detach_parser.add_argument("name", help="name or uuid of the wim")
2312 wim_detach_parser.add_argument("-a", "--all", action="store_true",
2313 help="removes all associations from this wim")
2314 wim_detach_parser.add_argument("-f", "--force", action="store_true",
2315 help="forces delete without asking")
2316 wim_detach_parser.set_defaults(func=wim_account_delete)
2317
2318 # WIM account edit
2319 wim_attach_edit_parser = subparsers.add_parser('wim-account-edit', parents=
2320 [parent_parser], help="modifies the association of a wim account to the operating tenant")
2321 wim_attach_edit_parser.add_argument("name", help="name or uuid of the wim")
2322 wim_attach_edit_parser.add_argument('--account-name', action='store',
2323 help="specify a name for the wim account.")
2324 wim_attach_edit_parser.add_argument("--user", action="store",
2325 help="user credentials for the wim account")
2326 wim_attach_edit_parser.add_argument("--password", action="store",
2327 help="password credentials for the wim account")
2328 wim_attach_edit_parser.add_argument("--config", action="store",
2329 help="additional configuration in json/yaml format")
2330 wim_attach_edit_parser.set_defaults(func=wim_account_edit)
2331
2332 # WIM port mapping set
2333 wim_port_mapping_set_parser = subparsers.add_parser('wim-port-mapping-set',
2334 parents=[parent_parser],
2335 help="Load a file with the mappings "
2336 "of ports of a WAN switch that is "
2337 "connected to a PoP and the ports "
2338 "of the switch controlled by the PoP")
2339 wim_port_mapping_set_parser.add_argument("name", action="store",
2340 help="specifies the wim")
2341 wim_port_mapping_set_parser.add_argument("file",
2342 help="json/yaml text or file with the wim port mapping")\
2343 .completer = FilesCompleter
2344 wim_port_mapping_set_parser.add_argument("-f", "--force",
2345 action="store_true", help="forces overwriting without asking")
2346 wim_port_mapping_set_parser.set_defaults(func=wim_port_mapping_set)
2347
2348 # WIM port mapping list
2349 wim_port_mapping_list_parser = subparsers.add_parser('wim-port-mapping-list',
2350 parents=[parent_parser], help="Show the port mappings for a wim")
2351 wim_port_mapping_list_parser.add_argument("name", action="store",
2352 help="specifies the wim")
2353 wim_port_mapping_list_parser.set_defaults(func=wim_port_mapping_list)
2354
2355 # WIM port mapping clear
2356 wim_port_mapping_clear_parser = subparsers.add_parser('wim-port-mapping-clear',
2357 parents=[parent_parser], help="Clean the port mapping in a wim")
2358 wim_port_mapping_clear_parser.add_argument("name", action="store",
2359 help="specifies the wim")
2360 wim_port_mapping_clear_parser.add_argument("-f", "--force",
2361 action="store_true",
2362 help="forces clearing without asking")
2363 wim_port_mapping_clear_parser.set_defaults(func=wim_port_mapping_clear)
2364
2365 # =======================================================
2366
tierno7edb6752016-03-21 17:37:52 +01002367 action_dict={'net-update': 'retrieves external networks from datacenter',
2368 'net-edit': 'edits an external network',
2369 'net-delete': 'deletes an external network',
2370 'net-list': 'lists external networks from a datacenter'
2371 }
2372 for item in action_dict:
2373 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
2374 datacenter_action_parser.add_argument("datacenter", help="name or uuid of the datacenter")
2375 if item=='net-edit' or item=='net-delete':
2376 datacenter_action_parser.add_argument("net", help="name or uuid of the datacenter net")
2377 if item=='net-edit':
2378 datacenter_action_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
2379 if item!='net-list':
2380 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2381 datacenter_action_parser.set_defaults(func=datacenter_net_action, action=item)
2382
2383
tierno5acf7202016-08-29 14:28:13 +02002384 action_dict={'netmap-import': 'create network senario netmap base on the datacenter networks',
tierno7edb6752016-03-21 17:37:52 +01002385 'netmap-create': 'create a new network senario netmap',
2386 'netmap-edit': 'edit name of a network senario netmap',
2387 'netmap-delete': 'deletes a network scenario netmap (--all for clearing all)',
2388 'netmap-list': 'list/show network scenario netmaps'
2389 }
2390 for item in action_dict:
2391 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
2392 datacenter_action_parser.add_argument("--datacenter", help="name or uuid of the datacenter")
2393 #if item=='net-add':
2394 # datacenter_action_parser.add_argument("net", help="name of the network")
2395 if item=='netmap-delete':
2396 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to delete")
2397 datacenter_action_parser.add_argument("--all", action="store_true", help="delete all netmap of this datacenter")
2398 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2399 if item=='netmap-edit':
2400 datacenter_action_parser.add_argument("netmap", help="name or uuid of the datacenter netmap do edit")
2401 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file with the changes").completer = FilesCompleter
2402 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap")
2403 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
2404 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2405 if item=='netmap-list':
2406 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to show")
2407 if item=='netmap-create':
2408 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file descriptor with the changes").completer = FilesCompleter
2409 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap, by default same as vim-name")
2410 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
2411 datacenter_action_parser.add_argument('--vim-name', action='store', help="specify vim network name")
tierno5acf7202016-08-29 14:28:13 +02002412 if item=='netmap-import':
tierno7edb6752016-03-21 17:37:52 +01002413 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2414 datacenter_action_parser.set_defaults(func=datacenter_netmap_action, action=item)
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002415
2416 # =======================vim_net_sdn_xxx section=======================
2417 # vim_net_sdn_attach
2418 vim_net_sdn_attach_parser = subparsers.add_parser('vim-net-sdn-attach',
2419 parents=[parent_parser],
2420 help="Specify the port to access to an external network using SDN")
2421 vim_net_sdn_attach_parser.add_argument("vim_net", action="store",
2422 help="Name/id of the network in the vim that will be used to connect to the external network")
2423 vim_net_sdn_attach_parser.add_argument("port", action="store", help="Specifies the port in the dataplane switch to access to the external network")
2424 vim_net_sdn_attach_parser.add_argument("--vlan", action="store", help="Specifies the vlan (if any) to use in the defined port")
2425 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")
2426 vim_net_sdn_attach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2427 vim_net_sdn_attach_parser.set_defaults(func=vim_net_sdn_attach)
2428
2429 # vim_net_sdn_detach
2430 vim_net_sdn_detach_parser = subparsers.add_parser('vim-net-sdn-detach',
2431 parents=[parent_parser],
2432 help="Remove the port information to access to an external network using SDN")
2433
2434 vim_net_sdn_detach_parser.add_argument("vim_net", action="store", help="Name/id of the vim network")
2435 vim_net_sdn_detach_parser.add_argument("--id", action="store",help="Specify the uuid of the external ports from this network to be detached")
2436 vim_net_sdn_detach_parser.add_argument("--all", action="store_true", help="Detach all external ports from this network")
2437 vim_net_sdn_detach_parser.add_argument("-f", "--force", action="store_true", help="forces clearing without asking")
2438 vim_net_sdn_detach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2439 vim_net_sdn_detach_parser.set_defaults(func=vim_net_sdn_detach)
2440 # =======================
2441
tierno4540ea52017-01-18 17:44:32 +01002442 for item in ("network", "tenant", "image"):
tierno7edb6752016-03-21 17:37:52 +01002443 if item=="network":
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002444 command_name = 'vim-net'
tierno7edb6752016-03-21 17:37:52 +01002445 else:
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002446 command_name = 'vim-'+item
2447 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 +01002448 vim_item_list_parser.add_argument("name", nargs='?', help="name or uuid of the " + item + "s")
2449 vim_item_list_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2450 vim_item_list_parser.set_defaults(func=vim_action, item=item, action="list")
2451
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002452 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 +01002453 vim_item_del_parser.add_argument("name", help="name or uuid of the " + item + "s")
2454 vim_item_del_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2455 vim_item_del_parser.set_defaults(func=vim_action, item=item, action="delete")
2456
tierno4540ea52017-01-18 17:44:32 +01002457 if item == "network" or item == "tenant":
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002458 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 +01002459 vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the %s. Must be a file or yaml/json text" % item).completer = FilesCompleter
2460 vim_item_create_parser.add_argument("--name", action="store", help="name of the %s" % item )
2461 vim_item_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2462 if item=="network":
2463 vim_item_create_parser.add_argument("--type", action="store", help="type of network, data, ptp, bridge")
2464 vim_item_create_parser.add_argument("--shared", action="store_true", help="Private or shared")
2465 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>'")
2466 else:
2467 vim_item_create_parser.add_argument("--description", action="store", help="description of the %s" % item)
2468 vim_item_create_parser.set_defaults(func=vim_action, item=item, action="create")
tierno7edb6752016-03-21 17:37:52 +01002469
2470 argcomplete.autocomplete(main_parser)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002471
tierno7edb6752016-03-21 17:37:52 +01002472 try:
2473 args = main_parser.parse_args()
2474 #logging info
2475 level = logging.CRITICAL
2476 streamformat = "%(asctime)s %(name)s %(levelname)s: %(message)s"
2477 if "debug" in args and args.debug:
2478 level = logging.DEBUG
2479 logging.basicConfig(format=streamformat, level= level)
2480 logger = logging.getLogger('mano')
2481 logger.setLevel(level)
2482 result = args.func(args)
2483 if result == None:
2484 result = 0
2485 #for some reason it fails if call exit inside try instance. Need to call exit at the end !?
2486 except (requests.exceptions.ConnectionError):
2487 print "Connection error: not possible to contact OPENMANO-SERVER (openmanod)"
2488 result = -2
2489 except (KeyboardInterrupt):
2490 print 'Exiting openmano'
2491 result = -3
2492 except (SystemExit, ArgumentParserError):
2493 result = -4
2494 except OpenmanoCLIError as e:
2495 print str(e)
2496 result = -5
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002497
tierno7edb6752016-03-21 17:37:52 +01002498 #print result
2499 exit(result)
2500