Add support cnf auto scale via threshold interface
Add the Performance Management Threshold CLI to support AutoScale. The Performance Management Threshold API is based on ETSI NFV-SOL 002 v3.3.1 and ETSI NFV-SOL 003 v3.3.1, which is Version "2.0.0" API of Tacker. Implements: blueprint support-auto-lcm Change-Id: Idd313d6abe47dfa41fc86ddc614d00f99f3fc3b2
This commit is contained in:
		| @@ -110,3 +110,8 @@ of individual command can be referred by **openstack help <command-name>**. | |||||||
|    openstack vnfpm job update                      Update PM job. |    openstack vnfpm job update                      Update PM job. | ||||||
|    openstack vnfpm job delete                      Delete PM job. |    openstack vnfpm job delete                      Delete PM job. | ||||||
|    openstack vnfpm report show                     Show PM report. |    openstack vnfpm report show                     Show PM report. | ||||||
|  |    openstack vnfpm threshold create                Create PM threshold. | ||||||
|  |    openstack vnfpm threshold list                  List PM threshold. | ||||||
|  |    openstack vnfpm threshold show                  Show PM threshold. | ||||||
|  |    openstack vnfpm threshold update                Update PM threshold. | ||||||
|  |    openstack vnfpm threshold delete                Delete PM threshold. | ||||||
|   | |||||||
| @@ -137,6 +137,11 @@ openstack.tackerclient.v2 = | |||||||
|      vnfpm_job_update = tackerclient.osc.v2.vnfpm.vnfpm_job:UpdateVnfPmJob |      vnfpm_job_update = tackerclient.osc.v2.vnfpm.vnfpm_job:UpdateVnfPmJob | ||||||
|      vnfpm_job_delete = tackerclient.osc.v2.vnfpm.vnfpm_job:DeleteVnfPmJob |      vnfpm_job_delete = tackerclient.osc.v2.vnfpm.vnfpm_job:DeleteVnfPmJob | ||||||
|      vnfpm_report_show = tackerclient.osc.v2.vnfpm.vnfpm_report:ShowVnfPmReport |      vnfpm_report_show = tackerclient.osc.v2.vnfpm.vnfpm_report:ShowVnfPmReport | ||||||
|  |      vnfpm_threshold_create = tackerclient.osc.v2.vnfpm.vnfpm_threshold:CreateVnfPmThreshold | ||||||
|  |      vnfpm_threshold_list = tackerclient.osc.v2.vnfpm.vnfpm_threshold:ListVnfPmThreshold | ||||||
|  |      vnfpm_threshold_show = tackerclient.osc.v2.vnfpm.vnfpm_threshold:ShowVnfPmThreshold | ||||||
|  |      vnfpm_threshold_update = tackerclient.osc.v2.vnfpm.vnfpm_threshold:UpdateVnfPmThreshold | ||||||
|  |      vnfpm_threshold_delete = tackerclient.osc.v2.vnfpm.vnfpm_threshold:DeleteVnfPmThreshold | ||||||
|      vnffm_alarm_list = tackerclient.osc.v2.vnffm.vnffm_alarm:ListVnfFmAlarm |      vnffm_alarm_list = tackerclient.osc.v2.vnffm.vnffm_alarm:ListVnfFmAlarm | ||||||
|      vnffm_alarm_show = tackerclient.osc.v2.vnffm.vnffm_alarm:ShowVnfFmAlarm |      vnffm_alarm_show = tackerclient.osc.v2.vnffm.vnffm_alarm:ShowVnfFmAlarm | ||||||
|      vnffm_alarm_update = tackerclient.osc.v2.vnffm.vnffm_alarm:UpdateVnfFmAlarm |      vnffm_alarm_update = tackerclient.osc.v2.vnffm.vnffm_alarm:UpdateVnfFmAlarm | ||||||
|   | |||||||
| @@ -20,7 +20,9 @@ Stuffs specific to tackerclient OSC plugin should not be added | |||||||
| to this module. They should go to tackerclient.osc.v1.utils. | to this module. They should go to tackerclient.osc.v1.utils. | ||||||
| """ | """ | ||||||
|  |  | ||||||
|  | import json | ||||||
| import operator | import operator | ||||||
|  | import os | ||||||
|  |  | ||||||
| from cliff import columns as cliff_columns | from cliff import columns as cliff_columns | ||||||
| from keystoneclient import exceptions as identity_exc | from keystoneclient import exceptions as identity_exc | ||||||
| @@ -29,6 +31,7 @@ from keystoneclient.v3 import projects | |||||||
| from osc_lib import utils | from osc_lib import utils | ||||||
| from oslo_serialization import jsonutils | from oslo_serialization import jsonutils | ||||||
|  |  | ||||||
|  | from tackerclient.common import exceptions | ||||||
| from tackerclient.i18n import _ | from tackerclient.i18n import _ | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -212,3 +215,29 @@ class FormatComplexDataColumn(cliff_columns.FormattableColumn): | |||||||
|  |  | ||||||
|     def human_readable(self): |     def human_readable(self): | ||||||
|         return format_dict_with_indention(self._value) |         return format_dict_with_indention(self._value) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def jsonfile2body(file_path): | ||||||
|  |  | ||||||
|  |     if file_path is None: | ||||||
|  |         msg = _("File %s does not exist") | ||||||
|  |         reason = msg % file_path | ||||||
|  |         raise exceptions.InvalidInput(reason=reason) | ||||||
|  |  | ||||||
|  |     if os.access(file_path, os.R_OK) is False: | ||||||
|  |         msg = _("User does not have read privileges to it") | ||||||
|  |         raise exceptions.InvalidInput(reason=msg) | ||||||
|  |  | ||||||
|  |     try: | ||||||
|  |         with open(file_path) as f: | ||||||
|  |             body = json.load(f) | ||||||
|  |     except (IOError, ValueError) as ex: | ||||||
|  |         msg = _("Failed to load parameter file. Error: %s") | ||||||
|  |         reason = msg % ex | ||||||
|  |         raise exceptions.InvalidInput(reason=reason) | ||||||
|  |  | ||||||
|  |     if not body: | ||||||
|  |         reason = _('The parameter file is empty') | ||||||
|  |         raise exceptions.EmptyInput(reason=reason) | ||||||
|  |  | ||||||
|  |     return body | ||||||
|   | |||||||
| @@ -13,9 +13,7 @@ | |||||||
| #    License for the specific language governing permissions and limitations | #    License for the specific language governing permissions and limitations | ||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import json |  | ||||||
| import logging | import logging | ||||||
| import os |  | ||||||
| import time | import time | ||||||
|  |  | ||||||
| from osc_lib.command import command | from osc_lib.command import command | ||||||
| @@ -113,7 +111,7 @@ class CreateVnfLcm(command.ShowOne): | |||||||
|         body = {} |         body = {} | ||||||
|  |  | ||||||
|         if file_path: |         if file_path: | ||||||
|             return jsonfile2body(file_path) |             return tacker_osc_utils.jsonfile2body(file_path) | ||||||
|  |  | ||||||
|         body['vnfdId'] = parsed_args.vnfd_id |         body['vnfdId'] = parsed_args.vnfd_id | ||||||
|  |  | ||||||
| @@ -184,29 +182,6 @@ class ListVnfLcm(command.Lister): | |||||||
|                 ) for s in vnf_instances)) |                 ) for s in vnf_instances)) | ||||||
|  |  | ||||||
|  |  | ||||||
| def jsonfile2body(file_path): |  | ||||||
|  |  | ||||||
|     if file_path is not None and os.access(file_path, os.R_OK) is False: |  | ||||||
|         msg = _("File %s does not exist or user does not have read " |  | ||||||
|                 "privileges to it") |  | ||||||
|         reason = msg % file_path |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     try: |  | ||||||
|         with open(file_path) as f: |  | ||||||
|             body = json.load(f) |  | ||||||
|     except (IOError, ValueError) as ex: |  | ||||||
|         msg = _("Failed to load parameter file. Error: %s") |  | ||||||
|         reason = msg % ex |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     if not body: |  | ||||||
|         reason = _('The parameter file is empty') |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     return body |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class InstantiateVnfLcm(command.Command): | class InstantiateVnfLcm(command.Command): | ||||||
|     _description = _("Instantiate a VNF Instance") |     _description = _("Instantiate a VNF Instance") | ||||||
|  |  | ||||||
| @@ -226,7 +201,7 @@ class InstantiateVnfLcm(command.Command): | |||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|         client = self.app.client_manager.tackerclient |         client = self.app.client_manager.tackerclient | ||||||
|         result = client.instantiate_vnf_instance( |         result = client.instantiate_vnf_instance( | ||||||
|             parsed_args.vnf_instance, jsonfile2body( |             parsed_args.vnf_instance, tacker_osc_utils.jsonfile2body( | ||||||
|                 parsed_args.instantiation_request_file)) |                 parsed_args.instantiation_request_file)) | ||||||
|         if not result: |         if not result: | ||||||
|             print((_('Instantiate request for VNF Instance %(id)s has been' |             print((_('Instantiate request for VNF Instance %(id)s has been' | ||||||
| @@ -271,7 +246,8 @@ class HealVnfLcm(command.Command): | |||||||
|         if parsed_args.vnfc_instance: |         if parsed_args.vnfc_instance: | ||||||
|             body['vnfcInstanceId'] = parsed_args.vnfc_instance |             body['vnfcInstanceId'] = parsed_args.vnfc_instance | ||||||
|         if parsed_args.additional_param_file: |         if parsed_args.additional_param_file: | ||||||
|             body.update(jsonfile2body(parsed_args.additional_param_file)) |             body.update(tacker_osc_utils.jsonfile2body( | ||||||
|  |                 parsed_args.additional_param_file)) | ||||||
|  |  | ||||||
|         return body |         return body | ||||||
|  |  | ||||||
| @@ -461,7 +437,7 @@ class UpdateVnfLcm(command.Command): | |||||||
|         body = {} |         body = {} | ||||||
|  |  | ||||||
|         if file_path: |         if file_path: | ||||||
|             return jsonfile2body(file_path) |             return tacker_osc_utils.jsonfile2body(file_path) | ||||||
|  |  | ||||||
|         return body |         return body | ||||||
|  |  | ||||||
| @@ -535,7 +511,8 @@ class ScaleVnfLcm(command.Command): | |||||||
|             body['numberOfSteps'] = parsed_args.number_of_steps |             body['numberOfSteps'] = parsed_args.number_of_steps | ||||||
|  |  | ||||||
|         if parsed_args.additional_param_file: |         if parsed_args.additional_param_file: | ||||||
|             body.update(jsonfile2body(parsed_args.additional_param_file)) |             body.update(tacker_osc_utils.jsonfile2body( | ||||||
|  |                 parsed_args.additional_param_file)) | ||||||
|  |  | ||||||
|         return body |         return body | ||||||
|  |  | ||||||
| @@ -574,7 +551,7 @@ class ChangeExtConnVnfLcm(command.Command): | |||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|         client = self.app.client_manager.tackerclient |         client = self.app.client_manager.tackerclient | ||||||
|         result = client.change_ext_conn_vnf_instance( |         result = client.change_ext_conn_vnf_instance( | ||||||
|             parsed_args.vnf_instance, jsonfile2body( |             parsed_args.vnf_instance, tacker_osc_utils.jsonfile2body( | ||||||
|                 parsed_args.request_file)) |                 parsed_args.request_file)) | ||||||
|         if not result: |         if not result: | ||||||
|             print((_('Change External VNF Connectivity for VNF Instance %s ' |             print((_('Change External VNF Connectivity for VNF Instance %s ' | ||||||
| @@ -601,7 +578,7 @@ class ChangeVnfPkgVnfLcm(command.Command): | |||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|         client = self.app.client_manager.tackerclient |         client = self.app.client_manager.tackerclient | ||||||
|         result = client.change_vnfpkg_vnf_instance( |         result = client.change_vnfpkg_vnf_instance( | ||||||
|             parsed_args.vnf_instance, jsonfile2body( |             parsed_args.vnf_instance, tacker_osc_utils.jsonfile2body( | ||||||
|                 parsed_args.request_file)) |                 parsed_args.request_file)) | ||||||
|         if not result: |         if not result: | ||||||
|             print((_('Change Current VNF Package for VNF Instance %s ' |             print((_('Change Current VNF Package for VNF Instance %s ' | ||||||
|   | |||||||
| @@ -13,9 +13,7 @@ | |||||||
| #    License for the specific language governing permissions and limitations | #    License for the specific language governing permissions and limitations | ||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import json |  | ||||||
| import logging | import logging | ||||||
| import os |  | ||||||
|  |  | ||||||
| from osc_lib.command import command | from osc_lib.command import command | ||||||
| from osc_lib import utils | from osc_lib import utils | ||||||
| @@ -49,29 +47,6 @@ def _get_columns(lccn_subsc_obj): | |||||||
|                                                            column_map) |                                                            column_map) | ||||||
|  |  | ||||||
|  |  | ||||||
| def jsonfile2body(file_path): |  | ||||||
|  |  | ||||||
|     if file_path is not None and os.access(file_path, os.R_OK) is False: |  | ||||||
|         msg = _("File %s does not exist or user does not have read " |  | ||||||
|                 "privileges to it") |  | ||||||
|         reason = msg % file_path |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     try: |  | ||||||
|         with open(file_path) as f: |  | ||||||
|             body = json.load(f) |  | ||||||
|     except (IOError, ValueError) as ex: |  | ||||||
|         msg = _("Failed to load parameter file. Error: %s") |  | ||||||
|         reason = msg % ex |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     if not body: |  | ||||||
|         reason = _('The parameter file is empty') |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     return body |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CreateLccnSubscription(command.ShowOne): | class CreateLccnSubscription(command.ShowOne): | ||||||
|     _description = _("Create a new Lccn Subscription") |     _description = _("Create a new Lccn Subscription") | ||||||
|  |  | ||||||
| @@ -86,7 +61,7 @@ class CreateLccnSubscription(command.ShowOne): | |||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|         client = self.app.client_manager.tackerclient |         client = self.app.client_manager.tackerclient | ||||||
|         subsc = client.create_lccn_subscription( |         subsc = client.create_lccn_subscription( | ||||||
|             jsonfile2body(parsed_args.create_request_file)) |             tacker_osc_utils.jsonfile2body(parsed_args.create_request_file)) | ||||||
|         display_columns, columns = _get_columns(subsc) |         display_columns, columns = _get_columns(subsc) | ||||||
|         data = utils.get_item_properties(sdk_utils.DictModel(subsc), |         data = utils.get_item_properties(sdk_utils.DictModel(subsc), | ||||||
|                                          columns, formatters=_FORMATTERS, |                                          columns, formatters=_FORMATTERS, | ||||||
|   | |||||||
| @@ -13,9 +13,7 @@ | |||||||
| #    License for the specific language governing permissions and limitations | #    License for the specific language governing permissions and limitations | ||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import json |  | ||||||
| import logging | import logging | ||||||
| import os |  | ||||||
|  |  | ||||||
| from osc_lib.command import command | from osc_lib.command import command | ||||||
| from osc_lib import utils | from osc_lib import utils | ||||||
| @@ -56,32 +54,6 @@ def _get_columns(vnffm_sub_obj): | |||||||
|         vnffm_sub_obj, column_map) |         vnffm_sub_obj, column_map) | ||||||
|  |  | ||||||
|  |  | ||||||
| def jsonfile2body(file_path): |  | ||||||
|  |  | ||||||
|     if file_path is None: |  | ||||||
|         msg = _("File %s does not exist") |  | ||||||
|         reason = msg % file_path |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     if os.access(file_path, os.R_OK) is False: |  | ||||||
|         msg = _("User does not have read privileges to it") |  | ||||||
|         raise exceptions.InvalidInput(reason=msg) |  | ||||||
|  |  | ||||||
|     try: |  | ||||||
|         with open(file_path) as f: |  | ||||||
|             body = json.load(f) |  | ||||||
|     except (IOError, ValueError) as ex: |  | ||||||
|         msg = _("Failed to load parameter file. Error: %s") |  | ||||||
|         reason = msg % ex |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     if not body: |  | ||||||
|         reason = _('The parameter file is empty') |  | ||||||
|         raise exceptions.EmptyInput(reason=reason) |  | ||||||
|  |  | ||||||
|     return body |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CreateVnfFmSub(command.ShowOne): | class CreateVnfFmSub(command.ShowOne): | ||||||
|     _description = _("Create a new VNF FM subscription") |     _description = _("Create a new VNF FM subscription") | ||||||
|  |  | ||||||
| @@ -97,7 +69,7 @@ class CreateVnfFmSub(command.ShowOne): | |||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|         client = self.app.client_manager.tackerclient |         client = self.app.client_manager.tackerclient | ||||||
|         vnf_fm_sub = client.create_vnf_fm_sub( |         vnf_fm_sub = client.create_vnf_fm_sub( | ||||||
|             jsonfile2body(parsed_args.request_file)) |             tacker_osc_utils.jsonfile2body(parsed_args.request_file)) | ||||||
|         display_columns, columns = _get_columns(vnf_fm_sub) |         display_columns, columns = _get_columns(vnf_fm_sub) | ||||||
|         data = utils.get_item_properties( |         data = utils.get_item_properties( | ||||||
|             sdk_utils.DictModel(vnf_fm_sub), columns, |             sdk_utils.DictModel(vnf_fm_sub), columns, | ||||||
|   | |||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | { | ||||||
|  |     "objectType": "Vnfc", | ||||||
|  |     "objectInstanceId": "object-instance-id-1", | ||||||
|  |     "subObjectInstanceIds": [ | ||||||
|  |         "sub-object-instance-id-2" | ||||||
|  |     ], | ||||||
|  |     "criteria": { | ||||||
|  |         "performanceMetric": "VCpuUsageMeanVnf.object-instance-id-1", | ||||||
|  |         "thresholdType": "SIMPLE", | ||||||
|  |         "simpleThresholdDetails": { | ||||||
|  |             "thresholdValue": 400.5, | ||||||
|  |             "hysteresis": 10.3 | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "callbackUri": "/nfvo/notify/threshold", | ||||||
|  |     "authentication": { | ||||||
|  |         "authType": [ | ||||||
|  |             "BASIC", | ||||||
|  |             "OAUTH2_CLIENT_CREDENTIALS", | ||||||
|  |             "OAUTH2_CLIENT_CERT" | ||||||
|  |         ], | ||||||
|  |         "paramsBasic": { | ||||||
|  |             "userName": "nfvo", | ||||||
|  |             "password": "nfvopwd" | ||||||
|  |         }, | ||||||
|  |         "paramsOauth2ClientCredentials": { | ||||||
|  |             "clientId": "auth_user_name", | ||||||
|  |             "clientPassword": "auth_password", | ||||||
|  |             "tokenEndpoint": "token_endpoint" | ||||||
|  |         }, | ||||||
|  |         "paramsOauth2ClientCert": { | ||||||
|  |             "clientId": "test", | ||||||
|  |             "certificateRef": { | ||||||
|  |                 "type": "x5t#256", | ||||||
|  |                 "value": "03c6e188d1fe5d3da8c9bc9a8dc531a2b3e" | ||||||
|  |             }, | ||||||
|  |             "tokenEndpoint": "http://127.0.0.1/token" | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,27 @@ | |||||||
|  | { | ||||||
|  |     "callbackUri": "/nfvo/notify/threshold", | ||||||
|  |     "authentication": { | ||||||
|  |         "authType": [ | ||||||
|  |             "BASIC", | ||||||
|  |             "OAUTH2_CLIENT_CREDENTIALS", | ||||||
|  |             "OAUTH2_CLIENT_CERT" | ||||||
|  |         ], | ||||||
|  |         "paramsBasic": { | ||||||
|  |             "userName": "nfvo", | ||||||
|  |             "password": "nfvopwd" | ||||||
|  |         }, | ||||||
|  |         "paramsOauth2ClientCredentials": { | ||||||
|  |             "clientId": "auth_user_name", | ||||||
|  |             "clientPassword": "auth_password", | ||||||
|  |             "tokenEndpoint": "token_endpoint" | ||||||
|  |         }, | ||||||
|  |         "paramsOauth2ClientCert": { | ||||||
|  |             "clientId": "test", | ||||||
|  |             "certificateRef": { | ||||||
|  |                 "type": "x5t#256", | ||||||
|  |                 "value": "03c6e188d1fe5d3da8c9bc9a8dc531a2b3e" | ||||||
|  |             }, | ||||||
|  |             "tokenEndpoint": "http://127.0.0.1/token" | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -13,9 +13,7 @@ | |||||||
| #    License for the specific language governing permissions and limitations | #    License for the specific language governing permissions and limitations | ||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import json |  | ||||||
| import logging | import logging | ||||||
| import os |  | ||||||
|  |  | ||||||
| from functools import reduce | from functools import reduce | ||||||
| from osc_lib.command import command | from osc_lib.command import command | ||||||
| @@ -78,32 +76,6 @@ def _get_columns(vnfpm_job_obj, action=None): | |||||||
|         vnfpm_job_obj, column_map) |         vnfpm_job_obj, column_map) | ||||||
|  |  | ||||||
|  |  | ||||||
| def jsonfile2body(file_path): |  | ||||||
|  |  | ||||||
|     if file_path is None: |  | ||||||
|         msg = _("File %s does not exist") |  | ||||||
|         reason = msg % file_path |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     if os.access(file_path, os.R_OK) is False: |  | ||||||
|         msg = _("User does not have read privileges to it") |  | ||||||
|         raise exceptions.InvalidInput(reason=msg) |  | ||||||
|  |  | ||||||
|     try: |  | ||||||
|         with open(file_path) as f: |  | ||||||
|             body = json.load(f) |  | ||||||
|     except (IOError, ValueError) as ex: |  | ||||||
|         msg = _("Failed to load parameter file. Error: %s") |  | ||||||
|         reason = msg % ex |  | ||||||
|         raise exceptions.InvalidInput(reason=reason) |  | ||||||
|  |  | ||||||
|     if not body: |  | ||||||
|         reason = _('The parameter file is empty') |  | ||||||
|         raise exceptions.EmptyInput(reason=reason) |  | ||||||
|  |  | ||||||
|     return body |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CreateVnfPmJob(command.ShowOne): | class CreateVnfPmJob(command.ShowOne): | ||||||
|     _description = _("Create a new VNF PM job") |     _description = _("Create a new VNF PM job") | ||||||
|  |  | ||||||
| @@ -119,7 +91,7 @@ class CreateVnfPmJob(command.ShowOne): | |||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|         client = self.app.client_manager.tackerclient |         client = self.app.client_manager.tackerclient | ||||||
|         vnf_pm_job = client.create_vnf_pm_job( |         vnf_pm_job = client.create_vnf_pm_job( | ||||||
|             jsonfile2body(parsed_args.request_file)) |             tacker_osc_utils.jsonfile2body(parsed_args.request_file)) | ||||||
|         display_columns, columns = _get_columns(vnf_pm_job) |         display_columns, columns = _get_columns(vnf_pm_job) | ||||||
|         data = utils.get_item_properties( |         data = utils.get_item_properties( | ||||||
|             sdk_utils.DictModel(vnf_pm_job), columns, |             sdk_utils.DictModel(vnf_pm_job), columns, | ||||||
| @@ -284,7 +256,7 @@ class UpdateVnfPmJob(command.ShowOne): | |||||||
|         client = self.app.client_manager.tackerclient |         client = self.app.client_manager.tackerclient | ||||||
|         updated_values = client.update_vnf_pm_job( |         updated_values = client.update_vnf_pm_job( | ||||||
|             parsed_args.vnf_pm_job_id, |             parsed_args.vnf_pm_job_id, | ||||||
|             jsonfile2body(parsed_args.request_file)) |             tacker_osc_utils.jsonfile2body(parsed_args.request_file)) | ||||||
|         display_columns, columns = _get_columns(updated_values, 'update') |         display_columns, columns = _get_columns(updated_values, 'update') | ||||||
|         data = utils.get_item_properties( |         data = utils.get_item_properties( | ||||||
|             sdk_utils.DictModel(updated_values), |             sdk_utils.DictModel(updated_values), | ||||||
|   | |||||||
							
								
								
									
										216
									
								
								tackerclient/osc/v2/vnfpm/vnfpm_threshold.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								tackerclient/osc/v2/vnfpm/vnfpm_threshold.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,216 @@ | |||||||
|  | # Copyright (C) 2023 Fujitsu | ||||||
|  | # All Rights Reserved. | ||||||
|  | # | ||||||
|  | #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||||
|  | #    not use this file except in compliance with the License. You may obtain | ||||||
|  | #    a copy of the License at | ||||||
|  | # | ||||||
|  | #         http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | #    Unless required by applicable law or agreed to in writing, software | ||||||
|  | #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
|  | #    License for the specific language governing permissions and limitations | ||||||
|  | #    under the License. | ||||||
|  |  | ||||||
|  | import logging | ||||||
|  |  | ||||||
|  | from osc_lib.command import command | ||||||
|  | from osc_lib import utils | ||||||
|  |  | ||||||
|  | from tackerclient.common import exceptions | ||||||
|  | from tackerclient.i18n import _ | ||||||
|  | from tackerclient.osc import sdk_utils | ||||||
|  | from tackerclient.osc import utils as tacker_osc_utils | ||||||
|  |  | ||||||
|  | LOG = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  | _ATTR_MAP = ( | ||||||
|  |     ('id', 'ID', tacker_osc_utils.LIST_BOTH), | ||||||
|  |     ('objectType', 'Object Type', tacker_osc_utils.LIST_BOTH), | ||||||
|  |     ('_links', 'Links', tacker_osc_utils.LIST_BOTH) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _FORMATTERS = { | ||||||
|  |     'subObjectInstanceIds': tacker_osc_utils.FormatComplexDataColumn, | ||||||
|  |     'criteria': tacker_osc_utils.FormatComplexDataColumn, | ||||||
|  |     '_links': tacker_osc_utils.FormatComplexDataColumn | ||||||
|  | } | ||||||
|  |  | ||||||
|  | _MIXED_CASE_FIELDS = ( | ||||||
|  |     'objectType', 'objectInstanceId', 'subObjectInstanceIds', 'callbackUri' | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _MIXED_CASE_FIELDS_UPDATE = ( | ||||||
|  |     'callbackUri' | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _VNF_PM_THRESHOLD_ID = 'vnf_pm_threshold_id' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _get_columns(vnf_pm_threshold, action=None): | ||||||
|  |     if action == 'update': | ||||||
|  |         column_map = { | ||||||
|  |             'callbackUri': 'Callback Uri' | ||||||
|  |         } | ||||||
|  |     else: | ||||||
|  |         column_map = { | ||||||
|  |             'id': 'ID', | ||||||
|  |             'objectType': 'Object Type', | ||||||
|  |             'objectInstanceId': 'Object Instance Id', | ||||||
|  |             'subObjectInstanceIds': 'Sub Object Instance Ids', | ||||||
|  |             'criteria': 'Criteria', | ||||||
|  |             'callbackUri': 'Callback Uri', | ||||||
|  |             '_links': 'Links' | ||||||
|  |         } | ||||||
|  |     return sdk_utils.get_osc_show_columns_for_sdk_resource( | ||||||
|  |         vnf_pm_threshold, column_map) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CreateVnfPmThreshold(command.ShowOne): | ||||||
|  |     _description = _("Create a new VNF PM threshold") | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         LOG.debug('get_parser(%s)', prog_name) | ||||||
|  |         parser = super(CreateVnfPmThreshold, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'request_file', | ||||||
|  |             metavar="<param-file>", | ||||||
|  |             help=_('Specify create VNF PM threshold request ' | ||||||
|  |                    'parameters in a json file.')) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         client = self.app.client_manager.tackerclient | ||||||
|  |         vnf_pm_threshold = client.create_vnf_pm_threshold( | ||||||
|  |             tacker_osc_utils.jsonfile2body(parsed_args.request_file)) | ||||||
|  |         display_columns, columns = _get_columns(vnf_pm_threshold) | ||||||
|  |         data = utils.get_item_properties( | ||||||
|  |             sdk_utils.DictModel(vnf_pm_threshold), columns, | ||||||
|  |             formatters=_FORMATTERS, mixed_case_fields=_MIXED_CASE_FIELDS) | ||||||
|  |         return (display_columns, data) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ListVnfPmThreshold(command.Lister): | ||||||
|  |     _description = _("List VNF PM thresholds") | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         LOG.debug('get_parser(%s)', prog_name) | ||||||
|  |         parser = super(ListVnfPmThreshold, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "--filter", | ||||||
|  |             metavar="<filter>", | ||||||
|  |             help=_("Attribute-based-filtering parameters"), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         _params = {} | ||||||
|  |  | ||||||
|  |         if parsed_args.filter: | ||||||
|  |             _params['filter'] = parsed_args.filter | ||||||
|  |  | ||||||
|  |         client = self.app.client_manager.tackerclient | ||||||
|  |         data = client.list_vnf_pm_thresholds(**_params) | ||||||
|  |         headers, columns = tacker_osc_utils.get_column_definitions( | ||||||
|  |             _ATTR_MAP, long_listing=True) | ||||||
|  |         return (headers, | ||||||
|  |                 (utils.get_dict_properties( | ||||||
|  |                     s, columns, formatters=_FORMATTERS, | ||||||
|  |                     mixed_case_fields=_MIXED_CASE_FIELDS, | ||||||
|  |                 ) for s in data['vnf_pm_thresholds'])) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ShowVnfPmThreshold(command.ShowOne): | ||||||
|  |     _description = _("Display VNF PM threshold details") | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         LOG.debug('get_parser(%s)', prog_name) | ||||||
|  |         parser = super(ShowVnfPmThreshold, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             _VNF_PM_THRESHOLD_ID, | ||||||
|  |             metavar="<vnf-pm-threshold-id>", | ||||||
|  |             help=_("VNF PM threshold ID to display")) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         client = self.app.client_manager.tackerclient | ||||||
|  |         obj = client.show_vnf_pm_threshold(parsed_args.vnf_pm_threshold_id) | ||||||
|  |         display_columns, columns = _get_columns(obj) | ||||||
|  |         data = utils.get_item_properties( | ||||||
|  |             sdk_utils.DictModel(obj), columns, | ||||||
|  |             mixed_case_fields=_MIXED_CASE_FIELDS, | ||||||
|  |             formatters=_FORMATTERS) | ||||||
|  |         return (display_columns, data) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class UpdateVnfPmThreshold(command.ShowOne): | ||||||
|  |     _description = _("Update information about an individual VNF PM threshold") | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         LOG.debug('get_parser(%s)', prog_name) | ||||||
|  |         parser = super(UpdateVnfPmThreshold, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             _VNF_PM_THRESHOLD_ID, | ||||||
|  |             metavar="<vnf-pm-threshold-id>", | ||||||
|  |             help=_("VNF PM threshold ID to update.") | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'request_file', | ||||||
|  |             metavar="<param-file>", | ||||||
|  |             help=_('Specify update PM threshold request ' | ||||||
|  |                    'parameters in a json file.')) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         client = self.app.client_manager.tackerclient | ||||||
|  |         updated_values = client.update_vnf_pm_threshold( | ||||||
|  |             parsed_args.vnf_pm_threshold_id, | ||||||
|  |             tacker_osc_utils.jsonfile2body(parsed_args.request_file)) | ||||||
|  |         display_columns, columns = _get_columns(updated_values, 'update') | ||||||
|  |         data = utils.get_item_properties( | ||||||
|  |             sdk_utils.DictModel(updated_values), columns, | ||||||
|  |             mixed_case_fields=_MIXED_CASE_FIELDS_UPDATE) | ||||||
|  |         return (display_columns, data) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class DeleteVnfPmThreshold(command.Command): | ||||||
|  |     _description = _("Delete VNF PM threshold") | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         LOG.debug('get_parser(%s)', prog_name) | ||||||
|  |         parser = super(DeleteVnfPmThreshold, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             _VNF_PM_THRESHOLD_ID, | ||||||
|  |             metavar="<vnf-pm-threshold-id>", | ||||||
|  |             nargs="+", | ||||||
|  |             help=_("VNF PM threshold ID(s) to delete")) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         error_count = 0 | ||||||
|  |         client = self.app.client_manager.tackerclient | ||||||
|  |         vnf_pm_threshold_ids = parsed_args.vnf_pm_threshold_id | ||||||
|  |  | ||||||
|  |         for threshold_id in vnf_pm_threshold_ids: | ||||||
|  |             try: | ||||||
|  |                 client.delete_vnf_pm_threshold(threshold_id) | ||||||
|  |             except Exception as e: | ||||||
|  |                 error_count += 1 | ||||||
|  |                 LOG.error(_("Failed to delete VNF PM threshold with " | ||||||
|  |                             "ID '%(threshold_id)s': %(e)s"), | ||||||
|  |                           {'threshold_id': threshold_id, 'e': e}) | ||||||
|  |  | ||||||
|  |         total = len(vnf_pm_threshold_ids) | ||||||
|  |         if error_count > 0: | ||||||
|  |             msg = (_("Failed to delete %(error_count)s of %(total)s " | ||||||
|  |                      "VNF PM thresholds.") % | ||||||
|  |                    {'error_count': error_count, 'total': total}) | ||||||
|  |             raise exceptions.CommandError(message=msg) | ||||||
|  |  | ||||||
|  |         if total > 1: | ||||||
|  |             print(_('All specified VNF PM thresholds are deleted ' | ||||||
|  |                     'successfully')) | ||||||
|  |             return | ||||||
|  |         print(_("VNF PM threshold '%s' deleted " | ||||||
|  |                 "successfully") % vnf_pm_threshold_ids[0]) | ||||||
| @@ -297,9 +297,9 @@ class TestInstantiateVnfLcm(TestVnfLcm): | |||||||
|                                self.instantiate_vnf_lcm.take_action, |                                self.instantiate_vnf_lcm.take_action, | ||||||
|                                parsed_args) |                                parsed_args) | ||||||
|  |  | ||||||
|         expected_msg = ("Invalid input: File %s does not exist " |         expected_msg = ("Invalid input: " | ||||||
|                         "or user does not have read privileges to it") |                         "User does not have read privileges to it") | ||||||
|         self.assertEqual(expected_msg % sample_param_file, str(ex)) |         self.assertEqual(expected_msg, str(ex)) | ||||||
|  |  | ||||||
|     @mock.patch("os.open") |     @mock.patch("os.open") | ||||||
|     @mock.patch("os.access") |     @mock.patch("os.access") | ||||||
| @@ -403,9 +403,9 @@ class TestHealVnfLcm(TestVnfLcm): | |||||||
|         ex = self.assertRaises(exceptions.InvalidInput, |         ex = self.assertRaises(exceptions.InvalidInput, | ||||||
|                                self.heal_vnf_lcm.take_action, parsed_args) |                                self.heal_vnf_lcm.take_action, parsed_args) | ||||||
|  |  | ||||||
|         expected_msg = ("Invalid input: File %s does not exist " |         expected_msg = ("Invalid input: " | ||||||
|                         "or user does not have read privileges to it") |                         "User does not have read privileges to it") | ||||||
|         self.assertEqual(expected_msg % sample_param_file, str(ex)) |         self.assertEqual(expected_msg, str(ex)) | ||||||
|  |  | ||||||
|  |  | ||||||
| @ddt.ddt | @ddt.ddt | ||||||
| @@ -774,9 +774,9 @@ class TestScaleVnfLcm(TestVnfLcm): | |||||||
|         ex = self.assertRaises(exceptions.InvalidInput, |         ex = self.assertRaises(exceptions.InvalidInput, | ||||||
|                                self.scale_vnf_lcm.take_action, parsed_args) |                                self.scale_vnf_lcm.take_action, parsed_args) | ||||||
|  |  | ||||||
|         expected_msg = ("Invalid input: File %s does not exist " |         expected_msg = ("Invalid input: " | ||||||
|                         "or user does not have read privileges to it") |                         "User does not have read privileges to it") | ||||||
|         self.assertEqual(expected_msg % sample_param_file, str(ex)) |         self.assertEqual(expected_msg, str(ex)) | ||||||
|  |  | ||||||
|     @ddt.data('SCALE_IN', 'SCALE_OUT') |     @ddt.data('SCALE_IN', 'SCALE_OUT') | ||||||
|     def test_take_action_vnf_instance_not_found(self, scale_type): |     def test_take_action_vnf_instance_not_found(self, scale_type): | ||||||
| @@ -888,9 +888,9 @@ class TestChangeExtConnVnfLcm(TestVnfLcm): | |||||||
|             self.change_ext_conn_vnf_lcm.take_action, |             self.change_ext_conn_vnf_lcm.take_action, | ||||||
|             parsed_args) |             parsed_args) | ||||||
|  |  | ||||||
|         expected_msg = ("Invalid input: File %s does not exist " |         expected_msg = ("Invalid input: " | ||||||
|                         "or user does not have read privileges to it") |                         "User does not have read privileges to it") | ||||||
|         self.assertEqual(expected_msg % sample_param_file, str(ex)) |         self.assertEqual(expected_msg, str(ex)) | ||||||
|  |  | ||||||
|     @mock.patch("os.open") |     @mock.patch("os.open") | ||||||
|     @mock.patch("os.access") |     @mock.patch("os.access") | ||||||
|   | |||||||
| @@ -121,9 +121,9 @@ class TestChangeVnfPkgVnfLcm(test_vnflcm.TestVnfLcm): | |||||||
|             self.change_vnfpkg_vnf_lcm.take_action, |             self.change_vnfpkg_vnf_lcm.take_action, | ||||||
|             parsed_args) |             parsed_args) | ||||||
|  |  | ||||||
|         expected_msg = ("Invalid input: File %s does not exist " |         expected_msg = ("Invalid input: " | ||||||
|                         "or user does not have read privileges to it") |                         "User does not have read privileges to it") | ||||||
|         self.assertEqual(expected_msg % sample_param_file, str(ex)) |         self.assertEqual(expected_msg, str(ex)) | ||||||
|  |  | ||||||
|     @mock.patch("os.open") |     @mock.patch("os.open") | ||||||
|     @mock.patch("os.access") |     @mock.patch("os.access") | ||||||
|   | |||||||
							
								
								
									
										398
									
								
								tackerclient/tests/unit/osc/v2/test_vnfpm_threshold.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										398
									
								
								tackerclient/tests/unit/osc/v2/test_vnfpm_threshold.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,398 @@ | |||||||
|  | # Copyright (C) 2023 Fujitsu | ||||||
|  | # All Rights Reserved. | ||||||
|  | # | ||||||
|  | #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||||
|  | #    not use this file except in compliance with the License. You may obtain | ||||||
|  | #    a copy of the License at | ||||||
|  | # | ||||||
|  | #         http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | #    Unless required by applicable law or agreed to in writing, software | ||||||
|  | #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
|  | #    License for the specific language governing permissions and limitations | ||||||
|  | #    under the License. | ||||||
|  |  | ||||||
|  | import ddt | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  |  | ||||||
|  | from io import StringIO | ||||||
|  | from oslo_utils.fixture import uuidsentinel | ||||||
|  | from unittest import mock | ||||||
|  |  | ||||||
|  | from tackerclient.common import exceptions | ||||||
|  | from tackerclient.osc import utils as tacker_osc_utils | ||||||
|  | from tackerclient.osc.v2.vnfpm import vnfpm_threshold | ||||||
|  | from tackerclient.tests.unit.osc import base | ||||||
|  | from tackerclient.tests.unit.osc.v1.fixture_data import client | ||||||
|  | from tackerclient.tests.unit.osc.v2 import vnfpm_threshold_fakes | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestVnfPmThreshold(base.FixturedTestCase): | ||||||
|  |     client_fixture_class = client.ClientFixture | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super(TestVnfPmThreshold, self).setUp() | ||||||
|  |         self.url = client.TACKER_URL | ||||||
|  |         self.header = {'content-type': 'application/json'} | ||||||
|  |         self.app = mock.Mock() | ||||||
|  |         self.app_args = mock.Mock() | ||||||
|  |         self.client_manager = self.cs | ||||||
|  |         self.app.client_manager.tackerclient = self.client_manager | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _get_columns_vnfpm_threshold(action=None): | ||||||
|  |     if action == 'update': | ||||||
|  |         columns = ['Callback Uri'] | ||||||
|  |     else: | ||||||
|  |         columns = ['ID', 'Object Type', 'Object Instance Id', | ||||||
|  |                    'Sub Object Instance Ids', 'Criteria', 'Callback Uri', | ||||||
|  |                    'Links'] | ||||||
|  |     if action == 'list': | ||||||
|  |         columns = [ | ||||||
|  |             'ID', 'Object Type', 'Links' | ||||||
|  |         ] | ||||||
|  |     return columns | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ddt.ddt | ||||||
|  | class TestCreateVnfPmThreshold(TestVnfPmThreshold): | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super(TestCreateVnfPmThreshold, self).setUp() | ||||||
|  |         self.create_vnf_pm_threshold = vnfpm_threshold.CreateVnfPmThreshold( | ||||||
|  |             self.app, self.app_args, cmd_name='vnfpm threshold create') | ||||||
|  |  | ||||||
|  |     def test_create_no_args(self): | ||||||
|  |         self.assertRaises(base.ParserException, self.check_parser, | ||||||
|  |                           self.create_vnf_pm_threshold, [], []) | ||||||
|  |  | ||||||
|  |     @ddt.unpack | ||||||
|  |     def test_take_action(self): | ||||||
|  |         param_file = ("./tackerclient/osc/v2/vnfpm/samples/" | ||||||
|  |                       "create_vnf_pm_threshold_param_sample.json") | ||||||
|  |  | ||||||
|  |         arg_list = [param_file] | ||||||
|  |         verify_list = [('request_file', param_file)] | ||||||
|  |  | ||||||
|  |         parsed_args = self.check_parser(self.create_vnf_pm_threshold, arg_list, | ||||||
|  |                                         verify_list) | ||||||
|  |  | ||||||
|  |         response_json = vnfpm_threshold_fakes.vnf_pm_threshold_response() | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'POST', os.path.join(self.url, 'vnfpm/v2/thresholds'), | ||||||
|  |             json=response_json, headers=self.header) | ||||||
|  |  | ||||||
|  |         actual_columns, data = ( | ||||||
|  |             self.create_vnf_pm_threshold.take_action(parsed_args)) | ||||||
|  |         self.assertCountEqual(_get_columns_vnfpm_threshold(), | ||||||
|  |                               actual_columns) | ||||||
|  |  | ||||||
|  |         _, attributes = vnfpm_threshold._get_columns(response_json) | ||||||
|  |         expected_data = vnfpm_threshold_fakes.get_vnfpm_threshold_data( | ||||||
|  |             response_json, columns=attributes) | ||||||
|  |         self.assertListItemsEqual(expected_data, data) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ddt.ddt | ||||||
|  | class TestListVnfPmThreshold(TestVnfPmThreshold): | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super(TestListVnfPmThreshold, self).setUp() | ||||||
|  |         self.list_vnf_pm_thresholds = vnfpm_threshold.ListVnfPmThreshold( | ||||||
|  |             self.app, self.app_args, cmd_name='vnfpm threshold list') | ||||||
|  |  | ||||||
|  |     def test_take_action(self): | ||||||
|  |         vnf_pm_threshold_objs = vnfpm_threshold_fakes.create_vnf_pm_thresholds( | ||||||
|  |             count=3) | ||||||
|  |         parsed_args = self.check_parser(self.list_vnf_pm_thresholds, [], []) | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'GET', | ||||||
|  |             os.path.join(self.url, 'vnfpm/v2/thresholds'), | ||||||
|  |             json=vnf_pm_threshold_objs, headers=self.header) | ||||||
|  |  | ||||||
|  |         actual_columns, data = self.list_vnf_pm_thresholds.take_action( | ||||||
|  |             parsed_args) | ||||||
|  |  | ||||||
|  |         _, columns = tacker_osc_utils.get_column_definitions( | ||||||
|  |             vnfpm_threshold._ATTR_MAP, long_listing=True) | ||||||
|  |  | ||||||
|  |         expected_data = [] | ||||||
|  |         for vnf_pm_threshold_obj_idx in vnf_pm_threshold_objs: | ||||||
|  |             expected_data.append( | ||||||
|  |                 vnfpm_threshold_fakes.get_vnfpm_threshold_data( | ||||||
|  |                     vnf_pm_threshold_obj_idx, columns=columns)) | ||||||
|  |  | ||||||
|  |         self.assertCountEqual(_get_columns_vnfpm_threshold(action='list'), | ||||||
|  |                               actual_columns) | ||||||
|  |         self.assertCountEqual(expected_data, list(data)) | ||||||
|  |  | ||||||
|  |     def test_take_action_with_filter(self): | ||||||
|  |         vnf_pm_threshold_objs = vnfpm_threshold_fakes.create_vnf_pm_thresholds( | ||||||
|  |             count=3) | ||||||
|  |         parsed_args = self.check_parser( | ||||||
|  |             self.list_vnf_pm_thresholds, | ||||||
|  |             ["--filter", '(eq,perceivedSeverity,WARNING)'], | ||||||
|  |             [('filter', '(eq,perceivedSeverity,WARNING)')]) | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'GET', os.path.join( | ||||||
|  |                 self.url, | ||||||
|  |                 'vnfpm/v2/thresholds?filter=(eq,perceivedSeverity,WARNING)'), | ||||||
|  |             json=vnf_pm_threshold_objs, headers=self.header) | ||||||
|  |  | ||||||
|  |         actual_columns, data = self.list_vnf_pm_thresholds.take_action( | ||||||
|  |             parsed_args) | ||||||
|  |  | ||||||
|  |         _, columns = tacker_osc_utils.get_column_definitions( | ||||||
|  |             vnfpm_threshold._ATTR_MAP, long_listing=True) | ||||||
|  |  | ||||||
|  |         expected_data = [] | ||||||
|  |         for vnf_pm_threshold_obj_idx in vnf_pm_threshold_objs: | ||||||
|  |             expected_data.append( | ||||||
|  |                 vnfpm_threshold_fakes.get_vnfpm_threshold_data( | ||||||
|  |                     vnf_pm_threshold_obj_idx, columns=columns)) | ||||||
|  |  | ||||||
|  |         self.assertCountEqual(_get_columns_vnfpm_threshold(action='list'), | ||||||
|  |                               actual_columns) | ||||||
|  |         self.assertListItemsEqual(expected_data, list(data)) | ||||||
|  |  | ||||||
|  |     def test_take_action_with_incorrect_filter(self): | ||||||
|  |         parsed_args = self.check_parser( | ||||||
|  |             self.list_vnf_pm_thresholds, | ||||||
|  |             ["--filter", '(perceivedSeverity)'], | ||||||
|  |             [('filter', '(perceivedSeverity)')]) | ||||||
|  |  | ||||||
|  |         url = os.path.join( | ||||||
|  |             self.url, 'vnfpm/v2/thresholds?filter=(perceivedSeverity)') | ||||||
|  |  | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'GET', url, headers=self.header, status_code=400, json={}) | ||||||
|  |  | ||||||
|  |         self.assertRaises(exceptions.TackerClientException, | ||||||
|  |                           self.list_vnf_pm_thresholds.take_action, | ||||||
|  |                           parsed_args) | ||||||
|  |  | ||||||
|  |     def test_take_action_internal_server_error(self): | ||||||
|  |         parsed_args = self.check_parser( | ||||||
|  |             self.list_vnf_pm_thresholds, | ||||||
|  |             ["--filter", '(eq,perceivedSeverity,WARNING)'], | ||||||
|  |             [('filter', '(eq,perceivedSeverity,WARNING)')]) | ||||||
|  |  | ||||||
|  |         url = os.path.join( | ||||||
|  |             self.url, | ||||||
|  |             'vnfpm/v2/thresholds?filter=(eq,perceivedSeverity,WARNING)') | ||||||
|  |  | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'GET', url, headers=self.header, status_code=500, json={}) | ||||||
|  |  | ||||||
|  |         self.assertRaises(exceptions.TackerClientException, | ||||||
|  |                           self.list_vnf_pm_thresholds.take_action, | ||||||
|  |                           parsed_args) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestShowVnfPmThreshold(TestVnfPmThreshold): | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super(TestShowVnfPmThreshold, self).setUp() | ||||||
|  |         self.show_vnf_pm_thresholds = vnfpm_threshold.ShowVnfPmThreshold( | ||||||
|  |             self.app, self.app_args, cmd_name='vnfpm threshold show') | ||||||
|  |  | ||||||
|  |     def test_take_action(self): | ||||||
|  |         vnfpm_threshold_obj = vnfpm_threshold_fakes.vnf_pm_threshold_response() | ||||||
|  |  | ||||||
|  |         arg_list = [vnfpm_threshold_obj['id']] | ||||||
|  |         verify_list = [('vnf_pm_threshold_id', vnfpm_threshold_obj['id'])] | ||||||
|  |  | ||||||
|  |         # command param | ||||||
|  |         parsed_args = self.check_parser( | ||||||
|  |             self.show_vnf_pm_thresholds, arg_list, verify_list) | ||||||
|  |         url = os.path.join( | ||||||
|  |             self.url, 'vnfpm/v2/thresholds', vnfpm_threshold_obj['id']) | ||||||
|  |  | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'GET', url, headers=self.header, json=vnfpm_threshold_obj) | ||||||
|  |  | ||||||
|  |         columns, data = (self.show_vnf_pm_thresholds.take_action(parsed_args)) | ||||||
|  |  | ||||||
|  |         self.assertCountEqual(_get_columns_vnfpm_threshold('show'), columns) | ||||||
|  |  | ||||||
|  |         _, attributes = vnfpm_threshold._get_columns(vnfpm_threshold_obj) | ||||||
|  |         self.assertListItemsEqual( | ||||||
|  |             vnfpm_threshold_fakes.get_vnfpm_threshold_data( | ||||||
|  |                 vnfpm_threshold_obj, columns=attributes), data) | ||||||
|  |  | ||||||
|  |     def test_take_action_vnf_pm_threshold_id_not_found(self): | ||||||
|  |         arg_list = [uuidsentinel.vnf_pm_threshold_id] | ||||||
|  |         verify_list = [('vnf_pm_threshold_id', | ||||||
|  |                         uuidsentinel.vnf_pm_threshold_id)] | ||||||
|  |  | ||||||
|  |         # command param | ||||||
|  |         parsed_args = self.check_parser( | ||||||
|  |             self.show_vnf_pm_thresholds, arg_list, verify_list) | ||||||
|  |  | ||||||
|  |         url = os.path.join( | ||||||
|  |             self.url, 'vnfpm/v2/thresholds', | ||||||
|  |             uuidsentinel.vnf_pm_threshold_id) | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'GET', url, headers=self.header, status_code=404, json={}) | ||||||
|  |  | ||||||
|  |         self.assertRaises(exceptions.TackerClientException, | ||||||
|  |                           self.show_vnf_pm_thresholds.take_action, | ||||||
|  |                           parsed_args) | ||||||
|  |  | ||||||
|  |     def test_take_action_internal_server_error(self): | ||||||
|  |         arg_list = [uuidsentinel.vnf_pm_threshold_id] | ||||||
|  |         verify_list = [('vnf_pm_threshold_id', | ||||||
|  |                         uuidsentinel.vnf_pm_threshold_id)] | ||||||
|  |  | ||||||
|  |         # command param | ||||||
|  |         parsed_args = self.check_parser( | ||||||
|  |             self.show_vnf_pm_thresholds, arg_list, verify_list) | ||||||
|  |  | ||||||
|  |         url = os.path.join( | ||||||
|  |             self.url, 'vnfpm/v2/thresholds', | ||||||
|  |             uuidsentinel.vnf_pm_threshold_id) | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'GET', url, headers=self.header, status_code=500, json={}) | ||||||
|  |  | ||||||
|  |         self.assertRaises(exceptions.TackerClientException, | ||||||
|  |                           self.show_vnf_pm_thresholds.take_action, | ||||||
|  |                           parsed_args) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ddt.ddt | ||||||
|  | class TestUpdateVnfPmThreshold(TestVnfPmThreshold): | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super(TestUpdateVnfPmThreshold, self).setUp() | ||||||
|  |         self.update_vnf_pm_threshold = vnfpm_threshold.UpdateVnfPmThreshold( | ||||||
|  |             self.app, self.app_args, cmd_name='vnfpm threshold update') | ||||||
|  |  | ||||||
|  |     def test_take_action(self): | ||||||
|  |         param_file = ("./tackerclient/osc/v2/vnfpm/samples/" | ||||||
|  |                       "update_vnf_pm_threshold_param_sample.json") | ||||||
|  |         arg_list = [uuidsentinel.vnf_pm_threshold_id, param_file] | ||||||
|  |         verify_list = [ | ||||||
|  |             ('vnf_pm_threshold_id', uuidsentinel.vnf_pm_threshold_id), | ||||||
|  |             ('request_file', param_file) | ||||||
|  |         ] | ||||||
|  |         vnfpm_threshold_obj = vnfpm_threshold_fakes.vnf_pm_threshold_response( | ||||||
|  |             None, 'update') | ||||||
|  |  | ||||||
|  |         # command param | ||||||
|  |         parsed_args = self.check_parser( | ||||||
|  |             self.update_vnf_pm_threshold, arg_list, verify_list) | ||||||
|  |         url = os.path.join( | ||||||
|  |             self.url, 'vnfpm/v2/thresholds', | ||||||
|  |             uuidsentinel.vnf_pm_threshold_id) | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'PATCH', url, headers=self.header, json=vnfpm_threshold_obj) | ||||||
|  |  | ||||||
|  |         actual_columns, data = ( | ||||||
|  |             self.update_vnf_pm_threshold.take_action(parsed_args)) | ||||||
|  |         expected_columns = _get_columns_vnfpm_threshold(action='update') | ||||||
|  |         self.assertCountEqual(expected_columns, actual_columns) | ||||||
|  |  | ||||||
|  |         _, columns = vnfpm_threshold._get_columns( | ||||||
|  |             vnfpm_threshold_obj, action='update') | ||||||
|  |         expected_data = vnfpm_threshold_fakes.get_vnfpm_threshold_data( | ||||||
|  |             vnfpm_threshold_obj, columns=columns) | ||||||
|  |         self.assertEqual(expected_data, data) | ||||||
|  |  | ||||||
|  |     def test_take_action_vnf_pm_threshold_id_not_found(self): | ||||||
|  |         param_file = ("./tackerclient/osc/v2/vnfpm/samples/" | ||||||
|  |                       "update_vnf_pm_threshold_param_sample.json") | ||||||
|  |         arg_list = [uuidsentinel.vnf_pm_threshold_id, param_file] | ||||||
|  |         verify_list = [ | ||||||
|  |             ('vnf_pm_threshold_id', uuidsentinel.vnf_pm_threshold_id), | ||||||
|  |             ('request_file', param_file) | ||||||
|  |         ] | ||||||
|  |  | ||||||
|  |         # command param | ||||||
|  |         parsed_args = self.check_parser( | ||||||
|  |             self.update_vnf_pm_threshold, arg_list, verify_list) | ||||||
|  |         url = os.path.join( | ||||||
|  |             self.url, 'vnfpm/v2/thresholds', | ||||||
|  |             uuidsentinel.vnf_pm_threshold_id) | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'PATCH', url, headers=self.header, status_code=404, json={}) | ||||||
|  |         self.assertRaises(exceptions.TackerClientException, | ||||||
|  |                           self.update_vnf_pm_threshold.take_action, | ||||||
|  |                           parsed_args) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestDeleteVnfPmThreshold(TestVnfPmThreshold): | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super(TestDeleteVnfPmThreshold, self).setUp() | ||||||
|  |         self.delete_vnf_pm_threshold = vnfpm_threshold.DeleteVnfPmThreshold( | ||||||
|  |             self.app, self.app_args, cmd_name='vnfpm threshold delete') | ||||||
|  |  | ||||||
|  |         # Vnf Pm threshold to delete | ||||||
|  |         self.vnf_pm_thresholds = ( | ||||||
|  |             vnfpm_threshold_fakes.create_vnf_pm_thresholds(count=3)) | ||||||
|  |  | ||||||
|  |     def _mock_request_url_for_delete(self, index): | ||||||
|  |         url = os.path.join(self.url, 'vnfpm/v2/thresholds', | ||||||
|  |                            self.vnf_pm_thresholds[index]['id']) | ||||||
|  |  | ||||||
|  |         self.requests_mock.register_uri('DELETE', url, | ||||||
|  |                                         headers=self.header, json={}) | ||||||
|  |  | ||||||
|  |     def test_delete_one_vnf_pm_threshold(self): | ||||||
|  |         arg_list = [self.vnf_pm_thresholds[0]['id']] | ||||||
|  |         verify_list = [('vnf_pm_threshold_id', | ||||||
|  |                        [self.vnf_pm_thresholds[0]['id']])] | ||||||
|  |  | ||||||
|  |         parsed_args = self.check_parser(self.delete_vnf_pm_threshold, arg_list, | ||||||
|  |                                         verify_list) | ||||||
|  |  | ||||||
|  |         self._mock_request_url_for_delete(0) | ||||||
|  |         sys.stdout = buffer = StringIO() | ||||||
|  |         result = self.delete_vnf_pm_threshold.take_action(parsed_args) | ||||||
|  |         self.assertIsNone(result) | ||||||
|  |         self.assertEqual( | ||||||
|  |             (f"VNF PM threshold '{self.vnf_pm_thresholds[0]['id']}' " | ||||||
|  |              f"deleted successfully"), buffer.getvalue().strip()) | ||||||
|  |  | ||||||
|  |     def test_delete_multiple_vnf_pm_threshold(self): | ||||||
|  |         arg_list = [] | ||||||
|  |         for obj in self.vnf_pm_thresholds: | ||||||
|  |             arg_list.append(obj['id']) | ||||||
|  |         verify_list = [('vnf_pm_threshold_id', arg_list)] | ||||||
|  |         parsed_args = self.check_parser(self.delete_vnf_pm_threshold, arg_list, | ||||||
|  |                                         verify_list) | ||||||
|  |         for i in range(0, len(self.vnf_pm_thresholds)): | ||||||
|  |             self._mock_request_url_for_delete(i) | ||||||
|  |         sys.stdout = buffer = StringIO() | ||||||
|  |         result = self.delete_vnf_pm_threshold.take_action(parsed_args) | ||||||
|  |         self.assertIsNone(result) | ||||||
|  |         self.assertEqual('All specified VNF PM thresholds are deleted ' | ||||||
|  |                          'successfully', buffer.getvalue().strip()) | ||||||
|  |  | ||||||
|  |     def test_delete_multiple_vnf_pm_threshold_exception(self): | ||||||
|  |         arg_list = [ | ||||||
|  |             self.vnf_pm_thresholds[0]['id'], | ||||||
|  |             'xxxx-yyyy-zzzz', | ||||||
|  |             self.vnf_pm_thresholds[1]['id'], | ||||||
|  |         ] | ||||||
|  |         verify_list = [('vnf_pm_threshold_id', arg_list)] | ||||||
|  |         parsed_args = self.check_parser(self.delete_vnf_pm_threshold, | ||||||
|  |                                         arg_list, verify_list) | ||||||
|  |  | ||||||
|  |         self._mock_request_url_for_delete(0) | ||||||
|  |  | ||||||
|  |         url = os.path.join(self.url, 'vnfpm/v2/thresholds', | ||||||
|  |                            'xxxx-yyyy-zzzz') | ||||||
|  |         self.requests_mock.register_uri( | ||||||
|  |             'GET', url, exc=exceptions.ConnectionFailed) | ||||||
|  |  | ||||||
|  |         self._mock_request_url_for_delete(1) | ||||||
|  |         exception = self.assertRaises(exceptions.CommandError, | ||||||
|  |                                       self.delete_vnf_pm_threshold.take_action, | ||||||
|  |                                       parsed_args) | ||||||
|  |  | ||||||
|  |         self.assertEqual( | ||||||
|  |             f'Failed to delete 1 of {len(self.vnf_pm_thresholds)} ' | ||||||
|  |             'VNF PM thresholds.', exception.message) | ||||||
							
								
								
									
										111
									
								
								tackerclient/tests/unit/osc/v2/vnfpm_threshold_fakes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								tackerclient/tests/unit/osc/v2/vnfpm_threshold_fakes.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | # Copyright (C) 2023 Fujitsu | ||||||
|  | # All Rights Reserved. | ||||||
|  | # | ||||||
|  | #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||||
|  | #    not use this file except in compliance with the License. You may obtain | ||||||
|  | #    a copy of the License at | ||||||
|  | # | ||||||
|  | #         http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | #    Unless required by applicable law or agreed to in writing, software | ||||||
|  | #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
|  | #    License for the specific language governing permissions and limitations | ||||||
|  | #    under the License. | ||||||
|  |  | ||||||
|  | from oslo_utils import uuidutils | ||||||
|  |  | ||||||
|  | from tackerclient.osc import utils as tacker_osc_utils | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def create_vnf_pm_thresholds(count=2): | ||||||
|  |     """Create multiple fake vnf pm thresholds. | ||||||
|  |  | ||||||
|  |     :param int count: | ||||||
|  |         The number of vnf_pm_thresholds to fake | ||||||
|  |     :return: | ||||||
|  |         A list of fake vnf pm thresholds dictionary | ||||||
|  |     """ | ||||||
|  |     vnf_pm_thresholds = [] | ||||||
|  |     for _ in range(0, count): | ||||||
|  |         unique_id = uuidutils.generate_uuid() | ||||||
|  |         vnf_pm_thresholds.append(vnf_pm_threshold_response( | ||||||
|  |             attrs={'id': unique_id})) | ||||||
|  |     return vnf_pm_thresholds | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def vnf_pm_threshold_response(attrs=None, action=None): | ||||||
|  |     """Create a fake vnf pm threshold. | ||||||
|  |  | ||||||
|  |     :param Dictionary attrs: | ||||||
|  |         A dictionary with all attributes | ||||||
|  |     :param String action: | ||||||
|  |         The operation performed on threshold | ||||||
|  |     :return: | ||||||
|  |         A pm threshold dict | ||||||
|  |     """ | ||||||
|  |     if action == 'update': | ||||||
|  |         fake_vnf_pm_threshold = { | ||||||
|  |             "callbackUri": "/nfvo/notify/threshold", | ||||||
|  |         } | ||||||
|  |         return fake_vnf_pm_threshold | ||||||
|  |  | ||||||
|  |     attrs = attrs or {} | ||||||
|  |     # Set default attributes. | ||||||
|  |     fake_vnf_pm_threshold = { | ||||||
|  |         "id": "2bb72d78-b1d9-48fe-8c64-332654ffeb5d", | ||||||
|  |         "objectType": "Vnfc", | ||||||
|  |         "objectInstanceId": "object-instance-id-1", | ||||||
|  |         "subObjectInstanceIds": [ | ||||||
|  |             "sub-object-instance-id-2" | ||||||
|  |         ], | ||||||
|  |         "criteria": { | ||||||
|  |             "performanceMetric": "VCpuUsageMeanVnf.object-instance-id-1", | ||||||
|  |             "thresholdType": "SIMPLE", | ||||||
|  |             "simpleThresholdDetails": { | ||||||
|  |                 "thresholdValue": 500.5, | ||||||
|  |                 "hysteresis": 10.5 | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "callbackUri": "/nfvo/notify/threshold", | ||||||
|  |         "_links": { | ||||||
|  |             "self": { | ||||||
|  |                 "href": "/vnfpm/v2/thresholds/" | ||||||
|  |                         "78a39661-60a8-4824-b989-88c1b0c3534a" | ||||||
|  |             }, | ||||||
|  |             "object": { | ||||||
|  |                 "href": "/vnflcm/v1/vnf_instances/" | ||||||
|  |                         "0e5f3086-4e79-47ed-a694-54c29155fa26" | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     # Overwrite default attributes. | ||||||
|  |     fake_vnf_pm_threshold.update(attrs) | ||||||
|  |  | ||||||
|  |     return fake_vnf_pm_threshold | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def get_vnfpm_threshold_data(vnf_pm_threshold, columns=None): | ||||||
|  |     """Get the vnfpm threshold. | ||||||
|  |  | ||||||
|  |     :param Dictionary vnf_pm_threshold: | ||||||
|  |         A dictionary with vnf_pm_threshold | ||||||
|  |     :param List columns: | ||||||
|  |         A list of column names | ||||||
|  |     :return: | ||||||
|  |         A tuple object sorted based on the name of the columns. | ||||||
|  |     """ | ||||||
|  |     complex_attributes = ['subObjectInstanceIds', | ||||||
|  |                           'criteria', '_links', 'authentication'] | ||||||
|  |  | ||||||
|  |     for attribute in complex_attributes: | ||||||
|  |         if vnf_pm_threshold.get(attribute): | ||||||
|  |             vnf_pm_threshold.update( | ||||||
|  |                 {attribute: tacker_osc_utils.FormatComplexDataColumn( | ||||||
|  |                     vnf_pm_threshold[attribute])}) | ||||||
|  |  | ||||||
|  |     # return the list of data as per column order | ||||||
|  |     if columns is None: | ||||||
|  |         columns = sorted(vnf_pm_threshold.keys()) | ||||||
|  |     return tuple([vnf_pm_threshold[key] for key in columns]) | ||||||
| @@ -1104,6 +1104,8 @@ class VnfPMClient(ClientBase): | |||||||
|     vnf_pm_jobs_path = '/vnfpm/v2/pm_jobs' |     vnf_pm_jobs_path = '/vnfpm/v2/pm_jobs' | ||||||
|     vnf_pm_job_path = '/vnfpm/v2/pm_jobs/%s' |     vnf_pm_job_path = '/vnfpm/v2/pm_jobs/%s' | ||||||
|     vnf_pm_reports_path = '/vnfpm/v2/pm_jobs/%(job_id)s/reports/%(report_id)s' |     vnf_pm_reports_path = '/vnfpm/v2/pm_jobs/%(job_id)s/reports/%(report_id)s' | ||||||
|  |     vnf_pm_thresholds_path = '/vnfpm/v2/thresholds' | ||||||
|  |     vnf_pm_threshold_path = '/vnfpm/v2/thresholds/%s' | ||||||
|  |  | ||||||
|     def build_action(self, action): |     def build_action(self, action): | ||||||
|         return action |         return action | ||||||
| @@ -1143,6 +1145,35 @@ class VnfPMClient(ClientBase): | |||||||
|                 'job_id': vnf_pm_job_id, 'report_id': vnf_pm_report_id |                 'job_id': vnf_pm_job_id, 'report_id': vnf_pm_report_id | ||||||
|             }, headers=self.headers) |             }, headers=self.headers) | ||||||
|  |  | ||||||
|  |     @APIParamsCall | ||||||
|  |     def create_vnf_pm_threshold(self, body): | ||||||
|  |         return self.post( | ||||||
|  |             self.vnf_pm_thresholds_path, body=body, headers=self.headers) | ||||||
|  |  | ||||||
|  |     @APIParamsCall | ||||||
|  |     def list_vnf_pm_thresholds(self, retrieve_all=True, **_params): | ||||||
|  |         return self.list( | ||||||
|  |             "vnf_pm_thresholds", self.vnf_pm_thresholds_path, retrieve_all, | ||||||
|  |             headers=self.headers, **_params) | ||||||
|  |  | ||||||
|  |     @APIParamsCall | ||||||
|  |     def show_vnf_pm_threshold(self, vnf_pm_threshold_id): | ||||||
|  |         return self.get( | ||||||
|  |             self.vnf_pm_threshold_path % vnf_pm_threshold_id, | ||||||
|  |             headers=self.headers) | ||||||
|  |  | ||||||
|  |     @APIParamsCall | ||||||
|  |     def update_vnf_pm_threshold(self, vnf_pm_threshold_id, body): | ||||||
|  |         return self.patch( | ||||||
|  |             self.vnf_pm_threshold_path % vnf_pm_threshold_id, body=body, | ||||||
|  |             headers=self.headers) | ||||||
|  |  | ||||||
|  |     @APIParamsCall | ||||||
|  |     def delete_vnf_pm_threshold(self, vnf_pm_threshold_id): | ||||||
|  |         return self.delete( | ||||||
|  |             self.vnf_pm_threshold_path % vnf_pm_threshold_id, | ||||||
|  |             headers=self.headers) | ||||||
|  |  | ||||||
|  |  | ||||||
| class Client(object): | class Client(object): | ||||||
|     """Unified interface to interact with multiple applications of tacker service. |     """Unified interface to interact with multiple applications of tacker service. | ||||||
| @@ -1527,3 +1558,20 @@ class Client(object): | |||||||
|     def show_vnf_pm_report(self, vnf_pm_job_id, vnf_pm_report_id): |     def show_vnf_pm_report(self, vnf_pm_job_id, vnf_pm_report_id): | ||||||
|         return self.vnf_pm_client.show_vnf_pm_report( |         return self.vnf_pm_client.show_vnf_pm_report( | ||||||
|             vnf_pm_job_id, vnf_pm_report_id) |             vnf_pm_job_id, vnf_pm_report_id) | ||||||
|  |  | ||||||
|  |     def create_vnf_pm_threshold(self, body): | ||||||
|  |         return self.vnf_pm_client.create_vnf_pm_threshold(body) | ||||||
|  |  | ||||||
|  |     def list_vnf_pm_thresholds(self, retrieve_all=True, **_params): | ||||||
|  |         return self.vnf_pm_client.list_vnf_pm_thresholds( | ||||||
|  |             retrieve_all=retrieve_all, **_params) | ||||||
|  |  | ||||||
|  |     def show_vnf_pm_threshold(self, vnf_pm_threshold_id): | ||||||
|  |         return self.vnf_pm_client.show_vnf_pm_threshold(vnf_pm_threshold_id) | ||||||
|  |  | ||||||
|  |     def update_vnf_pm_threshold(self, vnf_pm_threshold_id, body): | ||||||
|  |         return self.vnf_pm_client.update_vnf_pm_threshold( | ||||||
|  |             vnf_pm_threshold_id, body) | ||||||
|  |  | ||||||
|  |     def delete_vnf_pm_threshold(self, vnf_pm_threshold_id): | ||||||
|  |         return self.vnf_pm_client.delete_vnf_pm_threshold(vnf_pm_threshold_id) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Yi Feng
					Yi Feng