fe3a2bac7dbe3763491d182191c0285c27651845
[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 resp:
502 resp = json.loads(resp)
503 print(str(resp["id"]))
504
505 if not resp or "id" not in resp:
506 raise ClientException(
507 "unexpected response from server - {} ".format(resp)
508 )
509 if wait:
510 # Wait for status for NS instance creation
511 self._wait(resp.get("nslcmop_id"), wait)
512
513 return resp["id"]
514
515 except ClientException as exc:
516 message = "failed to create ns: {} nsd: {}\nerror:\n{}".format(
517 nsr_name, nsd_name, str(exc)
518 )
519 raise ClientException(message)
520
521 def list_op(self, name, filter=None):
522 """Returns the list of operations of a NS"""
523 self._logger.debug("")
524 ns = self.get(name)
525 try:
526 self._apiResource = "/ns_lcm_op_occs"
527 self._apiBase = "{}{}{}".format(
528 self._apiName, self._apiVersion, self._apiResource
529 )
530 filter_string = ""
531 if filter:
532 filter_string = "&{}".format(filter)
533 http_code, resp = self._http.get2_cmd(
534 "{}?nsInstanceId={}{}".format(self._apiBase, ns["_id"], filter_string)
535 )
536 # print('HTTP CODE: {}'.format(http_code))
537 # print('RESP: {}'.format(resp))
538 if http_code == 200:
539 if resp:
540 resp = json.loads(resp)
541 return resp
542 else:
543 raise ClientException("unexpected response from server")
544 else:
545 msg = resp or ""
546 # if resp:
547 # try:
548 # resp = json.loads(resp)
549 # msg = resp['detail']
550 # except ValueError:
551 # msg = resp
552 raise ClientException(msg)
553 except ClientException as exc:
554 message = "failed to get operation list of NS {}:\nerror:\n{}".format(
555 name, str(exc)
556 )
557 raise ClientException(message)
558
559 def get_op(self, operationId):
560 """Returns the status of an operation"""
561 self._logger.debug("")
562 self._client.get_token()
563 try:
564 self._apiResource = "/ns_lcm_op_occs"
565 self._apiBase = "{}{}{}".format(
566 self._apiName, self._apiVersion, self._apiResource
567 )
568 http_code, resp = self._http.get2_cmd(
569 "{}/{}".format(self._apiBase, operationId)
570 )
571 # print('HTTP CODE: {}'.format(http_code))
572 # print('RESP: {}'.format(resp))
573 if http_code == 200:
574 if resp:
575 resp = json.loads(resp)
576 return resp
577 else:
578 raise ClientException("unexpected response from server")
579 else:
580 msg = resp or ""
581 # if resp:
582 # try:
583 # resp = json.loads(resp)
584 # msg = resp['detail']
585 # except ValueError:
586 # msg = resp
587 raise ClientException(msg)
588 except ClientException as exc:
589 message = "failed to get status of operation {}:\nerror:\n{}".format(
590 operationId, str(exc)
591 )
592 raise ClientException(message)
593
594 def exec_op(
595 self,
596 name,
597 op_name,
598 op_data=None,
599 wait=False,
600 ):
601 """Executes an operation on a NS"""
602 self._logger.debug("")
603 ns = self.get(name)
604 try:
605 ns = self.get(name)
606 self._apiResource = "/ns_instances"
607 self._apiBase = "{}{}{}".format(
608 self._apiName, self._apiVersion, self._apiResource
609 )
610 endpoint = "{}/{}/{}".format(self._apiBase, ns["_id"], op_name)
611 # print('OP_NAME: {}'.format(op_name))
612 # print('OP_DATA: {}'.format(json.dumps(op_data)))
613 http_code, resp = self._http.post_cmd(
614 endpoint=endpoint, postfields_dict=op_data
615 )
616 # print('HTTP CODE: {}'.format(http_code))
617 # print('RESP: {}'.format(resp))
618 # if http_code in (200, 201, 202, 204):
619 if resp:
620 resp = json.loads(resp)
621 if not resp or "id" not in resp:
622 raise ClientException(
623 "unexpected response from server - {}".format(resp)
624 )
625 if wait:
626 # Wait for status for NS instance action
627 # For the 'action' operation, 'id' is used
628 self._wait(resp.get("id"), wait)
629 return resp["id"]
630 # else:
631 # msg = ""
632 # if resp:
633 # try:
634 # msg = json.loads(resp)
635 # except ValueError:
636 # msg = resp
637 # raise ClientException(msg)
638 except ClientException as exc:
639 message = "failed to exec operation {}:\nerror:\n{}".format(name, str(exc))
640 raise ClientException(message)
641
642 def scale_vnf(
643 self,
644 ns_name,
645 vnf_name,
646 scaling_group,
647 scale_in,
648 scale_out,
649 wait=False,
650 timeout=None,
651 ):
652 """Scales a VNF by adding/removing VDUs"""
653 self._logger.debug("")
654 self._client.get_token()
655 try:
656 op_data = {}
657 op_data["scaleType"] = "SCALE_VNF"
658 op_data["scaleVnfData"] = {}
659 if scale_in and not scale_out:
660 op_data["scaleVnfData"]["scaleVnfType"] = "SCALE_IN"
661 elif not scale_in and scale_out:
662 op_data["scaleVnfData"]["scaleVnfType"] = "SCALE_OUT"
663 else:
664 raise ClientException("you must set either 'scale_in' or 'scale_out'")
665 op_data["scaleVnfData"]["scaleByStepData"] = {
666 "member-vnf-index": vnf_name,
667 "scaling-group-descriptor": scaling_group,
668 }
669 if timeout:
670 op_data["timeout_ns_scale"] = timeout
671 op_id = self.exec_op(ns_name, op_name="scale", op_data=op_data, wait=wait)
672 print(str(op_id))
673 except ClientException as exc:
674 message = "failed to scale vnf {} of ns {}:\nerror:\n{}".format(
675 vnf_name, ns_name, str(exc)
676 )
677 raise ClientException(message)
678
679 def update(self, ns_name, data, wait=False):
680 """Update NS instance.
681
682 This function calls the NBI in order to perform an update operation
683 on a Network Service instance.
684
685 Args:
686 ns_name: (str)
687 data: (dict)
688 wait: (boolean)
689
690 Returns:
691 None
692
693 """
694 self._logger.debug("")
695 self._client.get_token()
696 try:
697 op_data = {"updateType": data.pop("updateType")}
698
699 # Check update parameters availability according to update type
700 if op_data["updateType"] == "CHANGE_VNFPKG":
701 if not (
702 data["config"]["changeVnfPackageData"][0].get("vnfInstanceId")
703 and data["config"]["changeVnfPackageData"][0].get("vnfdId")
704 ):
705 raise ClientException("you must set both vnfInstanceId and vnfdId")
706
707 # Fill up op_data
708 op_data["changeVnfPackageData"] = {}
709 op_data["changeVnfPackageData"]["vnfInstanceId"] = data["config"][
710 "changeVnfPackageData"
711 ][0].get("vnfInstanceId")
712
713 op_data["changeVnfPackageData"]["vnfdId"] = data["config"][
714 "changeVnfPackageData"
715 ][0].get("vnfdId")
716
717 if data.get("timeout"):
718 op_data["timeout_ns_update"] = data["timeout"]
719
720 op_id = self.exec_op(ns_name, op_name="update", op_data=op_data, wait=wait)
721 print(str(op_id))
722
723 except ClientException as exc:
724 message = "failed to update ns {}:\nerror:\n{}".format(ns_name, str(exc))
725 raise ClientException(message)
726
727 def create_alarm(self, alarm):
728 self._logger.debug("")
729 self._client.get_token()
730 data = {}
731 data["create_alarm_request"] = {}
732 data["create_alarm_request"]["alarm_create_request"] = alarm
733 try:
734 http_code, resp = self._http.post_cmd(
735 endpoint="/test/message/alarm_request", postfields_dict=data
736 )
737 # print('HTTP CODE: {}'.format(http_code))
738 # print('RESP: {}'.format(resp))
739 # if http_code in (200, 201, 202, 204):
740 # resp = json.loads(resp)
741 print("Alarm created")
742 # else:
743 # msg = ""
744 # if resp:
745 # try:
746 # msg = json.loads(resp)
747 # except ValueError:
748 # msg = resp
749 # raise ClientException('error: code: {}, resp: {}'.format(
750 # http_code, msg))
751 except ClientException as exc:
752 message = "failed to create alarm: alarm {}\n{}".format(alarm, str(exc))
753 raise ClientException(message)
754
755 def delete_alarm(self, name):
756 self._logger.debug("")
757 self._client.get_token()
758 data = {}
759 data["delete_alarm_request"] = {}
760 data["delete_alarm_request"]["alarm_delete_request"] = {}
761 data["delete_alarm_request"]["alarm_delete_request"]["alarm_uuid"] = name
762 try:
763 http_code, resp = self._http.post_cmd(
764 endpoint="/test/message/alarm_request", postfields_dict=data
765 )
766 # print('HTTP CODE: {}'.format(http_code))
767 # print('RESP: {}'.format(resp))
768 # if http_code in (200, 201, 202, 204):
769 # resp = json.loads(resp)
770 print("Alarm deleted")
771 # else:
772 # msg = ""
773 # if resp:
774 # try:
775 # msg = json.loads(resp)
776 # except ValueError:
777 # msg = resp
778 # raise ClientException('error: code: {}, resp: {}'.format(
779 # http_code, msg))
780 except ClientException as exc:
781 message = "failed to delete alarm: alarm {}\n{}".format(name, str(exc))
782 raise ClientException(message)
783
784 def get_alarm(self, project_name=None, ns_id=None, uuid=None):
785 self._client.get_token()
786 try:
787 self._apiName = "/nsfm"
788 self._apiResource = "/alarms"
789 self._apiBase = "{}{}{}".format(
790 self._apiName, self._apiVersion, self._apiResource
791 )
792 if uuid:
793 # if request is for any uuid
794 http_code, resp = self._http.get2_cmd(
795 "{}/{}".format(self._apiBase, uuid)
796 )
797 if not uuid:
798 http_code, resp = self._http.get2_cmd(
799 "{}/{}/{}/{}".format(self._apiBase, uuid, project_name, ns_id)
800 )
801 if http_code == 200:
802 if resp:
803 resp = json.loads(resp)
804 return resp
805 else:
806 raise ClientException("unexpected response from server")
807 else:
808 msg = resp or ""
809 raise ClientException(msg)
810 except ClientException as exc:
811 message = "failed to get alarm :\nerror:\n{}".format(str(exc))
812 raise ClientException(message)
813
814 def update_alarm(self, uuid, threshold=None, is_enable=None, wait=None):
815 self._client.get_token()
816 try:
817 op_data = {}
818 op_data["uuid"] = uuid
819 op_data["threshold"] = threshold
820 op_data["is_enable"] = is_enable
821 self._apiName = "/nsfm"
822 self._apiResource = "/alarms"
823 self._apiBase = "{}{}{}".format(
824 self._apiName, self._apiVersion, self._apiResource
825 )
826 http_code, resp = self._http.patch_cmd(
827 endpoint="{}".format(self._apiBase), postfields_dict=op_data
828 )
829 if resp:
830 resp = json.loads(resp)
831 print(resp)
832 return resp
833 except ClientException as exc:
834 message = "failed to update alarm :\nerror:\n{}".format(str(exc))
835 raise ClientException(message)
836
837 def export_metric(self, metric):
838 self._logger.debug("")
839 self._client.get_token()
840 data = {}
841 data["read_metric_data_request"] = metric
842 try:
843 http_code, resp = self._http.post_cmd(
844 endpoint="/test/message/metric_request", postfields_dict=data
845 )
846 # print('HTTP CODE: {}'.format(http_code))
847 # print('RESP: {}'.format(resp))
848 # if http_code in (200, 201, 202, 204):
849 # resp = json.loads(resp)
850 return "Metric exported"
851 # else:
852 # msg = ""
853 # if resp:
854 # try:
855 # msg = json.loads(resp)
856 # except ValueError:
857 # msg = resp
858 # raise ClientException('error: code: {}, resp: {}'.format(
859 # http_code, msg))
860 except ClientException as exc:
861 message = "failed to export metric: metric {}\n{}".format(metric, str(exc))
862 raise ClientException(message)
863
864 def get_field(self, ns_name, field):
865 self._logger.debug("")
866 nsr = self.get(ns_name)
867 print(yaml.safe_dump(nsr))
868 if nsr is None:
869 raise NotFound("failed to retrieve ns {}".format(ns_name))
870
871 if field in nsr:
872 return nsr[field]
873
874 raise NotFound("failed to find {} in ns {}".format(field, ns_name))
875
876 def heal(
877 self,
878 ns_name,
879 heal_dict,
880 wait=False,
881 timeout=None,
882 ):
883 """Heals a NS"""
884 self._logger.debug("")
885 self._client.get_token()
886 try:
887 op_data = heal_dict
888 if timeout:
889 op_data["timeout_ns_heal"] = timeout
890 op_id = self.exec_op(ns_name, op_name="heal", op_data=op_data, wait=wait)
891 print(str(op_id))
892 except ClientException as exc:
893 message = "failed to heal ns {}:\nerror:\n{}".format(ns_name, str(exc))
894 raise ClientException(message)