Compare commits

..

8 Commits

Author SHA1 Message Date
Sridhar Ramaswamy
7b93e46dfc Add default branch to stable/liberty
Change-Id: Ib9dbe5687db90fe4628ca0f8fc8b7ac44e57c93e
2016-03-10 20:57:28 +00:00
Martin Oemke
ec0629c98e Clean up references to neutron
Remove references to neutron project in tackerclient
doc and conf files.

Change-Id: I66a7479a5c12c49f82af0cbff197d6b9976a87c6
Closes-Bug: #1553715
(cherry picked from commit 80220f372b)
2016-03-10 20:22:41 +00:00
gong yong sheng
9399c8de37 Fix summary and author in setup.cfg
Change-Id: I5bae09865b4af368efe638fa831d90d2142cb9d0
(cherry picked from commit 633848c21a)
2016-03-10 20:03:18 +00:00
Jenkins
23e759da36 Merge "Deprecating "device" API and CLI in stable/liberty branch" into stable/liberty 2016-03-02 01:42:38 +00:00
dharmendra kushwaha
16c31a29ff Deprecating "device" API and CLI in stable/liberty branch
Change-Id: Ideb8a9830fa183a648dd1407b55dd06cd1f436dd
Related-Bug: #1543393
Depends-On: I8052d9d683a1a2e80d8c160c70d2ea8f8b7240cd
2016-03-01 10:45:35 +00:00
Jenkins
e584661305 Merge "update requirements according to global requ" into stable/liberty 2016-02-18 17:08:39 +00:00
yong sheng gong
fd38742d52 update requirements according to global requ
This patch updates the requirements in stable/liberty branch
of tacker according to global requirements in stable/liberty

Change-Id: I816f4a7a0459c4850696e09911eef3493e956647
Partial-Bug: #1543396
Depends-On: I8052d9d683a1a2e80d8c160c70d2ea8f8b7240cd
2016-02-17 11:56:44 +00:00
gong yong sheng
13ab0b98dd Remove service instance related stuff and fix unittests
Change-Id: I8052d9d683a1a2e80d8c160c70d2ea8f8b7240cd
Closes-bug: #1545595
(cherry picked from commit f342ea9c7a)
2016-02-17 08:48:17 +00:00
241 changed files with 2776 additions and 23345 deletions

5
.gitignore vendored
View File

@@ -17,10 +17,5 @@ run_tests.log
.autogenerated
.coverage
.testrepository/
.idea/
.tox/
.venv/
.stestr/
# Files created by releasenotes build
releasenotes/build

View File

@@ -1,4 +1,5 @@
[gerrit]
host=review.opendev.org
host=review.openstack.org
port=29418
project=openstack/python-tackerclient.git
defaultbranch=stable/liberty

View File

@@ -1,3 +0,0 @@
[DEFAULT]
test_path=./tackerclient/tests/unit
top_path=./

4
.testr.conf Normal file
View 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

View File

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

View File

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

View File

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

View File

@@ -1,69 +1 @@
========================
Team and repository tags
========================
.. image:: https://governance.openstack.org/tc/badges/python-tackerclient.svg
:target: https://governance.openstack.org/tc/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.

View File

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

View File

@@ -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.

View File

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

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *

View File

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

View File

@@ -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 *

View File

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

View File

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

View File

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

View File

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

View File

@@ -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:8888/
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.

View File

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

View File

