blob: b2eb3ffa1f703620b6c62d84b8d17fd45597a9d9 [file] [log] [blame]
tierno7d782ef2019-10-04 12:56:31 +00001#!/usr/bin/env python3
tierno7edb6752016-03-21 17:37:52 +01002# -*- coding: utf-8 -*-
3# PYTHON_ARGCOMPLETE_OK
4
5##
tierno92021022018-09-12 16:29:23 +02006# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
tierno7edb6752016-03-21 17:37:52 +01007# This file is part of openmano
8# All Rights Reserved.
9#
10# Licensed under the Apache License, Version 2.0 (the "License"); you may
11# not use this file except in compliance with the License. You may obtain
12# a copy of the License at
13#
14# http://www.apache.org/licenses/LICENSE-2.0
15#
16# Unless required by applicable law or agreed to in writing, software
17# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19# License for the specific language governing permissions and limitations
20# under the License.
21#
22# For those usages not covered by the Apache License, Version 2.0 please
23# contact with: nfvlabs@tid.es
24##
25
tierno20df3bb2017-07-07 14:31:00 +020026"""
Anderson Bravalheri0446cd52018-08-17 15:26:19 +010027openmano client used to interact with openmano-server (openmanod)
tierno20df3bb2017-07-07 14:31:00 +020028"""
tierno72a08d72017-05-25 13:12:30 +020029__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
30__date__ = "$09-oct-2014 09:09:48$"
tierno7d782ef2019-10-04 12:56:31 +000031__version__ = "0.5.0"
32version_date = "2019-010-04"
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
tierno7edb6752016-03-21 17:37:52 +010044
tierno7d782ef2019-10-04 12:56:31 +000045class ArgumentParserError(Exception):
46 pass
47
48
49class OpenmanoCLIError(Exception):
50 pass
51
tierno7edb6752016-03-21 17:37:52 +010052
53class ThrowingArgumentParser(argparse.ArgumentParser):
54 def error(self, message):
tierno7d782ef2019-10-04 12:56:31 +000055 print("Error: {}".format(message))
56 print()
tierno7edb6752016-03-21 17:37:52 +010057 self.print_usage()
58 #self.print_help()
tierno7d782ef2019-10-04 12:56:31 +000059 print()
60 print("Type 'openmano -h' for help")
tierno7edb6752016-03-21 17:37:52 +010061 raise ArgumentParserError
62
63
64def config(args):
tierno7d782ef2019-10-04 12:56:31 +000065 print("OPENMANO_HOST: {}".format(mano_host))
66 print("OPENMANO_PORT: {}".format(mano_port))
garciadeblas0e9fd832016-07-08 15:20:18 +020067 if args.n:
68 logger.debug("resolving tenant and datacenter names")
69 mano_tenant_id = "None"
70 mano_tenant_name = "None"
71 mano_datacenter_id = "None"
72 mano_datacenter_name = "None"
Anderson Bravalheri0446cd52018-08-17 15:26:19 +010073 # WIM additions
74 logger.debug("resolving WIM names")
75 mano_wim_id = "None"
76 mano_wim_name = "None"
garciadeblas0e9fd832016-07-08 15:20:18 +020077 try:
78 mano_tenant_id = _get_item_uuid("tenants", mano_tenant)
tierno7d782ef2019-10-04 12:56:31 +000079 URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, mano_tenant_id)
garciadeblas0e9fd832016-07-08 15:20:18 +020080 mano_response = requests.get(URLrequest)
81 logger.debug("openmano response: %s", mano_response.text )
82 content = mano_response.json()
83 mano_tenant_name = content["tenant"]["name"]
tierno7d782ef2019-10-04 12:56:31 +000084 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, mano_tenant_id,
85 mano_datacenter)
garciadeblas0e9fd832016-07-08 15:20:18 +020086 mano_response = requests.get(URLrequest)
tierno7d782ef2019-10-04 12:56:31 +000087 logger.debug("openmano response: %s", mano_response.text)
garciadeblas0e9fd832016-07-08 15:20:18 +020088 content = mano_response.json()
89 if "error" not in content:
90 mano_datacenter_id = content["datacenter"]["uuid"]
91 mano_datacenter_name = content["datacenter"]["name"]
Anderson Bravalheri0446cd52018-08-17 15:26:19 +010092
93 # WIM
tierno7d782ef2019-10-04 12:56:31 +000094 URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(
Anderson Bravalheri0446cd52018-08-17 15:26:19 +010095 mano_host, mano_port, mano_tenant_id, mano_wim)
96 mano_response = requests.get(URLrequest)
97 logger.debug("openmano response: %s", mano_response.text)
98 content = mano_response.json()
99 if "error" not in content:
100 mano_wim_id = content["wim"]["uuid"]
101 mano_wim_name = content["wim"]["name"]
102
garciadeblas0e9fd832016-07-08 15:20:18 +0200103 except OpenmanoCLIError:
104 pass
tierno7d782ef2019-10-04 12:56:31 +0000105 print( "OPENMANO_TENANT: {}".format(mano_tenant))
106 print( " Id: {}".format(mano_tenant_id))
107 print( " Name: {}".format(mano_tenant_name))
108 print( "OPENMANO_DATACENTER: {}".format(mano_datacenter))
109 print( " Id: {}".format(mano_datacenter_id))
110 print( " Name: {}".format(mano_datacenter_name))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100111 # WIM
tierno7d782ef2019-10-04 12:56:31 +0000112 print( "OPENMANO_WIM: {}".format( (mano_wim)))
113 print( " Id: {}".format(mano_wim_id))
114 print( " Name: {}".format(mano_wim_name))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100115
garciadeblas0e9fd832016-07-08 15:20:18 +0200116 else:
tierno7d782ef2019-10-04 12:56:31 +0000117 print("OPENMANO_TENANT: {}".format(mano_tenant))
118 print("OPENMANO_DATACENTER: {}".format(mano_datacenter))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100119 # WIM
tierno7d782ef2019-10-04 12:56:31 +0000120 print("OPENMANO_WIM: {}".format(mano_wim))
tierno7edb6752016-03-21 17:37:52 +0100121
122def _print_verbose(mano_response, verbose_level=0):
123 content = mano_response.json()
124 result = 0 if mano_response.status_code==200 else mano_response.status_code
125 if type(content)!=dict or len(content)!=1:
tierno7d782ef2019-10-04 12:56:31 +0000126 # print("Non expected format output")
127 print(str(content))
tierno7edb6752016-03-21 17:37:52 +0100128 return result
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100129
tierno7d782ef2019-10-04 12:56:31 +0000130 val = next(iter(content.values()))
tierno7edb6752016-03-21 17:37:52 +0100131 if type(val)==str:
tierno7d782ef2019-10-04 12:56:31 +0000132 print(val)
tierno7edb6752016-03-21 17:37:52 +0100133 return result
134 elif type(val) == list:
135 content_list = val
136 elif type(val)==dict:
137 content_list = [val]
138 else:
tierno7d782ef2019-10-04 12:56:31 +0000139 # print("Non expected dict/list format output"
140 print(str(content))
tierno7edb6752016-03-21 17:37:52 +0100141 return result
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100142
tierno7d782ef2019-10-04 12:56:31 +0000143 # print(content_list
tierno7edb6752016-03-21 17:37:52 +0100144 if verbose_level==None:
145 verbose_level=0
146 if verbose_level >= 3:
tierno7d782ef2019-10-04 12:56:31 +0000147 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100148 return result
149
150 if mano_response.status_code == 200:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +0100151 uuid = None
tierno7edb6752016-03-21 17:37:52 +0100152 for content in content_list:
153 if "uuid" in content:
154 uuid = content['uuid']
155 elif "id" in content:
156 uuid = content['id']
157 elif "vim_id" in content:
158 uuid = content['vim_id']
tierno250954a2017-01-31 14:25:57 +0100159 name = content.get('name');
160 if not uuid:
161 uuid = ""
162 if not name:
163 name = ""
tiernoa15c4b92017-10-05 12:41:44 +0200164 myoutput = "{:38} {:20}".format(uuid, name)
tierno250954a2017-01-31 14:25:57 +0100165 if content.get("status"):
tiernoa15c4b92017-10-05 12:41:44 +0200166 myoutput += " {:20}".format(content['status'])
tierno7edb6752016-03-21 17:37:52 +0100167 elif "enabled" in content and not content["enabled"]:
168 myoutput += " enabled=False".ljust(20)
169 if verbose_level >=1:
tierno250954a2017-01-31 14:25:57 +0100170 if content.get('created_at'):
tiernoa15c4b92017-10-05 12:41:44 +0200171 myoutput += " {:20}".format(content['created_at'])
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +0200172 if content.get('sdn_attached_ports'):
173 #myoutput += " " + str(content['sdn_attached_ports']).ljust(20)
174 myoutput += "\nsdn_attached_ports:\n" + yaml.safe_dump(content['sdn_attached_ports'], indent=4, default_flow_style=False)
tierno7edb6752016-03-21 17:37:52 +0100175 if verbose_level >=2:
176 new_line='\n'
tierno250954a2017-01-31 14:25:57 +0100177 if content.get('type'):
tiernoa15c4b92017-10-05 12:41:44 +0200178 myoutput += new_line + " Type: {:29}".format(content['type'])
tierno7edb6752016-03-21 17:37:52 +0100179 new_line=''
tierno250954a2017-01-31 14:25:57 +0100180 if content.get('description'):
tiernoa15c4b92017-10-05 12:41:44 +0200181 myoutput += new_line + " Description: {:20}".format(content['description'])
tierno7d782ef2019-10-04 12:56:31 +0000182 print(myoutput)
tierno7edb6752016-03-21 17:37:52 +0100183 else:
tierno7d782ef2019-10-04 12:56:31 +0000184 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100185 return result
186
187def parser_json_yaml(file_name):
188 try:
tierno7d782ef2019-10-04 12:56:31 +0000189 with open(file_name, "r") as f:
190 text = f.read()
tierno7edb6752016-03-21 17:37:52 +0100191 except Exception as e:
192 return (False, str(e))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100193
tierno7edb6752016-03-21 17:37:52 +0100194 #Read and parse file
195 if file_name[-5:]=='.yaml' or file_name[-4:]=='.yml' or (file_name[-5:]!='.json' and '\t' not in text):
196 try:
tierno7d782ef2019-10-04 12:56:31 +0000197 config = yaml.load(text, Loader=yaml.SafeLoader)
tierno7edb6752016-03-21 17:37:52 +0100198 except yaml.YAMLError as exc:
199 error_pos = ""
200 if hasattr(exc, 'problem_mark'):
201 mark = exc.problem_mark
tierno7d782ef2019-10-04 12:56:31 +0000202 error_pos = " at line:{} column:{}".format(mark.line+1, mark.column+1)
tierno7edb6752016-03-21 17:37:52 +0100203 return (False, "Error loading file '"+file_name+"' yaml format error" + error_pos)
204 else: #json
205 try:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100206 config = json.loads(text)
tierno7edb6752016-03-21 17:37:52 +0100207 except Exception as e:
208 return (False, "Error loading file '"+file_name+"' json format error " + str(e) )
tierno7edb6752016-03-21 17:37:52 +0100209 return True, config
210
211def _load_file_or_yaml(content):
212 '''
213 'content' can be or a yaml/json file or a text containing a yaml/json text format
214 This function autodetect, trying to load and parse the file,
215 if fails trying to parse the 'content' text
216 Returns the dictionary once parsed, or print an error and finish the program
217 '''
218 #Check config file exists
219 if os.path.isfile(content):
220 r,payload = parser_json_yaml(content)
221 if not r:
tierno7d782ef2019-10-04 12:56:31 +0000222 print(payload)
tierno7edb6752016-03-21 17:37:52 +0100223 exit(-1)
224 elif "{" in content or ":" in content:
225 try:
226 payload = yaml.load(content)
227 except yaml.YAMLError as exc:
228 error_pos = ""
229 if hasattr(exc, 'problem_mark'):
230 mark = exc.problem_mark
tierno7d782ef2019-10-04 12:56:31 +0000231 error_pos = " at position: ({}:{})".format(mark.line+1, mark.column+1)
232 print("Error loading yaml/json text"+error_pos)
tierno7edb6752016-03-21 17:37:52 +0100233 exit (-1)
234 else:
tierno7d782ef2019-10-04 12:56:31 +0000235 print("'{}' is neither a valid file nor a yaml/json content".format(content))
tierno7edb6752016-03-21 17:37:52 +0100236 exit(-1)
237 return payload
238
239def _get_item_uuid(item, item_name_id, tenant=None):
240 if tenant:
tierno7d782ef2019-10-04 12:56:31 +0000241 URLrequest = "http://{}:{}/openmano/{}/{}".format(mano_host, mano_port, tenant, item)
tierno7edb6752016-03-21 17:37:52 +0100242 else:
tierno7d782ef2019-10-04 12:56:31 +0000243 URLrequest = "http://{}:{}/openmano/{}".format(mano_host, mano_port, item)
tierno7edb6752016-03-21 17:37:52 +0100244 mano_response = requests.get(URLrequest)
245 logger.debug("openmano response: %s", mano_response.text )
246 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000247 # print(content
tierno7edb6752016-03-21 17:37:52 +0100248 found = 0
249 for i in content[item]:
250 if i["uuid"] == item_name_id:
251 return item_name_id
252 if i["name"] == item_name_id:
253 uuid = i["uuid"]
254 found += 1
tiernof1ba57e2017-09-07 12:23:19 +0200255 if item_name_id.startswith("osm_id=") and i.get("osm_id") == item_name_id[7:]:
256 uuid = i["uuid"]
257 found += 1
tierno7edb6752016-03-21 17:37:52 +0100258 if found == 0:
tierno7d782ef2019-10-04 12:56:31 +0000259 raise OpenmanoCLIError("No {} found with name/uuid '{}'".format(item[:-1], item_name_id))
tierno7edb6752016-03-21 17:37:52 +0100260 elif found > 1:
tierno7d782ef2019-10-04 12:56:31 +0000261 raise OpenmanoCLIError("{} {} found with name '{}'. uuid must be used".format(found, item, item_name_id))
tierno7edb6752016-03-21 17:37:52 +0100262 return uuid
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100263#
tierno7edb6752016-03-21 17:37:52 +0100264# def check_valid_uuid(uuid):
265# id_schema = {"type" : "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
266# try:
267# js_v(uuid, id_schema)
268# return True
269# except js_e.ValidationError:
270# return False
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100271
tierno7edb6752016-03-21 17:37:52 +0100272def _get_tenant(tenant_name_id = None):
273 if not tenant_name_id:
274 tenant_name_id = mano_tenant
275 if not mano_tenant:
276 raise OpenmanoCLIError("'OPENMANO_TENANT' environment variable is not set")
277 return _get_item_uuid("tenants", tenant_name_id)
278
279def _get_datacenter(datacenter_name_id = None, tenant = "any"):
280 if not datacenter_name_id:
281 datacenter_name_id = mano_datacenter
282 if not datacenter_name_id:
283 raise OpenmanoCLIError("neither 'OPENMANO_DATACENTER' environment variable is set nor --datacenter option is used")
284 return _get_item_uuid("datacenters", datacenter_name_id, tenant)
285
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100286# WIM
287def _get_wim(wim_name_id = None, tenant = "any"):
288 if not wim_name_id:
289 wim_name_id = mano_wim
290 if not wim_name_id:
291 raise OpenmanoCLIError("neither 'OPENMANO_WIM' environment variable is set nor --wim option is used")
292 return _get_item_uuid("wims", wim_name_id, tenant)
293
tierno7edb6752016-03-21 17:37:52 +0100294def vnf_create(args):
tierno7d782ef2019-10-04 12:56:31 +0000295 # print("vnf-create", args)
tierno7edb6752016-03-21 17:37:52 +0100296 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
297 tenant = _get_tenant()
298 myvnf = _load_file_or_yaml(args.file)
tierno7d782ef2019-10-04 12:56:31 +0000299
tiernof1ba57e2017-09-07 12:23:19 +0200300 api_version = ""
301 if "vnfd:vnfd-catalog" in myvnf or "vnfd-catalog" in myvnf:
302 api_version = "/v3"
303 token = "vnfd"
304 vnfd_catalog = myvnf.get("vnfd:vnfd-catalog")
305 if not vnfd_catalog:
306 vnfd_catalog = myvnf.get("vnfd-catalog")
307 vnfds = vnfd_catalog.get("vnfd:vnfd")
308 if not vnfds:
309 vnfds = vnfd_catalog.get("vnfd")
310 vnfd = vnfds[0]
gcalvino319b8a52018-11-05 15:33:23 +0100311 vdu_list = vnfd.get("vdu")
tiernof1ba57e2017-09-07 12:23:19 +0200312
313 else: # old API
314 api_version = ""
315 token = "vnfs"
316 vnfd = myvnf['vnf']
gcalvino319b8a52018-11-05 15:33:23 +0100317 vdu_list = vnfd.get("VNFC")
tierno7edb6752016-03-21 17:37:52 +0100318
garciadeblas14480452017-01-10 13:08:07 +0100319 if args.name or args.description or args.image_path or args.image_name or args.image_checksum:
tiernof1ba57e2017-09-07 12:23:19 +0200320 # TODO, change this for API v3
tierno7d782ef2019-10-04 12:56:31 +0000321 # print(args.name
tierno7edb6752016-03-21 17:37:52 +0100322 try:
323 if args.name:
tiernof1ba57e2017-09-07 12:23:19 +0200324 vnfd['name'] = args.name
tierno7edb6752016-03-21 17:37:52 +0100325 if args.description:
tiernof1ba57e2017-09-07 12:23:19 +0200326 vnfd['description'] = args.description
gcalvino319b8a52018-11-05 15:33:23 +0100327 if vdu_list:
328 if args.image_path:
329 index = 0
330 for image_path_ in args.image_path.split(","):
tierno7d782ef2019-10-04 12:56:31 +0000331 # print("image-path", image_path_)
gcalvino319b8a52018-11-05 15:33:23 +0100332 if api_version == "/v3":
333 if vdu_list[index].get("image"):
334 vdu_list[index]['image'] = image_path_
335 if "image-checksum" in vdu_list[index]:
336 del vdu_list[index]["image-checksum"]
337 else: # image name in volumes
338 vdu_list[index]["volumes"][0]["image"] = image_path_
339 if "image-checksum" in vdu_list[index]["volumes"][0]:
340 del vdu_list[index]["volumes"][0]["image-checksum"]
341 else:
342 vdu_list[index]['VNFC image'] = image_path_
343 if "image name" in vdu_list[index]:
344 del vdu_list[index]["image name"]
345 if "image checksum" in vdu_list[index]:
346 del vdu_list[index]["image checksum"]
347 index += 1
348 if args.image_name: # image name precedes if both are supplied
349 index = 0
350 for image_name_ in args.image_name.split(","):
351 if api_version == "/v3":
352 if vdu_list[index].get("image"):
353 vdu_list[index]['image'] = image_name_
354 if "image-checksum" in vdu_list[index]:
355 del vdu_list[index]["image-checksum"]
356 if vdu_list[index].get("alternative-images"):
357 for a_image in vdu_list[index]["alternative-images"]:
358 a_image['image'] = image_name_
359 if "image-checksum" in a_image:
360 del a_image["image-checksum"]
361 else: # image name in volumes
362 vdu_list[index]["volumes"][0]["image"] = image_name_
363 if "image-checksum" in vdu_list[index]["volumes"][0]:
364 del vdu_list[index]["volumes"][0]["image-checksum"]
365 else:
366 vdu_list[index]['image name'] = image_name_
367 if "VNFC image" in vdu_list[index]:
368 del vdu_list[index]["VNFC image"]
369 index += 1
370 if args.image_checksum:
371 index = 0
372 for image_checksum_ in args.image_checksum.split(","):
373 if api_version == "/v3":
374 if vdu_list[index].get("image"):
375 vdu_list[index]['image-checksum'] = image_checksum_
376 if vdu_list[index].get("alternative-images"):
377 for a_image in vdu_list[index]["alternative-images"]:
378 a_image['image-checksum'] = image_checksum_
379 else: # image name in volumes
380 vdu_list[index]["volumes"][0]["image-checksum"] = image_checksum_
381 else:
382 vdu_list[index]['image checksum'] = image_checksum_
383 index += 1
tierno7d782ef2019-10-04 12:56:31 +0000384 except (KeyError, TypeError) as e:
tiernof1ba57e2017-09-07 12:23:19 +0200385 if str(e) == 'vnf': error_pos= "missing field 'vnf'"
386 elif str(e) == 'name': error_pos= "missing field 'vnf':'name'"
387 elif str(e) == 'description': error_pos= "missing field 'vnf':'description'"
388 elif str(e) == 'VNFC': error_pos= "missing field 'vnf':'VNFC'"
389 elif str(e) == str(index): error_pos= "field 'vnf':'VNFC' must be an array"
390 elif str(e) == 'VNFC image': error_pos= "missing field 'vnf':'VNFC'['VNFC image']"
391 elif str(e) == 'image name': error_pos= "missing field 'vnf':'VNFC'['image name']"
392 elif str(e) == 'image checksum': error_pos= "missing field 'vnf':'VNFC'['image checksum']"
tierno7edb6752016-03-21 17:37:52 +0100393 else: error_pos="wrong format"
tierno7d782ef2019-10-04 12:56:31 +0000394 print("Wrong VNF descriptor: " + error_pos)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100395 return -1
tierno7edb6752016-03-21 17:37:52 +0100396 payload_req = json.dumps(myvnf)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100397
tierno7d782ef2019-10-04 12:56:31 +0000398 # print(payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100399
tiernof1ba57e2017-09-07 12:23:19 +0200400 URLrequest = "http://{}:{}/openmano{}/{}/{token}".format(mano_host, mano_port, api_version, tenant, token=token)
tierno7edb6752016-03-21 17:37:52 +0100401 logger.debug("openmano request: %s", payload_req)
tierno7d782ef2019-10-04 12:56:31 +0000402 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
tierno7edb6752016-03-21 17:37:52 +0100403 logger.debug("openmano response: %s", mano_response.text )
404
405 return _print_verbose(mano_response, args.verbose)
406
407def vnf_list(args):
tierno7d782ef2019-10-04 12:56:31 +0000408 # print("vnf-list",args
tierno7edb6752016-03-21 17:37:52 +0100409 if args.all:
410 tenant = "any"
411 else:
412 tenant = _get_tenant()
413 if args.name:
414 toshow = _get_item_uuid("vnfs", args.name, tenant)
tierno7d782ef2019-10-04 12:56:31 +0000415 URLrequest = "http://{}:{}/openmano/{}/vnfs/{}".format(mano_host, mano_port, tenant, toshow)
tierno7edb6752016-03-21 17:37:52 +0100416 else:
tierno7d782ef2019-10-04 12:56:31 +0000417 URLrequest = "http://{}:{}/openmano/{}/vnfs".format(mano_host, mano_port, tenant)
tierno7edb6752016-03-21 17:37:52 +0100418 mano_response = requests.get(URLrequest)
419 logger.debug("openmano response: %s", mano_response.text )
420 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000421 # print(json.dumps(content, indent=4)
tierno7edb6752016-03-21 17:37:52 +0100422 if args.verbose==None:
423 args.verbose=0
424 result = 0 if mano_response.status_code==200 else mano_response.status_code
425 if mano_response.status_code == 200:
426 if not args.name:
427 if args.verbose >= 3:
tierno7d782ef2019-10-04 12:56:31 +0000428 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100429 return result
430 if len(content['vnfs']) == 0:
tierno7d782ef2019-10-04 12:56:31 +0000431 print("No VNFs were found.")
tiernof1ba57e2017-09-07 12:23:19 +0200432 return 404 # HTTP_Not_Found
tierno7edb6752016-03-21 17:37:52 +0100433 for vnf in content['vnfs']:
tiernof1ba57e2017-09-07 12:23:19 +0200434 myoutput = "{:38} {:20}".format(vnf['uuid'], vnf['name'])
435 if vnf.get('osm_id') or args.verbose >= 1:
436 myoutput += " osm_id={:20}".format(vnf.get('osm_id'))
437 if args.verbose >= 1:
438 myoutput += " {}".format(vnf['created_at'])
tierno7d782ef2019-10-04 12:56:31 +0000439 print(myoutput)
tiernof1ba57e2017-09-07 12:23:19 +0200440 if args.verbose >= 2:
tierno7d782ef2019-10-04 12:56:31 +0000441 print(" Description: {}".format(vnf['description']))
442 # print(" VNF descriptor file: {}".format(vnf['path']))
tierno7edb6752016-03-21 17:37:52 +0100443 else:
444 if args.verbose:
tierno7d782ef2019-10-04 12:56:31 +0000445 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100446 return result
447 vnf = content['vnf']
tierno7d782ef2019-10-04 12:56:31 +0000448 print("{:38} {:20} osm_id={:20} {:20}".format(vnf['uuid'], vnf['name'], vnf.get('osm_id'),
449 vnf['created_at']), end=" ")
450 print(" Description: {}".format(vnf['description']))
451 # print(" VNF descriptor file: {}".format(vnf['path']))
452 print(" VMs:")
tierno7edb6752016-03-21 17:37:52 +0100453 for vm in vnf['VNFC']:
tierno7d782ef2019-10-04 12:56:31 +0000454 print(" {:20} osm_id={:20} {}".format(vm['name'], vm.get('osm_id'), vm['description']))
tiernof1ba57e2017-09-07 12:23:19 +0200455 if len(vnf['nets']) > 0:
tierno7d782ef2019-10-04 12:56:31 +0000456 print(" Internal nets:")
tierno7edb6752016-03-21 17:37:52 +0100457 for net in vnf['nets']:
tierno7d782ef2019-10-04 12:56:31 +0000458 print(" {:20} {}".format(net['name'], net['description']))
tiernof1ba57e2017-09-07 12:23:19 +0200459 if len(vnf['external-connections']) > 0:
tierno7d782ef2019-10-04 12:56:31 +0000460 print(" External interfaces:")
tierno7edb6752016-03-21 17:37:52 +0100461 for interface in vnf['external-connections']:
tierno7d782ef2019-10-04 12:56:31 +0000462 print(" {:20} {:20} {:20} {:14}".format(
tiernof1ba57e2017-09-07 12:23:19 +0200463 interface['external_name'], interface['vm_name'],
464 interface['internal_name'],
465 interface.get('vpci') if interface.get('vpci') else ""))
tierno7edb6752016-03-21 17:37:52 +0100466 else:
tierno7d782ef2019-10-04 12:56:31 +0000467 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100468 if args.verbose:
tierno7d782ef2019-10-04 12:56:31 +0000469 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100470 return result
471
472def vnf_delete(args):
tierno7d782ef2019-10-04 12:56:31 +0000473 # print("vnf-delete",args
tierno7edb6752016-03-21 17:37:52 +0100474 if args.all:
475 tenant = "any"
476 else:
477 tenant = _get_tenant()
478 todelete = _get_item_uuid("vnfs", args.name, tenant=tenant)
479 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +0000480 r = input("Delete VNF {} (y/N)? ".format(todelete))
tierno7edb6752016-03-21 17:37:52 +0100481 if not (len(r)>0 and r[0].lower()=="y"):
482 return 0
tierno7d782ef2019-10-04 12:56:31 +0000483 URLrequest = "http://{}:{}/openmano/{}/vnfs/{}".format(mano_host, mano_port, tenant, todelete)
tierno7edb6752016-03-21 17:37:52 +0100484 mano_response = requests.delete(URLrequest)
485 logger.debug("openmano response: %s", mano_response.text )
486 result = 0 if mano_response.status_code==200 else mano_response.status_code
487 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000488 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +0100489 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +0000490 print(content['result'])
tierno7edb6752016-03-21 17:37:52 +0100491 else:
tierno7d782ef2019-10-04 12:56:31 +0000492 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100493 return result
494
495def scenario_create(args):
tierno7d782ef2019-10-04 12:56:31 +0000496 # print("scenario-create",args
tierno7edb6752016-03-21 17:37:52 +0100497 tenant = _get_tenant()
498 headers_req = {'content-type': 'application/yaml'}
499 myscenario = _load_file_or_yaml(args.file)
tiernof1ba57e2017-09-07 12:23:19 +0200500 if "nsd:nsd-catalog" in myscenario or "nsd-catalog" in myscenario:
501 api_version = "/v3"
502 token = "nsd"
503 nsd_catalog = myscenario.get("nsd:nsd-catalog")
504 if not nsd_catalog:
505 nsd_catalog = myscenario.get("nsd-catalog")
506 nsds = nsd_catalog.get("nsd:nsd")
507 if not nsds:
508 nsds = nsd_catalog.get("nsd")
509 nsd = nsds[0]
510 else: # API<v3
511 api_version = ""
512 token = "scenarios"
513 if "scenario" in myscenario:
514 nsd = myscenario["scenario"]
515 else:
516 nsd = myscenario
517 # TODO modify for API v3
tierno7edb6752016-03-21 17:37:52 +0100518 if args.name:
tiernof1ba57e2017-09-07 12:23:19 +0200519 nsd['name'] = args.name
tierno7edb6752016-03-21 17:37:52 +0100520 if args.description:
tiernof1ba57e2017-09-07 12:23:19 +0200521 nsd['description'] = args.description
522 payload_req = yaml.safe_dump(myscenario, explicit_start=True, indent=4, default_flow_style=False, tags=False,
tierno7d782ef2019-10-04 12:56:31 +0000523 allow_unicode=True)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100524
tierno7d782ef2019-10-04 12:56:31 +0000525 # print(payload_req
tiernof1ba57e2017-09-07 12:23:19 +0200526 URLrequest = "http://{host}:{port}/openmano{api}/{tenant}/{token}".format(
527 host=mano_host, port=mano_port, api=api_version, tenant=tenant, token=token)
tierno7edb6752016-03-21 17:37:52 +0100528 logger.debug("openmano request: %s", payload_req)
529 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
530 logger.debug("openmano response: %s", mano_response.text )
531 return _print_verbose(mano_response, args.verbose)
532
533def scenario_list(args):
tierno7d782ef2019-10-04 12:56:31 +0000534 # print("scenario-list",args
tierno7edb6752016-03-21 17:37:52 +0100535 if args.all:
536 tenant = "any"
537 else:
538 tenant = _get_tenant()
539 if args.name:
540 toshow = _get_item_uuid("scenarios", args.name, tenant)
tierno7d782ef2019-10-04 12:56:31 +0000541 URLrequest = "http://{}:{}/openmano/{}/scenarios/{}".format(mano_host, mano_port, tenant, toshow)
tierno7edb6752016-03-21 17:37:52 +0100542 else:
tierno7d782ef2019-10-04 12:56:31 +0000543 URLrequest = "http://{}:{}/openmano/{}/scenarios".format(mano_host, mano_port, tenant)
tierno7edb6752016-03-21 17:37:52 +0100544 mano_response = requests.get(URLrequest)
545 logger.debug("openmano response: %s", mano_response.text )
546 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000547 # print(json.dumps(content, indent=4)
tierno7edb6752016-03-21 17:37:52 +0100548 if args.verbose==None:
549 args.verbose=0
550
551 result = 0 if mano_response.status_code==200 else mano_response.status_code
552 if mano_response.status_code == 200:
553 if not args.name:
554 if args.verbose >= 3:
tierno7d782ef2019-10-04 12:56:31 +0000555 print( yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100556 return result
557 if len(content['scenarios']) == 0:
tierno7d782ef2019-10-04 12:56:31 +0000558 print( "No scenarios were found.")
tierno7edb6752016-03-21 17:37:52 +0100559 return 404 #HTTP_Not_Found
560 for scenario in content['scenarios']:
tiernof1ba57e2017-09-07 12:23:19 +0200561 myoutput = "{:38} {:20}".format(scenario['uuid'], scenario['name'])
562 if scenario.get('osm_id') or args.verbose >= 1:
563 myoutput += " osm_id={:20}".format(scenario.get('osm_id'))
564 if args.verbose >= 1:
565 myoutput += " {}".format(scenario['created_at'])
tierno7d782ef2019-10-04 12:56:31 +0000566 print(myoutput)
tierno7edb6752016-03-21 17:37:52 +0100567 if args.verbose >=2:
tierno7d782ef2019-10-04 12:56:31 +0000568 print(" Description: {}".format(scenario['description']))
tierno7edb6752016-03-21 17:37:52 +0100569 else:
570 if args.verbose:
tierno7d782ef2019-10-04 12:56:31 +0000571 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100572 return result
573 scenario = content['scenario']
tierno7d782ef2019-10-04 12:56:31 +0000574 print("{:38} {:20} osm_id={:20} {:20}".format(scenario['uuid'], scenario['name'], scenario.get('osm_id'),
575 scenario['created_at']), end=" ")
576 print(" Description: {}".format(scenario['description']))
577 print(" VNFs:")
tierno7edb6752016-03-21 17:37:52 +0100578 for vnf in scenario['vnfs']:
tierno7d782ef2019-10-04 12:56:31 +0000579 print(" {:38} {:20} vnf_index={} {}".format(vnf['vnf_id'], vnf['name'], vnf.get("member_vnf_index"),
tiernof1ba57e2017-09-07 12:23:19 +0200580 vnf['description']))
581 if len(scenario['nets']) > 0:
tierno7d782ef2019-10-04 12:56:31 +0000582 print(" nets:")
tierno7edb6752016-03-21 17:37:52 +0100583 for net in scenario['nets']:
tiernof1ba57e2017-09-07 12:23:19 +0200584 description = net['description']
585 if not description: # if description does not exist, description is "-". Valid for external and internal nets.
586 description = '-'
587 vim_id = ""
588 if net.get('vim_id'):
589 vim_id = " vim_id=" + net["vim_id"]
590 external = ""
591 if net["external"]:
592 external = " external"
tierno7d782ef2019-10-04 12:56:31 +0000593 print(" {:20} {:38} {:30}{}{}".format(net['name'], net['uuid'], description, vim_id, external))
tierno7edb6752016-03-21 17:37:52 +0100594 else:
tierno7d782ef2019-10-04 12:56:31 +0000595 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100596 if args.verbose:
tierno7d782ef2019-10-04 12:56:31 +0000597 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100598 return result
599
600def scenario_delete(args):
tierno7d782ef2019-10-04 12:56:31 +0000601 # print("scenario-delete",args
tierno7edb6752016-03-21 17:37:52 +0100602 if args.all:
603 tenant = "any"
604 else:
605 tenant = _get_tenant()
606 todelete = _get_item_uuid("scenarios", args.name, tenant=tenant)
607 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +0000608 r = input("Delete scenario {} (y/N)? ".format(args.name))
tierno7edb6752016-03-21 17:37:52 +0100609 if not (len(r)>0 and r[0].lower()=="y"):
610 return 0
tierno7d782ef2019-10-04 12:56:31 +0000611 URLrequest = "http://{}:{}/openmano/{}/scenarios/{}".format(mano_host, mano_port, tenant, todelete)
tierno7edb6752016-03-21 17:37:52 +0100612 mano_response = requests.delete(URLrequest)
613 logger.debug("openmano response: %s", mano_response.text )
614 result = 0 if mano_response.status_code==200 else mano_response.status_code
615 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000616 # print(json.dumps(content, indent=4)
tierno7edb6752016-03-21 17:37:52 +0100617 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +0000618 print( content['result'])
tierno7edb6752016-03-21 17:37:52 +0100619 else:
tierno7d782ef2019-10-04 12:56:31 +0000620 print( content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100621 return result
622
623def scenario_deploy(args):
tierno7d782ef2019-10-04 12:56:31 +0000624 print("This command is deprecated, use 'openmano instance-scenario-create --scenario {} --name {}' instead!!!".format(args.scenario, args.name))
625 print()
tierno7edb6752016-03-21 17:37:52 +0100626 args.file = None
627 args.netmap_use = None
628 args.netmap_create = None
tiernobe41e222016-09-02 15:16:13 +0200629 args.keypair = None
630 args.keypair_auto = None
tierno7edb6752016-03-21 17:37:52 +0100631 return instance_create(args)
632
tierno7d782ef2019-10-04 12:56:31 +0000633# # print("scenario-deploy",args
tierno7edb6752016-03-21 17:37:52 +0100634# headers_req = {'content-type': 'application/json'}
635# action = {}
636# actionCmd="start"
637# if args.nostart:
638# actionCmd="reserve"
639# action[actionCmd] = {}
640# action[actionCmd]["instance_name"] = args.name
641# if args.datacenter != None:
642# action[actionCmd]["datacenter"] = args.datacenter
643# elif mano_datacenter != None:
644# action[actionCmd]["datacenter"] = mano_datacenter
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100645#
tierno7edb6752016-03-21 17:37:52 +0100646# if args.description:
647# action[actionCmd]["description"] = args.description
648# payload_req = json.dumps(action, indent=4)
tierno7d782ef2019-10-04 12:56:31 +0000649# # print(payload_req
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100650#
tierno7d782ef2019-10-04 12:56:31 +0000651# URLrequest = "http://{}:{}/openmano/{}/scenarios/{}/action".format(mano_host, mano_port, mano_tenant, args.scenario)
tierno7edb6752016-03-21 17:37:52 +0100652# logger.debug("openmano request: %s", payload_req)
653# mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
654# logger.debug("openmano response: %s", mano_response.text )
655# if args.verbose==None:
656# args.verbose=0
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100657#
tierno7edb6752016-03-21 17:37:52 +0100658# result = 0 if mano_response.status_code==200 else mano_response.status_code
659# content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000660# # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +0100661# if args.verbose >= 3:
tierno7d782ef2019-10-04 12:56:31 +0000662# print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100663# return result
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100664#
tierno7edb6752016-03-21 17:37:52 +0100665# if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +0000666# myoutput = "{} {}".format(content['uuid'].ljust(38),content['name'].ljust(20))
tierno7edb6752016-03-21 17:37:52 +0100667# if args.verbose >=1:
tierno7d782ef2019-10-04 12:56:31 +0000668# myoutput = "{} {}".format(myoutput, content['created_at'].ljust(20))
tierno7edb6752016-03-21 17:37:52 +0100669# if args.verbose >=2:
tierno7d782ef2019-10-04 12:56:31 +0000670# myoutput = "{} {} {}".format(myoutput, content['description'].ljust(30))
671# print(myoutput)
672# print("")
673# print("To check the status, run the following command:")
674# print("openmano instance-scenario-list <instance_id>"
tierno7edb6752016-03-21 17:37:52 +0100675# else:
tierno7d782ef2019-10-04 12:56:31 +0000676# print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100677# return result
678
679def scenario_verify(args):
tierno7d782ef2019-10-04 12:56:31 +0000680 # print("scenario-verify",args)
tierno72a08d72017-05-25 13:12:30 +0200681 tenant = _get_tenant()
tierno7edb6752016-03-21 17:37:52 +0100682 headers_req = {'content-type': 'application/json'}
683 action = {}
684 action["verify"] = {}
685 action["verify"]["instance_name"] = "scen-verify-return5"
686 payload_req = json.dumps(action, indent=4)
tierno7d782ef2019-10-04 12:56:31 +0000687 # print(payload_req)
tierno7edb6752016-03-21 17:37:52 +0100688
tierno7d782ef2019-10-04 12:56:31 +0000689 URLrequest = "http://{}:{}/openmano/{}/scenarios/{}/action".format(mano_host, mano_port, tenant, args.scenario)
tierno7edb6752016-03-21 17:37:52 +0100690 logger.debug("openmano request: %s", payload_req)
691 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
692 logger.debug("openmano response: %s", mano_response.text )
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100693
tierno7edb6752016-03-21 17:37:52 +0100694 result = 0 if mano_response.status_code==200 else mano_response.status_code
695 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000696 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +0100697 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +0000698 print(content['result'])
tierno7edb6752016-03-21 17:37:52 +0100699 else:
tierno7d782ef2019-10-04 12:56:31 +0000700 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100701 return result
702
703def instance_create(args):
704 tenant = _get_tenant()
705 headers_req = {'content-type': 'application/yaml'}
706 myInstance={"instance": {}, "schema_version": "0.1"}
707 if args.file:
708 instance_dict = _load_file_or_yaml(args.file)
709 if "instance" not in instance_dict:
710 myInstance = {"instance": instance_dict, "schema_version": "0.1"}
711 else:
712 myInstance = instance_dict
713 if args.name:
714 myInstance["instance"]['name'] = args.name
715 if args.description:
716 myInstance["instance"]['description'] = args.description
717 if args.nostart:
718 myInstance["instance"]['action'] = "reserve"
719 #datacenter
720 datacenter = myInstance["instance"].get("datacenter")
721 if args.datacenter != None:
722 datacenter = args.datacenter
723 myInstance["instance"]["datacenter"] = _get_datacenter(datacenter, tenant)
724 #scenario
725 scenario = myInstance["instance"].get("scenario")
726 if args.scenario != None:
727 scenario = args.scenario
728 if not scenario:
tierno7d782ef2019-10-04 12:56:31 +0000729 print("you must provide a scenario in the file descriptor or with --scenario")
tierno7edb6752016-03-21 17:37:52 +0100730 return -1
tierno7fe82642018-11-26 14:14:51 +0000731 if isinstance(scenario, str):
732 myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant)
tierno7edb6752016-03-21 17:37:52 +0100733 if args.netmap_use:
734 if "networks" not in myInstance["instance"]:
735 myInstance["instance"]["networks"] = {}
736 for net in args.netmap_use:
737 net_comma_list = net.split(",")
738 for net_comma in net_comma_list:
739 net_tuple = net_comma.split("=")
740 if len(net_tuple) != 2:
tierno7d782ef2019-10-04 12:56:31 +0000741 print("error at netmap-use. Expected net-scenario=net-datacenter. ({})?".format(net_comma))
tierno7edb6752016-03-21 17:37:52 +0100742 return
743 net_scenario = net_tuple[0].strip()
744 net_datacenter = net_tuple[1].strip()
745 if net_scenario not in myInstance["instance"]["networks"]:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100746 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200747 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
748 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
749 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-use"] = net_datacenter
tierno7edb6752016-03-21 17:37:52 +0100750 if args.netmap_create:
751 if "networks" not in myInstance["instance"]:
752 myInstance["instance"]["networks"] = {}
753 for net in args.netmap_create:
754 net_comma_list = net.split(",")
755 for net_comma in net_comma_list:
756 net_tuple = net_comma.split("=")
757 if len(net_tuple) == 1:
758 net_scenario = net_tuple[0].strip()
759 net_datacenter = None
760 elif len(net_tuple) == 2:
761 net_scenario = net_tuple[0].strip()
762 net_datacenter = net_tuple[1].strip()
763 else:
tierno7d782ef2019-10-04 12:56:31 +0000764 print("error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. ({})?".format(
765 net_comma))
tierno7edb6752016-03-21 17:37:52 +0100766 return
767 if net_scenario not in myInstance["instance"]["networks"]:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100768 myInstance["instance"]["networks"][net_scenario] = {}
tiernobe41e222016-09-02 15:16:13 +0200769 if "sites" not in myInstance["instance"]["networks"][net_scenario]:
770 myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
771 myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-create"] = net_datacenter
tiernoa4e1a6e2016-08-31 14:19:40 +0200772 if args.keypair:
773 if "cloud-config" not in myInstance["instance"]:
774 myInstance["instance"]["cloud-config"] = {}
775 cloud_config = myInstance["instance"]["cloud-config"]
776 for key in args.keypair:
777 index = key.find(":")
778 if index<0:
779 if "key-pairs" not in cloud_config:
780 cloud_config["key-pairs"] = []
781 cloud_config["key-pairs"].append(key)
782 else:
783 user = key[:index]
784 key_ = key[index+1:]
785 key_list = key_.split(",")
786 if "users" not in cloud_config:
787 cloud_config["users"] = []
788 cloud_config["users"].append({"name": user, "key-pairs": key_list })
789 if args.keypair_auto:
790 try:
791 keys=[]
792 home = os.getenv("HOME")
793 user = os.getenv("USER")
794 files = os.listdir(home+'/.ssh')
795 for file in files:
796 if file[-4:] == ".pub":
797 with open(home+'/.ssh/'+file, 'r') as f:
798 keys.append(f.read())
799 if not keys:
tierno7d782ef2019-10-04 12:56:31 +0000800 print("Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh'))
tiernoa4e1a6e2016-08-31 14:19:40 +0200801 return 1
802 except Exception as e:
tierno7d782ef2019-10-04 12:56:31 +0000803 print("Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e)))
tiernoa4e1a6e2016-08-31 14:19:40 +0200804 return 1
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100805
tiernoa4e1a6e2016-08-31 14:19:40 +0200806 if "cloud-config" not in myInstance["instance"]:
807 myInstance["instance"]["cloud-config"] = {}
808 cloud_config = myInstance["instance"]["cloud-config"]
809 if "key-pairs" not in cloud_config:
810 cloud_config["key-pairs"] = []
811 if user:
812 if "users" not in cloud_config:
813 cloud_config["users"] = []
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100814 cloud_config["users"].append({"name": user, "key-pairs": keys })
815
tierno7d782ef2019-10-04 12:56:31 +0000816 payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False,
817 allow_unicode=True)
tierno7edb6752016-03-21 17:37:52 +0100818 logger.debug("openmano request: %s", payload_req)
tierno7d782ef2019-10-04 12:56:31 +0000819 URLrequest = "http://{}:{}/openmano/{}/instances".format(mano_host, mano_port, tenant)
tierno7edb6752016-03-21 17:37:52 +0100820 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
821 logger.debug("openmano response: %s", mano_response.text )
822 if args.verbose==None:
823 args.verbose=0
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100824
tierno7edb6752016-03-21 17:37:52 +0100825 result = 0 if mano_response.status_code==200 else mano_response.status_code
826 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000827 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +0100828 if args.verbose >= 3:
tierno7d782ef2019-10-04 12:56:31 +0000829 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100830 return result
831
832 if mano_response.status_code == 200:
tiernoa15c4b92017-10-05 12:41:44 +0200833 myoutput = "{:38} {:20}".format(content['uuid'], content['name'])
tierno7edb6752016-03-21 17:37:52 +0100834 if args.verbose >=1:
tiernoa15c4b92017-10-05 12:41:44 +0200835 myoutput = "{} {:20}".format(myoutput, content['created_at'])
tierno7edb6752016-03-21 17:37:52 +0100836 if args.verbose >=2:
tiernoa15c4b92017-10-05 12:41:44 +0200837 myoutput = "{} {:30}".format(myoutput, content['description'])
tierno7d782ef2019-10-04 12:56:31 +0000838 print(myoutput)
tierno7edb6752016-03-21 17:37:52 +0100839 else:
tierno7d782ef2019-10-04 12:56:31 +0000840 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100841 return result
842
843def instance_scenario_list(args):
tierno7d782ef2019-10-04 12:56:31 +0000844 # print("instance-scenario-list",args)
tierno7edb6752016-03-21 17:37:52 +0100845 if args.all:
846 tenant = "any"
847 else:
848 tenant = _get_tenant()
849 if args.name:
850 toshow = _get_item_uuid("instances", args.name, tenant)
tierno7d782ef2019-10-04 12:56:31 +0000851 URLrequest = "http://{}:{}/openmano/{}/instances/{}".format(mano_host, mano_port, tenant, toshow)
tierno7edb6752016-03-21 17:37:52 +0100852 else:
tierno7d782ef2019-10-04 12:56:31 +0000853 URLrequest = "http://{}:{}/openmano/{}/instances".format(mano_host, mano_port, tenant)
tierno7edb6752016-03-21 17:37:52 +0100854 mano_response = requests.get(URLrequest)
855 logger.debug("openmano response: %s", mano_response.text )
856 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000857 # print(json.dumps(content, indent=4)
tierno7edb6752016-03-21 17:37:52 +0100858 if args.verbose==None:
859 args.verbose=0
860
861 result = 0 if mano_response.status_code==200 else mano_response.status_code
862 if mano_response.status_code == 200:
863 if not args.name:
864 if args.verbose >= 3:
tierno7d782ef2019-10-04 12:56:31 +0000865 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100866 return result
867 if len(content['instances']) == 0:
tierno7d782ef2019-10-04 12:56:31 +0000868 print("No scenario instances were found.")
tierno7edb6752016-03-21 17:37:52 +0100869 return result
870 for instance in content['instances']:
tiernoa15c4b92017-10-05 12:41:44 +0200871 myoutput = "{:38} {:20}".format(instance['uuid'], instance['name'])
tierno7edb6752016-03-21 17:37:52 +0100872 if args.verbose >=1:
tiernoa15c4b92017-10-05 12:41:44 +0200873 myoutput = "{} {:20}".format(myoutput, instance['created_at'])
tierno7d782ef2019-10-04 12:56:31 +0000874 print(myoutput)
tierno7edb6752016-03-21 17:37:52 +0100875 if args.verbose >=2:
tierno7d782ef2019-10-04 12:56:31 +0000876 print("Description: {}".format(instance['description']))
tierno7edb6752016-03-21 17:37:52 +0100877 else:
878 if args.verbose:
tierno7d782ef2019-10-04 12:56:31 +0000879 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100880 return result
881 instance = content
tierno7d782ef2019-10-04 12:56:31 +0000882 print("{:38} {:20} {:20}".format(instance['uuid'],instance['name'],instance['created_at']))
883 print("Description: {}".format(instance['description']))
884 print("Template scenario id: {}".format(instance['scenario_id']))
885 print("Template scenario name: {}".format(instance['scenario_name']))
886 print("---------------------------------------")
887 print("VNF instances: {}".format(len(instance['vnfs'])))
tierno7edb6752016-03-21 17:37:52 +0100888 for vnf in instance['vnfs']:
tierno7d782ef2019-10-04 12:56:31 +0000889 # print(" {} {} Template vnf name: {} Template vnf id: {}".format(vnf['uuid'].ljust(38), vnf['name'].ljust(20), vnf['vnf_name'].ljust(20), vnf['vnf_id'].ljust(38))
890 print(" {:38} {:20} Template vnf id: {:38}".format(vnf['uuid'], vnf['vnf_name'], vnf['vnf_id']))
tierno7edb6752016-03-21 17:37:52 +0100891 if len(instance['nets'])>0:
tierno7d782ef2019-10-04 12:56:31 +0000892 print("---------------------------------------")
893 print("Internal nets:")
tierno7edb6752016-03-21 17:37:52 +0100894 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000895 if net['created']:
tierno7d782ef2019-10-04 12:56:31 +0000896 print(" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
897 print("---------------------------------------")
898 print("External nets:")
tierno7edb6752016-03-21 17:37:52 +0100899 for net in instance['nets']:
tierno5c7c4732016-09-26 13:38:55 +0000900 if not net['created']:
tierno7d782ef2019-10-04 12:56:31 +0000901 print(" {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
902 print("---------------------------------------")
903 print("VM instances:")
tierno7edb6752016-03-21 17:37:52 +0100904 for vnf in instance['vnfs']:
905 for vm in vnf['vms']:
tierno7d782ef2019-10-04 12:56:31 +0000906 print(" {:38} {:20} {:20} {:12} VIM ID: {}".format(vm['uuid'], vnf['vnf_name'], vm['name'],
907 vm['status'], vm['vim_vm_id']))
tierno7edb6752016-03-21 17:37:52 +0100908 else:
tierno7d782ef2019-10-04 12:56:31 +0000909 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100910 if args.verbose:
tierno7d782ef2019-10-04 12:56:31 +0000911 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100912 return result
913
914def instance_scenario_status(args):
tierno7d782ef2019-10-04 12:56:31 +0000915 print("instance-scenario-status")
tierno7edb6752016-03-21 17:37:52 +0100916 return 0
917
918def instance_scenario_delete(args):
919 if args.all:
920 tenant = "any"
921 else:
922 tenant = _get_tenant()
923 todelete = _get_item_uuid("instances", args.name, tenant=tenant)
tierno7d782ef2019-10-04 12:56:31 +0000924 # print("instance-scenario-delete",args)
tierno7edb6752016-03-21 17:37:52 +0100925 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +0000926 r = input("Delete scenario instance {} (y/N)? ".format(args.name))
tierno7edb6752016-03-21 17:37:52 +0100927 if not (len(r)>0 and r[0].lower()=="y"):
928 return
tierno7d782ef2019-10-04 12:56:31 +0000929 URLrequest = "http://{}:{}/openmano/{}/instances/{}".format(mano_host, mano_port, tenant, todelete)
tierno7edb6752016-03-21 17:37:52 +0100930 mano_response = requests.delete(URLrequest)
931 logger.debug("openmano response: %s", mano_response.text )
932 result = 0 if mano_response.status_code==200 else mano_response.status_code
933 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000934 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +0100935 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +0000936 print(content['result'])
tierno7edb6752016-03-21 17:37:52 +0100937 else:
tierno7d782ef2019-10-04 12:56:31 +0000938 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100939 return result
940
tierno868220c2017-09-26 00:11:05 +0200941def get_action(args):
942 if not args.all:
943 tenant = _get_tenant()
944 else:
945 tenant = "any"
946 if not args.instance:
947 instance_id = "any"
948 else:
949 instance_id =args.instance
950 action_id = ""
951 if args.id:
952 action_id = "/" + args.id
953 URLrequest = "http://{}:{}/openmano/{}/instances/{}/action{}".format(mano_host, mano_port, tenant, instance_id,
954 action_id)
955 mano_response = requests.get(URLrequest)
956 logger.debug("openmano response: %s", mano_response.text )
957 if args.verbose == None:
958 args.verbose = 0
959 if args.id != None:
960 args.verbose += 1
961 return _print_verbose(mano_response, args.verbose)
962
tierno7edb6752016-03-21 17:37:52 +0100963def instance_scenario_action(args):
tierno7d782ef2019-10-04 12:56:31 +0000964 # print("instance-scenario-action", args)
tierno7edb6752016-03-21 17:37:52 +0100965 tenant = _get_tenant()
966 toact = _get_item_uuid("instances", args.name, tenant=tenant)
967 action={}
tiernofc5f80b2018-05-29 16:00:43 +0200968 action[ args.action ] = yaml.safe_load(args.param)
tierno7edb6752016-03-21 17:37:52 +0100969 if args.vnf:
970 action["vnfs"] = args.vnf
971 if args.vm:
972 action["vms"] = args.vm
Anderson Bravalheri0446cd52018-08-17 15:26:19 +0100973
tierno7edb6752016-03-21 17:37:52 +0100974 headers_req = {'content-type': 'application/json'}
975 payload_req = json.dumps(action, indent=4)
tierno7d782ef2019-10-04 12:56:31 +0000976 URLrequest = "http://{}:{}/openmano/{}/instances/{}/action".format(mano_host, mano_port, tenant, toact)
tierno7edb6752016-03-21 17:37:52 +0100977 logger.debug("openmano request: %s", payload_req)
978 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
979 logger.debug("openmano response: %s", mano_response.text )
980 result = 0 if mano_response.status_code==200 else mano_response.status_code
981 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +0000982 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +0100983 if mano_response.status_code == 200:
984 if args.verbose:
tierno7d782ef2019-10-04 12:56:31 +0000985 print(yaml.safe_dump(content, indent=4, default_flow_style=False))
tierno7edb6752016-03-21 17:37:52 +0100986 return result
tiernofc5f80b2018-05-29 16:00:43 +0200987 if "instance_action_id" in content:
988 print("instance_action_id={}".format(content["instance_action_id"]))
989 else:
tierno7d782ef2019-10-04 12:56:31 +0000990 for uuid,c in content.items():
991 print("{:38} {:20} {:20}".format(uuid, c.get('name'), c.get('description')))
tierno7edb6752016-03-21 17:37:52 +0100992 else:
tierno7d782ef2019-10-04 12:56:31 +0000993 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +0100994 return result
995
996
997def instance_vnf_list(args):
tierno7d782ef2019-10-04 12:56:31 +0000998 print("instance-vnf-list")
tierno7edb6752016-03-21 17:37:52 +0100999 return 0
1000
1001def instance_vnf_status(args):
tierno7d782ef2019-10-04 12:56:31 +00001002 print("instance-vnf-status")
tierno7edb6752016-03-21 17:37:52 +01001003 return 0
1004
1005def tenant_create(args):
1006 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1007 tenant_dict={"name": args.name}
1008 if args.description!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001009 tenant_dict["description"] = args.description
tierno7edb6752016-03-21 17:37:52 +01001010 payload_req = json.dumps( {"tenant": tenant_dict })
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001011
tierno7d782ef2019-10-04 12:56:31 +00001012 # print(payload_req)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001013
tierno7d782ef2019-10-04 12:56:31 +00001014 URLrequest = "http://{}:{}/openmano/tenants".format(mano_host, mano_port)
tierno7edb6752016-03-21 17:37:52 +01001015 logger.debug("openmano request: %s", payload_req)
1016 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1017 logger.debug("openmano response: %s", mano_response.text )
1018 return _print_verbose(mano_response, args.verbose)
1019
1020def tenant_list(args):
tierno7d782ef2019-10-04 12:56:31 +00001021 # print("tenant-list",args)
tierno7edb6752016-03-21 17:37:52 +01001022 if args.name:
tierno392f2852016-05-13 12:28:55 +02001023 toshow = _get_item_uuid("tenants", args.name)
tierno7d782ef2019-10-04 12:56:31 +00001024 URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, toshow)
tierno7edb6752016-03-21 17:37:52 +01001025 else:
tierno7d782ef2019-10-04 12:56:31 +00001026 URLrequest = "http://{}:{}/openmano/tenants".format(mano_host, mano_port)
tierno7edb6752016-03-21 17:37:52 +01001027 mano_response = requests.get(URLrequest)
1028 logger.debug("openmano response: %s", mano_response.text )
1029 if args.verbose==None:
1030 args.verbose=0
1031 if args.name!=None:
1032 args.verbose += 1
1033 return _print_verbose(mano_response, args.verbose)
1034
1035def tenant_delete(args):
tierno7d782ef2019-10-04 12:56:31 +00001036 # print("tenant-delete",args)
tierno7edb6752016-03-21 17:37:52 +01001037 todelete = _get_item_uuid("tenants", args.name)
1038 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001039 r = input("Delete tenant {} (y/N)? ".format(args.name))
tierno7edb6752016-03-21 17:37:52 +01001040 if not (len(r)>0 and r[0].lower()=="y"):
1041 return 0
tierno7d782ef2019-10-04 12:56:31 +00001042 URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, todelete)
tierno7edb6752016-03-21 17:37:52 +01001043 mano_response = requests.delete(URLrequest)
1044 logger.debug("openmano response: %s", mano_response.text )
1045 result = 0 if mano_response.status_code==200 else mano_response.status_code
1046 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +00001047 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +01001048 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +00001049 print(content['result'])
tierno7edb6752016-03-21 17:37:52 +01001050 else:
tierno7d782ef2019-10-04 12:56:31 +00001051 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +01001052 return result
1053
1054def datacenter_attach(args):
1055 tenant = _get_tenant()
1056 datacenter = _get_datacenter(args.name)
1057 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001058
tierno7edb6752016-03-21 17:37:52 +01001059 datacenter_dict={}
1060 if args.vim_tenant_id != None:
1061 datacenter_dict['vim_tenant'] = args.vim_tenant_id
1062 if args.vim_tenant_name != None:
1063 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
1064 if args.user != None:
1065 datacenter_dict['vim_username'] = args.user
1066 if args.password != None:
1067 datacenter_dict['vim_password'] = args.password
tierno8008c3a2016-10-13 15:34:28 +00001068 if args.config!=None:
1069 datacenter_dict["config"] = _load_file_or_yaml(args.config)
gcalvinoc62cfa52017-10-05 18:21:25 +02001070
tierno7edb6752016-03-21 17:37:52 +01001071 payload_req = json.dumps( {"datacenter": datacenter_dict })
gcalvinoc62cfa52017-10-05 18:21:25 +02001072
tierno7d782ef2019-10-04 12:56:31 +00001073 # print(payload_req)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001074
tierno7d782ef2019-10-04 12:56:31 +00001075 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter)
tierno7edb6752016-03-21 17:37:52 +01001076 logger.debug("openmano request: %s", payload_req)
1077 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1078 logger.debug("openmano response: %s", mano_response.text )
1079 result = _print_verbose(mano_response, args.verbose)
1080 #provide addional information if error
1081 if mano_response.status_code != 200:
1082 content = mano_response.json()
1083 if "already in use for 'name'" in content['error']['description'] and \
1084 "to database vim_tenants table" in content['error']['description']:
tierno7d782ef2019-10-04 12:56:31 +00001085 print("Try to specify a different name with --vim-tenant-name")
tierno7edb6752016-03-21 17:37:52 +01001086 return result
1087
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001088
1089def datacenter_edit_vim_tenant(args):
1090 tenant = _get_tenant()
1091 datacenter = _get_datacenter(args.name)
1092 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1093
1094 if not (args.vim_tenant_id or args.vim_tenant_name or args.user or args.password or args.config):
1095 raise OpenmanoCLIError("Error. At least one parameter must be updated.")
1096
1097 datacenter_dict = {}
1098 if args.vim_tenant_id != None:
1099 datacenter_dict['vim_tenant'] = args.vim_tenant_id
1100 if args.vim_tenant_name != None:
1101 datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
1102 if args.user != None:
1103 datacenter_dict['vim_username'] = args.user
1104 if args.password != None:
1105 datacenter_dict['vim_password'] = args.password
1106 if args.config != None:
1107 datacenter_dict["config"] = _load_file_or_yaml(args.config)
1108 payload_req = json.dumps({"datacenter": datacenter_dict})
1109
tierno7d782ef2019-10-04 12:56:31 +00001110 # print(payload_req)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001111
tierno7d782ef2019-10-04 12:56:31 +00001112 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001113 logger.debug("openmano request: %s", payload_req)
1114 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1115 logger.debug("openmano response: %s", mano_response.text)
1116 result = _print_verbose(mano_response, args.verbose)
1117
1118 return result
1119
tierno7edb6752016-03-21 17:37:52 +01001120def datacenter_detach(args):
1121 if args.all:
1122 tenant = "any"
1123 else:
1124 tenant = _get_tenant()
1125 datacenter = _get_datacenter(args.name, tenant)
1126 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
tierno7d782ef2019-10-04 12:56:31 +00001127 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter)
tierno7edb6752016-03-21 17:37:52 +01001128 mano_response = requests.delete(URLrequest, headers=headers_req)
1129 logger.debug("openmano response: %s", mano_response.text )
1130 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +00001131 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +01001132 result = 0 if mano_response.status_code==200 else mano_response.status_code
1133 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +00001134 print(content['result'])
tierno7edb6752016-03-21 17:37:52 +01001135 else:
tierno7d782ef2019-10-04 12:56:31 +00001136 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +01001137 return result
1138
1139def datacenter_create(args):
1140 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1141 datacenter_dict={"name": args.name, "vim_url": args.url}
1142 if args.description!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001143 datacenter_dict["description"] = args.description
tierno7edb6752016-03-21 17:37:52 +01001144 if args.type!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001145 datacenter_dict["type"] = args.type
tierno7edb6752016-03-21 17:37:52 +01001146 if args.url!=None:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001147 datacenter_dict["vim_url_admin"] = args.url_admin
tierno7edb6752016-03-21 17:37:52 +01001148 if args.config!=None:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001149 datacenter_dict["config"] = _load_file_or_yaml(args.config)
1150 if args.sdn_controller!=None:
1151 tenant = _get_tenant()
1152 sdn_controller = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1153 if not 'config' in datacenter_dict:
1154 datacenter_dict['config'] = {}
1155 datacenter_dict['config']['sdn-controller'] = sdn_controller
tierno7edb6752016-03-21 17:37:52 +01001156 payload_req = json.dumps( {"datacenter": datacenter_dict })
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001157
tierno7d782ef2019-10-04 12:56:31 +00001158 # print(payload_req)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001159
tierno7d782ef2019-10-04 12:56:31 +00001160 URLrequest = "http://{}:{}/openmano/datacenters".format(mano_host, mano_port)
tierno7edb6752016-03-21 17:37:52 +01001161 logger.debug("openmano request: %s", payload_req)
1162 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1163 logger.debug("openmano response: %s", mano_response.text )
1164 return _print_verbose(mano_response, args.verbose)
1165
1166def datacenter_delete(args):
tierno7d782ef2019-10-04 12:56:31 +00001167 # print("datacenter-delete",args)
tierno7edb6752016-03-21 17:37:52 +01001168 todelete = _get_item_uuid("datacenters", args.name, "any")
1169 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001170 r = input("Delete datacenter {} (y/N)? ".format(args.name))
tierno7edb6752016-03-21 17:37:52 +01001171 if not (len(r)>0 and r[0].lower()=="y"):
1172 return 0
tierno7d782ef2019-10-04 12:56:31 +00001173 URLrequest = "http://{}:{}/openmano/datacenters/{}".format(mano_host, mano_port, todelete)
tierno7edb6752016-03-21 17:37:52 +01001174 mano_response = requests.delete(URLrequest)
1175 logger.debug("openmano response: %s", mano_response.text )
1176 result = 0 if mano_response.status_code==200 else mano_response.status_code
1177 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +00001178 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +01001179 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +00001180 print(content['result'])
tierno7edb6752016-03-21 17:37:52 +01001181 else:
tierno7d782ef2019-10-04 12:56:31 +00001182 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +01001183 return result
1184
tierno20df3bb2017-07-07 14:31:00 +02001185
tierno7edb6752016-03-21 17:37:52 +01001186def datacenter_list(args):
tierno7d782ef2019-10-04 12:56:31 +00001187 # print("datacenter-list",args)
tierno7edb6752016-03-21 17:37:52 +01001188 tenant='any' if args.all else _get_tenant()
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001189
tierno7edb6752016-03-21 17:37:52 +01001190 if args.name:
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001191 toshow = _get_item_uuid("datacenters", args.name, tenant)
tierno7d782ef2019-10-04 12:56:31 +00001192 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, toshow)
tierno7edb6752016-03-21 17:37:52 +01001193 else:
tierno7d782ef2019-10-04 12:56:31 +00001194 URLrequest = "http://{}:{}/openmano/{}/datacenters".format(mano_host, mano_port, tenant)
tierno7edb6752016-03-21 17:37:52 +01001195 mano_response = requests.get(URLrequest)
1196 logger.debug("openmano response: %s", mano_response.text )
1197 if args.verbose==None:
1198 args.verbose=0
1199 if args.name!=None:
1200 args.verbose += 1
1201 return _print_verbose(mano_response, args.verbose)
1202
tierno20df3bb2017-07-07 14:31:00 +02001203
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001204def datacenter_sdn_port_mapping_set(args):
1205 tenant = _get_tenant()
1206 datacenter = _get_datacenter(args.name, tenant)
1207 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1208
1209 if not args.file:
1210 raise OpenmanoCLIError(
1211 "No yaml/json has been provided specifying the SDN port mapping")
tierno20df3bb2017-07-07 14:31:00 +02001212 sdn_port_mapping = _load_file_or_yaml(args.file)
1213 payload_req = json.dumps({"sdn_port_mapping": sdn_port_mapping})
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001214
tierno20df3bb2017-07-07 14:31:00 +02001215 # read
tierno7d782ef2019-10-04 12:56:31 +00001216 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
tierno20df3bb2017-07-07 14:31:00 +02001217 mano_response = requests.get(URLrequest)
1218 logger.debug("openmano response: %s", mano_response.text)
1219 port_mapping = mano_response.json()
1220 if mano_response.status_code != 200:
1221 str(mano_response.json())
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001222 raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001223 if len(port_mapping["sdn_port_mapping"]["ports_mapping"]) > 0:
1224 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001225 r = input("Datacenter {} already contains a port mapping. Overwrite? (y/N)? ".format(datacenter))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001226 if not (len(r) > 0 and r[0].lower() == "y"):
1227 return 0
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001228
tierno20df3bb2017-07-07 14:31:00 +02001229 # clear
tierno7d782ef2019-10-04 12:56:31 +00001230 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
tierno20df3bb2017-07-07 14:31:00 +02001231 mano_response = requests.delete(URLrequest)
1232 logger.debug("openmano response: %s", mano_response.text)
1233 if mano_response.status_code != 200:
1234 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001235
tierno20df3bb2017-07-07 14:31:00 +02001236 # set
tierno7d782ef2019-10-04 12:56:31 +00001237 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001238 logger.debug("openmano request: %s", payload_req)
1239 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1240 logger.debug("openmano response: %s", mano_response.text)
tierno20df3bb2017-07-07 14:31:00 +02001241 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001242
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001243
1244def datacenter_sdn_port_mapping_list(args):
1245 tenant = _get_tenant()
1246 datacenter = _get_datacenter(args.name, tenant)
1247
tierno7d782ef2019-10-04 12:56:31 +00001248 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001249 mano_response = requests.get(URLrequest)
1250 logger.debug("openmano response: %s", mano_response.text)
1251
tierno20df3bb2017-07-07 14:31:00 +02001252 return _print_verbose(mano_response, 4)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001253
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001254
1255def datacenter_sdn_port_mapping_clear(args):
1256 tenant = _get_tenant()
1257 datacenter = _get_datacenter(args.name, tenant)
1258
1259 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001260 r = input("Clean SDN port mapping for datacenter {} (y/N)? ".format(datacenter))
tierno20df3bb2017-07-07 14:31:00 +02001261 if not (len(r) > 0 and r[0].lower() == "y"):
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001262 return 0
1263
tierno7d782ef2019-10-04 12:56:31 +00001264 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001265 mano_response = requests.delete(URLrequest)
1266 logger.debug("openmano response: %s", mano_response.text)
1267
tierno20df3bb2017-07-07 14:31:00 +02001268 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001269
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001270
1271def sdn_controller_create(args):
1272 tenant = _get_tenant()
1273 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1274
tierno8fe7a492017-07-11 13:50:04 +02001275 error_msg=[]
1276 if not args.ip: error_msg.append("'ip'")
1277 if not args.port: error_msg.append("'port'")
1278 if not args.dpid: error_msg.append("'dpid'")
1279 if not args.type: error_msg.append("'type'")
1280 if error_msg:
1281 raise OpenmanoCLIError("The following arguments are required: " + ",".join(error_msg))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001282
1283 controller_dict = {}
1284 controller_dict['name'] = args.name
1285 controller_dict['ip'] = args.ip
1286 controller_dict['port'] = int(args.port)
1287 controller_dict['dpid'] = args.dpid
1288 controller_dict['type'] = args.type
1289 if args.description != None:
1290 controller_dict['description'] = args.description
1291 if args.user != None:
1292 controller_dict['user'] = args.user
1293 if args.password != None:
1294 controller_dict['password'] = args.password
1295
1296 payload_req = json.dumps({"sdn_controller": controller_dict})
1297
tierno7d782ef2019-10-04 12:56:31 +00001298 # print(payload_req)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001299
tierno7d782ef2019-10-04 12:56:31 +00001300 URLrequest = "http://{}:{}/openmano/{}/sdn_controllers".format(mano_host, mano_port, tenant)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001301 logger.debug("openmano request: %s", payload_req)
1302 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1303 logger.debug("openmano response: %s", mano_response.text)
1304 result = _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001305 return result
1306
tierno20df3bb2017-07-07 14:31:00 +02001307
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001308def sdn_controller_edit(args):
1309 tenant = _get_tenant()
1310 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1311 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1312
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001313 controller_dict = {}
tierno20df3bb2017-07-07 14:31:00 +02001314 if args.new_name:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001315 controller_dict['name'] = args.new_name
tierno20df3bb2017-07-07 14:31:00 +02001316 if args.ip:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001317 controller_dict['ip'] = args.ip
tierno20df3bb2017-07-07 14:31:00 +02001318 if args.port:
Pablo Montes Morenob12711f2017-04-06 11:54:34 +02001319 controller_dict['port'] = int(args.port)
tierno20df3bb2017-07-07 14:31:00 +02001320 if args.dpid:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001321 controller_dict['dpid'] = args.dpid
tierno20df3bb2017-07-07 14:31:00 +02001322 if args.type:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001323 controller_dict['type'] = args.type
tierno20df3bb2017-07-07 14:31:00 +02001324 if args.description:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001325 controller_dict['description'] = args.description
tierno20df3bb2017-07-07 14:31:00 +02001326 if args.user:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001327 controller_dict['user'] = args.user
tierno20df3bb2017-07-07 14:31:00 +02001328 if args.password:
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001329 controller_dict['password'] = args.password
1330
tierno20df3bb2017-07-07 14:31:00 +02001331 if not controller_dict:
1332 raise OpenmanoCLIError("At least one parameter must be edited")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001333
tierno20df3bb2017-07-07 14:31:00 +02001334 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001335 r = input("Update SDN controller {} (y/N)? ".format(args.name))
tierno20df3bb2017-07-07 14:31:00 +02001336 if not (len(r) > 0 and r[0].lower() == "y"):
1337 return 0
1338
1339 payload_req = json.dumps({"sdn_controller": controller_dict})
tierno7d782ef2019-10-04 12:56:31 +00001340 # print(payload_req)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001341
tierno7d782ef2019-10-04 12:56:31 +00001342 URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, controller_uuid)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001343 logger.debug("openmano request: %s", payload_req)
1344 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1345 logger.debug("openmano response: %s", mano_response.text)
1346 result = _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001347 return result
1348
tierno20df3bb2017-07-07 14:31:00 +02001349
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001350def sdn_controller_list(args):
1351 tenant = _get_tenant()
1352 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1353
1354 if args.name:
1355 toshow = _get_item_uuid("sdn_controllers", args.name, tenant)
tierno7d782ef2019-10-04 12:56:31 +00001356 URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, toshow)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001357 else:
tierno7d782ef2019-10-04 12:56:31 +00001358 URLrequest = "http://{}:{}/openmano/{}/sdn_controllers".format(mano_host, mano_port, tenant)
1359 # print(URLrequest)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001360 mano_response = requests.get(URLrequest)
1361 logger.debug("openmano response: %s", mano_response.text )
1362 if args.verbose==None:
1363 args.verbose=0
1364 if args.name!=None:
1365 args.verbose += 1
1366
tierno20df3bb2017-07-07 14:31:00 +02001367 # json.dumps(mano_response.json(), indent=4)
1368 return _print_verbose(mano_response, args.verbose)
1369
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001370
1371def sdn_controller_delete(args):
1372 tenant = _get_tenant()
1373 controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
1374
1375 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001376 r = input("Delete SDN controller {} (y/N)? ".format(args.name))
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001377 if not (len(r) > 0 and r[0].lower() == "y"):
1378 return 0
1379
tierno7d782ef2019-10-04 12:56:31 +00001380 URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, controller_uuid)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001381 mano_response = requests.delete(URLrequest)
1382 logger.debug("openmano response: %s", mano_response.text)
tierno20df3bb2017-07-07 14:31:00 +02001383 return _print_verbose(mano_response, args.verbose)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001384
tierno7edb6752016-03-21 17:37:52 +01001385def vim_action(args):
tierno7d782ef2019-10-04 12:56:31 +00001386 # print("datacenter-net-action",args)
tierno7edb6752016-03-21 17:37:52 +01001387 tenant = _get_tenant()
1388 datacenter = _get_datacenter(args.datacenter, tenant)
1389 if args.verbose==None:
1390 args.verbose=0
1391 if args.action=="list":
tierno7d782ef2019-10-04 12:56:31 +00001392 URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s".format(mano_host, mano_port, tenant, datacenter, args.item)
tierno7edb6752016-03-21 17:37:52 +01001393 if args.name!=None:
1394 args.verbose += 1
1395 URLrequest += "/" + args.name
1396 mano_response = requests.get(URLrequest)
1397 logger.debug("openmano response: %s", mano_response.text )
1398 return _print_verbose(mano_response, args.verbose)
1399 elif args.action=="delete":
tierno7d782ef2019-10-04 12:56:31 +00001400 URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s/{}".format(mano_host, mano_port, tenant, datacenter, args.item, args.name)
tierno7edb6752016-03-21 17:37:52 +01001401 mano_response = requests.delete(URLrequest)
1402 logger.debug("openmano response: %s", mano_response.text )
1403 result = 0 if mano_response.status_code==200 else mano_response.status_code
1404 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +00001405 # print(json.dumps(content, indent=4))
tierno7edb6752016-03-21 17:37:52 +01001406 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +00001407 print(content['result'])
tierno7edb6752016-03-21 17:37:52 +01001408 else:
tierno7d782ef2019-10-04 12:56:31 +00001409 print(content['error']['description'])
tierno7edb6752016-03-21 17:37:52 +01001410 return result
1411 elif args.action=="create":
1412 headers_req = {'content-type': 'application/yaml'}
1413 if args.file:
1414 create_dict = _load_file_or_yaml(args.file)
1415 if args.item not in create_dict:
1416 create_dict = {args.item: create_dict}
1417 else:
1418 create_dict = {args.item:{}}
1419 if args.name:
1420 create_dict[args.item]['name'] = args.name
1421 #if args.description:
1422 # create_dict[args.item]['description'] = args.description
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001423 if args.item=="network":
tierno7edb6752016-03-21 17:37:52 +01001424 if args.bind_net:
1425 create_dict[args.item]['bind_net'] = args.bind_net
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001426 if args.type:
1427 create_dict[args.item]['type'] = args.type
tierno7edb6752016-03-21 17:37:52 +01001428 if args.shared:
1429 create_dict[args.item]['shared'] = args.shared
1430 if "name" not in create_dict[args.item]:
tierno7d782ef2019-10-04 12:56:31 +00001431 print("You must provide a name in the descriptor file or with the --name option")
tierno7edb6752016-03-21 17:37:52 +01001432 return
tierno7d782ef2019-10-04 12:56:31 +00001433 payload_req = yaml.safe_dump(create_dict, explicit_start=True, indent=4, default_flow_style=False, tags=False,
1434 allow_unicode=True)
tierno7edb6752016-03-21 17:37:52 +01001435 logger.debug("openmano request: %s", payload_req)
tierno7d782ef2019-10-04 12:56:31 +00001436 URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s".format(mano_host, mano_port, tenant, datacenter, args.item)
tierno7edb6752016-03-21 17:37:52 +01001437 mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
1438 logger.debug("openmano response: %s", mano_response.text )
1439 if args.verbose==None:
1440 args.verbose=0
1441 return _print_verbose(mano_response, args.verbose)
1442
tierno20df3bb2017-07-07 14:31:00 +02001443
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001444def _get_items(item, item_name_id=None, datacenter=None, tenant=None):
tierno7d782ef2019-10-04 12:56:31 +00001445 URLrequest = "http://{}:{}/openmano".format(mano_host, mano_port)
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001446 if tenant:
1447 URLrequest += "/" + tenant
1448 if datacenter:
1449 URLrequest += "/vim/" + datacenter
1450 if item:
1451 URLrequest += "/" + item +"s"
1452 if item_name_id:
1453 URLrequest += "/" + item_name_id
1454 mano_response = requests.get(URLrequest)
1455 logger.debug("openmano response: %s", mano_response.text )
1456
1457 return mano_response
1458
tierno20df3bb2017-07-07 14:31:00 +02001459
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001460def vim_net_sdn_attach(args):
1461 #Verify the network exists in the vim
1462 tenant = _get_tenant()
1463 datacenter = _get_datacenter(args.datacenter, tenant)
1464 result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
1465 content = yaml.load(result.content)
1466 if 'networks' in content:
1467 raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
1468 if 'error' in content:
1469 raise OpenmanoCLIError(yaml.safe_dump(content))
1470 network_uuid = content['network']['id']
1471
1472 #Make call to attach the dataplane port to the SND network associated to the vim network
1473 headers_req = {'content-type': 'application/yaml'}
1474 payload_req = {'port': args.port}
1475 if args.vlan:
1476 payload_req['vlan'] = int(args.vlan)
1477 if args.mac:
1478 payload_req['mac'] = args.mac
1479
tierno7d782ef2019-10-04 12:56:31 +00001480 URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/attach".format(mano_host, mano_port, tenant, datacenter, network_uuid)
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001481 logger.debug("openmano request: %s", payload_req)
1482 mano_response = requests.post(URLrequest, headers=headers_req, data=json.dumps(payload_req))
1483 logger.debug("openmano response: %s", mano_response.text)
1484 result = _print_verbose(mano_response, args.verbose)
tierno20df3bb2017-07-07 14:31:00 +02001485 return result
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001486
1487
1488def vim_net_sdn_detach(args):
1489 if not args.all and not args.id:
tierno7d782ef2019-10-04 12:56:31 +00001490 print("--all or --id must be used")
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001491 return 1
1492
1493 # Verify the network exists in the vim
1494 tenant = _get_tenant()
1495 datacenter = _get_datacenter(args.datacenter, tenant)
1496 result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
1497 content = yaml.load(result.content)
1498 if 'networks' in content:
1499 raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
1500 if 'error' in content:
1501 raise OpenmanoCLIError(yaml.safe_dump(content))
1502 network_uuid = content['network']['id']
1503
1504 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001505 r = input("Confirm action' (y/N)? ")
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001506 if len(r) == 0 or r[0].lower() != "y":
1507 return 0
1508
1509 if args.id:
tierno7d782ef2019-10-04 12:56:31 +00001510 URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/detach/{}".format(
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001511 mano_host, mano_port, tenant, datacenter, network_uuid, args.id)
1512 else:
tierno7d782ef2019-10-04 12:56:31 +00001513 URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/detach".format(
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001514 mano_host, mano_port, tenant, datacenter, network_uuid)
1515 mano_response = requests.delete(URLrequest)
1516 logger.debug("openmano response: %s", mano_response.text)
1517 result = _print_verbose(mano_response, args.verbose)
tierno20df3bb2017-07-07 14:31:00 +02001518 return result
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02001519
tierno7edb6752016-03-21 17:37:52 +01001520
1521def datacenter_net_action(args):
1522 if args.action == "net-update":
tierno7d782ef2019-10-04 12:56:31 +00001523 print("This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano"
1524 " datacenter-netmap-import' instead!!!")
1525 print()
tierno7edb6752016-03-21 17:37:52 +01001526 args.action = "netmap-delete"
1527 args.netmap = None
1528 args.all = True
1529 r = datacenter_netmap_action(args)
1530 if r == 0:
1531 args.force = True
tierno5acf7202016-08-29 14:28:13 +02001532 args.action = "netmap-import"
tierno7edb6752016-03-21 17:37:52 +01001533 r = datacenter_netmap_action(args)
1534 return r
1535
1536 if args.action == "net-edit":
1537 args.netmap = args.net
1538 args.name = None
1539 elif args.action == "net-list":
1540 args.netmap = None
1541 elif args.action == "net-delete":
1542 args.netmap = args.net
1543 args.all = False
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001544
tierno7edb6752016-03-21 17:37:52 +01001545 args.action = "netmap" + args.action[3:]
1546 args.vim_name=None
1547 args.vim_id=None
tierno7d782ef2019-10-04 12:56:31 +00001548 print("This command is deprecated, use 'openmano datacenter-{}' instead!!!".format(args.action))
1549 print()
tierno7edb6752016-03-21 17:37:52 +01001550 return datacenter_netmap_action(args)
1551
1552def datacenter_netmap_action(args):
1553 tenant = _get_tenant()
1554 datacenter = _get_datacenter(args.datacenter, tenant)
tierno7d782ef2019-10-04 12:56:31 +00001555 # print("datacenter_netmap_action",args)
tierno7edb6752016-03-21 17:37:52 +01001556 payload_req = None
1557 if args.verbose==None:
1558 args.verbose=0
1559 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
tierno7d782ef2019-10-04 12:56:31 +00001560 URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/netmaps".format(mano_host, mano_port, tenant, datacenter)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001561
tierno7edb6752016-03-21 17:37:52 +01001562 if args.action=="netmap-list":
1563 if args.netmap:
1564 URLrequest += "/" + args.netmap
1565 args.verbose += 1
1566 mano_response = requests.get(URLrequest)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001567
tierno7edb6752016-03-21 17:37:52 +01001568 elif args.action=="netmap-delete":
1569 if args.netmap and args.all:
tierno7d782ef2019-10-04 12:56:31 +00001570 print("you can not use a netmap name and the option --all at the same time")
tierno7edb6752016-03-21 17:37:52 +01001571 return 1
1572 if args.netmap:
tierno7d782ef2019-10-04 12:56:31 +00001573 force_text= "Delete default netmap '{}' from datacenter '{}' (y/N)? ".format(args.netmap, datacenter)
tierno7edb6752016-03-21 17:37:52 +01001574 URLrequest += "/" + args.netmap
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001575 elif args.all:
tierno7d782ef2019-10-04 12:56:31 +00001576 force_text="Delete all default netmaps from datacenter '{}' (y/N)? ".format(datacenter)
tierno7edb6752016-03-21 17:37:52 +01001577 else:
tierno7d782ef2019-10-04 12:56:31 +00001578 print("you must specify a netmap name or the option --all")
tierno7edb6752016-03-21 17:37:52 +01001579 return 1
1580 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001581 r = input(force_text)
tierno7edb6752016-03-21 17:37:52 +01001582 if len(r)>0 and r[0].lower()=="y":
1583 pass
1584 else:
1585 return 0
1586 mano_response = requests.delete(URLrequest, headers=headers_req)
tierno5acf7202016-08-29 14:28:13 +02001587 elif args.action=="netmap-import":
tierno7edb6752016-03-21 17:37:52 +01001588 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001589 r = input("Create all the available networks from datacenter '{}' as default netmaps (y/N)? ".format(datacenter))
tierno7edb6752016-03-21 17:37:52 +01001590 if len(r)>0 and r[0].lower()=="y":
1591 pass
1592 else:
1593 return 0
1594 URLrequest += "/upload"
1595 mano_response = requests.post(URLrequest, headers=headers_req)
1596 elif args.action=="netmap-edit" or args.action=="netmap-create":
1597 if args.file:
1598 payload = _load_file_or_yaml(args.file)
1599 else:
1600 payload = {}
1601 if "netmap" not in payload:
1602 payload = {"netmap": payload}
1603 if args.name:
1604 payload["netmap"]["name"] = args.name
1605 if args.vim_id:
1606 payload["netmap"]["vim_id"] = args.vim_id
1607 if args.action=="netmap-create" and args.vim_name:
1608 payload["netmap"]["vim_name"] = args.vim_name
1609 payload_req = json.dumps(payload)
1610 logger.debug("openmano request: %s", payload_req)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001611
tierno7edb6752016-03-21 17:37:52 +01001612 if args.action=="netmap-edit" and not args.force:
1613 if len(payload["netmap"]) == 0:
tierno7d782ef2019-10-04 12:56:31 +00001614 print("You must supply some parameter to edit")
tierno7edb6752016-03-21 17:37:52 +01001615 return 1
tierno7d782ef2019-10-04 12:56:31 +00001616 r = input("Edit default netmap '{}' from datacenter '{}' (y/N)? ".format(args.netmap, datacenter))
tierno7edb6752016-03-21 17:37:52 +01001617 if len(r)>0 and r[0].lower()=="y":
1618 pass
1619 else:
1620 return 0
1621 URLrequest += "/" + args.netmap
1622 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1623 else: #netmap-create
1624 if "vim_name" not in payload["netmap"] and "vim_id" not in payload["netmap"]:
tierno7d782ef2019-10-04 12:56:31 +00001625 print("You must supply either --vim-id or --vim-name option; or include one of them in the file"
1626 " descriptor")
tierno7edb6752016-03-21 17:37:52 +01001627 return 1
1628 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1629
1630 logger.debug("openmano response: %s", mano_response.text )
1631 return _print_verbose(mano_response, args.verbose)
1632
tierno20df3bb2017-07-07 14:31:00 +02001633
tierno7edb6752016-03-21 17:37:52 +01001634def element_edit(args):
1635 element = _get_item_uuid(args.element, args.name)
1636 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
tierno7d782ef2019-10-04 12:56:31 +00001637 URLrequest = "http://{}:{}/openmano/{}/{}".format(mano_host, mano_port, args.element, element)
tierno7edb6752016-03-21 17:37:52 +01001638 payload=_load_file_or_yaml(args.file)
1639 if args.element[:-1] not in payload:
1640 payload = {args.element[:-1]: payload }
1641 payload_req = json.dumps(payload)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001642
tierno7d782ef2019-10-04 12:56:31 +00001643 # print(payload_req)
tierno7edb6752016-03-21 17:37:52 +01001644 if not args.force or (args.name==None and args.filer==None):
tierno7d782ef2019-10-04 12:56:31 +00001645 r = input(" Edit " + args.element[:-1] + " " + args.name + " (y/N)? ")
tierno7edb6752016-03-21 17:37:52 +01001646 if len(r)>0 and r[0].lower()=="y":
1647 pass
1648 else:
1649 return 0
1650 logger.debug("openmano request: %s", payload_req)
1651 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1652 logger.debug("openmano response: %s", mano_response.text )
1653 if args.verbose==None:
1654 args.verbose=0
1655 if args.name!=None:
1656 args.verbose += 1
1657 return _print_verbose(mano_response, args.verbose)
1658
1659
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001660def datacenter_edit(args):
1661 tenant = _get_tenant()
1662 element = _get_item_uuid('datacenters', args.name, tenant)
1663 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
tierno7d782ef2019-10-04 12:56:31 +00001664 URLrequest = "http://{}:{}/openmano/datacenters/{}".format(mano_host, mano_port, element)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001665
1666 has_arguments = False
1667 if args.file != None:
1668 has_arguments = True
1669 payload = _load_file_or_yaml(args.file)
1670 else:
1671 payload = {}
1672
1673 if args.sdn_controller != None:
1674 has_arguments = True
1675 if not 'config' in payload:
1676 payload['config'] = {}
1677 if not 'sdn-controller' in payload['config']:
1678 payload['config']['sdn-controller'] = {}
1679 if args.sdn_controller == 'null':
1680 payload['config']['sdn-controller'] = None
1681 else:
1682 payload['config']['sdn-controller'] = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
1683
1684 if not has_arguments:
1685 raise OpenmanoCLIError("At least one argument must be provided to modify the datacenter")
1686
1687 if 'datacenter' not in payload:
1688 payload = {'datacenter': payload}
1689 payload_req = json.dumps(payload)
1690
tierno7d782ef2019-10-04 12:56:31 +00001691 # print(payload_req)
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001692 if not args.force or (args.name == None and args.filer == None):
tierno7d782ef2019-10-04 12:56:31 +00001693 r = input(" Edit datacenter " + args.name + " (y/N)? ")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01001694 if len(r) > 0 and r[0].lower() == "y":
1695 pass
1696 else:
1697 return 0
1698 logger.debug("openmano request: %s", payload_req)
1699 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1700 logger.debug("openmano response: %s", mano_response.text)
1701 if args.verbose == None:
1702 args.verbose = 0
1703 if args.name != None:
1704 args.verbose += 1
1705 return _print_verbose(mano_response, args.verbose)
1706
tierno20df3bb2017-07-07 14:31:00 +02001707
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001708# WIM
1709def wim_account_create(args):
1710 tenant = _get_tenant()
1711 wim = _get_wim(args.name)
1712 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1713
1714 wim_dict = {}
1715 if args.account_name is not None:
1716 wim_dict['name'] = args.account_name
1717 if args.user is not None:
1718 wim_dict['user'] = args.user
1719 if args.password is not None:
1720 wim_dict['password'] = args.password
1721 if args.config is not None:
1722 wim_dict["config"] = _load_file_or_yaml(args.config)
1723
1724 payload_req = json.dumps({"wim_account": wim_dict})
1725
tierno7d782ef2019-10-04 12:56:31 +00001726 URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001727 logger.debug("openmano request: %s", payload_req)
1728 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1729 logger.debug("openmano response: %s", mano_response.text)
1730 result = _print_verbose(mano_response, args.verbose)
1731 # provide addional information if error
1732 if mano_response.status_code != 200:
1733 content = mano_response.json()
1734 if "already in use for 'name'" in content['error']['description'] and \
1735 "to database wim_tenants table" in content['error']['description']:
tierno7d782ef2019-10-04 12:56:31 +00001736 print("Try to specify a different name with --wim-tenant-name")
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001737 return result
1738
1739
1740def wim_account_delete(args):
1741 if args.all:
1742 tenant = "any"
1743 else:
1744 tenant = _get_tenant()
1745 wim = _get_wim(args.name, tenant)
1746 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
tierno7d782ef2019-10-04 12:56:31 +00001747 URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001748 mano_response = requests.delete(URLrequest, headers=headers_req)
1749 logger.debug("openmano response: %s", mano_response.text)
1750 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +00001751 # print(json.dumps(content, indent=4))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001752 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1753 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +00001754 print(content['result'])
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001755 else:
tierno7d782ef2019-10-04 12:56:31 +00001756 print(content['error']['description'])
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001757 return result
1758
1759
1760def wim_account_edit(args):
1761 tenant = _get_tenant()
1762 wim = _get_wim(args.name)
1763 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1764
1765 wim_dict = {}
1766 if not args.account_name:
1767 wim_dict['name'] = args.vim_tenant_name
1768 if not args.user:
1769 wim_dict['user'] = args.user
1770 if not args.password:
1771 wim_dict['password'] = args.password
1772 if not args.config:
1773 wim_dict["config"] = _load_file_or_yaml(args.config)
1774
1775 payload_req = json.dumps({"wim_account": wim_dict})
1776
tierno7d782ef2019-10-04 12:56:31 +00001777 # print(payload_req)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001778
tierno7d782ef2019-10-04 12:56:31 +00001779 URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001780 logger.debug("openmano request: %s", payload_req)
1781 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1782 logger.debug("openmano response: %s", mano_response.text)
1783 result = _print_verbose(mano_response, args.verbose)
1784 # provide addional information if error
1785 if mano_response.status_code != 200:
1786 content = mano_response.json()
1787 if "already in use for 'name'" in content['error']['description'] and \
1788 "to database wim_tenants table" in content['error']['description']:
tierno7d782ef2019-10-04 12:56:31 +00001789 print("Try to specify a different name with --wim-tenant-name")
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001790 return result
1791
1792def wim_create(args):
1793 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1794 wim_dict = {"name": args.name, "wim_url": args.url}
1795 if args.description != None:
1796 wim_dict["description"] = args.description
1797 if args.type != None:
1798 wim_dict["type"] = args.type
1799 if args.config != None:
1800 wim_dict["config"] = _load_file_or_yaml(args.config)
1801
1802 payload_req = json.dumps({"wim": wim_dict})
1803
tierno7d782ef2019-10-04 12:56:31 +00001804 URLrequest = "http://{}:{}/openmano/wims".format(mano_host, mano_port)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001805 logger.debug("openmano request: %s", payload_req)
1806 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1807 logger.debug("openmano response: %s", mano_response.text)
1808 return _print_verbose(mano_response, args.verbose)
1809
1810
1811def wim_edit(args):
1812 tenant = _get_tenant()
1813 element = _get_item_uuid('wims', args.name, tenant)
1814 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
tierno7d782ef2019-10-04 12:56:31 +00001815 URLrequest = "http://{}:{}/openmano/wims/{}".format(mano_host, mano_port, element)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001816
1817 has_arguments = False
1818 if args.file != None:
1819 has_arguments = True
1820 payload = _load_file_or_yaml(args.file)
1821 else:
1822 payload = {}
1823
1824 if not has_arguments:
1825 raise OpenmanoCLIError("At least one argument must be provided to modify the wim")
1826
1827 if 'wim' not in payload:
1828 payload = {'wim': payload}
1829 payload_req = json.dumps(payload)
1830
tierno7d782ef2019-10-04 12:56:31 +00001831 # print(payload_req)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001832 if not args.force or (args.name == None and args.filer == None):
tierno7d782ef2019-10-04 12:56:31 +00001833 r = input(" Edit wim " + args.name + " (y/N)? ")
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001834 if len(r) > 0 and r[0].lower() == "y":
1835 pass
1836 else:
1837 return 0
1838 logger.debug("openmano request: %s", payload_req)
1839 mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
1840 logger.debug("openmano response: %s", mano_response.text)
1841 if args.verbose == None:
1842 args.verbose = 0
1843 if args.name != None:
1844 args.verbose += 1
1845 return _print_verbose(mano_response, args.verbose)
1846
1847
1848def wim_delete(args):
tierno7d782ef2019-10-04 12:56:31 +00001849 # print("wim-delete",args)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001850 todelete = _get_item_uuid("wims", args.name, "any")
1851 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001852 r = input("Delete wim {} (y/N)? ".format(args.name))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001853 if not (len(r) > 0 and r[0].lower() == "y"):
1854 return 0
tierno7d782ef2019-10-04 12:56:31 +00001855 URLrequest = "http://{}:{}/openmano/wims/{}".format(mano_host, mano_port, todelete)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001856 mano_response = requests.delete(URLrequest)
1857 logger.debug("openmano response: %s", mano_response.text)
1858 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1859 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +00001860 # print(json.dumps(content, indent=4)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001861 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +00001862 print(content['result'])
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001863 else:
tierno7d782ef2019-10-04 12:56:31 +00001864 print(content['error']['description'])
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001865 return result
1866
1867
1868def wim_list(args):
tierno7d782ef2019-10-04 12:56:31 +00001869 # print("wim-list",args)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001870 tenant = 'any' if args.all else _get_tenant()
1871
1872 if args.name:
1873 toshow = _get_item_uuid("wims", args.name, tenant)
tierno7d782ef2019-10-04 12:56:31 +00001874 URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, toshow)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001875 else:
tierno7d782ef2019-10-04 12:56:31 +00001876 URLrequest = "http://{}:{}/openmano/{}/wims".format(mano_host, mano_port, tenant)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001877 mano_response = requests.get(URLrequest)
1878 logger.debug("openmano response: %s", mano_response.text)
1879 if args.verbose == None:
1880 args.verbose = 0
1881 if args.name != None:
1882 args.verbose += 1
1883 return _print_verbose(mano_response, args.verbose)
1884
1885
1886def wim_port_mapping_set(args):
1887 tenant = _get_tenant()
1888 wim = _get_wim(args.name, tenant)
1889 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
1890
1891 if not args.file:
1892 raise OpenmanoCLIError(
1893 "No yaml/json has been provided specifying the WIM port mapping")
1894 wim_port_mapping = _load_file_or_yaml(args.file)
1895
1896 payload_req = json.dumps({"wim_port_mapping": wim_port_mapping})
1897
1898 # read
tierno7d782ef2019-10-04 12:56:31 +00001899 URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001900 mano_response = requests.get(URLrequest)
1901 logger.debug("openmano response: %s", mano_response.text)
1902 port_mapping = mano_response.json()
1903
1904 if mano_response.status_code != 200:
1905 str(mano_response.json())
1906 raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
1907 # TODO: check this if statement
1908 if len(port_mapping["wim_port_mapping"]) > 0:
1909 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001910 r = input("WIM {} already contains a port mapping. Overwrite? (y/N)? ".format(wim))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001911 if not (len(r) > 0 and r[0].lower() == "y"):
1912 return 0
1913
1914 # clear
tierno7d782ef2019-10-04 12:56:31 +00001915 URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001916 mano_response = requests.delete(URLrequest)
1917 logger.debug("openmano response: %s", mano_response.text)
1918 if mano_response.status_code != 200:
1919 return _print_verbose(mano_response, args.verbose)
1920
1921 # set
tierno7d782ef2019-10-04 12:56:31 +00001922 URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001923 logger.debug("openmano request: %s", payload_req)
1924 mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
1925 logger.debug("openmano response: %s", mano_response.text)
1926 return _print_verbose(mano_response, 4)
1927
1928
1929def wim_port_mapping_list(args):
1930 tenant = _get_tenant()
1931 wim = _get_wim(args.name, tenant)
1932
tierno7d782ef2019-10-04 12:56:31 +00001933 URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001934 mano_response = requests.get(URLrequest)
1935 logger.debug("openmano response: %s", mano_response.text)
1936
1937 return _print_verbose(mano_response, 4)
1938
1939
1940def wim_port_mapping_clear(args):
1941 tenant = _get_tenant()
1942 wim = _get_wim(args.name, tenant)
1943
1944 if not args.force:
tierno7d782ef2019-10-04 12:56:31 +00001945 r = input("Clear WIM port mapping for wim {} (y/N)? ".format(wim))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001946 if not (len(r) > 0 and r[0].lower() == "y"):
1947 return 0
1948
tierno7d782ef2019-10-04 12:56:31 +00001949 URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001950 mano_response = requests.delete(URLrequest)
1951 logger.debug("openmano response: %s", mano_response.text)
1952 content = mano_response.json()
tierno7d782ef2019-10-04 12:56:31 +00001953 # print(json.dumps(content, indent=4))
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001954 result = 0 if mano_response.status_code == 200 else mano_response.status_code
1955 if mano_response.status_code == 200:
tierno7d782ef2019-10-04 12:56:31 +00001956 print(content['result'])
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001957 else:
tierno7d782ef2019-10-04 12:56:31 +00001958 print(content['error']['description'])
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001959 return result
1960
1961
tierno6ddeded2017-05-16 15:40:26 +02001962def version(args):
1963 headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
tierno7d782ef2019-10-04 12:56:31 +00001964 URLrequest = "http://{}:{}/openmano/version".format(mano_host, mano_port)
tierno6ddeded2017-05-16 15:40:26 +02001965
1966 mano_response = requests.get(URLrequest, headers=headers_req)
1967 logger.debug("openmano response: %s", mano_response.text)
tierno7d782ef2019-10-04 12:56:31 +00001968 print(mano_response.text)
tierno6ddeded2017-05-16 15:40:26 +02001969
1970
tierno7d782ef2019-10-04 12:56:31 +00001971def main():
1972 global mano_host
1973 global mano_port
1974 global mano_tenant
1975 global logger
tierno7edb6752016-03-21 17:37:52 +01001976 mano_tenant = os.getenv('OPENMANO_TENANT', None)
1977 mano_host = os.getenv('OPENMANO_HOST',"localhost")
1978 mano_port = os.getenv('OPENMANO_PORT',"9090")
1979 mano_datacenter = os.getenv('OPENMANO_DATACENTER',None)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001980 # WIM env variable for default WIM
1981 mano_wim = os.getenv('OPENMANO_WIM', None)
1982
tierno7edb6752016-03-21 17:37:52 +01001983 main_parser = ThrowingArgumentParser(description='User program to interact with OPENMANO-SERVER (openmanod)')
tierno6ddeded2017-05-16 15:40:26 +02001984 main_parser.add_argument('--version', action='version', help="get version of this client",
1985 version='%(prog)s client version ' + __version__ +
1986 " (Note: use '%(prog)s version' to get server version)")
1987
tierno7edb6752016-03-21 17:37:52 +01001988 subparsers = main_parser.add_subparsers(help='commands')
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01001989
tierno7edb6752016-03-21 17:37:52 +01001990 parent_parser = argparse.ArgumentParser(add_help=False)
1991 parent_parser.add_argument('--verbose', '-v', action='count', help="increase verbosity level. Use several times")
1992 parent_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
1993
garciadeblas0e9fd832016-07-08 15:20:18 +02001994 config_parser = subparsers.add_parser('config', parents=[parent_parser], help="prints configuration values")
1995 config_parser.add_argument("-n", action="store_true", help="resolves tenant and datacenter names")
1996 config_parser.set_defaults(func=config)
1997
tierno6ddeded2017-05-16 15:40:26 +02001998 version_parser = subparsers.add_parser('version', parents=[parent_parser], help="get server version")
1999 version_parser.set_defaults(func=version)
2000
tierno7edb6752016-03-21 17:37:52 +01002001 vnf_create_parser = subparsers.add_parser('vnf-create', parents=[parent_parser], help="adds a vnf into the catalogue")
2002 vnf_create_parser.add_argument("file", action="store", help="location of the JSON file describing the VNF").completer = FilesCompleter
2003 vnf_create_parser.add_argument("--name", action="store", help="name of the VNF (if it exists in the VNF descriptor, it is overwritten)")
2004 vnf_create_parser.add_argument("--description", action="store", help="description of the VNF (if it exists in the VNF descriptor, it is overwritten)")
2005 vnf_create_parser.add_argument("--image-path", action="store", help="change image path locations (overwritten)")
garciadeblas14480452017-01-10 13:08:07 +01002006 vnf_create_parser.add_argument("--image-name", action="store", help="change image name (overwritten)")
2007 vnf_create_parser.add_argument("--image-checksum", action="store", help="change image checksum (overwritten)")
tierno7edb6752016-03-21 17:37:52 +01002008 vnf_create_parser.set_defaults(func=vnf_create)
2009
2010 vnf_list_parser = subparsers.add_parser('vnf-list', parents=[parent_parser], help="lists information about a vnf")
2011 vnf_list_parser.add_argument("name", nargs='?', help="name of the VNF")
2012 vnf_list_parser.add_argument("-a", "--all", action="store_true", help="shows all vnfs, not only the owned or public ones")
2013 #vnf_list_parser.add_argument('--descriptor', help="prints the VNF descriptor", action="store_true")
2014 vnf_list_parser.set_defaults(func=vnf_list)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002015
tierno7edb6752016-03-21 17:37:52 +01002016 vnf_delete_parser = subparsers.add_parser('vnf-delete', parents=[parent_parser], help="deletes a vnf from the catalogue")
2017 vnf_delete_parser.add_argument("name", action="store", help="name or uuid of the VNF to be deleted")
2018 vnf_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2019 vnf_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2020 vnf_delete_parser.set_defaults(func=vnf_delete)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002021
tierno7edb6752016-03-21 17:37:52 +01002022 scenario_create_parser = subparsers.add_parser('scenario-create', parents=[parent_parser], help="adds a scenario into the OPENMANO DB")
2023 scenario_create_parser.add_argument("file", action="store", help="location of the YAML file describing the scenario").completer = FilesCompleter
2024 scenario_create_parser.add_argument("--name", action="store", help="name of the scenario (if it exists in the YAML scenario, it is overwritten)")
2025 scenario_create_parser.add_argument("--description", action="store", help="description of the scenario (if it exists in the YAML scenario, it is overwritten)")
2026 scenario_create_parser.set_defaults(func=scenario_create)
2027
2028 scenario_list_parser = subparsers.add_parser('scenario-list', parents=[parent_parser], help="lists information about a scenario")
2029 scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario")
2030 #scenario_list_parser.add_argument('--descriptor', help="prints the scenario descriptor", action="store_true")
2031 scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all scenarios, not only the owned or public ones")
2032 scenario_list_parser.set_defaults(func=scenario_list)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002033
tierno7edb6752016-03-21 17:37:52 +01002034 scenario_delete_parser = subparsers.add_parser('scenario-delete', parents=[parent_parser], help="deletes a scenario from the OPENMANO DB")
2035 scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario to be deleted")
2036 scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2037 scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2038 scenario_delete_parser.set_defaults(func=scenario_delete)
2039
2040 scenario_deploy_parser = subparsers.add_parser('scenario-deploy', parents=[parent_parser], help="deploys a scenario")
2041 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be deployed")
2042 scenario_deploy_parser.add_argument("name", action="store", help="name of the instance")
2043 scenario_deploy_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
2044 scenario_deploy_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
2045 scenario_deploy_parser.add_argument("--description", action="store", help="description of the instance")
2046 scenario_deploy_parser.set_defaults(func=scenario_deploy)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002047
tierno7edb6752016-03-21 17:37:52 +01002048 scenario_deploy_parser = subparsers.add_parser('scenario-verify', help="verifies if a scenario can be deployed (deploys it and deletes it)")
2049 scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be verified")
2050 scenario_deploy_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
2051 scenario_deploy_parser.set_defaults(func=scenario_verify)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002052
tierno7edb6752016-03-21 17:37:52 +01002053 instance_scenario_create_parser = subparsers.add_parser('instance-scenario-create', parents=[parent_parser], help="deploys a scenario")
2054 instance_scenario_create_parser.add_argument("file", nargs='?', help="descriptor of the instance. Must be a file or yaml/json text")
2055 instance_scenario_create_parser.add_argument("--scenario", action="store", help="name or uuid of the scenario to be deployed")
2056 instance_scenario_create_parser.add_argument("--name", action="store", help="name of the instance")
2057 instance_scenario_create_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
2058 instance_scenario_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
2059 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")
2060 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 +02002061 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")
2062 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 +01002063 instance_scenario_create_parser.add_argument("--description", action="store", help="description of the instance")
2064 instance_scenario_create_parser.set_defaults(func=instance_create)
2065
2066 instance_scenario_list_parser = subparsers.add_parser('instance-scenario-list', parents=[parent_parser], help="lists information about a scenario instance")
2067 instance_scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario instance")
2068 instance_scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all instance-scenarios, not only the owned")
2069 instance_scenario_list_parser.set_defaults(func=instance_scenario_list)
2070
2071 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)")
2072 instance_scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario instance to be deleted")
2073 instance_scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2074 instance_scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
2075 instance_scenario_delete_parser.set_defaults(func=instance_scenario_delete)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002076
tierno7edb6752016-03-21 17:37:52 +01002077 instance_scenario_action_parser = subparsers.add_parser('instance-scenario-action', parents=[parent_parser], help="invoke an action over part or the whole scenario instance")
2078 instance_scenario_action_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
2079 instance_scenario_action_parser.add_argument("action", action="store", type=str, \
tiernofc5f80b2018-05-29 16:00:43 +02002080 choices=["start","pause","resume","shutoff","shutdown","forceOff","rebuild","reboot", "console", "add_public_key","vdu-scaling"],\
tierno7edb6752016-03-21 17:37:52 +01002081 help="action to send")
tiernofc5f80b2018-05-29 16:00:43 +02002082 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 +01002083 instance_scenario_action_parser.add_argument("--vnf", action="append", help="VNF to act on (can use several entries)")
2084 instance_scenario_action_parser.add_argument("--vm", action="append", help="VM to act on (can use several entries)")
2085 instance_scenario_action_parser.set_defaults(func=instance_scenario_action)
2086
tierno868220c2017-09-26 00:11:05 +02002087 action_parser = subparsers.add_parser('action-list', parents=[parent_parser], help="get action over an instance status")
2088 action_parser.add_argument("id", nargs='?', action="store", help="action id")
2089 action_parser.add_argument("--instance", action="store", help="fitler by this instance_id")
2090 action_parser.add_argument("--all", action="store", help="Not filter by tenant")
2091 action_parser.set_defaults(func=get_action)
2092
tierno7edb6752016-03-21 17:37:52 +01002093 #instance_scenario_status_parser = subparsers.add_parser('instance-scenario-status', help="show the status of a scenario instance")
2094 #instance_scenario_status_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
2095 #instance_scenario_status_parser.set_defaults(func=instance_scenario_status)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002096
tierno7edb6752016-03-21 17:37:52 +01002097 tenant_create_parser = subparsers.add_parser('tenant-create', parents=[parent_parser], help="creates a new tenant")
2098 tenant_create_parser.add_argument("name", action="store", help="name for the tenant")
2099 tenant_create_parser.add_argument("--description", action="store", help="description of the tenant")
2100 tenant_create_parser.set_defaults(func=tenant_create)
2101
2102 tenant_delete_parser = subparsers.add_parser('tenant-delete', parents=[parent_parser], help="deletes a tenant from the catalogue")
2103 tenant_delete_parser.add_argument("name", action="store", help="name or uuid of the tenant to be deleted")
2104 tenant_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2105 tenant_delete_parser.set_defaults(func=tenant_delete)
2106
2107 tenant_list_parser = subparsers.add_parser('tenant-list', parents=[parent_parser], help="lists information about a tenant")
2108 tenant_list_parser.add_argument("name", nargs='?', help="name or uuid of the tenant")
2109 tenant_list_parser.set_defaults(func=tenant_list)
2110
tierno161c24b2017-05-16 15:45:56 +02002111 element_edit_parser = subparsers.add_parser('tenant-edit', parents=[parent_parser], help="edits one tenant")
2112 element_edit_parser.add_argument("name", help="name or uuid of the tenant")
2113 element_edit_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
2114 element_edit_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2115 element_edit_parser.set_defaults(func=element_edit, element='tenants')
tierno7edb6752016-03-21 17:37:52 +01002116
2117 datacenter_create_parser = subparsers.add_parser('datacenter-create', parents=[parent_parser], help="creates a new datacenter")
2118 datacenter_create_parser.add_argument("name", action="store", help="name for the datacenter")
2119 datacenter_create_parser.add_argument("url", action="store", help="url for the datacenter")
2120 datacenter_create_parser.add_argument("--url_admin", action="store", help="url for administration for the datacenter")
2121 datacenter_create_parser.add_argument("--type", action="store", help="datacenter type: openstack or openvim (default)")
2122 datacenter_create_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
2123 datacenter_create_parser.add_argument("--description", action="store", help="description of the datacenter")
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002124 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 +01002125 datacenter_create_parser.set_defaults(func=datacenter_create)
2126
2127 datacenter_delete_parser = subparsers.add_parser('datacenter-delete', parents=[parent_parser], help="deletes a datacenter from the catalogue")
2128 datacenter_delete_parser.add_argument("name", action="store", help="name or uuid of the datacenter to be deleted")
2129 datacenter_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2130 datacenter_delete_parser.set_defaults(func=datacenter_delete)
2131
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002132 datacenter_edit_parser = subparsers.add_parser('datacenter-edit', parents=[parent_parser], help="Edit datacenter")
2133 datacenter_edit_parser.add_argument("name", help="name or uuid of the datacenter")
2134 datacenter_edit_parser.add_argument("--file", help="json/yaml text or file with the changes").completer = FilesCompleter
2135 datacenter_edit_parser.add_argument("--sdn-controller", action="store",
2136 help="Name or uuid of the SDN controller to be used. Specify 'null' to clear entry", dest='sdn_controller')
2137 datacenter_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
2138 datacenter_edit_parser.set_defaults(func=datacenter_edit)
2139
tierno7edb6752016-03-21 17:37:52 +01002140 datacenter_list_parser = subparsers.add_parser('datacenter-list', parents=[parent_parser], help="lists information about a datacenter")
2141 datacenter_list_parser.add_argument("name", nargs='?', help="name or uuid of the datacenter")
2142 datacenter_list_parser.add_argument("-a", "--all", action="store_true", help="shows all datacenters, not only datacenters attached to tenant")
2143 datacenter_list_parser.set_defaults(func=datacenter_list)
2144
2145 datacenter_attach_parser = subparsers.add_parser('datacenter-attach', parents=[parent_parser], help="associates a datacenter to the operating tenant")
2146 datacenter_attach_parser.add_argument("name", help="name or uuid of the datacenter")
2147 datacenter_attach_parser.add_argument('--vim-tenant-id', action='store', help="specify a datacenter tenant to use. A new one is created by default")
2148 datacenter_attach_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
2149 datacenter_attach_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
2150 datacenter_attach_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
tierno8008c3a2016-10-13 15:34:28 +00002151 datacenter_attach_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
tierno7edb6752016-03-21 17:37:52 +01002152 datacenter_attach_parser.set_defaults(func=datacenter_attach)
2153
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002154 datacenter_edit_vim_tenant_parser = subparsers.add_parser('datacenter-edit-vim-tenant', parents=[parent_parser],
2155 help="Edit the association of a datacenter to the operating tenant")
2156 datacenter_edit_vim_tenant_parser.add_argument("name", help="name or uuid of the datacenter")
2157 datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-id', action='store',
2158 help="specify a datacenter tenant to use. A new one is created by default")
2159 datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
2160 datacenter_edit_vim_tenant_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
2161 datacenter_edit_vim_tenant_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
2162 datacenter_edit_vim_tenant_parser.add_argument("--config", action="store",
2163 help="aditional configuration in json/yaml format")
2164 datacenter_edit_vim_tenant_parser.set_defaults(func=datacenter_edit_vim_tenant)
2165
tierno7edb6752016-03-21 17:37:52 +01002166 datacenter_detach_parser = subparsers.add_parser('datacenter-detach', parents=[parent_parser], help="removes the association between a datacenter and the operating tenant")
2167 datacenter_detach_parser.add_argument("name", help="name or uuid of the datacenter")
2168 datacenter_detach_parser.add_argument("-a", "--all", action="store_true", help="removes all associations from this datacenter")
2169 datacenter_detach_parser.set_defaults(func=datacenter_detach)
2170
Pablo Montes Moreno3fbff9b2017-03-08 11:28:15 +01002171 #=======================datacenter_sdn_port_mapping_xxx section=======================
2172 #datacenter_sdn_port_mapping_set
2173 datacenter_sdn_port_mapping_set_parser = subparsers.add_parser('datacenter-sdn-port-mapping-set',
2174 parents=[parent_parser],
2175 help="Load a file with the mapping of physical ports "
2176 "and the ports of the dataplaneswitch controlled "
2177 "by a datacenter")
2178 datacenter_sdn_port_mapping_set_parser.add_argument("name", action="store", help="specifies the datacenter")
2179 datacenter_sdn_port_mapping_set_parser.add_argument("file",
2180 help="json/yaml text or file with the port mapping").completer = FilesCompleter
2181 datacenter_sdn_port_mapping_set_parser.add_argument("-f", "--force", action="store_true",
2182 help="forces overwriting without asking")
2183 datacenter_sdn_port_mapping_set_parser.set_defaults(func=datacenter_sdn_port_mapping_set)
2184
2185 #datacenter_sdn_port_mapping_list
2186 datacenter_sdn_port_mapping_list_parser = subparsers.add_parser('datacenter-sdn-port-mapping-list',
2187 parents=[parent_parser],
2188 help="Show the SDN port mapping in a datacenter")
2189 datacenter_sdn_port_mapping_list_parser.add_argument("name", action="store", help="specifies the datacenter")
2190 datacenter_sdn_port_mapping_list_parser.set_defaults(func=datacenter_sdn_port_mapping_list)
2191
2192 # datacenter_sdn_port_mapping_clear
2193 datacenter_sdn_port_mapping_clear_parser = subparsers.add_parser('datacenter-sdn-port-mapping-clear',
2194 parents=[parent_parser],
2195 help="Clean the the SDN port mapping in a datacenter")
2196 datacenter_sdn_port_mapping_clear_parser.add_argument("name", action="store",
2197 help="specifies the datacenter")
2198 datacenter_sdn_port_mapping_clear_parser.add_argument("-f", "--force", action="store_true",
2199 help="forces clearing without asking")
2200 datacenter_sdn_port_mapping_clear_parser.set_defaults(func=datacenter_sdn_port_mapping_clear)
2201 # =======================
2202
2203 # =======================sdn_controller_xxx section=======================
2204 # sdn_controller_create
2205 sdn_controller_create_parser = subparsers.add_parser('sdn-controller-create', parents=[parent_parser],
2206 help="Creates an SDN controller entity within RO")
2207 sdn_controller_create_parser.add_argument("name", help="name of the SDN controller")
2208 sdn_controller_create_parser.add_argument("--description", action="store", help="description of the SDN controller")
2209 sdn_controller_create_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
2210 sdn_controller_create_parser.add_argument("--port", action="store", help="Port of the SDN controller")
2211 sdn_controller_create_parser.add_argument("--dpid", action="store",
2212 help="DPID of the dataplane switch controlled by this SDN controller")
2213 sdn_controller_create_parser.add_argument("--type", action="store",
2214 help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
2215 sdn_controller_create_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
2216 sdn_controller_create_parser.add_argument("--passwd", action="store", dest='password',
2217 help="password credentials for the SDN controller")
2218 sdn_controller_create_parser.set_defaults(func=sdn_controller_create)
2219
2220 # sdn_controller_edit
2221 sdn_controller_edit_parser = subparsers.add_parser('sdn-controller-edit', parents=[parent_parser],
2222 help="Update one or more options of a SDN controller")
2223 sdn_controller_edit_parser.add_argument("name", help="name or uuid of the SDN controller", )
2224 sdn_controller_edit_parser.add_argument("--name", action="store", help="Update the name of the SDN controller",
2225 dest='new_name')
2226 sdn_controller_edit_parser.add_argument("--description", action="store", help="description of the SDN controller")
2227 sdn_controller_edit_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
2228 sdn_controller_edit_parser.add_argument("--port", action="store", help="Port of the SDN controller")
2229 sdn_controller_edit_parser.add_argument("--dpid", action="store",
2230 help="DPID of the dataplane switch controlled by this SDN controller")
2231 sdn_controller_edit_parser.add_argument("--type", action="store",
2232 help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
2233 sdn_controller_edit_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
2234 sdn_controller_edit_parser.add_argument("--password", action="store",
2235 help="password credentials for the SDN controller", dest='password')
2236 sdn_controller_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
2237 #TODO: include option --file
2238 sdn_controller_edit_parser.set_defaults(func=sdn_controller_edit)
2239
2240 #sdn_controller_list
2241 sdn_controller_list_parser = subparsers.add_parser('sdn-controller-list',
2242 parents=[parent_parser],
2243 help="List the SDN controllers")
2244 sdn_controller_list_parser.add_argument("name", nargs='?', help="name or uuid of the SDN controller")
2245 sdn_controller_list_parser.set_defaults(func=sdn_controller_list)
2246
2247 # sdn_controller_delete
2248 sdn_controller_delete_parser = subparsers.add_parser('sdn-controller-delete',
2249 parents=[parent_parser],
2250 help="Delete the the SDN controller")
2251 sdn_controller_delete_parser.add_argument("name", help="name or uuid of the SDN controller")
2252 sdn_controller_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
2253 sdn_controller_delete_parser.set_defaults(func=sdn_controller_delete)
2254 # =======================
tierno7edb6752016-03-21 17:37:52 +01002255
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002256 # WIM ======================= WIM section==================
2257
2258 # WIM create
2259 wim_create_parser = subparsers.add_parser('wim-create',
2260 parents=[parent_parser], help="creates a new wim")
2261 wim_create_parser.add_argument("name", action="store",
2262 help="name for the wim")
2263 wim_create_parser.add_argument("url", action="store",
2264 help="url for the wim")
2265 wim_create_parser.add_argument("--type", action="store",
tierno667d1582019-12-20 12:16:46 +00002266 help="wim type: ietfl2vpn, dynpac, ...")
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002267 wim_create_parser.add_argument("--config", action="store",
2268 help="additional configuration in json/yaml format")
2269 wim_create_parser.add_argument("--description", action="store",
2270 help="description of the wim")
2271 wim_create_parser.set_defaults(func=wim_create)
2272
2273 # WIM delete
2274 wim_delete_parser = subparsers.add_parser('wim-delete',
2275 parents=[parent_parser], help="deletes a wim from the catalogue")
2276 wim_delete_parser.add_argument("name", action="store",
2277 help="name or uuid of the wim to be deleted")
2278 wim_delete_parser.add_argument("-f", "--force", action="store_true",
2279 help="forces deletion without asking")
2280 wim_delete_parser.set_defaults(func=wim_delete)
2281
2282 # WIM edit
2283 wim_edit_parser = subparsers.add_parser('wim-edit',
2284 parents=[parent_parser], help="edits a wim")
2285 wim_edit_parser.add_argument("name", help="name or uuid of the wim")
2286 wim_edit_parser.add_argument("--file",
2287 help="json/yaml text or file with the changes")\
2288 .completer = FilesCompleter
2289 wim_edit_parser.add_argument("-f", "--force", action="store_true",
2290 help="do not prompt for confirmation")
2291 wim_edit_parser.set_defaults(func=wim_edit)
2292
2293 # WIM list
2294 wim_list_parser = subparsers.add_parser('wim-list',
2295 parents=[parent_parser],
2296 help="lists information about registered wims")
2297 wim_list_parser.add_argument("name", nargs='?',
2298 help="name or uuid of the wim")
2299 wim_list_parser.add_argument("-a", "--all", action="store_true",
2300 help="shows all wims, not only wims attached to tenant")
2301 wim_list_parser.set_defaults(func=wim_list)
2302
2303 # WIM account create
2304 wim_attach_parser = subparsers.add_parser('wim-account-create', parents=
2305 [parent_parser], help="associates a wim account to the operating tenant")
2306 wim_attach_parser.add_argument("name", help="name or uuid of the wim")
2307 wim_attach_parser.add_argument('--account-name', action='store',
2308 help="specify a name for the wim account.")
2309 wim_attach_parser.add_argument("--user", action="store",
2310 help="user credentials for the wim account")
2311 wim_attach_parser.add_argument("--password", action="store",
2312 help="password credentials for the wim account")
2313 wim_attach_parser.add_argument("--config", action="store",
2314 help="additional configuration in json/yaml format")
2315 wim_attach_parser.set_defaults(func=wim_account_create)
2316
2317 # WIM account delete
2318 wim_detach_parser = subparsers.add_parser('wim-account-delete',
2319 parents=[parent_parser],
2320 help="removes the association "
2321 "between a wim account and the operating tenant")
2322 wim_detach_parser.add_argument("name", help="name or uuid of the wim")
2323 wim_detach_parser.add_argument("-a", "--all", action="store_true",
2324 help="removes all associations from this wim")
2325 wim_detach_parser.add_argument("-f", "--force", action="store_true",
2326 help="forces delete without asking")
2327 wim_detach_parser.set_defaults(func=wim_account_delete)
2328
2329 # WIM account edit
2330 wim_attach_edit_parser = subparsers.add_parser('wim-account-edit', parents=
2331 [parent_parser], help="modifies the association of a wim account to the operating tenant")
2332 wim_attach_edit_parser.add_argument("name", help="name or uuid of the wim")
2333 wim_attach_edit_parser.add_argument('--account-name', action='store',
2334 help="specify a name for the wim account.")
2335 wim_attach_edit_parser.add_argument("--user", action="store",
2336 help="user credentials for the wim account")
2337 wim_attach_edit_parser.add_argument("--password", action="store",
2338 help="password credentials for the wim account")
2339 wim_attach_edit_parser.add_argument("--config", action="store",
2340 help="additional configuration in json/yaml format")
2341 wim_attach_edit_parser.set_defaults(func=wim_account_edit)
2342
2343 # WIM port mapping set
2344 wim_port_mapping_set_parser = subparsers.add_parser('wim-port-mapping-set',
2345 parents=[parent_parser],
2346 help="Load a file with the mappings "
2347 "of ports of a WAN switch that is "
2348 "connected to a PoP and the ports "
2349 "of the switch controlled by the PoP")
2350 wim_port_mapping_set_parser.add_argument("name", action="store",
2351 help="specifies the wim")
2352 wim_port_mapping_set_parser.add_argument("file",
2353 help="json/yaml text or file with the wim port mapping")\
2354 .completer = FilesCompleter
2355 wim_port_mapping_set_parser.add_argument("-f", "--force",
2356 action="store_true", help="forces overwriting without asking")
2357 wim_port_mapping_set_parser.set_defaults(func=wim_port_mapping_set)
2358
2359 # WIM port mapping list
2360 wim_port_mapping_list_parser = subparsers.add_parser('wim-port-mapping-list',
2361 parents=[parent_parser], help="Show the port mappings for a wim")
2362 wim_port_mapping_list_parser.add_argument("name", action="store",
2363 help="specifies the wim")
2364 wim_port_mapping_list_parser.set_defaults(func=wim_port_mapping_list)
2365
2366 # WIM port mapping clear
2367 wim_port_mapping_clear_parser = subparsers.add_parser('wim-port-mapping-clear',
2368 parents=[parent_parser], help="Clean the port mapping in a wim")
2369 wim_port_mapping_clear_parser.add_argument("name", action="store",
2370 help="specifies the wim")
2371 wim_port_mapping_clear_parser.add_argument("-f", "--force",
2372 action="store_true",
2373 help="forces clearing without asking")
2374 wim_port_mapping_clear_parser.set_defaults(func=wim_port_mapping_clear)
2375
2376 # =======================================================
2377
tierno7edb6752016-03-21 17:37:52 +01002378 action_dict={'net-update': 'retrieves external networks from datacenter',
2379 'net-edit': 'edits an external network',
2380 'net-delete': 'deletes an external network',
2381 'net-list': 'lists external networks from a datacenter'
2382 }
2383 for item in action_dict:
2384 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
2385 datacenter_action_parser.add_argument("datacenter", help="name or uuid of the datacenter")
2386 if item=='net-edit' or item=='net-delete':
2387 datacenter_action_parser.add_argument("net", help="name or uuid of the datacenter net")
2388 if item=='net-edit':
2389 datacenter_action_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
2390 if item!='net-list':
2391 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2392 datacenter_action_parser.set_defaults(func=datacenter_net_action, action=item)
2393
2394
tierno5acf7202016-08-29 14:28:13 +02002395 action_dict={'netmap-import': 'create network senario netmap base on the datacenter networks',
tierno7edb6752016-03-21 17:37:52 +01002396 'netmap-create': 'create a new network senario netmap',
2397 'netmap-edit': 'edit name of a network senario netmap',
2398 'netmap-delete': 'deletes a network scenario netmap (--all for clearing all)',
2399 'netmap-list': 'list/show network scenario netmaps'
2400 }
2401 for item in action_dict:
2402 datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
2403 datacenter_action_parser.add_argument("--datacenter", help="name or uuid of the datacenter")
2404 #if item=='net-add':
2405 # datacenter_action_parser.add_argument("net", help="name of the network")
2406 if item=='netmap-delete':
2407 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to delete")
2408 datacenter_action_parser.add_argument("--all", action="store_true", help="delete all netmap of this datacenter")
2409 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2410 if item=='netmap-edit':
2411 datacenter_action_parser.add_argument("netmap", help="name or uuid of the datacenter netmap do edit")
2412 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file with the changes").completer = FilesCompleter
2413 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap")
2414 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
2415 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2416 if item=='netmap-list':
2417 datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to show")
2418 if item=='netmap-create':
2419 datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file descriptor with the changes").completer = FilesCompleter
2420 datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap, by default same as vim-name")
2421 datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
2422 datacenter_action_parser.add_argument('--vim-name', action='store', help="specify vim network name")
tierno5acf7202016-08-29 14:28:13 +02002423 if item=='netmap-import':
tierno7edb6752016-03-21 17:37:52 +01002424 datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
2425 datacenter_action_parser.set_defaults(func=datacenter_netmap_action, action=item)
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002426
2427 # =======================vim_net_sdn_xxx section=======================
2428 # vim_net_sdn_attach
2429 vim_net_sdn_attach_parser = subparsers.add_parser('vim-net-sdn-attach',
2430 parents=[parent_parser],
2431 help="Specify the port to access to an external network using SDN")
2432 vim_net_sdn_attach_parser.add_argument("vim_net", action="store",
2433 help="Name/id of the network in the vim that will be used to connect to the external network")
2434 vim_net_sdn_attach_parser.add_argument("port", action="store", help="Specifies the port in the dataplane switch to access to the external network")
2435 vim_net_sdn_attach_parser.add_argument("--vlan", action="store", help="Specifies the vlan (if any) to use in the defined port")
2436 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")
2437 vim_net_sdn_attach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2438 vim_net_sdn_attach_parser.set_defaults(func=vim_net_sdn_attach)
2439
2440 # vim_net_sdn_detach
2441 vim_net_sdn_detach_parser = subparsers.add_parser('vim-net-sdn-detach',
2442 parents=[parent_parser],
2443 help="Remove the port information to access to an external network using SDN")
2444
2445 vim_net_sdn_detach_parser.add_argument("vim_net", action="store", help="Name/id of the vim network")
2446 vim_net_sdn_detach_parser.add_argument("--id", action="store",help="Specify the uuid of the external ports from this network to be detached")
2447 vim_net_sdn_detach_parser.add_argument("--all", action="store_true", help="Detach all external ports from this network")
2448 vim_net_sdn_detach_parser.add_argument("-f", "--force", action="store_true", help="forces clearing without asking")
2449 vim_net_sdn_detach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2450 vim_net_sdn_detach_parser.set_defaults(func=vim_net_sdn_detach)
2451 # =======================
2452
tierno4540ea52017-01-18 17:44:32 +01002453 for item in ("network", "tenant", "image"):
tierno7edb6752016-03-21 17:37:52 +01002454 if item=="network":
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002455 command_name = 'vim-net'
tierno7edb6752016-03-21 17:37:52 +01002456 else:
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002457 command_name = 'vim-'+item
2458 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 +01002459 vim_item_list_parser.add_argument("name", nargs='?', help="name or uuid of the " + item + "s")
2460 vim_item_list_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2461 vim_item_list_parser.set_defaults(func=vim_action, item=item, action="list")
2462
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002463 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 +01002464 vim_item_del_parser.add_argument("name", help="name or uuid of the " + item + "s")
2465 vim_item_del_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2466 vim_item_del_parser.set_defaults(func=vim_action, item=item, action="delete")
2467
tierno4540ea52017-01-18 17:44:32 +01002468 if item == "network" or item == "tenant":
Pablo Montes Moreno6aa0b2b2017-05-23 18:33:12 +02002469 vim_item_create_parser = subparsers.add_parser(command_name + '-create', parents=[parent_parser], help="create a "+item+" at vim")
tierno7d782ef2019-10-04 12:56:31 +00002470 vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the {}. Must be a file or yaml/json text".format(item)).completer = FilesCompleter
2471 vim_item_create_parser.add_argument("--name", action="store", help="name of the {}".format(item))
tierno4540ea52017-01-18 17:44:32 +01002472 vim_item_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
2473 if item=="network":
2474 vim_item_create_parser.add_argument("--type", action="store", help="type of network, data, ptp, bridge")
2475 vim_item_create_parser.add_argument("--shared", action="store_true", help="Private or shared")
2476 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>'")
2477 else:
tierno7d782ef2019-10-04 12:56:31 +00002478 vim_item_create_parser.add_argument("--description", action="store", help="description of the {}".format(item))
tierno4540ea52017-01-18 17:44:32 +01002479 vim_item_create_parser.set_defaults(func=vim_action, item=item, action="create")
tierno7edb6752016-03-21 17:37:52 +01002480
2481 argcomplete.autocomplete(main_parser)
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002482
tierno7edb6752016-03-21 17:37:52 +01002483 try:
2484 args = main_parser.parse_args()
2485 #logging info
2486 level = logging.CRITICAL
2487 streamformat = "%(asctime)s %(name)s %(levelname)s: %(message)s"
2488 if "debug" in args and args.debug:
2489 level = logging.DEBUG
2490 logging.basicConfig(format=streamformat, level= level)
2491 logger = logging.getLogger('mano')
2492 logger.setLevel(level)
tierno7d782ef2019-10-04 12:56:31 +00002493 # print("#TODO py3", args)
tierno7edb6752016-03-21 17:37:52 +01002494 result = args.func(args)
2495 if result == None:
2496 result = 0
2497 #for some reason it fails if call exit inside try instance. Need to call exit at the end !?
2498 except (requests.exceptions.ConnectionError):
tierno7d782ef2019-10-04 12:56:31 +00002499 print("Connection error: not possible to contact OPENMANO-SERVER (openmanod)")
tierno7edb6752016-03-21 17:37:52 +01002500 result = -2
2501 except (KeyboardInterrupt):
tierno7d782ef2019-10-04 12:56:31 +00002502 print('Exiting openmano')
tierno7edb6752016-03-21 17:37:52 +01002503 result = -3
2504 except (SystemExit, ArgumentParserError):
2505 result = -4
tierno7d782ef2019-10-04 12:56:31 +00002506 except (AttributeError):
2507 print("Type '--help' for more information")
2508 result = -4
tierno7edb6752016-03-21 17:37:52 +01002509 except OpenmanoCLIError as e:
tierno7d782ef2019-10-04 12:56:31 +00002510 # print("#TODO py3", e)
2511 print(e)
tierno7edb6752016-03-21 17:37:52 +01002512 result = -5
Anderson Bravalheri0446cd52018-08-17 15:26:19 +01002513
tierno7d782ef2019-10-04 12:56:31 +00002514 # print(result)
tierno7edb6752016-03-21 17:37:52 +01002515 exit(result)
2516
tierno7d782ef2019-10-04 12:56:31 +00002517
2518if __name__ == '__main__':
2519 main()
2520