Compare commits

...

16 Commits

Author SHA1 Message Date
Zuul
e5bd58ffe1 Merge "Extends unit test code support for merged patch" 2023-02-17 05:07:40 +00:00
Zuul
2add9e0f85 Merge "Fix list VNF/Subscription UT error" 2023-02-17 04:39:07 +00:00
Ai Hamano
a41323dc1d Fix list VNF/Subscription UT error
This patch resolves the following error caused by using one data in
multiple tests.
-----
ft1.2: tackerclient.tests.unit.osc.v1.test_vnflcm_subsc.
TestListLccnSubscription.test_take_action_with_
paginationtesttools.testresult.real._StringException:
 Traceback (most recent call last):
  File "/home/zuul/src/opendev.org/openstack/
python-tackerclient/tackerclient/tests/unit/osc/v1
/test_vnflcm_subsc.py", line 139, in test_take_action_with_
pagination
    expected_data.append(vnflcm_subsc_fakes.get_subscription_
data(
  File "/home/zuul/src/opendev.org/openstack
/python-tackerclient/tackerclient/tests/unit/osc/v1
/vnflcm_subsc_fakes.py", line 166, in get_subscription_data
    subscription.pop(item)
KeyError: 'filter'
-----

Add test data for each test.
(Three data are set for each test data so that the first, last, and
other values can be checked.)
And change not to modify test data directly in get method.

Closes-Bug: #2007524
Change-Id: Id3919fc638f6b858c115a3a7d7e4ca60036217d4
2023-02-17 02:25:25 +00:00
Zuul
a4e0790e75 Merge "Extra param for OpenStack type when register vim" 2023-02-16 12:07:03 +00:00
Zuul
0f9b6f5c52 Merge "Add support cnf auto scale via threshold interface" 2023-02-16 10:32:17 +00:00
kexuesheng
e398f422a8 Extra param for OpenStack type when register vim
This patch changes to allow setting the `extra` parameter in the VIM
configuration for openstack vim type.

Implements: blueprint enhance-api-policy
Change-Id: I37a3e21afced0aae6e0fd3c0cbb28ab16f2b7df8
2023-02-16 11:07:39 +09:00
Yi Feng
8b45c8082b 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
2023-02-16 10:36:47 +09:00
psingla
6b168365d6 Extends unit test code support for merged patch
This patch extends unit test code for the
feature which is implemented in this patch
https://review.opendev.org/c/openstack/python-tackerclient/+/847746

Implements: blueprint paging-query-result
Change-Id: Ic1c23ee51ab838168577c60a3ac44b600bca2563
2023-02-15 05:49:53 +00:00
Ayumu Ueha
156deea66c Add deprecation notice for Legacy APIs
This patch deprecates CLI for Legacy APIs excluding VIM feature.

Implements: blueprint deprecate-legacy-apis
Change-Id: Ib74db43b4a3de4676e61f4f9ce6d3d2095a11ddf
2023-01-27 00:38:21 +00:00
Ayumu Ueha
82bf387f77 Fix tox4 error
Remove skipsdist that it was never supported and causes breakage
when used with usedevelop.

Change-Id: Ia0c03eaa5474f13600880dd6eca79d284bba5ca8
2023-01-12 05:08:29 +00:00
Manpreet Kaur
326d02671e Update python classifier for python 3.10
In 2023.1 cycle, we are testing the python 3.10
as voting job so updating the python classifier.

Currently we have python 3.8 unit test job running on
Ubuntu Focal and python 3.10 job on Ubuntu Jammy.

Change-Id: Ie5ef1e398f6709e2164db57c3f5bbfbc69053a02
2022-12-15 12:21:12 +05:30
Zuul
6a13f2ecbd Merge "Switch to 2023.1 Python3 unit tests and generic template name" 2022-10-24 01:30:11 +00:00
0849569507 Switch to 2023.1 Python3 unit tests and generic template name
This is an automatically generated patch to ensure unit testing
is in place for all the of the tested runtimes for antelope. Also,
updating the template name to generic one.

See also the PTI in governance [1].

[1]: https://governance.openstack.org/tc/reference/project-testing-interface.html

Change-Id: I92990bd9aa48941e092fafc6246317e152ad4602
2022-09-14 09:28:28 +00:00
Zuul
190dc6d581 Merge "Update master for stable/zed" 2022-09-12 17:28:18 +00:00
b4e49b3653 Update master for stable/zed
Add file to the reno documentation build to show release notes for
stable/zed.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/zed.

Sem-Ver: feature
Change-Id: I2bf82a833e8adfb5606ccbd336872b4973f93440
2022-09-08 15:52:48 +00:00
Koji Shimizu
80ee721263 Add docs for cnf auto heal and scale
This patch makes the following updates to the API and CLI docs.

* Add support cnf auto heal and scale

Implements: blueprint support-auto-lcm
Change-Id: Ide4d8c8652cdf8ac611e65376a21806488667ace
2022-09-08 19:49:24 +09:00
47 changed files with 1209 additions and 172 deletions

View File

@@ -1,6 +1,6 @@
- project:
templates:
- check-requirements
- openstack-python3-zed-jobs
- openstack-python3-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3

View File

@@ -97,3 +97,21 @@ of individual command can be referred by **openstack help <command-name>**.
openstack vnflcm subsc delete Delete subscription.
openstack vnflcm subsc list List subscription.
openstack vnflcm subsc show Show subscription.
openstack vnffm alarm list List alarm.
openstack vnffm alarm show Show alarm.
openstack vnffm alarm update Update alarm.
openstack vnffm sub create Create FM subscription.
openstack vnffm sub list List FM subscription.
openstack vnffm sub show Show FM subscription.
openstack vnffm sub delete Delete FM subscription.
openstack vnfpm job create Create PM job.
openstack vnfpm job list List PM job.
openstack vnfpm job show Show PM job.
openstack vnfpm job update Update PM job.
openstack vnfpm job delete Delete PM job.
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.

View File

@@ -29,6 +29,8 @@ Operations for ETSI NFV-SOL implementation
vnf_package_commands
vnflcm_commands
vnffm_commands
vnfpm_commands
Operations for Legacy implementation
------------------------------------

View File

@@ -15,5 +15,10 @@
Event Management commands
=========================
.. warning::
Event Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: nfv event *

View File

@@ -11,9 +11,14 @@
License for the specific language governing permissions and limitations
under the License.
==============================================
Network Service Descriptor Management commands
==============================================
===================================
Network Service Management commands
===================================
.. warning::
Network Service Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: ns *

View File

@@ -15,5 +15,10 @@
Network Service Descriptor Management commands
==============================================
.. warning::
Network Service Descriptor Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: ns descriptor *

View File

@@ -15,5 +15,10 @@
Service Function Chain (SFC) Management commands
================================================
.. warning::
Service Function Chain (SFC) Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: vnf chain *

View File

@@ -15,5 +15,10 @@
Flow Classifier Management commands
===================================
.. warning::
Flow Classifier Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: vnf classifier *

View File

@@ -15,5 +15,10 @@
VNF Management commands
=======================
.. warning::
VNF Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: vnf *

View File

@@ -15,5 +15,10 @@
VNF Descriptor (VNFD) Management commands
=========================================
.. warning::
VNF Descriptor (VNFD) Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: vnf descriptor *

View File

@@ -15,5 +15,10 @@
VNF Forwarding Graph (VNFFG) Management commands
================================================
.. warning::
VNF Forwarding Graph (VNFFG) Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: vnf graph *

View File

@@ -15,5 +15,10 @@
VNF Forwarding Graph Descriptor (VNFFGD) Management commands
============================================================
.. warning::
VNF Forwarding Graph Descriptor (VNFFGD) Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: vnf graph descriptor *

View File

@@ -15,5 +15,10 @@
Network Forwarding Path Management commands
===========================================
.. warning::
Network Forwarding Path Management commands are deprecated
and will be removed in the first major release after the Tacker server
version 9.0.0 (2023.1 Antelope release).
.. autoprogram-cliff:: openstack.tackerclient.v1
:command: vnf network forwarding path *

View File

@@ -0,0 +1,28 @@
..
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.
===============
VNF FM commands
===============
VNF FM commands are CLI interface of VNF Fault Management interface in
`ETSI NFV-SOL 002 <https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/002/03.03.01_60/gs_NFV-SOL002v030301p.pdf>`_
and `ETSI NFV-SOL 003 <https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/03.03.01_60/gs_nfv-sol003v030301p.pdf>`_.
.. note::
Commands only support calling version 2 vnffm APIs.
You can use the commands with **\-\-os-tacker-api-version 2** to
call version 2 vnffm APIs.
.. autoprogram-cliff:: openstack.tackerclient.v2
:command: vnffm *

View File

@@ -0,0 +1,28 @@
..
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.
===============
VNF PM commands
===============
VNF PM commands are CLI interface of VNF Performance Management interface in
`ETSI NFV-SOL 002 <https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/002/03.03.01_60/gs_NFV-SOL002v030301p.pdf>`_
and `ETSI NFV-SOL 003 <https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/03.03.01_60/gs_nfv-sol003v030301p.pdf>`_.
.. note::
Commands only support calling version 2 vnfpm APIs.
You can use the commands with **\-\-os-tacker-api-version 2** to
call version 2 vnfpm APIs.
.. autoprogram-cliff:: openstack.tackerclient.v2
:command: vnfpm *

View File

@@ -0,0 +1,6 @@
---
deprecations:
- |
Legacy APIs excluding VIM feature are deprecated and will be removed in the
first major release after the Tacker server version 9.0.0 (2023.1 Antelope
release).

View File

@@ -7,6 +7,7 @@ Contents:
:maxdepth: 2
unreleased
zed
yoga
xena
wallaby

View File

@@ -0,0 +1,6 @@
========================
Zed Series Release Notes
========================
.. release-notes::
:branch: stable/zed

View File

@@ -22,6 +22,7 @@ classifier =
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
[files]
packages =
@@ -136,6 +137,11 @@ openstack.tackerclient.v2 =
vnfpm_job_update = tackerclient.osc.v2.vnfpm.vnfpm_job:UpdateVnfPmJob
vnfpm_job_delete = tackerclient.osc.v2.vnfpm.vnfpm_job:DeleteVnfPmJob
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_show = tackerclient.osc.v2.vnffm.vnffm_alarm:ShowVnfFmAlarm
vnffm_alarm_update = tackerclient.osc.v2.vnffm.vnffm_alarm:UpdateVnfFmAlarm

View File

@@ -20,6 +20,7 @@
import argparse
import logging
import os
import sys
from oslo_log import versionutils
from oslo_utils import encodeutils
@@ -183,3 +184,15 @@ def deprecate_warning(what, as_of, in_favor_of=None, remove_in=1):
versionutils.deprecation_warning(as_of=as_of, what=what,
in_favor_of=in_favor_of,
remove_in=remove_in)
# TODO(ueha): Remove this along with the deprecated commands in the first major
# python-tackerclient release after the Tacker server version 9.0.0 (2023.1
# Antelope release).
def deprecate_legacy_warning():
# NOTE(ueha): versionutils has not support Antelope version yet.
msg = _(
'The Legacy API interface has been deprecated. This command will be '
'removed in the first major release after the Tacker server version '
'9.0.0 (2023.1 Antelope release).')
print(msg, file=sys.stderr)

View File

@@ -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.
"""
import json
import operator
import os
from cliff import columns as cliff_columns
from keystoneclient import exceptions as identity_exc
@@ -29,6 +31,7 @@ from keystoneclient.v3 import projects
from osc_lib import utils
from oslo_serialization import jsonutils
from tackerclient.common import exceptions
from tackerclient.i18n import _
@@ -212,3 +215,29 @@ class FormatComplexDataColumn(cliff_columns.FormattableColumn):
def human_readable(self):
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

View File

@@ -17,6 +17,7 @@
from osc_lib.command import command
from osc_lib import utils
from tackerclient.common import utils as tacker_common_utils
from tackerclient.i18n import _
from tackerclient.osc import sdk_utils
from tackerclient.osc import utils as tacker_osc_utils
@@ -55,6 +56,7 @@ class ShowEvent(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _EVENT, parsed_args.event)
@@ -93,6 +95,7 @@ class ListEvent(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
_params = {}
if parsed_args.id:

View File

@@ -20,6 +20,7 @@ from osc_lib.command import command
from osc_lib import utils
from tackerclient.common import exceptions
from tackerclient.common import utils as tacker_common_utils
from tackerclient.i18n import _
from tackerclient.osc import sdk_utils
from tackerclient.osc import utils as tacker_osc_utils
@@ -133,6 +134,7 @@ class CreateNS(command.ShowOne):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
ns = client.create_ns(self.args2body(parsed_args))
display_columns, columns = _get_columns(ns[_NS])
@@ -174,6 +176,7 @@ class DeleteNS(command.Command):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
failure = False
deleted_ids = []
@@ -217,6 +220,7 @@ class ListNS(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
data = client.list_nss()
headers, columns = tacker_osc_utils.get_column_definitions(
@@ -240,6 +244,7 @@ class ShowNS(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _NS, parsed_args.ns)

View File

@@ -20,6 +20,7 @@ from osc_lib.command import command
from osc_lib import utils
from tackerclient.common import exceptions
from tackerclient.common import utils as tacker_common_utils
from tackerclient.i18n import _
from tackerclient.osc import sdk_utils
from tackerclient.osc import utils as tacker_osc_utils
@@ -86,6 +87,7 @@ class CreateNSD(command.ShowOne):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
nsd = client.create_nsd(self.args2body(parsed_args))
display_columns, columns = _get_columns(nsd[_NSD])
@@ -111,6 +113,7 @@ class DeleteNSD(command.Command):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
failure = False
deleted_ids = []
@@ -159,6 +162,7 @@ class ListNSD(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
data = client.list_nsds()
headers, columns = tacker_osc_utils.get_column_definitions(
@@ -182,6 +186,7 @@ class ShowNSD(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _NSD, parsed_args.nsd)
@@ -209,6 +214,7 @@ class ShowTemplateNSD(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _NSD, parsed_args.nsd)

View File

@@ -20,6 +20,7 @@ from osc_lib.command import command
from osc_lib import utils
from tackerclient.common import exceptions
from tackerclient.common import utils as tacker_common_utils
from tackerclient.i18n import _
from tackerclient.osc import sdk_utils
from tackerclient.osc import utils as tacker_osc_utils
@@ -169,6 +170,7 @@ class CreateVNFFG(command.ShowOne):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
vnffg = client.create_vnffg(self.args2body(parsed_args))
display_columns, columns = _get_columns(vnffg[_VNFFG])
@@ -206,6 +208,7 @@ class DeleteVNFFG(command.Command):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
failure = False
deleted_ids = []
@@ -316,6 +319,7 @@ class UpdateVNFFG(command.ShowOne):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNFFG, parsed_args.vnffg)
@@ -341,6 +345,7 @@ class ListVNFFG(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
data = client.list_vnffgs()
headers, columns = tacker_osc_utils.get_column_definitions(
@@ -364,6 +369,7 @@ class ShowVNFFG(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNFFG, parsed_args.vnffg)
@@ -387,6 +393,7 @@ class ListNFP(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
_params = {}
if parsed_args.vnffg_id:
@@ -423,6 +430,7 @@ class ShowNFP(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _NFP, parsed_args.nfp)
@@ -448,6 +456,7 @@ class ListFC(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
_params = {}
if parsed_args.nfp_id:
@@ -487,6 +496,7 @@ class ShowFC(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _FC, parsed_args.classifier)
@@ -513,6 +523,7 @@ class ListSFC(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
_params = {}
if parsed_args.nfp_id:
@@ -550,6 +561,7 @@ class ShowSFC(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _SFC, parsed_args.sfc)

View File

@@ -20,6 +20,7 @@ from osc_lib.command import command
from osc_lib import utils
from tackerclient.common import exceptions
from tackerclient.common import utils as tacker_common_utils
from tackerclient.i18n import _
from tackerclient.osc import sdk_utils
from tackerclient.osc import utils as tacker_osc_utils
@@ -87,6 +88,7 @@ class CreateVNFFGD(command.ShowOne):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
vnffgd = client.create_vnffgd(self.args2body(parsed_args))
display_columns, columns = _get_columns(vnffgd[_VNFFGD])
@@ -110,6 +112,7 @@ class DeleteVNFFGD(command.Command):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
failure = False
deleted_ids = []
@@ -158,6 +161,7 @@ class ListVNFFGD(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
data = client.list_vnffgds()
headers, columns = tacker_osc_utils.get_column_definitions(
@@ -181,6 +185,7 @@ class ShowVNFFGD(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNFFGD, parsed_args.vnffgd)
@@ -205,6 +210,7 @@ class ShowTemplateVNFFGD(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNFFGD, parsed_args.vnffgd)

View File

@@ -13,9 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import time
from osc_lib.command import command
@@ -113,7 +111,7 @@ class CreateVnfLcm(command.ShowOne):
body = {}
if file_path:
return jsonfile2body(file_path)
return tacker_osc_utils.jsonfile2body(file_path)
body['vnfdId'] = parsed_args.vnfd_id
@@ -184,29 +182,6 @@ class ListVnfLcm(command.Lister):
) 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):
_description = _("Instantiate a VNF Instance")
@@ -226,7 +201,7 @@ class InstantiateVnfLcm(command.Command):
def take_action(self, parsed_args):
client = self.app.client_manager.tackerclient
result = client.instantiate_vnf_instance(
parsed_args.vnf_instance, jsonfile2body(
parsed_args.vnf_instance, tacker_osc_utils.jsonfile2body(
parsed_args.instantiation_request_file))
if not result:
print((_('Instantiate request for VNF Instance %(id)s has been'
@@ -271,7 +246,8 @@ class HealVnfLcm(command.Command):
if parsed_args.vnfc_instance:
body['vnfcInstanceId'] = parsed_args.vnfc_instance
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
@@ -461,7 +437,7 @@ class UpdateVnfLcm(command.Command):
body = {}
if file_path:
return jsonfile2body(file_path)
return tacker_osc_utils.jsonfile2body(file_path)
return body
@@ -535,7 +511,8 @@ class ScaleVnfLcm(command.Command):
body['numberOfSteps'] = parsed_args.number_of_steps
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
@@ -574,7 +551,7 @@ class ChangeExtConnVnfLcm(command.Command):
def take_action(self, parsed_args):
client = self.app.client_manager.tackerclient
result = client.change_ext_conn_vnf_instance(
parsed_args.vnf_instance, jsonfile2body(
parsed_args.vnf_instance, tacker_osc_utils.jsonfile2body(
parsed_args.request_file))
if not result:
print((_('Change External VNF Connectivity for VNF Instance %s '
@@ -601,7 +578,7 @@ class ChangeVnfPkgVnfLcm(command.Command):
def take_action(self, parsed_args):
client = self.app.client_manager.tackerclient
result = client.change_vnfpkg_vnf_instance(
parsed_args.vnf_instance, jsonfile2body(
parsed_args.vnf_instance, tacker_osc_utils.jsonfile2body(
parsed_args.request_file))
if not result:
print((_('Change Current VNF Package for VNF Instance %s '

View File

@@ -13,9 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
from osc_lib.command import command
from osc_lib import utils
@@ -49,29 +47,6 @@ def _get_columns(lccn_subsc_obj):
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):
_description = _("Create a new Lccn Subscription")
@@ -86,7 +61,7 @@ class CreateLccnSubscription(command.ShowOne):
def take_action(self, parsed_args):
client = self.app.client_manager.tackerclient
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)
data = utils.get_item_properties(sdk_utils.DictModel(subsc),
columns, formatters=_FORMATTERS,

View File

@@ -21,6 +21,7 @@ from osc_lib import utils
from oslo_utils import encodeutils
from tackerclient.common import exceptions
from tackerclient.common import utils as tacker_common_utils
from tackerclient.i18n import _
from tackerclient.osc import sdk_utils
from tackerclient.osc import utils as tacker_osc_utils
@@ -170,6 +171,7 @@ class CreateVNF(command.ShowOne):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
vnf = client.create_vnf(self.args2body(parsed_args))
display_columns, columns = _get_columns(vnf[_VNF])
@@ -208,6 +210,7 @@ class DeleteVNF(command.Command):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
failure = False
deleted_ids = []
@@ -278,6 +281,7 @@ class ListVNF(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
_params = {}
if parsed_args.vim_id:
@@ -317,6 +321,7 @@ class ShowVNF(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNF, parsed_args.vnf)
@@ -343,6 +348,7 @@ class ListVNFResources(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNF, parsed_args.vnf)
@@ -418,6 +424,7 @@ class UpdateVNF(command.ShowOne):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNF, parsed_args.vnf)
@@ -457,6 +464,7 @@ class ScaleVNF(command.Command):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNF, parsed_args.vnf)

View File

@@ -20,6 +20,7 @@ from osc_lib.command import command
from osc_lib import utils
from tackerclient.common import exceptions
from tackerclient.common import utils as tacker_common_utils
from tackerclient.i18n import _
from tackerclient.osc import sdk_utils
from tackerclient.osc import utils as tacker_osc_utils
@@ -87,6 +88,7 @@ class CreateVNFD(command.ShowOne):
return body
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
vnfd = client.create_vnfd(self.args2body(parsed_args))
display_columns, columns = _get_columns(vnfd[_VNFD])
@@ -112,6 +114,7 @@ class DeleteVNFD(command.Command):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
failure = False
deleted_ids = []
@@ -160,6 +163,7 @@ class ListVNFD(command.Lister):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
data = client.list_vnfds()
headers, columns = tacker_osc_utils.get_column_definitions(
@@ -183,6 +187,7 @@ class ShowVNFD(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNFD, parsed_args.vnfd)
@@ -210,6 +215,7 @@ class ShowTemplateVNFD(command.ShowOne):
return parser
def take_action(self, parsed_args):
tacker_common_utils.deprecate_legacy_warning()
client = self.app.client_manager.tackerclient
obj_id = tackerV10.find_resourceid_by_name_or_id(
client, _VNFD, parsed_args.vnfd)

View File

@@ -13,9 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
from osc_lib.command import command
from osc_lib import utils
@@ -56,32 +54,6 @@ def _get_columns(vnffm_sub_obj):
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):
_description = _("Create a new VNF FM subscription")
@@ -97,7 +69,7 @@ class CreateVnfFmSub(command.ShowOne):
def take_action(self, parsed_args):
client = self.app.client_manager.tackerclient
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)
data = utils.get_item_properties(
sdk_utils.DictModel(vnf_fm_sub), columns,

View File

@@ -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"
}
}
}

View File

@@ -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"
}
}
}

View File

@@ -13,9 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
from functools import reduce
from osc_lib.command import command
@@ -78,32 +76,6 @@ def _get_columns(vnfpm_job_obj, action="/?originalUrl=https%3A%2F%2Fgit.openstack.org%2FNone)%3A%253C%2Fcode">
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):
_description = _("Create a new VNF PM job")
@@ -119,7 +91,7 @@ class CreateVnfPmJob(command.ShowOne):
def take_action(self, parsed_args):
client = self.app.client_manager.tackerclient
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)
data = utils.get_item_properties(
sdk_utils.DictModel(vnf_pm_job), columns,
@@ -284,7 +256,7 @@ class UpdateVnfPmJob(command.ShowOne):
client = self.app.client_manager.tackerclient
updated_values = client.update_vnf_pm_job(
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')
data = utils.get_item_properties(
sdk_utils.DictModel(updated_values),

View 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])

View File

@@ -96,9 +96,8 @@ def args2body_vim(config_param, vim):
ssl_ca_cert = config_param.pop('ssl_ca_cert', '')
if ssl_ca_cert:
vim['auth_cred']['ssl_ca_cert'] = ssl_ca_cert
extra = config_param.pop('extra', {})
if extra:
vim['extra'] = extra
if 'extra' in config_param:
vim['extra'] = config_param.pop('extra')
def validate_auth_url(url):

View File

@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
import filecmp
import os
import shutil
@@ -201,6 +202,51 @@ class TestListVnfPackage(TestVnfPackage):
self.assertCountEqual(self.get_list_columns(**kwargs), actual_columns)
self.assertListItemsEqual(expected_data, list(data))
def test_take_action_with_pagination(self):
next_links_num = 3
parsed_args = self.check_parser(self.list_vnf_package, [], [])
path = os.path.join(self.url, '/vnfpkgm/v1/vnf_packages?')
links = [0] * next_links_num
link_headers = [0] * next_links_num
for i in range(next_links_num):
links[i] = (
'{base_url}?nextpage_opaque_marker={vnf_package_id}'.format(
base_url=path,
vnf_package_id=self._vnf_packages
['vnf_packages'][i]['id']))
link_headers[i] = copy.deepcopy(self.header)
link_headers[i]['Link'] = '<{link_url}>; rel="next"'.format(
link_url=links[i])
self.requests_mock.register_uri(
'GET', path, json=[self._vnf_packages['vnf_packages'][0]],
headers=link_headers[0])
self.requests_mock.register_uri(
'GET', links[0], json=[self._vnf_packages['vnf_packages'][1]],
headers=link_headers[1])
self.requests_mock.register_uri(
'GET', links[1], json=[self._vnf_packages['vnf_packages'][2]],
headers=link_headers[2])
self.requests_mock.register_uri(
'GET', links[2], json=[], headers=self.header)
actual_columns, data = self.list_vnf_package.take_action(parsed_args)
kwargs = {}
headers, columns = tacker_osc_utils.get_column_definitions(
self.list_vnf_package.get_attributes(**kwargs), long_listing=True)
expected_data = []
for vnf_package_obj in self._vnf_packages['vnf_packages']:
expected_data.append(vnf_package_fakes.get_vnf_package_data(
vnf_package_obj, columns=columns, list_action=True, **kwargs))
self.assertCountEqual(self.get_list_columns(**kwargs), actual_columns)
self.assertListItemsEqual(expected_data, list(data))
def test_take_action_with_exclude_fields(self):
parsed_args = self.check_parser(
self.list_vnf_package,

View File

@@ -157,25 +157,24 @@ class TestShowVnfLcm(TestVnfLcm):
class TestListVnfLcm(TestVnfLcm):
vnf_instances = vnflcm_fakes.create_vnf_instances(count=3)
def setUp(self):
super(TestListVnfLcm, self).setUp()
self.list_vnf_instance = vnflcm.ListVnfLcm(
self.app, self.app_args, cmd_name='vnflcm list')
def test_take_action(self):
vnf_instances = vnflcm_fakes.create_vnf_instances(count=3)
parsed_args = self.check_parser(self.list_vnf_instance, [], [])
self.requests_mock.register_uri(
'GET', os.path.join(self.url, 'vnflcm/v1/vnf_instances'),
json=self.vnf_instances, headers=self.header)
json=vnf_instances, headers=self.header)
actual_columns, data = self.list_vnf_instance.take_action(parsed_args)
headers, columns = tacker_osc_utils.get_column_definitions(
vnflcm._attr_map, long_listing=True)
expected_data = []
for vnf_instance_obj in self.vnf_instances:
for vnf_instance_obj in vnf_instances:
expected_data.append(vnflcm_fakes.get_vnflcm_data(
vnf_instance_obj, columns=columns, list_action=True))
@@ -184,6 +183,7 @@ class TestListVnfLcm(TestVnfLcm):
self.assertCountEqual(expected_data, list(data))
def test_take_action_with_pagination(self):
vnf_instances = vnflcm_fakes.create_vnf_instances(count=3)
next_links_num = 3
parsed_args = self.check_parser(self.list_vnf_instance, [], [])
path = os.path.join(self.url, 'vnflcm/v1/vnf_instances')
@@ -195,18 +195,18 @@ class TestListVnfLcm(TestVnfLcm):
links[i] = (
'{base_url}?nextpage_opaque_marker={vnf_instance_id}'.format(
base_url=path,
vnf_instance_id=self.vnf_instances[i]['id']))
vnf_instance_id=vnf_instances[i]['id']))
link_headers[i] = copy.deepcopy(self.header)
link_headers[i]['Link'] = '<{link_url}>; rel="next"'.format(
link_url=links[i])
self.requests_mock.register_uri(
'GET', path, json=[self.vnf_instances[0]], headers=link_headers[0])
'GET', path, json=[vnf_instances[0]], headers=link_headers[0])
self.requests_mock.register_uri(
'GET', links[0], json=[self.vnf_instances[1]],
'GET', links[0], json=[vnf_instances[1]],
headers=link_headers[1])
self.requests_mock.register_uri(
'GET', links[1], json=[self.vnf_instances[2]],
'GET', links[1], json=[vnf_instances[2]],
headers=link_headers[2])
self.requests_mock.register_uri(
'GET', links[2], json=[], headers=self.header)
@@ -217,7 +217,7 @@ class TestListVnfLcm(TestVnfLcm):
vnflcm._attr_map, long_listing=True)
expected_data = []
for vnf_instance_obj in self.vnf_instances:
for vnf_instance_obj in vnf_instances:
expected_data.append(vnflcm_fakes.get_vnflcm_data(
vnf_instance_obj, columns=columns, list_action=True))
@@ -297,9 +297,9 @@ class TestInstantiateVnfLcm(TestVnfLcm):
self.instantiate_vnf_lcm.take_action,
parsed_args)
expected_msg = ("Invalid input: File %s does not exist "
"or user does not have read privileges to it")
self.assertEqual(expected_msg % sample_param_file, str(ex))
expected_msg = ("Invalid input: "
"User does not have read privileges to it")
self.assertEqual(expected_msg, str(ex))
@mock.patch("os.open")
@mock.patch("os.access")
@@ -403,9 +403,9 @@ class TestHealVnfLcm(TestVnfLcm):
ex = self.assertRaises(exceptions.InvalidInput,
self.heal_vnf_lcm.take_action, parsed_args)
expected_msg = ("Invalid input: File %s does not exist "
"or user does not have read privileges to it")
self.assertEqual(expected_msg % sample_param_file, str(ex))
expected_msg = ("Invalid input: "
"User does not have read privileges to it")
self.assertEqual(expected_msg, str(ex))
@ddt.ddt
@@ -774,9 +774,9 @@ class TestScaleVnfLcm(TestVnfLcm):
ex = self.assertRaises(exceptions.InvalidInput,
self.scale_vnf_lcm.take_action, parsed_args)
expected_msg = ("Invalid input: File %s does not exist "
"or user does not have read privileges to it")
self.assertEqual(expected_msg % sample_param_file, str(ex))
expected_msg = ("Invalid input: "
"User does not have read privileges to it")
self.assertEqual(expected_msg, str(ex))
@ddt.data('SCALE_IN', 'SCALE_OUT')
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,
parsed_args)
expected_msg = ("Invalid input: File %s does not exist "
"or user does not have read privileges to it")
self.assertEqual(expected_msg % sample_param_file, str(ex))
expected_msg = ("Invalid input: "
"User does not have read privileges to it")
self.assertEqual(expected_msg, str(ex))
@mock.patch("os.open")
@mock.patch("os.access")

View File

@@ -74,25 +74,24 @@ class TestCreateLccnSubscription(test_vnflcm.TestVnfLcm):
class TestListLccnSubscription(test_vnflcm.TestVnfLcm):
subscriptions = vnflcm_subsc_fakes.create_subscriptions(count=3)
def setUp(self):
super(TestListLccnSubscription, self).setUp()
self.list_subscription = vnflcm_subsc.ListLccnSubscription(
self.app, self.app_args, cmd_name='vnflcm subsc list')
def test_take_action(self):
subscriptions = vnflcm_subsc_fakes.create_subscriptions(count=3)
parsed_args = self.check_parser(self.list_subscription, [], [])
self.requests_mock.register_uri(
'GET', os.path.join(self.url, 'vnflcm/v1/subscriptions'),
json=self.subscriptions, headers=self.header)
json=subscriptions, headers=self.header)
actual_columns, data = self.list_subscription.take_action(parsed_args)
headers, columns = tacker_osc_utils.get_column_definitions(
self.list_subscription.get_attributes(), long_listing=True)
expected_data = []
for subscription_obj in self.subscriptions:
for subscription_obj in subscriptions:
expected_data.append(vnflcm_subsc_fakes.get_subscription_data(
subscription_obj, columns=columns, list_action=True))
@@ -101,6 +100,7 @@ class TestListLccnSubscription(test_vnflcm.TestVnfLcm):
self.assertCountEqual(expected_data, list(data))
def test_take_action_with_pagination(self):
subscriptions = vnflcm_subsc_fakes.create_subscriptions(count=3)
next_links_num = 3
path = os.path.join(self.url, 'vnflcm/v1/subscriptions')
parsed_args = self.check_parser(self.list_subscription, [], [])
@@ -112,19 +112,19 @@ class TestListLccnSubscription(test_vnflcm.TestVnfLcm):
links[i] = (
'{base_url}?nextpage_opaque_marker={subscription_id}'.format(
base_url=path,
subscription_id=self.subscriptions[i]['id']))
subscription_id=subscriptions[i]['id']))
link_headers[i] = copy.deepcopy(self.header)
link_headers[i]['Link'] = '<{link_url}>; rel="next"'.format(
link_url=links[i])
self.requests_mock.register_uri(
'GET', path, json=[self.subscriptions[0]], headers=link_headers[0])
'GET', path, json=[subscriptions[0]], headers=link_headers[0])
self.requests_mock.register_uri(
'GET', links[0], json=[self.subscriptions[1]],
'GET', links[0], json=[subscriptions[1]],
headers=link_headers[1])
self.requests_mock.register_uri(
'GET', links[1], json=[self.subscriptions[2]],
'GET', links[1], json=[subscriptions[2]],
headers=link_headers[2])
self.requests_mock.register_uri(
'GET', links[2], json=[], headers=self.header)
@@ -135,7 +135,7 @@ class TestListLccnSubscription(test_vnflcm.TestVnfLcm):
self.list_subscription.get_attributes(), long_listing=True)
expected_data = []
for subscription_obj in self.subscriptions:
for subscription_obj in subscriptions:
expected_data.append(vnflcm_subsc_fakes.get_subscription_data(
subscription_obj, columns=columns, list_action=True))

View File

@@ -121,23 +121,24 @@ def get_vnflcm_data(vnf_instance, list_action="/?originalUrl=https%3A%2F%2Fgit.openstack.org%2FFalse%2C%2520columns%3DNone)%3A%253C%2Fcode">
:return:
A tuple object sorted based on the name of the columns.
"""
vnf = vnf_instance.copy()
complex_attributes = ['vimConnectionInfo', 'instantiatedVnfInfo', '_links']
for attribute in complex_attributes:
if vnf_instance.get(attribute):
vnf_instance.update(
if vnf.get(attribute):
vnf.update(
{attribute: tacker_osc_utils.FormatComplexDataColumn(
vnf_instance[attribute])})
vnf[attribute])})
if list_action:
for item in ['vnfInstanceDescription', 'vnfdVersion']:
vnf_instance.pop(item)
vnf.pop(item)
# return the list of data as per column order
if columns:
return tuple([vnf_instance[key] for key in columns])
return tuple([vnf[key] for key in columns])
return tuple([vnf_instance[key] for key in sorted(
vnf_instance.keys())])
return tuple([vnf[key] for key in sorted(
vnf.keys())])
def create_vnf_instances(count=2):

