Compare commits
46 Commits
xena-eol
...
unmaintain
| Author | SHA1 | Date | |
|---|---|---|---|
| 7dbb27989c | |||
| a091ced648 | |||
| 3f04d0a220 | |||
|
|
e5bd58ffe1 | ||
|
|
2add9e0f85 | ||
|
|
a41323dc1d | ||
|
|
a4e0790e75 | ||
|
|
0f9b6f5c52 | ||
|
|
e398f422a8 | ||
|
|
8b45c8082b | ||
|
|
6b168365d6 | ||
|
|
156deea66c | ||
|
|
82bf387f77 | ||
|
|
326d02671e | ||
|
|
6a13f2ecbd | ||
| 0849569507 | |||
|
|
190dc6d581 | ||
| b4e49b3653 | |||
|
|
80ee721263 | ||
|
|
64d7a87670 | ||
|
|
3da27cc89a | ||
|
|
06750997e6 | ||
|
|
52ebdc0aec | ||
|
|
075a327f63 | ||
|
|
fa4a66858e | ||
|
|
bfc0c8fdeb | ||
|
|
0fcb9a59a1 | ||
|
|
21f60be225 | ||
|
|
5c643d007e | ||
| 50c6570c51 | |||
|
|
417f27b9b8 | ||
|
|
ab901b6466 | ||
|
|
3724240344 | ||
|
|
45412f63f0 | ||
|
|
cc73d9d099 | ||
|
|
1c73f54664 | ||
|
|
b7f27c3dc6 | ||
|
|
ccda0487d7 | ||
|
|
6834454309 | ||
|
|
7ee70f5236 | ||
| a3d485cfc5 | |||
|
|
861a57594b | ||
| 015e6e21df | |||
|
|
aed2714275 | ||
|
|
b6aec209fd | ||
| 4299140444 |
@@ -2,3 +2,4 @@
|
||||
host=review.opendev.org
|
||||
port=29418
|
||||
project=openstack/python-tackerclient.git
|
||||
defaultbranch=unmaintained/2023.1
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
- project:
|
||||
templates:
|
||||
- check-requirements
|
||||
- openstack-lower-constraints-jobs
|
||||
- openstack-python3-xena-jobs
|
||||
- openstack-python3-jobs
|
||||
- publish-openstack-docs-pti
|
||||
- release-notes-jobs-python3
|
||||
|
||||
@@ -11,14 +11,6 @@
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
=============
|
||||
Command List
|
||||
=============
|
||||
@@ -76,10 +68,50 @@ of individual command can be referred by **openstack help <command-name>**.
|
||||
openstack nfv event show Show event given the event id.
|
||||
openstack nfv event list List events of resources.
|
||||
openstack vnf package create Create a new individual VNF package resource.
|
||||
openstack vnf package delete Delete given VNF package(s).
|
||||
openstack vnf package list List all VNF packages.
|
||||
openstack vnf package show Show package details.
|
||||
openstack vnf package upload Upload a VNF package by providing the address information
|
||||
of the VNF package.
|
||||
openstack vnf package delete Delete given VNF package(s).
|
||||
|
||||
|
||||
openstack vnf package upload Upload a VNF package.
|
||||
openstack vnf package download Download a VNF package.
|
||||
openstack vnf package artifact download Download a VNF package artifact.
|
||||
openstack vnf package update Update a state of a VNF package.
|
||||
openstack vnflcm create Create a new VNF instance resource.
|
||||
openstack vnflcm instantiate Instantiate a VNF instance.
|
||||
openstack vnflcm list List VNF instance.
|
||||
openstack vnflcm show Show VNF instance.
|
||||
openstack vnflcm terminate Terminate a VNF instance.
|
||||
openstack vnflcm delete Delete a VNF instance resource.
|
||||
openstack vnflcm heal Heal a VNF instance.
|
||||
openstack vnflcm update Update information of a VNF instance.
|
||||
openstack vnflcm scale Scale a VNF instance.
|
||||
openstack vnflcm change-ext-conn Change external VNF connectivity.
|
||||
openstack vnflcm change-vnfpkg Change current VNF package.
|
||||
openstack vnflcm op rollback Rollback a VNF LCM operation occurrence.
|
||||
openstack vnflcm op retry Retry a VNF LCM operation occurrence.
|
||||
openstack vnflcm op fail Fail a VNF LCM operation occurrence.
|
||||
openstack vnflcm op list List VNF LCM operation occurrence.
|
||||
openstack vnflcm op show Show VNF LCM operation occurrence.
|
||||
openstack vnflcm op cancel Cancel a VNF LCM operation occurrence.
|
||||
openstack vnflcm versions Show VNF LCM API versions.
|
||||
openstack vnflcm subsc create Create new subscription.
|
||||
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.
|
||||
|
||||
@@ -1,9 +1,50 @@
|
||||
============
|
||||
..
|
||||
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.
|
||||
|
||||
=========
|
||||
CLI Usage
|
||||
============
|
||||
=========
|
||||
|
||||
Command List
|
||||
------------
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:maxdepth: 3
|
||||
|
||||
*
|
||||
commands
|
||||
|
||||
Operations for ETSI NFV-SOL implementation
|
||||
------------------------------------------
|
||||
|
||||
.. toctree::
|
||||
|
||||
vnf_package_commands
|
||||
vnflcm_commands
|
||||
vnffm_commands
|
||||
vnfpm_commands
|
||||
|
||||
Operations for Legacy implementation
|
||||
------------------------------------
|
||||
|
||||
.. toctree::
|
||||
|
||||
vnf_commands
|
||||
vnf_descriptor_commands
|
||||
vim_commands
|
||||
ns_commands
|
||||
ns_descriptor_commands
|
||||
vnf_graph_commands
|
||||
vnf_graph_descriptor_commands
|
||||
vnf_chain_commands
|
||||
vnf_classifier_commands
|
||||
vnf_network_forwarding_path_commands
|
||||
nfv_event_commands
|
||||
|
||||
24
doc/source/cli/nfv_event_commands.rst
Normal file
24
doc/source/cli/nfv_event_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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.
|
||||
|
||||
=========================
|
||||
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 *
|
||||
24
doc/source/cli/ns_commands.rst
Normal file
24
doc/source/cli/ns_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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.
|
||||
|
||||
===================================
|
||||
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 *
|
||||
24
doc/source/cli/ns_descriptor_commands.rst
Normal file
24
doc/source/cli/ns_descriptor_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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.
|
||||
|
||||
==============================================
|
||||
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 *
|
||||
19
doc/source/cli/vim_commands.rst
Normal file
19
doc/source/cli/vim_commands.rst
Normal file
@@ -0,0 +1,19 @@
|
||||
..
|
||||
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.
|
||||
|
||||
=======================
|
||||
VIM Management commands
|
||||
=======================
|
||||
|
||||
.. autoprogram-cliff:: openstack.tackerclient.v1
|
||||
:command: vim *
|
||||
24
doc/source/cli/vnf_chain_commands.rst
Normal file
24
doc/source/cli/vnf_chain_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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.
|
||||
|
||||
================================================
|
||||
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 *
|
||||
24
doc/source/cli/vnf_classifier_commands.rst
Normal file
24
doc/source/cli/vnf_classifier_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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.
|
||||
|
||||
===================================
|
||||
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 *
|
||||
24
doc/source/cli/vnf_commands.rst
Normal file
24
doc/source/cli/vnf_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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 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 *
|
||||
24
doc/source/cli/vnf_descriptor_commands.rst
Normal file
24
doc/source/cli/vnf_descriptor_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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 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 *
|
||||
24
doc/source/cli/vnf_graph_commands.rst
Normal file
24
doc/source/cli/vnf_graph_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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 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 *
|
||||
24
doc/source/cli/vnf_graph_descriptor_commands.rst
Normal file
24
doc/source/cli/vnf_graph_descriptor_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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 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 *
|
||||
24
doc/source/cli/vnf_network_forwarding_path_commands.rst
Normal file
24
doc/source/cli/vnf_network_forwarding_path_commands.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
..
|
||||
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.
|
||||
|
||||
===========================================
|
||||
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 *
|
||||
@@ -1,3 +1,16 @@
|
||||
..
|
||||
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 Package commands
|
||||
====================
|
||||
|
||||
28
doc/source/cli/vnffm_commands.rst
Normal file
28
doc/source/cli/vnffm_commands.rst
Normal 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 *
|
||||
34
doc/source/cli/vnflcm_commands.rst
Normal file
34
doc/source/cli/vnflcm_commands.rst
Normal file
@@ -0,0 +1,34 @@
|
||||
..
|
||||
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 Lcm commands
|
||||
================
|
||||
|
||||
VNF LCM commands are CLI interface of VNF Lifecycle 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 call version 1 vnflcm APIs by default.
|
||||
You can call the specific version of vnflcm APIs
|
||||
by using the option **\-\-os-tacker-api-version**.
|
||||
Commands with **\-\-os-tacker-api-version 2** call version 2 vnflcm APIs.
|
||||
**vnflcm op cancel** is included in only version 1 vnflcm APIs
|
||||
and **change-vnfpkg** is included in only version 2 vnflcm APIs.
|
||||
|
||||
.. autoprogram-cliff:: openstack.tackerclient.v1
|
||||
:command: vnflcm *
|
||||
|
||||
.. autoprogram-cliff:: openstack.tackerclient.v2
|
||||
:command: vnflcm change-vnfpkg
|
||||
28
doc/source/cli/vnfpm_commands.rst
Normal file
28
doc/source/cli/vnfpm_commands.rst
Normal 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 *
|
||||
@@ -11,14 +11,6 @@
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
|
||||
@@ -11,14 +11,6 @@
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
===================================
|
||||
Developing with Python-TackerClient
|
||||
===================================
|
||||
@@ -42,154 +34,6 @@ For details please refer to the `OpenStack IRC meetings`_ page.
|
||||
Testing
|
||||
=======
|
||||
|
||||
Install the prerequisites for Tox:
|
||||
|
||||
* On Ubuntu or Debian:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ apt-get install gcc gettext python-dev libxml2-dev libxslt1-dev \
|
||||
zlib1g-dev
|
||||
|
||||
You may need to use pip install for some packages.
|
||||
|
||||
|
||||
* On RHEL or CentOS including Fedora:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ yum install gcc python-devel libxml2-devel libxslt-devel
|
||||
|
||||
* On openSUSE or SUSE linux Enterprise:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ zypper install gcc python-devel libxml2-devel libxslt-devel
|
||||
|
||||
Install python-tox:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install tox
|
||||
|
||||
To run the full suite of tests maintained within TackerClient.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tox
|
||||
|
||||
.. NOTE::
|
||||
|
||||
The first time you run ``tox``, it will take additional time to build
|
||||
virtualenvs. You can later use the ``-r`` option with ``tox`` to rebuild
|
||||
your virtualenv in a similar manner.
|
||||
|
||||
|
||||
To run tests for one or more specific test environments(for example, the
|
||||
most common configuration of Python 2.7, Python 3.5 and PEP-8), list the
|
||||
environments with the ``-e`` option, separated by spaces:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tox -e py27,py35,pep8
|
||||
|
||||
See ``tox.ini`` for the full list of available test environments.
|
||||
|
||||
Building the Documentation
|
||||
==========================
|
||||
|
||||
The documentation is generated with Sphinx using the ``tox`` command. To
|
||||
create HTML docs, run the commands:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tox -e docs
|
||||
|
||||
The resultant HTML will be in the ``doc/build/html`` directory.
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
The release notes for a patch should be included in the patch. See the
|
||||
`Project Team Guide`_ for more information on using reno in OpenStack.
|
||||
|
||||
.. _`Project Team Guide`: http://docs.openstack.org/project-team-guide/release-management.html#managing-release-notes
|
||||
|
||||
If any of the following applies to the patch, a release note is required:
|
||||
|
||||
* The deployer needs to take an action when upgrading
|
||||
* The plugin interface changes
|
||||
* A new feature is implemented
|
||||
* A command or option is removed
|
||||
* Current behavior is changed
|
||||
* A security bug is fixed
|
||||
|
||||
Reno is used to generate release notes. Use the commands:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tox -e venv -- reno new <bug-,bp-,whatever>
|
||||
|
||||
Then edit the sample file that was created and push it with your change.
|
||||
|
||||
To run the commands and see results:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git commit # Commit the change because reno scans git log.
|
||||
|
||||
$ tox -e releasenotes
|
||||
|
||||
At last, look at the generated release notes
|
||||
files in ``releasenotes/build/html`` in your browser.
|
||||
|
||||
Testing new code
|
||||
================
|
||||
|
||||
If a developer wants to test new code (feature, command or option) that
|
||||
they have written, Python-TackerClient may be installed from source by running
|
||||
the following commands in the base directory of the project:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ python setup.py install
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install -e .
|
||||
|
||||
Standardize Import Format
|
||||
=========================
|
||||
|
||||
.. _`Import Order Guide`: https://docs.openstack.org/hacking/latest/user/hacking.html#imports
|
||||
|
||||
The import order shows below:
|
||||
|
||||
* {{stdlib imports in human alphabetical order}}
|
||||
* \n
|
||||
* {{third-party lib imports in human alphabetical order}}
|
||||
* \n
|
||||
* {{project imports in human alphabetical order}}
|
||||
* \n
|
||||
* \n
|
||||
* {{begin your code}}
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import copy
|
||||
import fixtures
|
||||
import mock
|
||||
import os
|
||||
|
||||
from osc_lib.api import auth
|
||||
from osc_lib import utils
|
||||
import six
|
||||
|
||||
from openstackclient import shell
|
||||
from openstackclient.tests import utils
|
||||
For details please refer to the `Developing with OpenStackClient`_ page.
|
||||
|
||||
.. _`Developing with OpenStackClient`: https://docs.openstack.org/python-openstackclient/latest/contributor/developing.html
|
||||
@@ -11,14 +11,6 @@
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
=================
|
||||
Contributor Guide
|
||||
=================
|
||||
|
||||
@@ -11,19 +11,12 @@
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
=================================
|
||||
Python-TackerClient Documentation
|
||||
=================================
|
||||
|
||||
This is a client for OpenStack NFV MANO (Tacker) API. It provides
|
||||
Python-TackerClient is a client for OpenStack NFV MANO (Tacker) API.
|
||||
It provides
|
||||
:doc:`Python API bindings <reference/index>` (the tackerclient module) and
|
||||
:doc:`command-line interface (CLI) <cli/index>`.
|
||||
|
||||
|
||||
@@ -11,16 +11,9 @@
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
=========
|
||||
Reference
|
||||
=========
|
||||
|
||||
(To be updated)
|
||||
- `Tacker API reference <https://docs.openstack.org/api-ref/nfv-orchestration/>`_
|
||||
- `Tacker CLI reference <https://docs.openstack.org/tacker/latest/cli/>`_
|
||||
@@ -1,56 +0,0 @@
|
||||
appdirs==1.3.0
|
||||
Babel==2.3.4
|
||||
cliff==2.8.0
|
||||
cmd2==0.8.0
|
||||
coverage==4.0
|
||||
ddt==1.0.1
|
||||
debtcollector==1.2.0
|
||||
decorator==3.4.0
|
||||
deprecation==1.0
|
||||
dogpile.cache==0.6.2
|
||||
extras==1.0.0
|
||||
fixtures==3.0.0
|
||||
iso8601==0.1.11
|
||||
jmespath==0.9.0
|
||||
jsonpatch==1.16
|
||||
jsonpointer==1.13
|
||||
keystoneauth1==3.4.0
|
||||
linecache2==1.0.0
|
||||
monotonic==0.6
|
||||
msgpack-python==0.4.0
|
||||
munch==2.1.0
|
||||
netaddr==0.7.18
|
||||
netifaces==0.10.4
|
||||
openstacksdk==0.11.2
|
||||
os-client-config==1.28.0
|
||||
os-service-types==1.2.0
|
||||
osc-lib==1.8.0
|
||||
oslo.config==5.2.0
|
||||
oslo.context==2.19.2
|
||||
oslo.i18n==3.15.3
|
||||
oslo.log==3.36.0
|
||||
oslo.serialization==2.18.0
|
||||
oslo.utils==3.40.0
|
||||
pbr==2.0.0
|
||||
positional==1.2.1
|
||||
prettytable==0.7.2
|
||||
pyinotify==0.9.6
|
||||
pyparsing==2.1.0
|
||||
pyperclip==1.5.27
|
||||
python-dateutil==2.5.3
|
||||
python-keystoneclient==3.8.0
|
||||
python-mimeparse==1.6.0
|
||||
python-subunit==1.0.0
|
||||
pytz==2013.6
|
||||
PyYAML==3.12
|
||||
requests==2.14.2
|
||||
requests-mock==1.2.0
|
||||
requestsexceptions==1.2.0
|
||||
rfc3986==0.3.1
|
||||
simplejson==3.5.1
|
||||
stestr==2.0.0
|
||||
stevedore==1.20.0
|
||||
testtools==2.2.0
|
||||
traceback2==1.4.0
|
||||
unittest2==1.1.0
|
||||
wrapt==1.7.0
|
||||
@@ -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).
|
||||
@@ -7,6 +7,10 @@ Contents:
|
||||
:maxdepth: 2
|
||||
|
||||
unreleased
|
||||
zed
|
||||
yoga
|
||||
xena
|
||||
wallaby
|
||||
victoria
|
||||
ussuri
|
||||
train
|
||||
|
||||
6
releasenotes/source/wallaby.rst
Normal file
6
releasenotes/source/wallaby.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
============================
|
||||
Wallaby Series Release Notes
|
||||
============================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/wallaby
|
||||
6
releasenotes/source/xena.rst
Normal file
6
releasenotes/source/xena.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
=========================
|
||||
Xena Series Release Notes
|
||||
=========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/xena
|
||||
6
releasenotes/source/yoga.rst
Normal file
6
releasenotes/source/yoga.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
=========================
|
||||
Yoga Series Release Notes
|
||||
=========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/yoga
|
||||
6
releasenotes/source/zed.rst
Normal file
6
releasenotes/source/zed.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
========================
|
||||
Zed Series Release Notes
|
||||
========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/zed
|
||||
46
setup.cfg
46
setup.cfg
@@ -1,12 +1,12 @@
|
||||
[metadata]
|
||||
name = python-tackerclient
|
||||
summary = CLI and Client Library for OpenStack Tacker
|
||||
description-file =
|
||||
description_file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author-email = openstack-discuss@lists.openstack.org
|
||||
home-page = https://docs.openstack.org/python-tackerclient/
|
||||
python-requires = >=3.6
|
||||
author_email = openstack-discuss@lists.openstack.org
|
||||
home_page = https://docs.openstack.org/python-tackerclient/
|
||||
python_requires = >=3.6
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Developers
|
||||
@@ -20,6 +20,9 @@ classifier =
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
|
||||
[files]
|
||||
packages =
|
||||
@@ -96,10 +99,15 @@ openstack.tackerclient.v1 =
|
||||
vnflcm_scale = tackerclient.osc.v1.vnflcm.vnflcm:ScaleVnfLcm
|
||||
vnflcm_change-ext-conn = tackerclient.osc.v1.vnflcm.vnflcm:ChangeExtConnVnfLcm
|
||||
vnflcm_op_rollback = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RollbackVnfLcmOp
|
||||
vnflcm_op_cancel = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:CancelVnfLcmOp
|
||||
vnflcm_op_fail = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:FailVnfLcmOp
|
||||
vnflcm_op_retry = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RetryVnfLcmOp
|
||||
vnflcm_op_list = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ListVnfLcmOp
|
||||
vnflcm_op_show = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ShowVnfLcmOp
|
||||
vnflcm_subsc_create = tackerclient.osc.v1.vnflcm.vnflcm_subsc:CreateLccnSubscription
|
||||
vnflcm_subsc_delete = tackerclient.osc.v1.vnflcm.vnflcm_subsc:DeleteLccnSubscription
|
||||
vnflcm_subsc_list = tackerclient.osc.v1.vnflcm.vnflcm_subsc:ListLccnSubscription
|
||||
vnflcm_subsc_show = tackerclient.osc.v1.vnflcm.vnflcm_subsc:ShowLccnSubscription
|
||||
vnflcm_versions = tackerclient.osc.common.vnflcm.vnflcm_versions:VnfLcmVersions
|
||||
openstack.tackerclient.v2 =
|
||||
vnflcm_create = tackerclient.osc.v1.vnflcm.vnflcm:CreateVnfLcm
|
||||
@@ -107,7 +115,37 @@ openstack.tackerclient.v2 =
|
||||
vnflcm_list = tackerclient.osc.v1.vnflcm.vnflcm:ListVnfLcm
|
||||
vnflcm_instantiate = tackerclient.osc.v1.vnflcm.vnflcm:InstantiateVnfLcm
|
||||
vnflcm_terminate = tackerclient.osc.v1.vnflcm.vnflcm:TerminateVnfLcm
|
||||
vnflcm_change-vnfpkg = tackerclient.osc.v1.vnflcm.vnflcm:ChangeVnfPkgVnfLcm
|
||||
vnflcm_delete = tackerclient.osc.v1.vnflcm.vnflcm:DeleteVnfLcm
|
||||
vnflcm_heal = tackerclient.osc.v1.vnflcm.vnflcm:HealVnfLcm
|
||||
vnflcm_update = tackerclient.osc.v1.vnflcm.vnflcm:UpdateVnfLcm
|
||||
vnflcm_scale = tackerclient.osc.v1.vnflcm.vnflcm:ScaleVnfLcm
|
||||
vnflcm_change-ext-conn = tackerclient.osc.v1.vnflcm.vnflcm:ChangeExtConnVnfLcm
|
||||
vnflcm_op_rollback = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RollbackVnfLcmOp
|
||||
vnflcm_op_fail = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:FailVnfLcmOp
|
||||
vnflcm_op_retry = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RetryVnfLcmOp
|
||||
vnflcm_op_list = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ListVnfLcmOp
|
||||
vnflcm_op_show = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ShowVnfLcmOp
|
||||
vnflcm_subsc_create = tackerclient.osc.v1.vnflcm.vnflcm_subsc:CreateLccnSubscription
|
||||
vnflcm_subsc_delete = tackerclient.osc.v1.vnflcm.vnflcm_subsc:DeleteLccnSubscription
|
||||
vnflcm_subsc_list = tackerclient.osc.v1.vnflcm.vnflcm_subsc:ListLccnSubscription
|
||||
vnflcm_subsc_show = tackerclient.osc.v1.vnflcm.vnflcm_subsc:ShowLccnSubscription
|
||||
vnflcm_versions = tackerclient.osc.common.vnflcm.vnflcm_versions:VnfLcmVersions
|
||||
vnfpm_job_create = tackerclient.osc.v2.vnfpm.vnfpm_job:CreateVnfPmJob
|
||||
vnfpm_job_list = tackerclient.osc.v2.vnfpm.vnfpm_job:ListVnfPmJob
|
||||
vnfpm_job_show = tackerclient.osc.v2.vnfpm.vnfpm_job:ShowVnfPmJob
|
||||
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
|
||||
vnffm_sub_create = tackerclient.osc.v2.vnffm.vnffm_sub:CreateVnfFmSub
|
||||
vnffm_sub_list = tackerclient.osc.v2.vnffm.vnffm_sub:ListVnfFmSub
|
||||
vnffm_sub_show = tackerclient.osc.v2.vnffm.vnffm_sub:ShowVnfFmSub
|
||||
vnffm_sub_delete = tackerclient.osc.v2.vnffm.vnffm_sub:DeleteVnfFmSub
|
||||
|
||||
@@ -207,6 +207,14 @@ class InvalidInput(TackerClientException):
|
||||
message = _("Invalid input: %(reason)s")
|
||||
|
||||
|
||||
class EmptyInput(TackerClientException):
|
||||
message = _("Empty input: %(reason)s")
|
||||
|
||||
|
||||
class UnsupportedCommandVersion(TackerClientException):
|
||||
message = _("This command is not supported in version %(version)s")
|
||||
|
||||
|
||||
# Command line exceptions
|
||||
|
||||
class TackerCLIError(TackerException):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"filter": {
|
||||
"vnfInstanceSubscriptionFilter": {
|
||||
"vnfdIds": [
|
||||
"dummy-vnfdId-1",
|
||||
"dummy-vnfdId-2"
|
||||
],
|
||||
"vnfProductsFromProviders": [
|
||||
{
|
||||
"vnfProvider": "dummy-vnfProvider-1",
|
||||
"vnfProducts": [
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-1-1",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersions": ["1.0", "2.0"]
|
||||
},
|
||||
{
|
||||
"vnfSoftwareVersion": "1.1",
|
||||
"vnfdVersions": ["1.1", "2.1"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-1-2",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersions": ["1.0", "2.0"]
|
||||
},
|
||||
{
|
||||
"vnfSoftwareVersion": "1.1",
|
||||
"vnfdVersions": ["1.1", "2.1"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"vnfProvider": "dummy-vnfProvider-2",
|
||||
"vnfProducts": [
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-2-1",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersions": ["1.0", "2.0"]
|
||||
},
|
||||
{
|
||||
"vnfSoftwareVersion": "1.1",
|
||||
"vnfdVersions": ["1.1", "2.1"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-2-2",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersions": ["1.0", "2.0"]
|
||||
},
|
||||
{
|
||||
"vnfSoftwareVersion": "1.1",
|
||||
"vnfdVersions": ["1.1", "2.1"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vnfInstanceIds": [
|
||||
"dummy-vnfInstanceId-1",
|
||||
"dummy-vnfInstanceId-2"
|
||||
],
|
||||
"vnfInstanceNames": [
|
||||
"dummy-vnfInstanceName-1",
|
||||
"dummy-vnfInstanceName-2"
|
||||
]
|
||||
},
|
||||
"notificationTypes": [
|
||||
"VnfLcmOperationOccurrenceNotification",
|
||||
"VnfIdentifierCreationNotification",
|
||||
"VnfIdentifierDeletionNotification"
|
||||
],
|
||||
"operationTypes": [
|
||||
"INSTANTIATE",
|
||||
"SCALE",
|
||||
"TERMINATE",
|
||||
"HEAL",
|
||||
"MODIFY_INFO",
|
||||
"CHANGE_EXT_CONN"
|
||||
],
|
||||
"operationStates": [
|
||||
"COMPLETED",
|
||||
"FAILED",
|
||||
"FAILED_TEMP",
|
||||
"PROCESSING",
|
||||
"ROLLING_BACK",
|
||||
"ROLLED_BACK",
|
||||
"STARTING"
|
||||
]
|
||||
},
|
||||
"callbackUri": "http://localhost:9990/notification/callback/test",
|
||||
"authentication": {
|
||||
"authType": [
|
||||
"BASIC"
|
||||
],
|
||||
"paramsBasic": {
|
||||
"password": "test_pass",
|
||||
"userName": "test_user"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"additionalParams": {"all": true}
|
||||
}
|
||||
@@ -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'
|
||||
@@ -238,6 +213,12 @@ class HealVnfLcm(command.Command):
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(HealVnfLcm, self).get_parser(prog_name)
|
||||
usage_message = ('''%(prog)s [-h] [--cause CAUSE]
|
||||
[--vnfc-instance <vnfc-instance-id> '''
|
||||
'''[<vnfc-instance-id> ...]]
|
||||
[--additional-param-file <additional-param-file>]
|
||||
-- <vnf-instance>''')
|
||||
parser.usage = usage_message
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
@@ -251,6 +232,11 @@ class HealVnfLcm(command.Command):
|
||||
nargs="+",
|
||||
help=_("List of VNFC instances requiring a healing action.")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--additional-param-file',
|
||||
metavar="<additional-param-file>",
|
||||
help=_("Additional parameters passed by the NFVO as input "
|
||||
"to the healing process."))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
@@ -259,6 +245,9 @@ class HealVnfLcm(command.Command):
|
||||
body['cause'] = parsed_args.cause
|
||||
if parsed_args.vnfc_instance:
|
||||
body['vnfcInstanceId'] = parsed_args.vnfc_instance
|
||||
if parsed_args.additional_param_file:
|
||||
body.update(tacker_osc_utils.jsonfile2body(
|
||||
parsed_args.additional_param_file))
|
||||
|
||||
return body
|
||||
|
||||
@@ -334,7 +323,7 @@ class TerminateVnfLcm(command.Command):
|
||||
|
||||
result = client.delete_vnf_instance(parsed_args.vnf_instance)
|
||||
if not result:
|
||||
print(_("VNF Instance '%(id)s' deleted successfully") %
|
||||
print(_("VNF Instance '%(id)s' is deleted successfully") %
|
||||
{'id': parsed_args.vnf_instance})
|
||||
|
||||
def _wait_until_vnf_is_terminated(self, client, vnf_instance_id,
|
||||
@@ -407,7 +396,7 @@ class DeleteVnfLcm(command.Command):
|
||||
print(_('All specified vnf instances are deleted '
|
||||
'successfully'))
|
||||
else:
|
||||
print(_("Vnf instance '%s' deleted "
|
||||
print(_("Vnf instance '%s' is deleted "
|
||||
"successfully") % vnf_instances[0])
|
||||
|
||||
|
||||
@@ -448,7 +437,7 @@ class UpdateVnfLcm(command.Command):
|
||||
body = {}
|
||||
|
||||
if file_path:
|
||||
return jsonfile2body(file_path)
|
||||
return tacker_osc_utils.jsonfile2body(file_path)
|
||||
|
||||
return body
|
||||
|
||||
@@ -522,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
|
||||
|
||||
@@ -561,8 +551,35 @@ 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 '
|
||||
'has been accepted.') % parsed_args.vnf_instance))
|
||||
|
||||
|
||||
class ChangeVnfPkgVnfLcm(command.Command):
|
||||
_description = _("Change Current VNF Package")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ChangeVnfPkgVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_("VNF instance ID to Change Current VNF Package"))
|
||||
parser.add_argument(
|
||||
'request_file',
|
||||
metavar="<param-file>",
|
||||
help=_("Specify change-vnfpkg request parameters "
|
||||
"in a json file."))
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.change_vnfpkg_vnf_instance(
|
||||
parsed_args.vnf_instance, tacker_osc_utils.jsonfile2body(
|
||||
parsed_args.request_file))
|
||||
if not result:
|
||||
print((_('Change Current VNF Package for VNF Instance %s '
|
||||
'has been accepted.') % parsed_args.vnf_instance))
|
||||
|
||||
@@ -101,6 +101,47 @@ class RollbackVnfLcmOp(command.Command):
|
||||
' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id}))
|
||||
|
||||
|
||||
class CancelVnfLcmOp(command.ShowOne):
|
||||
_description = _("Cancel VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
prog_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(CancelVnfLcmOp, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_LCM_OP_OCC_ID,
|
||||
metavar="<vnf-lcm-op-occ-id>",
|
||||
help=_('VNF lifecycle management operation occurrence ID.'))
|
||||
parser.add_argument(
|
||||
"--cancel-mode",
|
||||
default='GRACEFUL',
|
||||
metavar="<cancel-mode>",
|
||||
choices=['GRACEFUL', 'FORCEFUL'],
|
||||
help=_("Cancel mode can be 'GRACEFUL' or 'FORCEFUL'. "
|
||||
"Default is 'GRACEFUL'"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute cancel_vnf_instance and output comment.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.cancel_vnf_instance(
|
||||
parsed_args.vnf_lcm_op_occ_id,
|
||||
{'cancelMode': parsed_args.cancel_mode})
|
||||
if not result:
|
||||
print((_('Cancel request for LCM operation %(id)s has been'
|
||||
' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id}))
|
||||
|
||||
|
||||
class FailVnfLcmOp(command.ShowOne):
|
||||
_description = _("Fail VNF Instance")
|
||||
|
||||
@@ -201,9 +242,12 @@ class ListVnfLcmOp(command.Lister):
|
||||
)
|
||||
return parser
|
||||
|
||||
def get_attributes(self):
|
||||
def get_attributes(self, exclude=None):
|
||||
"""Get attributes.
|
||||
|
||||
Args:
|
||||
exclude([exclude]): a list of fields which needs to exclude.
|
||||
|
||||
Returns:
|
||||
attributes([attributes]): a list of table entry definitions.
|
||||
Each entry should be a tuple consisting of
|
||||
@@ -229,10 +273,13 @@ class ListVnfLcmOp(command.Lister):
|
||||
]
|
||||
|
||||
attributes = []
|
||||
for field in fields:
|
||||
attributes.extend([(field['key'], field['value'],
|
||||
tacker_osc_utils.LIST_BOTH)])
|
||||
if exclude is None:
|
||||
exclude = []
|
||||
|
||||
for field in fields:
|
||||
if field['value'] not in exclude:
|
||||
attributes.extend([(field['key'], field['value'],
|
||||
tacker_osc_utils.LIST_BOTH)])
|
||||
return tuple(attributes)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@@ -260,7 +307,7 @@ class ListVnfLcmOp(command.Lister):
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnflcm_op_occs = client.list_vnf_lcm_op_occs(**params)
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.get_attributes(),
|
||||
self.get_attributes(exclude=exclude_fields),
|
||||
long_listing=True)
|
||||
|
||||
dictionary_properties = (utils.get_dict_properties(
|
||||
|
||||
181
tackerclient/osc/v1/vnflcm/vnflcm_subsc.py
Normal file
181
tackerclient/osc/v1/vnflcm/vnflcm_subsc.py
Normal file
@@ -0,0 +1,181 @@
|
||||
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
|
||||
# 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__)
|
||||
|
||||
_LCCN_SUBSCRIPTION_ID = 'subscription_id'
|
||||
|
||||
_MIXED_CASE_FIELDS = ['filter', 'callbackUri']
|
||||
|
||||
_FORMATTERS = {
|
||||
'filter': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'_links': tacker_osc_utils.FormatComplexDataColumn
|
||||
}
|
||||
|
||||
|
||||
def _get_columns(lccn_subsc_obj):
|
||||
|
||||
column_map = {
|
||||
'id': 'ID',
|
||||
'filter': 'Filter',
|
||||
'callbackUri': 'Callback URI',
|
||||
'_links': 'Links'
|
||||
}
|
||||
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(lccn_subsc_obj,
|
||||
column_map)
|
||||
|
||||
|
||||
class CreateLccnSubscription(command.ShowOne):
|
||||
_description = _("Create a new Lccn Subscription")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateLccnSubscription, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'create_request_file',
|
||||
metavar="<param-file>",
|
||||
help=_('Specify create request parameters in a json file.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
subsc = client.create_lccn_subscription(
|
||||
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,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class DeleteLccnSubscription(command.Command):
|
||||
_description = _("Delete Lccn Subscription(s)")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteLccnSubscription, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_LCCN_SUBSCRIPTION_ID,
|
||||
metavar="<subscription-id>",
|
||||
nargs="+",
|
||||
help=_("Lccn Subscription ID(s) to delete"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
error_count = 0
|
||||
client = self.app.client_manager.tackerclient
|
||||
lccn_subscriptions = parsed_args.subscription_id
|
||||
for lccn_subscription in lccn_subscriptions:
|
||||
try:
|
||||
client.delete_lccn_subscription(lccn_subscription)
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
LOG.error(_("Failed to delete Lccn Subscription with "
|
||||
"ID '%(subsc)s': %(e)s"),
|
||||
{'subsc': lccn_subscription, 'e': e})
|
||||
|
||||
total = len(lccn_subscriptions)
|
||||
if (error_count > 0):
|
||||
msg = (_("Failed to delete %(error_count)s of %(total)s "
|
||||
"Lccn Subscriptions.") % {'error_count': error_count,
|
||||
'total': total})
|
||||
raise exceptions.CommandError(message=msg)
|
||||
else:
|
||||
if total > 1:
|
||||
print(_('All specified Lccn Subscriptions are deleted '
|
||||
'successfully'))
|
||||
else:
|
||||
print(_("Lccn Subscription '%s' is deleted "
|
||||
"successfully") % lccn_subscriptions[0])
|
||||
|
||||
|
||||
class ListLccnSubscription(command.Lister):
|
||||
_description = _("List Lccn Subscriptions")
|
||||
|
||||
def get_parser(self, program_name):
|
||||
parser = super(ListLccnSubscription, self).get_parser(program_name)
|
||||
parser.add_argument(
|
||||
"--filter",
|
||||
metavar="<filter>",
|
||||
help=_("Attribute-based-filtering parameters"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def get_attributes(self, exclude=None):
|
||||
fields = [
|
||||
{
|
||||
"key": "id",
|
||||
"value": "ID"
|
||||
},
|
||||
{
|
||||
"key": "callbackUri",
|
||||
"value": "Callback URI"
|
||||
}
|
||||
]
|
||||
|
||||
attributes = []
|
||||
|
||||
for field in fields:
|
||||
attributes.extend([(field['key'], field['value'],
|
||||
tacker_osc_utils.LIST_BOTH)])
|
||||
return tuple(attributes)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
params = {}
|
||||
|
||||
if parsed_args.filter:
|
||||
params['filter'] = parsed_args.filter
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
subscriptions = client.list_lccn_subscriptions(**params)
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.get_attributes(), long_listing=True)
|
||||
|
||||
dictionary_properties = (utils.get_dict_properties(
|
||||
s, columns, mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
for s in subscriptions
|
||||
)
|
||||
|
||||
return (headers, dictionary_properties)
|
||||
|
||||
|
||||
class ShowLccnSubscription(command.ShowOne):
|
||||
_description = _("Display Lccn Subscription details")
|
||||
|
||||
def get_parser(self, program_name):
|
||||
parser = super(ShowLccnSubscription, self).get_parser(program_name)
|
||||
parser.add_argument(
|
||||
_LCCN_SUBSCRIPTION_ID,
|
||||
metavar="<subscription-id>",
|
||||
help=_('Lccn Subscription ID to display'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.show_lccn_subscription(parsed_args.subscription_id)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj),
|
||||
columns, formatters=_FORMATTERS,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
return (display_columns, data)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
0
tackerclient/osc/v2/__init__.py
Normal file
0
tackerclient/osc/v2/__init__.py
Normal file
0
tackerclient/osc/v2/vnffm/__init__.py
Normal file
0
tackerclient/osc/v2/vnffm/__init__.py
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"filter": {
|
||||
"vnfInstanceSubscriptionFilter": {
|
||||
"vnfdIds": [
|
||||
"dummy-vnfdId-1"
|
||||
],
|
||||
"vnfProductsFromProviders": [
|
||||
{
|
||||
"vnfProvider": "dummy-vnfProvider-1",
|
||||
"vnfProducts": [
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-1-1",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": 1.0,
|
||||
"vnfdVersions": [1.0, 2.0]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vnfInstanceIds": [
|
||||
"dummy-vnfInstanceId-1"
|
||||
],
|
||||
"vnfInstanceNames": [
|
||||
"dummy-vnfInstanceName-1"
|
||||
]
|
||||
},
|
||||
"notificationTypes": [
|
||||
"AlarmNotification"
|
||||
],
|
||||
"faultyResourceTypes": [
|
||||
"COMPUTE"
|
||||
],
|
||||
"perceivedSeverities": [
|
||||
"WARNING"
|
||||
],
|
||||
"eventTypes": [
|
||||
"EQUIPMENT_ALARM"
|
||||
],
|
||||
"probableCauses": [
|
||||
"The server cannot be connected."
|
||||
]
|
||||
},
|
||||
"callbackUri": "/nfvo/notify/alarm",
|
||||
"authentication": {
|
||||
"authType": [
|
||||
"BASIC",
|
||||
"OAUTH2_CLIENT_CREDENTIALS"
|
||||
],
|
||||
"paramsBasic": {
|
||||
"userName": "nfvo",
|
||||
"password": "nfvopwd"
|
||||
},
|
||||
"paramsOauth2ClientCredentials": {
|
||||
"clientId": "auth_user_name",
|
||||
"clientPassword": "auth_password",
|
||||
"tokenEndpoint": "token_endpoint"
|
||||
}
|
||||
}
|
||||
}
|
||||
177
tackerclient/osc/v2/vnffm/vnffm_alarm.py
Normal file
177
tackerclient/osc/v2/vnffm/vnffm_alarm.py
Normal file
@@ -0,0 +1,177 @@
|
||||
# Copyright (C) 2022 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.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),
|
||||
('managedObjectId', 'Managed Object Id', tacker_osc_utils.LIST_BOTH),
|
||||
('ackState', 'Ack State', tacker_osc_utils.LIST_BOTH),
|
||||
('eventType', 'Event Type', tacker_osc_utils.LIST_BOTH),
|
||||
('perceivedSeverity', 'Perceived Severity', tacker_osc_utils.LIST_BOTH),
|
||||
('probableCause', 'Probable Cause', tacker_osc_utils.LIST_BOTH)
|
||||
)
|
||||
|
||||
_FORMATTERS = {
|
||||
'vnfcInstanceIds': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'rootCauseFaultyResource': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'correlatedAlarmIds': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'faultDetails': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'_links': tacker_osc_utils.FormatComplexDataColumn
|
||||
}
|
||||
|
||||
_MIXED_CASE_FIELDS = (
|
||||
'managedObjectId', 'rootCauseFaultyResource', 'vnfcInstanceIds',
|
||||
'alarmRaisedTime', 'alarmChangedTime', 'alarmClearedTime',
|
||||
'alarmAcknowledgedTime', 'ackState', 'perceivedSeverity', 'eventTime',
|
||||
'eventType', 'faultType', 'probableCause', 'isRootCause',
|
||||
'correlatedAlarmIds', 'faultDetails'
|
||||
)
|
||||
|
||||
_VNF_FM_ALARM_ID = 'vnf_fm_alarm_id'
|
||||
|
||||
|
||||
def _get_columns(vnffm_alarm_obj, action=None):
|
||||
if action == 'update':
|
||||
column_map = {
|
||||
'ackState': 'Ack State'
|
||||
}
|
||||
else:
|
||||
column_map = {
|
||||
'id': 'ID',
|
||||
'managedObjectId': 'Managed Object Id',
|
||||
'ackState': 'Ack State',
|
||||
'perceivedSeverity': 'Perceived Severity',
|
||||
'eventType': 'Event Type',
|
||||
'probableCause': 'Probable Cause'
|
||||
}
|
||||
|
||||
if action == 'show':
|
||||
column_map.update({
|
||||
'vnfcInstanceIds': 'Vnfc Instance Ids',
|
||||
'rootCauseFaultyResource': 'Root Cause Faulty Resource',
|
||||
'alarmRaisedTime': 'Alarm Raised Time',
|
||||
'alarmChangedTime': 'Alarm Changed Time',
|
||||
'alarmClearedTime': 'Alarm Cleared Time',
|
||||
'alarmAcknowledgedTime': 'Alarm Acknowledged Time',
|
||||
'eventTime': 'Event Time',
|
||||
'faultType': 'Fault Type',
|
||||
'isRootCause': 'Is Root Cause',
|
||||
'correlatedAlarmIds': 'Correlated Alarm Ids',
|
||||
'faultDetails': 'Fault Details',
|
||||
'_links': 'Links'
|
||||
})
|
||||
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(
|
||||
vnffm_alarm_obj, column_map)
|
||||
|
||||
|
||||
class ListVnfFmAlarm(command.Lister):
|
||||
_description = _("List VNF FM alarms")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
LOG.debug('get_parser(%s)', prog_name)
|
||||
parser = super(ListVnfFmAlarm, 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_fm_alarms(**_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_fm_alarms']))
|
||||
|
||||
|
||||
class ShowVnfFmAlarm(command.ShowOne):
|
||||
_description = _("Display VNF FM alarm details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowVnfFmAlarm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_FM_ALARM_ID,
|
||||
metavar="<vnf-fm-alarm-id>",
|
||||
help=_("VNF FM alarm ID to display"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.show_vnf_fm_alarm(parsed_args.vnf_fm_alarm_id)
|
||||
display_columns, columns = _get_columns(obj, action='show')
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj), columns,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS,
|
||||
formatters=_FORMATTERS)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class UpdateVnfFmAlarm(command.ShowOne):
|
||||
_description = _("Update information about an individual VNF FM alarm")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
LOG.debug('get_parser(%s)', prog_name)
|
||||
parser = super(UpdateVnfFmAlarm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_FM_ALARM_ID,
|
||||
metavar="<vnf-fm-alarm-id>",
|
||||
help=_("VNF FM alarm ID to update.")
|
||||
)
|
||||
update_require_parameters = parser.add_argument_group(
|
||||
"require arguments"
|
||||
)
|
||||
update_require_parameters.add_argument(
|
||||
"--ack-state",
|
||||
metavar="<ack-state>",
|
||||
choices=['ACKNOWLEDGED', 'UNACKNOWLEDGED'],
|
||||
help=_("Ask state can be 'ACKNOWLEDGED' or 'UNACKNOWLEDGED'."))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {'ackState': parsed_args.ack_state}
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
updated_values = client.update_vnf_fm_alarm(
|
||||
parsed_args.vnf_fm_alarm_id, self.args2body(parsed_args))
|
||||
display_columns, columns = _get_columns(
|
||||
updated_values, action='update')
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(updated_values), columns,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS,
|
||||
formatters=_FORMATTERS)
|
||||
return (display_columns, data)
|
||||
169
tackerclient/osc/v2/vnffm/vnffm_sub.py
Normal file
169
tackerclient/osc/v2/vnffm/vnffm_sub.py
Normal file
@@ -0,0 +1,169 @@
|
||||
# Copyright (C) 2022 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),
|
||||
('callbackUri', 'Callback Uri', tacker_osc_utils.LIST_BOTH)
|
||||
)
|
||||
|
||||
_FORMATTERS = {
|
||||
'filter': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'_links': tacker_osc_utils.FormatComplexDataColumn
|
||||
}
|
||||
|
||||
_MIXED_CASE_FIELDS = (
|
||||
'callbackUri'
|
||||
)
|
||||
|
||||
_VNF_FM_SUB_ID = 'vnf_fm_sub_id'
|
||||
|
||||
|
||||
def _get_columns(vnffm_sub_obj):
|
||||
column_map = {
|
||||
'id': 'ID',
|
||||
'filter': 'Filter',
|
||||
'callbackUri': 'Callback Uri',
|
||||
'_links': 'Links'
|
||||
}
|
||||
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(
|
||||
vnffm_sub_obj, column_map)
|
||||
|
||||
|
||||
class CreateVnfFmSub(command.ShowOne):
|
||||
_description = _("Create a new VNF FM subscription")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateVnfFmSub, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'request_file',
|
||||
metavar="<param-file>",
|
||||
help=_('Specify create VNF FM subscription request '
|
||||
'parameters in a json file.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnf_fm_sub = client.create_vnf_fm_sub(
|
||||
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,
|
||||
formatters=_FORMATTERS, mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ListVnfFmSub(command.Lister):
|
||||
_description = _("List VNF FM subs")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
LOG.debug('get_parser(%s)', prog_name)
|
||||
parser = super(ListVnfFmSub, 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_fm_subs(**_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_fm_subs']))
|
||||
|
||||
|
||||
class ShowVnfFmSub(command.ShowOne):
|
||||
_description = _("Display VNF FM subscription details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowVnfFmSub, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_FM_SUB_ID,
|
||||
metavar="<vnf-fm-sub-id>",
|
||||
help=_("VNF FM subscription ID to display"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.show_vnf_fm_sub(parsed_args.vnf_fm_sub_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 DeleteVnfFmSub(command.Command):
|
||||
_description = _("Delete VNF FM subscription(s)")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteVnfFmSub, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_FM_SUB_ID,
|
||||
metavar="<vnf-fm-sub-id>",
|
||||
nargs="+",
|
||||
help=_("VNF FM subscription ID(s) to delete"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
error_count = 0
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnf_fm_sub_ids = parsed_args.vnf_fm_sub_id
|
||||
|
||||
for sub_id in vnf_fm_sub_ids:
|
||||
try:
|
||||
client.delete_vnf_fm_sub(sub_id)
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
LOG.error(_("Failed to delete VNF FM subscription with "
|
||||
"ID '%(sub_id)s': %(e)s"),
|
||||
{'sub_id': sub_id, 'e': e})
|
||||
|
||||
total = len(vnf_fm_sub_ids)
|
||||
if error_count > 0:
|
||||
msg = (_("Failed to delete %(error_count)s of %(total)s "
|
||||
"VNF FM subscriptions.") % {'error_count': error_count,
|
||||
'total': total})
|
||||
raise exceptions.CommandError(message=msg)
|
||||
|
||||
if total > 1:
|
||||
print(_('All specified VNF FM subscriptions are deleted '
|
||||
'successfully'))
|
||||
else:
|
||||
print(_("VNF FM subscription '%s' deleted "
|
||||
"successfully") % vnf_fm_sub_ids[0])
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"vnfdId": "c6595341-a5bb-8246-53c4-7aeb843d60c5",
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf": "./Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"vdu_params": [{
|
||||
"vduId": "VDU1",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "VDU1_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "VDU1_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
}
|
||||
}, {
|
||||
"vduId": "VDU2",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "VDU2_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "VDU2_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
0
tackerclient/osc/v2/vnfpm/__init__.py
Normal file
0
tackerclient/osc/v2/vnfpm/__init__.py
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"objectType": "VNFC",
|
||||
"objectInstanceIds": [
|
||||
"object-instance-id-1"
|
||||
],
|
||||
"subObjectInstanceIds": [
|
||||
"sub-object-instance-id-2"
|
||||
],
|
||||
"criteria": {
|
||||
"performanceMetric": [
|
||||
"VCpuUsageMeanVnf.object-instance-id-1"
|
||||
],
|
||||
"performanceMetricGroup": [
|
||||
"VirtualisedComputeResource"
|
||||
],
|
||||
"collectionPeriod": "500",
|
||||
"reportingPeriod": "1000",
|
||||
"reportingBoundary": "2022/07/25 10:43:55"
|
||||
},
|
||||
"callbackUri": "/nfvo/notify/job",
|
||||
"authentication": {
|
||||
"authType": [
|
||||
"BASIC",
|
||||
"OAUTH2_CLIENT_CREDENTIALS"
|
||||
],
|
||||
"paramsBasic": {
|
||||
"userName": "nfvo",
|
||||
"password": "nfvopwd"
|
||||
},
|
||||
"paramsOauth2ClientCredentials": {
|
||||
"clientId": "auth_user_name",
|
||||
"clientPassword": "auth_password",
|
||||
"tokenEndpoint": "token_endpoint"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,18 @@
|
||||
{
|
||||
"callbackUri": "/nfvo/notify/job",
|
||||
"authentication": {
|
||||
"authType": [
|
||||
"BASIC",
|
||||
"OAUTH2_CLIENT_CREDENTIALS"
|
||||
],
|
||||
"paramsBasic": {
|
||||
"userName": "nfvo",
|
||||
"password": "nfvopwd"
|
||||
},
|
||||
"paramsOauth2ClientCredentials": {
|
||||
"clientId": "auth_user_name",
|
||||
"clientPassword": "auth_password",
|
||||
"tokenEndpoint": "token_endpoint"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
306
tackerclient/osc/v2/vnfpm/vnfpm_job.py
Normal file
306
tackerclient/osc/v2/vnfpm/vnfpm_job.py
Normal file
@@ -0,0 +1,306 @@
|
||||
# Copyright (C) 2022 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 functools import reduce
|
||||
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__)
|
||||
|
||||
_FORMATTERS = {
|
||||
'objectInstanceIds': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'subObjectInstanceIds': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'criteria': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'reports': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'_links': tacker_osc_utils.FormatComplexDataColumn
|
||||
}
|
||||
|
||||
_FORMATTERS_UPDATE = {
|
||||
'authentication': tacker_osc_utils.FormatComplexDataColumn
|
||||
}
|
||||
|
||||
_MIXED_CASE_FIELDS = (
|
||||
'objectType', 'objectInstanceIds', 'subObjectInstanceIds', 'callbackUri'
|
||||
)
|
||||
|
||||
_MIXED_CASE_FIELDS_UPDATE = (
|
||||
'callbackUri'
|
||||
)
|
||||
|
||||
_VNF_PM_JOB_ID = 'vnf_pm_job_id'
|
||||
|
||||
|
||||
def _get_columns(vnfpm_job_obj, action=None):
|
||||
if action == 'update':
|
||||
column_map = {
|
||||
'callbackUri': 'Callback Uri',
|
||||
'authentication': 'Authentication'
|
||||
}
|
||||
else:
|
||||
column_map = {
|
||||
'id': 'ID',
|
||||
'objectType': 'Object Type',
|
||||
'objectInstanceIds': 'Object Instance Ids',
|
||||
'subObjectInstanceIds': 'Sub Object Instance Ids',
|
||||
'criteria': 'Criteria',
|
||||
'callbackUri': 'Callback Uri',
|
||||
'reports': 'Reports',
|
||||
'_links': 'Links'
|
||||
}
|
||||
|
||||
if action == 'show':
|
||||
column_map.update(
|
||||
{'reports': 'Reports'}
|
||||
)
|
||||
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(
|
||||
vnfpm_job_obj, column_map)
|
||||
|
||||
|
||||
class CreateVnfPmJob(command.ShowOne):
|
||||
_description = _("Create a new VNF PM job")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateVnfPmJob, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'request_file',
|
||||
metavar="<param-file>",
|
||||
help=_('Specify create VNF PM job request '
|
||||
'parameters in a json file.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnf_pm_job = client.create_vnf_pm_job(
|
||||
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,
|
||||
formatters=_FORMATTERS, mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ListVnfPmJob(command.Lister):
|
||||
_description = _("List VNF PM jobs")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
LOG.debug('get_parser(%s)', prog_name)
|
||||
parser = super(ListVnfPmJob, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"--filter",
|
||||
metavar="<filter>",
|
||||
help=_("Attribute-based-filtering parameters"),
|
||||
)
|
||||
fields_exclusive_group = parser.add_mutually_exclusive_group(
|
||||
required=False)
|
||||
fields_exclusive_group.add_argument(
|
||||
"--all_fields",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help=_("Include all complex attributes in the response"),
|
||||
)
|
||||
fields_exclusive_group.add_argument(
|
||||
"--fields",
|
||||
metavar="fields",
|
||||
help=_("Complex attributes to be included into the response"),
|
||||
)
|
||||
fields_exclusive_group.add_argument(
|
||||
"--exclude_fields",
|
||||
metavar="exclude-fields",
|
||||
help=_("Complex attributes to be excluded from the response"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--exclude_default",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help=_("Indicates to exclude all complex attributes"
|
||||
" from the response. This argument can be used alone or"
|
||||
" with --fields and --filter. For all other combinations"
|
||||
" tacker server will throw bad request error"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def case_modify(self, field):
|
||||
return reduce(
|
||||
lambda x, y: x + (' ' if y.isupper() else '') + y, field).title()
|
||||
|
||||
def get_attributes(self, extra_fields=None, all_fields=False,
|
||||
exclude_fields=None, exclude_default=False):
|
||||
fields = ['id', 'objectType', '_links']
|
||||
complex_fields = [
|
||||
'objectInstanceIds',
|
||||
'subObjectInstanceIds',
|
||||
'criteria',
|
||||
'reports']
|
||||
simple_fields = ['callbackUri']
|
||||
|
||||
if extra_fields:
|
||||
fields.extend(extra_fields)
|
||||
|
||||
if exclude_fields:
|
||||
fields.extend([field for field in complex_fields
|
||||
if field not in exclude_fields])
|
||||
if all_fields:
|
||||
fields.extend(complex_fields)
|
||||
fields.extend(simple_fields)
|
||||
|
||||
if exclude_default:
|
||||
fields.extend(simple_fields)
|
||||
|
||||
attrs = []
|
||||
for field in fields:
|
||||
if field == '_links':
|
||||
attrs.extend([(field, 'Links', tacker_osc_utils.LIST_BOTH)])
|
||||
else:
|
||||
attrs.extend([(field, self.case_modify(field),
|
||||
tacker_osc_utils.LIST_BOTH)])
|
||||
|
||||
return tuple(attrs)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
_params = {}
|
||||
extra_fields = []
|
||||
exclude_fields = []
|
||||
all_fields = False
|
||||
exclude_default = False
|
||||
if parsed_args.filter:
|
||||
_params['filter'] = parsed_args.filter
|
||||
if parsed_args.fields:
|
||||
_params['fields'] = parsed_args.fields
|
||||
fields = parsed_args.fields.split(',')
|
||||
for field in fields:
|
||||
extra_fields.append(field.split('/')[0])
|
||||
if parsed_args.exclude_fields:
|
||||
_params['exclude_fields'] = parsed_args.exclude_fields
|
||||
fields = parsed_args.exclude_fields.split(',')
|
||||
exclude_fields.extend(fields)
|
||||
if parsed_args.exclude_default:
|
||||
_params['exclude_default'] = None
|
||||
exclude_default = True
|
||||
if parsed_args.all_fields:
|
||||
_params['all_fields'] = None
|
||||
all_fields = True
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
data = client.list_vnf_pm_jobs(**_params)
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.get_attributes(extra_fields, all_fields, exclude_fields,
|
||||
exclude_default), 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_jobs']))
|
||||
|
||||
|
||||
class ShowVnfPmJob(command.ShowOne):
|
||||
_description = _("Display VNF PM job details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowVnfPmJob, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_PM_JOB_ID,
|
||||
metavar="<vnf-pm-job-id>",
|
||||
help=_("VNF PM job ID to display"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.show_vnf_pm_job(parsed_args.vnf_pm_job_id)
|
||||
display_columns, columns = _get_columns(obj, action='show')
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj), columns,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS,
|
||||
formatters=_FORMATTERS)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class UpdateVnfPmJob(command.ShowOne):
|
||||
_description = _("Update information about an individual VNF PM job")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
LOG.debug('get_parser(%s)', prog_name)
|
||||
parser = super(UpdateVnfPmJob, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_PM_JOB_ID,
|
||||
metavar="<vnf-pm-job-id>",
|
||||
help=_("VNF PM job ID to update.")
|
||||
)
|
||||
parser.add_argument(
|
||||
'request_file',
|
||||
metavar="<param-file>",
|
||||
help=_('Specify update PM job 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_job(
|
||||
parsed_args.vnf_pm_job_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, formatters=_FORMATTERS_UPDATE,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS_UPDATE)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class DeleteVnfPmJob(command.Command):
|
||||
_description = _("Delete VNF PM job")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteVnfPmJob, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_PM_JOB_ID,
|
||||
metavar="<vnf-pm-job-id>",
|
||||
nargs="+",
|
||||
help=_("VNF PM job ID(s) to delete"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
error_count = 0
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnf_pm_job_ids = parsed_args.vnf_pm_job_id
|
||||
|
||||
for job_id in vnf_pm_job_ids:
|
||||
try:
|
||||
client.delete_vnf_pm_job(job_id)
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
LOG.error(_("Failed to delete VNF PM job with "
|
||||
"ID '%(job_id)s': %(e)s"),
|
||||
{'job_id': job_id, 'e': e})
|
||||
|
||||
total = len(vnf_pm_job_ids)
|
||||
if error_count > 0:
|
||||
msg = (_("Failed to delete %(error_count)s of %(total)s "
|
||||
"VNF PM jobs.") % {'error_count': error_count,
|
||||
'total': total})
|
||||
raise exceptions.CommandError(message=msg)
|
||||
|
||||
if total > 1:
|
||||
print(_('All specified VNF PM jobs are deleted '
|
||||
'successfully'))
|
||||
else:
|
||||
print(_("VNF PM job '%s' deleted "
|
||||
"successfully") % vnf_pm_job_ids[0])
|
||||
67
tackerclient/osc/v2/vnfpm/vnfpm_report.py
Normal file
67
tackerclient/osc/v2/vnfpm/vnfpm_report.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# Copyright (C) 2022 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.i18n import _
|
||||
from tackerclient.osc import sdk_utils
|
||||
from tackerclient.osc import utils as tacker_osc_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
_FORMATTERS = {
|
||||
'entries': tacker_osc_utils.FormatComplexDataColumn
|
||||
}
|
||||
|
||||
_VNF_PM_JOB_ID = 'vnf_pm_job_id'
|
||||
_VNF_PM_REPORT_ID = 'vnf_pm_report_id'
|
||||
|
||||
|
||||
def _get_columns(vnfpm_report_obj):
|
||||
column_map = {
|
||||
'entries': 'Entries'
|
||||
}
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(
|
||||
vnfpm_report_obj, column_map)
|
||||
|
||||
|
||||
class ShowVnfPmReport(command.ShowOne):
|
||||
_description = _("Display VNF PM report details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowVnfPmReport, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_PM_JOB_ID,
|
||||
metavar="<vnf-pm-job-id>",
|
||||
help=_("VNF PM job id where the VNF PM report is located"))
|
||||
parser.add_argument(
|
||||
_VNF_PM_REPORT_ID,
|
||||
metavar="<vnf-pm-report-id>",
|
||||
help=_("VNF PM report ID to display"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.show_vnf_pm_report(
|
||||
parsed_args.vnf_pm_job_id, parsed_args.vnf_pm_report_id)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj),
|
||||
columns, formatters=_FORMATTERS,
|
||||
mixed_case_fields=None)
|
||||
return (display_columns, data)
|
||||
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])
|
||||
@@ -63,7 +63,25 @@ def args2body_vim(config_param, vim):
|
||||
message='Project name must be specified in Kubernetes VIM,'
|
||||
'it is namespace in Kubernetes environment',
|
||||
status_code=404)
|
||||
if ('username' in config_param) and ('password' in config_param):
|
||||
if 'oidc_token_url' in config_param:
|
||||
if ('username' not in config_param or
|
||||
'password' not in config_param or
|
||||
'client_id' not in config_param):
|
||||
# the username, password, client_id are required.
|
||||
# client_secret is not required when client type is public.
|
||||
raise exceptions.TackerClientException(
|
||||
message='oidc_token_url must be specified with username,'
|
||||
' password, client_id, client_secret(optional).',
|
||||
status_code=404)
|
||||
vim['auth_cred'] = {
|
||||
'oidc_token_url': config_param.pop('oidc_token_url'),
|
||||
'username': config_param.pop('username'),
|
||||
'password': config_param.pop('password'),
|
||||
'client_id': config_param.pop('client_id')}
|
||||
if 'client_secret' in config_param:
|
||||
vim['auth_cred']['client_secret'] = config_param.pop(
|
||||
'client_secret')
|
||||
elif ('username' in config_param) and ('password' in config_param):
|
||||
vim['auth_cred'] = {
|
||||
'username': config_param.pop('username', ''),
|
||||
'password': config_param.pop('password', '')}
|
||||
@@ -78,6 +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
|
||||
if 'extra' in config_param:
|
||||
vim['extra'] = config_param.pop('extra')
|
||||
|
||||
|
||||
def validate_auth_url(url):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
from io import StringIO
|
||||
import os
|
||||
import sys
|
||||
@@ -156,25 +157,67 @@ 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))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm(action='list'),
|
||||
actual_columns)
|
||||
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')
|
||||
|
||||
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_instance_id}'.format(
|
||||
base_url=path,
|
||||
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=[vnf_instances[0]], headers=link_headers[0])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[0], json=[vnf_instances[1]],
|
||||
headers=link_headers[1])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[1], json=[vnf_instances[2]],
|
||||
headers=link_headers[2])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[2], json=[], 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 vnf_instances:
|
||||
expected_data.append(vnflcm_fakes.get_vnflcm_data(
|
||||
vnf_instance_obj, columns=columns, list_action=True))
|
||||
|
||||
@@ -254,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")
|
||||
@@ -288,6 +331,9 @@ class TestHealVnfLcm(TestVnfLcm):
|
||||
self.heal_vnf_lcm = vnflcm.HealVnfLcm(
|
||||
self.app, self.app_args, cmd_name='vnflcm heal')
|
||||
|
||||
_heal_sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||
"heal_vnf_instance_param_sample.json")
|
||||
|
||||
@ddt.data((['--cause', 'test-cause', "--vnfc-instance",
|
||||
'vnfc-id-1', 'vnfc-id-2'],
|
||||
[('cause', 'test-cause'),
|
||||
@@ -296,6 +342,8 @@ class TestHealVnfLcm(TestVnfLcm):
|
||||
[('cause', 'test-cause')]),
|
||||
(["--vnfc-instance", 'vnfc-id-1', 'vnfc-id-2'],
|
||||
[('vnfc_instance', ['vnfc-id-1', 'vnfc-id-2'])]),
|
||||
(["--additional-param-file", _heal_sample_param_file],
|
||||
[('additional_param_file', _heal_sample_param_file)]),
|
||||
([], []))
|
||||
@ddt.unpack
|
||||
def test_take_action(self, arglist, verifylist):
|
||||
@@ -340,6 +388,25 @@ class TestHealVnfLcm(TestVnfLcm):
|
||||
self.heal_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_param_file_not_exists(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = "./not_exists.json"
|
||||
arglist = [vnf_instance['id'],
|
||||
'--additional-param-file', sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('additional_param_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.heal_vnf_lcm, arglist,
|
||||
verifylist)
|
||||
|
||||
ex = self.assertRaises(exceptions.InvalidInput,
|
||||
self.heal_vnf_lcm.take_action, parsed_args)
|
||||
|
||||
expected_msg = ("Invalid input: "
|
||||
"User does not have read privileges to it")
|
||||
self.assertEqual(expected_msg, str(ex))
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestTerminateVnfLcm(TestVnfLcm):
|
||||
@@ -396,7 +463,7 @@ class TestTerminateVnfLcm(TestVnfLcm):
|
||||
self.assertIn(expected_message, actual_message)
|
||||
|
||||
if delete_vnf:
|
||||
expected_message = ("VNF Instance '%s' deleted successfully"
|
||||
expected_message = ("VNF Instance '%s' is deleted successfully"
|
||||
% vnf_instance['id'])
|
||||
self.assertIn(expected_message, actual_message)
|
||||
|
||||
@@ -512,7 +579,7 @@ class TestDeleteVnfLcm(TestVnfLcm):
|
||||
sys.stdout = buffer = StringIO()
|
||||
result = self.delete_vnf_instance.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual(("Vnf instance '%s' deleted successfully")
|
||||
self.assertEqual(("Vnf instance '%s' is deleted successfully")
|
||||
% self.vnf_instances[0]['id'],
|
||||
buffer.getvalue().strip())
|
||||
|
||||
@@ -707,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):
|
||||
@@ -821,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")
|
||||
@@ -850,6 +917,40 @@ class TestChangeExtConnVnfLcm(TestVnfLcm):
|
||||
self.assertIn(expected_msg, str(ex))
|
||||
|
||||
|
||||
class TestChangeVnfPkgVnfLcm(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestChangeVnfPkgVnfLcm, self).setUp()
|
||||
self.change_vnfpkg_vnf_lcm = vnflcm.ChangeVnfPkgVnfLcm(
|
||||
self.app, self.app_args,
|
||||
cmd_name='vnflcm change-vnfpkg')
|
||||
|
||||
def test_take_action_with_v1_version(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = ("./tackerclient/osc/v2/vnflcm/samples/"
|
||||
"change_vnfpkg_vnf_instance_param_sample.json")
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||
vnf_instance['id'], 'change_vnfpkg')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=400, json={})
|
||||
|
||||
ex = self.assertRaises(exceptions.UnsupportedCommandVersion,
|
||||
self.change_vnfpkg_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
expected_msg = "This command is not supported in version 1"
|
||||
self.assertEqual(expected_msg, str(ex))
|
||||
|
||||
|
||||
class TestVnfLcmV1(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
api_version = '1'
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
from io import StringIO
|
||||
import os
|
||||
import sys
|
||||
|
||||
import ddt
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
from unittest import mock
|
||||
|
||||
@@ -25,7 +27,7 @@ from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
from tackerclient.tests.unit.osc.v1 import vnflcm_op_occs_fakes
|
||||
|
||||
|
||||
def _get_columns_vnflcm_op_occs(action='show'):
|
||||
def _get_columns_vnflcm_op_occs(action='show', parameter=None):
|
||||
|
||||
if action == 'fail':
|
||||
return ['ID', 'Operation State', 'State Entered Time',
|
||||
@@ -33,8 +35,11 @@ def _get_columns_vnflcm_op_occs(action="/?originalUrl=https%3A%2F%2Fgit.openstack.org%2F%26%2339%3Bshow%26%2339%3B)%3A%253C%2Fcode">
|
||||
'Is Automatic Invocation', 'Is Cancel Pending',
|
||||
'Error', 'Links']
|
||||
elif action == 'list':
|
||||
return ['ID', 'Operation State', 'VNF Instance ID',
|
||||
'Operation']
|
||||
if parameter is not None:
|
||||
return ['ID', 'Operation']
|
||||
else:
|
||||
return ['ID', 'Operation State', 'VNF Instance ID',
|
||||
'Operation']
|
||||
else:
|
||||
return ['ID', 'Operation State', 'State Entered Time',
|
||||
'Start Time', 'VNF Instance ID', 'Grant ID',
|
||||
@@ -57,6 +62,70 @@ class TestVnfLcm(base.FixturedTestCase):
|
||||
self.app.client_manager.tackerclient = self.client_manager
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestCancelVnfLcmOp(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCancelVnfLcmOp, self).setUp()
|
||||
self.cancel_vnf_lcm = vnflcm_op_occs.CancelVnfLcmOp(
|
||||
self.app, self.app_args, cmd_name='vnflcm op cancel')
|
||||
|
||||
@ddt.data('GRACEFUL', 'FORCEFUL')
|
||||
def test_take_action(self, cancel_mode):
|
||||
"""take_action normal system test"""
|
||||
|
||||
arglist = ['--cancel-mode', cancel_mode,
|
||||
uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verifylist = [('cancel_mode', cancel_mode),
|
||||
('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.cancel_vnf_lcm, arglist, verifylist)
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'cancel')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, json={})
|
||||
|
||||
sys.stdout = buffer = StringIO()
|
||||
self.cancel_vnf_lcm.take_action(parsed_args)
|
||||
|
||||
actual_message = buffer.getvalue().strip()
|
||||
|
||||
expected_message = (
|
||||
'Cancel request for LCM operation ' +
|
||||
uuidsentinel.vnf_lcm_op_occ_id +
|
||||
' has been accepted')
|
||||
|
||||
self.assertEqual(expected_message, actual_message)
|
||||
|
||||
def test_terminate_no_options(self):
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.cancel_vnf_lcm, [], [])
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_id_not_found(self):
|
||||
"""take_action abnomaly system test"""
|
||||
|
||||
arglist = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verifylist = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.cancel_vnf_lcm, arglist, verifylist)
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'cancel')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.cancel_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestRollbackVnfLcmOp(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
@@ -431,6 +500,80 @@ class TestListVnfLcmOp(TestVnfLcm):
|
||||
self.list_vnflcm_op_occ.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_with_exclude_fields(self):
|
||||
|
||||
vnflcm_op_occs_obj = vnflcm_op_occs_fakes.create_vnflcm_op_occs(
|
||||
count=3)
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnflcm_op_occ,
|
||||
["--exclude-fields", 'VNF Instance ID,Operation State'],
|
||||
[('exclude_fields', 'VNF Instance ID,Operation State')])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs?'
|
||||
'exclude-fields=VNF Instance ID,Operation State'),
|
||||
json=vnflcm_op_occs_obj, headers=self.header)
|
||||
actual_columns, data = self.list_vnflcm_op_occ.take_action(parsed_args)
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnflcm_op_occ.get_attributes(
|
||||
exclude=['VNF Instance ID', 'Operation State']),
|
||||
long_listing=True)
|
||||
expected_data = []
|
||||
for vnflcm_op_occ_obj_idx in vnflcm_op_occs_obj:
|
||||
expected_data.append(
|
||||
vnflcm_op_occs_fakes.get_vnflcm_op_occ_data(
|
||||
vnflcm_op_occ_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_op_occs(
|
||||
action='list', parameter="exclude_fields"),
|
||||
actual_columns)
|
||||
self.assertListItemsEqual(expected_data, list(data))
|
||||
|
||||
def test_take_action_with_pagination(self):
|
||||
next_links_num = 3
|
||||
vnflcm_op_occs_obj = vnflcm_op_occs_fakes.create_vnflcm_op_occs(
|
||||
count=next_links_num)
|
||||
parsed_args = self.check_parser(self.list_vnflcm_op_occ, [], [])
|
||||
path = os.path.join(self.url, 'vnflcm/v1/vnf_lcm_op_occs')
|
||||
|
||||
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={vnflcm_op_occ_id}'.format(
|
||||
base_url=path,
|
||||
vnflcm_op_occ_id=vnflcm_op_occs_obj[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=[vnflcm_op_occs_obj[0]], headers=link_headers[0])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[0], json=[vnflcm_op_occs_obj[1]],
|
||||
headers=link_headers[1])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[1], json=[vnflcm_op_occs_obj[2]],
|
||||
headers=link_headers[2])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[2], json=[], headers=self.header)
|
||||
|
||||
actual_columns, data = self.list_vnflcm_op_occ.take_action(parsed_args)
|
||||
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnflcm_op_occ.get_attributes(), long_listing=True)
|
||||
|
||||
expected_data = []
|
||||
for vnflcm_op_occ_obj_idx in vnflcm_op_occs_obj:
|
||||
expected_data.append(vnflcm_op_occs_fakes.get_vnflcm_op_occ_data(
|
||||
vnflcm_op_occ_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_op_occs(action='list'),
|
||||
actual_columns)
|
||||
self.assertCountEqual(expected_data, list(data))
|
||||
|
||||
|
||||
class TestShowVnfLcmOp(TestVnfLcm):
|
||||
|
||||
|
||||
254
tackerclient/tests/unit/osc/v1/test_vnflcm_subsc.py
Normal file
254
tackerclient/tests/unit/osc/v1/test_vnflcm_subsc.py
Normal file
@@ -0,0 +1,254 @@
|
||||
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
|
||||
# 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 copy
|
||||
import os
|
||||
import sys
|
||||
|
||||
from io import StringIO
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.osc import utils as tacker_osc_utils
|
||||
from tackerclient.osc.v1.vnflcm import vnflcm_subsc
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1 import test_vnflcm
|
||||
from tackerclient.tests.unit.osc.v1 import vnflcm_subsc_fakes
|
||||
|
||||
|
||||
def _get_columns_vnflcm_subsc(action=None):
|
||||
columns = ['ID', 'Filter', 'Callback URI', 'Links']
|
||||
if action == 'list':
|
||||
columns = [ele for ele in columns if ele not in
|
||||
['Filter', 'Links']]
|
||||
return columns
|
||||
|
||||
|
||||
class TestCreateLccnSubscription(test_vnflcm.TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCreateLccnSubscription, self).setUp()
|
||||
self.create_subscription = vnflcm_subsc.CreateLccnSubscription(
|
||||
self.app, self.app_args, cmd_name='vnflcm subsc create')
|
||||
|
||||
def test_create_no_args(self):
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.create_subscription, [], [])
|
||||
|
||||
def test_take_action(self):
|
||||
subscription = vnflcm_subsc_fakes.lccn_subsc_response()
|
||||
sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||
"create_lccn_subscription_param_sample.json")
|
||||
|
||||
arglist = [sample_param_file]
|
||||
verifylist = [('create_request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.create_subscription,
|
||||
arglist, verifylist)
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'POST', os.path.join(self.url, 'vnflcm/v1/subscriptions'),
|
||||
json=subscription, headers=self.header)
|
||||
|
||||
actual_columns, data = (self.create_subscription.take_action(
|
||||
parsed_args))
|
||||
|
||||
headers, attributes = vnflcm_subsc._get_columns(subscription)
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_subsc(),
|
||||
actual_columns)
|
||||
self.assertListItemsEqual(vnflcm_subsc_fakes.get_subscription_data(
|
||||
subscription, columns=attributes), data)
|
||||
|
||||
|
||||
class TestListLccnSubscription(test_vnflcm.TestVnfLcm):
|
||||
|
||||
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=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 subscriptions:
|
||||
expected_data.append(vnflcm_subsc_fakes.get_subscription_data(
|
||||
subscription_obj, columns=columns, list_action=True))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_subsc(action='list'),
|
||||
actual_columns)
|
||||
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, [], [])
|
||||
|
||||
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={subscription_id}'.format(
|
||||
base_url=path,
|
||||
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=[subscriptions[0]], headers=link_headers[0])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[0], json=[subscriptions[1]],
|
||||
headers=link_headers[1])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[1], json=[subscriptions[2]],
|
||||
headers=link_headers[2])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', links[2], json=[], 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 subscriptions:
|
||||
expected_data.append(vnflcm_subsc_fakes.get_subscription_data(
|
||||
subscription_obj, columns=columns, list_action=True))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_subsc(action='list'),
|
||||
actual_columns)
|
||||
|
||||
self.assertCountEqual(expected_data, list(data))
|
||||
|
||||
|
||||
class TestShowLccnSubscription(test_vnflcm.TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShowLccnSubscription, self).setUp()
|
||||
self.show_subscription = vnflcm_subsc.ShowLccnSubscription(
|
||||
self.app, self.app_args, cmd_name='vnflcm subsc show')
|
||||
|
||||
def test_take_action(self):
|
||||
subscription = vnflcm_subsc_fakes.lccn_subsc_response()
|
||||
|
||||
arglist = [subscription['id']]
|
||||
verifylist = [('subscription_id', subscription['id'])]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.show_subscription, arglist,
|
||||
verifylist)
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(self.url, 'vnflcm/v1/subscriptions',
|
||||
subscription['id']),
|
||||
json=subscription, headers=self.header)
|
||||
|
||||
columns, data = (self.show_subscription.take_action(parsed_args))
|
||||
self.assertCountEqual(_get_columns_vnflcm_subsc(),
|
||||
columns)
|
||||
headers, attributes = vnflcm_subsc._get_columns(subscription)
|
||||
self.assertListItemsEqual(
|
||||
vnflcm_subsc_fakes.get_subscription_data(subscription,
|
||||
columns=attributes),
|
||||
data)
|
||||
|
||||
|
||||
class TestDeleteLccnSubscription(test_vnflcm.TestVnfLcm):
|
||||
|
||||
subscriptions = vnflcm_subsc_fakes.create_subscriptions(count=3)
|
||||
|
||||
def setUp(self):
|
||||
super(TestDeleteLccnSubscription, self).setUp()
|
||||
self.delete_subscription = vnflcm_subsc.DeleteLccnSubscription(
|
||||
self.app, self.app_args, cmd_name='vnflcm subsc delete')
|
||||
|
||||
def _mock_request_url_for_delete(self, subsc_index):
|
||||
url = os.path.join(self.url, 'vnflcm/v1/subscriptions',
|
||||
self.subscriptions[subsc_index]['id'])
|
||||
|
||||
json = self.subscriptions[subsc_index]
|
||||
|
||||
self.requests_mock.register_uri('GET', url, json=json,
|
||||
headers=self.header)
|
||||
self.requests_mock.register_uri('DELETE', url,
|
||||
headers=self.header, json={})
|
||||
|
||||
def test_delete_one_subscription(self):
|
||||
arglist = [self.subscriptions[0]['id']]
|
||||
verifylist = [('subscription_id',
|
||||
[self.subscriptions[0]['id']])]
|
||||
|
||||
parsed_args = self.check_parser(self.delete_subscription,
|
||||
arglist, verifylist)
|
||||
|
||||
self._mock_request_url_for_delete(0)
|
||||
sys.stdout = buffer = StringIO()
|
||||
result = self.delete_subscription.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual(("Lccn Subscription '%s' is deleted successfully")
|
||||
% self.subscriptions[0]['id'],
|
||||
buffer.getvalue().strip())
|
||||
|
||||
def test_delete_multiple_subscription(self):
|
||||
arglist = []
|
||||
for subscription in self.subscriptions:
|
||||
arglist.append(subscription['id'])
|
||||
verifylist = [('subscription_id', arglist)]
|
||||
parsed_args = self.check_parser(self.delete_subscription,
|
||||
arglist, verifylist)
|
||||
for i in range(0, 3):
|
||||
self._mock_request_url_for_delete(i)
|
||||
sys.stdout = buffer = StringIO()
|
||||
result = self.delete_subscription.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual('All specified Lccn Subscriptions are deleted '
|
||||
'successfully', buffer.getvalue().strip())
|
||||
|
||||
def test_delete_multiple_subscription_exception(self):
|
||||
arglist = [
|
||||
self.subscriptions[0]['id'],
|
||||
'xxxx-yyyy-zzzz',
|
||||
self.subscriptions[1]['id'],
|
||||
]
|
||||
verifylist = [('subscription_id', arglist)]
|
||||
parsed_args = self.check_parser(self.delete_subscription,
|
||||
arglist, verifylist)
|
||||
|
||||
self._mock_request_url_for_delete(0)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v1/subscriptions',
|
||||
'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_subscription.take_action,
|
||||
parsed_args)
|
||||
|
||||
self.assertEqual('Failed to delete 1 of 3 Lccn Subscriptions.',
|
||||
exception.message)
|
||||
@@ -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):
|
||||
|
||||
191
tackerclient/tests/unit/osc/v1/vnflcm_subsc_fakes.py
Normal file
191
tackerclient/tests/unit/osc/v1/vnflcm_subsc_fakes.py
Normal file
@@ -0,0 +1,191 @@
|
||||
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
|
||||
# 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.fixture import uuidsentinel
|
||||
from oslo_utils import uuidutils
|
||||
from tackerclient.osc import utils as tacker_osc_utils
|
||||
|
||||
|
||||
def lccn_subsc_response(attrs=None):
|
||||
"""Create a fake subscription.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:return:
|
||||
A subscription dict
|
||||
"""
|
||||
attrs = attrs or {}
|
||||
id = uuidsentinel.lccn_subsc_id
|
||||
|
||||
# Set default attributes.
|
||||
dummy_subscription = {
|
||||
"id": id,
|
||||
"filter": {
|
||||
"vnfInstanceSubscriptionFilter": {
|
||||
"vnfdIds": [
|
||||
"dummy-vnfdId-1",
|
||||
"dummy-vnfdId-2"
|
||||
],
|
||||
"vnfProductsFromProviders": [
|
||||
{
|
||||
"vnfProvider": "dummy-vnfProvider-1",
|
||||
"vnfProducts": [
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-1-1",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersions": ["1.0", "2.0"]
|
||||
},
|
||||
{
|
||||
"vnfSoftwareVersion": "1.1",
|
||||
"vnfdVersions": ["1.1", "2.1"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-1-2",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersions": ["1.0", "2.0"]
|
||||
},
|
||||
{
|
||||
"vnfSoftwareVersion": "1.1",
|
||||
"vnfdVersions": ["1.1", "2.1"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"vnfProvider": "dummy-vnfProvider-2",
|
||||
"vnfProducts": [
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-2-1",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersions": ["1.0", "2.0"]
|
||||
},
|
||||
{
|
||||
"vnfSoftwareVersion": "1.1",
|
||||
"vnfdVersions": ["1.1", "2.1"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-2-2",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": "1.0",
|
||||
"vnfdVersions": ["1.0", "2.0"]
|
||||
},
|
||||
{
|
||||
"vnfSoftwareVersion": "1.1",
|
||||
"vnfdVersions": ["1.1", "2.1"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vnfInstanceIds": [
|
||||
"dummy-vnfInstanceId-1",
|
||||
"dummy-vnfInstanceId-2"
|
||||
],
|
||||
"vnfInstanceNames": [
|
||||
"dummy-vnfInstanceName-1",
|
||||
"dummy-vnfInstanceName-2"
|
||||
]
|
||||
},
|
||||
"notificationTypes": [
|
||||
"VnfLcmOperationOccurrenceNotification",
|
||||
"VnfIdentifierCreationNotification",
|
||||
"VnfIdentifierDeletionNotification"
|
||||
],
|
||||
"operationTypes": [
|
||||
"INSTANTIATE",
|
||||
"SCALE",
|
||||
"TERMINATE",
|
||||
"HEAL",
|
||||
"MODIFY_INFO",
|
||||
"CHANGE_EXT_CONN"
|
||||
],
|
||||
"operationStates": [
|
||||
"COMPLETED",
|
||||
"FAILED",
|
||||
"FAILED_TEMP",
|
||||
"PROCESSING",
|
||||
"ROLLING_BACK",
|
||||
"ROLLED_BACK",
|
||||
"STARTING"
|
||||
]
|
||||
},
|
||||
"callbackUri": "http://localhost:9990/notification/callback/test",
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "http://127.0.0.1:9890/vnflcm/v2/subscriptions/" + id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
dummy_subscription.update(attrs)
|
||||
|
||||
return dummy_subscription
|
||||
|
||||
|
||||
def get_subscription_data(subscription, list_action=False, columns=None):
|
||||
"""Get the subscription data.
|
||||
|
||||
: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 subsc.get(attribute):
|
||||
subsc.update(
|
||||
{attribute: tacker_osc_utils.FormatComplexDataColumn(
|
||||
subsc[attribute])})
|
||||
|
||||
if list_action:
|
||||
for item in ['filter', '_links']:
|
||||
subsc.pop(item)
|
||||
|
||||
# return the list of data as per column order
|
||||
if columns:
|
||||
return tuple([subsc[key] for key in columns])
|
||||
|
||||
return tuple([subsc[key] for key in sorted(
|
||||
subsc.keys())])
|
||||
|
||||
|
||||
def create_subscriptions(count=2):
|
||||
"""Create multiple fake subscriptions.
|
||||
|
||||
:param count: The number of subscriptions to fake
|
||||
:return:
|
||||
A list of fake subscriptions dictionary
|
||||
"""
|
||||
uri = "http://localhost:9990/notification/callback/"
|
||||
subscriptions = []
|
||||
for i in range(0, count):
|
||||
unique_id = uuidutils.generate_uuid()
|
||||
subscriptions.append(lccn_subsc_response(
|
||||
attrs={'id': unique_id,
|
||||
'callbackUri': uri + str(i)}))
|
||||
return subscriptions
|
||||
307
tackerclient/tests/unit/osc/v2/test_vnffm_alarm.py
Normal file
307
tackerclient/tests/unit/osc/v2/test_vnffm_alarm.py
Normal file
@@ -0,0 +1,307 @@
|
||||
# Copyright (C) 2022 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
|
||||
|
||||
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.vnffm import vnffm_alarm
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
from tackerclient.tests.unit.osc.v2 import vnffm_alarm_fakes
|
||||
|
||||
|
||||
class TestVnfFmAlarm(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfFmAlarm, 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_vnffm_alarm(action=None):
|
||||
if action == 'update':
|
||||
columns = ['Ack State']
|
||||
else:
|
||||
columns = ['ID', 'Managed Object Id', 'Ack State',
|
||||
'Perceived Severity', 'Event Type', 'Probable Cause']
|
||||
|
||||
if action == 'show':
|
||||
columns.extend([
|
||||
'Vnfc Instance Ids', 'Root Cause Faulty Resource',
|
||||
'Alarm Raised Time', 'Alarm Changed Time',
|
||||
'Alarm Cleared Time', 'Alarm Acknowledged Time',
|
||||
'Event Time', 'Fault Type', 'Is Root Cause',
|
||||
'Correlated Alarm Ids', 'Fault Details', 'Links'
|
||||
])
|
||||
|
||||
return columns
|
||||
|
||||
|
||||
class TestListVnfFmAlarm(TestVnfFmAlarm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestListVnfFmAlarm, self).setUp()
|
||||
self.list_vnf_fm_alarms = vnffm_alarm.ListVnfFmAlarm(
|
||||
self.app, self.app_args, cmd_name='vnffm alarm list')
|
||||
|
||||
def test_take_action(self):
|
||||
vnffm_alarms_obj = vnffm_alarm_fakes.create_vnf_fm_alarms(
|
||||
count=3)
|
||||
parsed_args = self.check_parser(self.list_vnf_fm_alarms, [], [])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(self.url, 'vnffm/v1/alarms'),
|
||||
json=vnffm_alarms_obj, headers=self.header)
|
||||
|
||||
actual_columns, data = self.list_vnf_fm_alarms.take_action(parsed_args)
|
||||
|
||||
_, columns = tacker_osc_utils.get_column_definitions(
|
||||
vnffm_alarm._ATTR_MAP, long_listing=True)
|
||||
|
||||
expected_data = []
|
||||
for vnffm_alarm_obj_idx in vnffm_alarms_obj:
|
||||
expected_data.append(vnffm_alarm_fakes.get_vnffm_alarm_data(
|
||||
vnffm_alarm_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnffm_alarm(action='list'),
|
||||
actual_columns)
|
||||
self.assertCountEqual(expected_data, list(data))
|
||||
|
||||
def test_take_action_with_filter(self):
|
||||
vnffm_alarms_obj = vnffm_alarm_fakes.create_vnf_fm_alarms(
|
||||
count=3)
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnf_fm_alarms,
|
||||
["--filter", '(eq,perceivedSeverity,WARNING)'],
|
||||
[('filter', '(eq,perceivedSeverity,WARNING)')])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(
|
||||
self.url,
|
||||
'vnffm/v1/alarms?filter=(eq,perceivedSeverity,WARNING)'),
|
||||
json=vnffm_alarms_obj, headers=self.header)
|
||||
|
||||
actual_columns, data = self.list_vnf_fm_alarms.take_action(parsed_args)
|
||||
|
||||
_, columns = tacker_osc_utils.get_column_definitions(
|
||||
vnffm_alarm._ATTR_MAP, long_listing=True)
|
||||
|
||||
expected_data = []
|
||||
for vnffm_alarm_obj_idx in vnffm_alarms_obj:
|
||||
expected_data.append(vnffm_alarm_fakes.get_vnffm_alarm_data(
|
||||
vnffm_alarm_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnffm_alarm(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_fm_alarms,
|
||||
["--filter", '(perceivedSeverity)'],
|
||||
[('filter', '(perceivedSeverity)')])
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnffm/v1/alarms?filter=(perceivedSeverity)')
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=400, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.list_vnf_fm_alarms.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_internal_server_error(self):
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnf_fm_alarms,
|
||||
["--filter", '(eq,perceivedSeverity,WARNING)'],
|
||||
[('filter', '(eq,perceivedSeverity,WARNING)')])
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnffm/v1/alarms?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_fm_alarms.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestShowVnfFmAlarm(TestVnfFmAlarm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShowVnfFmAlarm, self).setUp()
|
||||
self.show_vnf_fm_alarm = vnffm_alarm.ShowVnfFmAlarm(
|
||||
self.app, self.app_args, cmd_name='vnffm alarm show')
|
||||
|
||||
def test_take_action(self):
|
||||
"""Test of take_action()"""
|
||||
vnffm_alarm_obj = vnffm_alarm_fakes.vnf_fm_alarm_response()
|
||||
|
||||
arglist = [vnffm_alarm_obj['id']]
|
||||
verifylist = [('vnf_fm_alarm_id', vnffm_alarm_obj['id'])]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_fm_alarm, arglist, verifylist)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnffm/v1/alarms', vnffm_alarm_obj['id'])
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, json=vnffm_alarm_obj)
|
||||
|
||||
columns, _ = (self.show_vnf_fm_alarm.take_action(parsed_args))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnffm_alarm(action='show'),
|
||||
columns)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_id_not_found(self):
|
||||
"""Test if vnf-lcm-op-occ-id does not find."""
|
||||
arglist = [uuidsentinel.vnf_fm_alarm_id]
|
||||
verifylist = [('vnf_fm_alarm_id', uuidsentinel.vnf_fm_alarm_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_fm_alarm, arglist, verifylist)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnffm/v1/alarms', uuidsentinel.vnf_fm_alarm_id)
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_fm_alarm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_internal_server_error(self):
|
||||
"""Test for internal server error."""
|
||||
arglist = [uuidsentinel.vnf_fm_alarm_id]
|
||||
verifylist = [('vnf_fm_alarm_id', uuidsentinel.vnf_fm_alarm_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_fm_alarm, arglist, verifylist)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnffm/v1/alarms', uuidsentinel.vnf_fm_alarm_id)
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_fm_alarm.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestUpdateVnfFmAlarm(TestVnfFmAlarm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestUpdateVnfFmAlarm, self).setUp()
|
||||
self.update_vnf_fm_alarm = vnffm_alarm.UpdateVnfFmAlarm(
|
||||
self.app, self.app_args, cmd_name='vnffm alarm update')
|
||||
|
||||
@ddt.data('ACKNOWLEDGED', 'UNACKNOWLEDGED')
|
||||
def test_take_action(self, ack_state):
|
||||
"""Test of take_action()"""
|
||||
|
||||
vnffm_alarm_obj = vnffm_alarm_fakes.vnf_fm_alarm_response(
|
||||
None, 'update')
|
||||
|
||||
arg_list = ['--ack-state', ack_state, uuidsentinel.vnf_fm_alarm_id]
|
||||
verify_list = [('ack_state', ack_state),
|
||||
('vnf_fm_alarm_id', uuidsentinel.vnf_fm_alarm_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.update_vnf_fm_alarm, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnffm/v1/alarms', uuidsentinel.vnf_fm_alarm_id)
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'PATCH', url, headers=self.header, json=vnffm_alarm_obj)
|
||||
|
||||
actual_columns, data = (
|
||||
self.update_vnf_fm_alarm.take_action(parsed_args))
|
||||
|
||||
expected_columns = _get_columns_vnffm_alarm(action='update')
|
||||
|
||||
self.assertCountEqual(expected_columns, actual_columns)
|
||||
|
||||
_, columns = vnffm_alarm._get_columns(
|
||||
vnffm_alarm_obj, action='update')
|
||||
|
||||
expected_data = vnffm_alarm_fakes.get_vnffm_alarm_data(
|
||||
vnffm_alarm_obj, columns=columns)
|
||||
|
||||
self.assertEqual(expected_data, data)
|
||||
|
||||
@ddt.data('ACKNOWLEDGED')
|
||||
def test_take_action_vnf_lcm_op_occ_id_not_found(self, ack_state):
|
||||
"""Test if vnf-lcm-op-occ-id does not find"""
|
||||
|
||||
arg_list = ['--ack-state', ack_state, uuidsentinel.vnf_fm_alarm_id]
|
||||
verify_list = [('ack_state', ack_state),
|
||||
('vnf_fm_alarm_id', uuidsentinel.vnf_fm_alarm_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.update_vnf_fm_alarm, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnffm/v1/alarms', uuidsentinel.vnf_fm_alarm_id)
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'PATCH', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.update_vnf_fm_alarm.take_action,
|
||||
parsed_args)
|
||||
|
||||
@ddt.data('UNACKNOWLEDGED')
|
||||
def test_take_action_vnf_lcm_op_occ_state_is_conflict(self, ack_state):
|
||||
"""Test if vnf-lcm-op-occ state is conflict"""
|
||||
|
||||
arg_list = ['--ack-state', ack_state, uuidsentinel.vnf_fm_alarm_id]
|
||||
verify_list = [('ack_state', ack_state),
|
||||
('vnf_fm_alarm_id', uuidsentinel.vnf_fm_alarm_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.update_vnf_fm_alarm, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnffm/v1/alarms', uuidsentinel.vnf_fm_alarm_id)
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'PATCH', url, headers=self.header, status_code=409, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.update_vnf_fm_alarm.take_action,
|
||||
parsed_args)
|
||||
329
tackerclient/tests/unit/osc/v2/test_vnffm_sub.py
Normal file
329
tackerclient/tests/unit/osc/v2/test_vnffm_sub.py
Normal file
@@ -0,0 +1,329 @@
|
||||
# Copyright (C) 2022 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.vnffm import vnffm_sub
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
from tackerclient.tests.unit.osc.v2 import vnffm_sub_fakes
|
||||
|
||||
|
||||
class TestVnfFmSub(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfFmSub, 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_vnffm_sub(action=None):
|
||||
columns = ['ID', 'Callback Uri']
|
||||
|
||||
if action == 'show' or action == 'create':
|
||||
columns.extend(['Filter', 'Links'])
|
||||
|
||||
return columns
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestCreateVnfFmSub(TestVnfFmSub):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCreateVnfFmSub, self).setUp()
|
||||
self.create_vnf_fm_sub = vnffm_sub.CreateVnfFmSub(
|
||||
self.app, self.app_args, cmd_name='vnffm sub create')
|
||||
|
||||
def test_create_no_args(self):
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.create_vnf_fm_sub, [], [])
|
||||
|
||||
@ddt.unpack
|
||||
def test_take_action(self):
|
||||
|
||||
param_file = ("./tackerclient/osc/v2/vnffm/samples/"
|
||||
"create_vnf_fm_subscription_param_sample.json")
|
||||
|
||||
arg_list = [param_file]
|
||||
verify_list = [('request_file', param_file)]
|
||||
|
||||
parsed_args = self.check_parser(self.create_vnf_fm_sub, arg_list,
|
||||
verify_list)
|
||||
|
||||
json = vnffm_sub_fakes.vnf_fm_sub_response()
|
||||
self.requests_mock.register_uri(
|
||||
'POST', os.path.join(self.url, 'vnffm/v1/subscriptions'),
|
||||
json=json, headers=self.header)
|
||||
|
||||
actual_columns, data = (
|
||||
self.create_vnf_fm_sub.take_action(parsed_args))
|
||||
|
||||
_, attributes = vnffm_sub._get_columns(json)
|
||||
|
||||
self.assertCountEqual(_get_columns_vnffm_sub("create"),
|
||||
actual_columns)
|
||||
self.assertListItemsEqual(vnffm_sub_fakes.get_vnffm_sub_data(
|
||||
json, columns=attributes), data)
|
||||
|
||||
|
||||
class TestListVnfFmSub(TestVnfFmSub):
|
||||
|
||||
def setUp(self):
|
||||
super(TestListVnfFmSub, self).setUp()
|
||||
self.list_vnffm_sub = vnffm_sub.ListVnfFmSub(
|
||||
self.app, self.app_args, cmd_name='vnffm sub list')
|
||||
|
||||
def test_take_action(self):
|
||||
vnffm_subs_obj = vnffm_sub_fakes.create_vnf_fm_subs(
|
||||
count=3)
|
||||
parsed_args = self.check_parser(self.list_vnffm_sub, [], [])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(self.url, 'vnffm/v1/subscriptions'),
|
||||
json=vnffm_subs_obj, headers=self.header)
|
||||
|
||||
actual_columns, data = self.list_vnffm_sub.take_action(parsed_args)
|
||||
|
||||
_, columns = tacker_osc_utils.get_column_definitions(
|
||||
vnffm_sub._ATTR_MAP, long_listing=True)
|
||||
|
||||
expected_data = []
|
||||
for vnffm_sub_obj_idx in vnffm_subs_obj:
|
||||
expected_data.append(vnffm_sub_fakes.get_vnffm_sub_data(
|
||||
vnffm_sub_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnffm_sub(action='list'),
|
||||
actual_columns)
|
||||
self.assertCountEqual(expected_data, list(data))
|
||||
|
||||
def test_take_action_with_filter(self):
|
||||
vnffm_subs_obj = vnffm_sub_fakes.create_vnf_fm_subs(
|
||||
count=3)
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnffm_sub,
|
||||
["--filter", '(eq,callbackUri,/nfvo/notify/alarm)'],
|
||||
[('filter', '(eq,callbackUri,/nfvo/notify/alarm)')])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(
|
||||
self.url,
|
||||
'vnffm/v1/subscriptions?'
|
||||
'filter=(eq,callbackUri,/nfvo/notify/alarm)'),
|
||||
json=vnffm_subs_obj, headers=self.header)
|
||||
|
||||
actual_columns, data = self.list_vnffm_sub.take_action(parsed_args)
|
||||
|
||||
_, columns = tacker_osc_utils.get_column_definitions(
|
||||
vnffm_sub._ATTR_MAP, long_listing=True)
|
||||
|
||||
expected_data = []
|
||||
for vnffm_sub_obj_idx in vnffm_subs_obj:
|
||||
expected_data.append(vnffm_sub_fakes.get_vnffm_sub_data(
|
||||
vnffm_sub_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnffm_sub(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_vnffm_sub,
|
||||
["--filter", '(callbackUri)'],
|
||||
[('filter', '(callbackUri)')])
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnffm/v1/subscriptions?filter=(callbackUri)')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=400, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.list_vnffm_sub.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_internal_server_error(self):
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnffm_sub,
|
||||
["--filter", '(eq,callbackUri,/nfvo/notify/alarm)'],
|
||||
[('filter', '(eq,callbackUri,/nfvo/notify/alarm)')])
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnffm/v1/subscriptions?'
|
||||
'filter=(eq,callbackUri,/nfvo/notify/alarm)')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.list_vnffm_sub.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestShowVnfFmSub(TestVnfFmSub):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShowVnfFmSub, self).setUp()
|
||||
self.show_vnf_fm_subs = vnffm_sub.ShowVnfFmSub(
|
||||
self.app, self.app_args, cmd_name='vnffm sub show')
|
||||
|
||||
def test_take_action(self):
|
||||
"""Test of take_action()"""
|
||||
vnffm_sub_obj = vnffm_sub_fakes.vnf_fm_sub_response()
|
||||
|
||||
arg_list = [vnffm_sub_obj['id']]
|
||||
verify_list = [('vnf_fm_sub_id', vnffm_sub_obj['id'])]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_fm_subs, arg_list, verify_list)
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnffm/v1/subscriptions',
|
||||
vnffm_sub_obj['id'])
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, json=vnffm_sub_obj)
|
||||
|
||||
columns, _ = (self.show_vnf_fm_subs.take_action(parsed_args))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnffm_sub('show'),
|
||||
columns)
|
||||
|
||||
def test_take_action_vnf_fm_sub_id_not_found(self):
|
||||
"""Test if vnf-lcm-op-occ-id does not find."""
|
||||
arg_list = [uuidsentinel.vnf_fm_sub_id]
|
||||
verify_list = [('vnf_fm_sub_id', uuidsentinel.vnf_fm_sub_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_fm_subs, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnffm/v1/subscriptions',
|
||||
uuidsentinel.vnf_fm_sub_id)
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_fm_subs.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_internal_server_error(self):
|
||||
"""Test for internal server error."""
|
||||
arg_list = [uuidsentinel.vnf_fm_sub_id]
|
||||
verify_list = [('vnf_fm_sub_id', uuidsentinel.vnf_fm_sub_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_fm_subs, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnffm/v1/subscriptions',
|
||||
uuidsentinel.vnf_fm_sub_id)
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_fm_subs.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestDeleteVnfFmSub(TestVnfFmSub):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDeleteVnfFmSub, self).setUp()
|
||||
self.delete_vnf_fm_sub = vnffm_sub.DeleteVnfFmSub(
|
||||
self.app, self.app_args, cmd_name='vnffm sub delete')
|
||||
|
||||
# Vnf Fm subscription to delete
|
||||
self.vnf_fm_subs = vnffm_sub_fakes.create_vnf_fm_subs(count=3)
|
||||
|
||||
def _mock_request_url_for_delete(self, index):
|
||||
url = os.path.join(self.url, 'vnffm/v1/subscriptions',
|
||||
self.vnf_fm_subs[index]['id'])
|
||||
|
||||
self.requests_mock.register_uri('DELETE', url,
|
||||
headers=self.header, json={})
|
||||
|
||||
def test_delete_one_vnf_fm_sub(self):
|
||||
arg_list = [self.vnf_fm_subs[0]['id']]
|
||||
verify_list = [('vnf_fm_sub_id',
|
||||
[self.vnf_fm_subs[0]['id']])]
|
||||
|
||||
parsed_args = self.check_parser(self.delete_vnf_fm_sub, arg_list,
|
||||
verify_list)
|
||||
|
||||
self._mock_request_url_for_delete(0)
|
||||
sys.stdout = buffer = StringIO()
|
||||
result = self.delete_vnf_fm_sub.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual(
|
||||
(f"VNF FM subscription '{self.vnf_fm_subs[0]['id']}' "
|
||||
f"deleted successfully"), buffer.getvalue().strip())
|
||||
|
||||
def test_delete_multiple_vnf_fm_sub(self):
|
||||
arg_list = []
|
||||
for obj in self.vnf_fm_subs:
|
||||
arg_list.append(obj['id'])
|
||||
verify_list = [('vnf_fm_sub_id', arg_list)]
|
||||
parsed_args = self.check_parser(self.delete_vnf_fm_sub, arg_list,
|
||||
verify_list)
|
||||
for i in range(0, 3):
|
||||
self._mock_request_url_for_delete(i)
|
||||
sys.stdout = buffer = StringIO()
|
||||
result = self.delete_vnf_fm_sub.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual('All specified VNF FM subscriptions are deleted '
|
||||
'successfully', buffer.getvalue().strip())
|
||||
|
||||
def test_delete_multiple_vnf_fm_sub_exception(self):
|
||||
arg_list = [
|
||||
self.vnf_fm_subs[0]['id'],
|
||||
'xxxx-yyyy-zzzz',
|
||||
self.vnf_fm_subs[1]['id'],
|
||||
]
|
||||
verify_list = [('vnf_fm_sub_id', arg_list)]
|
||||
parsed_args = self.check_parser(self.delete_vnf_fm_sub,
|
||||
arg_list, verify_list)
|
||||
|
||||
self._mock_request_url_for_delete(0)
|
||||
|
||||
url = os.path.join(self.url, 'vnffm/v1/subscriptions',
|
||||
'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_fm_sub.take_action,
|
||||
parsed_args)
|
||||
|
||||
self.assertEqual('Failed to delete 1 of 3 VNF FM subscriptions.',
|
||||
exception.message)
|
||||
@@ -13,8 +13,18 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from io import StringIO
|
||||
import os
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.osc.v1.vnflcm import vnflcm
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
from tackerclient.tests.unit.osc.v1 import test_vnflcm
|
||||
from tackerclient.tests.unit.osc.v1 import vnflcm_fakes
|
||||
from tackerclient.v1_0 import client as proxy_client
|
||||
|
||||
|
||||
class TestVnfLcmV2(base.FixturedTestCase):
|
||||
@@ -30,3 +40,112 @@ class TestVnfLcmV2(base.FixturedTestCase):
|
||||
self.assertEqual(self.cs.vnf_lcm_client.vnf_instances_path,
|
||||
'/vnflcm/v2/vnf_instances')
|
||||
# check of other paths is omitted.
|
||||
|
||||
|
||||
class TestChangeVnfPkgVnfLcm(test_vnflcm.TestVnfLcm):
|
||||
api_version = '2'
|
||||
|
||||
def setUp(self):
|
||||
super(TestChangeVnfPkgVnfLcm, self).setUp()
|
||||
self.change_vnfpkg_vnf_lcm = vnflcm.ChangeVnfPkgVnfLcm(
|
||||
self.app, self.app_args,
|
||||
cmd_name='vnflcm change-vnfpkg')
|
||||
|
||||
def test_take_action(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = ("./tackerclient/osc/v2/vnflcm/samples/"
|
||||
"change_vnfpkg_vnf_instance_param_sample.json")
|
||||
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v2/vnf_instances',
|
||||
vnf_instance['id'], 'change_vnfpkg')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, json={})
|
||||
|
||||
sys.stdout = buffer = StringIO()
|
||||
with mock.patch.object(proxy_client.ClientBase,
|
||||
'_handle_fault_response') as m:
|
||||
self.change_vnfpkg_vnf_lcm.take_action(parsed_args)
|
||||
# check no fault response is received
|
||||
self.assertNotCalled(m)
|
||||
self.assertEqual(
|
||||
('Change Current VNF Package for VNF Instance {0} '
|
||||
'has been accepted.'.format(vnf_instance['id'])),
|
||||
buffer.getvalue().strip())
|
||||
|
||||
def test_take_action_vnf_instance_not_found(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||
"change_vnfpkg_vnf_instance_param_sample.json")
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v2/vnf_instances',
|
||||
vnf_instance['id'], 'change_vnfpkg')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.change_vnfpkg_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_param_file_not_exists(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = "./not_exists.json"
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
ex = self.assertRaises(
|
||||
exceptions.InvalidInput,
|
||||
self.change_vnfpkg_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
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")
|
||||
def test_take_action_invalid_format_param_file(self, mock_access,
|
||||
mock_open):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = "./invalid_param_file.json"
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
mock_open.return_value = "invalid_json_data"
|
||||
mock_access.return_value = True
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
ex = self.assertRaises(
|
||||
exceptions.InvalidInput,
|
||||
self.change_vnfpkg_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
expected_msg = "Failed to load parameter file."
|
||||
self.assertIn(expected_msg, str(ex))
|
||||
|
||||
476
tackerclient/tests/unit/osc/v2/test_vnfpm_job.py
Normal file
476
tackerclient/tests/unit/osc/v2/test_vnfpm_job.py
Normal file
@@ -0,0 +1,476 @@
|
||||
# Copyright (C) 2022 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_job
|
||||
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_job_fakes
|
||||
|
||||
|
||||
class TestVnfPmJob(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfPmJob, 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_job(action=None):
|
||||
if action == 'update':
|
||||
columns = ['Callback Uri', 'Authentication']
|
||||
else:
|
||||
columns = ['ID', 'Object Type', 'Object Instance Ids',
|
||||
'Sub Object Instance Ids', 'Criteria', 'Callback Uri',
|
||||
'Reports', 'Links']
|
||||
if action == 'list':
|
||||
columns = [
|
||||
ele for ele in columns if ele not in [
|
||||
'Criteria', 'Sub Object Instance Ids', 'Reports', 'Links'
|
||||
]
|
||||
]
|
||||
return columns
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestCreateVnfPmJob(TestVnfPmJob):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCreateVnfPmJob, self).setUp()
|
||||
self.create_vnf_pm_job = vnfpm_job.CreateVnfPmJob(
|
||||
self.app, self.app_args, cmd_name='vnfpm job create')
|
||||
|
||||
def test_create_no_args(self):
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.create_vnf_pm_job, [], [])
|
||||
|
||||
@ddt.unpack
|
||||
def test_take_action(self):
|
||||
param_file = ("./tackerclient/osc/v2/vnfpm/samples/"
|
||||
"create_vnf_pm_job_param_sample.json")
|
||||
|
||||
arg_list = [param_file]
|
||||
verify_list = [('request_file', param_file)]
|
||||
|
||||
parsed_args = self.check_parser(self.create_vnf_pm_job, arg_list,
|
||||
verify_list)
|
||||
|
||||
json = vnfpm_job_fakes.vnf_pm_job_response()
|
||||
self.requests_mock.register_uri(
|
||||
'POST', os.path.join(self.url, 'vnfpm/v2/pm_jobs'),
|
||||
json=json, headers=self.header)
|
||||
|
||||
actual_columns, data = (
|
||||
self.create_vnf_pm_job.take_action(parsed_args))
|
||||
self.assertCountEqual(_get_columns_vnfpm_job(),
|
||||
actual_columns)
|
||||
|
||||
_, attributes = vnfpm_job._get_columns(json)
|
||||
expected_data = vnfpm_job_fakes.get_vnfpm_job_data(
|
||||
json, columns=attributes)
|
||||
self.assertListItemsEqual(expected_data, data)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestListVnfPmJob(TestVnfPmJob):
|
||||
|
||||
def setUp(self):
|
||||
super(TestListVnfPmJob, self).setUp()
|
||||
self.list_vnf_pm_jobs = vnfpm_job.ListVnfPmJob(
|
||||
self.app, self.app_args, cmd_name='vnfpm job list')
|
||||
self._vnf_pm_jobs = self._get_vnf_pm_jobs()
|
||||
|
||||
def _get_vnf_pm_jobs(self):
|
||||
return vnfpm_job_fakes.create_vnf_pm_jobs(count=3)
|
||||
|
||||
def get_list_columns(self, all_fields=False, exclude_fields=None,
|
||||
extra_fields=None, exclude_default=False):
|
||||
|
||||
columns = ['Id', 'Object Type', 'Links']
|
||||
complex_columns = [
|
||||
'Object Instance Ids',
|
||||
'Sub Object Instance Ids',
|
||||
'Criteria',
|
||||
'Reports'
|
||||
]
|
||||
simple_columns = ['Callback Uri']
|
||||
|
||||
if extra_fields:
|
||||
columns.extend(extra_fields)
|
||||
|
||||
if exclude_fields:
|
||||
columns.extend([field for field in complex_columns
|
||||
if field not in exclude_fields])
|
||||
if all_fields:
|
||||
columns.extend(complex_columns)
|
||||
columns.extend(simple_columns)
|
||||
|
||||
if exclude_default:
|
||||
columns.extend(simple_columns)
|
||||
|
||||
return columns
|
||||
|
||||
def _get_mock_response_for_list_vnf_pm_jobs(
|
||||
self, filter_attribute, json=None):
|
||||
self.requests_mock.register_uri(
|
||||
'GET', self.url + '/vnfpm/v2/pm_jobs?' + filter_attribute,
|
||||
json=json if json else self._get_vnf_pm_jobs(),
|
||||
headers=self.header)
|
||||
|
||||
def test_take_action_default_fields(self):
|
||||
parsed_args = self.check_parser(self.list_vnf_pm_jobs, [], [])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', self.url + '/vnfpm/v2/pm_jobs',
|
||||
json=self._vnf_pm_jobs, headers=self.header)
|
||||
actual_columns, data = self.list_vnf_pm_jobs.take_action(parsed_args)
|
||||
expected_data = []
|
||||
_, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnf_pm_jobs.get_attributes(), long_listing=True)
|
||||
|
||||
for vnf_pm_job_obj in self._vnf_pm_jobs['vnf_pm_jobs']:
|
||||
expected_data.append(vnfpm_job_fakes.get_vnfpm_job_data(
|
||||
vnf_pm_job_obj, columns=columns))
|
||||
self.assertCountEqual(self.get_list_columns(), actual_columns)
|
||||
self.assertListItemsEqual(expected_data, list(data))
|
||||
|
||||
@ddt.data('all_fields', 'exclude_default')
|
||||
def test_take_action(self, arg):
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnf_pm_jobs,
|
||||
["--" + arg, "--filter", '(eq,objectType,VNFC)'],
|
||||
[(arg, True), ('filter', '(eq,objectType,VNFC)')])
|
||||
vnf_pm_jobs = self._get_vnf_pm_jobs()
|
||||
self._get_mock_response_for_list_vnf_pm_jobs(
|
||||
'filter=(eq,objectType,VNFC)&' + arg, json=vnf_pm_jobs)
|
||||
|
||||
actual_columns, data = self.list_vnf_pm_jobs.take_action(parsed_args)
|
||||
expected_data = []
|
||||
kwargs = {arg: True}
|
||||
_, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnf_pm_jobs.get_attributes(**kwargs), long_listing=True)
|
||||
|
||||
for vnf_pm_job_obj in vnf_pm_jobs['vnf_pm_jobs']:
|
||||
expected_data.append(vnfpm_job_fakes.get_vnfpm_job_data(
|
||||
vnf_pm_job_obj, columns=columns))
|
||||
|
||||
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_pm_jobs,
|
||||
["--exclude_fields", 'objectInstanceIds,criteria',
|
||||
"--filter", '(eq,objectType,VNFC)'],
|
||||
[('exclude_fields', 'objectInstanceIds,criteria'),
|
||||
('filter', '(eq,objectType,VNFC)')])
|
||||
vnf_pm_jobs = self._get_vnf_pm_jobs()
|
||||
updated_vnf_pm_jobs = {'vnf_pm_jobs': []}
|
||||
for vnf_pm_job_obj in vnf_pm_jobs['vnf_pm_jobs']:
|
||||
vnf_pm_job_obj.pop('objectInstanceIds')
|
||||
vnf_pm_job_obj.pop('criteria')
|
||||
updated_vnf_pm_jobs['vnf_pm_jobs'].append(vnf_pm_job_obj)
|
||||
self._get_mock_response_for_list_vnf_pm_jobs(
|
||||
'filter=(eq,objectType,VNFC)&'
|
||||
'exclude_fields=objectInstanceIds,criteria',
|
||||
json=updated_vnf_pm_jobs)
|
||||
|
||||
actual_columns, data = self.list_vnf_pm_jobs.take_action(parsed_args)
|
||||
expected_data = []
|
||||
_, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnf_pm_jobs.get_attributes(
|
||||
exclude_fields=['objectInstanceIds', 'criteria']),
|
||||
long_listing=True)
|
||||
|
||||
for updated_vnf_pm_obj in updated_vnf_pm_jobs['vnf_pm_jobs']:
|
||||
expected_data.append(vnfpm_job_fakes.get_vnfpm_job_data(
|
||||
updated_vnf_pm_obj, columns=columns))
|
||||
expected_columns = self.get_list_columns(
|
||||
exclude_fields=['Object Instance Ids', 'Criteria'])
|
||||
self.assertCountEqual(expected_columns, actual_columns)
|
||||
self.assertListItemsEqual(expected_data, list(data))
|
||||
|
||||
@ddt.data((['--all_fields', '--fields', 'objectInstanceIds'],
|
||||
[('all_fields', True), ('fields', 'objectInstanceIds')]),
|
||||
(['--all_fields', '--exclude_fields', 'criteria'],
|
||||
[('all_fields', True), ('exclude_fields', 'criteria')]),
|
||||
(['--fields', 'objectInstanceIds',
|
||||
'--exclude_fields', 'criteria'],
|
||||
[('fields', 'objectInstanceIds'),
|
||||
('exclude_fields', 'criteria')]))
|
||||
@ddt.unpack
|
||||
def test_take_action_with_invalid_combination(self, arglist, verifylist):
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.list_vnf_pm_jobs, arglist, verifylist)
|
||||
|
||||
def test_take_action_with_valid_combination(self):
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnf_pm_jobs,
|
||||
[
|
||||
"--fields", 'subObjectInstanceIds,criteria',
|
||||
"--exclude_default"
|
||||
],
|
||||
[
|
||||
('fields', 'subObjectInstanceIds,criteria'),
|
||||
('exclude_default', True)
|
||||
])
|
||||
vnf_pm_jobs = self._get_vnf_pm_jobs()
|
||||
|
||||
updated_vnf_pm_jobs = {'vnf_pm_jobs': []}
|
||||
for vnf_pm_job_obj in vnf_pm_jobs['vnf_pm_jobs']:
|
||||
# vnf_pm_job_obj.pop('userDefinedData')
|
||||
updated_vnf_pm_jobs['vnf_pm_jobs'].append(vnf_pm_job_obj)
|
||||
|
||||
self._get_mock_response_for_list_vnf_pm_jobs(
|
||||
'exclude_default&fields=subObjectInstanceIds,criteria',
|
||||
json=updated_vnf_pm_jobs)
|
||||
|
||||
actual_columns, data = self.list_vnf_pm_jobs.take_action(parsed_args)
|
||||
expected_data = []
|
||||
_, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnf_pm_jobs.get_attributes(
|
||||
extra_fields=['subObjectInstanceIds', 'criteria'],
|
||||
exclude_default=True),
|
||||
long_listing=True)
|
||||
|
||||
for updated_vnf_pm_job_obj in updated_vnf_pm_jobs['vnf_pm_jobs']:
|
||||
expected_data.append(vnfpm_job_fakes.get_vnfpm_job_data(
|
||||
updated_vnf_pm_job_obj, columns=columns))
|
||||
|
||||
expected_columns = self.get_list_columns(
|
||||
extra_fields=['Sub Object Instance Ids', 'Criteria'],
|
||||
exclude_default=True)
|
||||
self.assertCountEqual(expected_columns, actual_columns)
|
||||
self.assertListItemsEqual(expected_data, list(data))
|
||||
|
||||
|
||||
class TestShowVnfPmJob(TestVnfPmJob):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShowVnfPmJob, self).setUp()
|
||||
self.show_vnf_pm_jobs = vnfpm_job.ShowVnfPmJob(
|
||||
self.app, self.app_args, cmd_name='vnfpm job show')
|
||||
|
||||
def test_take_action(self):
|
||||
"""Test of take_action()"""
|
||||
vnfpm_job_obj = vnfpm_job_fakes.vnf_pm_job_response()
|
||||
|
||||
arg_list = [vnfpm_job_obj['id']]
|
||||
verify_list = [('vnf_pm_job_id', vnfpm_job_obj['id'])]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_pm_jobs, arg_list, verify_list)
|
||||
url = os.path.join(
|
||||
self.url, 'vnfpm/v2/pm_jobs', vnfpm_job_obj['id'])
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, json=vnfpm_job_obj)
|
||||
|
||||
columns, data = (self.show_vnf_pm_jobs.take_action(parsed_args))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnfpm_job('show'), columns)
|
||||
|
||||
_, attributes = vnfpm_job._get_columns(vnfpm_job_obj)
|
||||
self.assertListItemsEqual(
|
||||
vnfpm_job_fakes.get_vnfpm_job_data(
|
||||
vnfpm_job_obj, columns=attributes), data)
|
||||
|
||||
def test_take_action_vnf_pm_job_id_not_found(self):
|
||||
"""Test if vnf-pm-job-id does not find."""
|
||||
arg_list = [uuidsentinel.vnf_pm_job_id]
|
||||
verify_list = [('vnf_pm_job_id', uuidsentinel.vnf_pm_job_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_pm_jobs, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnfpm/v2/pm_jobs', uuidsentinel.vnf_pm_job_id)
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_pm_jobs.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_internal_server_error(self):
|
||||
"""Test for internal server error."""
|
||||
arg_list = [uuidsentinel.vnf_pm_job_id]
|
||||
verify_list = [('vnf_pm_job_id', uuidsentinel.vnf_pm_job_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_pm_jobs, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnfpm/v2/pm_jobs', uuidsentinel.vnf_pm_job_id)
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_pm_jobs.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestUpdateVnfPmJob(TestVnfPmJob):
|
||||
|
||||
def setUp(self):
|
||||
super(TestUpdateVnfPmJob, self).setUp()
|
||||
self.update_vnf_pm_job = vnfpm_job.UpdateVnfPmJob(
|
||||
self.app, self.app_args, cmd_name='vnfpm job update')
|
||||
|
||||
def test_take_action(self):
|
||||
"""Test of take_action()"""
|
||||
|
||||
param_file = ("./tackerclient/osc/v2/vnfpm/samples/"
|
||||
"update_vnf_pm_job_param_sample.json")
|
||||
arg_list = [uuidsentinel.vnf_pm_job_id, param_file]
|
||||
verify_list = [
|
||||
('vnf_pm_job_id', uuidsentinel.vnf_pm_job_id),
|
||||
('request_file', param_file)
|
||||
]
|
||||
vnfpm_job_obj = vnfpm_job_fakes.vnf_pm_job_response(
|
||||
None, 'update')
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.update_vnf_pm_job, arg_list, verify_list)
|
||||
url = os.path.join(
|
||||
self.url, 'vnfpm/v2/pm_jobs', uuidsentinel.vnf_pm_job_id)
|
||||
self.requests_mock.register_uri(
|
||||
'PATCH', url, headers=self.header, json=vnfpm_job_obj)
|
||||
|
||||
actual_columns, data = (
|
||||
self.update_vnf_pm_job.take_action(parsed_args))
|
||||
expected_columns = _get_columns_vnfpm_job(action='update')
|
||||
self.assertCountEqual(expected_columns, actual_columns)
|
||||
|
||||
_, columns = vnfpm_job._get_columns(
|
||||
vnfpm_job_obj, action='update')
|
||||
expected_data = vnfpm_job_fakes.get_vnfpm_job_data(
|
||||
vnfpm_job_obj, columns=columns)
|
||||
self.assertEqual(expected_data, data)
|
||||
|
||||
def test_take_action_vnf_pm_job_id_not_found(self):
|
||||
"""Test if vnf-pm-job-id does not find"""
|
||||
|
||||
param_file = ("./tackerclient/osc/v2/vnfpm/samples/"
|
||||
"update_vnf_pm_job_param_sample.json")
|
||||
arg_list = [uuidsentinel.vnf_pm_job_id, param_file]
|
||||
verify_list = [
|
||||
('vnf_pm_job_id', uuidsentinel.vnf_pm_job_id),
|
||||
('request_file', param_file)
|
||||
]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.update_vnf_pm_job, arg_list, verify_list)
|
||||
url = os.path.join(
|
||||
self.url, 'vnfpm/v2/pm_jobs', uuidsentinel.vnf_pm_job_id)
|
||||
self.requests_mock.register_uri(
|
||||
'PATCH', url, headers=self.header, status_code=404, json={})
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.update_vnf_pm_job.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestDeleteVnfPmJob(TestVnfPmJob):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDeleteVnfPmJob, self).setUp()
|
||||
self.delete_vnf_pm_job = vnfpm_job.DeleteVnfPmJob(
|
||||
self.app, self.app_args, cmd_name='vnfpm job delete')
|
||||
|
||||
# Vnf Fm job to delete
|
||||
self.vnf_pm_jobs = vnfpm_job_fakes.create_vnf_pm_jobs(
|
||||
count=3)['vnf_pm_jobs']
|
||||
|
||||
def _mock_request_url_for_delete(self, index):
|
||||
url = os.path.join(self.url, 'vnfpm/v2/pm_jobs',
|
||||
self.vnf_pm_jobs[index]['id'])
|
||||
|
||||
self.requests_mock.register_uri('DELETE', url,
|
||||
headers=self.header, json={})
|
||||
|
||||
def test_delete_one_vnf_pm_job(self):
|
||||
arg_list = [self.vnf_pm_jobs[0]['id']]
|
||||
verify_list = [('vnf_pm_job_id',
|
||||
[self.vnf_pm_jobs[0]['id']])]
|
||||
|
||||
parsed_args = self.check_parser(self.delete_vnf_pm_job, arg_list,
|
||||
verify_list)
|
||||
|
||||
self._mock_request_url_for_delete(0)
|
||||
sys.stdout = buffer = StringIO()
|
||||
result = self.delete_vnf_pm_job.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual(
|
||||
(f"VNF PM job '{self.vnf_pm_jobs[0]['id']}' "
|
||||
f"deleted successfully"), buffer.getvalue().strip())
|
||||
|
||||
def test_delete_multiple_vnf_pm_job(self):
|
||||
arg_list = []
|
||||
for obj in self.vnf_pm_jobs:
|
||||
arg_list.append(obj['id'])
|
||||
verify_list = [('vnf_pm_job_id', arg_list)]
|
||||
parsed_args = self.check_parser(self.delete_vnf_pm_job, arg_list,
|
||||
verify_list)
|
||||
for i in range(0, 3):
|
||||
self._mock_request_url_for_delete(i)
|
||||
sys.stdout = buffer = StringIO()
|
||||
result = self.delete_vnf_pm_job.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual('All specified VNF PM jobs are deleted '
|
||||
'successfully', buffer.getvalue().strip())
|
||||
|
||||
def test_delete_multiple_vnf_pm_job_exception(self):
|
||||
arg_list = [
|
||||
self.vnf_pm_jobs[0]['id'],
|
||||
'xxxx-yyyy-zzzz',
|
||||
self.vnf_pm_jobs[1]['id'],
|
||||
]
|
||||
verify_list = [('vnf_pm_job_id', arg_list)]
|
||||
parsed_args = self.check_parser(self.delete_vnf_pm_job,
|
||||
arg_list, verify_list)
|
||||
|
||||
self._mock_request_url_for_delete(0)
|
||||
|
||||
url = os.path.join(self.url, 'vnfpm/v2/jobs',
|
||||
'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_job.take_action,
|
||||
parsed_args)
|
||||
|
||||
self.assertEqual('Failed to delete 1 of 3 VNF PM jobs.',
|
||||
exception.message)
|
||||
131
tackerclient/tests/unit/osc/v2/test_vnfpm_report.py
Normal file
131
tackerclient/tests/unit/osc/v2/test_vnfpm_report.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# Copyright (C) 2022 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 os
|
||||
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
from unittest import mock
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.osc.v2.vnfpm import vnfpm_report
|
||||
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_report_fakes
|
||||
|
||||
|
||||
class TestVnfPmReport(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfPmReport, 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_report():
|
||||
columns = ['Entries']
|
||||
return columns
|
||||
|
||||
|
||||
class TestShowVnfPmReport(TestVnfPmReport):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShowVnfPmReport, self).setUp()
|
||||
self.show_vnf_pm_reports = vnfpm_report.ShowVnfPmReport(
|
||||
self.app, self.app_args, cmd_name='vnfpm report show')
|
||||
|
||||
def test_take_action(self):
|
||||
"""Test of take_action()"""
|
||||
vnfpm_report_obj = vnfpm_report_fakes.vnf_pm_report_response()
|
||||
vnf_pm_job_id = uuidsentinel.vnf_pm_job_id
|
||||
vnf_pm_report_id = uuidsentinel.vnfpm_report_obj
|
||||
arg_list = [vnf_pm_job_id, vnf_pm_report_id]
|
||||
verify_list = [
|
||||
('vnf_pm_job_id', vnf_pm_job_id),
|
||||
('vnf_pm_report_id', vnf_pm_report_id)
|
||||
]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_pm_reports, arg_list, verify_list)
|
||||
url = os.path.join(
|
||||
self.url, 'vnfpm/v2/pm_jobs', vnf_pm_job_id,
|
||||
'reports', vnf_pm_report_id)
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, json=vnfpm_report_obj)
|
||||
|
||||
columns, data = (self.show_vnf_pm_reports.take_action(parsed_args))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnfpm_report(), columns)
|
||||
|
||||
_, attributes = vnfpm_report._get_columns(vnfpm_report_obj)
|
||||
expected_data = vnfpm_report_fakes.get_vnfpm_report_data(
|
||||
vnfpm_report_obj, columns=attributes)
|
||||
|
||||
print(f'123, {expected_data}')
|
||||
print(f'456, {data}')
|
||||
self.assertListItemsEqual(expected_data, data)
|
||||
|
||||
def test_take_action_vnf_pm_report_id_not_found(self):
|
||||
"""Test if vnf-pm-report-id does not find."""
|
||||
vnf_pm_job_id = uuidsentinel.vnf_pm_job_id
|
||||
vnf_pm_report_id = uuidsentinel.vnf_pm_report_id
|
||||
arg_list = [vnf_pm_job_id, vnf_pm_report_id]
|
||||
verify_list = [
|
||||
('vnf_pm_job_id', vnf_pm_job_id),
|
||||
('vnf_pm_report_id', vnf_pm_report_id)
|
||||
]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_pm_reports, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnfpm/v2/pm_jobs', vnf_pm_job_id,
|
||||
'reports', vnf_pm_report_id)
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_pm_reports.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_internal_server_error(self):
|
||||
"""Test for internal server error."""
|
||||
vnf_pm_job_id = uuidsentinel.vnf_pm_job_id
|
||||
vnf_pm_report_id = uuidsentinel.vnf_pm_report_id
|
||||
arg_list = [vnf_pm_job_id, vnf_pm_report_id]
|
||||
verify_list = [
|
||||
('vnf_pm_job_id', vnf_pm_job_id),
|
||||
('vnf_pm_report_id', vnf_pm_report_id)
|
||||
]
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_pm_reports, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url, 'vnfpm/v2/pm_jobs', vnf_pm_job_id,
|
||||
'reports', vnf_pm_report_id)
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_pm_reports.take_action,
|
||||
parsed_args)
|
||||
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)
|
||||
127
tackerclient/tests/unit/osc/v2/vnffm_alarm_fakes.py
Normal file
127
tackerclient/tests/unit/osc/v2/vnffm_alarm_fakes.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# Copyright (C) 2022 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_fm_alarms(count=2):
|
||||
"""Create multiple fake vnf packages.
|
||||
|
||||
:param int count:
|
||||
The number of vnf_fm_alarms to fake
|
||||
:return:
|
||||
A list of fake vnf fm alarms dictionary
|
||||
"""
|
||||
vnf_fm_alarms = []
|
||||
for i in range(0, count):
|
||||
unique_id = uuidutils.generate_uuid()
|
||||
vnf_fm_alarms.append(vnf_fm_alarm_response(attrs={'id': unique_id}))
|
||||
return vnf_fm_alarms
|
||||
|
||||
|
||||
def vnf_fm_alarm_response(attrs=None, action=None):
|
||||
"""Create a fake vnf fm alarm.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:return:
|
||||
A FakeVnfFmAlarm dict
|
||||
"""
|
||||
|
||||
if action == 'update':
|
||||
fake_vnf_fm_alarm = {
|
||||
"ackState": "UNACKNOWLEDGED"
|
||||
}
|
||||
return fake_vnf_fm_alarm
|
||||
|
||||
attrs = attrs or {}
|
||||
# Set default attributes.
|
||||
fake_vnf_fm_alarm = {
|
||||
"id": "78a39661-60a8-4824-b989-88c1b0c3534a",
|
||||
"managedObjectId": "c61314d0-f583-4ab3-a457-46426bce02d3",
|
||||
"vnfcInstanceIds": "0e5f3086-4e79-47ed-a694-54c29155fa26",
|
||||
"rootCauseFaultyResource": {
|
||||
"faultyResource": {
|
||||
"vimConnectionId": "0d57e928-86a4-4445-a4bd-1634edae73f3",
|
||||
"resourceId": "4e6ccbe1-38ec-4b1b-a278-64de09ba01b3",
|
||||
"vimLevelResourceType": "OS::Nova::Server"
|
||||
},
|
||||
"faultyResourceType": "COMPUTE"
|
||||
},
|
||||
"alarmRaisedTime": "2021-09-03 10:21:03",
|
||||
"alarmChangedTime": "2021-09-04 10:21:03",
|
||||
"alarmClearedTime": "2021-09-05 10:21:03",
|
||||
"alarmAcknowledgedTime": "2021-09-06 10:21:03",
|
||||
"ackState": "UNACKNOWLEDGED",
|
||||
"perceivedSeverity": "WARNING",
|
||||
"eventTime": "2021-09-07 10:06:03",
|
||||
"eventType": "EQUIPMENT_ALARM",
|
||||
"faultType": "Fault Type",
|
||||
"probableCause": "The server cannot be connected.",
|
||||
"isRootCause": False,
|
||||
"correlatedAlarmIds": [
|
||||
"c88b624e-e997-4b17-b674-10ca2bab62e0",
|
||||
"c16d41fd-12e2-49a6-bb17-72faf702353f"
|
||||
],
|
||||
"faultDetails": [
|
||||
"Fault",
|
||||
"Details"
|
||||
],
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "/vnffm/v1/alarms/"
|
||||
"78a39661-60a8-4824-b989-88c1b0c3534a"
|
||||
},
|
||||
"objectInstance": {
|
||||
"href": "/vnflcm/v1/vnf_instances/"
|
||||
"0e5f3086-4e79-47ed-a694-54c29155fa26"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
fake_vnf_fm_alarm.update(attrs)
|
||||
|
||||
return fake_vnf_fm_alarm
|
||||
|
||||
|
||||
def get_vnffm_alarm_data(vnf_fm_alarm, columns=None):
|
||||
"""Get the vnffm alarm.
|
||||
|
||||
:return:
|
||||
A tuple object sorted based on the name of the columns.
|
||||
"""
|
||||
complex_attributes = [
|
||||
'vnfcInstanceIds',
|
||||
'rootCauseFaultyResource',
|
||||
'correlatedAlarmIds',
|
||||
'faultDetails',
|
||||
'_links'
|
||||
]
|
||||
|
||||
for attribute in complex_attributes:
|
||||
if vnf_fm_alarm.get(attribute):
|
||||
vnf_fm_alarm.update(
|
||||
{attribute: tacker_osc_utils.FormatComplexDataColumn(
|
||||
vnf_fm_alarm[attribute])})
|
||||
|
||||
# return the list of data as per column order
|
||||
if columns:
|
||||
return tuple([vnf_fm_alarm[key] for key in columns])
|
||||
|
||||
return tuple([vnf_fm_alarm[key] for key in sorted(
|
||||
vnf_fm_alarm.keys())])
|
||||
127
tackerclient/tests/unit/osc/v2/vnffm_sub_fakes.py
Normal file
127
tackerclient/tests/unit/osc/v2/vnffm_sub_fakes.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# Copyright (C) 2022 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_fm_subs(count=2):
|
||||
"""Create multiple fake vnf packages.
|
||||
|
||||
:param int count:
|
||||
The number of vnf_fm_subs to fake
|
||||
:return:
|
||||
A list of fake vnf fm subs dictionary
|
||||
"""
|
||||
vnf_fm_subs = []
|
||||
for i in range(0, count):
|
||||
unique_id = uuidutils.generate_uuid()
|
||||
vnf_fm_subs.append(vnf_fm_sub_response(attrs={'id': unique_id}))
|
||||
return vnf_fm_subs
|
||||
|
||||
|
||||
def vnf_fm_sub_response(attrs=None):
|
||||
"""Create a fake vnf fm sub.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:return:
|
||||
A FakeVnfFmAlarm dict
|
||||
"""
|
||||
|
||||
attrs = attrs or {}
|
||||
# Set default attributes.
|
||||
fake_vnf_fm_sub = {
|
||||
"id": "78a39661-60a8-4824-b989-88c1b0c3534a",
|
||||
"filter": {
|
||||
"vnfInstanceSubscriptionFilter": {
|
||||
"vnfdIds": [
|
||||
"dummy-vnfdId-1"
|
||||
],
|
||||
"vnfProductsFromProviders": [
|
||||
{
|
||||
"vnfProvider": "dummy-vnfProvider-1",
|
||||
"vnfProducts": [
|
||||
{
|
||||
"vnfProductName": "dummy-vnfProductName-1-1",
|
||||
"versions": [
|
||||
{
|
||||
"vnfSoftwareVersion": 1.0,
|
||||
"vnfdVersions": [1.0, 2.0]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vnfInstanceIds": [
|
||||
"dummy-vnfInstanceId-1"
|
||||
],
|
||||
"vnfInstanceNames": [
|
||||
"dummy-vnfInstanceName-1"
|
||||
]
|
||||
},
|
||||
"notificationTypes": [
|
||||
"AlarmNotification"
|
||||
],
|
||||
"faultyResourceTypes": [
|
||||
"COMPUTE"
|
||||
],
|
||||
"perceivedSeverities": [
|
||||
"WARNING"
|
||||
],
|
||||
"eventTypes": [
|
||||
"EQUIPMENT_ALARM"
|
||||
],
|
||||
"probableCauses": [
|
||||
"The server cannot be connected."
|
||||
]
|
||||
},
|
||||
"callbackUri": "/nfvo/notify/alarm",
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "/vnffm/v1/subscriptions/"
|
||||
"78a39661-60a8-4824-b989-88c1b0c3534a"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
fake_vnf_fm_sub.update(attrs)
|
||||
|
||||
return fake_vnf_fm_sub
|
||||
|
||||
|
||||
def get_vnffm_sub_data(vnf_fm_sub, columns=None):
|
||||
"""Get the vnffm sub.
|
||||
|
||||
:return:
|
||||
A tuple object sorted based on the name of the columns.
|
||||
"""
|
||||
complex_attributes = ['filter', '_links']
|
||||
|
||||
for attribute in complex_attributes:
|
||||
if vnf_fm_sub.get(attribute):
|
||||
vnf_fm_sub.update(
|
||||
{attribute: tacker_osc_utils.FormatComplexDataColumn(
|
||||
vnf_fm_sub[attribute])})
|
||||
|
||||
# return the list of data as per column order
|
||||
if columns:
|
||||
return tuple([vnf_fm_sub[key] for key in columns])
|
||||
|
||||
return tuple([vnf_fm_sub[key] for key in sorted(
|
||||
vnf_fm_sub.keys())])
|
||||
134
tackerclient/tests/unit/osc/v2/vnfpm_job_fakes.py
Normal file
134
tackerclient/tests/unit/osc/v2/vnfpm_job_fakes.py
Normal file
@@ -0,0 +1,134 @@
|
||||
# Copyright (C) 2022 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_jobs(count=2):
|
||||
"""Create multiple fake vnf pm jobs.
|
||||
|
||||
:param int count:
|
||||
The number of vnf_pm_jobs to fake
|
||||
:return:
|
||||
A list of fake vnf pm jobs dictionary
|
||||
"""
|
||||
vnf_pm_jobs = []
|
||||
for i in range(0, count):
|
||||
unique_id = uuidutils.generate_uuid()
|
||||
vnf_pm_jobs.append(vnf_pm_job_response(attrs={'id': unique_id}))
|
||||
return {'vnf_pm_jobs': vnf_pm_jobs}
|
||||
|
||||
|
||||
def vnf_pm_job_response(attrs=None, action=None):
|
||||
"""Create a fake vnf pm job.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:return:
|
||||
A pm job dict
|
||||
"""
|
||||
if action == 'update':
|
||||
fake_vnf_pm_job = {
|
||||
"callbackUri": "/nfvo/notify/job",
|
||||
"authentication": {
|
||||
"authType": [
|
||||
"BASIC",
|
||||
"OAUTH2_CLIENT_CREDENTIALS"
|
||||
],
|
||||
"paramsBasic": {
|
||||
"userName": "nfvo",
|
||||
"password": "nfvopwd"
|
||||
},
|
||||
"paramsOauth2ClientCredentials": {
|
||||
"clientId": "auth_user_name",
|
||||
"clientPassword": "auth_password",
|
||||
"tokenEndpoint": "token_endpoint"
|
||||
}
|
||||
}
|
||||
}
|
||||
return fake_vnf_pm_job
|
||||
|
||||
attrs = attrs or {}
|
||||
# Set default attributes.
|
||||
fake_vnf_pm_job = {
|
||||
"id": "2bb72d78-b1d9-48fe-8c64-332654ffeb5d",
|
||||
"objectType": "VNFC",
|
||||
"objectInstanceIds": [
|
||||
"object-instance-id-1"
|
||||
],
|
||||
"subObjectInstanceIds": [
|
||||
"sub-object-instance-id-2"
|
||||
],
|
||||
"criteria": {
|
||||
"performanceMetric": [
|
||||
"VCpuUsageMeanVnf.object-instance-id-1"
|
||||
],
|
||||
"performanceMetricGroup": [
|
||||
"VirtualisedComputeResource"
|
||||
],
|
||||
"collectionPeriod": 500,
|
||||
"reportingPeriod": 1000,
|
||||
"reportingBoundary": "2022/07/25 10:43:55"
|
||||
},
|
||||
"callbackUri": "/nfvo/notify/job",
|
||||
"reports": [{
|
||||
"href": "/vnfpm/v2/pm_jobs/2bb72d78-b1d9-48fe-8c64-332654ffeb5d/"
|
||||
"reports/09d46aed-3ec2-45d9-bfa2-add431e069b3",
|
||||
"readyTime": "2022/07/25 10:43:55",
|
||||
"expiryTime": "2022/07/25 10:43:55",
|
||||
"fileSize": 9999
|
||||
}],
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "/vnfpm/v2/pm_jobs/"
|
||||
"78a39661-60a8-4824-b989-88c1b0c3534a"
|
||||
},
|
||||
"objects": [{
|
||||
"href": "/vnflcm/v1/vnf_instances/"
|
||||
"0e5f3086-4e79-47ed-a694-54c29155fa26"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
fake_vnf_pm_job.update(attrs)
|
||||
|
||||
return fake_vnf_pm_job
|
||||
|
||||
|
||||
def get_vnfpm_job_data(vnf_pm_job, columns=None):
|
||||
"""Get the vnfpm job.
|
||||
|
||||
:return:
|
||||
A tuple object sorted based on the name of the columns.
|
||||
"""
|
||||
complex_attributes = [
|
||||
'objectInstanceIds', 'subObjectInstanceIds',
|
||||
'criteria', 'reports', '_links',
|
||||
'authentication'
|
||||
]
|
||||
|
||||
for attribute in complex_attributes:
|
||||
if vnf_pm_job.get(attribute):
|
||||
vnf_pm_job.update(
|
||||
{attribute: tacker_osc_utils.FormatComplexDataColumn(
|
||||
vnf_pm_job[attribute])})
|
||||
|
||||
# return the list of data as per column order
|
||||
if columns is None:
|
||||
columns = sorted(vnf_pm_job.keys())
|
||||
return tuple([vnf_pm_job[key] for key in columns])
|
||||
73
tackerclient/tests/unit/osc/v2/vnfpm_report_fakes.py
Normal file
73
tackerclient/tests/unit/osc/v2/vnfpm_report_fakes.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# Copyright (C) 2022 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 tackerclient.osc import utils as tacker_osc_utils
|
||||
|
||||
|
||||
def vnf_pm_report_response(attrs=None):
|
||||
"""Create a fake vnf pm report.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:return:
|
||||
A pm report dict
|
||||
"""
|
||||
|
||||
attrs = attrs or {}
|
||||
# Set default attributes.
|
||||
fake_vnf_pm_report = {
|
||||
"entries": [
|
||||
{
|
||||
"objectType": "VNFC",
|
||||
"objectInstanceId": "2bb72d78-b1d9-48fe-8c64-332654ffeb5d",
|
||||
"subObjectInstanceId": "09d46aed-3ec2-45d9-bfa2-add431e069b3",
|
||||
"performanceMetric":
|
||||
"VCpuUsagePeakVnf.2bb72d78-b1d9-48fe-8c64-332654ffeb5d,",
|
||||
"performanceValues": [
|
||||
{
|
||||
"timeStamp": "2022/07/27 08:58:58",
|
||||
"value": "1.88",
|
||||
"context": {
|
||||
"key": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
fake_vnf_pm_report.update(attrs)
|
||||
|
||||
return fake_vnf_pm_report
|
||||
|
||||
|
||||
def get_vnfpm_report_data(vnf_pm_report, columns=None):
|
||||
"""Get the vnfpm report.
|
||||
|
||||
:return:
|
||||
A tuple object sorted based on the name of the columns.
|
||||
"""
|
||||
attribute = 'entries'
|
||||
|
||||
if vnf_pm_report.get(attribute):
|
||||
vnf_pm_report.update(
|
||||
{attribute: tacker_osc_utils.FormatComplexDataColumn(
|
||||
vnf_pm_report[attribute])})
|
||||
|
||||
# return the list of data as per column order
|
||||
if columns is None:
|
||||
columns = sorted(vnf_pm_report.keys())
|
||||
return tuple([vnf_pm_report[key] for key in columns])
|
||||
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])
|
||||
@@ -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,
|
||||
@@ -76,6 +98,68 @@ class TestVIMUtils(testtools.TestCase):
|
||||
vim_utils.args2body_vim(config_param.copy(), vim)
|
||||
self.assertEqual(expected_vim, vim)
|
||||
|
||||
def test_args2body_kubernetes_vim_oidc(self):
|
||||
config_param = {'oidc_token_url': sentinel.oidc_token_url,
|
||||
'username': sentinel.username,
|
||||
'password': sentinel.password,
|
||||
'client_id': sentinel.client_id,
|
||||
'client_secret': sentinel.client_secret,
|
||||
'ssl_ca_cert': "None",
|
||||
'project_name': sentinel.prj_name,
|
||||
'type': 'kubernetes'}
|
||||
vim = {}
|
||||
auth_cred = config_param.copy()
|
||||
auth_cred.pop('project_name')
|
||||
auth_cred.pop('type')
|
||||
expected_vim = {'auth_cred': auth_cred,
|
||||
'vim_project':
|
||||
{'name': sentinel.prj_name},
|
||||
'type': 'kubernetes'}
|
||||
vim_utils.args2body_vim(config_param.copy(), vim)
|
||||
self.assertEqual(expected_vim, vim)
|
||||
|
||||
def test_args2body_kubernetes_vim_extra(self):
|
||||
extra_param = {
|
||||
'helm_info': {
|
||||
'masternode_ip': [
|
||||
'192.168.10.110'
|
||||
],
|
||||
'masternode_username': 'helm_user',
|
||||
'masternode_password': 'helm_pass'
|
||||
}}
|
||||
|
||||
config_param = {'username': sentinel.usrname1,
|
||||
'password': sentinel.password1,
|
||||
'ssl_ca_cert': 'abcxyz',
|
||||
'project_name': sentinel.prj_name,
|
||||
'type': 'kubernetes',
|
||||
'extra': extra_param}
|
||||
vim = {}
|
||||
auth_cred = config_param.copy()
|
||||
auth_cred.pop('project_name')
|
||||
auth_cred.pop('type')
|
||||
auth_cred.pop('extra')
|
||||
expected_vim = {'auth_cred': auth_cred,
|
||||
'vim_project':
|
||||
{'name': sentinel.prj_name},
|
||||
'type': 'kubernetes',
|
||||
'extra': extra_param}
|
||||
vim_utils.args2body_vim(config_param.copy(), vim)
|
||||
self.assertEqual(expected_vim, vim)
|
||||
|
||||
def test_args2body_kubernetes_vim_oidc_no_username(self):
|
||||
config_param = {'oidc_token_url': sentinel.oidc_token_url,
|
||||
'password': sentinel.password,
|
||||
'client_id': sentinel.client_id,
|
||||
'client_secret': sentinel.client_secret,
|
||||
'ssl_ca_cert': "None",
|
||||
'project_name': sentinel.prj_name,
|
||||
'type': 'kubernetes'}
|
||||
vim = {}
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
vim_utils.args2body_vim,
|
||||
config_param, vim)
|
||||
|
||||
def test_args2body_vim_no_project(self):
|
||||
config_param = {'username': sentinel.usrname1,
|
||||
'password': sentinel.password1,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#
|
||||
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
|
||||
import requests
|
||||
@@ -180,6 +181,8 @@ class ClientBase(object):
|
||||
self.format = 'json'
|
||||
self.action_prefix = "/v%s" % (self.version)
|
||||
self.retry_interval = 1
|
||||
self.rel = None
|
||||
self.params = None
|
||||
|
||||
def _handle_fault_response(self, status_code, response_body):
|
||||
# Create exception with HTTP status code and message
|
||||
@@ -246,6 +249,19 @@ class ClientBase(object):
|
||||
else:
|
||||
self.format = 'json'
|
||||
|
||||
url = None
|
||||
rel = None
|
||||
|
||||
link = resp.headers.get('Link', None)
|
||||
if link is not None:
|
||||
url = re.findall('<(.*)>', link)[0]
|
||||
rel = re.findall('rel="(.*)"', link)[0]
|
||||
|
||||
if rel == 'next':
|
||||
self.rel = 'next'
|
||||
query_str = urlparse.urlparse(url).query
|
||||
self.params = urlparse.parse_qs(query_str)
|
||||
|
||||
status_code = resp.status_code
|
||||
if status_code in (requests.codes.ok,
|
||||
requests.codes.created,
|
||||
@@ -379,21 +395,23 @@ class ClientBase(object):
|
||||
linkrel = 'next'
|
||||
next = True
|
||||
while next:
|
||||
self.rel = None
|
||||
res = self.get(path, headers=headers, params=params)
|
||||
yield res
|
||||
next = False
|
||||
try:
|
||||
# TODO(tpatil): Handle pagination for list data type
|
||||
# once it's supported by tacker.
|
||||
if type(res) is list:
|
||||
break
|
||||
|
||||
for link in res['%s_links' % collection]:
|
||||
if link['rel'] == linkrel:
|
||||
query_str = urlparse.urlparse(link['href']).query
|
||||
params = urlparse.parse_qs(query_str)
|
||||
if self.rel == 'next':
|
||||
params = self.params
|
||||
next = True
|
||||
break
|
||||
|
||||
else:
|
||||
for link in res['%s_links' % collection]:
|
||||
if link['rel'] == linkrel:
|
||||
query_str = urlparse.urlparse(link['href']).query
|
||||
params = urlparse.parse_qs(query_str)
|
||||
next = True
|
||||
break
|
||||
except KeyError:
|
||||
break
|
||||
|
||||
@@ -895,6 +913,10 @@ class VnfLCMClient(ClientBase):
|
||||
'/vnflcm/{}/vnf_lcm_op_occs'.format(sol_api_version))
|
||||
self.vnf_lcm_op_occs_path = (
|
||||
'/vnflcm/{}/vnf_lcm_op_occs/%s'.format(sol_api_version))
|
||||
self.lccn_subscriptions_path = (
|
||||
'/vnflcm/{}/subscriptions'.format(sol_api_version))
|
||||
self.lccn_subscription_path = (
|
||||
'/vnflcm/{}/subscriptions/%s'.format(sol_api_version))
|
||||
|
||||
def build_action(self, action):
|
||||
return action
|
||||
@@ -951,6 +973,11 @@ class VnfLCMClient(ClientBase):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/rollback") % occ_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def cancel_vnf_instance(self, occ_id, body):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/cancel") % occ_id,
|
||||
body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def fail_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/fail") % occ_id,
|
||||
@@ -961,6 +988,15 @@ class VnfLCMClient(ClientBase):
|
||||
return self.post((self.vnf_instance_path + "/change_ext_conn") %
|
||||
vnf_id, body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def change_vnfpkg_vnf_instance(self, vnf_id, body):
|
||||
# NOTE: it is only supported by V2-API.
|
||||
if self.vnf_instance_path.split('/')[2] == 'v2':
|
||||
return self.post((self.vnf_instance_path + "/change_vnfpkg") %
|
||||
vnf_id, body=body, headers=self.headers)
|
||||
else:
|
||||
raise exceptions.UnsupportedCommandVersion(version='1')
|
||||
|
||||
@APIParamsCall
|
||||
def retry_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/retry") % occ_id,
|
||||
@@ -978,6 +1014,28 @@ class VnfLCMClient(ClientBase):
|
||||
return self.get(self.vnf_lcm_op_occs_path % occ_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def create_lccn_subscription(self, body):
|
||||
return self.post(self.lccn_subscriptions_path, body=body,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_lccn_subscription(self, subsc_id):
|
||||
return self.delete(self.lccn_subscription_path % subsc_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def list_lccn_subscriptions(self, retrieve_all=True, **_params):
|
||||
subscriptions = self.list(None, self.lccn_subscriptions_path,
|
||||
retrieve_all, headers=self.headers,
|
||||
**_params)
|
||||
return subscriptions
|
||||
|
||||
@APIParamsCall
|
||||
def show_lccn_subscription(self, subsc_id):
|
||||
return self.get(self.lccn_subscription_path % subsc_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_lcm_versions(self, major_version):
|
||||
if major_version is None:
|
||||
@@ -991,6 +1049,132 @@ class VnfLCMClient(ClientBase):
|
||||
return self.get(path, headers={'Version': '2.0.0'})
|
||||
|
||||
|
||||
class VnfFMClient(ClientBase):
|
||||
headers = {'Version': '1.3.0'}
|
||||
vnf_fm_alarms_path = '/vnffm/v1/alarms'
|
||||
vnf_fm_alarm_path = '/vnffm/v1/alarms/%s'
|
||||
vnf_fm_subs_path = '/vnffm/v1/subscriptions'
|
||||
vnf_fm_sub_path = '/vnffm/v1/subscriptions/%s'
|
||||
|
||||
def build_action(self, action):
|
||||
return action
|
||||
|
||||
@APIParamsCall
|
||||
def list_vnf_fm_alarms(self, retrieve_all=True, **_params):
|
||||
vnf_fm_alarms = self.list(
|
||||
"vnf_fm_alarms", self.vnf_fm_alarms_path, retrieve_all,
|
||||
headers=self.headers, **_params)
|
||||
return vnf_fm_alarms
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_fm_alarm(self, vnf_fm_alarm_id):
|
||||
return self.get(
|
||||
self.vnf_fm_alarm_path % vnf_fm_alarm_id, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def update_vnf_fm_alarm(self, vnf_fm_alarm_id, body):
|
||||
return self.patch(
|
||||
self.vnf_fm_alarm_path % vnf_fm_alarm_id, body=body,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def create_vnf_fm_sub(self, body):
|
||||
return self.post(
|
||||
self.vnf_fm_subs_path, body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def list_vnf_fm_subs(self, retrieve_all=True, **_params):
|
||||
vnf_fm_subs = self.list("vnf_fm_subs", self.vnf_fm_subs_path,
|
||||
retrieve_all, headers=self.headers, **_params)
|
||||
return vnf_fm_subs
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_fm_sub(self, vnf_fm_sub_id):
|
||||
return self.get(
|
||||
self.vnf_fm_sub_path % vnf_fm_sub_id, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_vnf_fm_sub(self, vnf_fm_sub_id):
|
||||
return self.delete(
|
||||
self.vnf_fm_sub_path % vnf_fm_sub_id, headers=self.headers)
|
||||
|
||||
|
||||
class VnfPMClient(ClientBase):
|
||||
headers = {'Version': '2.1.0'}
|
||||
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
|
||||
|
||||
@APIParamsCall
|
||||
def create_vnf_pm_job(self, body):
|
||||
return self.post(
|
||||
self.vnf_pm_jobs_path, body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def list_vnf_pm_jobs(self, retrieve_all=True, **_params):
|
||||
vnf_pm_jobs = self.list(
|
||||
"vnf_pm_jobs", self.vnf_pm_jobs_path, retrieve_all,
|
||||
headers=self.headers, **_params)
|
||||
return vnf_pm_jobs
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_pm_job(self, vnf_pm_job_id):
|
||||
return self.get(
|
||||
self.vnf_pm_job_path % vnf_pm_job_id, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def update_vnf_pm_job(self, vnf_pm_job_id, body):
|
||||
return self.patch(
|
||||
self.vnf_pm_job_path % vnf_pm_job_id, body=body,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_vnf_pm_job(self, vnf_pm_job_id):
|
||||
return self.delete(
|
||||
self.vnf_pm_job_path % vnf_pm_job_id, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_pm_report(self, vnf_pm_job_id, vnf_pm_report_id):
|
||||
return self.get(
|
||||
self.vnf_pm_reports_path % {
|
||||
'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.
|
||||
|
||||
@@ -1013,6 +1197,8 @@ class Client(object):
|
||||
def __init__(self, **kwargs):
|
||||
api_version = kwargs.pop('api_version', '1')
|
||||
self.vnf_lcm_client = VnfLCMClient(api_version, **kwargs)
|
||||
self.vnf_fm_client = VnfFMClient(**kwargs)
|
||||
self.vnf_pm_client = VnfPMClient(**kwargs)
|
||||
self.vnf_package_client = VnfPackageClient(**kwargs)
|
||||
self.legacy_client = LegacyClient(**kwargs)
|
||||
|
||||
@@ -1267,6 +1453,9 @@ class Client(object):
|
||||
def change_ext_conn_vnf_instance(self, vnf_id, body):
|
||||
return self.vnf_lcm_client.change_ext_conn_vnf_instance(vnf_id, body)
|
||||
|
||||
def change_vnfpkg_vnf_instance(self, vnf_id, body):
|
||||
return self.vnf_lcm_client.change_vnfpkg_vnf_instance(vnf_id, body)
|
||||
|
||||
def delete_vnf_instance(self, vnf_id):
|
||||
return self.vnf_lcm_client.delete_vnf_instance(vnf_id)
|
||||
|
||||
@@ -1276,6 +1465,9 @@ class Client(object):
|
||||
def rollback_vnf_instance(self, occ_id):
|
||||
return self.vnf_lcm_client.rollback_vnf_instance(occ_id)
|
||||
|
||||
def cancel_vnf_instance(self, occ_id, body):
|
||||
return self.vnf_lcm_client.cancel_vnf_instance(occ_id, body)
|
||||
|
||||
def fail_vnf_instance(self, occ_id):
|
||||
return self.vnf_lcm_client.fail_vnf_instance(occ_id)
|
||||
|
||||
@@ -1304,5 +1496,82 @@ class Client(object):
|
||||
def show_vnf_lcm_op_occs(self, occ_id):
|
||||
return self.vnf_lcm_client.show_vnf_lcm_op_occs(occ_id)
|
||||
|
||||
def create_lccn_subscription(self, body):
|
||||
return self.vnf_lcm_client.create_lccn_subscription(body)
|
||||
|
||||
def delete_lccn_subscription(self, subsc_id):
|
||||
return self.vnf_lcm_client.delete_lccn_subscription(subsc_id)
|
||||
|
||||
def list_lccn_subscriptions(self, retrieve_all=True, **_params):
|
||||
return self.vnf_lcm_client.list_lccn_subscriptions(
|
||||
retrieve_all=retrieve_all, **_params)
|
||||
|
||||
def show_lccn_subscription(self, subsc_id):
|
||||
return self.vnf_lcm_client.show_lccn_subscription(subsc_id)
|
||||
|
||||
def show_vnf_lcm_versions(self, major_version):
|
||||
return self.vnf_lcm_client.show_vnf_lcm_versions(major_version)
|
||||
|
||||
# VnfFMClient methods.
|
||||
|
||||
def list_vnf_fm_alarms(self, retrieve_all=True, **_params):
|
||||
return self.vnf_fm_client.list_vnf_fm_alarms(
|
||||
retrieve_all=retrieve_all, **_params)
|
||||
|
||||
def show_vnf_fm_alarm(self, vnf_fm_alarm_id):
|
||||
return self.vnf_fm_client.show_vnf_fm_alarm(vnf_fm_alarm_id)
|
||||
|
||||
def update_vnf_fm_alarm(self, vnf_fm_alarm_id, body):
|
||||
return self.vnf_fm_client.update_vnf_fm_alarm(vnf_fm_alarm_id, body)
|
||||
|
||||
def create_vnf_fm_sub(self, body):
|
||||
return self.vnf_fm_client.create_vnf_fm_sub(body)
|
||||
|
||||
def list_vnf_fm_subs(self, retrieve_all=True, **_params):
|
||||
return self.vnf_fm_client.list_vnf_fm_subs(
|
||||
retrieve_all=retrieve_all, **_params)
|
||||
|
||||
def show_vnf_fm_sub(self, vnf_fm_sub_id):
|
||||
return self.vnf_fm_client.show_vnf_fm_sub(vnf_fm_sub_id)
|
||||
|
||||
def delete_vnf_fm_sub(self, vnf_fm_sub_id):
|
||||
return self.vnf_fm_client.delete_vnf_fm_sub(vnf_fm_sub_id)
|
||||
|
||||
# VnfPMClient methods.
|
||||
|
||||
def create_vnf_pm_job(self, body):
|
||||
return self.vnf_pm_client.create_vnf_pm_job(body)
|
||||
|
||||
def list_vnf_pm_jobs(self, retrieve_all=True, **_params):
|
||||
return self.vnf_pm_client.list_vnf_pm_jobs(
|
||||
retrieve_all=retrieve_all, **_params)
|
||||
|
||||
def show_vnf_pm_job(self, vnf_pm_job_id):
|
||||
return self.vnf_pm_client.show_vnf_pm_job(vnf_pm_job_id)
|
||||
|
||||
def update_vnf_pm_job(self, vnf_pm_job_id, body):
|
||||
return self.vnf_pm_client.update_vnf_pm_job(vnf_pm_job_id, body)
|
||||
|
||||
def delete_vnf_pm_job(self, vnf_pm_job_id):
|
||||
return self.vnf_pm_client.delete_vnf_pm_job(vnf_pm_job_id)
|
||||
|
||||
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)
|
||||
|
||||
13
tox.ini
13
tox.ini
@@ -1,7 +1,6 @@
|
||||
[tox]
|
||||
envlist = py38,py36,pep8,docs
|
||||
envlist = py39,py38,py36,pep8,docs
|
||||
minversion = 3.18.0
|
||||
skipsdist = True
|
||||
ignore_basepython_conflict = True
|
||||
|
||||
[testenv]
|
||||
@@ -12,7 +11,7 @@ setenv = VIRTUAL_ENV={envdir}
|
||||
LC_ALL=C
|
||||
usedevelop = True
|
||||
deps =
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2023.1}
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
commands = stestr run --slowest {posargs}
|
||||
@@ -30,7 +29,7 @@ commands = sphinx-build -W -b html doc/source doc/build/html
|
||||
|
||||
[testenv:releasenotes]
|
||||
deps =
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2023.1}
|
||||
-r{toxinidir}/doc/requirements.txt
|
||||
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
|
||||
|
||||
@@ -52,9 +51,3 @@ exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,tools
|
||||
# F821 undefined name 'unicode'
|
||||
# if isinstance(config, str) or isinstance(config, unicode):
|
||||
builtins = unicode
|
||||
|
||||
[testenv:lower-constraints]
|
||||
deps =
|
||||
-c{toxinidir}/lower-constraints.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
-r{toxinidir}/requirements.txt
|
||||
|
||||
Reference in New Issue
Block a user