bd72d42156d83e0c2e78ae4b396558eed942752a
1 # Copyright 2018 Telefonica
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
21 from osmclient
.common
import utils
22 from osmclient
.common
.exceptions
import ClientException
23 from osmclient
.common
.exceptions
import NotFound
30 def __init__(self
, http
=None, client
=None):
33 self
._apiName
= '/nslcm'
34 self
._apiVersion
= '/v1'
35 self
._apiResource
= '/ns_instances_content'
36 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
37 self
._apiVersion
, self
._apiResource
)
39 def list(self
, filter=None):
40 """Returns a list of NS
44 filter_string
= '?{}'.format(filter)
45 resp
= self
._http
.get_cmd('{}{}'.format(self
._apiBase
,filter_string
))
51 """Returns an NS based on name or id
53 if utils
.validate_uuid4(name
):
54 for ns
in self
.list():
58 for ns
in self
.list():
59 if name
== ns
['name']:
61 raise NotFound("ns {} not found".format(name
))
63 def get_individual(self
, name
):
65 if not utils
.validate_uuid4(name
):
66 for ns
in self
.list():
67 if name
== ns
['name']:
70 resp
= self
._http
.get_cmd('{}/{}'.format(self
._apiBase
, ns_id
))
71 #resp = self._http.get_cmd('{}/{}/nsd_content'.format(self._apiBase, ns_id))
72 #print yaml.safe_dump(resp)
75 raise NotFound("ns {} not found".format(name
))
77 def delete(self
, name
, force
=False):
81 querystring
= '?FORCE=True'
82 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
83 ns
['_id'], querystring
))
84 #print 'HTTP CODE: {}'.format(http_code)
85 #print 'RESP: {}'.format(resp)
87 print('Deletion in progress')
88 elif http_code
== 204:
94 msg
= json
.loads(resp
)
97 raise ClientException("failed to delete ns {} - {}".format(name
, msg
))
99 def create(self
, nsd_name
, nsr_name
, account
, config
=None,
100 ssh_keys
=None, description
='default description',
101 admin_status
='ENABLED'):
103 nsd
= self
._client
.nsd
.get(nsd_name
)
107 def get_vim_account_id(vim_account
):
108 if vim_account_id
.get(vim_account
):
109 return vim_account_id
[vim_account
]
111 vim
= self
._client
.vim
.get(vim_account
)
113 raise NotFound("cannot find vim account '{}'".format(vim_account
))
114 vim_account_id
[vim_account
] = vim
['_id']
118 ns
['nsdId'] = nsd
['_id']
119 ns
['nsName'] = nsr_name
120 ns
['nsDescription'] = description
121 ns
['vimAccountId'] = get_vim_account_id(account
)
123 #ns['userdata']['key1']='value1'
124 #ns['userdata']['key2']='value2'
126 if ssh_keys
is not None:
128 for pubkeyfile
in ssh_keys
.split(','):
129 with
open(pubkeyfile
, 'r') as f
:
130 ns
['ssh_keys'].append(f
.read())
132 ns_config
= yaml
.load(config
)
133 if "vim-network-name" in ns_config
:
134 ns_config
["vld"] = ns_config
.pop("vim-network-name")
135 if "vld" in ns_config
:
136 for vld
in ns_config
["vld"]:
137 if vld
.get("vim-network-name"):
138 if isinstance(vld
["vim-network-name"], dict):
139 vim_network_name_dict
= {}
140 for vim_account
, vim_net
in list(vld
["vim-network-name"].items()):
141 vim_network_name_dict
[get_vim_account_id(vim_account
)] = vim_net
142 vld
["vim-network-name"] = vim_network_name_dict
143 ns
["vld"] = ns_config
["vld"]
144 if "vnf" in ns_config
:
145 for vnf
in ns_config
["vnf"]:
146 if vnf
.get("vim_account"):
147 vnf
["vimAccountId"] = get_vim_account_id(vnf
.pop("vim_account"))
148 ns
["vnf"] = ns_config
["vnf"]
150 if "additionalParamsForNs" in ns_config
:
151 ns
["additionalParamsForNs"] = ns_config
.pop("additionalParamsForNs")
152 if not isinstance(ns
["additionalParamsForNs"], dict):
153 raise ValueError("Error at --config 'additionalParamsForNs' must be a dictionary")
154 if "additionalParamsForVnf" in ns_config
:
155 ns
["additionalParamsForVnf"] = ns_config
.pop("additionalParamsForVnf")
156 if not isinstance(ns
["additionalParamsForVnf"], list):
157 raise ValueError("Error at --config 'additionalParamsForVnf' must be a list")
158 for additional_param_vnf
in ns
["additionalParamsForVnf"]:
159 if not isinstance(additional_param_vnf
, dict):
160 raise ValueError("Error at --config 'additionalParamsForVnf' items must be dictionaries")
161 if not additional_param_vnf
.get("member-vnf-index"):
162 raise ValueError("Error at --config 'additionalParamsForVnf' items must contain "
163 "'member-vnf-index'")
164 if not additional_param_vnf
.get("additionalParams"):
165 raise ValueError("Error at --config 'additionalParamsForVnf' items must contain "
166 "'additionalParams'")
168 # print yaml.safe_dump(ns)
170 self
._apiResource
= '/ns_instances_content'
171 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
172 self
._apiVersion
, self
._apiResource
)
173 headers
= self
._client
._headers
174 headers
['Content-Type'] = 'application/yaml'
175 http_header
= ['{}: {}'.format(key
,val
)
176 for (key
,val
) in list(headers
.items())]
177 self
._http
.set_http_header(http_header
)
178 http_code
, resp
= self
._http
.post_cmd(endpoint
=self
._apiBase
,
180 #print 'HTTP CODE: {}'.format(http_code)
181 #print 'RESP: {}'.format(resp)
182 if http_code
in (200, 201, 202, 204):
184 resp
= json
.loads(resp
)
185 if not resp
or 'id' not in resp
:
186 raise ClientException('unexpected response from server - {} '.format(
193 msg
= json
.loads(resp
)
196 raise ClientException(msg
)
197 except ClientException
as exc
:
198 message
="failed to create ns: {} nsd: {}\nerror:\n{}".format(
202 raise ClientException(message
)
204 def list_op(self
, name
, filter=None):
205 """Returns the list of operations of a NS
209 self
._apiResource
= '/ns_lcm_op_occs'
210 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
211 self
._apiVersion
, self
._apiResource
)
214 filter_string
= '&{}'.format(filter)
215 http_code
, resp
= self
._http
.get2_cmd('{}?nsInstanceId={}'.format(
216 self
._apiBase
, ns
['_id'],
218 #print 'HTTP CODE: {}'.format(http_code)
219 #print 'RESP: {}'.format(resp)
222 resp
= json
.loads(resp
)
225 raise ClientException('unexpected response from server')
230 resp
= json
.loads(resp
)
234 raise ClientException(msg
)
235 except ClientException
as exc
:
236 message
="failed to get operation list of NS {}:\nerror:\n{}".format(
239 raise ClientException(message
)
241 def get_op(self
, operationId
):
242 """Returns the status of an operation
245 self
._apiResource
= '/ns_lcm_op_occs'
246 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
247 self
._apiVersion
, self
._apiResource
)
248 http_code
, resp
= self
._http
.get2_cmd('{}/{}'.format(self
._apiBase
, operationId
))
249 #print 'HTTP CODE: {}'.format(http_code)
250 #print 'RESP: {}'.format(resp)
253 resp
= json
.loads(resp
)
256 raise ClientException('unexpected response from server')
261 resp
= json
.loads(resp
)
265 raise ClientException(msg
)
266 except ClientException
as exc
:
267 message
="failed to get status of operation {}:\nerror:\n{}".format(
270 raise ClientException(message
)
272 def exec_op(self
, name
, op_name
, op_data
=None):
273 """Executes an operation on a NS
277 self
._apiResource
= '/ns_instances'
278 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
279 self
._apiVersion
, self
._apiResource
)
280 endpoint
= '{}/{}/{}'.format(self
._apiBase
, ns
['_id'], op_name
)
281 #print 'OP_NAME: {}'.format(op_name)
282 #print 'OP_DATA: {}'.format(json.dumps(op_data))
283 http_code
, resp
= self
._http
.post_cmd(endpoint
=endpoint
, postfields_dict
=op_data
)
284 #print 'HTTP CODE: {}'.format(http_code)
285 #print 'RESP: {}'.format(resp)
286 if http_code
in (200, 201, 202, 204):
288 resp
= json
.loads(resp
)
289 if not resp
or 'id' not in resp
:
290 raise ClientException('unexpected response from server - {}'.format(
297 msg
= json
.loads(resp
)
300 raise ClientException(msg
)
301 except ClientException
as exc
:
302 message
="failed to exec operation {}:\nerror:\n{}".format(
305 raise ClientException(message
)
307 def scale_vnf(self
, ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
):
308 """Scales a VNF by adding/removing VDUs
312 op_data
["scaleType"] = "SCALE_VNF"
313 op_data
["scaleVnfData"] = {}
315 op_data
["scaleVnfData"]["scaleVnfType"] = "SCALE_IN"
317 op_data
["scaleVnfData"]["scaleVnfType"] = "SCALE_OUT"
318 op_data
["scaleVnfData"]["scaleByStepData"] = {
319 "member-vnf-index": vnf_name
,
320 "scaling-group-descriptor": scaling_group
,
322 self
.exec_op(ns_name
, op_name
='scale', op_data
=op_data
)
323 except ClientException
as exc
:
324 message
="failed to scale vnf {} of ns {}:\nerror:\n{}".format(
325 vnf_name
, ns_name
, exc
.message
)
326 raise ClientException(message
)
328 def create_alarm(self
, alarm
):
330 data
["create_alarm_request"] = {}
331 data
["create_alarm_request"]["alarm_create_request"] = alarm
333 http_code
, resp
= self
._http
.post_cmd(endpoint
='/test/message/alarm_request',
334 postfields_dict
=data
)
335 #print 'HTTP CODE: {}'.format(http_code)
336 #print 'RESP: {}'.format(resp)
337 if http_code
in (200, 201, 202, 204):
338 #resp = json.loads(resp)
339 print('Alarm created')
344 msg
= json
.loads(resp
)
347 raise ClientException('error: code: {}, resp: {}'.format(
349 except ClientException
as exc
:
350 message
="failed to create alarm: alarm {}\n{}".format(
353 raise ClientException(message
)
355 def delete_alarm(self
, name
):
357 data
["delete_alarm_request"] = {}
358 data
["delete_alarm_request"]["alarm_delete_request"] = {}
359 data
["delete_alarm_request"]["alarm_delete_request"]["alarm_uuid"] = name
361 http_code
, resp
= self
._http
.post_cmd(endpoint
='/test/message/alarm_request',
362 postfields_dict
=data
)
363 #print 'HTTP CODE: {}'.format(http_code)
364 #print 'RESP: {}'.format(resp)
365 if http_code
in (200, 201, 202, 204):
366 #resp = json.loads(resp)
367 print('Alarm deleted')
372 msg
= json
.loads(resp
)
375 raise ClientException('error: code: {}, resp: {}'.format(
377 except ClientException
as exc
:
378 message
="failed to delete alarm: alarm {}\n{}".format(
381 raise ClientException(message
)
383 def export_metric(self
, metric
):
385 data
["read_metric_data_request"] = metric
387 http_code
, resp
= self
._http
.post_cmd(endpoint
='/test/message/metric_request',
388 postfields_dict
=data
)
389 #print 'HTTP CODE: {}'.format(http_code)
390 #print 'RESP: {}'.format(resp)
391 if http_code
in (200, 201, 202, 204):
392 #resp = json.loads(resp)
393 return 'Metric exported'
398 msg
= json
.loads(resp
)
401 raise ClientException('error: code: {}, resp: {}'.format(
403 except ClientException
as exc
:
404 message
="failed to export metric: metric {}\n{}".format(
407 raise ClientException(message
)
409 def get_field(self
, ns_name
, field
):
410 nsr
= self
.get(ns_name
)
412 raise NotFound("failed to retrieve ns {}".format(ns_name
))
417 raise NotFound("failed to find {} in ns {}".format(field
, ns_name
))