Add PaaS service creation UTs
[osm/osmclient.git] / osmclient / sol005 / ns.py
1 # Copyright 2018 Telefonica
2 #
3 # All Rights Reserved.
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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
15 # under the License.
16
17 """
18 OSM ns API handling
19 """
20
21 from osmclient.common import utils
22 from osmclient.common import wait as WaitForStatus
23 from osmclient.common.exceptions import ClientException
24 from osmclient.common.exceptions import NotFound
25 import yaml
26 import json
27 import logging
28
29
30 class Ns(object):
31 def __init__(self, http=None, client=None):
32 self._http = http
33 self._client = client
34 self._logger = logging.getLogger("osmclient")
35 self._apiName = "/nslcm"
36 self._apiVersion = "/v1"
37 self._apiResource = "/ns_instances_content"
38 self._apiBase = "{}{}{}".format(
39 self._apiName, self._apiVersion, self._apiResource
40 )
41
42 # NS '--wait' option
43 def _wait(self, op_id, wait_time, delete_flag=False):
44 self._logger.debug("")
45 # Endpoint to get operation status
46 apiUrlStatus = "{}{}{}".format(
47 self._apiName, self._apiVersion, "/ns_lcm_op_occs"
48 )
49 # Wait for status for NS instance creation/update/deletion
50 if isinstance(wait_time, bool):
51 wait_time = WaitForStatus.TIMEOUT_NS_OPERATION
52 WaitForStatus.wait_for_status(
53 "NS",
54 str(op_id),
55 wait_time,
56 apiUrlStatus,
57 self._http.get2_cmd,
58 deleteFlag=delete_flag,
59 )
60
61 def list(self, filter=None):
62 """Returns a list of NS"""
63 self._logger.debug("")
64 self._client.get_token()
65 filter_string = ""
66 if filter:
67 filter_string = "?{}".format(filter)
68 _, resp = self._http.get2_cmd("{}{}".format(self._apiBase, filter_string))
69 if resp:
70 return json.loads(resp)
71 return list()
72
73 def get(self, name):
74 """Returns an NS based on name or id"""
75 self._logger.debug("")
76 self._client.get_token()
77 if utils.validate_uuid4(name):
78 for ns in self.list():
79 if name == ns["_id"]:
80 return ns
81 else:
82 for ns in self.list():
83 if name == ns["name"]:
84 return ns
85 raise NotFound("ns '{}' not found".format(name))
86
87 def get_individual(self, name):
88 self._logger.debug("")
89 self._client.get_token()
90 ns_id = name
91 if not utils.validate_uuid4(name):
92 for ns in self.list():
93 if name == ns["name"]:
94 ns_id = ns["_id"]
95 break
96 try:
97 _, resp = self._http.get2_cmd("{}/{}".format(self._apiBase, ns_id))
98 # resp = self._http.get_cmd('{}/{}/nsd_content'.format(self._apiBase, ns_id))
99 # print(yaml.safe_dump(resp))
100 if resp:
101 return json.loads(resp)
102 except NotFound:
103 raise NotFound("ns '{}' not found".format(name))
104 raise NotFound("ns '{}' not found".format(name))
105
106 def delete(self, name, force=False, config=None, wait=False):
107 """
108 Deletes a Network Service (NS)
109 :param name: name of network service
110 :param force: set force. Direct deletion without cleaning at VIM
111 :param config: parameters of deletion, as:
112 autoremove: Bool (default True)
113 timeout_ns_terminate: int
114 skip_terminate_primitives: Bool (default False) to not exec termination primitives
115 :param wait: Make synchronous. Wait until deletion is completed:
116 False to not wait (by default), True to wait a standard time, or int (time to wait)
117 :return: None. Exception if fail
118 """
119 self._logger.debug("")
120 ns = self.get(name)
121 querystring_list = []
122 querystring = ""
123 if config:
124 ns_config = yaml.safe_load(config)
125 querystring_list += ["{}={}".format(k, v) for k, v in ns_config.items()]
126 if force:
127 querystring_list.append("FORCE=True")
128 if querystring_list:
129 querystring = "?" + "&".join(querystring_list)
130 http_code, resp = self._http.delete_cmd(
131 "{}/{}{}".format(self._apiBase, ns["_id"], querystring)
132 )
133 # TODO change to use a POST self._http.post_cmd('{}/{}/terminate{}'.format(_apiBase, ns['_id'], querystring),
134 # postfields_dict=ns_config)
135 # seting autoremove as True by default
136 # print('HTTP CODE: {}'.format(http_code))
137 # print('RESP: {}'.format(resp))
138 if http_code == 202:
139 if wait and resp:
140 resp = json.loads(resp)
141 # For the 'delete' operation, '_id' is used
142 self._wait(resp.get("_id"), wait, delete_flag=True)
143 else:
144 print("Deletion in progress")
145 elif http_code == 204:
146 print("Deleted")
147 else:
148 msg = resp or ""
149 raise ClientException("failed to delete ns {} - {}".format(name, msg))
150
151 def _get_vim_account_id(self, vim_account: str, vim_account_dict: dict) -> str:
152 """Get VIM account ID.
153 Args:
154 vim_account (str): VIM account id as string
155 vim_account_dict (dict): A dictionary which includes vim account id
156
157 Returns:
158 vim_id (str): VIM account id as string
159
160 Raises:
161 NotFound Exception
162 """
163 self._logger.debug("")
164 if vim_account_dict.get(vim_account):
165 return vim_account_dict[vim_account]
166 vim = self._client.vim.get(vim_account)
167 if vim is None:
168 raise NotFound("cannot find vim account '{}'".format(vim_account))
169 vim_account_dict[vim_account] = vim["_id"]
170 return vim["_id"]
171
172 def _get_wim_account_id(self, wim_account: str, wim_account_dict: dict) -> str:
173 """Get WIM account ID.
174 Args:
175 wim_account (str): WIM account id as string
176 wim_account_dict (dict): A dictionary which includes wim account id
177
178 Returns:
179 wim_id (str): WIM account id as string
180
181 Raises:
182 NotFound Exception
183 """
184 self._logger.debug("")
185 # wim_account can be False (boolean) to indicate not use wim account
186 if not isinstance(wim_account, str):
187 return wim_account
188 if wim_account_dict.get(wim_account):
189 return wim_account_dict[wim_account]
190 wim = self._client.wim.get(wim_account)
191 if wim is None:
192 raise NotFound("cannot find wim account '{}'".format(wim_account))
193 wim_account_dict[wim_account] = wim["_id"]
194 return wim["_id"]
195
196 def _get_paas_account_id(self, paas_account: str) -> str:
197 """Get PaaS account ID.
198 Args:
199 paas_account (str): PaaS account id as string
200
201 Returns:
202 paas_id (str): PaaS account id as string
203
204 Raises:
205 NotFound Exception
206 """
207 self._logger.debug("")
208 paas = self._client.paas.get(paas_account)
209 if paas is None:
210 raise NotFound("cannot find PaaS account '{}'".format(paas_account))
211 return paas["_id"]
212
213 def _update_vnf_in_ns_config(self, ns_config: dict, vim_account_dict: dict) -> dict:
214 """Update vnf field in ns_config.
215 Args:
216 ns_config (dict): NS config dictionary which includes additional params
217 vim_account_dict (dict): A dictionary which includes vim account id
218
219 Returns:
220 ns (dict): NS dictionary
221 """
222 if "vnf" in ns_config:
223 for vnf in ns_config["vnf"]:
224 if vnf.get("vim_account"):
225 vnf["vimAccountId"] = self._get_vim_account_id(
226 vnf.pop("vim_account"), vim_account_dict
227 )
228 return ns_config
229
230 def _update_wim_account_in_ns(
231 self, ns_config: dict, wim_account_dict: dict, ns: dict
232 ) -> dict:
233 """Update WIM_account in NS dictionary.
234 Args:
235 ns_config (dict): NS config dictionary which includes additional params
236 wim_account_dict (dict): A dictionary which includes wim account id
237 ns (dict): NS dictionary which includes ns_id, ns_name, description etc.
238
239 Returns:
240 ns (dict): NS dictionary
241 """
242 if "wim_account" in ns_config:
243 wim_account = ns_config.pop("wim_account")
244 if wim_account is not None:
245 ns["wimAccountId"] = self._get_wim_account_id(
246 wim_account, wim_account_dict
247 )
248 return ns
249
250 def _update_vld_in_ns_config(
251 self, ns_config: dict, vim_account_dict: dict, wim_account_dict: dict
252 ) -> dict:
253 """Validating the additionalParamsForNs and additionalParamsForVnf in ns_config.
254
255 Args:
256 ns_config (dict): NS config dictionary which includes additional params
257 vim_account_dict (dict): A dictionary which includes vim account id
258 wim_account_dict (dict): A dictionary which includes wim account id
259
260 Returns:
261 ns_config (dict): NS config dictionary which includes additional params
262
263 Raises:
264 ClientException
265 """
266 if "vld" in ns_config:
267 if not isinstance(ns_config["vld"], list):
268 raise ClientException(
269 "Error at --config 'vld' must be a list of dictionaries"
270 )
271 for vld in ns_config["vld"]:
272 if not isinstance(vld, dict):
273 raise ClientException(
274 "Error at --config 'vld' must be a list of dictionaries"
275 )
276 if vld.get("vim-network-name"):
277 if isinstance(vld["vim-network-name"], dict):
278 vim_network_name_dict = {}
279 for vim_account, vim_net in vld["vim-network-name"].items():
280 vim_network_name_dict[
281 self._get_vim_account_id(vim_account, vim_account_dict)
282 ] = vim_net
283 vld["vim-network-name"] = vim_network_name_dict
284 if "wim_account" in vld and vld["wim_account"] is not None:
285 vld["wimAccountId"] = self._get_wim_account_id(
286 vld.pop("wim_account"), wim_account_dict
287 )
288 return ns_config
289
290 def _validate_additional_params_in_ns_config(self, ns_config: dict) -> None:
291 """Validating the additionalParamsForNs and additionalParamsForVnf in ns_config.
292 Args:
293 ns_config (dict): NS config dictionary which includes additional params
294
295 Raises:
296 ClientException
297 """
298 if "additionalParamsForNs" in ns_config:
299 if not isinstance(ns_config["additionalParamsForNs"], dict):
300 raise ClientException(
301 "Error at --config 'additionalParamsForNs' must be a dictionary"
302 )
303 if "additionalParamsForVnf" in ns_config:
304 if not isinstance(ns_config["additionalParamsForVnf"], list):
305 raise ClientException(
306 "Error at --config 'additionalParamsForVnf' must be a list"
307 )
308 for additional_param_vnf in ns_config["additionalParamsForVnf"]:
309 if not isinstance(additional_param_vnf, dict):
310 raise ClientException(
311 "Error at --config 'additionalParamsForVnf' items must be dictionaries"
312 )
313 if not additional_param_vnf.get("member-vnf-index"):
314 raise ClientException(
315 "Error at --config 'additionalParamsForVnf' items must contain "
316 "'member-vnf-index'"
317 )
318
319 def process_ns_create_with_vim_account(
320 self,
321 vim_account: str,
322 nsd: dict,
323 nsr_name: str,
324 description: str,
325 config: dict = None,
326 ssh_keys: str = None,
327 timeout: int = None,
328 ) -> dict:
329 """Process NS create request which includes VIM Account.
330 Args:
331 vim_account (str): VIM Account id as string
332 nsd (dict): A dictionary which includes network service description
333 nsr_name (str): Network service record name
334 description (str): Service description
335 config (dict): Placeholder for additional configuration
336 ssh_keys (str): ssh-key file
337 timeout (int): Max time to wait (seconds)
338
339 Returns:
340 ns (dict): Payload for ns create request
341
342 Raises:
343 ClientException
344 """
345 vim_account_dict = {}
346 wim_account_dict = {}
347 vim_id = self._get_vim_account_id(vim_account, vim_account_dict)
348 ns = {
349 "nsdId": nsd["_id"],
350 "nsName": nsr_name,
351 "nsDescription": description,
352 "vimAccountId": vim_id,
353 }
354
355 if ssh_keys is not None:
356 ns["ssh_keys"] = []
357 for pubkeyfile in ssh_keys.split(","):
358 with open(pubkeyfile, "r") as f:
359 ns["ssh_keys"].append(f.read())
360
361 if timeout:
362 ns["timeout_ns_deploy"] = timeout
363
364 if config:
365 ns_config = yaml.safe_load(config)
366 if "vim-network-name" in ns_config:
367 ns_config["vld"] = ns_config.pop("vim-network-name")
368
369 ns_config = self._update_vld_in_ns_config(
370 ns_config, vim_account_dict, wim_account_dict
371 )
372 ns_config = self._update_vnf_in_ns_config(ns_config, vim_account_dict)
373 self._validate_additional_params_in_ns_config(ns_config)
374 ns = self._update_wim_account_in_ns(ns_config, vim_account_dict, ns)
375 ns.update(ns_config)
376
377 return ns
378
379 def process_ns_create_with_paas_account(
380 self,
381 paas_account: str,
382 nsd: dict,
383 nsr_name: str,
384 description: str,
385 config: dict = None,
386 timeout: int = None,
387 ) -> dict:
388 """Process NS create request which includes PaaS Account.
389 Args:
390 paas_account (str): PaaS Account id as string
391 nsd (dict): A dictionary which includes network service description
392 nsr_name (str): Network service record name
393 description (str): Service description
394 config (dict): Placeholder for additional configuration
395 timeout (int): Max time to wait (seconds)
396
397 Returns:
398 ns (dict): Payload for ns create request
399
400 Raises:
401 ClientException
402 """
403 paas_id = self._get_paas_account_id(paas_account)
404 ns = {
405 "nsdId": nsd["_id"],
406 "nsName": nsr_name,
407 "nsDescription": description,
408 "paasAccountId": paas_id,
409 }
410
411 if timeout:
412 ns["timeout_ns_deploy"] = timeout
413
414 if config:
415 ns_config = yaml.safe_load(config)
416 self._validate_additional_params_in_ns_config(ns_config)
417 ns.update(ns_config)
418
419 return ns
420
421 def create(
422 self,
423 nsd_name: dict,
424 nsr_name: str,
425 vim_account: str = None,
426 paas_account: str = None,
427 config: dict = None,
428 ssh_keys: str = None,
429 description: str = "default description",
430 admin_status: str = "ENABLED",
431 wait: bool = False,
432 timeout: int = None,
433 ) -> str:
434 """NS create request which includes PaaS Account or VIM account.
435 Args:
436 nsd_name (dict): A dictionary which includes network service description
437 nsr_name (str): Network service record name
438 vim_account (str): VIM account ID as string
439 paas_account (str): PaaS Account id as string
440 config (dict): Placeholder for additional configuration
441 ssh_keys (str): ssh-key file
442 description (str): Service description
443 admin_status (str): Administration Status
444 wait (Boolean): True or False
445 timeout (int): Max time to wait (seconds)
446
447 Returns:
448 response id (str): Response ID
449
450 Raises:
451 ClientException
452 """
453 self._logger.debug("")
454
455 if not (vim_account or paas_account):
456 raise ClientException(
457 "Both of vim_account and paas_account options are empty."
458 )
459
460 if vim_account and paas_account:
461 raise ClientException(
462 "Both of vim_account and paas_account options are set."
463 )
464
465 self._client.get_token()
466 nsd = self._client.nsd.get(nsd_name)
467
468 if vim_account:
469 # VIM account is provided as input parameter.
470 ns = self.process_ns_create_with_vim_account(
471 vim_account,
472 nsd,
473 nsr_name,
474 description,
475 config=config,
476 ssh_keys=ssh_keys,
477 timeout=timeout,
478 )
479
480 elif paas_account:
481 # PaaS account is provided as input parameter.
482 ns = self.process_ns_create_with_paas_account(
483 paas_account, nsd, nsr_name, description, config=config, timeout=timeout
484 )
485
486 try:
487 self._apiResource = "/ns_instances_content"
488 self._apiBase = "{}{}{}".format(
489 self._apiName, self._apiVersion, self._apiResource
490 )
491 headers = self._client._headers
492 headers["Content-Type"] = "application/yaml"
493 http_header = [
494 "{}: {}".format(key, val) for (key, val) in list(headers.items())
495 ]
496 self._http.set_http_header(http_header)
497 http_code, resp = self._http.post_cmd(
498 endpoint=self._apiBase, postfields_dict=ns
499 )
500
501 if not resp or "id" not in resp:
502 raise ClientException(
503 "unexpected response from server - {} ".format(resp)
504 )
505 if resp:
506 resp = json.loads(resp)
507 print(str(resp["id"]))
508 if wait:
509 # Wait for status for NS instance creation
510 self._wait(resp.get("nslcmop_id"), wait)
511
512 return resp["id"]
513
514 except ClientException as exc:
515 message = "failed to create ns: {} nsd: {}\nerror:\n{}".format(
516 nsr_name, nsd_name, str(exc)
517 )
518 raise ClientException(message)
519
520 def list_op(self, name, filter=None):
521 """Returns the list of operations of a NS"""
522 self._logger.debug("")
523 ns = self.get(name)
524 try:
525 self._apiResource = "/ns_lcm_op_occs"
526 self._apiBase = "{}{}{}".format(
527 self._apiName, self._apiVersion, self._apiResource
528 )
529 filter_string = ""
530 if filter:
531 filter_string = "&{}".format(filter)
532 http_code, resp = self._http.get2_cmd(
533 "{}?nsInstanceId={}{}".format(self._apiBase, ns["_id"], filter_string)
534 )
535 # print('HTTP CODE: {}'.format(http_code))
536 # print('RESP: {}'.format(resp))
537 if http_code == 200:
538 if resp:
539 resp = json.loads(resp)
540 return resp
541 else:
542 raise ClientException("unexpected response from server")
543 else:
544 msg = resp or ""
545 # if resp:
546 # try:
547 # resp = json.loads(resp)
548 # msg = resp['detail']
549 # except ValueError:
550 # msg = resp
551 raise ClientException(msg)
552 except ClientException as exc:
553 message = "failed to get operation list of NS {}:\nerror:\n{}".format(
554 name, str(exc)
555 )
556 raise ClientException(message)
557
558 def get_op(self, operationId):
559 """Returns the status of an operation"""
560 self._logger.debug("")
561 self._client.get_token()
562 try:
563 self._apiResource = "/ns_lcm_op_occs"
564 self._apiBase = "{}{}{}".format(
565 self._apiName, self._apiVersion, self._apiResource
566 )
567 http_code, resp = self._http.get2_cmd(
568 "{}/{}".format(self._apiBase, operationId)
569 )
570 # print('HTTP CODE: {}'.format(http_code))
571 # print('RESP: {}'.format(resp))
572 if http_code == 200:
573 if resp:
574 resp = json.loads(resp)
575 return resp
576 else:
577 raise ClientException("unexpected response from server")
578 else:
579 msg = resp or ""
580 # if resp:
581 # try:
582 # resp = json.loads(resp)
583 # msg = resp['detail']
584 # except ValueError:
585 # msg = resp
586 raise ClientException(msg)
587 except ClientException as exc:
588 message = "failed to get status of operation {}:\nerror:\n{}".format(
589 operationId, str(exc)
590 )
591 raise ClientException(message)
592
593 def exec_op(
594 self,
595 name,
596 op_name,
597 op_data=None,
598 wait=False,
599 ):
600 """Executes an operation on a NS"""
601 self._logger.debug("")
602 ns = self.get(name)
603 try:
604 ns = self.get(name)
605 self._apiResource = "/ns_instances"
606 self._apiBase = "{}{}{}".format(
607 self._apiName, self._apiVersion, self._apiResource
608 )
609 endpoint = "{}/{}/{}".format(self._apiBase, ns["_id"], op_name)
610 # print('OP_NAME: {}'.format(op_name))
611 # print('OP_DATA: {}'.format(json.dumps(op_data)))
612 http_code, resp = self._http.post_cmd(
613 endpoint=endpoint, postfields_dict=op_data
614 )
615 # print('HTTP CODE: {}'.format(http_code))
616 # print('RESP: {}'.format(resp))
617 # if http_code in (200, 201, 202, 204):
618 if resp:
619 resp = json.loads(resp)
620 if not resp or "id" not in resp:
621 raise ClientException(
622 "unexpected response from server - {}".format(resp)
623 )
624 if wait:
625 # Wait for status for NS instance action
626 # For the 'action' operation, 'id' is used
627 self._wait(resp.get("id"), wait)
628 return resp["id"]
629 # else:
630 # msg = ""
631 # if resp:
632 # try:
633 # msg = json.loads(resp)
634 # except ValueError:
635 # msg = resp
636 # raise ClientException(msg)
637 except ClientException as exc:
638 message = "failed to exec operation {}:\nerror:\n{}".format(name, str(exc))
639 raise ClientException(message)
640
641 def scale_vnf(
642 self,
643 ns_name,
644 vnf_name,
645 scaling_group,
646 scale_in,
647 scale_out,
648 wait=False,
649 timeout=None,
650 ):
651 """Scales a VNF by adding/removing VDUs"""
652 self._logger.debug("")
653 self._client.get_token()
654 try:
655 op_data = {}
656 op_data["scaleType"] = "SCALE_VNF"
657 op_data["scaleVnfData"] = {}
658 if scale_in and not scale_out:
659 op_data["scaleVnfData"]["scaleVnfType"] = "SCALE_IN"
660 elif not scale_in and scale_out:
661 op_data["scaleVnfData"]["scaleVnfType"] = "SCALE_OUT"
662 else:
663 raise ClientException("you must set either 'scale_in' or 'scale_out'")
664 op_data["scaleVnfData"]["scaleByStepData"] = {
665 "member-vnf-index": vnf_name,
666 "scaling-group-descriptor": scaling_group,
667 }
668 if timeout:
669 op_data["timeout_ns_scale"] = timeout
670 op_id = self.exec_op(ns_name, op_name="scale", op_data=op_data, wait=wait)
671 print(str(op_id))
672 except ClientException as exc:
673 message = "failed to scale vnf {} of ns {}:\nerror:\n{}".format(
674 vnf_name, ns_name, str(exc)
675 )
676 raise ClientException(message)
677
678 def update(self, ns_name, data, wait=False):
679 """Update NS instance.
680
681 This function calls the NBI in order to perform an update operation
682 on a Network Service instance.
683
684 Args:
685 ns_name: (str)
686 data: (dict)
687 wait: (boolean)
688
689 Returns:
690 None
691
692 """
693 self._logger.debug("")
694 self._client.get_token()
695 try:
696 op_data = {"updateType": data.pop("updateType")}
697
698 # Check update parameters availability according to update type
699 if op_data["updateType"] == "CHANGE_VNFPKG":
700 if not (
701 data["config"]["changeVnfPackageData"][0].get("vnfInstanceId")
702 and data["config"]["changeVnfPackageData"][0].get("vnfdId")
703 ):
704 raise ClientException("you must set both vnfInstanceId and vnfdId")
705
706 # Fill up op_data
707 op_data["changeVnfPackageData"] = {}
708 op_data["changeVnfPackageData"]["vnfInstanceId"] = data["config"][
709 "changeVnfPackageData"
710 ][0].get("vnfInstanceId")
711
712 op_data["changeVnfPackageData"]["vnfdId"] = data["config"][
713 "changeVnfPackageData"
714 ][0].get("vnfdId")
715
716 if data.get("timeout"):
717 op_data["timeout_ns_update"] = data["timeout"]
718
719 op_id = self.exec_op(ns_name, op_name="update", op_data=op_data, wait=wait)
720 print(str(op_id))
721
722 except ClientException as exc:
723 message = "failed to update ns {}:\nerror:\n{}".format(ns_name, str(exc))
724 raise ClientException(message)
725
726 def create_alarm(self, alarm):
727 self._logger.debug("")
728 self._client.get_token()
729 data = {}
730 data["create_alarm_request"] = {}
731 data["create_alarm_request"]["alarm_create_request"] = alarm
732 try:
733 http_code, resp = self._http.post_cmd(
734 endpoint="/test/message/alarm_request", postfields_dict=data
735 )
736 # print('HTTP CODE: {}'.format(http_code))
737 # print('RESP: {}'.format(resp))
738 # if http_code in (200, 201, 202, 204):
739 # resp = json.loads(resp)
740 print("Alarm created")
741 # else:
742 # msg = ""
743 # if resp:
744 # try:
745 # msg = json.loads(resp)
746 # except ValueError:
747 # msg = resp
748 # raise ClientException('error: code: {}, resp: {}'.format(
749 # http_code, msg))
750 except ClientException as exc:
751 message = "failed to create alarm: alarm {}\n{}".format(alarm, str(exc))
752 raise ClientException(message)
753
754 def delete_alarm(self, name):
755 self._logger.debug("")
756 self._client.get_token()
757 data = {}
758 data["delete_alarm_request"] = {}
759 data["delete_alarm_request"]["alarm_delete_request"] = {}
760 data["delete_alarm_request"]["alarm_delete_request"]["alarm_uuid"] = name
761 try:
762 http_code, resp = self._http.post_cmd(
763 endpoint="/test/message/alarm_request", postfields_dict=data
764 )
765 # print('HTTP CODE: {}'.format(http_code))
766 # print('RESP: {}'.format(resp))
767 # if http_code in (200, 201, 202, 204):
768 # resp = json.loads(resp)
769 print("Alarm deleted")
770 # else:
771 # msg = ""
772 # if resp:
773 # try:
774 # msg = json.loads(resp)
775 # except ValueError:
776 # msg = resp
777 # raise ClientException('error: code: {}, resp: {}'.format(
778 # http_code, msg))
779 except ClientException as exc:
780 message = "failed to delete alarm: alarm {}\n{}".format(name, str(exc))
781 raise ClientException(message)
782
783 def get_alarm(self, project_name=None, ns_id=None, uuid=None):
784 self._client.get_token()
785 try:
786 self._apiName = "/nsfm"
787 self._apiResource = "/alarms"
788 self._apiBase = "{}{}{}".format(
789 self._apiName, self._apiVersion, self._apiResource
790 )
791 if uuid:
792 # if request is for any uuid
793 http_code, resp = self._http.get2_cmd(
794 "{}/{}".format(self._apiBase, uuid)
795 )
796 if not uuid:
797 http_code, resp = self._http.get2_cmd(
798 "{}/{}/{}/{}".format(self._apiBase, uuid, project_name, ns_id)
799 )
800 if http_code == 200:
801 if resp:
802 resp = json.loads(resp)
803 return resp
804 else:
805 raise ClientException("unexpected response from server")
806 else:
807 msg = resp or ""
808 raise ClientException(msg)
809 except ClientException as exc:
810 message = "failed to get alarm :\nerror:\n{}".format(str(exc))
811 raise ClientException(message)
812
813 def update_alarm(self, uuid, threshold=None, is_enable=None, wait=None):
814 self._client.get_token()
815 try:
816 op_data = {}
817 op_data["uuid"] = uuid
818 op_data["threshold"] = threshold
819 op_data["is_enable"] = is_enable
820 self._apiName = "/nsfm"
821 self._apiResource = "/alarms"
822 self._apiBase = "{}{}{}".format(
823 self._apiName, self._apiVersion, self._apiResource
824 )
825 http_code, resp = self._http.patch_cmd(
826 endpoint="{}".format(self._apiBase), postfields_dict=op_data
827 )
828 if resp:
829 resp = json.loads(resp)
830 print(resp)
831 return resp
832 except ClientException as exc:
833 message = "failed to update alarm :\nerror:\n{}".format(str(exc))
834 raise ClientException(message)
835
836 def export_metric(self, metric):
837 self._logger.debug("")
838 self._client.get_token()
839 data = {}
840 data["read_metric_data_request"] = metric
841 try:
842 http_code, resp = self._http.post_cmd(
843 endpoint="/test/message/metric_request", postfields_dict=data
844 )
845 # print('HTTP CODE: {}'.format(http_code))
846 # print('RESP: {}'.format(resp))
847 # if http_code in (200, 201, 202, 204):
848 # resp = json.loads(resp)
849 return "Metric exported"
850 # else:
851 # msg = ""
852 # if resp:
853 # try:
854 # msg = json.loads(resp)
855 # except ValueError:
856 # msg = resp
857 # raise ClientException('error: code: {}, resp: {}'.format(
858 # http_code, msg))
859 except ClientException as exc:
860 message = "failed to export metric: metric {}\n{}".format(metric, str(exc))
861 raise ClientException(message)
862
863 def get_field(self, ns_name, field):
864 self._logger.debug("")
865 nsr = self.get(ns_name)
866 print(yaml.safe_dump(nsr))
867 if nsr is None:
868 raise NotFound("failed to retrieve ns {}".format(ns_name))
869
870 if field in nsr:
871 return nsr[field]
872
873 raise NotFound("failed to find {} in ns {}".format(field, ns_name))
874
875 def heal(
876 self,
877 ns_name,
878 heal_dict,
879 wait=False,
880 timeout=None,
881 ):
882 """Heals a NS"""
883 self._logger.debug("")
884 self._client.get_token()
885 try:
886 op_data = heal_dict
887 if timeout:
888 op_data["timeout_ns_heal"] = timeout
889 op_id = self.exec_op(ns_name, op_name="heal", op_data=op_data, wait=wait)
890 print(str(op_id))
891 except ClientException as exc:
892 message = "failed to heal ns {}:\nerror:\n{}".format(ns_name, str(exc))
893 raise ClientException(message)