Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c786b3ee3 | ||
|
|
29345d5131 | ||
|
|
204af449db | ||
|
|
85535f3ae2 | ||
|
|
8e2e4ebbf9 | ||
|
|
843f158456 | ||
| 549b5476f8 | |||
| 04d3b47d50 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -20,7 +20,6 @@ run_tests.log
|
||||
.idea/
|
||||
.tox/
|
||||
.venv/
|
||||
.stestr/
|
||||
|
||||
# Files created by releasenotes build
|
||||
releasenotes/build
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
host=review.opendev.org
|
||||
port=29418
|
||||
project=openstack/python-tackerclient.git
|
||||
defaultbranch=stable/ocata
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
[DEFAULT]
|
||||
test_path=./tackerclient/tests/unit
|
||||
top_path=./
|
||||
4
.testr.conf
Normal file
4
.testr.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./tackerclient/tests/unit/vm} $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
||||
@@ -1,6 +1,7 @@
|
||||
- project:
|
||||
templates:
|
||||
- openstack-python-jobs
|
||||
- openstack-python35-jobs-nonvoting
|
||||
- check-requirements
|
||||
- openstack-python3-jobs
|
||||
- publish-openstack-docs-pti
|
||||
- release-notes-jobs-python3
|
||||
- publish-openstack-sphinx-docs
|
||||
- release-notes-jobs
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
If you would like to contribute to the development of OpenStack,
|
||||
you must follow the steps in this page:
|
||||
|
||||
https://docs.openstack.org/infra/manual/developers.html
|
||||
|
||||
Once those steps have been completed, changes to OpenStack
|
||||
should be submitted for review via the Gerrit tool, following
|
||||
the workflow documented at:
|
||||
|
||||
https://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
|
||||
Pull requests submitted through GitHub will be ignored.
|
||||
|
||||
Bugs should be filed on Launchpad, not GitHub:
|
||||
|
||||
https://bugs.launchpad.net/python-tackerclient
|
||||
26
HACKING.rst
26
HACKING.rst
@@ -1,26 +1,26 @@
|
||||
Tacker Style Commandments
|
||||
=========================
|
||||
================================
|
||||
|
||||
- Step 1: Read the OpenStack Style Commandments
|
||||
https://docs.openstack.org/hacking/latest
|
||||
http://docs.openstack.org/developer/hacking/
|
||||
- Step 2: Read on
|
||||
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
The testing system is based on a combination of tox and stestr. The canonical
|
||||
approach to running tests is to simply run the command ``tox``. This will
|
||||
create virtual environments, populate them with dependencies and run all of
|
||||
The testing system is based on a combination of tox and testr. The canonical
|
||||
approach to running tests is to simply run the command `tox`. This will
|
||||
create virtual environments, populate them with depenedencies and run all of
|
||||
the tests that OpenStack CI systems run. Behind the scenes, tox is running
|
||||
``stestr run``, but is set up such that you can supply any additional
|
||||
stestr arguments that are needed to tox. For example, you can run:
|
||||
``tox -- --analyze-isolation`` to cause tox to tell stestr to add
|
||||
`testr run --parallel`, but is set up such that you can supply any additional
|
||||
testr arguments that are needed to tox. For example, you can run:
|
||||
`tox -- --analyze-isolation` to cause tox to tell testr to add
|
||||
--analyze-isolation to its argument list.
|
||||
|
||||
It is also possible to run the tests inside of a virtual environment
|
||||
you have created, or it is possible that you have all of the dependencies
|
||||
installed locally already. In this case, you can interact with the stestr
|
||||
command directly. Running ``stestr run`` will run the entire test suite.
|
||||
``stestr run --concurrency=1`` will run tests serially (by default, stestr runs
|
||||
tests in parallel). More information about stestr can be found at:
|
||||
http://stestr.readthedocs.io/
|
||||
installed locally already. In this case, you can interact with the testr
|
||||
command directly. Running `testr run` will run the entire test suite. `testr
|
||||
run --parallel` will run it in parallel (this is the default incantation tox
|
||||
uses.) More information about testr can be found at:
|
||||
http://wiki.openstack.org/testr
|
||||
|
||||
65
README.rst
65
README.rst
@@ -2,68 +2,9 @@
|
||||
Team and repository tags
|
||||
========================
|
||||
|
||||
.. image:: https://governance.openstack.org/tc/badges/python-tackerclient.svg
|
||||
:target: https://governance.openstack.org/tc/reference/tags/index.html
|
||||
.. image:: http://governance.openstack.org/badges/python-tackerclient.svg
|
||||
:target: http://governance.openstack.org/reference/tags/index.html
|
||||
|
||||
.. Change things from this point on
|
||||
|
||||
NFV Orchestration (Tacker) Client
|
||||
=================================
|
||||
|
||||
CLI and Client Library for OpenStack Tacker
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
**Note:** The paths we are using for configuration files in these steps
|
||||
are with reference to Ubuntu Operating System. The paths may vary for
|
||||
other Operating Systems.
|
||||
|
||||
The branch_name which is used in commands, specify the branch_name
|
||||
as stable/<branch> for any stable branch installation. For eg:
|
||||
stable/queens, stable/pike. If unspecified the default will be
|
||||
master branch.
|
||||
|
||||
Using python install
|
||||
--------------------
|
||||
Clone python-tackerclient repository.
|
||||
|
||||
::
|
||||
|
||||
$ cd ~/
|
||||
$ git clone https://github.com/openstack/python-tackerclient -b <branch_name>
|
||||
|
||||
|
||||
Install python-tackerclient.
|
||||
|
||||
::
|
||||
|
||||
$ cd python-tackerclient
|
||||
$ sudo python setup.py install
|
||||
|
||||
|
||||
Using pip
|
||||
---------
|
||||
|
||||
You can also install the latest version by using ``pip`` command:
|
||||
|
||||
::
|
||||
|
||||
$ pip install python-tackerclient
|
||||
|
||||
|
||||
Or, if it is needed to install ``python-tackerclient`` from master branch,
|
||||
type
|
||||
|
||||
::
|
||||
|
||||
$ pip install git+https://github.com/openstack/python-tackerclient.git
|
||||
|
||||
|
||||
More Information
|
||||
================
|
||||
|
||||
* Python-tackerclient documentation: https://docs.openstack.org/python-tackerclient/latest/
|
||||
* Tacker Documentation: https://docs.openstack.org/tacker/latest/
|
||||
* Tacker Wiki: https://wiki.openstack.org/wiki/Tacker
|
||||
* Release Notes: https://docs.openstack.org/releasenotes/python-tackerclient
|
||||
This is the client API library for Tacker.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
# These are needed for docs generation
|
||||
sphinx>=2.0.0,!=2.1.0 # BSD
|
||||
openstackdocstheme>=2.2.1 # Apache-2.0
|
||||
reno>=3.1.0 # Apache-2.0
|
||||
@@ -1,117 +0,0 @@
|
||||
..
|
||||
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.
|
||||
|
||||
=============
|
||||
Command List
|
||||
=============
|
||||
|
||||
The following list covers the extended commands for Tacker services
|
||||
available in **openstack** command.
|
||||
|
||||
These commands can be referenced by doing **openstack help** and the detail
|
||||
of individual command can be referred by **openstack help <command-name>**.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
openstack vnf create Create a VNF.
|
||||
openstack vnf delete Delete given VNF(s).
|
||||
openstack vnf list List VNF(s) that belong to a given tenant.
|
||||
openstack vnf resource list List resources of a VNF like VDU, CP, etc.
|
||||
openstack vnf scale Scale a VNF.
|
||||
openstack vnf show Show information of a given VNF.
|
||||
openstack vnf set Update a given VNF.
|
||||
openstack vnf descriptor create Create a VNFD.
|
||||
openstack vnf descriptor delete Delete given VNFD(s).
|
||||
openstack vnf descriptor list List VNFD(s) that belong to a given tenant.
|
||||
openstack vnf descriptor show Show information of a given VNFD.
|
||||
openstack vnf descriptor template show Show template of a given VNFD.
|
||||
openstack vim list List VIM(s) that belong to a given tenant.
|
||||
openstack vim register Create a VIM.
|
||||
openstack vim show Show information of a given VIM.
|
||||
openstack vim set Update a given VIM.
|
||||
openstack vim delete Delete given VIM(s).
|
||||
openstack ns create Create a NS.
|
||||
openstack ns delete Delete given NS(s).
|
||||
openstack ns list List NS that belong to a given tenant.
|
||||
openstack ns show Show information of a given NS.
|
||||
openstack ns descriptor create Create a NSD.
|
||||
openstack ns descriptor delete Delete a given NSD.
|
||||
openstack ns descriptor list List NSD(s) that belong to a given tenant.
|
||||
openstack ns descriptor show Show information of a given NSD.
|
||||
openstack ns descriptor template show Show template of a given NSD.
|
||||
openstack vnf graph create Create a VNFFG.
|
||||
openstack vnf graph delete Delete a given VNFFG.
|
||||
openstack vnf graph list List VNFFG(s) that belong to a given tenant.
|
||||
openstack vnf graph show Show information of a given VNFFG.
|
||||
openstack vnf graph set Update a given VNFFG.
|
||||
openstack vnf graph descriptor create Create a VNFFGD.
|
||||
openstack vnf graph descriptor delete Delete a given VNFFGD.
|
||||
openstack vnf graph descriptor list List VNFFGD(s) that belong to a given tenant.
|
||||
openstack vnf graph descriptor show Show information of a given VNFFGD.
|
||||
openstack vnf graph descriptor template show Show template of a given VNFFGD.
|
||||
openstack vnf chain list List SFC(s) that belong to a given tenant.
|
||||
openstack vnf chain show Show information of a given SFC.
|
||||
openstack vnf classifier list List FC(s) that belong to a given tenant.
|
||||
openstack vnf classifier show Show information of a given FC.
|
||||
openstack vnf network forwarding path list List NFP(s) that belong to a given tenant.
|
||||
openstack vnf network forwarding path show Show information of a given NFP.
|
||||
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.
|
||||
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,50 +0,0 @@
|
||||
..
|
||||
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::
|
||||
|
||||
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
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,19 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,24 +0,0 @@
|
||||
..
|
||||
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,22 +0,0 @@
|
||||
..
|
||||
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
|
||||
====================
|
||||
|
||||
VNF Package commands are CLI interface of VNF Package Management Interface in
|
||||
`ETSI NFV-SOL 005 <https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/005/02.06.01_60/gs_NFV-SOL005v020601p.pdf>`_.
|
||||
|
||||
.. autoprogram-cliff:: openstack.tackerclient.v1
|
||||
:command: vnf package *
|
||||
@@ -1,28 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,34 +0,0 @@
|
||||
..
|
||||
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
|
||||
@@ -1,28 +0,0 @@
|
||||
..
|
||||
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 *
|
||||
@@ -1,38 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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.
|
||||
|
||||
# python-tackerclient documentation build configuration file
|
||||
project = 'python-tackerclient'
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
# sys.path.append(os.path.abspath('.'))
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
|
||||
# -- General configuration ----------------------------------------------------
|
||||
# -- General configuration ---------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'reno.sphinxext',
|
||||
'openstackdocstheme',
|
||||
'cliff.sphinxext',
|
||||
]
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -44,7 +19,7 @@ source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
copyright = 'OpenStack Contributors'
|
||||
copyright = u'OpenStack Foundation'
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
@@ -54,33 +29,27 @@ add_function_parentheses = True
|
||||
add_module_names = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'native'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
# -- Options for HTML output ---------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
html_theme = 'openstackdocs'
|
||||
html_theme = 'nature'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'tackerclientdoc'
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
|
||||
# -- Options for manual page output -------------------------------------------
|
||||
|
||||
man_pages = [
|
||||
('cli/index', 'tacker', 'Client for Tacker API',
|
||||
['OpenStack Contributors'], 1),
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index',
|
||||
'%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation', 'manual'),
|
||||
]
|
||||
|
||||
# -- Options for openstackdocstheme -------------------------------------------
|
||||
|
||||
openstackdocs_repo_name = 'openstack/python-tackerclient'
|
||||
openstackdocs_bug_project = 'python-tackerclient'
|
||||
openstackdocs_bug_tag = 'doc'
|
||||
|
||||
# -- Options for cliff.sphinxext plugin ---------------------------------------
|
||||
|
||||
autoprogram_cliff_application = 'openstack'
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'http://docs.python.org/': None}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
..
|
||||
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.
|
||||
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
|
||||
.. include:: ../../../CONTRIBUTING.rst
|
||||
@@ -1,39 +0,0 @@
|
||||
..
|
||||
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.
|
||||
|
||||
===================================
|
||||
Developing with Python-TackerClient
|
||||
===================================
|
||||
|
||||
Project Info
|
||||
============
|
||||
|
||||
* **Free software:** under the `Apache license <http://www.apache.org/licenses/LICENSE-2.0>`_
|
||||
* **Tacker Service:** https://opendev.org/openstack/tacker
|
||||
* **Tacker Client Library:** https://opendev.org/openstack/python-tackerclient
|
||||
* **Tacker Service Bugs:** https://bugs.launchpad.net/tacker
|
||||
* **Client Bugs:** https://bugs.launchpad.net/python-tackerclient
|
||||
* **Blueprints:** https://blueprints.launchpad.net/tacker
|
||||
|
||||
Meetings
|
||||
========
|
||||
For details please refer to the `OpenStack IRC meetings`_ page.
|
||||
|
||||
.. _`OpenStack IRC meetings`: http://eavesdrop.openstack.org/#Tacker_(NFV_Orchestrator_and_VNF_Manager)_Team_Meeting
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
For details please refer to the `Developing with OpenStackClient`_ page.
|
||||
|
||||
.. _`Developing with OpenStackClient`: https://docs.openstack.org/python-openstackclient/latest/contributor/developing.html
|
||||
@@ -1,28 +0,0 @@
|
||||
..
|
||||
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.
|
||||
|
||||
=================
|
||||
Contributor Guide
|
||||
=================
|
||||
|
||||
In the Contributor Guide, you will find information on tackerclient's
|
||||
lower level programming details or APIs as well as the transition to
|
||||
OpenStack client.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
contributing.rst
|
||||
developing.rst
|
||||
|
||||
|
||||
@@ -1,48 +1,25 @@
|
||||
..
|
||||
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
|
||||
Python bindings to the OpenStack Tacker API
|
||||
============================================
|
||||
|
||||
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.
|
||||
|
||||
=================================
|
||||
Python-TackerClient Documentation
|
||||
=================================
|
||||
|
||||
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>`.
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
install/index
|
||||
cli/index
|
||||
contributor/index
|
||||
reference/index
|
||||
In order to use the python tacker client directly, you must first obtain an auth token and identify which endpoint you wish to speak to. Once you have done so, you can use the API.
|
||||
|
||||
|
||||
Release Notes
|
||||
-------------
|
||||
Command-line Tool
|
||||
=================
|
||||
In order to use the CLI, you must provide your OpenStack username, password, tenant, and auth endpoint. Use the corresponding configuration options (``--os-username``, ``--os-password``, ``--os-tenant-name``, and ``--os-auth-url``) or set them in environment variables::
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
export OS_USERNAME=user
|
||||
export OS_PASSWORD=pass
|
||||
export OS_TENANT_NAME=tenant
|
||||
export OS_AUTH_URL=http://auth.example.com:5000/v2.0
|
||||
|
||||
Release Notes <https://docs.openstack.org/releasenotes/python-tackerclient/>
|
||||
The command line tool will attempt to reauthenticate using your provided credentials for every request. You can override this behavior by manually supplying an auth token using ``--os-url`` and ``--os-auth-token``. You can alternatively set these environment variables::
|
||||
|
||||
export OS_URL=http://tacker.example.org:9890/
|
||||
export OS_TOKEN=3bcc3d3a03f44e3d8377f9247b0ad155
|
||||
|
||||
Indices and Tables
|
||||
------------------
|
||||
If tacker server does not require authentication, besides these two arguments or environment variables (We can use any value as token.), we need manually supply ``--os-auth-strategy`` or set the environment variable::
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
export OS_AUTH_STRATEGY=noauth
|
||||
|
||||
Once you've configured your authentication parameters, you can run ``tacker -h`` to see a complete listing of available commands.
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
..
|
||||
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.
|
||||
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
This document describes how to install python-tackerclient.
|
||||
|
||||
.. note::
|
||||
|
||||
This installation guide contents are specific to Ubuntu distro.
|
||||
|
||||
Using python install
|
||||
====================
|
||||
|
||||
#. Clone python-tackerclient repository.
|
||||
|
||||
You can use -b for specific release, optionally.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd ~/
|
||||
$ git clone https://opendev.org/openstack/python-tackerclient -b <branch_name>
|
||||
|
||||
.. note::
|
||||
|
||||
Make sure to replace the ``<branch_name>`` in command example with
|
||||
specific branch name, such as ``stable/victoria``.
|
||||
|
||||
#. Install python-tackerclient.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd python-tackerclient
|
||||
$ sudo python3 setup.py install
|
||||
|
||||
Using pip
|
||||
=========
|
||||
|
||||
You can also install the latest version by using ``pip`` command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip3 install python-tackerclient
|
||||
|
||||
Or, if it is needed to install ``python-tackerclient`` from master branch,
|
||||
type
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip3 install git+https://opendev.org/openstack/python-tackerclient
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
..
|
||||
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.
|
||||
|
||||
=========
|
||||
Reference
|
||||
=========
|
||||
|
||||
- `Tacker API reference <https://docs.openstack.org/api-ref/nfv-orchestration/>`_
|
||||
- `Tacker CLI reference <https://docs.openstack.org/tacker/latest/cli/>`_
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Support to create directly VNFFG and NS from its descriptor template
|
||||
without creating VNFFGD and NSD.
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add 'vnf_ids' and 'vnffg_ids' fields in outputs from network
|
||||
service list command. Users can know which VNFs or VNFFGs,
|
||||
belongs to specific NS.
|
||||
Add 'ns_id' field to VNFFG list command, that shows the
|
||||
network service the current VNFFG belongs to.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
The VNFFGD CLI cannot show the VNFFGD template.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Add documentation for python-tackerclient.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fix the VNFFG update osc command misusing create_vnffg function.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fix local test fail with pypy.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Enable CLI to support clustering service in Tacker Server.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
features:
|
||||
-
|
||||
As user gives input of project and user name in vim_config.yaml,
|
||||
delete the user and project id from the vim specific commands
|
||||
output.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
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).
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
deprecations:
|
||||
- |
|
||||
tacker CLI is deprecated, will be deleted after Rocky release.
|
||||
Use `openstack CLI`_ instead.
|
||||
|
||||
.. _openstack CLI: https://docs.openstack.org/python-tackerclient/latest/cli/index.html
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
Python 2.7 support has been dropped. Last release of python-tackerclient
|
||||
to support python 2.7 is OpenStack Train. The minimum version of Python now
|
||||
supported by python-tackerclient is Python 3.6.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add python-vnfd, vnf, nsd, ns, vnffgd, vnffg, event commands support.
|
||||
@@ -1,3 +0,0 @@
|
||||
---
|
||||
features:
|
||||
- VIM can be updated without config-file argument in tacker vim-update command.
|
||||
@@ -1,6 +0,0 @@
|
||||
===========================
|
||||
2023.1 Series Release Notes
|
||||
===========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/2023.1
|
||||
@@ -36,8 +36,8 @@
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'reno.sphinxext',
|
||||
'openstackdocstheme',
|
||||
'oslosphinx',
|
||||
'reno.sphinxext'
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
@@ -53,12 +53,17 @@ source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'Tacker Client Release Notes'
|
||||
copyright = '2016, Tacker Developers'
|
||||
project = u'Tacker Client Release Notes'
|
||||
copyright = u'2016, Tacker Developers'
|
||||
|
||||
# Release notes are version independent.
|
||||
release = ''
|
||||
version = ''
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
import pbr.version
|
||||
tacker_client_version = pbr.version.VersionInfo('python-tackerclient')
|
||||
release = tacker_client_version.version_string_with_vcs()
|
||||
version = tacker_client_version.canonical_version_string()
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@@ -90,7 +95,7 @@ exclude_patterns = []
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'native'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
# modindex_common_prefix = []
|
||||
@@ -100,7 +105,7 @@ pygments_style = 'native'
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'openstackdocs'
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
@@ -131,6 +136,10 @@ html_theme = 'openstackdocs'
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
# html_use_smartypants = True
|
||||
@@ -190,8 +199,8 @@ latex_elements = {
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'TackerClientReleaseNotes.tex',
|
||||
'Tacker Client Release Notes Documentation',
|
||||
'Tacker Developers', 'manual'),
|
||||
u'Tacker Client Release Notes Documentation',
|
||||
u'Tacker Developers', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
@@ -221,8 +230,8 @@ latex_documents = [
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'tackerreleasenotes',
|
||||
'Tacker Client Release Notes Documentation',
|
||||
['Tacker Developers'], 1)
|
||||
u'Tacker Client Release Notes Documentation',
|
||||
[u'Tacker Developers'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
@@ -236,8 +245,8 @@ man_pages = [
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'TackerClientReleaseNotes',
|
||||
'Tacker Client Release Notes Documentation',
|
||||
'Tacker Developers', 'TackerClientReleaseNotes',
|
||||
u'Tacker Client Release Notes Documentation',
|
||||
u'Tacker Developers', 'TackerClientReleaseNotes',
|
||||
'Tacker Client Project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
@@ -253,9 +262,3 @@ texinfo_documents = [
|
||||
|
||||
# -- Options for Internationalization output ------------------------------
|
||||
locale_dirs = ['locale/']
|
||||
|
||||
# -- Options for openstackdocstheme -------------------------------------------
|
||||
openstackdocs_repo_name = 'openstack/python-tackerclient'
|
||||
openstackdocs_bug_project = 'python-tackerclient'
|
||||
openstackdocs_bug_tag = ''
|
||||
openstackdocs_auto_name = False
|
||||
|
||||
@@ -7,17 +7,4 @@ Contents:
|
||||
:maxdepth: 2
|
||||
|
||||
unreleased
|
||||
2023.1
|
||||
zed
|
||||
yoga
|
||||
xena
|
||||
wallaby
|
||||
victoria
|
||||
ussuri
|
||||
train
|
||||
stein
|
||||
rocky
|
||||
queens
|
||||
pike
|
||||
ocata
|
||||
newton
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
===================================
|
||||
Ocata Series Release Notes
|
||||
===================================
|
||||
|
||||
.. release-notes::
|
||||
:branch: origin/stable/ocata
|
||||
@@ -1,6 +0,0 @@
|
||||
===================================
|
||||
Pike Series Release Notes
|
||||
===================================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/pike
|
||||
@@ -1,6 +0,0 @@
|
||||
===================================
|
||||
Queens Series Release Notes
|
||||
===================================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/queens
|
||||
@@ -1,6 +0,0 @@
|
||||
===================================
|
||||
Rocky Series Release Notes
|
||||
===================================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/rocky
|
||||
@@ -1,6 +0,0 @@
|
||||
===================================
|
||||
Stein Series Release Notes
|
||||
===================================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/stein
|
||||
@@ -1,6 +0,0 @@
|
||||
==========================
|
||||
Train Series Release Notes
|
||||
==========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/train
|
||||
@@ -1,6 +0,0 @@
|
||||
===========================
|
||||
Ussuri Series Release Notes
|
||||
===========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/ussuri
|
||||
@@ -1,6 +0,0 @@
|
||||
=============================
|
||||
Victoria Series Release Notes
|
||||
=============================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/victoria
|
||||
@@ -1,6 +0,0 @@
|
||||
============================
|
||||
Wallaby Series Release Notes
|
||||
============================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/wallaby
|
||||
@@ -1,6 +0,0 @@
|
||||
=========================
|
||||
Xena Series Release Notes
|
||||
=========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/xena
|
||||
@@ -1,6 +0,0 @@
|
||||
=========================
|
||||
Yoga Series Release Notes
|
||||
=========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/yoga
|
||||
@@ -1,6 +0,0 @@
|
||||
========================
|
||||
Zed Series Release Notes
|
||||
========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/zed
|
||||
@@ -1,17 +1,19 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
cliff!=2.9.0,>=2.8.0 # Apache-2.0
|
||||
pbr>=1.8 # Apache-2.0
|
||||
cliff>=2.3.0 # Apache-2.0
|
||||
iso8601>=0.1.11 # MIT
|
||||
netaddr>=0.7.18 # BSD
|
||||
requests>=2.14.2 # Apache-2.0
|
||||
netaddr!=0.7.16,>=0.7.13 # BSD
|
||||
requests!=2.12.2,>=2.10.0 # Apache-2.0
|
||||
python-keystoneclient>=3.8.0 # Apache-2.0
|
||||
simplejson>=3.5.1 # MIT
|
||||
stevedore>=1.20.0 # Apache-2.0
|
||||
Babel!=2.4.0,>=2.3.4 # BSD
|
||||
oslo.i18n>=3.15.3 # Apache-2.0
|
||||
osc-lib>=1.8.0 # Apache-2.0
|
||||
oslo.log>=3.36.0 # Apache-2.0
|
||||
oslo.utils>=3.40.0 # Apache-2.0
|
||||
oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
|
||||
simplejson>=2.2.0 # MIT
|
||||
six>=1.9.0 # MIT
|
||||
stevedore>=1.17.1 # Apache-2.0
|
||||
Babel>=2.3.4 # BSD
|
||||
|
||||
oslo.i18n>=2.1.0 # Apache-2.0
|
||||
oslo.log>=3.11.0 # Apache-2.0
|
||||
oslo.utils>=3.18.0 # Apache-2.0
|
||||
oslosphinx>=4.7.0 # Apache-2.0
|
||||
oslo.serialization>=1.10.0 # Apache-2.0
|
||||
|
||||
153
setup.cfg
153
setup.cfg
@@ -1,12 +1,12 @@
|
||||
[metadata]
|
||||
name = python-tackerclient
|
||||
description = CLI and Client Library for OpenStack Tacker
|
||||
long_description = file: README.rst
|
||||
summary = CLI and Client Library for OpenStack Tacker
|
||||
description-file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author_email = openstack-discuss@lists.openstack.org
|
||||
url = https://docs.openstack.org/python-tackerclient/
|
||||
python_requires = >=3.6
|
||||
classifiers =
|
||||
author-email = openstack-dev@lists.openstack.org
|
||||
home-page = http://docs.openstack.org/developer/tacker/
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Developers
|
||||
Intended Audience :: Information Technology
|
||||
@@ -14,137 +14,30 @@ classifiers =
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
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
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
|
||||
[files]
|
||||
packages =
|
||||
tackerclient
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
pbr.hooks.setup_hook
|
||||
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
tacker = tackerclient.shell:main
|
||||
|
||||
openstack.cli.extension =
|
||||
tackerclient = tackerclient.osc.plugin
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
build-dir = doc/build
|
||||
source-dir = doc/source
|
||||
|
||||
openstack.tackerclient.v1 =
|
||||
vim_register = tackerclient.osc.v1.nfvo.vim:CreateVIM
|
||||
vim_list = tackerclient.osc.v1.nfvo.vim:ListVIM
|
||||
vim_set = tackerclient.osc.v1.nfvo.vim:UpdateVIM
|
||||
vim_delete = tackerclient.osc.v1.nfvo.vim:DeleteVIM
|
||||
vim_show = tackerclient.osc.v1.nfvo.vim:ShowVIM
|
||||
vnf_descriptor_create = tackerclient.osc.v1.vnfm.vnfd:CreateVNFD
|
||||
vnf_descriptor_delete = tackerclient.osc.v1.vnfm.vnfd:DeleteVNFD
|
||||
vnf_descriptor_list = tackerclient.osc.v1.vnfm.vnfd:ListVNFD
|
||||
vnf_descriptor_show = tackerclient.osc.v1.vnfm.vnfd:ShowVNFD
|
||||
vnf_descriptor_template_show = tackerclient.osc.v1.vnfm.vnfd:ShowTemplateVNFD
|
||||
vnf_create = tackerclient.osc.v1.vnfm.vnf:CreateVNF
|
||||
vnf_delete = tackerclient.osc.v1.vnfm.vnf:DeleteVNF
|
||||
vnf_list = tackerclient.osc.v1.vnfm.vnf:ListVNF
|
||||
vnf_show = tackerclient.osc.v1.vnfm.vnf:ShowVNF
|
||||
vnf_resource_list = tackerclient.osc.v1.vnfm.vnf:ListVNFResources
|
||||
vnf_set = tackerclient.osc.v1.vnfm.vnf:UpdateVNF
|
||||
vnf_scale = tackerclient.osc.v1.vnfm.vnf:ScaleVNF
|
||||
vnf_graph_descriptor_create = tackerclient.osc.v1.nfvo.vnffgd:CreateVNFFGD
|
||||
vnf_graph_descriptor_delete = tackerclient.osc.v1.nfvo.vnffgd:DeleteVNFFGD
|
||||
vnf_graph_descriptor_list = tackerclient.osc.v1.nfvo.vnffgd:ListVNFFGD
|
||||
vnf_graph_descriptor_show = tackerclient.osc.v1.nfvo.vnffgd:ShowVNFFGD
|
||||
vnf_graph_descriptor_template_show = tackerclient.osc.v1.nfvo.vnffgd:ShowTemplateVNFFGD
|
||||
ns_descriptor_create = tackerclient.osc.v1.nfvo.nsd:CreateNSD
|
||||
ns_descriptor_delete = tackerclient.osc.v1.nfvo.nsd:DeleteNSD
|
||||
ns_descriptor_list = tackerclient.osc.v1.nfvo.nsd:ListNSD
|
||||
ns_descriptor_show = tackerclient.osc.v1.nfvo.nsd:ShowNSD
|
||||
ns_descriptor_template_show = tackerclient.osc.v1.nfvo.nsd:ShowTemplateNSD
|
||||
nfv_event_show = tackerclient.osc.v1.events.events:ShowEvent
|
||||
nfv_event_list = tackerclient.osc.v1.events.events:ListEvent
|
||||
ns_create = tackerclient.osc.v1.nfvo.ns:CreateNS
|
||||
ns_delete = tackerclient.osc.v1.nfvo.ns:DeleteNS
|
||||
ns_list = tackerclient.osc.v1.nfvo.ns:ListNS
|
||||
ns_show = tackerclient.osc.v1.nfvo.ns:ShowNS
|
||||
vnf_graph_create = tackerclient.osc.v1.nfvo.vnffg:CreateVNFFG
|
||||
vnf_graph_delete = tackerclient.osc.v1.nfvo.vnffg:DeleteVNFFG
|
||||
vnf_graph_set = tackerclient.osc.v1.nfvo.vnffg:UpdateVNFFG
|
||||
vnf_graph_list = tackerclient.osc.v1.nfvo.vnffg:ListVNFFG
|
||||
vnf_graph_show = tackerclient.osc.v1.nfvo.vnffg:ShowVNFFG
|
||||
vnf_network_forwarding_path_list = tackerclient.osc.v1.nfvo.vnffg:ListNFP
|
||||
vnf_network_forwarding_path_show = tackerclient.osc.v1.nfvo.vnffg:ShowNFP
|
||||
vnf_classifier_list = tackerclient.osc.v1.nfvo.vnffg:ListFC
|
||||
vnf_classifier_show = tackerclient.osc.v1.nfvo.vnffg:ShowFC
|
||||
vnf_chain_list = tackerclient.osc.v1.nfvo.vnffg:ListSFC
|
||||
vnf_chain_show = tackerclient.osc.v1.nfvo.vnffg:ShowSFC
|
||||
vnf_package_create = tackerclient.osc.v1.vnfpkgm.vnf_package:CreateVnfPackage
|
||||
vnf_package_list = tackerclient.osc.v1.vnfpkgm.vnf_package:ListVnfPackage
|
||||
vnf_package_show = tackerclient.osc.v1.vnfpkgm.vnf_package:ShowVnfPackage
|
||||
vnf_package_upload = tackerclient.osc.v1.vnfpkgm.vnf_package:UploadVnfPackage
|
||||
vnf_package_delete = tackerclient.osc.v1.vnfpkgm.vnf_package:DeleteVnfPackage
|
||||
vnf_package_update = tackerclient.osc.v1.vnfpkgm.vnf_package:UpdateVnfPackage
|
||||
vnf_package_download = tackerclient.osc.v1.vnfpkgm.vnf_package:DownloadVnfPackage
|
||||
vnf_package_artifact_download = tackerclient.osc.v1.vnfpkgm.vnf_package:DownloadVnfPackageArtifact
|
||||
vnflcm_create = tackerclient.osc.v1.vnflcm.vnflcm:CreateVnfLcm
|
||||
vnflcm_show = tackerclient.osc.v1.vnflcm.vnflcm:ShowVnfLcm
|
||||
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_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_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
|
||||
vnflcm_show = tackerclient.osc.v1.vnflcm.vnflcm:ShowVnfLcm
|
||||
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
|
||||
[build_releasenotes]
|
||||
all_files = 1
|
||||
build-dir = releasenotes/build
|
||||
source-dir = releasenotes/source
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
||||
|
||||
11
setup.py
11
setup.py
@@ -13,8 +13,17 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||
import setuptools
|
||||
|
||||
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
||||
# setuptools if some other modules registered functions in `atexit`.
|
||||
# solution from: http://bugs.python.org/issue15881#msg170215
|
||||
try:
|
||||
import multiprocessing # noqa
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr>=2.0.0'],
|
||||
setup_requires=['pbr>=1.8'],
|
||||
pbr=True)
|
||||
|
||||
@@ -144,8 +144,6 @@ class HTTPClient(object):
|
||||
verify=self.verify_cert,
|
||||
timeout=self.timeout,
|
||||
**kwargs)
|
||||
if resp.headers.get('content-type') == 'application/zip':
|
||||
return resp, resp.content
|
||||
|
||||
return resp, resp.text
|
||||
|
||||
@@ -165,7 +163,6 @@ class HTTPClient(object):
|
||||
# re-authenticate and try again. If it still fails, bail.
|
||||
try:
|
||||
kwargs.setdefault('headers', {})
|
||||
kwargs.setdefault('content_type', kwargs.get('content_type'))
|
||||
if self.auth_token is None:
|
||||
self.auth_token = ""
|
||||
kwargs['headers']['X-Auth-Token'] = self.auth_token
|
||||
@@ -293,10 +290,6 @@ class SessionClient(adapter.Adapter):
|
||||
headers.setdefault('Content-Type', content_type)
|
||||
|
||||
resp = super(SessionClient, self).request(*args, **kwargs)
|
||||
|
||||
if resp.headers.get('content-type') == 'application/zip':
|
||||
return resp, resp.content
|
||||
|
||||
return resp, resp.text
|
||||
|
||||
def _check_uri_length(self, url):
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
"""oslo.i18n integration module.
|
||||
|
||||
See https://docs.openstack.org/oslo.i18n/latest/user/index.html.
|
||||
See http://docs.openstack.org/developer/oslo.i18n/usage.html .
|
||||
|
||||
"""
|
||||
|
||||
@@ -35,6 +35,16 @@ _C = _translators.contextual_form
|
||||
# requires oslo.i18n >=2.1.0
|
||||
_P = _translators.plural_form
|
||||
|
||||
# Translators for log levels.
|
||||
#
|
||||
# The abbreviated names are meant to reflect the usual use of a short
|
||||
# name like '_'. The "L" is for "log" and the other letter comes from
|
||||
# the level.
|
||||
_LI = _translators.log_info
|
||||
_LW = _translators.log_warning
|
||||
_LE = _translators.log_error
|
||||
_LC = _translators.log_critical
|
||||
|
||||
|
||||
def get_available_languages():
|
||||
return oslo_i18n.get_available_languages(DOMAIN)
|
||||
return oslo_i18n.get_available_languages(DOMAIN)
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from sys import stderr
|
||||
|
||||
from cliff import command
|
||||
|
||||
|
||||
@@ -25,8 +23,6 @@ class OpenStackCommand(command.Command):
|
||||
api = None
|
||||
|
||||
def run(self, parsed_args):
|
||||
stderr.write("Deprecated: tacker command line is deprecated, "
|
||||
"will be deleted after Rocky is released.\n")
|
||||
if not self.api:
|
||||
return
|
||||
else:
|
||||
|
||||
@@ -28,6 +28,7 @@ ATOM_LINK_NOTATION = "{%s}link" % ATOM_NAMESPACE
|
||||
|
||||
TYPE_BOOL = "bool"
|
||||
TYPE_INT = "int"
|
||||
TYPE_LONG = "long"
|
||||
TYPE_FLOAT = "float"
|
||||
TYPE_LIST = "list"
|
||||
TYPE_DICT = "dict"
|
||||
|
||||
@@ -203,18 +203,6 @@ class InvalidContentType(TackerClientException):
|
||||
message = _("Invalid content type %(content_type)s.")
|
||||
|
||||
|
||||
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):
|
||||
|
||||
@@ -18,6 +18,7 @@ from xml.etree import ElementTree as etree
|
||||
from xml.parsers import expat
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
|
||||
from tackerclient.common import constants
|
||||
from tackerclient.common import exceptions as exception
|
||||
@@ -25,6 +26,9 @@ from tackerclient.i18n import _
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
if six.PY3:
|
||||
long = int
|
||||
|
||||
|
||||
class ActionDispatcher(object):
|
||||
"""Maps method name to local methods through action name."""
|
||||
@@ -54,7 +58,7 @@ class JSONDictSerializer(DictSerializer):
|
||||
|
||||
def default(self, data):
|
||||
def sanitizer(obj):
|
||||
return str(obj)
|
||||
return six.text_type(obj)
|
||||
return jsonutils.dumps(data, default=sanitizer)
|
||||
|
||||
|
||||
@@ -89,7 +93,7 @@ class XMLDictSerializer(DictSerializer):
|
||||
root_key = constants.VIRTUAL_ROOT_KEY
|
||||
root_value = None
|
||||
else:
|
||||
link_keys = [k for k in data.keys() or []
|
||||
link_keys = [k for k in six.iterkeys(data) or []
|
||||
if k.endswith('_links')]
|
||||
if link_keys:
|
||||
links = data.pop(link_keys[0], None)
|
||||
@@ -179,6 +183,10 @@ class XMLDictSerializer(DictSerializer):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_INT)
|
||||
elif isinstance(data, long):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_LONG)
|
||||
elif isinstance(data, float):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
@@ -186,7 +194,7 @@ class XMLDictSerializer(DictSerializer):
|
||||
LOG.debug("Data %(data)s type is %(type)s",
|
||||
{'data': data,
|
||||
'type': type(data)})
|
||||
result.text = str(data)
|
||||
result.text = six.text_type(data)
|
||||
return result
|
||||
|
||||
def _create_link_nodes(self, xml_doc, links):
|
||||
@@ -315,6 +323,8 @@ class XMLDeserializer(TextDeserializer):
|
||||
lambda x: x.lower() == 'true',
|
||||
constants.TYPE_INT:
|
||||
lambda x: int(x),
|
||||
constants.TYPE_LONG:
|
||||
lambda x: long(x),
|
||||
constants.TYPE_FLOAT:
|
||||
lambda x: float(x)}
|
||||
if attrType and attrType in converters:
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from oslo_log import versionutils
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import importutils
|
||||
import six
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.i18n import _
|
||||
@@ -57,7 +57,7 @@ def get_client_class(api_name, version, version_map):
|
||||
"one of: %(map_keys)s")
|
||||
msg = msg % {'api_name': api_name, 'version': version,
|
||||
'map_keys': ', '.join(version_map.keys())}
|
||||
raise exceptions.UnsupportedVersion(message=msg)
|
||||
raise exceptions.UnsupportedVersion(msg)
|
||||
|
||||
return importutils.import_class(client_path)
|
||||
|
||||
@@ -141,7 +141,7 @@ def http_log_resp(_logger, resp, body):
|
||||
|
||||
|
||||
def _safe_encode_without_obj(data):
|
||||
if isinstance(data, str):
|
||||
if isinstance(data, six.string_types):
|
||||
return encodeutils.safe_encode(data)
|
||||
return data
|
||||
|
||||
@@ -184,15 +184,3 @@ 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)
|
||||
|
||||
@@ -54,7 +54,7 @@ def validate_int_range(parsed_args, attr_name, min_value=None, max_value=None):
|
||||
{'attr_name': attr_name.replace('_', '-'),
|
||||
'val': val})
|
||||
|
||||
raise exceptions.CommandError(message=msg)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
def validate_ip_subnet(parsed_args, attr_name):
|
||||
@@ -65,5 +65,5 @@ def validate_ip_subnet(parsed_args, attr_name):
|
||||
netaddr.IPNetwork(val)
|
||||
except (netaddr.AddrFormatError, ValueError):
|
||||
raise exceptions.CommandError(
|
||||
message=(_('%(attr_name)s "%(val)s" is not a valid CIDR.') %
|
||||
{'attr_name': attr_name.replace('_', '-'), 'val': val}))
|
||||
(_('%(attr_name)s "%(val)s" is not a valid CIDR.') %
|
||||
{'attr_name': attr_name.replace('_', '-'), 'val': val}))
|
||||
|
||||
@@ -16,3 +16,13 @@ _translators = i18n.TranslatorFactory(domain='tackerclient')
|
||||
|
||||
# The primary translation function using the well-known name "_"
|
||||
_ = _translators.primary
|
||||
|
||||
# Translators for log levels.
|
||||
#
|
||||
# The abbreviated names are meant to reflect the usual use of a short
|
||||
# name like '_'. The "L" is for "log" and the other letter comes from
|
||||
# the level.
|
||||
_LI = _translators.log_info
|
||||
_LW = _translators.log_warning
|
||||
_LE = _translators.log_error
|
||||
_LC = _translators.log_critical
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# Copyright (C) 2021 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 osc_lib.command import command
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.i18n import _
|
||||
|
||||
|
||||
SUPPORTED_VERSIONS = [1, 2]
|
||||
|
||||
|
||||
class VnfLcmVersions(command.ShowOne):
|
||||
_description = _("Show VnfLcm Api versions")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(VnfLcmVersions, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--major-version',
|
||||
metavar="<major-version>",
|
||||
type=int,
|
||||
help=_('Show only specify major version.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
v = None
|
||||
if parsed_args.major_version:
|
||||
if parsed_args.major_version not in SUPPORTED_VERSIONS:
|
||||
msg = _("Major version %d is not supported")
|
||||
reason = msg % parsed_args.major_version
|
||||
raise exceptions.InvalidInput(reason=reason)
|
||||
v = "v{}".format(parsed_args.major_version)
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
data = client.show_vnf_lcm_versions(v)
|
||||
|
||||
return (tuple(data.keys()), tuple(data.values()))
|
||||
@@ -1,64 +0,0 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""OpenStackClient plugin for nfv-orchestration service."""
|
||||
|
||||
import logging
|
||||
|
||||
from osc_lib import utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# Required by the OSC plugin interface
|
||||
DEFAULT_TACKER_API_VERSION = '1'
|
||||
API_NAME = 'tackerclient'
|
||||
API_VERSION_OPTION = 'os_tacker_api_version'
|
||||
API_VERSIONS = {
|
||||
'1': 'tackerclient.v1_0.client.Client',
|
||||
'2': 'tackerclient.v1_0.client.Client',
|
||||
}
|
||||
|
||||
|
||||
def make_client(instance):
|
||||
"""Returns a client to the ClientManager."""
|
||||
|
||||
api_version = instance._api_version[API_NAME]
|
||||
tacker_client = utils.get_client_class(
|
||||
API_NAME,
|
||||
api_version,
|
||||
API_VERSIONS)
|
||||
LOG.debug('Instantiating tacker client: %s', tacker_client)
|
||||
|
||||
kwargs = {'service_type': 'nfv-orchestration',
|
||||
'region_name': instance._region_name,
|
||||
'endpoint_type': instance._interface,
|
||||
'interface': instance._interface,
|
||||
'session': instance.session,
|
||||
'api_version': api_version
|
||||
}
|
||||
|
||||
client = tacker_client(**kwargs)
|
||||
|
||||
return client
|
||||
|
||||
|
||||
def build_option_parser(parser):
|
||||
"""Hook to add global options."""
|
||||
parser.add_argument(
|
||||
'--os-tacker-api-version',
|
||||
metavar='<tacker-api-version>',
|
||||
default=utils.env(
|
||||
'OS_TACKER_API_VERSION',
|
||||
default=DEFAULT_TACKER_API_VERSION))
|
||||
return parser
|
||||
@@ -1,129 +0,0 @@
|
||||
# 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 sys
|
||||
|
||||
from oslo_utils import encodeutils
|
||||
|
||||
|
||||
def get_osc_show_columns_for_sdk_resource(
|
||||
sdk_resource,
|
||||
osc_column_map,
|
||||
invisible_columns=None
|
||||
):
|
||||
"""Get and filter the display and attribute columns for an SDK resource.
|
||||
|
||||
Common utility function for preparing the output of an OSC show command.
|
||||
Some of the columns may need to get renamed, others made invisible.
|
||||
|
||||
:param sdk_resource: An SDK resource
|
||||
:param osc_column_map: A hash of mappings for display column names
|
||||
:param invisible_columns: A list of invisible column names
|
||||
|
||||
:returns: Two tuples containing the names of the display and attribute
|
||||
columns
|
||||
"""
|
||||
|
||||
if getattr(sdk_resource, 'allow_get', None) is not None:
|
||||
resource_dict = sdk_resource.to_dict(
|
||||
body=True, headers=False, ignore_none=False)
|
||||
else:
|
||||
resource_dict = sdk_resource
|
||||
|
||||
# Build the OSC column names to display for the SDK resource.
|
||||
attr_map = {}
|
||||
display_columns = list(resource_dict.keys())
|
||||
invisible_columns = [] if invisible_columns is None else invisible_columns
|
||||
for col_name in invisible_columns:
|
||||
if col_name in display_columns:
|
||||
display_columns.remove(col_name)
|
||||
for sdk_attr, osc_attr in osc_column_map.items():
|
||||
if sdk_attr in display_columns:
|
||||
attr_map[osc_attr] = sdk_attr
|
||||
display_columns.remove(sdk_attr)
|
||||
if osc_attr not in display_columns:
|
||||
display_columns.append(osc_attr)
|
||||
sorted_display_columns = sorted(display_columns)
|
||||
|
||||
# Build the SDK attribute names for the OSC column names.
|
||||
attr_columns = []
|
||||
for column in sorted_display_columns:
|
||||
new_column = attr_map[column] if column in attr_map else column
|
||||
attr_columns.append(new_column)
|
||||
return tuple(sorted_display_columns), tuple(attr_columns)
|
||||
|
||||
|
||||
class DictModel(dict):
|
||||
"""Convert dict into an object that provides attribute access to values."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Convert dict values to DictModel values."""
|
||||
super(DictModel, self).__init__(*args, **kwargs)
|
||||
|
||||
def needs_upgrade(item):
|
||||
return isinstance(item, dict) and not isinstance(item, DictModel)
|
||||
|
||||
def upgrade(item):
|
||||
"""Upgrade item if it needs to be upgraded."""
|
||||
if needs_upgrade(item):
|
||||
return DictModel(item)
|
||||
else:
|
||||
return item
|
||||
|
||||
for key, value in self.items():
|
||||
if isinstance(value, (list, tuple)):
|
||||
# Keep the same type but convert dicts to DictModels
|
||||
self[key] = type(value)(
|
||||
(upgrade(item) for item in value)
|
||||
)
|
||||
elif needs_upgrade(value):
|
||||
# Change dict instance values to DictModel instance values
|
||||
self[key] = DictModel(value)
|
||||
|
||||
def __getattr__(self, name):
|
||||
try:
|
||||
return self[name]
|
||||
except KeyError as e:
|
||||
raise AttributeError(e)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
self[name] = value
|
||||
|
||||
def __delattr__(self, name):
|
||||
del self[name]
|
||||
|
||||
def __str__(self):
|
||||
pairs = ['%s=%s' % (k, v) for k, v in self.items()]
|
||||
return ', '.join(sorted(pairs))
|
||||
|
||||
|
||||
def save_data(data, path):
|
||||
"""Save data to the specified path.
|
||||
|
||||
:param data: binary or string data
|
||||
:param path: file path to save data
|
||||
"""
|
||||
if path is None:
|
||||
vnfpackage = getattr(sys.stdout, 'buffer', sys.stdout)
|
||||
else:
|
||||
mode = 'wb' if isinstance(data, bytes) else 'w'
|
||||
vnfpackage = open(path, mode)
|
||||
try:
|
||||
vnfpackage.write(data)
|
||||
finally:
|
||||
vnfpackage.close()
|
||||
|
||||
|
||||
def exit(msg=None, exit_code=1):
|
||||
if msg:
|
||||
print(encodeutils.safe_decode(msg))
|
||||
sys.exit(exit_code)
|
||||
@@ -1,243 +0,0 @@
|
||||
# Copyright 2016 NEC Corporation
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""This module should contain OSC plugin generic methods.
|
||||
|
||||
Methods in this module are candidates adopted to osc-lib.
|
||||
|
||||
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
|
||||
from keystoneclient.v3 import domains
|
||||
from keystoneclient.v3 import projects
|
||||
from osc_lib import utils
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.i18n import _
|
||||
|
||||
|
||||
LIST_BOTH = 'both'
|
||||
LIST_SHORT_ONLY = 'short_only'
|
||||
LIST_LONG_ONLY = 'long_only'
|
||||
|
||||
|
||||
def format_dict_with_indention(data):
|
||||
"""Return a formatted string of key value pairs
|
||||
|
||||
:param data: a dict
|
||||
:rtype: a string formatted to key='value'
|
||||
"""
|
||||
|
||||
if data is None:
|
||||
return None
|
||||
return jsonutils.dumps(data, indent=4)
|
||||
|
||||
|
||||
def get_column_definitions(attr_map, long_listing):
|
||||
"""Return table headers and column names for a listing table.
|
||||
|
||||
:param attr_map: a list of table entry definitions.
|
||||
Each entry should be a tuple consisting of
|
||||
(API attribute name, header name, listing mode). For example:
|
||||
(('id', 'ID', LIST_BOTH),
|
||||
('name', 'Name', LIST_BOTH),
|
||||
('tenant_id', 'Project', LIST_LONG_ONLY))
|
||||
The third field of each tuple must be one of LIST_BOTH,
|
||||
LIST_LONG_ONLY (a corresponding column is shown only in a long mode), or
|
||||
LIST_SHORT_ONLY (a corresponding column is shown only in a short mode).
|
||||
:param long_listing: A boolean value which indicates a long listing
|
||||
or not. In most cases, parsed_args.long is passed to this argument.
|
||||
:return: A tuple of a list of table headers and a list of column names.
|
||||
"""
|
||||
|
||||
if long_listing:
|
||||
headers = [hdr for col, hdr, listing_mode in attr_map
|
||||
if listing_mode in (LIST_BOTH, LIST_LONG_ONLY)]
|
||||
columns = [col for col, hdr, listing_mode in attr_map
|
||||
if listing_mode in (LIST_BOTH, LIST_LONG_ONLY)]
|
||||
else:
|
||||
headers = [hdr for col, hdr, listing_mode in attr_map
|
||||
if listing_mode in (LIST_BOTH, LIST_SHORT_ONLY)]
|
||||
columns = [col for col, hdr, listing_mode in attr_map
|
||||
if listing_mode in (LIST_BOTH, LIST_SHORT_ONLY)]
|
||||
|
||||
return headers, columns
|
||||
|
||||
|
||||
def get_columns(item, attr_map=None):
|
||||
"""Return pair of resource attributes and corresponding display names.
|
||||
|
||||
Assume the following item and attr_map are passed.
|
||||
item: {'id': 'myid', 'name': 'myname',
|
||||
'foo': 'bar', 'tenant_id': 'mytenan'}
|
||||
attr_map:
|
||||
(('id', 'ID', LIST_BOTH),
|
||||
('name', 'Name', LIST_BOTH),
|
||||
('tenant_id', 'Project', LIST_LONG_ONLY))
|
||||
|
||||
This method returns:
|
||||
|
||||
(('id', 'name', 'tenant_id', 'foo'), # attributes
|
||||
('ID', 'Name', 'Project', 'foo') # display names
|
||||
|
||||
Both tuples of attributes and display names are sorted by display names
|
||||
in the alphabetical order.
|
||||
Attributes not found in a given attr_map are kept as-is.
|
||||
|
||||
:param item: a dictionary which represents a resource.
|
||||
Keys of the dictionary are expected to be attributes of the resource.
|
||||
Values are not referred to by this method.
|
||||
:param attr_map: a list of mapping from attribute to display name.
|
||||
The same format is used as for get_column_definitions attr_map.
|
||||
:return: A pair of tuple of attributes and tuple of display names.
|
||||
"""
|
||||
attr_map = attr_map or tuple([])
|
||||
_attr_map_dict = dict((col, hdr) for col, hdr, listing_mode in attr_map)
|
||||
|
||||
columns = [(column, _attr_map_dict.get(column, column))
|
||||
for column in item.keys()]
|
||||
columns = sorted(columns, key=operator.itemgetter(1))
|
||||
return (tuple(col[0] for col in columns),
|
||||
tuple(col[1] for col in columns))
|
||||
|
||||
|
||||
# TODO(amotoki): Use osc-lib version once osc-lib provides this.
|
||||
def add_project_owner_option_to_parser(parser):
|
||||
"""Register project and project domain options.
|
||||
|
||||
:param parser: argparse.Argument parser object.
|
||||
|
||||
"""
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help=_("Owner's project (name or ID)")
|
||||
)
|
||||
# Borrowed from openstackclient.identity.common
|
||||
# as it is not exposed officially.
|
||||
parser.add_argument(
|
||||
'--project-domain',
|
||||
metavar='<project-domain>',
|
||||
help=_('Domain the project belongs to (name or ID). '
|
||||
'This can be used in case collisions between project names '
|
||||
'exist.'),
|
||||
)
|
||||
|
||||
|
||||
# The following methods are borrowed from openstackclient.identity.common
|
||||
# as it is not exposed officially.
|
||||
# TODO(amotoki): Use osc-lib version once osc-lib provides this.
|
||||
|
||||
|
||||
def find_domain(identity_client, name_or_id):
|
||||
return _find_identity_resource(identity_client.domains, name_or_id,
|
||||
domains.Domain)
|
||||
|
||||
|
||||
def find_project(identity_client, name_or_id, domain_name_or_id=None):
|
||||
domain_id = _get_domain_id_if_requested(identity_client, domain_name_or_id)
|
||||
if not domain_id:
|
||||
return _find_identity_resource(identity_client.projects, name_or_id,
|
||||
projects.Project)
|
||||
else:
|
||||
return _find_identity_resource(identity_client.projects, name_or_id,
|
||||
projects.Project, domain_id=domain_id)
|
||||
|
||||
|
||||
def _get_domain_id_if_requested(identity_client, domain_name_or_id):
|
||||
if not domain_name_or_id:
|
||||
return None
|
||||
domain = find_domain(identity_client, domain_name_or_id)
|
||||
return domain.id
|
||||
|
||||
|
||||
def _find_identity_resource(identity_client_manager, name_or_id,
|
||||
resource_type, **kwargs):
|
||||
"""Find a specific identity resource.
|
||||
|
||||
Using keystoneclient's manager, attempt to find a specific resource by its
|
||||
name or ID. If Forbidden to find the resource (a common case if the user
|
||||
does not have permission), then return the resource by creating a local
|
||||
instance of keystoneclient's Resource.
|
||||
|
||||
The parameter identity_client_manager is a keystoneclient manager,
|
||||
for example: keystoneclient.v3.users or keystoneclient.v3.projects.
|
||||
|
||||
The parameter resource_type is a keystoneclient resource, for example:
|
||||
keystoneclient.v3.users.User or keystoneclient.v3.projects.Project.
|
||||
|
||||
:param identity_client_manager: the manager that contains the resource
|
||||
:type identity_client_manager: `keystoneclient.base.CrudManager`
|
||||
:param name_or_id: the resources's name or ID
|
||||
:type name_or_id: string
|
||||
:param resource_type: class that represents the resource type
|
||||
:type resource_type: `keystoneclient.base.Resource`
|
||||
|
||||
:returns: the resource in question
|
||||
:rtype: `keystoneclient.base.Resource`
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
identity_resource = utils.find_resource(identity_client_manager,
|
||||
name_or_id, **kwargs)
|
||||
if identity_resource is not None:
|
||||
return identity_resource
|
||||
except identity_exc.Forbidden:
|
||||
pass
|
||||
|
||||
return resource_type(None, {'id': name_or_id, 'name': name_or_id})
|
||||
|
||||
|
||||
# The above are borrowed from openstackclient.identity.common.
|
||||
|
||||
|
||||
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
|
||||
@@ -1,119 +0,0 @@
|
||||
# Copyright 2018 OpenStack Foundation
|
||||
# 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 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
|
||||
from tackerclient.tacker import v1_0 as tackerV10
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('resource_type', 'Resource Type', tacker_osc_utils.LIST_BOTH),
|
||||
('resource_id', 'Resource ID', tacker_osc_utils.LIST_BOTH),
|
||||
('resource_state', 'Resource State', tacker_osc_utils.LIST_BOTH),
|
||||
('event_type', 'Event Type', tacker_osc_utils.LIST_BOTH),
|
||||
('timestamp', 'Timestamp', tacker_osc_utils.LIST_BOTH),
|
||||
('event_details', 'Event Details', tacker_osc_utils.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_EVENT = "event"
|
||||
|
||||
events_path = '/events'
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
column_map = {}
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||
|
||||
|
||||
class ShowEvent(command.ShowOne):
|
||||
_description = _("Show event given the event id.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowEvent, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_EVENT,
|
||||
metavar="ID",
|
||||
help=_("ID of event to display")
|
||||
)
|
||||
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)
|
||||
obj = client.show_event(obj_id)
|
||||
display_columns, columns = _get_columns(obj[_EVENT])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_EVENT]),
|
||||
columns,)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ListEvent(command.Lister):
|
||||
_description = _("List events of resources.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListEvent, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--id',
|
||||
help=_("id of the event to look up."))
|
||||
parser.add_argument(
|
||||
'--resource-type',
|
||||
help=_("resource type of the events to look up."))
|
||||
parser.add_argument(
|
||||
'--resource-id',
|
||||
help=_("resource id of the events to look up."))
|
||||
parser.add_argument(
|
||||
'--resource-state',
|
||||
help=_("resource state of the events to look up."))
|
||||
parser.add_argument(
|
||||
'--event-type',
|
||||
help=_("event type of the events to look up."))
|
||||
parser.add_argument(
|
||||
'--long',
|
||||
action='store_true',
|
||||
help=_("List additional fields in output"))
|
||||
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:
|
||||
_params['id'] = parsed_args.id
|
||||
if parsed_args.resource_id:
|
||||
_params['resource_id'] = parsed_args.resource_id
|
||||
if parsed_args.resource_state:
|
||||
_params['resource_state'] = parsed_args.resource_id
|
||||
if parsed_args.event_type:
|
||||
_params['event_type'] = parsed_args.event_type
|
||||
if parsed_args.resource_type:
|
||||
_params['resource_type'] = parsed_args.resource_type
|
||||
events = client.list('events', events_path, True, **_params)
|
||||
data = {}
|
||||
data['events'] = events['events']
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_EVENT + 's']))
|
||||
@@ -1,261 +0,0 @@
|
||||
# Copyright 2018 OpenStack Foundation.
|
||||
# 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 yaml
|
||||
|
||||
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
|
||||
from tackerclient.tacker import v1_0 as tackerV10
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('name', 'Name', tacker_osc_utils.LIST_BOTH),
|
||||
('nsd_id', 'NSD ID', tacker_osc_utils.LIST_BOTH),
|
||||
('vnf_ids', 'VNF IDs', tacker_osc_utils.LIST_BOTH),
|
||||
('vnffg_ids', 'VNFFG IDs', tacker_osc_utils.LIST_BOTH),
|
||||
('mgmt_ip_addresses', 'Mgmt Ip Addresses', tacker_osc_utils.LIST_BOTH),
|
||||
('status', 'Status', tacker_osc_utils.LIST_BOTH),
|
||||
)
|
||||
|
||||
_NS = 'ns'
|
||||
_RESOURCE = 'resource'
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
column_map = {
|
||||
'tenant_id': 'project_id',
|
||||
}
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||
|
||||
|
||||
class CreateNS(command.ShowOne):
|
||||
_description = _("Create a new NS")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateNS, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'name', metavar='NAME',
|
||||
help=_('Name for NS'))
|
||||
parser.add_argument(
|
||||
'--tenant-id', metavar='TENANT_ID',
|
||||
help=_('The owner tenant ID'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help=_('Set description for the NS'))
|
||||
nsd_group = parser.add_mutually_exclusive_group(required=True)
|
||||
nsd_group.add_argument(
|
||||
'--nsd-id',
|
||||
help=_('NSD ID to use as template to create NS'))
|
||||
nsd_group.add_argument(
|
||||
'--nsd-template',
|
||||
help=_('NSD file to create NS'))
|
||||
nsd_group.add_argument(
|
||||
'--nsd-name',
|
||||
help=_('NSD name to use as template to create NS'))
|
||||
vim_group = parser.add_mutually_exclusive_group()
|
||||
vim_group.add_argument(
|
||||
'--vim-id',
|
||||
help=_('VIM ID to use to create NS on the specified VIM'))
|
||||
vim_group.add_argument(
|
||||
'--vim-name',
|
||||
help=_('VIM name to use to create NS on the specified VIM'))
|
||||
parser.add_argument(
|
||||
'--vim-region-name',
|
||||
help=_('VIM Region to use to create NS on the specified VIM'))
|
||||
parser.add_argument(
|
||||
'--param-file',
|
||||
help=_('Specify parameter YAML file'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {_NS: {}}
|
||||
body[_NS]['attributes'] = {}
|
||||
|
||||
if parsed_args.vim_region_name:
|
||||
body[_NS].setdefault('placement_attr', {})['region_name'] = \
|
||||
parsed_args.vim_region_name
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
if parsed_args.vim_name:
|
||||
_id = tackerV10.find_resourceid_by_name_or_id(client, 'vim',
|
||||
parsed_args.vim_name)
|
||||
parsed_args.vim_id = _id
|
||||
if parsed_args.nsd_name:
|
||||
_id = tackerV10.find_resourceid_by_name_or_id(client, 'nsd',
|
||||
parsed_args.nsd_name)
|
||||
parsed_args.nsd_id = _id
|
||||
elif parsed_args.nsd_template:
|
||||
with open(parsed_args.nsd_template) as f:
|
||||
template = f.read()
|
||||
try:
|
||||
template = yaml.load(
|
||||
template, Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
if not template:
|
||||
raise exceptions.InvalidInput(
|
||||
reason='The nsd file is empty')
|
||||
body[_NS]['nsd_template'] = template
|
||||
|
||||
if parsed_args.param_file:
|
||||
with open(parsed_args.param_file) as f:
|
||||
param_yaml = f.read()
|
||||
try:
|
||||
param_yaml = yaml.load(
|
||||
param_yaml, Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
if not param_yaml:
|
||||
raise exceptions.InvalidInput(
|
||||
reason='The parameter file is empty')
|
||||
body[_NS]['attributes'] = {'param_values': param_yaml}
|
||||
tackerV10.update_dict(parsed_args, body[_NS],
|
||||
['tenant_id', 'name', 'description',
|
||||
'nsd_id', 'vim_id'])
|
||||
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])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(ns[_NS]),
|
||||
columns)
|
||||
lstdata = list(data)
|
||||
for index, value in enumerate(lstdata):
|
||||
if value is None:
|
||||
lstdata[index] = ''
|
||||
data = tuple(lstdata)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class DeleteNS(command.Command):
|
||||
_description = _("Delete NS(s).")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteNS, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_NS,
|
||||
metavar="<NS>",
|
||||
nargs="+",
|
||||
help=_("NS(s) to delete (name or ID)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help=_('Force delete Network Service')
|
||||
)
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
if parsed_args.force:
|
||||
body = {_NS: {'attributes': {'force': True}}}
|
||||
else:
|
||||
body = dict()
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
tacker_common_utils.deprecate_legacy_warning()
|
||||
client = self.app.client_manager.tackerclient
|
||||
failure = False
|
||||
deleted_ids = []
|
||||
failed_items = {}
|
||||
body = self.args2body(parsed_args)
|
||||
for resource_id in parsed_args.ns:
|
||||
try:
|
||||
obj = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, _NS, resource_id)
|
||||
client.delete_ns(obj, body)
|
||||
deleted_ids.append(resource_id)
|
||||
except Exception as e:
|
||||
failure = True
|
||||
failed_items[resource_id] = e
|
||||
if failure:
|
||||
msg = ''
|
||||
if deleted_ids:
|
||||
msg = (_('Successfully deleted %(resource)s(s):'
|
||||
' %(deleted_list)s') % {'deleted_list':
|
||||
', '.join(deleted_ids),
|
||||
'resource': _NS})
|
||||
err_msg = _("\n\nUnable to delete the below"
|
||||
" %s(s):") % _NS
|
||||
for failed_id, error in failed_items.items():
|
||||
err_msg += (_('\n Cannot delete %(failed_id)s: %(error)s')
|
||||
% {'failed_id': failed_id,
|
||||
'error': error})
|
||||
msg += err_msg
|
||||
raise exceptions.CommandError(message=msg)
|
||||
else:
|
||||
print((_('All specified %(resource)s(s) deleted successfully')
|
||||
% {'resource': _NS}))
|
||||
return
|
||||
|
||||
|
||||
class ListNS(command.Lister):
|
||||
_description = ("List (NS)s that belong to a given tenant.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListNS, self).get_parser(prog_name)
|
||||
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(
|
||||
_attr_map, long_listing=None)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_NS + 's']))
|
||||
|
||||
|
||||
class ShowNS(command.ShowOne):
|
||||
_description = _("Display NS details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowNS, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_NS,
|
||||
metavar="<NS>",
|
||||
help=_("NS to display (name or ID)")
|
||||
)
|
||||
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)
|
||||
obj = client.show_ns(obj_id)
|
||||
display_columns, columns = _get_columns(obj[_NS])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_NS]),
|
||||
columns)
|
||||
lstdata = list(data)
|
||||
for index, value in enumerate(lstdata):
|
||||
if value is None:
|
||||
lstdata[index] = ''
|
||||
data = tuple(lstdata)
|
||||
return (display_columns, data)
|
||||
@@ -1,229 +0,0 @@
|
||||
# Copyright 2018 OpenStack Foundation
|
||||
# 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 yaml
|
||||
|
||||
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
|
||||
from tackerclient.tacker import v1_0 as tackerV10
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('name', 'Name', tacker_osc_utils.LIST_BOTH),
|
||||
('template_source', 'Template_Source',
|
||||
tacker_osc_utils.LIST_BOTH),
|
||||
('description', 'Description', tacker_osc_utils.LIST_BOTH),
|
||||
)
|
||||
|
||||
_NSD = 'nsd'
|
||||
|
||||
_formatters = {
|
||||
'attributes': tacker_osc_utils.format_dict_with_indention,
|
||||
}
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
column_map = {
|
||||
'tenant_id': 'project_id',
|
||||
}
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||
|
||||
|
||||
class CreateNSD(command.ShowOne):
|
||||
_description = _("Create a new NSD.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateNSD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'name', metavar='NAME',
|
||||
help=_('Name for NSD'))
|
||||
parser.add_argument(
|
||||
'--tenant-id', metavar='TENANT_ID',
|
||||
help=_('The owner tenant ID or project ID'))
|
||||
parser.add_argument(
|
||||
'--nsd-file',
|
||||
required=True,
|
||||
help=_('YAML file with NSD parameters'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help=_('Set a description for the NSD'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {_NSD: {}}
|
||||
nsd = None
|
||||
if not parsed_args.nsd_file:
|
||||
raise exceptions.InvalidInput(reason="Invalid input for nsd file")
|
||||
with open(parsed_args.nsd_file) as f:
|
||||
nsd = f.read()
|
||||
try:
|
||||
nsd = yaml.load(nsd, Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
if not nsd:
|
||||
raise exceptions.InvalidInput(reason="nsd file is empty")
|
||||
body[_NSD]['attributes'] = {'nsd': nsd}
|
||||
tackerV10.update_dict(parsed_args, body[_NSD],
|
||||
['tenant_id', 'name', 'description'])
|
||||
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])
|
||||
nsd[_NSD]['attributes']['nsd'] = yaml.load(
|
||||
nsd[_NSD]['attributes']['nsd'])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(nsd[_NSD]),
|
||||
columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class DeleteNSD(command.Command):
|
||||
_description = _("Delete NSD(s).")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteNSD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_NSD,
|
||||
metavar="<NSD>",
|
||||
nargs="+",
|
||||
help=_("NSD(s) to delete (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
tacker_common_utils.deprecate_legacy_warning()
|
||||
client = self.app.client_manager.tackerclient
|
||||
failure = False
|
||||
deleted_ids = []
|
||||
failed_items = {}
|
||||
for resource_id in parsed_args.nsd:
|
||||
try:
|
||||
obj = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, _NSD, resource_id)
|
||||
client.delete_nsd(obj)
|
||||
deleted_ids.append(resource_id)
|
||||
except Exception as e:
|
||||
failure = True
|
||||
failed_items[resource_id] = e
|
||||
if failure:
|
||||
msg = ''
|
||||
if deleted_ids:
|
||||
msg = (_('Successfully deleted %(resource)s(s):'
|
||||
' %(deleted_list)s') % {'deleted_list':
|
||||
', '.join(deleted_ids),
|
||||
'resource': _NSD})
|
||||
err_msg = _("\n\nUnable to delete the below"
|
||||
" %s(s):") % _NSD
|
||||
for failed_id, error in failed_items.items():
|
||||
err_msg += (_('\n Cannot delete %(failed_id)s: %(error)s')
|
||||
% {'failed_id': failed_id,
|
||||
'error': error})
|
||||
msg += err_msg
|
||||
raise exceptions.CommandError(message=msg)
|
||||
else:
|
||||
print((_('All specified %(resource)s(s) deleted successfully')
|
||||
% {'resource': _NSD}))
|
||||
return
|
||||
|
||||
|
||||
class ListNSD(command.Lister):
|
||||
_description = ("List (NSD)s that belong to a given tenant.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListNSD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--template-source',
|
||||
help=_("List NSD with specified template source. Available \
|
||||
options are 'onboared' (default), 'inline' or 'all'"),
|
||||
action='store',
|
||||
default='onboarded')
|
||||
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(
|
||||
_attr_map, long_listing=None)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_NSD + 's']))
|
||||
|
||||
|
||||
class ShowNSD(command.ShowOne):
|
||||
_description = _("Display NSD details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowNSD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_NSD,
|
||||
metavar="<NSD>",
|
||||
help=_("NSD to display (name or ID)")
|
||||
)
|
||||
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)
|
||||
obj = client.show_nsd(obj_id)
|
||||
obj[_NSD]['attributes']['nsd'] = yaml.load(
|
||||
obj[_NSD]['attributes']['nsd'])
|
||||
display_columns, columns = _get_columns(obj[_NSD])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_NSD]),
|
||||
columns,
|
||||
formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ShowTemplateNSD(command.ShowOne):
|
||||
_description = _("Display NSD Template details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowTemplateNSD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_NSD,
|
||||
metavar="<NSD>",
|
||||
help=_("NSD to display (name or ID)")
|
||||
)
|
||||
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)
|
||||
obj = client.show_nsd(obj_id)
|
||||
obj[_NSD]['attributes']['nsd'] = yaml.load(
|
||||
obj[_NSD]['attributes']['nsd'])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_NSD]),
|
||||
('attributes',),
|
||||
formatters=_formatters)
|
||||
data = (data or _('Unable to display NSD template!'))
|
||||
return (('attributes',), data)
|
||||
@@ -1,271 +0,0 @@
|
||||
# Copyright 2016 Brocade Communications Systems Inc
|
||||
# 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 yaml
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils
|
||||
from oslo_utils import strutils
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.i18n import _
|
||||
from tackerclient.osc import sdk_utils
|
||||
from tackerclient.osc import utils as tacker_osc_utils
|
||||
from tackerclient.tacker import v1_0 as tackerV10
|
||||
from tackerclient.tacker.v1_0.nfvo import vim_utils
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('name', 'Name', tacker_osc_utils.LIST_BOTH),
|
||||
('tenant_id', 'Tenant_id', tacker_osc_utils.LIST_BOTH),
|
||||
('type', 'Type', tacker_osc_utils.LIST_BOTH),
|
||||
('is_default', 'Is Default',
|
||||
tacker_osc_utils.LIST_BOTH),
|
||||
('placement_attr', 'Placement attribution',
|
||||
tacker_osc_utils.LIST_LONG_ONLY),
|
||||
('status', 'Status', tacker_osc_utils.LIST_BOTH),
|
||||
)
|
||||
|
||||
_VIM = 'vim'
|
||||
|
||||
|
||||
class ListVIM(command.Lister):
|
||||
_description = _("List VIMs that belong to a given tenant.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListVIM, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--long',
|
||||
action='store_true',
|
||||
help=_("List additional fields in output")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
data = client.list_vims()
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_VIM + 's']))
|
||||
|
||||
|
||||
class ShowVIM(command.ShowOne):
|
||||
_description = _("Display VIM details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowVIM, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VIM,
|
||||
metavar="<VIM>",
|
||||
help=_("VIM to display (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj_id = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, _VIM, parsed_args.vim)
|
||||
obj = client.show_vim(obj_id)
|
||||
display_columns, columns = _get_columns(obj[_VIM])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_VIM]),
|
||||
columns,
|
||||
formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class CreateVIM(command.ShowOne):
|
||||
_description = _("Register a new VIM")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateVIM, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'name', metavar='NAME',
|
||||
help=_('Set a name for the VIM'))
|
||||
parser.add_argument(
|
||||
'--tenant-id', metavar='TENANT_ID',
|
||||
help=_('The owner tenant ID or project ID'))
|
||||
parser.add_argument(
|
||||
'--config-file',
|
||||
required=True,
|
||||
help=_('YAML file with VIM configuration parameters'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help=_('Set a description for the VIM'))
|
||||
parser.add_argument(
|
||||
'--is-default',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Set as default VIM'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {_VIM: {}}
|
||||
if parsed_args.config_file:
|
||||
with open(parsed_args.config_file) as f:
|
||||
vim_config = f.read()
|
||||
try:
|
||||
config_param = yaml.load(vim_config,
|
||||
Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
vim_obj = body[_VIM]
|
||||
try:
|
||||
auth_url = config_param.pop('auth_url')
|
||||
except KeyError:
|
||||
raise exceptions.TackerClientException(message='Auth URL must be '
|
||||
'specified',
|
||||
status_code=404)
|
||||
vim_obj['auth_url'] = vim_utils.validate_auth_url(auth_url).geturl()
|
||||
vim_utils.args2body_vim(config_param, vim_obj)
|
||||
tackerV10.update_dict(parsed_args, body[_VIM],
|
||||
['tenant_id', 'name', 'description',
|
||||
'is_default'])
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
vim = client.create_vim(self.args2body(parsed_args))
|
||||
display_columns, columns = _get_columns(vim[_VIM])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(vim[_VIM]),
|
||||
columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class DeleteVIM(command.Command):
|
||||
_description = _("Delete VIM(s).")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteVIM, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VIM,
|
||||
metavar="<VIM>",
|
||||
nargs="+",
|
||||
help=_("VIM(s) to delete (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
failure = False
|
||||
deleted_ids = []
|
||||
failed_items = {}
|
||||
for resource_id in parsed_args.vim:
|
||||
try:
|
||||
obj = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, _VIM, resource_id)
|
||||
client.delete_vim(obj)
|
||||
deleted_ids.append(resource_id)
|
||||
except Exception as e:
|
||||
failure = True
|
||||
failed_items[resource_id] = e
|
||||
if failure:
|
||||
msg = ''
|
||||
if deleted_ids:
|
||||
msg = (_('Successfully deleted %(resource)s(s):'
|
||||
' %(deleted_list)s') % {'deleted_list':
|
||||
', '.join(deleted_ids),
|
||||
'resource': _VIM})
|
||||
err_msg = _("\n\nUnable to delete the below"
|
||||
" %s(s):") % _VIM
|
||||
for failed_id, error in failed_items.items():
|
||||
err_msg += (_('\n Cannot delete %(failed_id)s: %(error)s')
|
||||
% {'failed_id': failed_id,
|
||||
'error': error})
|
||||
msg += err_msg
|
||||
raise exceptions.CommandError(message=msg)
|
||||
else:
|
||||
print((_('All specified %(resource)s(s) deleted successfully')
|
||||
% {'resource': _VIM}))
|
||||
return
|
||||
|
||||
|
||||
class UpdateVIM(command.ShowOne):
|
||||
_description = _("Update VIM.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateVIM, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'id', metavar="VIM",
|
||||
help=_('ID or name of %s to update') % _VIM)
|
||||
parser.add_argument(
|
||||
'--config-file',
|
||||
required=False,
|
||||
help=_('YAML file with VIM configuration parameters'))
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
help=_('New name for the VIM'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help=_('New description for the VIM'))
|
||||
parser.add_argument(
|
||||
'--is-default',
|
||||
type=strutils.bool_from_string,
|
||||
metavar='{True,False}',
|
||||
help=_('Indicate whether the VIM is used as default'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {_VIM: {}}
|
||||
config_param = None
|
||||
# config arg passed as data overrides config yaml when both args passed
|
||||
if parsed_args.config_file:
|
||||
with open(parsed_args.config_file) as f:
|
||||
config_yaml = f.read()
|
||||
try:
|
||||
config_param = yaml.load(config_yaml,
|
||||
Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
vim_obj = body[_VIM]
|
||||
if config_param is not None:
|
||||
vim_utils.args2body_vim(config_param, vim_obj)
|
||||
tackerV10.update_dict(parsed_args, body[_VIM],
|
||||
['tenant_id', 'name', 'description',
|
||||
'is_default'])
|
||||
# type attribute is read-only, it can't be updated, so remove it
|
||||
# in update method
|
||||
body[_VIM].pop('type', None)
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj_id = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, _VIM, parsed_args.id)
|
||||
vim = client.update_vim(obj_id, self.args2body(parsed_args))
|
||||
display_columns, columns = _get_columns(vim[_VIM])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(vim[_VIM]), columns,
|
||||
formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
_formatters = {
|
||||
'auth_cred': tacker_osc_utils.format_dict_with_indention,
|
||||
'placement_attr': tacker_osc_utils.format_dict_with_indention,
|
||||
'vim_project': tacker_osc_utils.format_dict_with_indention,
|
||||
}
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
column_map = {
|
||||
'tenant_id': 'project_id',
|
||||
}
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||
@@ -1,574 +0,0 @@
|
||||
# Copyright 2018 OpenStack Foundation.
|
||||
# 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 yaml
|
||||
|
||||
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
|
||||
from tackerclient.tacker import v1_0 as tackerV10
|
||||
|
||||
_VNFFG = 'vnffg' # VNF Forwarding Graph
|
||||
_NFP = 'nfp' # Network Forwarding Path
|
||||
_SFC = 'sfc' # Service Function Chain
|
||||
_FC = 'classifier' # Flow Classifier
|
||||
|
||||
nfps_path = '/nfps'
|
||||
fcs_path = '/classifiers'
|
||||
sfcs_path = '/sfcs'
|
||||
|
||||
DEFAULT_ERROR_REASON_LENGTH = 100
|
||||
|
||||
_attr_map_vnffg = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('name', 'Name', tacker_osc_utils.LIST_BOTH),
|
||||
('ns_id', 'NS ID', tacker_osc_utils.LIST_BOTH),
|
||||
('vnffgd_id', 'VNFFGD ID', tacker_osc_utils.LIST_BOTH),
|
||||
('status', 'Status', tacker_osc_utils.LIST_BOTH),
|
||||
('description', 'Description', tacker_osc_utils.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_nfp = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('name', 'Name', tacker_osc_utils.LIST_BOTH),
|
||||
('status', 'Status', tacker_osc_utils.LIST_BOTH),
|
||||
('vnffg_id', 'VNFFG ID', tacker_osc_utils.LIST_BOTH),
|
||||
('path_id', 'Path ID', tacker_osc_utils.LIST_BOTH),
|
||||
)
|
||||
|
||||
_attr_map_sfc = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('status', 'Status', tacker_osc_utils.LIST_BOTH),
|
||||
('nfp_id', 'NFP ID', tacker_osc_utils.LIST_BOTH),
|
||||
)
|
||||
|
||||
_attr_map_fc = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('name', 'Name', tacker_osc_utils.LIST_BOTH),
|
||||
('status', 'Status', tacker_osc_utils.LIST_BOTH),
|
||||
('nfp_id', 'NFP ID', tacker_osc_utils.LIST_BOTH),
|
||||
('chain_id', 'Chain ID', tacker_osc_utils.LIST_BOTH),
|
||||
)
|
||||
|
||||
_formatters = {
|
||||
'attributes': tacker_osc_utils.format_dict_with_indention,
|
||||
'match': tacker_osc_utils.format_dict_with_indention,
|
||||
'chain': tacker_osc_utils.format_dict_with_indention,
|
||||
}
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
column_map = {
|
||||
'tenant_id': 'project_id',
|
||||
}
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||
|
||||
|
||||
class CreateVNFFG(command.ShowOne):
|
||||
_description = _("Create a new VNFFG.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateVNFFG, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'name', metavar='NAME',
|
||||
help=_('Set a name for the VNFFG'))
|
||||
parser.add_argument(
|
||||
'--tenant-id', metavar='TENANT_ID',
|
||||
help=_('The owner tenant ID'))
|
||||
vnffgd_group = parser.add_mutually_exclusive_group(required=True)
|
||||
vnffgd_group.add_argument(
|
||||
'--vnffgd-id',
|
||||
help=_('VNFFGD ID to use as template to create VNFFG'))
|
||||
vnffgd_group.add_argument(
|
||||
'--vnffgd-name',
|
||||
help=_('VNFFGD Name to use as template to create VNFFG'))
|
||||
vnffgd_group.add_argument(
|
||||
'--vnffgd-template',
|
||||
help=_('VNFFGD file to create VNFFG'))
|
||||
parser.add_argument(
|
||||
'--vnf-mapping',
|
||||
help=_('List of logical VNFD name to VNF instance name mapping. '
|
||||
'Example: VNF1:my_vnf1,VNF2:my_vnf2'))
|
||||
parser.add_argument(
|
||||
'--symmetrical',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Should a reverse path be created for the NFP '
|
||||
'(True or False)'))
|
||||
parser.add_argument(
|
||||
'--param-file',
|
||||
help=_('YAML file with specific VNFFG parameters'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help=_('Set a description for the VNFFG'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {_VNFFG: {}}
|
||||
body[_VNFFG]['attributes'] = {}
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
if parsed_args.vnf_mapping:
|
||||
_vnf_mapping = dict()
|
||||
_vnf_mappings = parsed_args.vnf_mapping.split(",")
|
||||
for mapping in _vnf_mappings:
|
||||
vnfd_name, vnf = mapping.split(":", 1)
|
||||
_vnf_mapping[vnfd_name] = \
|
||||
tackerV10.find_resourceid_by_name_or_id(
|
||||
client, 'vnf', vnf)
|
||||
parsed_args.vnf_mapping = _vnf_mapping
|
||||
|
||||
if parsed_args.vnffgd_name:
|
||||
_id = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, 'vnffgd', parsed_args.vnffgd_name)
|
||||
parsed_args.vnffgd_id = _id
|
||||
elif parsed_args.vnffgd_template:
|
||||
with open(parsed_args.vnffgd_template) as f:
|
||||
template = f.read()
|
||||
try:
|
||||
template = yaml.load(template, Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
if not template:
|
||||
raise exceptions.InvalidInput(
|
||||
reason='The vnffgd file is empty')
|
||||
body[_VNFFG]['vnffgd_template'] = template
|
||||
|
||||
if parsed_args.param_file:
|
||||
with open(parsed_args.param_file) as f:
|
||||
param_yaml = f.read()
|
||||
try:
|
||||
param_yaml = yaml.load(
|
||||
param_yaml, Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
if not param_yaml:
|
||||
raise exceptions.InvalidInput(
|
||||
reason='The parameter file is empty')
|
||||
body[_VNFFG]['attributes'] = {'param_values': param_yaml}
|
||||
tackerV10.update_dict(parsed_args, body[_VNFFG],
|
||||
['tenant_id', 'name', 'vnffgd_id',
|
||||
'symmetrical', 'vnf_mapping', 'description'])
|
||||
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])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(vnffg[_VNFFG]),
|
||||
columns,
|
||||
formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class DeleteVNFFG(command.Command):
|
||||
_description = _("Delete VNFFG(s).")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteVNFFG, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNFFG,
|
||||
metavar="<VNFFG>",
|
||||
nargs="+",
|
||||
help=_("VNFFG(s) to delete (name or ID)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help=_('Force delete VNFFG'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = dict()
|
||||
if parsed_args.force:
|
||||
body[_VNFFG] = dict()
|
||||
body[_VNFFG]['attributes'] = dict()
|
||||
body[_VNFFG]['attributes']['force'] = True
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
tacker_common_utils.deprecate_legacy_warning()
|
||||
client = self.app.client_manager.tackerclient
|
||||
failure = False
|
||||
deleted_ids = []
|
||||
failed_items = {}
|
||||
body = self.args2body(parsed_args)
|
||||
for resource_id in parsed_args.vnffg:
|
||||
try:
|
||||
obj = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, _VNFFG, resource_id)
|
||||
client.delete_vnffg(obj, body)
|
||||
deleted_ids.append(resource_id)
|
||||
except Exception as e:
|
||||
failure = True
|
||||
failed_items[resource_id] = e
|
||||
if failure:
|
||||
msg = ''
|
||||
if deleted_ids:
|
||||
msg = (_('Successfully deleted %(resource)s(s):'
|
||||
' %(deleted_list)s') % {'deleted_list':
|
||||
', '.join(deleted_ids),
|
||||
'resource': _VNFFG})
|
||||
err_msg = _("\n\nUnable to delete the below"
|
||||
" %s(s):") % _VNFFG
|
||||
for failed_id, error in failed_items.items():
|
||||
err_msg += (_('\n Cannot delete %(failed_id)s: %(error)s')
|
||||
% {'failed_id': failed_id,
|
||||
'error': error})
|
||||
msg += err_msg
|
||||
raise exceptions.CommandError(message=msg)
|
||||
else:
|
||||
print((_('All specified %(resource)s(s) deleted successfully')
|
||||
% {'resource': _VNFFG}))
|
||||
return
|
||||
|
||||
|
||||
class UpdateVNFFG(command.ShowOne):
|
||||
_description = _("Update VNFFG.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateVNFFG, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNFFG,
|
||||
metavar="<VNFFG>",
|
||||
help=_('VNFFG to update (name or ID)'))
|
||||
parser.add_argument(
|
||||
'--vnffgd-template',
|
||||
help=_('VNFFGD file to update VNFFG'))
|
||||
parser.add_argument(
|
||||
'--vnf-mapping',
|
||||
help=_('List of logical VNFD name to VNF instance name mapping. '
|
||||
'Example: VNF1:my_vnf1,VNF2:my_vnf2'))
|
||||
parser.add_argument(
|
||||
'--symmetrical',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Should a reverse path be created for the NFP'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help=_('Set a description for the VNFFG'))
|
||||
parser.add_argument(
|
||||
'--param-file',
|
||||
help=_('YAML file with specific VNFFG parameters'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {_VNFFG: {}}
|
||||
body[_VNFFG]['attributes'] = {}
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
|
||||
if parsed_args.vnf_mapping:
|
||||
_vnf_mapping = dict()
|
||||
_vnf_mappings = parsed_args.vnf_mapping.split(",")
|
||||
for mapping in _vnf_mappings:
|
||||
vnfd_name, vnf = mapping.split(":", 1)
|
||||
_vnf_mapping[vnfd_name] = \
|
||||
tackerV10.find_resourceid_by_name_or_id(
|
||||
client, 'vnf', vnf)
|
||||
parsed_args.vnf_mapping = _vnf_mapping
|
||||
|
||||
if parsed_args.vnffgd_template:
|
||||
with open(parsed_args.vnffgd_template) as f:
|
||||
template = f.read()
|
||||
try:
|
||||
template = yaml.load(
|
||||
template, Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
if not template:
|
||||
raise exceptions.InvalidInput(
|
||||
reason='The vnffgd file is empty')
|
||||
body[_VNFFG]['vnffgd_template'] = template
|
||||
|
||||
if parsed_args.param_file:
|
||||
with open(parsed_args.param_file) as f:
|
||||
param_yaml = f.read()
|
||||
try:
|
||||
param_yaml = yaml.load(
|
||||
param_yaml, Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
if not param_yaml:
|
||||
raise exceptions.InvalidInput(
|
||||
reason='The parameter file is empty')
|
||||
body[_VNFFG]['attributes'] = {'param_values': param_yaml}
|
||||
tackerV10.update_dict(parsed_args, body[_VNFFG],
|
||||
['vnf_mapping', 'symmetrical', 'description'])
|
||||
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)
|
||||
vnffg = client.update_vnffg(obj_id, self.args2body(parsed_args))
|
||||
display_columns, columns = _get_columns(vnffg[_VNFFG])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(vnffg[_VNFFG]),
|
||||
columns,
|
||||
formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ListVNFFG(command.Lister):
|
||||
_description = ("List VNFFG(s) that belong to a given tenant.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListVNFFG, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--long',
|
||||
action='store_true',
|
||||
help=_('List additional fields in output')
|
||||
)
|
||||
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(
|
||||
_attr_map_vnffg, long_listing=parsed_args.long)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_VNFFG + 's']))
|
||||
|
||||
|
||||
class ShowVNFFG(command.ShowOne):
|
||||
_description = _("Display VNFFG details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowVNFFG, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNFFG,
|
||||
metavar="<VNFFG>",
|
||||
help=_('VNFFG to display (name or ID)')
|
||||
)
|
||||
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)
|
||||
obj = client.show_vnffg(obj_id)
|
||||
display_columns, columns = _get_columns(obj[_VNFFG])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_VNFFG]),
|
||||
columns,
|
||||
formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ListNFP(command.Lister):
|
||||
_description = ("List NFP(s) that belong to a given tenant.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListNFP, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--vnffg-id',
|
||||
help=_('List NFP(s) with specific VNFFG ID'))
|
||||
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:
|
||||
_params['vnffg_id'] = parsed_args.vnffg_id
|
||||
nfps = client.list('nfps', nfps_path, True, **_params)
|
||||
for nfp in nfps['nfps']:
|
||||
error_reason = nfp.get('error_reason', None)
|
||||
if error_reason and \
|
||||
len(error_reason) > DEFAULT_ERROR_REASON_LENGTH:
|
||||
nfp['error_reason'] = error_reason[
|
||||
:DEFAULT_ERROR_REASON_LENGTH]
|
||||
nfp['error_reason'] += '...'
|
||||
data = {}
|
||||
data['nfps'] = nfps['nfps']
|
||||
data = client.list_nfps()
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
_attr_map_nfp, long_listing=None)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_NFP + 's']))
|
||||
|
||||
|
||||
class ShowNFP(command.ShowOne):
|
||||
_description = _("Display NFP details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowNFP, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_NFP,
|
||||
metavar="<NFP>",
|
||||
help=_('NFP to display (name or ID)')
|
||||
)
|
||||
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)
|
||||
obj = client.show_nfp(obj_id)
|
||||
display_columns, columns = _get_columns(obj[_NFP])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_NFP]),
|
||||
columns)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ListFC(command.Lister):
|
||||
_description = ("List flow classifier(s) that belong to a given tenant.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListFC, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--nfp-id',
|
||||
help=_('List flow classifier(s) with specific nfp id'))
|
||||
parser.add_argument(
|
||||
'--tenant-id', metavar='TENANT_ID',
|
||||
help=_('The owner tenant ID or project ID'))
|
||||
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:
|
||||
_params['nfp_id'] = parsed_args.nfp_id
|
||||
if parsed_args.tenant_id:
|
||||
_params['tenant_id'] = parsed_args.tenant_id
|
||||
classifiers = client.list('classifiers', fcs_path, True,
|
||||
**_params)
|
||||
for classifier in classifiers['classifiers']:
|
||||
error_reason = classifier.get('error_reason', None)
|
||||
if error_reason and \
|
||||
len(error_reason) > DEFAULT_ERROR_REASON_LENGTH:
|
||||
classifier['error_reason'] = error_reason[
|
||||
:DEFAULT_ERROR_REASON_LENGTH]
|
||||
classifier['error_reason'] += '...'
|
||||
data = {}
|
||||
data['classifiers'] = classifiers['classifiers']
|
||||
data = client.list_classifiers()
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
_attr_map_fc, long_listing=None)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_FC + 's']))
|
||||
|
||||
|
||||
class ShowFC(command.ShowOne):
|
||||
_description = _("Display flow classifier details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowFC, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_FC,
|
||||
metavar="<Classifier ID>",
|
||||
help=_('Flow Classifier to display (name or ID)')
|
||||
)
|
||||
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)
|
||||
obj = client.show_classifier(obj_id)
|
||||
display_columns, columns = _get_columns(obj[_FC])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_FC]),
|
||||
columns,
|
||||
formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ListSFC(command.Lister):
|
||||
_description = ("List SFC(s) that belong to a given tenant.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListSFC, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--nfp-id',
|
||||
help=_('List SFC(s) with specific nfp id'))
|
||||
parser.add_argument(
|
||||
'--tenant-id', metavar='TENANT_ID',
|
||||
help=_('The owner tenant ID or project ID'))
|
||||
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:
|
||||
_params['nfp_id'] = parsed_args.nfp_id
|
||||
if parsed_args.tenant_id:
|
||||
_params['tenant_id'] = parsed_args.tenant_id
|
||||
sfcs = client.list('sfcs', sfcs_path, True, **_params)
|
||||
for chain in sfcs['sfcs']:
|
||||
error_reason = chain.get('error_reason', None)
|
||||
if error_reason and \
|
||||
len(error_reason) > DEFAULT_ERROR_REASON_LENGTH:
|
||||
chain['error_reason'] = error_reason[
|
||||
:DEFAULT_ERROR_REASON_LENGTH]
|
||||
chain['error_reason'] += '...'
|
||||
data = {}
|
||||
data['sfcs'] = sfcs['sfcs']
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
_attr_map_sfc, long_listing=None)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_SFC + 's']))
|
||||
|
||||
|
||||
class ShowSFC(command.ShowOne):
|
||||
_description = _("Display SFC details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowSFC, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_SFC,
|
||||
metavar="<SFC>",
|
||||
help=_('SFC to display (name or ID)')
|
||||
)
|
||||
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)
|
||||
obj = client.show_sfc(obj_id)
|
||||
display_columns, columns = _get_columns(obj[_SFC])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_SFC]),
|
||||
columns,
|
||||
formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
@@ -1,223 +0,0 @@
|
||||
# Copyright 2018 OpenStack Foundation.
|
||||
# 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 yaml
|
||||
|
||||
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
|
||||
from tackerclient.tacker import v1_0 as tackerV10
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('name', 'Name', tacker_osc_utils.LIST_BOTH),
|
||||
('template_source', 'Template_Source',
|
||||
tacker_osc_utils.LIST_BOTH),
|
||||
('description', 'Description', tacker_osc_utils.LIST_BOTH),
|
||||
)
|
||||
|
||||
_VNFFGD = "vnffgd"
|
||||
|
||||
_formatters = {
|
||||
'template': tacker_osc_utils.format_dict_with_indention,
|
||||
}
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
column_map = {
|
||||
'tenant_id': 'project_id',
|
||||
}
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||
|
||||
|
||||
class CreateVNFFGD(command.ShowOne):
|
||||
_description = _("Create a new VNFFGD")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateVNFFGD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'name', metavar='NAME',
|
||||
help=_('Name for VNFFGD'))
|
||||
parser.add_argument(
|
||||
'--tenant-id', metavar='TENANT_ID',
|
||||
help=_('The owner tenant ID or project ID'))
|
||||
parser.add_argument(
|
||||
'--vnffgd-file',
|
||||
required=True,
|
||||
help=_('YAML file with VNFFGD parameters'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help=_('Set a description for the VNFFGD'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {_VNFFGD: {}}
|
||||
vnffgd = None
|
||||
if not parsed_args.vnffgd_file:
|
||||
raise exceptions.InvalidInput(
|
||||
reason="Invalid input for vnffgd file")
|
||||
with open(parsed_args.vnffgd_file) as f:
|
||||
vnffgd = f.read()
|
||||
try:
|
||||
vnffgd = yaml.load(vnffgd, Loader=yaml.SafeLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
if not vnffgd:
|
||||
raise exceptions.InvalidInput(reason="vnffgd file is empty")
|
||||
body[_VNFFGD]['template'] = {'vnffgd': vnffgd}
|
||||
tackerV10.update_dict(parsed_args, body[_VNFFGD],
|
||||
['tenant_id', 'name', 'description'])
|
||||
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])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(vnffgd[_VNFFGD]),
|
||||
columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class DeleteVNFFGD(command.Command):
|
||||
_description = _("Delete VNFFGD(s).")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteVNFFGD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNFFGD,
|
||||
metavar="<VNFFGD>",
|
||||
nargs="+",
|
||||
help=_("VNFFGD(s) to delete (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
tacker_common_utils.deprecate_legacy_warning()
|
||||
client = self.app.client_manager.tackerclient
|
||||
failure = False
|
||||
deleted_ids = []
|
||||
failed_items = {}
|
||||
for resource_id in parsed_args.vnffgd:
|
||||
try:
|
||||
obj = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, _VNFFGD, resource_id)
|
||||
client.delete_vnffgd(obj)
|
||||
deleted_ids.append(resource_id)
|
||||
except Exception as e:
|
||||
failure = True
|
||||
failed_items[resource_id] = e
|
||||
if failure:
|
||||
msg = ''
|
||||
if deleted_ids:
|
||||
msg = (_('Successfully deleted %(resource)s(s):'
|
||||
' %(deleted_list)s') % {'deleted_list':
|
||||
', '.join(deleted_ids),
|
||||
'resource': _VNFFGD})
|
||||
err_msg = _("\n\nUnable to delete the below"
|
||||
" %s(s):") % _VNFFGD
|
||||
for failed_id, error in failed_items.items():
|
||||
err_msg += (_('\n Cannot delete %(failed_id)s: %(error)s')
|
||||
% {'failed_id': failed_id,
|
||||
'error': error})
|
||||
msg += err_msg
|
||||
raise exceptions.CommandError(message=msg)
|
||||
else:
|
||||
print((_('All specified %(resource)s(s) deleted successfully')
|
||||
% {'resource': _VNFFGD}))
|
||||
return
|
||||
|
||||
|
||||
class ListVNFFGD(command.Lister):
|
||||
_description = ("List (VNFFGD)s that belong to a given tenant.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListVNFFGD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--template-source',
|
||||
help=_("List VNFFGD with specified template source. Available \
|
||||
options are 'onboarded' (default), 'inline' or 'all'"),
|
||||
action='store',
|
||||
default='onboarded')
|
||||
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(
|
||||
_attr_map, long_listing=None)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[_VNFFGD + 's']))
|
||||
|
||||
|
||||
class ShowVNFFGD(command.ShowOne):
|
||||
_description = _("Display VNFFGD details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowVNFFGD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNFFGD,
|
||||
metavar="<VNFFGD>",
|
||||
help=_("VNFFGD to display (name or ID)")
|
||||
)
|
||||
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)
|
||||
obj = client.show_vnffgd(obj_id)
|
||||
display_columns, columns = _get_columns(obj[_VNFFGD])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_VNFFGD]),
|
||||
columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ShowTemplateVNFFGD(command.ShowOne):
|
||||
_description = _("Display VNFFGD Template details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowTemplateVNFFGD, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNFFGD,
|
||||
metavar="<VNFFGD>",
|
||||
help=_("VNFFGD to display (name or ID)")
|
||||
)
|
||||
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)
|
||||
obj = client.show_vnffgd(obj_id)
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_VNFFGD]),
|
||||
('template',),
|
||||
formatters=_formatters)
|
||||
data = (data or _('Unable to display VNFFGD template!'))
|
||||
return (('template',), data)
|
||||
@@ -1,69 +0,0 @@
|
||||
{
|
||||
"extVirtualLinks": [
|
||||
{
|
||||
"id": "ext-vl-uuid-VL1",
|
||||
"resourceId": "neutron-network-uuid_VL1",
|
||||
"extCps": [
|
||||
{
|
||||
"cpdId": "CP1",
|
||||
"cpConfig": [
|
||||
{
|
||||
"cpProtocolData": [
|
||||
{
|
||||
"layerProtocol": "IP_OVER_ETHERNET",
|
||||
"ipOverEthernet": {
|
||||
"ipAddresses": [
|
||||
{
|
||||
"type": "IPV4",
|
||||
"numDynamicAddresses": 1,
|
||||
"subnetId": "subnet-uuid"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cpdId": "CP2",
|
||||
"cpConfig": [
|
||||
{
|
||||
"cpProtocolData": [
|
||||
{
|
||||
"layerProtocol": "IP_OVER_ETHERNET",
|
||||
"ipOverEthernet": {
|
||||
"ipAddresses": [
|
||||
{
|
||||
"type": "IPV4",
|
||||
"fixedAddresses": [
|
||||
"10.0.0.1"
|
||||
],
|
||||
"subnetId": "subnet-uuid"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vimConnectionInfo": [
|
||||
{
|
||||
"id": "vim-uuid",
|
||||
"vimType": "ETSINFV.OPENSTACK_KEYSTONE.v_2",
|
||||
"vimConnectionId": "dummy-vimid",
|
||||
"interfaceInfo": {
|
||||
"key1":"value1",
|
||||
"key2":"value2"
|
||||
},
|
||||
"accessInfo": {
|
||||
"key1":"value1",
|
||||
"key2":"value2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"additionalParams": {"all": true}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"flavourId":"simple",
|
||||
"instantiationLevelId":"instantiation_level_1",
|
||||
"extVirtualLinks":[
|
||||
{
|
||||
"id":"ext-vl-uuid-VL1",
|
||||
"vimConnectionId":"vim-uuid",
|
||||
"resourceProviderId":"resource-provider-id",
|
||||
"resourceId":"neutron-network-uuid_VL1",
|
||||
"extCps":[
|
||||
{
|
||||
"cpdId":"CP1",
|
||||
"cpConfig":[
|
||||
{
|
||||
"cpInstanceId":"cp-instance-id",
|
||||
"linkPortId":"link-port-uuid_CP1",
|
||||
"cpProtocolData":[
|
||||
{
|
||||
"layerProtocol":"IP_OVER_ETHERNET",
|
||||
"ipOverEthernet":{
|
||||
"macAddress":"00:25:96:FF:FE:12:34:56",
|
||||
"ipAddresses":[
|
||||
{
|
||||
"addressRange":{
|
||||
"minAddress":"192.168.11.01",
|
||||
"maxAddress":"192.168.21.201"
|
||||
},
|
||||
"subnetId":"neutron-subnet-uuid_CP1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"extLinkPorts":[
|
||||
{
|
||||
"id":"link-port-uuid_CP1",
|
||||
"resourceHandle":{
|
||||
"vimConnectionId":"vim-uuid",
|
||||
"resourceProviderId":"resource-provider-id",
|
||||
"resourceId":"neutron-port-uuid_CP1",
|
||||
"vimLevelResourceType":"LINKPORT"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"extManagedVirtualLinks":[
|
||||
{
|
||||
"id":"extMngVLnk-uuid_VL3",
|
||||
"vnfVirtualLinkDescId":"VL3",
|
||||
"vimConnectionId":"vim-uuid",
|
||||
"resourceProviderId":"resource-provider-id",
|
||||
"resourceId":"neutron-network-uuid_VL3"
|
||||
}
|
||||
],
|
||||
"vimConnectionInfo":[
|
||||
{
|
||||
"id":"vim-uuid",
|
||||
"vimId":"dummy-vimid",
|
||||
"vimType":"ETSINFV.OPENSTACK_KEYSTONE.v_2",
|
||||
"interfaceInfo":{
|
||||
"key1":"value1",
|
||||
"key2":"value2"
|
||||
},
|
||||
"accessInfo":{
|
||||
"key1":"value1",
|
||||
"key2":"value2"
|
||||
},
|
||||
"extra":{
|
||||
"key1":"value1",
|
||||
"key2":"value2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"additionalParams": {"key1":"value1", "key2":"value2"}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"vnfInstanceName": "sample",
|
||||
"vnfInstanceDescription" : "sample_description",
|
||||
"vnfdId" : "sample_id"
|
||||
}
|
||||
@@ -1,585 +0,0 @@
|
||||
# Copyright (C) 2020 NTT DATA
|
||||
# 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
|
||||
import time
|
||||
|
||||
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
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', tacker_osc_utils.LIST_BOTH),
|
||||
('vnfInstanceName', 'VNF Instance Name', tacker_osc_utils.LIST_BOTH),
|
||||
('instantiationState', 'Instantiation State', tacker_osc_utils.LIST_BOTH),
|
||||
('vnfProvider', 'VNF Provider', tacker_osc_utils.LIST_BOTH),
|
||||
('vnfSoftwareVersion', 'VNF Software Version', tacker_osc_utils.LIST_BOTH),
|
||||
('vnfProductName', 'VNF Product Name', tacker_osc_utils.LIST_BOTH),
|
||||
('vnfdId', 'VNFD ID', tacker_osc_utils.LIST_BOTH)
|
||||
)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
_mixed_case_fields = ('vnfInstanceName', 'vnfInstanceDescription', 'vnfdId',
|
||||
'vnfProvider', 'vnfProductName', 'vnfSoftwareVersion',
|
||||
'vnfdVersion', 'instantiationState',
|
||||
'vimConnectionInfo', 'instantiatedVnfInfo',
|
||||
'vnfConfigurableProperties')
|
||||
|
||||
_VNF_INSTANCE = 'vnf_instance'
|
||||
|
||||
VNF_INSTANCE_TERMINATION_TIMEOUT = 300
|
||||
|
||||
EXTRA_WAITING_TIME = 10
|
||||
|
||||
SLEEP_TIME = 1
|
||||
|
||||
formatters = {'vimConnectionInfo': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'instantiatedVnfInfo': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'_links': tacker_osc_utils.FormatComplexDataColumn}
|
||||
|
||||
|
||||
def _get_columns(vnflcm_obj, action=None):
|
||||
column_map = {
|
||||
'id': 'ID',
|
||||
'vnfInstanceName': 'VNF Instance Name',
|
||||
'vnfInstanceDescription': 'VNF Instance Description',
|
||||
'vnfdId': 'VNFD ID',
|
||||
'vnfProvider': 'VNF Provider',
|
||||
'vnfProductName': 'VNF Product Name',
|
||||
'vnfSoftwareVersion': 'VNF Software Version',
|
||||
'vnfdVersion': 'VNFD Version',
|
||||
'instantiationState': 'Instantiation State',
|
||||
'_links': 'Links',
|
||||
'vnfConfigurableProperties': 'VNF Configurable Properties',
|
||||
}
|
||||
if action == 'show':
|
||||
if vnflcm_obj['instantiationState'] == 'INSTANTIATED':
|
||||
column_map.update(
|
||||
{'instantiatedVnfInfo': 'Instantiated Vnf Info'}
|
||||
)
|
||||
column_map.update(
|
||||
{'vimConnectionInfo': 'VIM Connection Info',
|
||||
'_links': 'Links'}
|
||||
)
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(vnflcm_obj,
|
||||
column_map)
|
||||
|
||||
|
||||
class CreateVnfLcm(command.ShowOne):
|
||||
_description = _("Create a new VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'vnfd_id',
|
||||
metavar="<vnfd-id>",
|
||||
help=_('Identifier that identifies the VNFD which defines the '
|
||||
'VNF instance to be created.'))
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
metavar="<vnf-instance-name>",
|
||||
help=_('Name of the VNF instance to be created.'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar="<vnf-instance-description>",
|
||||
help=_('Description of the VNF instance to be created.'))
|
||||
parser.add_argument(
|
||||
'--I',
|
||||
metavar="<param-file>",
|
||||
help=_("Instantiate VNF subsequently after it's creation. "
|
||||
"Specify instantiate request parameters in a json file."))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args, file_path=None):
|
||||
body = {}
|
||||
|
||||
if file_path:
|
||||
return tacker_osc_utils.jsonfile2body(file_path)
|
||||
|
||||
body['vnfdId'] = parsed_args.vnfd_id
|
||||
|
||||
if parsed_args.description:
|
||||
body['vnfInstanceDescription'] = parsed_args.description
|
||||
|
||||
if parsed_args.name:
|
||||
body['vnfInstanceName'] = parsed_args.name
|
||||
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnf = client.create_vnf_instance(self.args2body(parsed_args))
|
||||
if parsed_args.I:
|
||||
# Instantiate VNF instance.
|
||||
result = client.instantiate_vnf_instance(
|
||||
vnf['id'],
|
||||
self.args2body(parsed_args, file_path=parsed_args.I))
|
||||
if not result:
|
||||
print((_('VNF Instance %(id)s is created and instantiation'
|
||||
' request has been accepted.') % {'id': vnf['id']}))
|
||||
display_columns, columns = _get_columns(vnf)
|
||||
data = utils.get_item_properties(sdk_utils.DictModel(vnf),
|
||||
columns, formatters=formatters,
|
||||
mixed_case_fields=_mixed_case_fields)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class ShowVnfLcm(command.ShowOne):
|
||||
_description = _("Display VNF instance details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_("VNF instance ID to display"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.show_vnf_instance(parsed_args.vnf_instance)
|
||||
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 ListVnfLcm(command.Lister):
|
||||
_description = _("List VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListVnfLcm, self).get_parser(prog_name)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
_params = {}
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnf_instances = client.list_vnf_instances(**_params)
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
_attr_map, long_listing=True)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns, mixed_case_fields=_mixed_case_fields,
|
||||
) for s in vnf_instances))
|
||||
|
||||
|
||||
class InstantiateVnfLcm(command.Command):
|
||||
_description = _("Instantiate a VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(InstantiateVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_("VNF instance ID to instantiate"))
|
||||
parser.add_argument(
|
||||
'instantiation_request_file',
|
||||
metavar="<param-file>",
|
||||
help=_('Specify instantiate request parameters in a json file.'))
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.instantiate_vnf_instance(
|
||||
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'
|
||||
' accepted.') % {'id': parsed_args.vnf_instance}))
|
||||
|
||||
|
||||
class HealVnfLcm(command.Command):
|
||||
_description = _("Heal VNF Instance")
|
||||
|
||||
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>",
|
||||
help=_("VNF instance ID to heal"))
|
||||
parser.add_argument(
|
||||
'--cause',
|
||||
help=_('Specify the reason why a healing procedure is required.'))
|
||||
parser.add_argument(
|
||||
'--vnfc-instance',
|
||||
metavar="<vnfc-instance-id>",
|
||||
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):
|
||||
body = {}
|
||||
if parsed_args.cause:
|
||||
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
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.heal_vnf_instance(
|
||||
parsed_args.vnf_instance, self.args2body(parsed_args))
|
||||
if not result:
|
||||
print((_('Heal request for VNF Instance %(id)s has been'
|
||||
' accepted.') % {'id': parsed_args.vnf_instance}))
|
||||
|
||||
|
||||
class TerminateVnfLcm(command.Command):
|
||||
_description = _("Terminate a VNF instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(TerminateVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_("VNF instance ID to terminate"))
|
||||
parser.add_argument(
|
||||
"--termination-type",
|
||||
default='GRACEFUL',
|
||||
metavar="<termination-type>",
|
||||
choices=['GRACEFUL', 'FORCEFUL'],
|
||||
help=_("Termination type can be 'GRACEFUL' or 'FORCEFUL'. "
|
||||
"Default is 'GRACEFUL'"))
|
||||
parser.add_argument(
|
||||
'--graceful-termination-timeout',
|
||||
metavar="<graceful-termination-timeout>",
|
||||
type=int,
|
||||
help=_('This attribute is only applicable in case of graceful '
|
||||
'termination. It defines the time to wait for the VNF to be'
|
||||
' taken out of service before shutting down the VNF and '
|
||||
'releasing the resources. The unit is seconds.'))
|
||||
parser.add_argument(
|
||||
'--D',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Delete VNF Instance subsequently after it's termination"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {}
|
||||
body['terminationType'] = parsed_args.termination_type
|
||||
|
||||
if parsed_args.graceful_termination_timeout:
|
||||
if parsed_args.termination_type == 'FORCEFUL':
|
||||
exceptions.InvalidInput(reason='--graceful-termination-timeout'
|
||||
' argument is invalid for "FORCEFUL"'
|
||||
' termination')
|
||||
body['gracefulTerminationTimeout'] = parsed_args.\
|
||||
graceful_termination_timeout
|
||||
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.terminate_vnf_instance(parsed_args.vnf_instance,
|
||||
self.args2body(parsed_args))
|
||||
if not result:
|
||||
print(_("Terminate request for VNF Instance '%(id)s' has been"
|
||||
" accepted.") % {'id': parsed_args.vnf_instance})
|
||||
if parsed_args.D:
|
||||
print(_("Waiting for vnf instance to be terminated before "
|
||||
"deleting"))
|
||||
|
||||
self._wait_until_vnf_is_terminated(
|
||||
client, parsed_args.vnf_instance,
|
||||
graceful_timeout=parsed_args.graceful_termination_timeout)
|
||||
|
||||
result = client.delete_vnf_instance(parsed_args.vnf_instance)
|
||||
if not result:
|
||||
print(_("VNF Instance '%(id)s' is deleted successfully") %
|
||||
{'id': parsed_args.vnf_instance})
|
||||
|
||||
def _wait_until_vnf_is_terminated(self, client, vnf_instance_id,
|
||||
graceful_timeout=None):
|
||||
# wait until vnf instance 'instantiationState' is set to
|
||||
# 'NOT_INSTANTIATED'
|
||||
if graceful_timeout:
|
||||
# If graceful_termination_timeout is provided,
|
||||
# terminate vnf will start after this timeout period.
|
||||
# Hence, it should wait for extra time of 10 seconds
|
||||
# after this graceful_termination_timeout period.
|
||||
timeout = graceful_timeout + EXTRA_WAITING_TIME
|
||||
else:
|
||||
timeout = VNF_INSTANCE_TERMINATION_TIMEOUT
|
||||
|
||||
start_time = int(time.time())
|
||||
while True:
|
||||
vnf_instance = client.show_vnf_instance(vnf_instance_id)
|
||||
if vnf_instance['instantiationState'] == 'NOT_INSTANTIATED':
|
||||
break
|
||||
|
||||
if ((int(time.time()) - start_time) > timeout):
|
||||
msg = _("Couldn't verify vnf instance is terminated within "
|
||||
"'%(timeout)s' seconds. Unable to delete vnf instance "
|
||||
"%(id)s")
|
||||
raise exceptions.CommandError(
|
||||
message=msg % {'timeout': timeout, 'id': vnf_instance_id})
|
||||
time.sleep(SLEEP_TIME)
|
||||
|
||||
|
||||
class DeleteVnfLcm(command.Command):
|
||||
"""Vnf lcm delete
|
||||
|
||||
DeleteVnfLcm class supports bulk deletion of vnf instances, and error
|
||||
handling.
|
||||
"""
|
||||
|
||||
_description = _("Delete VNF Instance(s)")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'vnf_instances',
|
||||
metavar="<vnf-instance>",
|
||||
nargs="+",
|
||||
help=_("VNF instance ID(s) to delete"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
error_count = 0
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnf_instances = parsed_args.vnf_instances
|
||||
for vnf_instance in vnf_instances:
|
||||
try:
|
||||
client.delete_vnf_instance(vnf_instance)
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
LOG.error(_("Failed to delete vnf instance with "
|
||||
"ID '%(vnf)s': %(e)s"),
|
||||
{'vnf': vnf_instance, 'e': e})
|
||||
|
||||
total = len(vnf_instances)
|
||||
if (error_count > 0):
|
||||
msg = (_("Failed to delete %(error_count)s of %(total)s "
|
||||
"vnf instances.") % {'error_count': error_count,
|
||||
'total': total})
|
||||
raise exceptions.CommandError(message=msg)
|
||||
else:
|
||||
if total > 1:
|
||||
print(_('All specified vnf instances are deleted '
|
||||
'successfully'))
|
||||
else:
|
||||
print(_("Vnf instance '%s' is deleted "
|
||||
"successfully") % vnf_instances[0])
|
||||
|
||||
|
||||
class UpdateVnfLcm(command.Command):
|
||||
_description = _("Update VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
prog_name ([string]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]): [description]
|
||||
"""
|
||||
parser = super(UpdateVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_('VNF instance ID to update.'))
|
||||
parser.add_argument(
|
||||
'--I',
|
||||
metavar="<param-file>",
|
||||
help=_("Specify update request parameters in a json file."))
|
||||
|
||||
return parser
|
||||
|
||||
def args2body(self, file_path=None):
|
||||
"""Call jsonfile2body to store request body to body(dict)
|
||||
|
||||
Args:
|
||||
file_path ([string], optional): file path of param file(json).
|
||||
Defaults to None.
|
||||
|
||||
Returns:
|
||||
body ([dict]): Request body is stored
|
||||
"""
|
||||
body = {}
|
||||
|
||||
if file_path:
|
||||
return tacker_osc_utils.jsonfile2body(file_path)
|
||||
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute update_vnf_instance and output result comment
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): [description]
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
if parsed_args.I:
|
||||
# Update VNF instance.
|
||||
result = client.update_vnf_instance(
|
||||
parsed_args.vnf_instance,
|
||||
self.args2body(file_path=parsed_args.I))
|
||||
if not result:
|
||||
print((_('Update vnf:%(id)s ') %
|
||||
{'id': parsed_args.vnf_instance}))
|
||||
|
||||
|
||||
class ScaleVnfLcm(command.Command):
|
||||
_description = _("Scale a VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ScaleVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_('VNF instance ID to scale'))
|
||||
parser.add_argument(
|
||||
'--number-of-steps',
|
||||
metavar="<number-of-steps>",
|
||||
type=int,
|
||||
help=_("Number of scaling steps to be executed as part of "
|
||||
"this Scale VNF operation."))
|
||||
parser.add_argument(
|
||||
'--additional-param-file',
|
||||
metavar="<additional-param-file>",
|
||||
help=_("Additional parameters passed by the NFVO as input "
|
||||
"to the scaling process."))
|
||||
|
||||
scale_require_parameters = parser.add_argument_group(
|
||||
"require arguments"
|
||||
)
|
||||
scale_require_parameters.add_argument(
|
||||
'--type',
|
||||
metavar="<type>",
|
||||
required=True,
|
||||
choices=['SCALE_OUT', 'SCALE_IN'],
|
||||
help=_("SCALE_OUT or SCALE_IN for type of scale operation."))
|
||||
scale_require_parameters.add_argument(
|
||||
'--aspect-id',
|
||||
required=True,
|
||||
metavar="<aspect-id>",
|
||||
help=_("Identifier of the scaling aspect."))
|
||||
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
"""To store request body, call jsonfile2body.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
|
||||
Returns:
|
||||
body ([dict]): Request body is stored
|
||||
"""
|
||||
body = {'type': parsed_args.type, 'aspectId': parsed_args.aspect_id}
|
||||
|
||||
if parsed_args.number_of_steps:
|
||||
body['numberOfSteps'] = parsed_args.number_of_steps
|
||||
|
||||
if parsed_args.additional_param_file:
|
||||
body.update(tacker_osc_utils.jsonfile2body(
|
||||
parsed_args.additional_param_file))
|
||||
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute scale_vnf_instance and output result comment.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.scale_vnf_instance(
|
||||
parsed_args.vnf_instance,
|
||||
self.args2body(parsed_args))
|
||||
if not result:
|
||||
print((_('Scale request for VNF Instance %s has been accepted.')
|
||||
% parsed_args.vnf_instance))
|
||||
|
||||
|
||||
class ChangeExtConnVnfLcm(command.Command):
|
||||
_description = _("Change External VNF Connectivity")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ChangeExtConnVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_("VNF instance ID to Change External VNF Connectivity"))
|
||||
parser.add_argument(
|
||||
'request_file',
|
||||
metavar="<param-file>",
|
||||
help=_("Specify change-ext-conn request parameters "
|
||||
"in a json file."))
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.change_ext_conn_vnf_instance(
|
||||
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))
|
||||
@@ -1,353 +0,0 @@
|
||||
# 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 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
|
||||
|
||||
_VNF_LCM_OP_OCC_ID = 'vnf_lcm_op_occ_id'
|
||||
|
||||
_MIXED_CASE_FIELDS = ['operationState', 'stateEnteredTime', 'startTime',
|
||||
'vnfInstanceId', 'grantId', 'isAutomaticInvocation',
|
||||
'isCancelPending', 'cancelMode', 'operationParams',
|
||||
'resourceChanges', 'changedInfo',
|
||||
'changedExtConnectivity']
|
||||
|
||||
_FORMATTERS = {
|
||||
'operationParams': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'error': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'resourceChanges': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'changedInfo': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'changedExtConnectivity': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'_links': tacker_osc_utils.FormatComplexDataColumn
|
||||
}
|
||||
|
||||
_ATTR_MAP = (
|
||||
('id', 'id', tacker_osc_utils.LIST_BOTH),
|
||||
('operationState', 'operationState', tacker_osc_utils.LIST_BOTH),
|
||||
('vnfInstanceId', 'vnfInstanceId', tacker_osc_utils.LIST_BOTH),
|
||||
('operation', 'operation', tacker_osc_utils.LIST_BOTH)
|
||||
)
|
||||
|
||||
|
||||
def _get_columns(vnflcm_op_occ_obj, action=None):
|
||||
|
||||
column_map = {
|
||||
'id': 'ID',
|
||||
'operationState': 'Operation State',
|
||||
'stateEnteredTime': 'State Entered Time',
|
||||
'startTime': 'Start Time',
|
||||
'vnfInstanceId': 'VNF Instance ID',
|
||||
'operation': 'Operation',
|
||||
'isAutomaticInvocation': 'Is Automatic Invocation',
|
||||
'isCancelPending': 'Is Cancel Pending',
|
||||
'error': 'Error',
|
||||
'_links': 'Links'
|
||||
}
|
||||
|
||||
if action == 'show':
|
||||
column_map.update(
|
||||
{'operationParams': 'Operation Parameters',
|
||||
'grantId': 'Grant ID',
|
||||
'resourceChanges': 'Resource Changes',
|
||||
'changedInfo': 'Changed Info',
|
||||
'cancelMode': 'Cancel Mode',
|
||||
'changedExtConnectivity': 'Changed External Connectivity'}
|
||||
)
|
||||
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(vnflcm_op_occ_obj,
|
||||
column_map)
|
||||
|
||||
|
||||
class RollbackVnfLcmOp(command.Command):
|
||||
def get_parser(self, prog_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
prog_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(RollbackVnfLcmOp, 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.'))
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute rollback_vnf_instance and output comment.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.rollback_vnf_instance(parsed_args.vnf_lcm_op_occ_id)
|
||||
if not result:
|
||||
print((_('Rollback request for LCM operation %(id)s has been'
|
||||
' 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")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
prog_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(FailVnfLcmOp, 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.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute fail_vnf_instance and output response.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.fail_vnf_instance(parsed_args.vnf_lcm_op_occ_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)
|
||||
|
||||
|
||||
class RetryVnfLcmOp(command.Command):
|
||||
_description = _("Retry VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
prog_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
|
||||
parser = super(RetryVnfLcmOp, 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.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute retry_vnf_instance and output comment.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.retry_vnf_instance(parsed_args.vnf_lcm_op_occ_id)
|
||||
if not result:
|
||||
print((_('Retry request for LCM operation %(id)s has been'
|
||||
' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id}))
|
||||
|
||||
|
||||
class ListVnfLcmOp(command.Lister):
|
||||
_description = _("List LCM Operation Occurrences")
|
||||
|
||||
def get_parser(self, program_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
program_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(ListVnfLcmOp, self).get_parser(program_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(
|
||||
"--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"),
|
||||
)
|
||||
return parser
|
||||
|
||||
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
|
||||
(API attribute name, header name, listing mode).
|
||||
"""
|
||||
fields = [
|
||||
{
|
||||
"key": "id",
|
||||
"value": "ID"
|
||||
},
|
||||
{
|
||||
"key": "operationState",
|
||||
"value": "Operation State"
|
||||
},
|
||||
{
|
||||
"key": "vnfInstanceId",
|
||||
"value": "VNF Instance ID"
|
||||
},
|
||||
{
|
||||
"key": "operation",
|
||||
"value": "Operation"
|
||||
}
|
||||
]
|
||||
|
||||
attributes = []
|
||||
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):
|
||||
"""Execute list_vnflcm_op_occs and output response.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
params = {}
|
||||
exclude_fields = []
|
||||
extra_fields = []
|
||||
|
||||
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)
|
||||
|
||||
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(exclude=exclude_fields),
|
||||
long_listing=True)
|
||||
|
||||
dictionary_properties = (utils.get_dict_properties(
|
||||
s, columns, mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
for s in vnflcm_op_occs
|
||||
)
|
||||
|
||||
return (headers, dictionary_properties)
|
||||
|
||||
|
||||
class ShowVnfLcmOp(command.ShowOne):
|
||||
_description = _("Display Operation Occurrence details")
|
||||
|
||||
def get_parser(self, program_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
program_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(ShowVnfLcmOp, self).get_parser(program_name)
|
||||
parser.add_argument(
|
||||
_VNF_LCM_OP_OCC_ID,
|
||||
metavar="<vnf-lcm-op-occ-id>",
|
||||
help=_('VNF lifecycle management operation occurrence ID.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute show_vnf_lcm_op_occs and output response.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.show_vnf_lcm_op_occs(parsed_args.vnf_lcm_op_occ_id)
|
||||
display_columns, columns = _get_columns(obj, action='show')
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj),
|
||||
columns, formatters=_FORMATTERS,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
return (display_columns, data)
|
||||
@@ -1,181 +0,0 @@
|
||||
# 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)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user