View File

@@ -154,23 +154,24 @@ def get_subscription_data(subscription, list_action="/?originalUrl=https%3A%2F%2Fgit.openstack.org%2FFalse%2C%2520columns%3DNone)%3A%253C%2Fcode">
:return:
A tuple object sorted based on the name of the columns.
"""
subsc = subscription.copy()
complex_attributes = ['filter', '_links']
for attribute in complex_attributes:
if subscription.get(attribute):
subscription.update(
if subsc.get(attribute):
subsc.update(
{attribute: tacker_osc_utils.FormatComplexDataColumn(
subscription[attribute])})
subsc[attribute])})
if list_action:
for item in ['filter', '_links']:
subscription.pop(item)
subsc.pop(item)
# return the list of data as per column order
if columns:
return tuple([subscription[key] for key in columns])
return tuple([subsc[key] for key in columns])
return tuple([subscription[key] for key in sorted(
subscription.keys())])
return tuple([subsc[key] for key in sorted(
subsc.keys())])
def create_subscriptions(count=2):

View File

@@ -121,9 +121,9 @@ class TestChangeVnfPkgVnfLcm(test_vnflcm.TestVnfLcm):
self.change_vnfpkg_vnf_lcm.take_action,
parsed_args)
expected_msg = ("Invalid input: File %s does not exist "
"or user does not have read privileges to it")
self.assertEqual(expected_msg % sample_param_file, str(ex))
expected_msg = ("Invalid input: "
"User does not have read privileges to it")
self.assertEqual(expected_msg, str(ex))
@mock.patch("os.open")
@mock.patch("os.access")

View 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)

View 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])

View File

@@ -43,6 +43,28 @@ class TestVIMUtils(testtools.TestCase):
vim_utils.args2body_vim(config_param.copy(), vim)
self.assertEqual(expected_vim, vim)
def test_args2body_vim_extra(self):
auth_cred = {'username': sentinel.usrname1,
'password': sentinel.password1,
'user_domain_name': sentinel.user_domain.name,
'cert_verify': 'True'}
config_param = {'project_name': sentinel.prj_name,
'project_domain_name': sentinel.prj_domain_name1,
'type': 'openstack',
'extra': {'area': 'area_A@region_A'},
**auth_cred}
vim = {}
expected_vim = {'auth_cred': auth_cred,
'vim_project':
{'name': sentinel.prj_name,
'project_domain_name': sentinel.prj_domain_name1},
'type': 'openstack',
'extra': {'area': 'area_A@region_A'}}
vim_utils.args2body_vim(config_param.copy(), vim)
self.assertEqual(expected_vim, vim)
def test_args2body_kubernetes_vim(self):
config_param = {'username': sentinel.usrname1,
'password': sentinel.password1,

View File

@@ -1104,6 +1104,8 @@ class VnfPMClient(ClientBase):
vnf_pm_jobs_path = '/vnfpm/v2/pm_jobs'
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_thresholds_path = '/vnfpm/v2/thresholds'
vnf_pm_threshold_path = '/vnfpm/v2/thresholds/%s'
def build_action(self, action):
return action
@@ -1143,6 +1145,35 @@ class VnfPMClient(ClientBase):
'job_id': vnf_pm_job_id, 'report_id': vnf_pm_report_id
}, 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):
"""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):
return self.vnf_pm_client.show_vnf_pm_report(
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)

View File

@@ -1,7 +1,6 @@
[tox]
envlist = py39,py38,py36,pep8,docs
minversion = 3.18.0
skipsdist = True
ignore_basepython_conflict = True
[testenv]