Code Coverage

Cobertura Coverage Report > osmclient.sol005 >

ns.py

Trend

File Coverage summary

NameClassesLinesConditionals
ns.py
100%
1/1
8%
29/382
100%
0/0

Coverage Breakdown by Class

NameLinesConditionals
ns.py
8%
29/382
N/A

Source

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 1 """
18 OSM ns API handling
19 """
20
21 1 from osmclient.common import utils
22 1 from osmclient.common import wait as WaitForStatus
23 1 from osmclient.common.exceptions import ClientException
24 1 from osmclient.common.exceptions import NotFound
25 1 import yaml
26 1 import json
27 1 import logging
28
29
30 1 class Ns(object):
31 1     def __init__(self, http=None, client=None):
32 0         self._http = http
33 0         self._client = client
34 0         self._logger = logging.getLogger("osmclient")
35 0         self._apiName = "/nslcm"
36 0         self._apiVersion = "/v1"
37 0         self._apiResource = "/ns_instances_content"
38 0         self._apiBase = "{}{}{}".format(
39             self._apiName, self._apiVersion, self._apiResource
40         )
41
42     # NS '--wait' option
43 1     def _wait(self, id, wait_time, deleteFlag=False, entity="NS"):
44 0         self._logger.debug("")
45         # Endpoint to get operation status
46 0         apiUrlStatus = "{}{}{}".format(
47             self._apiName, self._apiVersion, "/ns_lcm_op_occs"
48         )
49         # Wait for status for NS instance creation/update/deletion
50 0         if isinstance(wait_time, bool):
51 0             wait_time = WaitForStatus.TIMEOUT_NS_OPERATION
52 0         WaitForStatus.wait_for_status(
53             entity,
54             str(id),
55             wait_time,
56             apiUrlStatus,
57             self._http.get2_cmd,
58             deleteFlag=deleteFlag,
59         )
60
61 1     def list(self, filter=None):
62         """Returns a list of NS"""
63 0         self._logger.debug("")
64 0         self._client.get_token()
65 0         filter_string = ""
66 0         if filter:
67 0             filter_string = "?{}".format(filter)
68 0         _, resp = self._http.get2_cmd("{}{}".format(self._apiBase, filter_string))
69 0         if resp:
70 0             return json.loads(resp)
71 0         return list()
72
73 1     def get(self, name):
74         """Returns an NS based on name or id"""
75 0         self._logger.debug("")
76 0         self._client.get_token()
77 0         if utils.validate_uuid4(name):
78 0             for ns in self.list():
79 0                 if name == ns["_id"]:
80 0                     return ns
81         else:
82 0             for ns in self.list():
83 0                 if name == ns["name"]:
84 0                     return ns
85 0         raise NotFound("ns '{}' not found".format(name))
86
87 1     def get_individual(self, name):
88 0         self._logger.debug("")
89 0         self._client.get_token()
90 0         ns_id = name
91 0         if not utils.validate_uuid4(name):
92 0             for ns in self.list():
93 0                 if name == ns["name"]:
94 0                     ns_id = ns["_id"]
95 0                     break
96 0         try:
97 0             _, 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 0             if resp:
101 0                 return json.loads(resp)
102 0         except NotFound:
103 0             raise NotFound("ns '{}' not found".format(name))
104 0         raise NotFound("ns '{}' not found".format(name))
105
106 1     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 the terminate 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 0         self._logger.debug("")
120 0         ns = self.get(name)
121 0         querystring_list = []
122 0         querystring = ""
123 0         if config:
124 0             ns_config = yaml.safe_load(config)
125 0             querystring_list += ["{}={}".format(k, v) for k, v in ns_config.items()]
126 0         if force:
127 0             querystring_list.append("FORCE=True")
128 0         if querystring_list:
129 0             querystring = "?" + "&".join(querystring_list)
130 0         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 0         if http_code == 202:
139 0             if wait and resp:
140 0                 resp = json.loads(resp)
141                 # For the 'delete' operation, '_id' is used
142 0                 self._wait(resp.get("_id"), wait, deleteFlag=True)
143             else:
144 0                 print("Deletion in progress")
145 0         elif http_code == 204:
146 0             print("Deleted")
147         else:
148 0             msg = resp or ""
149             # if resp:
150             #     try:
151             #         msg = json.loads(resp)
152             #     except ValueError:
153             #         msg = resp
154 0             raise ClientException("failed to delete ns {} - {}".format(name, msg))
155
156 1     def create(
157         self,
158         nsd_name,
159         nsr_name,
160         account,
161         config=None,
162         ssh_keys=None,
163         description="default description",
164         admin_status="ENABLED",
165         wait=False,
166         timeout=None,
167     ):
168 0         self._logger.debug("")
169 0         self._client.get_token()
170 0         nsd = self._client.nsd.get(nsd_name)
171
172 0         vim_account_id = {}
173 0         wim_account_id = {}
174
175 0         def get_vim_account_id(vim_account):
176 0             self._logger.debug("")
177 0             if vim_account_id.get(vim_account):
178 0                 return vim_account_id[vim_account]
179 0             vim = self._client.vim.get(vim_account)
180 0             if vim is None:
181 0                 raise NotFound("cannot find vim account '{}'".format(vim_account))
182 0             vim_account_id[vim_account] = vim["_id"]
183 0             return vim["_id"]
184
185 0         def get_wim_account_id(wim_account):
186 0             self._logger.debug("")
187             # wim_account can be False (boolean) to indicate not use wim account
188 0             if not isinstance(wim_account, str):
189 0                 return wim_account
190 0             if wim_account_id.get(wim_account):
191 0                 return wim_account_id[wim_account]
192 0             wim = self._client.wim.get(wim_account)
193 0             if wim is None:
194 0                 raise NotFound("cannot find wim account '{}'".format(wim_account))
195 0             wim_account_id[wim_account] = wim["_id"]
196 0             return wim["_id"]
197
198 0         vim_id = get_vim_account_id(account)
199 0         ns = {}
200 0         ns["nsdId"] = nsd["_id"]
201 0         ns["nsName"] = nsr_name
202 0         ns["nsDescription"] = description
203 0         ns["vimAccountId"] = vim_id
204         # ns['userdata'] = {}
205         # ns['userdata']['key1']='value1'
206         # ns['userdata']['key2']='value2'
207
208 0         if ssh_keys is not None:
209 0             ns["ssh_keys"] = []
210 0             for pubkeyfile in ssh_keys.split(","):
211 0                 with open(pubkeyfile, "r") as f:
212 0                     ns["ssh_keys"].append(f.read())
213 0         if timeout:
214 0             ns["timeout_ns_deploy"] = timeout
215 0         if config:
216 0             ns_config = yaml.safe_load(config)
217 0             if "vim-network-name" in ns_config:
218 0                 ns_config["vld"] = ns_config.pop("vim-network-name")
219 0             if "vld" in ns_config:
220 0                 if not isinstance(ns_config["vld"], list):
221 0                     raise ClientException(
222                         "Error at --config 'vld' must be a list of dictionaries"
223                     )
224 0                 for vld in ns_config["vld"]:
225 0                     if not isinstance(vld, dict):
226 0                         raise ClientException(
227                             "Error at --config 'vld' must be a list of dictionaries"
228                         )
229 0                     if vld.get("vim-network-name"):
230 0                         if isinstance(vld["vim-network-name"], dict):
231 0                             vim_network_name_dict = {}
232 0                             for vim_account, vim_net in vld["vim-network-name"].items():
233 0                                 vim_network_name_dict[
234                                     get_vim_account_id(vim_account)
235                                 ] = vim_net
236 0                             vld["vim-network-name"] = vim_network_name_dict
237 0                     if "wim_account" in vld and vld["wim_account"] is not None:
238 0                         vld["wimAccountId"] = get_wim_account_id(vld.pop("wim_account"))
239 0             if "vnf" in ns_config:
240 0                 for vnf in ns_config["vnf"]:
241 0                     if vnf.get("vim_account"):
242 0                         vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
243
244 0             if "additionalParamsForNs" in ns_config:
245 0                 if not isinstance(ns_config["additionalParamsForNs"], dict):
246 0                     raise ClientException(
247                         "Error at --config 'additionalParamsForNs' must be a dictionary"
248                     )
249 0             if "additionalParamsForVnf" in ns_config:
250 0                 if not isinstance(ns_config["additionalParamsForVnf"], list):
251 0                     raise ClientException(
252                         "Error at --config 'additionalParamsForVnf' must be a list"
253                     )
254 0                 for additional_param_vnf in ns_config["additionalParamsForVnf"]:
255 0                     if not isinstance(additional_param_vnf, dict):
256 0                         raise ClientException(
257                             "Error at --config 'additionalParamsForVnf' items must be dictionaries"
258                         )
259 0                     if not additional_param_vnf.get("member-vnf-index"):
260 0                         raise ClientException(
261                             "Error at --config 'additionalParamsForVnf' items must contain "
262                             "'member-vnf-index'"
263                         )
264 0             if "wim_account" in ns_config:
265 0                 wim_account = ns_config.pop("wim_account")
266 0                 if wim_account is not None:
267 0                     ns["wimAccountId"] = get_wim_account_id(wim_account)
268             # rest of parameters without any transformation or checking
269             # "timeout_ns_deploy"
270             # "placement-engine"
271 0             ns.update(ns_config)
272
273         # print(yaml.safe_dump(ns))
274 0         try:
275 0             self._apiResource = "/ns_instances_content"
276 0             self._apiBase = "{}{}{}".format(
277                 self._apiName, self._apiVersion, self._apiResource
278             )
279 0             headers = self._client._headers
280 0             headers["Content-Type"] = "application/yaml"
281 0             self._http.set_http_header(headers)
282 0             http_code, resp = self._http.post_cmd(
283                 endpoint=self._apiBase, postfields_dict=ns
284             )
285             # print('HTTP CODE: {}'.format(http_code))
286             # print('RESP: {}'.format(resp))
287             # if http_code in (200, 201, 202, 204):
288 0             if resp:
289 0                 resp = json.loads(resp)
290 0             if not resp or "id" not in resp:
291 0                 raise ClientException(
292                     "unexpected response from server - {} ".format(resp)
293                 )
294 0             if wait:
295                 # Wait for status for NS instance creation
296 0                 self._wait(resp.get("nslcmop_id"), wait)
297 0             print(resp["id"])
298 0             return resp["id"]
299             # else:
300             #    msg = ""
301             #    if resp:
302             #        try:
303             #            msg = json.loads(resp)
304             #        except ValueError:
305             #            msg = resp
306             #    raise ClientException(msg)
307 0         except ClientException as exc:
308 0             message = "failed to create ns: {} nsd: {}\nerror:\n{}".format(
309                 nsr_name, nsd_name, str(exc)
310             )
311 0             raise ClientException(message)
312
313 1     def list_op(self, name, filter=None):
314         """Returns the list of operations of a NS"""
315 0         self._logger.debug("")
316 0         ns = self.get(name)
317 0         try:
318 0             self._apiResource = "/ns_lcm_op_occs"
319 0             self._apiBase = "{}{}{}".format(
320                 self._apiName, self._apiVersion, self._apiResource
321             )
322 0             filter_string = ""
323 0             if filter:
324 0                 filter_string = "&{}".format(filter)
325 0             http_code, resp = self._http.get2_cmd(
326                 "{}?nsInstanceId={}{}".format(self._apiBase, ns["_id"], filter_string)
327             )
328             # print('HTTP CODE: {}'.format(http_code))
329             # print('RESP: {}'.format(resp))
330 0             if http_code == 200:
331 0                 if resp:
332 0                     resp = json.loads(resp)
333 0                     return resp
334                 else:
335 0                     raise ClientException("unexpected response from server")
336             else:
337 0                 msg = resp or ""
338                 #    if resp:
339                 #        try:
340                 #            resp = json.loads(resp)
341                 #            msg = resp['detail']
342                 #        except ValueError:
343                 #            msg = resp
344 0                 raise ClientException(msg)
345 0         except ClientException as exc:
346 0             message = "failed to get operation list of NS {}:\nerror:\n{}".format(
347                 name, str(exc)
348             )
349 0             raise ClientException(message)
350
351 1     def get_op(self, operationId):
352         """Returns the status of an operation"""
353 0         self._logger.debug("")
354 0         self._client.get_token()
355 0         try:
356 0             self._apiResource = "/ns_lcm_op_occs"
357 0             self._apiBase = "{}{}{}".format(
358                 self._apiName, self._apiVersion, self._apiResource
359             )
360 0             http_code, resp = self._http.get2_cmd(
361                 "{}/{}".format(self._apiBase, operationId)
362             )
363             # print('HTTP CODE: {}'.format(http_code))
364             # print('RESP: {}'.format(resp))
365 0             if http_code == 200:
366 0                 if resp:
367 0                     resp = json.loads(resp)
368 0                     return resp
369                 else:
370 0                     raise ClientException("unexpected response from server")
371             else:
372 0                 msg = resp or ""
373                 #    if resp:
374                 #        try:
375                 #            resp = json.loads(resp)
376                 #            msg = resp['detail']
377                 #        except ValueError:
378                 #            msg = resp
379 0                 raise ClientException(msg)
380 0         except ClientException as exc:
381 0             message = "failed to get status of operation {}:\nerror:\n{}".format(
382                 operationId, str(exc)
383             )
384 0             raise ClientException(message)
385
386 1     def exec_op(
387         self,
388         name,
389         op_name,
390         op_data=None,
391         wait=False,
392     ):
393         """Executes an operation on a NS"""
394 0         self._logger.debug("")
395 0         ns = self.get(name)
396 0         try:
397 0             ns = self.get(name)
398 0             self._apiResource = "/ns_instances"
399 0             self._apiBase = "{}{}{}".format(
400                 self._apiName, self._apiVersion, self._apiResource
401             )
402 0             endpoint = "{}/{}/{}".format(self._apiBase, ns["_id"], op_name)
403             # print('OP_NAME: {}'.format(op_name))
404             # print('OP_DATA: {}'.format(json.dumps(op_data)))
405 0             http_code, resp = self._http.post_cmd(
406                 endpoint=endpoint, postfields_dict=op_data
407             )
408             # print('HTTP CODE: {}'.format(http_code))
409             # print('RESP: {}'.format(resp))
410             # if http_code in (200, 201, 202, 204):
411 0             if resp:
412 0                 resp = json.loads(resp)
413 0             if not resp or "id" not in resp:
414 0                 raise ClientException(
415                     "unexpected response from server - {}".format(resp)
416                 )
417 0             if wait:
418                 # Wait for status for NS instance action
419                 # For the 'action' operation, 'id' is used
420 0                 self._wait(resp.get("id"), wait)
421 0             return resp["id"]
422             # else:
423             #    msg = ""
424             #    if resp:
425             #        try:
426             #            msg = json.loads(resp)
427             #        except ValueError:
428             #            msg = resp
429             #    raise ClientException(msg)
430 0         except ClientException as exc:
431 0             message = "failed to exec operation {}:\nerror:\n{}".format(name, str(exc))
432 0             raise ClientException(message)
433
434 1     def cancel_op(self, operation_id, cancel_mode, wait=False):
435         """Cancels an LCM operation"""
436 0         self._client.get_token()
437 0         self._apiResource = "/ns_lcm_op_occs"
438 0         self._apiBase = "{}{}{}".format(
439             self._apiName, self._apiVersion, self._apiResource
440         )
441 0         endpoint = "{}/{}/cancel".format(self._apiBase, operation_id)
442 0         op_data = {"cancelMode": cancel_mode}
443 0         try:
444 0             http_code, resp = self._http.post_cmd(
445                 endpoint=endpoint, postfields_dict=op_data
446             )
447 0             if http_code == 202:
448 0                 if wait:
449 0                     self._wait(operation_id, wait, deleteFlag=True, entity="OPCANCEL")
450                 else:
451 0                     print("Cancellation in progress")
452             else:
453 0                 msg = resp or ""
454 0                 raise ClientException(msg)
455 0         except ClientException as exc:
456 0             message = "failed to exec operation {}:\nerror:\n{}".format(
457                 operation_id, str(exc)
458             )
459 0             raise ClientException(message)
460
461 1     def scale_vnf(
462         self,
463         ns_name,
464         vnf_name,
465         scaling_group,
466         scale_in,
467         scale_out,
468         wait=False,
469         timeout=None,
470     ):
471         """Scales a VNF by adding/removing VDUs"""
472 0         self._logger.debug("")
473 0         self._client.get_token()
474 0         try:
475 0             op_data = {}
476 0             op_data["scaleType"] = "SCALE_VNF"
477 0             op_data["scaleVnfData"] = {}
478 0             if scale_in and not scale_out:
479 0                 op_data["scaleVnfData"]["scaleVnfType"] = "SCALE_IN"
480 0             elif not scale_in and scale_out:
481 0                 op_data["scaleVnfData"]["scaleVnfType"] = "SCALE_OUT"
482             else:
483 0                 raise ClientException("you must set either 'scale_in' or 'scale_out'")
484 0             op_data["scaleVnfData"]["scaleByStepData"] = {
485                 "member-vnf-index": vnf_name,
486                 "scaling-group-descriptor": scaling_group,
487             }
488 0             if timeout:
489 0                 op_data["timeout_ns_scale"] = timeout
490 0             op_id = self.exec_op(ns_name, op_name="scale", op_data=op_data, wait=wait)
491 0             print(str(op_id))
492 0         except ClientException as exc:
493 0             message = "failed to scale vnf {} of ns {}:\nerror:\n{}".format(
494                 vnf_name, ns_name, str(exc)
495             )
496 0             raise ClientException(message)
497
498 1     def update(self, ns_name, data, wait=False):
499         """Update NS instance.
500
501         This function calls the NBI in order to perform an update operation
502         on a Network Service instance.
503
504         Args:
505             ns_name: (str)
506             data: (dict)
507             wait: (boolean)
508
509         Returns:
510             None
511
512         """
513 0         self._logger.debug("")
514 0         self._client.get_token()
515 0         try:
516 0             op_data = {"updateType": data.pop("updateType")}
517
518             # Check update parameters availability according to update type
519 0             if op_data["updateType"] == "CHANGE_VNFPKG":
520 0                 if not (
521                     data["config"]["changeVnfPackageData"][0].get("vnfInstanceId")
522                     and data["config"]["changeVnfPackageData"][0].get("vnfdId")
523                 ):
524 0                     raise ClientException("you must set both vnfInstanceId and vnfdId")
525
526             # Fill up op_data
527 0             op_data["changeVnfPackageData"] = {}
528 0             op_data["changeVnfPackageData"]["vnfInstanceId"] = data["config"][
529                 "changeVnfPackageData"
530             ][0].get("vnfInstanceId")
531
532 0             op_data["changeVnfPackageData"]["vnfdId"] = data["config"][
533                 "changeVnfPackageData"
534             ][0].get("vnfdId")
535
536 0             if data.get("timeout"):
537 0                 op_data["timeout_ns_update"] = data["timeout"]
538
539 0             op_id = self.exec_op(ns_name, op_name="update", op_data=op_data, wait=wait)
540 0             print(str(op_id))
541
542 0         except ClientException as exc:
543 0             message = "failed to update ns {}:\nerror:\n{}".format(ns_name, str(exc))
544 0             raise ClientException(message)
545
546 1     def create_alarm(self, alarm):
547 0         self._logger.debug("")
548 0         self._client.get_token()
549 0         data = {}
550 0         data["create_alarm_request"] = {}
551 0         data["create_alarm_request"]["alarm_create_request"] = alarm
552 0         try:
553 0             http_code, resp = self._http.post_cmd(
554                 endpoint="/test/message/alarm_request", postfields_dict=data
555             )
556             # print('HTTP CODE: {}'.format(http_code))
557             # print('RESP: {}'.format(resp))
558             # if http_code in (200, 201, 202, 204):
559             #     resp = json.loads(resp)
560 0             print("Alarm created")
561             # else:
562             #    msg = ""
563             #    if resp:
564             #        try:
565             #            msg = json.loads(resp)
566             #        except ValueError:
567             #            msg = resp
568             #    raise ClientException('error: code: {}, resp: {}'.format(
569             #                          http_code, msg))
570 0         except ClientException as exc:
571 0             message = "failed to create alarm: alarm {}\n{}".format(alarm, str(exc))
572 0             raise ClientException(message)
573
574 1     def delete_alarm(self, name):
575 0         self._logger.debug("")
576 0         self._client.get_token()
577 0         data = {}
578 0         data["delete_alarm_request"] = {}
579 0         data["delete_alarm_request"]["alarm_delete_request"] = {}
580 0         data["delete_alarm_request"]["alarm_delete_request"]["alarm_uuid"] = name
581 0         try:
582 0             http_code, resp = self._http.post_cmd(
583                 endpoint="/test/message/alarm_request", postfields_dict=data
584             )
585             # print('HTTP CODE: {}'.format(http_code))
586             # print('RESP: {}'.format(resp))
587             # if http_code in (200, 201, 202, 204):
588             #    resp = json.loads(resp)
589 0             print("Alarm deleted")
590             # else:
591             #    msg = ""
592             #    if resp:
593             #        try:
594             #            msg = json.loads(resp)
595             #        except ValueError:
596             #            msg = resp
597             #    raise ClientException('error: code: {}, resp: {}'.format(
598             #                          http_code, msg))
599 0         except ClientException as exc:
600 0             message = "failed to delete alarm: alarm {}\n{}".format(name, str(exc))
601 0             raise ClientException(message)
602
603 1     def get_alarm(self, project_name=None, ns_id=None, uuid=None):
604 0         self._client.get_token()
605 0         try:
606 0             self._apiName = "/nsfm"
607 0             self._apiResource = "/alarms"
608 0             self._apiBase = "{}{}{}".format(
609                 self._apiName, self._apiVersion, self._apiResource
610             )
611 0             if uuid:
612                 # if request is for any uuid
613 0                 http_code, resp = self._http.get2_cmd(
614                     "{}/{}".format(self._apiBase, uuid)
615                 )
616             else:  # if not uuid
617 0                 http_code, resp = self._http.get2_cmd(
618                     "{}/{}/{}/{}".format(self._apiBase, uuid, project_name, ns_id)
619                 )
620 0             if http_code == 200:
621 0                 if resp:
622 0                     resp = json.loads(resp)
623 0                     return resp
624                 else:
625 0                     raise ClientException("unexpected response from server")
626             else:
627 0                 msg = resp or ""
628 0                 raise ClientException(msg)
629 0         except ClientException as exc:
630 0             message = "failed to get alarm :\nerror:\n{}".format(str(exc))
631 0             raise ClientException(message)
632
633 1     def update_alarm(self, uuid, threshold=None, is_enable=None, wait=None):
634 0         self._client.get_token()
635 0         try:
636 0             op_data = {}
637 0             op_data["uuid"] = uuid
638 0             op_data["threshold"] = threshold
639 0             op_data["is_enable"] = is_enable
640 0             self._apiName = "/nsfm"
641 0             self._apiResource = "/alarms"
642 0             self._apiBase = "{}{}{}".format(
643                 self._apiName, self._apiVersion, self._apiResource
644             )
645 0             http_code, resp = self._http.patch_cmd(
646                 endpoint="{}".format(self._apiBase), postfields_dict=op_data
647             )
648 0             if resp:
649 0                 resp = json.loads(resp)
650 0             print(resp)
651 0             return resp
652 0         except ClientException as exc:
653 0             message = "failed to update alarm :\nerror:\n{}".format(str(exc))
654 0             raise ClientException(message)
655
656 1     def export_metric(self, metric):
657 0         self._logger.debug("")
658 0         self._client.get_token()
659 0         data = {}
660 0         data["read_metric_data_request"] = metric
661 0         try:
662 0             http_code, resp = self._http.post_cmd(
663                 endpoint="/test/message/metric_request", postfields_dict=data
664             )
665             # print('HTTP CODE: {}'.format(http_code))
666             # print('RESP: {}'.format(resp))
667             # if http_code in (200, 201, 202, 204):
668             #    resp = json.loads(resp)
669 0             return "Metric exported"
670             # else:
671             #    msg = ""
672             #    if resp:
673             #        try:
674             #            msg = json.loads(resp)
675             #        except ValueError:
676             #            msg = resp
677             #    raise ClientException('error: code: {}, resp: {}'.format(
678             #                          http_code, msg))
679 0         except ClientException as exc:
680 0             message = "failed to export metric: metric {}\n{}".format(metric, str(exc))
681 0             raise ClientException(message)
682
683 1     def get_field(self, ns_name, field):
684 0         self._logger.debug("")
685 0         nsr = self.get(ns_name)
686 0         print(yaml.safe_dump(nsr))
687 0         if nsr is None:
688 0             raise NotFound("failed to retrieve ns {}".format(ns_name))
689
690 0         if field in nsr:
691 0             return nsr[field]
692
693 0         raise NotFound("failed to find {} in ns {}".format(field, ns_name))
694
695 1     def heal(
696         self,
697         ns_name,
698         heal_dict,
699         wait=False,
700         timeout=None,
701     ):
702         """Heals a NS"""
703 0         self._logger.debug("")
704 0         self._client.get_token()
705 0         try:
706 0             op_data = heal_dict
707 0             if timeout:
708 0                 op_data["timeout_ns_heal"] = timeout
709 0             op_id = self.exec_op(ns_name, op_name="heal", op_data=op_data, wait=wait)
710 0             print(str(op_id))
711 0         except ClientException as exc:
712 0             message = "failed to heal ns {}:\nerror:\n{}".format(ns_name, str(exc))
713 0             raise ClientException(message)