@@ -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/>`_

7
openstack-common.conf Normal file
View File

@@ -0,0 +1,7 @@
[DEFAULT]
# The list of modules to copy from openstack-common
modules=gettextutils,jsonutils,strutils,timeutils
# The base module to hold the copy of openstack.common
base=tackerclient

View File

@@ -1,5 +0,0 @@
---
features:
- |
Support to create directly VNFFG and NS from its descriptor template
without creating VNFFGD and NSD.

View File

@@ -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.

View File

@@ -1,4 +0,0 @@
---
fixes:
- |
The VNFFGD CLI cannot show the VNFFGD template.

View File

@@ -1,4 +0,0 @@
---
fixes:
- |
Add documentation for python-tackerclient.

View File

@@ -1,4 +0,0 @@
---
fixes:
- |
Fix the VNFFG update osc command misusing create_vnffg function.

View File

@@ -1,4 +0,0 @@
---
fixes:
- |
Fix local test fail with pypy.

View File

@@ -1,4 +0,0 @@
---
features:
- |
Enable CLI to support clustering service in Tacker Server.

View File

@@ -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.

View File

@@ -1,6 +0,0 @@
---
deprecations:
- |
Direct YAML input of any kind is now deprecated. Only file based YAML
input is supported. This deprecation is across all resources like VNFFGD
template, VNFD template and VNF configuration input.

View File

@@ -1,4 +0,0 @@
---
deprecations:
- infra_driver and mgmt_driver attributes in VNFD client
attribute is deprecated and will be removed in Ocata.

View File

@@ -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).

View File

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

View File

@@ -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.

View File

@@ -1,3 +0,0 @@
---
features:
- Add support for multi delete feature for resources.

View File

@@ -1,6 +0,0 @@
---
features:
- |
CLIs to onboard Network Services Descriptor (NSD) based on TOSCA Simple
Profile for NFV and to create Network Services using NSD to create multiple
related VNFs using a single TOSCA template.

View File

@@ -1,4 +0,0 @@
---
features:
- Adds new CLI command 'vnf-resource-list' to view VNF
resources, such as VDU, CP, etc.

View File

@@ -1,3 +0,0 @@
---
fixes:
- Remove passing mgmt and infra driver from client.

View File

@@ -1,4 +0,0 @@
---
features:
- |
Add python-vnfd, vnf, nsd, ns, vnffgd, vnffg, event commands support.

View File

@@ -1,3 +0,0 @@
---
features:
- VIM can be updated without config-file argument in tacker vim-update command.

View File

@@ -1,3 +0,0 @@
---
features:
- Support to create VNF with direct VNFD template input from CLI.

View File

@@ -1,3 +0,0 @@
---
features:
- Made VNFD/VNF/VIM names mandatory in tacker CLI.

View File

@@ -1,3 +0,0 @@
---
features:
- Add client support for VNFFG.

View File

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

View File

@@ -1,261 +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.
#
# tacker client documentation build configuration file, created by
# sphinx-quickstart on Tue May 31 19:07:30 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
#
# 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.insert(0, os.path.abspath('.'))
# -- General configuration -------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'
# 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',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'Tacker Client Release Notes'
copyright = '2016, Tacker Developers'
# Release notes are version independent.
release = ''
version = ''
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to
# use for all documents.
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'native'
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'openstackdocs'
# 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
# documentation.
# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}
# If false, no module index is generated.
# html_domain_indices = True
# If false, no index is generated.
# html_use_index = True
# If true, the index is split into individual pages for each letter.
# html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'tackerclientdoc'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
# 'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
('index', 'TackerClientReleaseNotes.tex',
'Tacker Client Release Notes Documentation',
'Tacker Developers', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
# If true, show page references after internal links.
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
# latex_appendices = []
# If false, no module index is generated.
# latex_domain_indices = True
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'tackerreleasenotes',
'Tacker Client Release Notes Documentation',
['Tacker Developers'], 1)
]
# If true, show URL addresses after external links.
# man_show_urls = False
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'TackerClientReleaseNotes',
'Tacker Client Release Notes Documentation',
'Tacker Developers', 'TackerClientReleaseNotes',
'Tacker Client Project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
# texinfo_appendices = []
# If false, no module index is generated.
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
# texinfo_show_urls = 'footnote'
# -- 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

View File

@@ -1,23 +0,0 @@
Python-TackerClient Release Notes
=================================
Contents:
.. toctree::
:maxdepth: 2
unreleased
2023.1
zed
yoga
xena
wallaby
victoria
ussuri
train
stein
rocky
queens
pike
ocata
newton

View File

@@ -1,6 +0,0 @@
===================================
Newton Series Release Notes
===================================
.. release-notes::
:branch: origin/stable/newton

View File

@@ -1,6 +0,0 @@
===================================
Ocata Series Release Notes
===================================
.. release-notes::
:branch: origin/stable/ocata

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +0,0 @@
============================
Current Series Release Notes
============================
.. release-notes::

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,17 +1,13 @@
# 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
iso8601>=0.1.11 # MIT
netaddr>=0.7.18 # BSD
requests>=2.14.2 # 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
pbr>=1.6
argparse
cliff>=1.14.0 # Apache-2.0
iso8601>=0.1.9
netaddr>=0.7.12,!=0.7.16
requests>=2.5.2,!=2.8.0,!=2.9.0
python-keystoneclient>=1.6.0,!=1.8.0
simplejson>=2.2.0
six>=1.9.0
Babel>=1.3

149
setup.cfg
View File

@@ -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://www.openstack.org/
classifier =
Environment :: OpenStack
Intended Audience :: Developers
Intended Audience :: Information Technology
@@ -14,137 +14,26 @@ 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
Programming Language :: Python :: 2.6
[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
[wheel]
universal = 1

View File

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

View File

@@ -56,7 +56,7 @@ class HTTPClient(object):
endpoint_url=None, insecure=False,
endpoint_type='publicURL',
auth_strategy='keystone', ca_cert=None, log_credentials=False,
service_type='nfv-orchestration',
service_type='servicevm',
**kwargs):
self.username = username
@@ -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
@@ -174,6 +171,8 @@ class HTTPClient(object):
return resp, body
except exceptions.Unauthorized:
self.authenticate()
kwargs.setdefault('headers', {})
kwargs['headers']['X-Auth-Token'] = self.auth_token
resp, body = self._cs_request(
self.endpoint_url + url, method, **kwargs)
return resp, body
@@ -188,7 +187,7 @@ class HTTPClient(object):
if not self.endpoint_url:
self.endpoint_url = self.service_catalog.url_for(
region_name=self.region_name,
attr='region', filter_value=self.region_name,
service_type=self.service_type,
endpoint_type=self.endpoint_type)
@@ -257,7 +256,7 @@ class HTTPClient(object):
body = json.loads(body)
for endpoint in body.get('endpoints', []):
if (endpoint['type'] == 'nfv-orchestration' and
if (endpoint['type'] == 'servicevm' and
endpoint.get('region') == self.region_name):
if self.endpoint_type not in endpoint:
raise exceptions.EndpointTypeNotFound(
@@ -293,10 +292,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):
@@ -364,7 +359,7 @@ def construct_http_client(username=None,
log_credentials=None,
auth_strategy='keystone',
ca_cert=None,
service_type='nfv-orchestration',
service_type='servicevm',
session=None,
**kwargs):

View File

@@ -1,40 +0,0 @@
# Copyright 2016 OpenStack Foundation
#
# 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.
"""oslo.i18n integration module.
See https://docs.openstack.org/oslo.i18n/latest/user/index.html.
"""
import oslo_i18n
DOMAIN = "tackerclient"
_translators = oslo_i18n.TranslatorFactory(domain=DOMAIN)
# The primary translation function using the well-known name "_"
_ = _translators.primary
# The contextual translation function using the name "_C"
# requires oslo.i18n >=2.1.0
_C = _translators.contextual_form
# The plural translation function using the name "_P"
# requires oslo.i18n >=2.1.0
_P = _translators.plural_form
def get_available_languages():
return oslo_i18n.get_available_languages(DOMAIN)

View File

@@ -17,10 +17,15 @@
"""Manage access to the clients, including authenticating when needed.
"""
import logging
from tackerclient import client
from tackerclient.tacker import client as tacker_client
LOG = logging.getLogger(__name__)
class ClientCache(object):
"""Descriptor class for caching created client handles."""

View File

@@ -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:

View File

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

View File

@@ -148,6 +148,12 @@ class OverQuotaClient(Conflict):
pass
# TODO(amotoki): It is unused in Tacker, but it is referred to
# in Horizon code. After Horizon code is updated, remove it.
class AlreadyAttachedClient(Conflict):
pass
class IpAddressGenerationFailureClient(Conflict):
pass
@@ -203,18 +209,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):
@@ -227,9 +221,7 @@ class CommandError(TackerCLIError):
class UnsupportedVersion(TackerCLIError):
"""Unsupported Version.
Indicates that the user is trying to use an unsupported version of
"""Indicates that the user is trying to use an unsupported version of
the API.
"""
pass

View File

@@ -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:

View File

@@ -18,13 +18,14 @@
"""Utilities and helper functions."""
import argparse
import functools
import logging
import os
import sys
import warnings
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 +58,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 +142,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
@@ -174,25 +175,14 @@ def add_boolean_argument(parser, name, **kwargs):
**kwargs)
def get_file_path(filename):
file_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
'../%s' % filename))
return file_path
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)
def deprecated(name):
"""This decorator can be used to mark a call as deprecated."""
def _deprecate(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
warnings.simplefilter('always', DeprecationWarning)
warnings.warn("Call to %s deprecated, avoid its usage." % name,
category=DeprecationWarning)
return func(*args, **kwargs)
return wrapper
return _deprecate

View File

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

View File

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

View File

@@ -0,0 +1,17 @@
#
# 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 six
six.add_move(six.MovedModule('mox', 'mox', 'mox3.mox'))

View File

@@ -0,0 +1,320 @@
# Copyright 2012 Red Hat, Inc.
# Copyright 2013 IBM Corp.
# 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.
"""
gettext for openstack-common modules.
Usual usage in an openstack.common module:
from tackerclient.openstack.common.gettextutils import _
"""
import copy
import gettext
import logging
import os
import re
import UserString
from babel import localedata
import six
_localedir = os.environ.get('tackerclient'.upper() + '_LOCALEDIR')
_t = gettext.translation('tackerclient', localedir=_localedir, fallback=True)
_AVAILABLE_LANGUAGES = {}
USE_LAZY = False
def enable_lazy():
"""Convenience function for configuring _() to use lazy gettext
Call this at the start of execution to enable the gettextutils._
function to use lazy gettext functionality. This is useful if
your project is importing _ directly instead of using the
gettextutils.install() way of importing the _ function.
"""
global USE_LAZY
USE_LAZY = True
def _(msg):
if USE_LAZY:
return Message(msg, 'tackerclient')
else:
return _t.ugettext(msg)
def install(domain, lazy=False):
"""Install a _() function using the given translation domain.
Given a translation domain, install a _() function using gettext's
install() function.
The main difference from gettext.install() is that we allow
overriding the default localedir (e.g. /usr/share/locale) using
a translation-domain-specific environment variable (e.g.
NOVA_LOCALEDIR).
:param domain: the translation domain
:param lazy: indicates whether or not to install the lazy _() function.
The lazy _() introduces a way to do deferred translation
of messages by installing a _ that builds Message objects,
instead of strings, which can then be lazily translated into
any available locale.
"""
if lazy:
# NOTE(mrodden): Lazy gettext functionality.
#
# The following introduces a deferred way to do translations on
# messages in OpenStack. We override the standard _() function
# and % (format string) operation to build Message objects that can
# later be translated when we have more information.
#
# Also included below is an example LocaleHandler that translates
# Messages to an associated locale, effectively allowing many logs,
# each with their own locale.
def _lazy_gettext(msg):
"""Create and return a Message object.
Lazy gettext function for a given domain, it is a factory method
for a project/module to get a lazy gettext function for its own
translation domain (i.e. nova, glance, cinder, etc.)
Message encapsulates a string so that we can translate
it later when needed.
"""
return Message(msg, domain)
import __builtin__
__builtin__.__dict__['_'] = _lazy_gettext
else:
localedir = '%s_LOCALEDIR' % domain.upper()
gettext.install(domain,
localedir=os.environ.get(localedir),
unicode=True)
class Message(UserString.UserString, object):
"""Class used to encapsulate translatable messages."""
def __init__(self, msg, domain):
# _msg is the gettext msgid and should never change
self._msg = msg
self._left_extra_msg = ''
self._right_extra_msg = ''
self.params = None
self.locale = None
self.domain = domain
@property
def data(self):
# NOTE(mrodden): this should always resolve to a unicode string
# that best represents the state of the message currently
localedir = os.environ.get(self.domain.upper() + '_LOCALEDIR')
if self.locale:
lang = gettext.translation(self.domain,
localedir=localedir,
languages=[self.locale],
fallback=True)
else:
# use system locale for translations
lang = gettext.translation(self.domain,
localedir=localedir,
fallback=True)
full_msg = (self._left_extra_msg +
lang.ugettext(self._msg) +
self._right_extra_msg)
if self.params is not None:
full_msg = full_msg % self.params
return six.text_type(full_msg)
def _save_dictionary_parameter(self, dict_param):
full_msg = self.data
# look for %(blah) fields in string;
# ignore %% and deal with the
# case where % is first character on the line
keys = re.findall('(?:[^%]|^)?%\((\w*)\)[a-z]', full_msg)
# if we don't find any %(blah) blocks but have a %s
if not keys and re.findall('(?:[^%]|^)%[a-z]', full_msg):
# apparently the full dictionary is the parameter
params = copy.deepcopy(dict_param)
else:
params = {}
for key in keys:
try:
params[key] = copy.deepcopy(dict_param[key])
except TypeError:
# cast uncopyable thing to unicode string
params[key] = unicode(dict_param[key])
return params
def _save_parameters(self, other):
# we check for None later to see if
# we actually have parameters to inject,
# so encapsulate if our parameter is actually None
if other is None:
self.params = (other, )
elif isinstance(other, dict):
self.params = self._save_dictionary_parameter(other)
else:
# fallback to casting to unicode,
# this will handle the problematic python code-like
# objects that cannot be deep-copied
try:
self.params = copy.deepcopy(other)
except TypeError:
self.params = unicode(other)
return self
# overrides to be more string-like
def __unicode__(self):
return self.data
def __str__(self):
return self.data.encode('utf-8')
def __getstate__(self):
to_copy = ['_msg', '_right_extra_msg', '_left_extra_msg',
'domain', 'params', 'locale']
new_dict = self.__dict__.fromkeys(to_copy)
for attr in to_copy:
new_dict[attr] = copy.deepcopy(self.__dict__[attr])
return new_dict
def __setstate__(self, state):
for (k, v) in state.items():
setattr(self, k, v)
# operator overloads
def __add__(self, other):
copied = copy.deepcopy(self)
copied._right_extra_msg += other.__str__()
return copied
def __radd__(self, other):
copied = copy.deepcopy(self)
copied._left_extra_msg += other.__str__()
return copied
def __mod__(self, other):
# do a format string to catch and raise
# any possible KeyErrors from missing parameters
self.data % other
copied = copy.deepcopy(self)
return copied._save_parameters(other)
def __mul__(self, other):
return self.data * other
def __rmul__(self, other):
return other * self.data
def __getitem__(self, key):
return self.data[key]
def __getslice__(self, start, end):
return self.data.__getslice__(start, end)
def __getattribute__(self, name):
# NOTE(mrodden): handle lossy operations that we can't deal with yet
# These override the UserString implementation, since UserString
# uses our __class__ attribute to try and build a new message
# after running the inner data string through the operation.
# At that point, we have lost the gettext message id and can just
# safely resolve to a string instead.
ops = ['capitalize', 'center', 'decode', 'encode',
'expandtabs', 'ljust', 'lstrip', 'replace', 'rjust', 'rstrip',
'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
if name in ops:
return getattr(self.data, name)
else:
return UserString.UserString.__getattribute__(self, name)
def get_available_languages(domain):
"""Lists the available languages for the given translation domain.
:param domain: the domain to get languages for
"""
if domain in _AVAILABLE_LANGUAGES:
return copy.copy(_AVAILABLE_LANGUAGES[domain])
localedir = '%s_LOCALEDIR' % domain.upper()
find = lambda x: gettext.find(domain,
localedir=os.environ.get(localedir),
languages=[x])
# NOTE(mrodden): en_US should always be available (and first in case
# order matters) since our in-line message strings are en_US
language_list = ['en_US']
# NOTE(luisg): Babel <1.0 used a function called list(), which was
# renamed to locale_identifiers() in >=1.0, the requirements master list
# requires >=0.9.6, uncapped, so defensively work with both. We can remove
# this check when the master list updates to >=1.0, and all projects udpate
list_identifiers = (getattr(localedata, 'list', None) or
getattr(localedata, 'locale_identifiers'))
locale_identifiers = list_identifiers()
for i in locale_identifiers:
if find(i) is not None:
language_list.append(i)
_AVAILABLE_LANGUAGES[domain] = language_list
return copy.copy(language_list)
def get_localized_message(message, user_locale):
"""Gets a localized version of the given message in the given locale."""
if isinstance(message, Message):
if user_locale:
message.locale = user_locale
return unicode(message)
else:
return message
class LocaleHandler(logging.Handler):
"""Handler that can have a locale associated to translate Messages.
A quick example of how to utilize the Message class above.
LocaleHandler takes a locale and a target logging.Handler object
to forward LogRecord objects to after translating the internal Message.
"""
def __init__(self, locale, target):
"""Initialize a LocaleHandler
:param locale: locale to use for translating messages
:param target: logging.Handler object to forward
LogRecord objects to after translation
"""
logging.Handler.__init__(self)
self.locale = locale
self.target = target
def emit(self, record):
if isinstance(record.msg, Message):
# set the locale and resolve to a string
record.msg.locale = self.locale
self.target.emit(record)

View File

@@ -0,0 +1,67 @@
# Copyright 2011 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 related utilities and helper functions.
"""
import sys
import traceback
from tackerclient.openstack.common.gettextutils import _
def import_class(import_str):
"""Returns a class from a string including module and class."""
mod_str, _sep, class_str = import_str.rpartition('.')
try:
__import__(mod_str)
return getattr(sys.modules[mod_str], class_str)
except (ValueError, AttributeError):
raise ImportError(_('Class %s cannot be found (%s)') %
(class_str,
traceback.format_exception(*sys.exc_info())))
def import_object(import_str, *args, **kwargs):
"""Import a class and return an instance of it."""
return import_class(import_str)(*args, **kwargs)
def import_object_ns(name_space, import_str, *args, **kwargs):
"""Tries to import object from default namespace.
Imports a class and return an instance of it, first by trying
to find the class in a default namespace, then failing back to
a full path if not found in the default namespace.
"""
import_value = "%s.%s" % (name_space, import_str)
try:
return import_class(import_value)(*args, **kwargs)
except ImportError:
return import_class(import_str)(*args, **kwargs)
def import_module(import_str):
"""Import a module."""
__import__(import_str)
return sys.modules[import_str]
def try_import(import_str, default=None):
"""Try to import a module and if it fails return default."""
try:
return import_module(import_str)
except ImportError:
return default

View File

@@ -0,0 +1,186 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# Copyright 2011 Justin Santa Barbara
# 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.
'''
JSON related utilities.
This module provides a few things:
1) A handy function for getting an object down to something that can be
JSON serialized. See to_primitive().
2) Wrappers around loads() and dumps(). The dumps() wrapper will
automatically use to_primitive() for you if needed.
3) This sets up anyjson to use the loads() and dumps() wrappers if anyjson
is available.
'''
import codecs
import datetime
import functools
import inspect
import itertools
import sys
if sys.version_info < (2, 7):
# On Python <= 2.6, json module is not C boosted, so try to use
# simplejson module if available
try:
import simplejson as json
except ImportError:
import json
else:
import json
import six
import six.moves.xmlrpc_client as xmlrpclib
from tackerclient.openstack.common import gettextutils
from tackerclient.openstack.common import importutils
from tackerclient.openstack.common import strutils
from tackerclient.openstack.common import timeutils
netaddr = importutils.try_import("netaddr")
_nasty_type_tests = [inspect.ismodule, inspect.isclass, inspect.ismethod,
inspect.isfunction, inspect.isgeneratorfunction,
inspect.isgenerator, inspect.istraceback, inspect.isframe,
inspect.iscode, inspect.isbuiltin, inspect.isroutine,
inspect.isabstract]
_simple_types = (six.string_types + six.integer_types
+ (type(None), bool, float))
def to_primitive(value, convert_instances=False, convert_datetime=True,
level=0, max_depth=3):
"""Convert a complex object into primitives.
Handy for JSON serialization. We can optionally handle instances,
but since this is a recursive function, we could have cyclical
data structures.
To handle cyclical data structures we could track the actual objects
visited in a set, but not all objects are hashable. Instead we just
track the depth of the object inspections and don't go too deep.
Therefore, convert_instances=True is lossy ... be aware.
"""
# handle obvious types first - order of basic types determined by running
# full tests on nova project, resulting in the following counts:
# 572754 <type 'NoneType'>
# 460353 <type 'int'>
# 379632 <type 'unicode'>
# 274610 <type 'str'>
# 199918 <type 'dict'>
# 114200 <type 'datetime.datetime'>
# 51817 <type 'bool'>
# 26164 <type 'list'>
# 6491 <type 'float'>
# 283 <type 'tuple'>
# 19 <type 'long'>
if isinstance(value, _simple_types):
return value
if isinstance(value, datetime.datetime):
if convert_datetime:
return timeutils.strtime(value)
else:
return value
# value of itertools.count doesn't get caught by nasty_type_tests
# and results in infinite loop when list(value) is called.
if type(value) == itertools.count:
return six.text_type(value)
# FIXME(vish): Workaround for LP bug 852095. Without this workaround,
# tests that raise an exception in a mocked method that
# has a @wrap_exception with a notifier will fail. If
# we up the dependency to 0.5.4 (when it is released) we
# can remove this workaround.
if getattr(value, '__module__', None) == 'mox':
return 'mock'
if level > max_depth:
return '?'
# The try block may not be necessary after the class check above,
# but just in case ...
try:
recursive = functools.partial(to_primitive,
convert_instances=convert_instances,
convert_datetime=convert_datetime,
level=level,
max_depth=max_depth)
if isinstance(value, dict):
return dict((k, recursive(v)) for k, v in six.iteritems(value))
elif isinstance(value, (list, tuple)):
return [recursive(lv) for lv in value]
# It's not clear why xmlrpclib created their own DateTime type, but
# for our purposes, make it a datetime type which is explicitly
# handled
if isinstance(value, xmlrpclib.DateTime):
value = datetime.datetime(*tuple(value.timetuple())[:6])
if convert_datetime and isinstance(value, datetime.datetime):
return timeutils.strtime(value)
elif isinstance(value, gettextutils.Message):
return value.data
elif hasattr(value, 'iteritems'):
return recursive(dict(value.iteritems()), level=level + 1)
elif hasattr(value, '__iter__'):
return recursive(list(value))
elif convert_instances and hasattr(value, '__dict__'):
# Likely an instance of something. Watch for cycles.
# Ignore class member vars.
return recursive(value.__dict__, level=level + 1)
elif netaddr and isinstance(value, netaddr.IPAddress):
return six.text_type(value)
else:
if any(test(value) for test in _nasty_type_tests):
return six.text_type(value)
return value
except TypeError:
# Class objects are tricky since they may define something like
# __iter__ defined but it isn't callable as list().
return six.text_type(value)
def dumps(value, default=to_primitive, **kwargs):
return json.dumps(value, default=default, **kwargs)
def loads(s, encoding='utf-8'):
return json.loads(strutils.safe_decode(s, encoding))
def load(fp, encoding='utf-8'):
return json.load(codecs.getreader(encoding)(fp))
try:
import anyjson
except ImportError:
pass
else:
anyjson._modules.append((__name__, 'dumps', TypeError,
'loads', ValueError, 'load'))
anyjson.force_implementation(__name__)

View File

@@ -0,0 +1,216 @@
# Copyright 2011 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.
"""
System-level utilities and helper functions.
"""
import re
import sys
import unicodedata
import six
from tackerclient.openstack.common.gettextutils import _ # noqa
# Used for looking up extensions of text
# to their 'multiplied' byte amount
BYTE_MULTIPLIERS = {
'': 1,
't': 1024 ** 4,
'g': 1024 ** 3,
'm': 1024 ** 2,
'k': 1024,
}
BYTE_REGEX = re.compile(r'(^-?\d+)(\D*)')
TRUE_STRINGS = ('1', 't', 'true', 'on', 'y', 'yes')
FALSE_STRINGS = ('0', 'f', 'false', 'off', 'n', 'no')
SLUGIFY_STRIP_RE = re.compile(r"[^\w\s-]")
SLUGIFY_HYPHENATE_RE = re.compile(r"[-\s]+")
def int_from_bool_as_string(subject):
"""Interpret a string as a boolean and return either 1 or 0.
Any string value in:
('True', 'true', 'On', 'on', '1')
is interpreted as a boolean True.
Useful for JSON-decoded stuff and config file parsing
"""
return bool_from_string(subject) and 1 or 0
def bool_from_string(subject, strict=False):
"""Interpret a string as a boolean.
A case-insensitive match is performed such that strings matching 't',
'true', 'on', 'y', 'yes', or '1' are considered True and, when
`strict=False`, anything else is considered False.
Useful for JSON-decoded stuff and config file parsing.
If `strict=True`, unrecognized values, including None, will raise a
ValueError which is useful when parsing values passed in from an API call.
Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
"""
if not isinstance(subject, six.string_types):
subject = str(subject)
lowered = subject.strip().lower()
if lowered in TRUE_STRINGS:
return True
elif lowered in FALSE_STRINGS:
return False
elif strict:
acceptable = ', '.join(
"'%s'" % s for s in sorted(TRUE_STRINGS + FALSE_STRINGS))
msg = _("Unrecognized value '%(val)s', acceptable values are:"
" %(acceptable)s") % {'val': subject,
'acceptable': acceptable}
raise ValueError(msg)
else:
return False
def safe_decode(text, incoming=None, errors='strict'):
"""Decodes incoming str using `incoming` if they're not already unicode.
:param incoming: Text's current encoding
:param errors: Errors handling policy. See here for valid
values http://docs.python.org/2/library/codecs.html
:returns: text or a unicode `incoming` encoded
representation of it.
:raises TypeError: If text is not an isntance of str
"""
if not isinstance(text, six.string_types):
raise TypeError("%s can't be decoded" % type(text))
if isinstance(text, six.text_type):
return text
if not incoming:
incoming = (sys.stdin.encoding or
sys.getdefaultencoding())
try:
return text.decode(incoming, errors)
except UnicodeDecodeError:
# Note(flaper87) If we get here, it means that
# sys.stdin.encoding / sys.getdefaultencoding
# didn't return a suitable encoding to decode
# text. This happens mostly when global LANG
# var is not set correctly and there's no
# default encoding. In this case, most likely
# python will use ASCII or ANSI encoders as
# default encodings but they won't be capable
# of decoding non-ASCII characters.
#
# Also, UTF-8 is being used since it's an ASCII
# extension.
return text.decode('utf-8', errors)
def safe_encode(text, incoming=None,
encoding='utf-8', errors='strict'):
"""Encodes incoming str/unicode using `encoding`.
If incoming is not specified, text is expected to be encoded with
current python's default encoding. (`sys.getdefaultencoding`)
:param incoming: Text's current encoding
:param encoding: Expected encoding for text (Default UTF-8)
:param errors: Errors handling policy. See here for valid
values http://docs.python.org/2/library/codecs.html
:returns: text or a bytestring `encoding` encoded
representation of it.
:raises TypeError: If text is not an isntance of str
"""
if not isinstance(text, six.string_types):
raise TypeError(_("%s can't be encoded") % type(text).capitalize())
if not incoming:
incoming = (sys.stdin.encoding or
sys.getdefaultencoding())
if isinstance(text, six.text_type):
return text.encode(encoding, errors)
elif text and encoding != incoming:
# Decode text before encoding it with `encoding`
text = safe_decode(text, incoming, errors)
return text.encode(encoding, errors)
return text
def to_bytes(text, default=0):
"""Converts a string into an integer of bytes.
Looks at the last characters of the text to determine
what conversion is needed to turn the input text into a byte number.
Supports "B, K(B), M(B), G(B), and T(B)". (case insensitive)
:param text: String input for bytes size conversion.
:param default: Default return value when text is blank.
"""
match = BYTE_REGEX.search(text)
if match:
magnitude = int(match.group(1))
mult_key_org = match.group(2)
if not mult_key_org:
return magnitude
elif text:
msg = _('Invalid string format: %s') % text
raise TypeError(msg)
else:
return default
mult_key = mult_key_org.lower().replace('b', '', 1)
multiplier = BYTE_MULTIPLIERS.get(mult_key)
if multiplier is None:
msg = _('Unknown byte multiplier: %s') % mult_key_org
raise TypeError(msg)
return magnitude * multiplier
def to_slug(value, incoming=None, errors="strict"):
"""Normalize string.
Convert to lowercase, remove non-word characters, and convert spaces
to hyphens.
Inspired by Django's `slugify` filter.
:param value: Text to slugify
:param incoming: Text's current encoding
:param errors: Errors handling policy. See here for valid
values http://docs.python.org/2/library/codecs.html
:returns: slugified unicode representation of `value`
:raises TypeError: If text is not an instance of str
"""
value = safe_decode(value, incoming, errors)
# NOTE(aababilov): no need to use safe_(encode|decode) here:
# encodings are always "ascii", error handling is always "ignore"
# and types are always known (first: unicode; second: str)
value = unicodedata.normalize("NFKD", value).encode(
"ascii", "ignore").decode("ascii")
value = SLUGIFY_STRIP_RE.sub("", value).strip().lower()
return SLUGIFY_HYPHENATE_RE.sub("-", value)

View File

@@ -0,0 +1,186 @@
# Copyright 2011 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.
"""
Time related utilities and helper functions.
"""
import calendar
import datetime
import iso8601
import six
# ISO 8601 extended time format with microseconds
_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f'
_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
PERFECT_TIME_FORMAT = _ISO8601_TIME_FORMAT_SUBSECOND
def isotime(at=None, subsecond=False):
"""Stringify time in ISO 8601 format."""
if not at:
at = utcnow()
st = at.strftime(_ISO8601_TIME_FORMAT
if not subsecond
else _ISO8601_TIME_FORMAT_SUBSECOND)
tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
st += ('Z' if tz == 'UTC' else tz)
return st
def parse_isotime(timestr):
"""Parse time from ISO 8601 format."""
try:
return iso8601.parse_date(timestr)
except iso8601.ParseError as e:
raise ValueError(unicode(e))
except TypeError as e:
raise ValueError(unicode(e))
def strtime(at=None, fmt=PERFECT_TIME_FORMAT):
"""Returns formatted utcnow."""
if not at:
at = utcnow()
return at.strftime(fmt)
def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT):
"""Turn a formatted time back into a datetime."""
return datetime.datetime.strptime(timestr, fmt)
def normalize_time(timestamp):
"""Normalize time in arbitrary timezone to UTC naive object."""
offset = timestamp.utcoffset()
if offset is None:
return timestamp
return timestamp.replace(tzinfo=None) - offset
def is_older_than(before, seconds):
"""Return True if before is older than seconds."""
if isinstance(before, six.string_types):
before = parse_strtime(before).replace(tzinfo=None)
return utcnow() - before > datetime.timedelta(seconds=seconds)
def is_newer_than(after, seconds):
"""Return True if after is newer than seconds."""
if isinstance(after, six.string_types):
after = parse_strtime(after).replace(tzinfo=None)
return after - utcnow() > datetime.timedelta(seconds=seconds)
def utcnow_ts():
"""Timestamp version of our utcnow function."""
return calendar.timegm(utcnow().timetuple())
def utcnow():
"""Overridable version of utils.utcnow."""
if utcnow.override_time:
try:
return utcnow.override_time.pop(0)
except AttributeError:
return utcnow.override_time
return datetime.datetime.utcnow()
def iso8601_from_timestamp(timestamp):
"""Returns a iso8601 formated date from timestamp."""
return isotime(datetime.datetime.utcfromtimestamp(timestamp))
utcnow.override_time = None
def set_time_override(override_time=datetime.datetime.utcnow()):
"""Overrides utils.utcnow.
Make it return a constant time or a list thereof, one at a time.
"""
utcnow.override_time = override_time
def advance_time_delta(timedelta):
"""Advance overridden time using a datetime.timedelta."""
assert(not utcnow.override_time is None)
try:
for dt in utcnow.override_time:
dt += timedelta
except TypeError:
utcnow.override_time += timedelta
def advance_time_seconds(seconds):
"""Advance overridden time by seconds."""
advance_time_delta(datetime.timedelta(0, seconds))
def clear_time_override():
"""Remove the overridden time."""
utcnow.override_time = None
def marshall_now(now=None):
"""Make an rpc-safe datetime with microseconds.
Note: tzinfo is stripped, but not required for relative times.
"""
if not now:
now = utcnow()
return dict(day=now.day, month=now.month, year=now.year, hour=now.hour,
minute=now.minute, second=now.second,
microsecond=now.microsecond)
def unmarshall_time(tyme):
"""Unmarshall a datetime dict."""
return datetime.datetime(day=tyme['day'],
month=tyme['month'],
year=tyme['year'],
hour=tyme['hour'],
minute=tyme['minute'],
second=tyme['second'],
microsecond=tyme['microsecond'])
def delta_seconds(before, after):
"""Return the difference between two timing objects.
Compute the difference in seconds between two date, time, or
datetime objects (as a float, to microsecond resolution).
"""
delta = after - before
try:
return delta.total_seconds()
except AttributeError:
return ((delta.days * 24 * 3600) + delta.seconds +
float(delta.microseconds) / (10 ** 6))
def is_soon(dt, window):
"""Determines if time is going to happen in the next window seconds.
:params dt: the time
:params window: minimum seconds to remain to consider the time not soon
:return: True if expiration is within the given duration
"""
soon = (utcnow() + datetime.timedelta(seconds=window))
return normalize_time(dt) <= soon

View File

@@ -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()))

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More