├── tackerclient
├── __init__.py
├── osc
│ ├── __init__.py
│ ├── v1
│ │ ├── __init__.py
│ │ ├── nfvo
│ │ │ └── __init__.py
│ │ ├── vnflcm
│ │ │ ├── __init__.py
│ │ │ └── samples
│ │ │ │ ├── heal_vnf_instance_param_sample.json
│ │ │ │ ├── scale_vnf_instance_param_sample.json
│ │ │ │ ├── update_vnf_instance_param_sample.json
│ │ │ │ ├── change_ext_conn_vnf_instance_param_sample.json
│ │ │ │ ├── instantiate_vnf_instance_param_sample.json
│ │ │ │ └── create_lccn_subscription_param_sample.json
│ │ └── vnfpkgm
│ │ │ └── __init__.py
│ ├── v2
│ │ ├── __init__.py
│ │ ├── vnffm
│ │ │ ├── __init__.py
│ │ │ ├── samples
│ │ │ │ └── create_vnf_fm_subscription_param_sample.json
│ │ │ └── vnffm_sub.py
│ │ ├── vnfpm
│ │ │ ├── __init__.py
│ │ │ ├── samples
│ │ │ │ ├── update_vnf_pm_job_param_sample.json
│ │ │ │ ├── update_vnf_pm_threshold_param_sample.json
│ │ │ │ ├── create_vnf_pm_job_param_sample.json
│ │ │ │ └── create_vnf_pm_threshold_param_sample.json
│ │ │ └── vnfpm_report.py
│ │ └── vnflcm
│ │ │ └── samples
│ │ │ └── change_vnfpkg_vnf_instance_param_sample.json
│ ├── common
│ │ ├── __init__.py
│ │ └── vnflcm
│ │ │ ├── __init__.py
│ │ │ └── vnflcm_versions.py
│ ├── plugin.py
│ └── sdk_utils.py
├── common
│ ├── __init__.py
│ ├── constants.py
│ ├── _i18n.py
│ ├── command.py
│ ├── validators.py
│ ├── extension.py
│ ├── clientmanager.py
│ ├── serializer.py
│ ├── exceptions.py
│ └── utils.py
├── tacker
│ ├── __init__.py
│ ├── v1_0
│ │ └── nfvo
│ │ │ ├── __init__.py
│ │ │ ├── vim_utils.py
│ │ │ └── vim.py
│ └── client.py
├── tests
│ ├── __init__.py
│ └── unit
│ │ ├── __init__.py
│ │ ├── vm
│ │ ├── __init__.py
│ │ └── samples
│ │ │ ├── vim_k8s_bearer_token_without_auth_url.yaml
│ │ │ ├── vim_k8s_config_without_auth_url.yaml
│ │ │ ├── vim_k8s_bearer_token.yaml
│ │ │ ├── vim_k8s_config.yaml
│ │ │ ├── vim_config_without_auth_url.yaml
│ │ │ ├── vim_config.yaml
│ │ │ └── vim_config_with_false_cert_verify.yaml
│ │ ├── osc
│ │ ├── __init__.py
│ │ ├── v1
│ │ │ ├── __init__.py
│ │ │ ├── fixture_data
│ │ │ │ ├── __init__.py
│ │ │ │ ├── sample_vnf_package_artifacts
│ │ │ │ │ ├── Scripts
│ │ │ │ │ │ └── install.sh
│ │ │ │ │ ├── TOSCA-Metadata
│ │ │ │ │ │ └── TOSCA.meta
│ │ │ │ │ └── Definitions
│ │ │ │ │ │ ├── helloworld3_top.vnfd.yaml
│ │ │ │ │ │ └── helloworld3_types.yaml
│ │ │ │ ├── sample_vnf_package
│ │ │ │ │ ├── TOSCA-Metadata
│ │ │ │ │ │ └── TOSCA.meta
│ │ │ │ │ └── Definitions
│ │ │ │ │ │ ├── helloworld3_top.vnfd.yaml
│ │ │ │ │ │ └── helloworld3_types.yaml
│ │ │ │ └── client.py
│ │ │ ├── vnflcm_op_occs_fakes.py
│ │ │ └── vnflcm_fakes.py
│ │ ├── v2
│ │ │ ├── __init__.py
│ │ │ ├── vnfpm_report_fakes.py
│ │ │ ├── vnfpm_threshold_fakes.py
│ │ │ ├── vnfpm_job_fakes.py
│ │ │ ├── vnffm_sub_fakes.py
│ │ │ ├── vnffm_alarm_fakes.py
│ │ │ └── test_vnfpm_report.py
│ │ ├── common
│ │ │ ├── __init__.py
│ │ │ └── test_vnflcm_versions.py
│ │ └── base.py
│ │ ├── test_command_meta.py
│ │ ├── test_http.py
│ │ ├── test_ssl.py
│ │ ├── test_validators.py
│ │ ├── test_casual_args.py
│ │ └── test_utils.py
├── v1_0
│ └── __init__.py
├── i18n.py
└── version.py
├── releasenotes
├── source
│ ├── _static
│ │ └── .placeholder
│ ├── _templates
│ │ └── .placeholder
│ ├── unreleased.rst
│ ├── zed.rst
│ ├── train.rst
│ ├── xena.rst
│ ├── yoga.rst
│ ├── 2023.2.rst
│ ├── 2024.1.rst
│ ├── 2024.2.rst
│ ├── 2025.1.rst
│ ├── 2025.2.rst
│ ├── ussuri.rst
│ ├── 2023.1.rst
│ ├── pike.rst
│ ├── rocky.rst
│ ├── stein.rst
│ ├── wallaby.rst
│ ├── queens.rst
│ ├── victoria.rst
│ ├── newton.rst
│ ├── ocata.rst
│ └── index.rst
└── notes
│ ├── vnffg-client-abd7d7f06860b91d.yaml
│ ├── bug-1754926-06ac4d7ffd17b5ce.yaml
│ ├── bug-1754556-53268d3081fa18d1.yaml
│ ├── bug-1750865-04c3ebd0c3f8af29.yaml
│ ├── multi-delete-support-in-tacker-acd4a7e86114f0be.yaml
│ ├── bug-1754793-54446bcd0a4e84aa.yaml
│ ├── obsolete-legacy-apis-excluding-vim-43d8dd73c3768fbb.yaml
│ ├── vnf-inline-template-25f6a0b66f7407a1.yaml
│ ├── clustering-service-cli-e15cc6627de293fa.yaml
│ ├── vnfd-vnf-vim-name-mandatory-in-tacker-cli-dfe802af6de5c80e.yaml
│ ├── remove-passing-mgmt-and-infra-driver-from-client-c9135f84480b2cae.yaml
│ ├── update-vim-without-config-c3b637741889eff6.yaml
│ ├── tacker-support-python-openstackclient-b88b20b80b872229.yaml
│ ├── new-commmand-vnf-resource-list-d5422ab917f0892f.yaml
│ ├── add-creating-ns-vnffg-from-template-213eee7f1820aa0c.yaml
│ ├── deprecate-infra-mgmt-driver-attributes-e371624c50accee8.yaml
│ ├── del-project_and_user_id-e9dd396f83a162d6.yaml
│ ├── deprecate-legacy-apis-excluding-vim-debaa69507f73179.yaml
│ ├── drop-py-2-7-b2052825c4b92b52.yaml
│ ├── deprecated-tacker-command-29121558bd748082.yaml
│ ├── network-services-descriptor-06f6abe90adb40f3.yaml
│ ├── deprecate-direct-yaml-cli-input-812564bab1b99b4b.yaml
│ └── add-vnffg-and-vnf-ids-to-ns-list-commands-9d462efc103f8ecb.yaml
├── .stestr.conf
├── .gitreview
├── .coveragerc
├── MANIFEST.in
├── .zuul.yaml
├── doc
├── requirements.txt
└── source
│ ├── contributor
│ ├── contributing.rst
│ ├── index.rst
│ └── developing.rst
│ ├── cli
│ ├── vim_commands.rst
│ ├── vnf_package_commands.rst
│ ├── index.rst
│ ├── vnffm_commands.rst
│ ├── vnfpm_commands.rst
│ ├── vnflcm_commands.rst
│ └── commands.rst
│ ├── reference
│ └── index.rst
│ ├── index.rst
│ ├── install
│ └── index.rst
│ └── conf.py
├── .gitignore
├── test-requirements.txt
├── CONTRIBUTING.rst
├── requirements.txt
├── setup.py
├── tools
└── tacker.bash_completion
├── HACKING.rst
├── .pylintrc
├── tox.ini
└── README.rst
/tackerclient/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/common/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tacker/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/v1_0/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/common/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/nfvo/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/vnflcm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnffm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnfpm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/vm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/releasenotes/source/_static/.placeholder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/releasenotes/source/_templates/.placeholder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/common/vnflcm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/vnfpkgm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tacker/v1_0/nfvo/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v2/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/common/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.stestr.conf:
--------------------------------------------------------------------------------
1 | [DEFAULT]
2 | test_path=./tackerclient/tests/unit
3 | top_path=./
4 |
--------------------------------------------------------------------------------
/.gitreview:
--------------------------------------------------------------------------------
1 | [gerrit]
2 | host=review.opendev.org
3 | port=29418
4 | project=openstack/python-tackerclient.git
5 |
--------------------------------------------------------------------------------
/releasenotes/notes/vnffg-client-abd7d7f06860b91d.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - Add client support for VNFFG.
4 |
--------------------------------------------------------------------------------
/releasenotes/notes/bug-1754926-06ac4d7ffd17b5ce.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | fixes:
3 | - |
4 | Fix local test fail with pypy.
5 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/vnflcm/samples/heal_vnf_instance_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "additionalParams": {"all": true}
3 | }
4 |
--------------------------------------------------------------------------------
/releasenotes/notes/bug-1754556-53268d3081fa18d1.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | fixes:
3 | - |
4 | Add documentation for python-tackerclient.
5 |
--------------------------------------------------------------------------------
/releasenotes/notes/bug-1750865-04c3ebd0c3f8af29.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | fixes:
3 | - |
4 | The VNFFGD CLI cannot show the VNFFGD template.
5 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/sample_vnf_package_artifacts/Scripts/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Hello, World!"
4 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/vnflcm/samples/scale_vnf_instance_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "additionalParams": {"key1":"value1", "key2":"value2"}
3 | }
--------------------------------------------------------------------------------
/releasenotes/notes/multi-delete-support-in-tacker-acd4a7e86114f0be.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - Add support for multi delete feature for resources.
4 |
--------------------------------------------------------------------------------
/releasenotes/notes/bug-1754793-54446bcd0a4e84aa.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | fixes:
3 | - |
4 | Fix the VNFFG update osc command misusing create_vnffg function.
5 |
--------------------------------------------------------------------------------
/releasenotes/notes/obsolete-legacy-apis-excluding-vim-43d8dd73c3768fbb.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | upgrade:
3 | - |
4 | Legacy APIs excluding VIM feature are obsoleted.
--------------------------------------------------------------------------------
/releasenotes/notes/vnf-inline-template-25f6a0b66f7407a1.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - Support to create VNF with direct VNFD template input from CLI.
4 |
--------------------------------------------------------------------------------
/releasenotes/notes/clustering-service-cli-e15cc6627de293fa.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - |
4 | Enable CLI to support clustering service in Tacker Server.
5 |
--------------------------------------------------------------------------------
/releasenotes/notes/vnfd-vnf-vim-name-mandatory-in-tacker-cli-dfe802af6de5c80e.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - Made VNFD/VNF/VIM names mandatory in tacker CLI.
4 |
--------------------------------------------------------------------------------
/releasenotes/source/unreleased.rst:
--------------------------------------------------------------------------------
1 | ============================
2 | Current Series Release Notes
3 | ============================
4 |
5 | .. release-notes::
6 |
--------------------------------------------------------------------------------
/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | branch = True
3 | source = tackerclient
4 | omit = tackerclient/openstack/*,tackerclient/tests/*
5 |
6 | [report]
7 | ignore_errors = True
8 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include tox.ini
2 | include LICENSE README.rst HACKING.rst
3 | include AUTHORS
4 | include ChangeLog
5 | include tools/*
6 | recursive-include tests *
7 |
--------------------------------------------------------------------------------
/releasenotes/notes/remove-passing-mgmt-and-infra-driver-from-client-c9135f84480b2cae.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | fixes:
3 | - Remove passing mgmt and infra driver from client.
4 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/vm/samples/vim_k8s_bearer_token_without_auth_url.yaml:
--------------------------------------------------------------------------------
1 | bearer_token: 'xyz'
2 | ssl_ca_cert: None
3 | project_name: 'default'
4 | type: 'kubernetes'
--------------------------------------------------------------------------------
/releasenotes/notes/update-vim-without-config-c3b637741889eff6.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - VIM can be updated without config-file argument in tacker vim-update command.
4 |
--------------------------------------------------------------------------------
/releasenotes/source/zed.rst:
--------------------------------------------------------------------------------
1 | ========================
2 | Zed Series Release Notes
3 | ========================
4 |
5 | .. release-notes::
6 | :branch: unmaintained/zed
7 |
--------------------------------------------------------------------------------
/releasenotes/source/train.rst:
--------------------------------------------------------------------------------
1 | ==========================
2 | Train Series Release Notes
3 | ==========================
4 |
5 | .. release-notes::
6 | :branch: stable/train
7 |
--------------------------------------------------------------------------------
/releasenotes/source/xena.rst:
--------------------------------------------------------------------------------
1 | =========================
2 | Xena Series Release Notes
3 | =========================
4 |
5 | .. release-notes::
6 | :branch: unmaintained/xena
7 |
--------------------------------------------------------------------------------
/releasenotes/source/yoga.rst:
--------------------------------------------------------------------------------
1 | =========================
2 | Yoga Series Release Notes
3 | =========================
4 |
5 | .. release-notes::
6 | :branch: unmaintained/yoga
7 |
--------------------------------------------------------------------------------
/.zuul.yaml:
--------------------------------------------------------------------------------
1 | - project:
2 | templates:
3 | - check-requirements
4 | - openstack-python3-jobs
5 | - publish-openstack-docs-pti
6 | - release-notes-jobs-python3
7 |
--------------------------------------------------------------------------------
/releasenotes/notes/tacker-support-python-openstackclient-b88b20b80b872229.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - |
4 | Add python-vnfd, vnf, nsd, ns, vnffgd, vnffg, event commands support.
5 |
--------------------------------------------------------------------------------
/releasenotes/source/2023.2.rst:
--------------------------------------------------------------------------------
1 | ===========================
2 | 2023.2 Series Release Notes
3 | ===========================
4 |
5 | .. release-notes::
6 | :branch: stable/2023.2
7 |
--------------------------------------------------------------------------------
/releasenotes/source/2024.1.rst:
--------------------------------------------------------------------------------
1 | ===========================
2 | 2024.1 Series Release Notes
3 | ===========================
4 |
5 | .. release-notes::
6 | :branch: stable/2024.1
7 |
--------------------------------------------------------------------------------
/releasenotes/source/2024.2.rst:
--------------------------------------------------------------------------------
1 | ===========================
2 | 2024.2 Series Release Notes
3 | ===========================
4 |
5 | .. release-notes::
6 | :branch: stable/2024.2
7 |
--------------------------------------------------------------------------------
/releasenotes/source/2025.1.rst:
--------------------------------------------------------------------------------
1 | ===========================
2 | 2025.1 Series Release Notes
3 | ===========================
4 |
5 | .. release-notes::
6 | :branch: stable/2025.1
7 |
--------------------------------------------------------------------------------
/releasenotes/source/2025.2.rst:
--------------------------------------------------------------------------------
1 | ===========================
2 | 2025.2 Series Release Notes
3 | ===========================
4 |
5 | .. release-notes::
6 | :branch: stable/2025.2
7 |
--------------------------------------------------------------------------------
/releasenotes/source/ussuri.rst:
--------------------------------------------------------------------------------
1 | ===========================
2 | Ussuri Series Release Notes
3 | ===========================
4 |
5 | .. release-notes::
6 | :branch: stable/ussuri
7 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/vm/samples/vim_k8s_config_without_auth_url.yaml:
--------------------------------------------------------------------------------
1 | username: 'xyz'
2 | password: '12345'
3 | ssl_ca_cert: 'abcxyz'
4 | project_name: 'default'
5 | type: 'kubernetes'
--------------------------------------------------------------------------------
/releasenotes/source/2023.1.rst:
--------------------------------------------------------------------------------
1 | ===========================
2 | 2023.1 Series Release Notes
3 | ===========================
4 |
5 | .. release-notes::
6 | :branch: unmaintained/2023.1
7 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/vm/samples/vim_k8s_bearer_token.yaml:
--------------------------------------------------------------------------------
1 | auth_url: 'https://1.2.3.4:6443'
2 | bearer_token: 'xyz'
3 | ssl_ca_cert: None
4 | project_name: 'default'
5 | type: 'kubernetes'
--------------------------------------------------------------------------------
/releasenotes/notes/new-commmand-vnf-resource-list-d5422ab917f0892f.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - Adds new CLI command 'vnf-resource-list' to view VNF
4 | resources, such as VDU, CP, etc.
5 |
--------------------------------------------------------------------------------
/releasenotes/source/pike.rst:
--------------------------------------------------------------------------------
1 | ===================================
2 | Pike Series Release Notes
3 | ===================================
4 |
5 | .. release-notes::
6 | :branch: stable/pike
7 |
--------------------------------------------------------------------------------
/releasenotes/source/rocky.rst:
--------------------------------------------------------------------------------
1 | ===================================
2 | Rocky Series Release Notes
3 | ===================================
4 |
5 | .. release-notes::
6 | :branch: stable/rocky
7 |
--------------------------------------------------------------------------------
/releasenotes/source/stein.rst:
--------------------------------------------------------------------------------
1 | ===================================
2 | Stein Series Release Notes
3 | ===================================
4 |
5 | .. release-notes::
6 | :branch: stable/stein
7 |
--------------------------------------------------------------------------------
/releasenotes/source/wallaby.rst:
--------------------------------------------------------------------------------
1 | ============================
2 | Wallaby Series Release Notes
3 | ============================
4 |
5 | .. release-notes::
6 | :branch: unmaintained/wallaby
7 |
--------------------------------------------------------------------------------
/releasenotes/source/queens.rst:
--------------------------------------------------------------------------------
1 | ===================================
2 | Queens Series Release Notes
3 | ===================================
4 |
5 | .. release-notes::
6 | :branch: stable/queens
7 |
--------------------------------------------------------------------------------
/releasenotes/source/victoria.rst:
--------------------------------------------------------------------------------
1 | =============================
2 | Victoria Series Release Notes
3 | =============================
4 |
5 | .. release-notes::
6 | :branch: unmaintained/victoria
7 |
--------------------------------------------------------------------------------
/releasenotes/source/newton.rst:
--------------------------------------------------------------------------------
1 | ===================================
2 | Newton Series Release Notes
3 | ===================================
4 |
5 | .. release-notes::
6 | :branch: origin/stable/newton
7 |
--------------------------------------------------------------------------------
/releasenotes/source/ocata.rst:
--------------------------------------------------------------------------------
1 | ===================================
2 | Ocata Series Release Notes
3 | ===================================
4 |
5 | .. release-notes::
6 | :branch: origin/stable/ocata
7 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/vnflcm/samples/update_vnf_instance_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "vnfInstanceName": "sample",
3 | "vnfInstanceDescription" : "sample_description",
4 | "vnfdId" : "sample_id"
5 | }
--------------------------------------------------------------------------------
/tackerclient/tests/unit/vm/samples/vim_k8s_config.yaml:
--------------------------------------------------------------------------------
1 | auth_url: 'https://1.2.3.4:6443'
2 | username: 'xyz'
3 | password: '12345'
4 | ssl_ca_cert: 'abcxyz'
5 | project_name: 'default'
6 | type: 'kubernetes'
--------------------------------------------------------------------------------
/releasenotes/notes/add-creating-ns-vnffg-from-template-213eee7f1820aa0c.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - |
4 | Support to create directly VNFFG and NS from its descriptor template
5 | without creating VNFFGD and NSD.
--------------------------------------------------------------------------------
/releasenotes/notes/deprecate-infra-mgmt-driver-attributes-e371624c50accee8.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | deprecations:
3 | - infra_driver and mgmt_driver attributes in VNFD client
4 | attribute is deprecated and will be removed in Ocata.
5 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/sample_vnf_package/TOSCA-Metadata/TOSCA.meta:
--------------------------------------------------------------------------------
1 | TOSCA-Meta-File-Version: 1.0
2 | Created-by: Hiroyuki JO
3 | CSAR-Version: 1.1
4 | Entry-Definitions: Definitions/helloworld3_top.vnfd.yaml
5 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/vm/samples/vim_config_without_auth_url.yaml:
--------------------------------------------------------------------------------
1 | username: 'xyz'
2 | password: '12345'
3 | project_name: 'abc'
4 | project_domain_name: 'prj_domain_name'
5 | user_domain_name: 'user_domain_name'
6 | type: 'openstack'
7 |
--------------------------------------------------------------------------------
/releasenotes/notes/del-project_and_user_id-e9dd396f83a162d6.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | -
4 | As user gives input of project and user name in vim_config.yaml,
5 | delete the user and project id from the vim specific commands
6 | output.
7 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/vm/samples/vim_config.yaml:
--------------------------------------------------------------------------------
1 | auth_url: 'http://1.2.3.4:5000'
2 | username: 'xyz'
3 | password: '12345'
4 | project_name: 'abc'
5 | project_domain_name: 'prj_domain_name'
6 | user_domain_name: 'user_domain_name'
7 | type: 'openstack'
--------------------------------------------------------------------------------
/releasenotes/notes/deprecate-legacy-apis-excluding-vim-debaa69507f73179.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | deprecations:
3 | - |
4 | Legacy APIs excluding VIM feature are deprecated and will be removed in the
5 | first major release after the Tacker server version 9.0.0 (2023.1 Antelope
6 | release).
7 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/vm/samples/vim_config_with_false_cert_verify.yaml:
--------------------------------------------------------------------------------
1 | auth_url: 'http://1.2.3.4:5000'
2 | username: 'xyz'
3 | password: '12345'
4 | project_name: 'abc'
5 | project_domain_name: 'prj_domain_name'
6 | user_domain_name: 'user_domain_name'
7 | cert_verify: 'False'
8 | type: 'openstack'
--------------------------------------------------------------------------------
/releasenotes/notes/drop-py-2-7-b2052825c4b92b52.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | upgrade:
3 | - |
4 | Python 2.7 support has been dropped. Last release of python-tackerclient
5 | to support python 2.7 is OpenStack Train. The minimum version of Python now
6 | supported by python-tackerclient is Python 3.6.
7 |
--------------------------------------------------------------------------------
/releasenotes/notes/deprecated-tacker-command-29121558bd748082.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | deprecations:
3 | - |
4 | tacker CLI is deprecated, will be deleted after Rocky release.
5 | Use `openstack CLI`_ instead.
6 |
7 | .. _openstack CLI: https://docs.openstack.org/python-tackerclient/latest/cli/index.html
8 |
--------------------------------------------------------------------------------
/releasenotes/notes/network-services-descriptor-06f6abe90adb40f3.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - |
4 | CLIs to onboard Network Services Descriptor (NSD) based on TOSCA Simple
5 | Profile for NFV and to create Network Services using NSD to create multiple
6 | related VNFs using a single TOSCA template.
7 |
--------------------------------------------------------------------------------
/releasenotes/notes/deprecate-direct-yaml-cli-input-812564bab1b99b4b.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | deprecations:
3 | - |
4 | Direct YAML input of any kind is now deprecated. Only file based YAML
5 | input is supported. This deprecation is across all resources like VNFFGD
6 | template, VNFD template and VNF configuration input.
7 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/sample_vnf_package_artifacts/TOSCA-Metadata/TOSCA.meta:
--------------------------------------------------------------------------------
1 | TOSCA-Meta-File-Version: 1.0
2 | Created-by: Dummy User
3 | CSAR-Version: 1.1
4 | Entry-Definitions: Definitions/helloworld3_top.vnfd.yaml
5 |
6 | Source: Scripts/install.sh
7 | Algorithm: SHA-256
8 | Hash: 27bbdb25d8f4ed6d07d6f6581b86515e8b2f0059b236ef7b6f50d6674b34f02a
9 |
--------------------------------------------------------------------------------
/doc/requirements.txt:
--------------------------------------------------------------------------------
1 | # The order of packages is significant, because pip processes them in the order
2 | # of appearance. Changing the order has an impact on the overall integration
3 | # process, which may cause wedges in the gate later.
4 | # These are needed for docs generation
5 | sphinx>=2.0.0,!=2.1.0 # BSD
6 | openstackdocstheme>=2.2.1 # Apache-2.0
7 | reno>=3.1.0 # Apache-2.0
8 |
--------------------------------------------------------------------------------
/releasenotes/notes/add-vnffg-and-vnf-ids-to-ns-list-commands-9d462efc103f8ecb.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | features:
3 | - |
4 | Add 'vnf_ids' and 'vnffg_ids' fields in outputs from network
5 | service list command. Users can know which VNFs or VNFFGs,
6 | belongs to specific NS.
7 | Add 'ns_id' field to VNFFG list command, that shows the
8 | network service the current VNFFG belongs to.
9 |
10 |
--------------------------------------------------------------------------------
/releasenotes/source/index.rst:
--------------------------------------------------------------------------------
1 | Python-TackerClient Release Notes
2 | =================================
3 |
4 | Contents:
5 |
6 | .. toctree::
7 | :maxdepth: 2
8 |
9 | unreleased
10 | 2025.2
11 | 2025.1
12 | 2024.2
13 | 2024.1
14 | 2023.2
15 | 2023.1
16 | zed
17 | yoga
18 | xena
19 | wallaby
20 | victoria
21 | ussuri
22 | train
23 | stein
24 | rocky
25 | queens
26 | pike
27 | ocata
28 | newton
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.DS_Store
3 | *.egg
4 | *.sw?
5 | AUTHORS
6 | ChangeLog
7 | build/*
8 | build-stamp
9 | cover/*
10 | doc/build/
11 | doc/source/api/
12 | python_tackerclient.egg-info/*
13 | tacker/vcsversion.py
14 | tackerclient/versioninfo
15 | run_tests.err.log
16 | run_tests.log
17 | .autogenerated
18 | .coverage
19 | .testrepository/
20 | .idea/
21 | .tox/
22 | .venv/
23 | .stestr/
24 |
25 | # Files created by releasenotes build
26 | releasenotes/build
27 |
--------------------------------------------------------------------------------
/test-requirements.txt:
--------------------------------------------------------------------------------
1 | # The order of packages is significant, because pip processes them in the order
2 | # of appearance. Changing the order has an impact on the overall integration
3 | # process, which may cause wedges in the gate later.
4 |
5 | hacking>=7.0.0,<7.1.0 # Apache-2.0
6 | coverage!=4.4,>=4.0 # Apache-2.0
7 | ddt>=1.0.1 # MIT
8 | fixtures>=3.0.0 # Apache-2.0/BSD
9 | python-subunit>=1.0.0 # Apache-2.0/BSD
10 | requests-mock>=1.2.0 # Apache-2.0
11 | stestr>=2.0.0 # Apache-2.0
12 | testtools>=2.2.0 # MIT
13 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnfpm/samples/update_vnf_pm_job_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "callbackUri": "/nfvo/notify/job",
3 | "authentication": {
4 | "authType": [
5 | "BASIC",
6 | "OAUTH2_CLIENT_CREDENTIALS"
7 | ],
8 | "paramsBasic": {
9 | "userName": "nfvo",
10 | "password": "nfvopwd"
11 | },
12 | "paramsOauth2ClientCredentials": {
13 | "clientId": "auth_user_name",
14 | "clientPassword": "auth_password",
15 | "tokenEndpoint": "token_endpoint"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/CONTRIBUTING.rst:
--------------------------------------------------------------------------------
1 | If you would like to contribute to the development of OpenStack,
2 | you must follow the steps in this page:
3 |
4 | https://docs.openstack.org/infra/manual/developers.html
5 |
6 | Once those steps have been completed, changes to OpenStack
7 | should be submitted for review via the Gerrit tool, following
8 | the workflow documented at:
9 |
10 | https://docs.openstack.org/infra/manual/developers.html#development-workflow
11 |
12 | Pull requests submitted through GitHub will be ignored.
13 |
14 | Bugs should be filed on Launchpad, not GitHub:
15 |
16 | https://bugs.launchpad.net/python-tackerclient
17 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | # The order of packages is significant, because pip processes them in the order
2 | # of appearance. Changing the order has an impact on the overall integration
3 | # process, which may cause wedges in the gate later.
4 | pbr!=2.1.0,>=2.0.0 # Apache-2.0
5 | cliff!=2.9.0,>=2.8.0 # Apache-2.0
6 | iso8601>=0.1.11 # MIT
7 | netaddr>=0.7.18 # BSD
8 | requests>=2.14.2 # Apache-2.0
9 | python-keystoneclient>=3.8.0 # Apache-2.0
10 | stevedore>=1.20.0 # Apache-2.0
11 | Babel!=2.4.0,>=2.3.4 # BSD
12 | oslo.i18n>=3.15.3 # Apache-2.0
13 | osc-lib>=1.8.0 # Apache-2.0
14 | oslo.utils>=3.40.0 # Apache-2.0
15 | oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
16 |
--------------------------------------------------------------------------------
/doc/source/contributor/contributing.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | ============
15 | Contributing
16 | ============
17 |
18 | .. include:: ../../../CONTRIBUTING.rst
19 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 | # implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import setuptools
17 |
18 | setuptools.setup(
19 | setup_requires=['pbr>=2.0.0'],
20 | pbr=True)
21 |
--------------------------------------------------------------------------------
/tackerclient/common/constants.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2012 OpenStack Foundation.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 | # implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 |
17 | TYPE_BOOL = "bool"
18 | TYPE_INT = "int"
19 | TYPE_FLOAT = "float"
20 | TYPE_LIST = "list"
21 | TYPE_DICT = "dict"
22 |
--------------------------------------------------------------------------------
/tackerclient/i18n.py:
--------------------------------------------------------------------------------
1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 | # not use this file except in compliance with the License. You may obtain
3 | # a copy of the License at
4 | #
5 | # http://www.apache.org/licenses/LICENSE-2.0
6 | #
7 | # Unless required by applicable law or agreed to in writing, software
8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 | # License for the specific language governing permissions and limitations
11 | # under the License.
12 |
13 | import oslo_i18n as i18n
14 |
15 | _translators = i18n.TranslatorFactory(domain='tackerclient')
16 |
17 | # The primary translation function using the well-known name "_"
18 | _ = _translators.primary
19 |
--------------------------------------------------------------------------------
/doc/source/cli/vim_commands.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | =======================
15 | VIM Management commands
16 | =======================
17 |
18 | .. autoprogram-cliff:: openstack.tackerclient.v1
19 | :command: vim *
20 |
--------------------------------------------------------------------------------
/tackerclient/version.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import pbr.version
17 |
18 |
19 | __version__ = pbr.version.VersionInfo('python-tackerclient').version_string()
20 |
--------------------------------------------------------------------------------
/doc/source/reference/index.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | =========
15 | Reference
16 | =========
17 |
18 | - `Tacker API reference `_
19 | - `Tacker CLI reference `_
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnfpm/samples/update_vnf_pm_threshold_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "callbackUri": "/nfvo/notify/threshold",
3 | "authentication": {
4 | "authType": [
5 | "BASIC",
6 | "OAUTH2_CLIENT_CREDENTIALS",
7 | "OAUTH2_CLIENT_CERT"
8 | ],
9 | "paramsBasic": {
10 | "userName": "nfvo",
11 | "password": "nfvopwd"
12 | },
13 | "paramsOauth2ClientCredentials": {
14 | "clientId": "auth_user_name",
15 | "clientPassword": "auth_password",
16 | "tokenEndpoint": "token_endpoint"
17 | },
18 | "paramsOauth2ClientCert": {
19 | "clientId": "test",
20 | "certificateRef": {
21 | "type": "x5t#256",
22 | "value": "03c6e188d1fe5d3da8c9bc9a8dc531a2b3e"
23 | },
24 | "tokenEndpoint": "http://127.0.0.1/token"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/doc/source/contributor/index.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | =================
15 | Contributor Guide
16 | =================
17 |
18 | In the Contributor Guide, you will find information on tackerclient's
19 | lower level programming details or APIs as well as the transition to
20 | OpenStack client.
21 |
22 | .. toctree::
23 | :maxdepth: 2
24 |
25 | contributing.rst
26 | developing.rst
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tools/tacker.bash_completion:
--------------------------------------------------------------------------------
1 | _tacker_opts="" # lazy init
2 | _tacker_flags="" # lazy init
3 | _tacker_opts_exp="" # lazy init
4 | _tacker()
5 | {
6 | local cur prev nbc cflags
7 | COMPREPLY=()
8 | cur="${COMP_WORDS[COMP_CWORD]}"
9 | prev="${COMP_WORDS[COMP_CWORD-1]}"
10 |
11 | if [ "x$_tacker_opts" == "x" ] ; then
12 | nbc="`tacker bash-completion`"
13 | _tacker_opts="`echo "$nbc" | sed -e "s/--[a-z0-9_-]*//g" -e "s/\s\s*/ /g"`"
14 | _tacker_flags="`echo " $nbc" | sed -e "s/ [^-][^-][a-z0-9_-]*//g" -e "s/\s\s*/ /g"`"
15 | _tacker_opts_exp="`echo "$_tacker_opts" | sed -e "s/\s/|/g"`"
16 | fi
17 |
18 | if [[ " ${COMP_WORDS[@]} " =~ " "($_tacker_opts_exp)" " && "$prev" != "help" ]] ; then
19 | COMPLETION_CACHE=~/.tackerclient/*/*-cache
20 | cflags="$_tacker_flags "$(cat $COMPLETION_CACHE 2> /dev/null | tr '\n' ' ')
21 | COMPREPLY=($(compgen -W "${cflags}" -- ${cur}))
22 | else
23 | COMPREPLY=($(compgen -W "${_tacker_opts}" -- ${cur}))
24 | fi
25 | return 0
26 | }
27 | complete -F _tacker tacker
28 |
--------------------------------------------------------------------------------
/doc/source/cli/vnf_package_commands.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | ====================
15 | VNF Package commands
16 | ====================
17 |
18 | VNF Package commands are CLI interface of VNF Package Management Interface in
19 | `ETSI NFV-SOL 005 `_.
20 |
21 | .. autoprogram-cliff:: openstack.tackerclient.v1
22 | :command: vnf package *
23 |
--------------------------------------------------------------------------------
/doc/source/cli/index.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | =========
15 | CLI Usage
16 | =========
17 |
18 | Command List
19 | ------------
20 |
21 | .. toctree::
22 |
23 | commands
24 |
25 | Operations for ETSI NFV-SOL implementation
26 | ------------------------------------------
27 |
28 | .. toctree::
29 |
30 | vnf_package_commands
31 | vnflcm_commands
32 | vnffm_commands
33 | vnfpm_commands
34 |
35 | Operations for Legacy implementation
36 | ------------------------------------
37 |
38 | .. toctree::
39 |
40 | vim_commands
41 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnfpm/samples/create_vnf_pm_job_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "objectType": "VNFC",
3 | "objectInstanceIds": [
4 | "object-instance-id-1"
5 | ],
6 | "subObjectInstanceIds": [
7 | "sub-object-instance-id-2"
8 | ],
9 | "criteria": {
10 | "performanceMetric": [
11 | "VCpuUsageMeanVnf.object-instance-id-1"
12 | ],
13 | "performanceMetricGroup": [
14 | "VirtualisedComputeResource"
15 | ],
16 | "collectionPeriod": "500",
17 | "reportingPeriod": "1000",
18 | "reportingBoundary": "2022/07/25 10:43:55"
19 | },
20 | "callbackUri": "/nfvo/notify/job",
21 | "authentication": {
22 | "authType": [
23 | "BASIC",
24 | "OAUTH2_CLIENT_CREDENTIALS"
25 | ],
26 | "paramsBasic": {
27 | "userName": "nfvo",
28 | "password": "nfvopwd"
29 | },
30 | "paramsOauth2ClientCredentials": {
31 | "clientId": "auth_user_name",
32 | "clientPassword": "auth_password",
33 | "tokenEndpoint": "token_endpoint"
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/sample_vnf_package/Definitions/helloworld3_top.vnfd.yaml:
--------------------------------------------------------------------------------
1 | tosca_definitions_version: tosca_simple_yaml_1_0
2 |
3 | description: Sample VNF of NTT NS lab.
4 |
5 | imports:
6 | - etsi_nfv_sol001_common_types.yaml
7 | - etsi_nfv_sol001_vnfd_types.yaml
8 | - helloworld3_types.yaml
9 | - helloworld3_df_simple.yaml
10 | # - helloworld3_df_complex.yaml
11 |
12 | topology_template:
13 | inputs:
14 | selected_flavour:
15 | type: string
16 | description: VNF deployment flavour selected by the consumer. It is provided in the API
17 |
18 | node_templates:
19 | VNF:
20 | type: ntt.nslab.VNF
21 | properties:
22 | flavour_id: { get_input: selected_flavour }
23 | descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177
24 | provider: NTT NS lab
25 | product_name: Sample VNF
26 | software_version: '1.0'
27 | descriptor_version: '1.0'
28 | vnfm_info:
29 | - Tacker
30 | requirements:
31 | #- virtual_link_external # mapped in lower-level templates
32 | #- virtual_link_internal # mapped in lower-level templates
33 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/sample_vnf_package_artifacts/Definitions/helloworld3_top.vnfd.yaml:
--------------------------------------------------------------------------------
1 | tosca_definitions_version: tosca_simple_yaml_1_0
2 |
3 | description: Sample VNF of NTT NS lab.
4 |
5 | imports:
6 | - etsi_nfv_sol001_common_types.yaml
7 | - etsi_nfv_sol001_vnfd_types.yaml
8 | - helloworld3_types.yaml
9 | - helloworld3_df_simple.yaml
10 | # - helloworld3_df_complex.yaml
11 |
12 | topology_template:
13 | inputs:
14 | selected_flavour:
15 | type: string
16 | description: VNF deployment flavour selected by the consumer. It is provided in the API
17 |
18 | node_templates:
19 | VNF:
20 | type: ntt.nslab.VNF
21 | properties:
22 | flavour_id: { get_input: selected_flavour }
23 | descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177
24 | provider: NTT NS lab
25 | product_name: Sample VNF
26 | software_version: '1.0'
27 | descriptor_version: '1.0'
28 | vnfm_info:
29 | - Tacker
30 | requirements:
31 | #- virtual_link_external # mapped in lower-level templates
32 | #- virtual_link_internal # mapped in lower-level templates
33 |
--------------------------------------------------------------------------------
/HACKING.rst:
--------------------------------------------------------------------------------
1 | Tacker Style Commandments
2 | =========================
3 |
4 | - Step 1: Read the OpenStack Style Commandments
5 | https://docs.openstack.org/hacking/latest
6 | - Step 2: Read on
7 |
8 |
9 | Running Tests
10 | -------------
11 | The testing system is based on a combination of tox and stestr. The canonical
12 | approach to running tests is to simply run the command ``tox``. This will
13 | create virtual environments, populate them with dependencies and run all of
14 | the tests that OpenStack CI systems run. Behind the scenes, tox is running
15 | ``stestr run``, but is set up such that you can supply any additional
16 | stestr arguments that are needed to tox. For example, you can run:
17 | ``tox -- --analyze-isolation`` to cause tox to tell stestr to add
18 | --analyze-isolation to its argument list.
19 |
20 | It is also possible to run the tests inside of a virtual environment
21 | you have created, or it is possible that you have all of the dependencies
22 | installed locally already. In this case, you can interact with the stestr
23 | command directly. Running ``stestr run`` will run the entire test suite.
24 | ``stestr run --concurrency=1`` will run tests serially (by default, stestr runs
25 | tests in parallel). More information about stestr can be found at:
26 | http://stestr.readthedocs.io/
27 |
--------------------------------------------------------------------------------
/doc/source/cli/vnffm_commands.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | ===============
15 | VNF FM commands
16 | ===============
17 |
18 | VNF FM commands are CLI interface of VNF Fault Management interface in
19 | `ETSI NFV-SOL 002 `_
20 | and `ETSI NFV-SOL 003 `_.
21 |
22 | .. note::
23 | Commands only support calling version 2 vnffm APIs.
24 | You can use the commands with **\-\-os-tacker-api-version 2** to
25 | call version 2 vnffm APIs.
26 |
27 | .. autoprogram-cliff:: openstack.tackerclient.v2
28 | :command: vnffm *
29 |
--------------------------------------------------------------------------------
/doc/source/cli/vnfpm_commands.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | ===============
15 | VNF PM commands
16 | ===============
17 |
18 | VNF PM commands are CLI interface of VNF Performance Management interface in
19 | `ETSI NFV-SOL 002 `_
20 | and `ETSI NFV-SOL 003 `_.
21 |
22 | .. note::
23 | Commands only support calling version 2 vnfpm APIs.
24 | You can use the commands with **\-\-os-tacker-api-version 2** to
25 | call version 2 vnfpm APIs.
26 |
27 | .. autoprogram-cliff:: openstack.tackerclient.v2
28 | :command: vnfpm *
29 |
--------------------------------------------------------------------------------
/tackerclient/common/_i18n.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 OpenStack Foundation
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 | # not use this file except in compliance with the License. You may obtain
5 | # a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | # License for the specific language governing permissions and limitations
13 | # under the License.
14 |
15 | """oslo.i18n integration module.
16 |
17 | See https://docs.openstack.org/oslo.i18n/latest/user/index.html.
18 |
19 | """
20 |
21 | import oslo_i18n
22 |
23 | DOMAIN = "tackerclient"
24 |
25 | _translators = oslo_i18n.TranslatorFactory(domain=DOMAIN)
26 |
27 | # The primary translation function using the well-known name "_"
28 | _ = _translators.primary
29 |
30 | # The contextual translation function using the name "_C"
31 | # requires oslo.i18n >=2.1.0
32 | _C = _translators.contextual_form
33 |
34 | # The plural translation function using the name "_P"
35 | # requires oslo.i18n >=2.1.0
36 | _P = _translators.plural_form
37 |
38 |
39 | def get_available_languages():
40 | return oslo_i18n.get_available_languages(DOMAIN)
41 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnflcm/samples/change_vnfpkg_vnf_instance_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "vnfdId": "c6595341-a5bb-8246-53c4-7aeb843d60c5",
3 | "additionalParams": {
4 | "upgrade_type": "RollingUpdate",
5 | "lcm-operation-coordinate-old-vnf": "./Scripts/coordinate_old_vnf.py",
6 | "lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
7 | "lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_new_vnf.py",
8 | "lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
9 | "vdu_params": [{
10 | "vduId": "VDU1",
11 | "old_vnfc_param": {
12 | "cp_name": "VDU1_CP1",
13 | "username": "ubuntu",
14 | "password": "ubuntu"
15 | },
16 | "new_vnfc_param": {
17 | "cp_name": "VDU1_CP1",
18 | "username": "ubuntu",
19 | "password": "ubuntu"
20 | }
21 | }, {
22 | "vduId": "VDU2",
23 | "old_vnfc_param": {
24 | "cp_name": "VDU2_CP1",
25 | "username": "ubuntu",
26 | "password": "ubuntu"
27 | },
28 | "new_vnfc_param": {
29 | "cp_name": "VDU2_CP1",
30 | "username": "ubuntu",
31 | "password": "ubuntu"
32 | }
33 | }]
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnfpm/samples/create_vnf_pm_threshold_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "objectType": "Vnfc",
3 | "objectInstanceId": "object-instance-id-1",
4 | "subObjectInstanceIds": [
5 | "sub-object-instance-id-2"
6 | ],
7 | "criteria": {
8 | "performanceMetric": "VCpuUsageMeanVnf.object-instance-id-1",
9 | "thresholdType": "SIMPLE",
10 | "simpleThresholdDetails": {
11 | "thresholdValue": 400.5,
12 | "hysteresis": 10.3
13 | }
14 | },
15 | "callbackUri": "/nfvo/notify/threshold",
16 | "authentication": {
17 | "authType": [
18 | "BASIC",
19 | "OAUTH2_CLIENT_CREDENTIALS",
20 | "OAUTH2_CLIENT_CERT"
21 | ],
22 | "paramsBasic": {
23 | "userName": "nfvo",
24 | "password": "nfvopwd"
25 | },
26 | "paramsOauth2ClientCredentials": {
27 | "clientId": "auth_user_name",
28 | "clientPassword": "auth_password",
29 | "tokenEndpoint": "token_endpoint"
30 | },
31 | "paramsOauth2ClientCert": {
32 | "clientId": "test",
33 | "certificateRef": {
34 | "type": "x5t#256",
35 | "value": "03c6e188d1fe5d3da8c9bc9a8dc531a2b3e"
36 | },
37 | "tokenEndpoint": "http://127.0.0.1/token"
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tackerclient/common/command.py:
--------------------------------------------------------------------------------
1 | # Copyright 2012 OpenStack Foundation.
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 | #
16 |
17 | from sys import stderr
18 |
19 | from cliff import command
20 |
21 |
22 | class OpenStackCommand(command.Command):
23 | """Base class for OpenStack commands."""
24 |
25 | api = None
26 |
27 | def run(self, parsed_args):
28 | stderr.write("Deprecated: tacker command line is deprecated, "
29 | "will be deleted after Rocky is released.\n")
30 | if not self.api:
31 | return
32 | else:
33 | return super(OpenStackCommand, self).run(parsed_args)
34 |
35 | def get_data(self, parsed_args):
36 | pass
37 |
38 | def take_action(self, parsed_args):
39 | return self.get_data(parsed_args)
40 |
--------------------------------------------------------------------------------
/doc/source/index.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | =================================
15 | Python-TackerClient Documentation
16 | =================================
17 |
18 | Python-TackerClient is a client for OpenStack NFV MANO (Tacker) API.
19 | It provides
20 | :doc:`Python API bindings ` (the tackerclient module) and
21 | :doc:`command-line interface (CLI) `.
22 |
23 | Contents
24 | --------
25 |
26 | .. toctree::
27 | :maxdepth: 2
28 |
29 | install/index
30 | cli/index
31 | contributor/index
32 | reference/index
33 |
34 |
35 | Release Notes
36 | -------------
37 |
38 | .. toctree::
39 | :maxdepth: 1
40 |
41 | Release Notes
42 |
43 |
44 | Indices and Tables
45 | ------------------
46 |
47 | * :ref:`genindex`
48 | * :ref:`search`
49 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/test_command_meta.py:
--------------------------------------------------------------------------------
1 | # Copyright 2013 Intel Corporation
2 | # All Rights Reserved.
3 | #
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | import logging
18 |
19 | import testtools
20 |
21 | from tackerclient.tacker import v1_0 as tackerV10
22 |
23 |
24 | class TestCommandMeta(testtools.TestCase):
25 | def test_tacker_command_meta_defines_log(self):
26 | class FakeCommand(tackerV10.TackerCommand):
27 | pass
28 |
29 | self.assertTrue(hasattr(FakeCommand, 'log'))
30 | self.assertIsInstance(FakeCommand.log, logging.getLoggerClass())
31 | self.assertEqual(FakeCommand.log.name, __name__ + ".FakeCommand")
32 |
33 | def test_tacker_command_log_defined_explicitly(self):
34 | class FakeCommand(tackerV10.TackerCommand):
35 | log = None
36 |
37 | self.assertTrue(hasattr(FakeCommand, 'log'))
38 | self.assertIsNone(FakeCommand.log)
39 |
--------------------------------------------------------------------------------
/.pylintrc:
--------------------------------------------------------------------------------
1 | # The format of this file isn't really documented; just use --generate-rcfile
2 | [MASTER]
3 | # Add to the black list. It should be a base name, not a
4 | # path. You may set this option multiple times.
5 | ignore=test
6 |
7 | [Messages Control]
8 | # NOTE(justinsb): We might want to have a 2nd strict pylintrc in future
9 | # C0111: Don't require docstrings on every method
10 | # W0511: TODOs in code comments are fine.
11 | # W0142: *args and **kwargs are fine.
12 | # W0622: Redefining id is fine.
13 | disable=C0111,W0511,W0142,W0622
14 |
15 | [Basic]
16 | # Variable names can be 1 to 31 characters long, with lowercase and underscores
17 | variable-rgx=[a-z_][a-z0-9_]{0,30}$
18 |
19 | # Argument names can be 2 to 31 characters long, with lowercase and underscores
20 | argument-rgx=[a-z_][a-z0-9_]{1,30}$
21 |
22 | # Method names should be at least 3 characters long
23 | # and be lowecased with underscores
24 | method-rgx=([a-z_][a-z0-9_]{2,50}|setUp|tearDown)$
25 |
26 | # Module names matching quantum-* are ok (files in bin/)
27 | module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(quantum-[a-z0-9_-]+))$
28 |
29 | # Don't require docstrings on tests.
30 | no-docstring-rgx=((__.*__)|([tT]est.*)|setUp|tearDown)$
31 |
32 | [Design]
33 | max-public-methods=100
34 | min-public-methods=0
35 | max-args=6
36 |
37 | [Variables]
38 |
39 | # List of additional names supposed to be defined in builtins. Remember that
40 | # you should avoid to define new builtins when possible.
41 | # _ is used by our localization
42 | additional-builtins=_
43 |
--------------------------------------------------------------------------------
/doc/source/cli/vnflcm_commands.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | ================
15 | VNF Lcm commands
16 | ================
17 |
18 | VNF LCM commands are CLI interface of VNF Lifecycle Management Interface in
19 | `ETSI NFV-SOL 002 `_
20 | and `ETSI NFV-SOL 003 `_.
21 |
22 | .. note::
23 | Commands call version 1 vnflcm APIs by default.
24 | You can call the specific version of vnflcm APIs
25 | by using the option **\-\-os-tacker-api-version**.
26 | Commands with **\-\-os-tacker-api-version 2** call version 2 vnflcm APIs.
27 | **vnflcm op cancel** is included in only version 1 vnflcm APIs
28 | and **change-vnfpkg** is included in only version 2 vnflcm APIs.
29 |
30 | .. autoprogram-cliff:: openstack.tackerclient.v1
31 | :command: vnflcm *
32 |
33 | .. autoprogram-cliff:: openstack.tackerclient.v2
34 | :command: vnflcm change-vnfpkg
35 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py39,py38,py36,pep8,docs
3 | minversion = 3.18.0
4 | ignore_basepython_conflict = True
5 |
6 | [testenv]
7 | basepython = python3
8 | setenv = VIRTUAL_ENV={envdir}
9 | LANG=en_US.UTF-8
10 | LANGUAGE=en_US:en
11 | LC_ALL=C
12 | usedevelop = True
13 | deps =
14 | -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
15 | -r{toxinidir}/requirements.txt
16 | -r{toxinidir}/test-requirements.txt
17 | commands = stestr run --slowest {posargs}
18 |
19 | [testenv:pep8]
20 | commands = flake8
21 | distribute = false
22 |
23 | [testenv:venv]
24 | commands = {posargs}
25 |
26 | [testenv:docs]
27 | deps = -r{toxinidir}/doc/requirements.txt
28 | commands = sphinx-build -W -b html doc/source doc/build/html
29 |
30 | [testenv:releasenotes]
31 | deps =
32 | -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
33 | -r{toxinidir}/doc/requirements.txt
34 | commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
35 |
36 | [testenv:cover]
37 | setenv =
38 | PYTHON=coverage run --source tackerclient --parallel-mode
39 | commands =
40 | stestr run {posargs}
41 | coverage combine
42 | coverage html -d cover
43 | coverage xml -o cover/coverage.xml
44 |
45 | [flake8]
46 | # E125 continuation line does not distinguish itself from next logical line
47 | # W504 line break after binary operator
48 | ignore = E125,W504
49 | show-source = true
50 | exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,tools
51 | # F821 undefined name 'unicode'
52 | # if isinstance(config, str) or isinstance(config, unicode):
53 | builtins = unicode
54 |
--------------------------------------------------------------------------------
/doc/source/contributor/developing.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | ===================================
15 | Developing with Python-TackerClient
16 | ===================================
17 |
18 | Project Info
19 | ============
20 |
21 | * **Free software:** under the `Apache license `_
22 | * **Tacker Service:** https://opendev.org/openstack/tacker
23 | * **Tacker Client Library:** https://opendev.org/openstack/python-tackerclient
24 | * **Tacker Service Bugs:** https://bugs.launchpad.net/tacker
25 | * **Client Bugs:** https://bugs.launchpad.net/python-tackerclient
26 | * **Blueprints:** https://blueprints.launchpad.net/tacker
27 |
28 | Meetings
29 | ========
30 | For details please refer to the `OpenStack IRC meetings`_ page.
31 |
32 | .. _`OpenStack IRC meetings`: http://eavesdrop.openstack.org/#Tacker_(NFV_Orchestrator_and_VNF_Manager)_Team_Meeting
33 |
34 | Testing
35 | =======
36 |
37 | For details please refer to the `Developing with OpenStackClient`_ page.
38 |
39 | .. _`Developing with OpenStackClient`: https://docs.openstack.org/python-openstackclient/latest/contributor/developing.html
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/sample_vnf_package/Definitions/helloworld3_types.yaml:
--------------------------------------------------------------------------------
1 | tosca_definitions_version: tosca_simple_yaml_1_0
2 |
3 | description: ntt.nslab.VNF type definition
4 |
5 | imports:
6 | - etsi_nfv_sol001_common_types.yaml
7 | - etsi_nfv_sol001_vnfd_types.yaml
8 |
9 | node_types:
10 | ntt.nslab.VNF:
11 | derived_from: tosca.nodes.nfv.VNF
12 | properties:
13 | descriptor_id:
14 | type: string
15 | constraints: [ valid_values: [ b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 ] ]
16 | default: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177
17 | descriptor_version:
18 | type: string
19 | constraints: [ valid_values: [ '1.0' ] ]
20 | default: '1.0'
21 | provider:
22 | type: string
23 | constraints: [ valid_values: [ 'NTT NS lab' ] ]
24 | default: 'NTT NS lab'
25 | product_name:
26 | type: string
27 | constraints: [ valid_values: [ 'Sample VNF' ] ]
28 | default: 'Sample VNF'
29 | software_version:
30 | type: string
31 | constraints: [ valid_values: [ '1.0' ] ]
32 | default: '1.0'
33 | vnfm_info:
34 | type: list
35 | entry_schema:
36 | type: string
37 | constraints: [ valid_values: [ Tacker ] ]
38 | default: [ Tacker ]
39 | flavour_id:
40 | type: string
41 | constraints: [ valid_values: [ simple ] ]
42 | default: simple
43 | flavour_description:
44 | type: string
45 | default: ""
46 | requirements:
47 | - virtual_link_external:
48 | capability: tosca.capabilities.nfv.VirtualLinkable
49 | - virtual_link_internal:
50 | capability: tosca.capabilities.nfv.VirtualLinkable
51 | interfaces:
52 | Vnflcm:
53 | type: tosca.interfaces.nfv.Vnflcm
54 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/sample_vnf_package_artifacts/Definitions/helloworld3_types.yaml:
--------------------------------------------------------------------------------
1 | tosca_definitions_version: tosca_simple_yaml_1_0
2 |
3 | description: ntt.nslab.VNF type definition
4 |
5 | imports:
6 | - etsi_nfv_sol001_common_types.yaml
7 | - etsi_nfv_sol001_vnfd_types.yaml
8 |
9 | node_types:
10 | ntt.nslab.VNF:
11 | derived_from: tosca.nodes.nfv.VNF
12 | properties:
13 | descriptor_id:
14 | type: string
15 | constraints: [ valid_values: [ b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 ] ]
16 | default: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177
17 | descriptor_version:
18 | type: string
19 | constraints: [ valid_values: [ '1.0' ] ]
20 | default: '1.0'
21 | provider:
22 | type: string
23 | constraints: [ valid_values: [ 'NTT NS lab' ] ]
24 | default: 'NTT NS lab'
25 | product_name:
26 | type: string
27 | constraints: [ valid_values: [ 'Sample VNF' ] ]
28 | default: 'Sample VNF'
29 | software_version:
30 | type: string
31 | constraints: [ valid_values: [ '1.0' ] ]
32 | default: '1.0'
33 | vnfm_info:
34 | type: list
35 | entry_schema:
36 | type: string
37 | constraints: [ valid_values: [ Tacker ] ]
38 | default: [ Tacker ]
39 | flavour_id:
40 | type: string
41 | constraints: [ valid_values: [ simple ] ]
42 | default: simple
43 | flavour_description:
44 | type: string
45 | default: ""
46 | requirements:
47 | - virtual_link_external:
48 | capability: tosca.capabilities.nfv.VirtualLinkable
49 | - virtual_link_internal:
50 | capability: tosca.capabilities.nfv.VirtualLinkable
51 | interfaces:
52 | Vnflcm:
53 | type: tosca.interfaces.nfv.Vnflcm
54 |
--------------------------------------------------------------------------------
/doc/source/install/index.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | ============
15 | Installation
16 | ============
17 |
18 | This document describes how to install python-tackerclient.
19 |
20 | .. note::
21 |
22 | This installation guide contents are specific to Ubuntu distro.
23 |
24 | Using python install
25 | ====================
26 |
27 | #. Clone python-tackerclient repository.
28 |
29 | You can use -b for specific release, optionally.
30 |
31 | .. code-block:: console
32 |
33 | $ cd ~/
34 | $ git clone https://opendev.org/openstack/python-tackerclient -b
35 |
36 | .. note::
37 |
38 | Make sure to replace the ```` in command example with
39 | specific branch name, such as ``stable/victoria``.
40 |
41 | #. Install python-tackerclient.
42 |
43 | .. code-block:: console
44 |
45 | $ cd python-tackerclient
46 | $ sudo python3 setup.py install
47 |
48 | Using pip
49 | =========
50 |
51 | You can also install the latest version by using ``pip`` command:
52 |
53 | .. code-block:: console
54 |
55 | $ pip3 install python-tackerclient
56 |
57 | Or, if it is needed to install ``python-tackerclient`` from master branch,
58 | type
59 |
60 | .. code-block:: console
61 |
62 | $ pip3 install git+https://opendev.org/openstack/python-tackerclient
63 |
64 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ========================
2 | Team and repository tags
3 | ========================
4 |
5 | .. image:: https://governance.openstack.org/tc/badges/python-tackerclient.svg
6 | :target: https://governance.openstack.org/tc/reference/tags/index.html
7 |
8 | .. Change things from this point on
9 |
10 | NFV Orchestration (Tacker) Client
11 | =================================
12 |
13 | CLI and Client Library for OpenStack Tacker
14 |
15 | Installation
16 | ============
17 |
18 | **Note:** The paths we are using for configuration files in these steps
19 | are with reference to Ubuntu Operating System. The paths may vary for
20 | other Operating Systems.
21 |
22 | The branch_name which is used in commands, specify the branch_name
23 | as stable/ for any stable branch installation. For eg:
24 | stable/queens, stable/pike. If unspecified the default will be
25 | master branch.
26 |
27 | Using python install
28 | --------------------
29 | Clone python-tackerclient repository.
30 |
31 | ::
32 |
33 | $ cd ~/
34 | $ git clone https://github.com/openstack/python-tackerclient -b
35 |
36 |
37 | Install python-tackerclient.
38 |
39 | ::
40 |
41 | $ cd python-tackerclient
42 | $ sudo python setup.py install
43 |
44 |
45 | Using pip
46 | ---------
47 |
48 | You can also install the latest version by using ``pip`` command:
49 |
50 | ::
51 |
52 | $ pip install python-tackerclient
53 |
54 |
55 | Or, if it is needed to install ``python-tackerclient`` from master branch,
56 | type
57 |
58 | ::
59 |
60 | $ pip install git+https://github.com/openstack/python-tackerclient.git
61 |
62 |
63 | More Information
64 | ================
65 |
66 | * Python-tackerclient documentation: https://docs.openstack.org/python-tackerclient/latest/
67 | * Tacker Documentation: https://docs.openstack.org/tacker/latest/
68 | * Tacker Wiki: https://wiki.openstack.org/wiki/Tacker
69 | * Release Notes: https://docs.openstack.org/releasenotes/python-tackerclient
70 |
--------------------------------------------------------------------------------
/tackerclient/osc/common/vnflcm/vnflcm_versions.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2021 Nippon Telegraph and Telephone Corporation
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from osc_lib.command import command
17 |
18 | from tackerclient.common import exceptions
19 | from tackerclient.i18n import _
20 |
21 |
22 | SUPPORTED_VERSIONS = [1, 2]
23 |
24 |
25 | class VnfLcmVersions(command.ShowOne):
26 | _description = _("Show VnfLcm Api versions")
27 |
28 | def get_parser(self, prog_name):
29 | parser = super(VnfLcmVersions, self).get_parser(prog_name)
30 | parser.add_argument(
31 | '--major-version',
32 | metavar="",
33 | type=int,
34 | help=_('Show only specify major version.'))
35 | return parser
36 |
37 | def take_action(self, parsed_args):
38 | v = None
39 | if parsed_args.major_version:
40 | if parsed_args.major_version not in SUPPORTED_VERSIONS:
41 | msg = _("Major version %d is not supported")
42 | reason = msg % parsed_args.major_version
43 | raise exceptions.InvalidInput(reason=reason)
44 | v = "v{}".format(parsed_args.major_version)
45 |
46 | client = self.app.client_manager.tackerclient
47 | data = client.show_vnf_lcm_versions(v)
48 |
49 | return (tuple(data.keys()), tuple(data.values()))
50 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnffm/samples/create_vnf_fm_subscription_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "filter": {
3 | "vnfInstanceSubscriptionFilter": {
4 | "vnfdIds": [
5 | "dummy-vnfdId-1"
6 | ],
7 | "vnfProductsFromProviders": [
8 | {
9 | "vnfProvider": "dummy-vnfProvider-1",
10 | "vnfProducts": [
11 | {
12 | "vnfProductName": "dummy-vnfProductName-1-1",
13 | "versions": [
14 | {
15 | "vnfSoftwareVersion": 1.0,
16 | "vnfdVersions": [1.0, 2.0]
17 | }
18 | ]
19 | }
20 | ]
21 | }
22 | ],
23 | "vnfInstanceIds": [
24 | "dummy-vnfInstanceId-1"
25 | ],
26 | "vnfInstanceNames": [
27 | "dummy-vnfInstanceName-1"
28 | ]
29 | },
30 | "notificationTypes": [
31 | "AlarmNotification"
32 | ],
33 | "faultyResourceTypes": [
34 | "COMPUTE"
35 | ],
36 | "perceivedSeverities": [
37 | "WARNING"
38 | ],
39 | "eventTypes": [
40 | "EQUIPMENT_ALARM"
41 | ],
42 | "probableCauses": [
43 | "The server cannot be connected."
44 | ]
45 | },
46 | "callbackUri": "/nfvo/notify/alarm",
47 | "authentication": {
48 | "authType": [
49 | "BASIC",
50 | "OAUTH2_CLIENT_CREDENTIALS"
51 | ],
52 | "paramsBasic": {
53 | "userName": "nfvo",
54 | "password": "nfvopwd"
55 | },
56 | "paramsOauth2ClientCredentials": {
57 | "clientId": "auth_user_name",
58 | "clientPassword": "auth_password",
59 | "tokenEndpoint": "token_endpoint"
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/vnflcm/samples/change_ext_conn_vnf_instance_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "extVirtualLinks": [
3 | {
4 | "id": "ext-vl-uuid-VL1",
5 | "resourceId": "neutron-network-uuid_VL1",
6 | "extCps": [
7 | {
8 | "cpdId": "CP1",
9 | "cpConfig": [
10 | {
11 | "cpProtocolData": [
12 | {
13 | "layerProtocol": "IP_OVER_ETHERNET",
14 | "ipOverEthernet": {
15 | "ipAddresses": [
16 | {
17 | "type": "IPV4",
18 | "numDynamicAddresses": 1,
19 | "subnetId": "subnet-uuid"
20 | }
21 | ]
22 | }
23 | }
24 | ]
25 | }
26 | ]
27 | },
28 | {
29 | "cpdId": "CP2",
30 | "cpConfig": [
31 | {
32 | "cpProtocolData": [
33 | {
34 | "layerProtocol": "IP_OVER_ETHERNET",
35 | "ipOverEthernet": {
36 | "ipAddresses": [
37 | {
38 | "type": "IPV4",
39 | "fixedAddresses": [
40 | "10.0.0.1"
41 | ],
42 | "subnetId": "subnet-uuid"
43 | }
44 | ]
45 | }
46 | }
47 | ]
48 | }
49 | ]
50 | }
51 | ]
52 | }
53 | ],
54 | "vimConnectionInfo": [
55 | {
56 | "id": "vim-uuid",
57 | "vimType": "ETSINFV.OPENSTACK_KEYSTONE.v_2",
58 | "vimConnectionId": "dummy-vimid",
59 | "interfaceInfo": {
60 | "key1":"value1",
61 | "key2":"value2"
62 | },
63 | "accessInfo": {
64 | "key1":"value1",
65 | "key2":"value2"
66 | }
67 | }
68 | ]
69 | }
70 |
--------------------------------------------------------------------------------
/tackerclient/osc/plugin.py:
--------------------------------------------------------------------------------
1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 | # not use this file except in compliance with the License. You may obtain
3 | # a copy of the License at
4 | #
5 | # http://www.apache.org/licenses/LICENSE-2.0
6 | #
7 | # Unless required by applicable law or agreed to in writing, software
8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 | # License for the specific language governing permissions and limitations
11 | # under the License.
12 | #
13 |
14 | """OpenStackClient plugin for nfv-orchestration service."""
15 |
16 | import logging
17 |
18 | from osc_lib import utils
19 |
20 |
21 | LOG = logging.getLogger(__name__)
22 |
23 | # Required by the OSC plugin interface
24 | DEFAULT_TACKER_API_VERSION = '1'
25 | API_NAME = 'tackerclient'
26 | API_VERSION_OPTION = 'os_tacker_api_version'
27 | API_VERSIONS = {
28 | '1': 'tackerclient.v1_0.client.Client',
29 | '2': 'tackerclient.v1_0.client.Client',
30 | }
31 |
32 |
33 | def make_client(instance):
34 | """Returns a client to the ClientManager."""
35 |
36 | api_version = instance._api_version[API_NAME]
37 | tacker_client = utils.get_client_class(
38 | API_NAME,
39 | api_version,
40 | API_VERSIONS)
41 | LOG.debug('Instantiating tacker client: %s', tacker_client)
42 |
43 | kwargs = {'service_type': 'nfv-orchestration',
44 | 'region_name': instance._region_name,
45 | 'endpoint_type': instance._interface,
46 | 'interface': instance._interface,
47 | 'session': instance.session,
48 | 'api_version': api_version
49 | }
50 |
51 | client = tacker_client(**kwargs)
52 |
53 | return client
54 |
55 |
56 | def build_option_parser(parser):
57 | """Hook to add global options."""
58 | parser.add_argument(
59 | '--os-tacker-api-version',
60 | metavar='',
61 | default=utils.env(
62 | 'OS_TACKER_API_VERSION',
63 | default=DEFAULT_TACKER_API_VERSION))
64 | return parser
65 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnfpm/vnfpm_report.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2022 Fujitsu
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import logging
17 |
18 | from osc_lib.command import command
19 | from osc_lib import utils
20 |
21 | from tackerclient.i18n import _
22 | from tackerclient.osc import sdk_utils
23 | from tackerclient.osc import utils as tacker_osc_utils
24 |
25 | LOG = logging.getLogger(__name__)
26 |
27 | _FORMATTERS = {
28 | 'entries': tacker_osc_utils.FormatComplexDataColumn
29 | }
30 |
31 | _VNF_PM_JOB_ID = 'vnf_pm_job_id'
32 | _VNF_PM_REPORT_ID = 'vnf_pm_report_id'
33 |
34 |
35 | def _get_columns(vnfpm_report_obj):
36 | column_map = {
37 | 'entries': 'Entries'
38 | }
39 | return sdk_utils.get_osc_show_columns_for_sdk_resource(
40 | vnfpm_report_obj, column_map)
41 |
42 |
43 | class ShowVnfPmReport(command.ShowOne):
44 | _description = _("Display VNF PM report details")
45 |
46 | def get_parser(self, prog_name):
47 | parser = super(ShowVnfPmReport, self).get_parser(prog_name)
48 | parser.add_argument(
49 | _VNF_PM_JOB_ID,
50 | metavar="",
51 | help=_("VNF PM job id where the VNF PM report is located"))
52 | parser.add_argument(
53 | _VNF_PM_REPORT_ID,
54 | metavar="",
55 | help=_("VNF PM report ID to display"))
56 | return parser
57 |
58 | def take_action(self, parsed_args):
59 | client = self.app.client_manager.tackerclient
60 | obj = client.show_vnf_pm_report(
61 | parsed_args.vnf_pm_job_id, parsed_args.vnf_pm_report_id)
62 | display_columns, columns = _get_columns(obj)
63 | data = utils.get_item_properties(
64 | sdk_utils.DictModel(obj),
65 | columns, formatters=_FORMATTERS,
66 | mixed_case_fields=None)
67 | return (display_columns, data)
68 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v2/vnfpm_report_fakes.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2022 Fujitsu
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from tackerclient.osc import utils as tacker_osc_utils
17 |
18 |
19 | def vnf_pm_report_response(attrs=None):
20 | """Create a fake vnf pm report.
21 |
22 | :param Dictionary attrs:
23 | A dictionary with all attributes
24 | :return:
25 | A pm report dict
26 | """
27 |
28 | attrs = attrs or {}
29 | # Set default attributes.
30 | fake_vnf_pm_report = {
31 | "entries": [
32 | {
33 | "objectType": "VNFC",
34 | "objectInstanceId": "2bb72d78-b1d9-48fe-8c64-332654ffeb5d",
35 | "subObjectInstanceId": "09d46aed-3ec2-45d9-bfa2-add431e069b3",
36 | "performanceMetric":
37 | "VCpuUsagePeakVnf.2bb72d78-b1d9-48fe-8c64-332654ffeb5d,",
38 | "performanceValues": [
39 | {
40 | "timeStamp": "2022/07/27 08:58:58",
41 | "value": "1.88",
42 | "context": {
43 | "key": "value"
44 | }
45 | }
46 | ]
47 | }
48 | ]
49 | }
50 |
51 | # Overwrite default attributes.
52 | fake_vnf_pm_report.update(attrs)
53 |
54 | return fake_vnf_pm_report
55 |
56 |
57 | def get_vnfpm_report_data(vnf_pm_report, columns=None):
58 | """Get the vnfpm report.
59 |
60 | :return:
61 | A tuple object sorted based on the name of the columns.
62 | """
63 | attribute = 'entries'
64 |
65 | if vnf_pm_report.get(attribute):
66 | vnf_pm_report.update(
67 | {attribute: tacker_osc_utils.FormatComplexDataColumn(
68 | vnf_pm_report[attribute])})
69 |
70 | # return the list of data as per column order
71 | if columns is None:
72 | columns = sorted(vnf_pm_report.keys())
73 | return tuple([vnf_pm_report[key] for key in columns])
74 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/fixture_data/client.py:
--------------------------------------------------------------------------------
1 | # Copyright 2019 NTT DATA
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 | # not use this file except in compliance with the License. You may obtain
5 | # a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | # License for the specific language governing permissions and limitations
13 | # under the License.
14 |
15 | import fixtures
16 | from keystoneauth1 import fixture
17 | from keystoneauth1 import loading
18 | from keystoneauth1 import session
19 |
20 | from tackerclient.v1_0 import client as proxy_client
21 |
22 | IDENTITY_URL = 'http://identityserver:5000/v3'
23 | TACKER_URL = 'http://nfv-orchestration'
24 |
25 |
26 | class ClientFixture(fixtures.Fixture):
27 |
28 | def __init__(self, requests_mock, identity_url=IDENTITY_URL,
29 | api_version='1'):
30 | super(ClientFixture, self).__init__()
31 | self.identity_url = identity_url
32 | self.client = None
33 | self.token = fixture.V2Token()
34 | self.token.set_scope()
35 | self.requests_mock = requests_mock
36 | self.discovery = fixture.V2Discovery(href=self.identity_url)
37 | s = self.token.add_service('nfv-orchestration')
38 | s.add_endpoint(TACKER_URL)
39 | self.api_version = api_version
40 |
41 | def setUp(self):
42 | super(ClientFixture, self).setUp()
43 | auth_url = '%s/tokens' % self.identity_url
44 | headers = {'X-Content-Type': 'application/json'}
45 | self.requests_mock.post(auth_url, json=self.token, headers=headers)
46 | self.requests_mock.get(self.identity_url, json=self.discovery,
47 | headers=headers)
48 | self.client = self.new_client()
49 |
50 | def new_client(self):
51 | self.session = session.Session()
52 | loader = loading.get_plugin_loader('password')
53 | self.session.auth = loader.load_from_options(
54 | auth_url=self.identity_url, username='xx', password='xx')
55 |
56 | return proxy_client.Client(service_type='nfv-orchestration',
57 | interface='public',
58 | endpoint_type='public',
59 | region_name='RegionOne',
60 | auth_url=self.identity_url,
61 | token=self.token.token_id,
62 | endpoint_url=TACKER_URL,
63 | api_version=self.api_version)
64 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/test_http.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 OpenStack Foundation.
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import testtools
17 | from unittest import mock
18 |
19 | from tackerclient.client import HTTPClient
20 | from tackerclient.common import exceptions
21 | from tackerclient.tests.unit.test_cli10 import MyResp
22 |
23 |
24 | AUTH_TOKEN = 'test_token'
25 | END_URL = 'test_url'
26 | METHOD = 'GET'
27 | URL = 'http://test.test:1234/v1.0/test'
28 | headers = {'User-Agent': 'python-tackerclient'}
29 |
30 |
31 | class TestHTTPClient(testtools.TestCase):
32 |
33 | def setUp(self):
34 |
35 | super(TestHTTPClient, self).setUp()
36 | self.addCleanup(mock.patch.stopall)
37 | self.http = HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL)
38 |
39 | @mock.patch('tackerclient.client.HTTPClient.request')
40 | def test_request_error(self, mock_request):
41 |
42 | mock_request.side_effect = Exception('error msg')
43 | self.assertRaises(
44 | exceptions.ConnectionFailed,
45 | self.http._cs_request,
46 | URL, METHOD
47 | )
48 |
49 | @mock.patch('tackerclient.client.HTTPClient.request')
50 | def test_request_success(self, mock_request):
51 |
52 | rv_should_be = MyResp(200), 'test content'
53 | mock_request.return_value = rv_should_be
54 | self.assertEqual(rv_should_be, self.http._cs_request(URL, METHOD))
55 |
56 | @mock.patch('tackerclient.client.HTTPClient.request')
57 | def test_request_unauthorized(self, mock_request):
58 |
59 | mock_request.return_value = MyResp(401), 'unauthorized message'
60 |
61 | e = self.assertRaises(exceptions.Unauthorized,
62 | self.http._cs_request, URL, METHOD)
63 | self.assertEqual('unauthorized message', str(e))
64 | mock_request.assert_called_with(URL, METHOD, headers=headers)
65 |
66 | @mock.patch('tackerclient.client.HTTPClient.request')
67 | def test_request_forbidden_is_returned_to_caller(self, mock_request):
68 |
69 | rv_should_be = MyResp(403), 'forbidden message'
70 | mock_request.return_value = rv_should_be
71 | self.assertEqual(rv_should_be, self.http._cs_request(URL, METHOD))
72 |
--------------------------------------------------------------------------------
/tackerclient/tacker/client.py:
--------------------------------------------------------------------------------
1 | # Copyright 2012 OpenStack Foundation.
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 | #
16 |
17 | from tackerclient.common._i18n import _
18 | from tackerclient.common import exceptions
19 | from tackerclient.common import utils
20 |
21 |
22 | API_NAME = 'nfv-orchestration'
23 | API_VERSIONS = {
24 | '1.0': 'tackerclient.v1_0.client.Client',
25 | }
26 |
27 |
28 | def make_client(instance):
29 | """Returns an tacker client."""
30 |
31 | tacker_client = utils.get_client_class(
32 | API_NAME,
33 | instance._api_version[API_NAME],
34 | API_VERSIONS,
35 | )
36 | instance.initialize()
37 | url = instance._url
38 | url = url.rstrip("/")
39 | if '1.0' == instance._api_version[API_NAME]:
40 | client = tacker_client(username=instance._username,
41 | tenant_name=instance._tenant_name,
42 | password=instance._password,
43 | region_name=instance._region_name,
44 | auth_url=instance._auth_url,
45 | endpoint_url=url,
46 | endpoint_type=instance._endpoint_type,
47 | token=instance._token,
48 | auth_strategy=instance._auth_strategy,
49 | insecure=instance._insecure,
50 | ca_cert=instance._ca_cert,
51 | retries=instance._retries,
52 | raise_errors=instance._raise_errors,
53 | session=instance._session,
54 | auth=instance._auth)
55 | return client
56 | else:
57 | raise exceptions.UnsupportedVersion(
58 | reason=_("API version %s is not supported") %
59 | instance._api_version[API_NAME])
60 |
61 |
62 | def Client(api_version, *args, **kwargs):
63 | """Return an tacker client.
64 |
65 | :param api_version: only 1.0 is supported now
66 | """
67 | tacker_client = utils.get_client_class(
68 | API_NAME,
69 | api_version,
70 | API_VERSIONS,
71 | )
72 | return tacker_client(*args, **kwargs)
73 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/vnflcm/samples/instantiate_vnf_instance_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "flavourId":"simple",
3 | "instantiationLevelId":"instantiation_level_1",
4 | "extVirtualLinks":[
5 | {
6 | "id":"ext-vl-uuid-VL1",
7 | "vimConnectionId":"vim-uuid",
8 | "resourceProviderId":"resource-provider-id",
9 | "resourceId":"neutron-network-uuid_VL1",
10 | "extCps":[
11 | {
12 | "cpdId":"CP1",
13 | "cpConfig":[
14 | {
15 | "cpInstanceId":"cp-instance-id",
16 | "linkPortId":"link-port-uuid_CP1",
17 | "cpProtocolData":[
18 | {
19 | "layerProtocol":"IP_OVER_ETHERNET",
20 | "ipOverEthernet":{
21 | "macAddress":"00:25:96:FF:FE:12:34:56",
22 | "ipAddresses":[
23 | {
24 | "addressRange":{
25 | "minAddress":"192.168.11.01",
26 | "maxAddress":"192.168.21.201"
27 | },
28 | "subnetId":"neutron-subnet-uuid_CP1"
29 | }
30 | ]
31 | }
32 | }
33 | ]
34 | }
35 | ]
36 | }
37 | ],
38 | "extLinkPorts":[
39 | {
40 | "id":"link-port-uuid_CP1",
41 | "resourceHandle":{
42 | "vimConnectionId":"vim-uuid",
43 | "resourceProviderId":"resource-provider-id",
44 | "resourceId":"neutron-port-uuid_CP1",
45 | "vimLevelResourceType":"LINKPORT"
46 | }
47 | }
48 | ]
49 | }
50 | ],
51 | "extManagedVirtualLinks":[
52 | {
53 | "id":"extMngVLnk-uuid_VL3",
54 | "vnfVirtualLinkDescId":"VL3",
55 | "vimConnectionId":"vim-uuid",
56 | "resourceProviderId":"resource-provider-id",
57 | "resourceId":"neutron-network-uuid_VL3"
58 | }
59 | ],
60 | "vimConnectionInfo":[
61 | {
62 | "id":"vim-uuid",
63 | "vimId":"dummy-vimid",
64 | "vimType":"ETSINFV.OPENSTACK_KEYSTONE.v_2",
65 | "interfaceInfo":{
66 | "key1":"value1",
67 | "key2":"value2"
68 | },
69 | "accessInfo":{
70 | "key1":"value1",
71 | "key2":"value2"
72 | },
73 | "extra":{
74 | "key1":"value1",
75 | "key2":"value2"
76 | }
77 | }
78 | ]
79 | }
--------------------------------------------------------------------------------
/tackerclient/common/validators.py:
--------------------------------------------------------------------------------
1 | # Copyright 2014 NEC Corporation
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import netaddr
17 |
18 | from tackerclient.common import exceptions
19 | from tackerclient.i18n import _
20 |
21 |
22 | def validate_int_range(parsed_args, attr_name, min_value=None, max_value=None):
23 | val = getattr(parsed_args, attr_name, None)
24 | if val is None:
25 | return
26 | try:
27 | if not isinstance(val, int):
28 | int_val = int(val, 0)
29 | else:
30 | int_val = val
31 | if ((min_value is None or min_value <= int_val) and
32 | (max_value is None or int_val <= max_value)):
33 | return
34 | except (ValueError, TypeError):
35 | pass
36 |
37 | if min_value is not None and max_value is not None:
38 | msg = (_('%(attr_name)s "%(val)s" should be an integer '
39 | '[%(min)i:%(max)i].') %
40 | {'attr_name': attr_name.replace('_', '-'),
41 | 'val': val, 'min': min_value, 'max': max_value})
42 | elif min_value is not None:
43 | msg = (_('%(attr_name)s "%(val)s" should be an integer '
44 | 'greater than or equal to %(min)i.') %
45 | {'attr_name': attr_name.replace('_', '-'),
46 | 'val': val, 'min': min_value})
47 | elif max_value is not None:
48 | msg = (_('%(attr_name)s "%(val)s" should be an integer '
49 | 'smaller than or equal to %(max)i.') %
50 | {'attr_name': attr_name.replace('_', '-'),
51 | 'val': val, 'max': max_value})
52 | else:
53 | msg = (_('%(attr_name)s "%(val)s" should be an integer.') %
54 | {'attr_name': attr_name.replace('_', '-'),
55 | 'val': val})
56 |
57 | raise exceptions.CommandError(message=msg)
58 |
59 |
60 | def validate_ip_subnet(parsed_args, attr_name):
61 | val = getattr(parsed_args, attr_name)
62 | if not val:
63 | return
64 | try:
65 | netaddr.IPNetwork(val)
66 | except (netaddr.AddrFormatError, ValueError):
67 | raise exceptions.CommandError(
68 | message=(_('%(attr_name)s "%(val)s" is not a valid CIDR.') %
69 | {'attr_name': attr_name.replace('_', '-'), 'val': val}))
70 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/base.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 NTT DATA
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from requests_mock.contrib import fixture as requests_mock_fixture
17 | import testtools
18 | from unittest import mock
19 |
20 | from cliff import columns as cliff_columns
21 |
22 |
23 | class FixturedTestCase(testtools.TestCase):
24 | client_fixture_class = None
25 | api_version = '1'
26 |
27 | def setUp(self):
28 | super(FixturedTestCase, self).setUp()
29 | self.app = mock.MagicMock()
30 | if self.client_fixture_class:
31 | self.requests_mock = self.useFixture(requests_mock_fixture.
32 | Fixture())
33 | fix = self.client_fixture_class(self.requests_mock,
34 | api_version=self.api_version)
35 | self.cs = self.useFixture(fix).client
36 |
37 | def check_parser(self, cmd, args, verify_args):
38 | cmd_parser = cmd.get_parser('check_parser')
39 | try:
40 | parsed_args = cmd_parser.parse_args(args)
41 | except SystemExit:
42 | raise ParserException
43 | for av in verify_args:
44 | attr, value = av
45 | if attr:
46 | self.assertIn(attr, parsed_args)
47 | self.assertEqual(getattr(parsed_args, attr), value)
48 | return parsed_args
49 |
50 | def assertNotCalled(self, m, msg=None):
51 | """Assert a function was not called"""
52 |
53 | if m.called:
54 | if not msg:
55 | msg = 'method %s should not have been called' % m
56 | self.fail(msg)
57 |
58 | def assertListItemsEqual(self, expected, actual):
59 | """Assertion based on human_readable values of list items"""
60 |
61 | self.assertEqual(len(expected), len(actual))
62 | for col_expected, col_actual in zip(expected, actual):
63 | if isinstance(col_actual, tuple):
64 | self.assertListItemsEqual(col_expected, col_actual)
65 | elif isinstance(col_expected, cliff_columns.FormattableColumn):
66 | self.assertIsInstance(col_actual, col_expected.__class__)
67 | self.assertEqual(col_expected.human_readable(),
68 | col_actual.human_readable())
69 | else:
70 | self.assertEqual(col_expected, col_actual)
71 |
72 |
73 | class ParserException(Exception):
74 | pass
75 |
--------------------------------------------------------------------------------
/doc/source/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | # not use this file except in compliance with the License. You may obtain
4 | # a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | # License for the specific language governing permissions and limitations
12 | # under the License.
13 |
14 | # python-tackerclient documentation build configuration file
15 |
16 | import os
17 | import sys
18 |
19 | # If extensions (or modules to document with autodoc) are in another directory,
20 | # add these directories to sys.path here. If the directory is relative to the
21 | # documentation root, use os.path.abspath to make it absolute, like shown here.
22 | # sys.path.append(os.path.abspath('.'))
23 |
24 | sys.path.insert(0, os.path.abspath('../..'))
25 |
26 | # -- General configuration ----------------------------------------------------
27 |
28 | # Add any Sphinx extension module names here, as strings. They can be
29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
30 | extensions = [
31 | 'sphinx.ext.autodoc',
32 | 'reno.sphinxext',
33 | 'openstackdocstheme',
34 | 'cliff.sphinxext',
35 | ]
36 |
37 | # Add any paths that contain templates here, relative to this directory.
38 | templates_path = ['_templates']
39 |
40 | # The suffix of source filenames.
41 | source_suffix = '.rst'
42 |
43 | # The master toctree document.
44 | master_doc = 'index'
45 |
46 | # General information about the project.
47 | copyright = 'OpenStack Contributors'
48 |
49 | # If true, '()' will be appended to :func: etc. cross-reference text.
50 | add_function_parentheses = True
51 |
52 | # If true, the current module name will be prepended to all description
53 | # unit titles (such as .. function::).
54 | add_module_names = True
55 |
56 | # The name of the Pygments (syntax highlighting) style to use.
57 | pygments_style = 'native'
58 |
59 | # -- Options for HTML output --------------------------------------------------
60 |
61 | # The theme to use for HTML and HTML Help pages. Major themes that come with
62 | # Sphinx are currently 'default' and 'sphinxdoc'.
63 | html_theme = 'openstackdocs'
64 |
65 | # Output file base name for HTML help builder.
66 | htmlhelp_basename = 'tackerclientdoc'
67 |
68 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
69 | # using the given strftime format.
70 |
71 | # -- Options for manual page output -------------------------------------------
72 |
73 | man_pages = [
74 | ('cli/index', 'tacker', 'Client for Tacker API',
75 | ['OpenStack Contributors'], 1),
76 | ]
77 |
78 | # -- Options for openstackdocstheme -------------------------------------------
79 |
80 | openstackdocs_repo_name = 'openstack/python-tackerclient'
81 | openstackdocs_bug_project = 'python-tackerclient'
82 | openstackdocs_bug_tag = 'doc'
83 |
84 | # -- Options for cliff.sphinxext plugin ---------------------------------------
85 |
86 | autoprogram_cliff_application = 'openstack'
87 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/test_ssl.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 OpenStack Foundation.
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from unittest import mock
17 |
18 | import fixtures
19 | from keystoneclient import session
20 | import requests
21 | import testtools
22 |
23 | from tackerclient import client
24 | from tackerclient.common import clientmanager
25 | from tackerclient.common import exceptions
26 | from tackerclient import shell as openstack_shell
27 |
28 |
29 | AUTH_TOKEN = 'test_token'
30 | END_URL = 'test_url'
31 | METHOD = 'GET'
32 | URL = 'http://test.test:1234/v1.0/'
33 | CA_CERT = '/tmp/test/path'
34 | DEFAULT_API_VERSION = '1.0'
35 |
36 |
37 | class TestSSL(testtools.TestCase):
38 | def setUp(self):
39 | super(TestSSL, self).setUp()
40 |
41 | self.useFixture(fixtures.EnvironmentVariable('OS_TOKEN', AUTH_TOKEN))
42 | self.useFixture(fixtures.EnvironmentVariable('OS_URL', END_URL))
43 | self.addCleanup(mock.patch.stopall)
44 |
45 | def _test_verify_client_manager(self, cacert):
46 | with mock.patch.object(session, 'Session'), \
47 | mock.patch.object(clientmanager, 'ClientManager') as mock_cmgr:
48 |
49 | mock_cmgr.return_value = 0
50 | shell = openstack_shell.TackerShell(DEFAULT_API_VERSION)
51 | shell.options = mock.Mock()
52 | auth_session = shell._get_keystone_session()
53 |
54 | shell.run(cacert)
55 |
56 | mock_cmgr.assert_called_with(
57 | api_version={'nfv-orchestration': '1.0'},
58 | auth=auth_session.auth, auth_strategy='keystone',
59 | auth_url='', ca_cert=CA_CERT, endpoint_type='publicURL',
60 | insecure=False, log_credentials=True, password='',
61 | raise_errors=False, region_name='', retries=0,
62 | service_type='nfv-orchestration', session=auth_session,
63 | tenant_id='', tenant_name='', timeout=None,
64 | token='test_token', url='test_url', user_id='', username='')
65 |
66 | def test_ca_cert_passed(self):
67 | cacert = ['--os-cacert', CA_CERT]
68 | self._test_verify_client_manager(cacert)
69 |
70 | def test_ca_cert_passed_as_env_var(self):
71 | self.useFixture(fixtures.EnvironmentVariable('OS_CACERT', CA_CERT))
72 | self._test_verify_client_manager([])
73 |
74 | @mock.patch.object(client.HTTPClient, 'request')
75 | def test_proper_exception_is_raised_when_cert_validation_fails(self,
76 | mock_req):
77 | http = client.HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL)
78 | mock_req.side_effect = requests.exceptions.SSLError()
79 | self.assertRaises(
80 | exceptions.SslCertificateValidationError,
81 | http._cs_request,
82 | URL, METHOD
83 | )
84 |
--------------------------------------------------------------------------------
/tackerclient/common/extension.py:
--------------------------------------------------------------------------------
1 | # Copyright 2015 Rackspace Hosting Inc.
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 | #
16 | from stevedore import extension
17 |
18 | from tackerclient.tacker import v1_0 as tackerV10
19 |
20 |
21 | def _discover_via_entry_points():
22 | emgr = extension.ExtensionManager('tackerclient.extension',
23 | invoke_on_load=False)
24 | return ((ext.name, ext.plugin) for ext in emgr)
25 |
26 |
27 | class TackerClientExtension(tackerV10.TackerCommand):
28 | pagination_support = False
29 | _formatters = {}
30 | sorting_support = False
31 |
32 |
33 | class ClientExtensionShow(TackerClientExtension, tackerV10.ShowCommand):
34 | def get_data(self, parsed_args):
35 | # NOTE(mdietz): Calls 'execute' to provide a consistent pattern
36 | # for any implementers adding extensions with
37 | # regard to any other extension verb.
38 | return self.execute(parsed_args)
39 |
40 | def execute(self, parsed_args):
41 | return super(ClientExtensionShow, self).get_data(parsed_args)
42 |
43 |
44 | class ClientExtensionList(TackerClientExtension, tackerV10.ListCommand):
45 |
46 | def get_data(self, parsed_args):
47 | # NOTE(mdietz): Calls 'execute' to provide a consistent pattern
48 | # for any implementers adding extensions with
49 | # regard to any other extension verb.
50 | return self.execute(parsed_args)
51 |
52 | def execute(self, parsed_args):
53 | return super(ClientExtensionList, self).get_data(parsed_args)
54 |
55 |
56 | class ClientExtensionDelete(TackerClientExtension, tackerV10.DeleteCommand):
57 | def run(self, parsed_args):
58 | # NOTE(mdietz): Calls 'execute' to provide a consistent pattern
59 | # for any implementers adding extensions with
60 | # regard to any other extension verb.
61 | return self.execute(parsed_args)
62 |
63 | def execute(self, parsed_args):
64 | return super(ClientExtensionDelete, self).run(parsed_args)
65 |
66 |
67 | class ClientExtensionCreate(TackerClientExtension, tackerV10.CreateCommand):
68 | def get_data(self, parsed_args):
69 | # NOTE(mdietz): Calls 'execute' to provide a consistent pattern
70 | # for any implementers adding extensions with
71 | # regard to any other extension verb.
72 | return self.execute(parsed_args)
73 |
74 | def execute(self, parsed_args):
75 | return super(ClientExtensionCreate, self).get_data(parsed_args)
76 |
77 |
78 | class ClientExtensionUpdate(TackerClientExtension, tackerV10.UpdateCommand):
79 | def run(self, parsed_args):
80 | # NOTE(mdietz): Calls 'execute' to provide a consistent pattern
81 | # for any implementers adding extensions with
82 | # regard to any other extension verb.
83 | return self.execute(parsed_args)
84 |
85 | def execute(self, parsed_args):
86 | return super(ClientExtensionUpdate, self).run(parsed_args)
87 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/vnflcm_op_occs_fakes.py:
--------------------------------------------------------------------------------
1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 | # not use this file except in compliance with the License. You may obtain
3 | # a copy of the License at
4 | #
5 | # http://www.apache.org/licenses/LICENSE-2.0
6 | #
7 | # Unless required by applicable law or agreed to in writing, software
8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 | # License for the specific language governing permissions and limitations
11 | # under the License.
12 |
13 | from oslo_utils.fixture import uuidsentinel
14 | from oslo_utils import uuidutils
15 |
16 | from tackerclient.osc import utils as tacker_osc_utils
17 |
18 |
19 | def vnflcm_op_occ_response(attrs=None, action=''):
20 | """Create a fake vnflcm op occurrence.
21 |
22 | :param Dictionary attrs:
23 | A dictionary with all attributes
24 | :return:
25 | A vnf lcm op occs dict
26 | """
27 | attrs = attrs or {}
28 |
29 | # Set default attributes.
30 | dummy_vnf_lcm_op_occ = {
31 | "id": uuidsentinel.vnflcm_op_occ_id,
32 | "operationState": "STARTING",
33 | "stateEnteredTime": "2018-12-22T16:59:45.187Z",
34 | "startTime": "2018-12-22T16:59:45.187Z",
35 | "vnfInstanceId": "376f37f3-d4e9-4d41-8e6a-9b0ec98695cc",
36 | "grantId": "",
37 | "operation": "INSTANTIATE",
38 | "isAutomaticInvocation": "true",
39 | "operationParams": {
40 | "flavourId": "default",
41 | "instantiationLevelId": "n-mme-min"
42 | },
43 | "isCancelPending": "true",
44 | "cancelMode": "",
45 | "error": {
46 | "status": "500",
47 | "detail": "internal server error"
48 | },
49 | "resourceChanges": [],
50 | "changedInfo": [],
51 | "changedExtConnectivity": [],
52 | "_links": {
53 | "self": ""
54 | }
55 | }
56 |
57 | if action == 'fail':
58 | fail_not_needed_columns = [
59 | 'grantId', 'operationParams',
60 | 'cancelMode', 'resourceChanges', 'changedInfo',
61 | 'changedExtConnectivity']
62 |
63 | for key in fail_not_needed_columns:
64 | del dummy_vnf_lcm_op_occ[key]
65 |
66 | # Overwrite default attributes.
67 | dummy_vnf_lcm_op_occ.update(attrs)
68 |
69 | return dummy_vnf_lcm_op_occ
70 |
71 |
72 | def get_vnflcm_op_occ_data(vnf_lcm_op_occ, columns=None):
73 | """Get the vnflcm op occurrence.
74 |
75 | :return:
76 | A tuple object sorted based on the name of the columns.
77 | """
78 | complex_attributes = [
79 | 'operationParams', 'error', 'resourceChanges',
80 | 'changedInfo', 'changedExtConnectivity', 'links']
81 |
82 | for attribute in complex_attributes:
83 | if vnf_lcm_op_occ.get(attribute):
84 | vnf_lcm_op_occ.update(
85 | {attribute: tacker_osc_utils.FormatComplexDataColumn(
86 | vnf_lcm_op_occ[attribute])})
87 |
88 | # return the list of data as per column order
89 | if columns:
90 | return tuple([vnf_lcm_op_occ[key] for key in columns])
91 |
92 | return tuple([vnf_lcm_op_occ[key] for key in sorted(
93 | vnf_lcm_op_occ.keys())])
94 |
95 |
96 | def create_vnflcm_op_occs(count=2):
97 | """Create multiple fake vnflcm op occs.
98 |
99 | :param count: The number of vnflcm op occs to fake
100 | :return:
101 | A list of fake vnflcm op occs dictionary
102 | """
103 | vnflcm_op_occs = []
104 | for i in range(0, count):
105 | unique_id = uuidutils.generate_uuid()
106 | vnflcm_op_occs.append(vnflcm_op_occ_response(attrs={'id': unique_id}))
107 | return vnflcm_op_occs
108 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v2/vnfpm_threshold_fakes.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2023 Fujitsu
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from oslo_utils import uuidutils
17 |
18 | from tackerclient.osc import utils as tacker_osc_utils
19 |
20 |
21 | def create_vnf_pm_thresholds(count=2):
22 | """Create multiple fake vnf pm thresholds.
23 |
24 | :param int count:
25 | The number of vnf_pm_thresholds to fake
26 | :return:
27 | A list of fake vnf pm thresholds dictionary
28 | """
29 | vnf_pm_thresholds = []
30 | for _ in range(0, count):
31 | unique_id = uuidutils.generate_uuid()
32 | vnf_pm_thresholds.append(vnf_pm_threshold_response(
33 | attrs={'id': unique_id}))
34 | return vnf_pm_thresholds
35 |
36 |
37 | def vnf_pm_threshold_response(attrs=None, action=None):
38 | """Create a fake vnf pm threshold.
39 |
40 | :param Dictionary attrs:
41 | A dictionary with all attributes
42 | :param String action:
43 | The operation performed on threshold
44 | :return:
45 | A pm threshold dict
46 | """
47 | if action == 'update':
48 | fake_vnf_pm_threshold = {
49 | "callbackUri": "/nfvo/notify/threshold",
50 | }
51 | return fake_vnf_pm_threshold
52 |
53 | attrs = attrs or {}
54 | # Set default attributes.
55 | fake_vnf_pm_threshold = {
56 | "id": "2bb72d78-b1d9-48fe-8c64-332654ffeb5d",
57 | "objectType": "Vnfc",
58 | "objectInstanceId": "object-instance-id-1",
59 | "subObjectInstanceIds": [
60 | "sub-object-instance-id-2"
61 | ],
62 | "criteria": {
63 | "performanceMetric": "VCpuUsageMeanVnf.object-instance-id-1",
64 | "thresholdType": "SIMPLE",
65 | "simpleThresholdDetails": {
66 | "thresholdValue": 500.5,
67 | "hysteresis": 10.5
68 | }
69 | },
70 | "callbackUri": "/nfvo/notify/threshold",
71 | "_links": {
72 | "self": {
73 | "href": "/vnfpm/v2/thresholds/"
74 | "78a39661-60a8-4824-b989-88c1b0c3534a"
75 | },
76 | "object": {
77 | "href": "/vnflcm/v1/vnf_instances/"
78 | "0e5f3086-4e79-47ed-a694-54c29155fa26"
79 | }
80 | }
81 | }
82 |
83 | # Overwrite default attributes.
84 | fake_vnf_pm_threshold.update(attrs)
85 |
86 | return fake_vnf_pm_threshold
87 |
88 |
89 | def get_vnfpm_threshold_data(vnf_pm_threshold, columns=None):
90 | """Get the vnfpm threshold.
91 |
92 | :param Dictionary vnf_pm_threshold:
93 | A dictionary with vnf_pm_threshold
94 | :param List columns:
95 | A list of column names
96 | :return:
97 | A tuple object sorted based on the name of the columns.
98 | """
99 | complex_attributes = ['subObjectInstanceIds',
100 | 'criteria', '_links', 'authentication']
101 |
102 | for attribute in complex_attributes:
103 | if vnf_pm_threshold.get(attribute):
104 | vnf_pm_threshold.update(
105 | {attribute: tacker_osc_utils.FormatComplexDataColumn(
106 | vnf_pm_threshold[attribute])})
107 |
108 | # return the list of data as per column order
109 | if columns is None:
110 | columns = sorted(vnf_pm_threshold.keys())
111 | return tuple([vnf_pm_threshold[key] for key in columns])
112 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v2/vnfpm_job_fakes.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2022 Fujitsu
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from oslo_utils import uuidutils
17 |
18 | from tackerclient.osc import utils as tacker_osc_utils
19 |
20 |
21 | def create_vnf_pm_jobs(count=2):
22 | """Create multiple fake vnf pm jobs.
23 |
24 | :param int count:
25 | The number of vnf_pm_jobs to fake
26 | :return:
27 | A list of fake vnf pm jobs dictionary
28 | """
29 | vnf_pm_jobs = []
30 | for i in range(0, count):
31 | unique_id = uuidutils.generate_uuid()
32 | vnf_pm_jobs.append(vnf_pm_job_response(attrs={'id': unique_id}))
33 | return {'vnf_pm_jobs': vnf_pm_jobs}
34 |
35 |
36 | def vnf_pm_job_response(attrs=None, action=None):
37 | """Create a fake vnf pm job.
38 |
39 | :param Dictionary attrs:
40 | A dictionary with all attributes
41 | :return:
42 | A pm job dict
43 | """
44 | if action == 'update':
45 | fake_vnf_pm_job = {
46 | "callbackUri": "/nfvo/notify/job"
47 | }
48 | return fake_vnf_pm_job
49 |
50 | attrs = attrs or {}
51 | # Set default attributes.
52 | fake_vnf_pm_job = {
53 | "id": "2bb72d78-b1d9-48fe-8c64-332654ffeb5d",
54 | "objectType": "VNFC",
55 | "objectInstanceIds": [
56 | "object-instance-id-1"
57 | ],
58 | "subObjectInstanceIds": [
59 | "sub-object-instance-id-2"
60 | ],
61 | "criteria": {
62 | "performanceMetric": [
63 | "VCpuUsageMeanVnf.object-instance-id-1"
64 | ],
65 | "performanceMetricGroup": [
66 | "VirtualisedComputeResource"
67 | ],
68 | "collectionPeriod": 500,
69 | "reportingPeriod": 1000,
70 | "reportingBoundary": "2022/07/25 10:43:55"
71 | },
72 | "callbackUri": "/nfvo/notify/job",
73 | "reports": [{
74 | "href": "/vnfpm/v2/pm_jobs/2bb72d78-b1d9-48fe-8c64-332654ffeb5d/"
75 | "reports/09d46aed-3ec2-45d9-bfa2-add431e069b3",
76 | "readyTime": "2022/07/25 10:43:55",
77 | "expiryTime": "2022/07/25 10:43:55",
78 | "fileSize": 9999
79 | }],
80 | "_links": {
81 | "self": {
82 | "href": "/vnfpm/v2/pm_jobs/"
83 | "78a39661-60a8-4824-b989-88c1b0c3534a"
84 | },
85 | "objects": [{
86 | "href": "/vnflcm/v1/vnf_instances/"
87 | "0e5f3086-4e79-47ed-a694-54c29155fa26"
88 | }]
89 | }
90 | }
91 |
92 | # Overwrite default attributes.
93 | fake_vnf_pm_job.update(attrs)
94 |
95 | return fake_vnf_pm_job
96 |
97 |
98 | def get_vnfpm_job_data(vnf_pm_job, columns=None):
99 | """Get the vnfpm job.
100 |
101 | :return:
102 | A tuple object sorted based on the name of the columns.
103 | """
104 | complex_attributes = [
105 | 'objectInstanceIds', 'subObjectInstanceIds',
106 | 'criteria', 'reports', '_links',
107 | 'authentication'
108 | ]
109 |
110 | for attribute in complex_attributes:
111 | if vnf_pm_job.get(attribute):
112 | vnf_pm_job.update(
113 | {attribute: tacker_osc_utils.FormatComplexDataColumn(
114 | vnf_pm_job[attribute])})
115 |
116 | # return the list of data as per column order
117 | if columns is None:
118 | columns = sorted(vnf_pm_job.keys())
119 | return tuple([vnf_pm_job[key] for key in columns])
120 |
--------------------------------------------------------------------------------
/tackerclient/common/clientmanager.py:
--------------------------------------------------------------------------------
1 | # Copyright 2012 OpenStack Foundation.
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 | #
16 |
17 | """Manage access to the clients, including authenticating when needed.
18 | """
19 |
20 | from tackerclient import client
21 | from tackerclient.tacker import client as tacker_client
22 |
23 |
24 | class ClientCache(object):
25 | """Descriptor class for caching created client handles."""
26 |
27 | def __init__(self, factory):
28 | self.factory = factory
29 | self._handle = None
30 |
31 | def __get__(self, instance, owner):
32 | # Tell the ClientManager to login to keystone
33 | if self._handle is None:
34 | self._handle = self.factory(instance)
35 | return self._handle
36 |
37 |
38 | class ClientManager(object):
39 | """Manages access to API clients, including authentication."""
40 | tacker = ClientCache(tacker_client.make_client)
41 |
42 | def __init__(self, token=None, url=None,
43 | auth_url=None,
44 | endpoint_type=None,
45 | tenant_name=None,
46 | tenant_id=None,
47 | username=None,
48 | user_id=None,
49 | password=None,
50 | region_name=None,
51 | api_version=None,
52 | auth_strategy=None,
53 | insecure=False,
54 | ca_cert=None,
55 | log_credentials=False,
56 | service_type=None,
57 | timeout=None,
58 | retries=0,
59 | raise_errors=True,
60 | session=None,
61 | auth=None,
62 | ):
63 | self._token = token
64 | self._url = url
65 | self._auth_url = auth_url
66 | self._service_type = service_type
67 | self._endpoint_type = endpoint_type
68 | self._tenant_name = tenant_name
69 | self._tenant_id = tenant_id
70 | self._username = username
71 | self._user_id = user_id
72 | self._password = password
73 | self._region_name = region_name
74 | self._api_version = api_version
75 | self._service_catalog = None
76 | self._auth_strategy = auth_strategy
77 | self._insecure = insecure
78 | self._ca_cert = ca_cert
79 | self._log_credentials = log_credentials
80 | self._timeout = timeout
81 | self._retries = retries
82 | self._raise_errors = raise_errors
83 | self._session = session
84 | self._auth = auth
85 | return
86 |
87 | def initialize(self):
88 | if not self._url:
89 | httpclient = client.construct_http_client(
90 | username=self._username,
91 | user_id=self._user_id,
92 | tenant_name=self._tenant_name,
93 | tenant_id=self._tenant_id,
94 | password=self._password,
95 | region_name=self._region_name,
96 | auth_url=self._auth_url,
97 | service_type=self._service_type,
98 | endpoint_type=self._endpoint_type,
99 | insecure=self._insecure,
100 | ca_cert=self._ca_cert,
101 | timeout=self._timeout,
102 | session=self._session,
103 | auth=self._auth,
104 | log_credentials=self._log_credentials)
105 | httpclient.authenticate()
106 | # Populate other password flow attributes
107 | self._token = httpclient.auth_token
108 | self._url = httpclient.endpoint_url
109 |
--------------------------------------------------------------------------------
/tackerclient/common/serializer.py:
--------------------------------------------------------------------------------
1 | # Copyright 2013 OpenStack Foundation.
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import logging
17 |
18 | from oslo_serialization import jsonutils
19 |
20 | from tackerclient.common import exceptions as exception
21 | from tackerclient.i18n import _
22 |
23 | LOG = logging.getLogger(__name__)
24 |
25 |
26 | class ActionDispatcher(object):
27 | """Maps method name to local methods through action name."""
28 |
29 | def dispatch(self, *args, **kwargs):
30 | """Find and call local method."""
31 | action = kwargs.pop('action', 'default')
32 | action_method = getattr(self, str(action), self.default)
33 | return action_method(*args, **kwargs)
34 |
35 | def default(self, data):
36 | raise NotImplementedError()
37 |
38 |
39 | class DictSerializer(ActionDispatcher):
40 | """Default request body serialization."""
41 |
42 | def serialize(self, data, action='default'):
43 | return self.dispatch(data, action=action)
44 |
45 | def default(self, data):
46 | return ""
47 |
48 |
49 | class JSONDictSerializer(DictSerializer):
50 | """Default JSON request body serialization."""
51 |
52 | def default(self, data):
53 | def sanitizer(obj):
54 | return str(obj)
55 | return jsonutils.dumps(data, default=sanitizer)
56 |
57 |
58 | class TextDeserializer(ActionDispatcher):
59 | """Default request body deserialization."""
60 |
61 | def deserialize(self, datastring, action='default'):
62 | return self.dispatch(datastring, action=action)
63 |
64 | def default(self, datastring):
65 | return {}
66 |
67 |
68 | class JSONDeserializer(TextDeserializer):
69 |
70 | def _from_json(self, datastring):
71 | try:
72 | return jsonutils.loads(datastring)
73 | except ValueError:
74 | msg = _("Cannot understand JSON")
75 | raise exception.MalformedResponseBody(reason=msg)
76 |
77 | def default(self, datastring):
78 | return {'body': self._from_json(datastring)}
79 |
80 |
81 | # NOTE(maru): this class is duplicated from tacker.wsgi
82 | class Serializer(object):
83 | """Serializes and deserializes dictionaries to certain MIME types."""
84 |
85 | def __init__(self, metadata=None):
86 | """Create a serializer based on the given WSGI environment.
87 |
88 | 'metadata' is an optional dict mapping MIME types to information
89 | needed to serialize a dictionary to that type.
90 |
91 | """
92 | self.metadata = metadata or {}
93 |
94 | def _get_serialize_handler(self, content_type):
95 | handlers = {
96 | 'application/json': JSONDictSerializer()
97 | }
98 |
99 | try:
100 | return handlers[content_type]
101 | except Exception:
102 | raise exception.InvalidContentType(content_type=content_type)
103 |
104 | def serialize(self, data, content_type):
105 | """Serialize a dictionary into the specified content type."""
106 | return self._get_serialize_handler(content_type).serialize(data)
107 |
108 | def deserialize(self, datastring, content_type):
109 | """Deserialize a string to a dictionary.
110 |
111 | The string must be in the format of a supported MIME type.
112 | """
113 | return self.get_deserialize_handler(content_type).deserialize(
114 | datastring)
115 |
116 | def get_deserialize_handler(self, content_type):
117 | handlers = {
118 | 'application/json': JSONDeserializer()
119 | }
120 |
121 | try:
122 | return handlers[content_type]
123 | except Exception:
124 | raise exception.InvalidContentType(content_type=content_type)
125 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/common/test_vnflcm_versions.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2021 Nippon Telegraph and Telephone Corporation
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import os
17 |
18 | import ddt
19 | from unittest import mock
20 |
21 | from tackerclient.common import exceptions
22 | from tackerclient.osc.common.vnflcm import vnflcm_versions
23 | from tackerclient.tests.unit.osc import base
24 | from tackerclient.tests.unit.osc.v1.fixture_data import client
25 |
26 |
27 | class TestVnfLcm(base.FixturedTestCase):
28 | client_fixture_class = client.ClientFixture
29 |
30 | def setUp(self):
31 | super(TestVnfLcm, self).setUp()
32 | self.url = client.TACKER_URL
33 | self.header = {'content-type': 'application/json'}
34 | self.app = mock.Mock()
35 | self.app_args = mock.Mock()
36 | self.client_manager = self.cs
37 | self.app.client_manager.tackerclient = self.client_manager
38 |
39 |
40 | @ddt.ddt
41 | class TestVnfLcmVersions(TestVnfLcm):
42 |
43 | def setUp(self):
44 | super(TestVnfLcmVersions, self).setUp()
45 | self.vnflcm_versions = vnflcm_versions.VnfLcmVersions(
46 | self.app, self.app_args, cmd_name='vnflcm versions')
47 |
48 | def _versions_response(self, major_version=None):
49 | if major_version is None:
50 | return {"uriPrefix": "/vnflcm",
51 | "apiVersions": [{"version": "1.3.0",
52 | "isDeprecated": False},
53 | {"version": "2.0.0",
54 | "isDeprecated": False}]}
55 | elif major_version == "1":
56 | return {"uriPrefix": "/vnflcm/v1",
57 | "apiVersions": [{"version": "1.3.0",
58 | "isDeprecated": False}]}
59 | elif major_version == "2":
60 | return {"uriPrefix": "/vnflcm/v2",
61 | "apiVersions": [{"version": "2.0.0",
62 | "isDeprecated": False}]}
63 |
64 | def test_invalid_major_version(self):
65 | parser = self.vnflcm_versions.get_parser('vnflcm versions')
66 | parsed_args = parser.parse_args(["--major-version", "3"])
67 | self.assertRaises(exceptions.InvalidInput,
68 | self.vnflcm_versions.take_action,
69 | parsed_args)
70 |
71 | def test_take_action_no_arg(self):
72 | parser = self.vnflcm_versions.get_parser('vnflcm versions')
73 | parsed_args = parser.parse_args([])
74 |
75 | response = self._versions_response()
76 | self.requests_mock.register_uri(
77 | 'GET', os.path.join(self.url, 'vnflcm/api_versions'),
78 | json=response, headers=self.header)
79 |
80 | colmns, data = self.vnflcm_versions.take_action(parsed_args)
81 |
82 | self.assertEqual(colmns, tuple(response.keys()))
83 | self.assertEqual(data, tuple(response.values()))
84 |
85 | @ddt.data('1', '2')
86 | def test_take_action_with_major_version(self, major_version):
87 | parser = self.vnflcm_versions.get_parser('vnflcm versions')
88 | parsed_args = parser.parse_args(["--major-version",
89 | major_version])
90 |
91 | response = self._versions_response(major_version)
92 | self.requests_mock.register_uri(
93 | 'GET',
94 | os.path.join(self.url,
95 | 'vnflcm/v{}/api_versions'.format(major_version)),
96 | json=response, headers=self.header)
97 |
98 | colmns, data = self.vnflcm_versions.take_action(parsed_args)
99 |
100 | self.assertEqual(colmns, tuple(response.keys()))
101 | self.assertEqual(data, tuple(response.values()))
102 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v2/vnffm_sub_fakes.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2022 Fujitsu
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from oslo_utils import uuidutils
17 |
18 | from tackerclient.osc import utils as tacker_osc_utils
19 |
20 |
21 | def create_vnf_fm_subs(count=2):
22 | """Create multiple fake vnf packages.
23 |
24 | :param int count:
25 | The number of vnf_fm_subs to fake
26 | :return:
27 | A list of fake vnf fm subs dictionary
28 | """
29 | vnf_fm_subs = []
30 | for i in range(0, count):
31 | unique_id = uuidutils.generate_uuid()
32 | vnf_fm_subs.append(vnf_fm_sub_response(attrs={'id': unique_id}))
33 | return vnf_fm_subs
34 |
35 |
36 | def vnf_fm_sub_response(attrs=None):
37 | """Create a fake vnf fm sub.
38 |
39 | :param Dictionary attrs:
40 | A dictionary with all attributes
41 | :return:
42 | A FakeVnfFmAlarm dict
43 | """
44 |
45 | attrs = attrs or {}
46 | # Set default attributes.
47 | fake_vnf_fm_sub = {
48 | "id": "78a39661-60a8-4824-b989-88c1b0c3534a",
49 | "filter": {
50 | "vnfInstanceSubscriptionFilter": {
51 | "vnfdIds": [
52 | "dummy-vnfdId-1"
53 | ],
54 | "vnfProductsFromProviders": [
55 | {
56 | "vnfProvider": "dummy-vnfProvider-1",
57 | "vnfProducts": [
58 | {
59 | "vnfProductName": "dummy-vnfProductName-1-1",
60 | "versions": [
61 | {
62 | "vnfSoftwareVersion": 1.0,
63 | "vnfdVersions": [1.0, 2.0]
64 | }
65 | ]
66 | }
67 | ]
68 | }
69 | ],
70 | "vnfInstanceIds": [
71 | "dummy-vnfInstanceId-1"
72 | ],
73 | "vnfInstanceNames": [
74 | "dummy-vnfInstanceName-1"
75 | ]
76 | },
77 | "notificationTypes": [
78 | "AlarmNotification"
79 | ],
80 | "faultyResourceTypes": [
81 | "COMPUTE"
82 | ],
83 | "perceivedSeverities": [
84 | "WARNING"
85 | ],
86 | "eventTypes": [
87 | "EQUIPMENT_ALARM"
88 | ],
89 | "probableCauses": [
90 | "The server cannot be connected."
91 | ]
92 | },
93 | "callbackUri": "/nfvo/notify/alarm",
94 | "_links": {
95 | "self": {
96 | "href": "/vnffm/v1/subscriptions/"
97 | "78a39661-60a8-4824-b989-88c1b0c3534a"
98 | }
99 | }
100 | }
101 |
102 | # Overwrite default attributes.
103 | fake_vnf_fm_sub.update(attrs)
104 |
105 | return fake_vnf_fm_sub
106 |
107 |
108 | def get_vnffm_sub_data(vnf_fm_sub, columns=None):
109 | """Get the vnffm sub.
110 |
111 | :return:
112 | A tuple object sorted based on the name of the columns.
113 | """
114 | complex_attributes = ['filter', '_links']
115 |
116 | for attribute in complex_attributes:
117 | if vnf_fm_sub.get(attribute):
118 | vnf_fm_sub.update(
119 | {attribute: tacker_osc_utils.FormatComplexDataColumn(
120 | vnf_fm_sub[attribute])})
121 |
122 | # return the list of data as per column order
123 | if columns:
124 | return tuple([vnf_fm_sub[key] for key in columns])
125 |
126 | return tuple([vnf_fm_sub[key] for key in sorted(
127 | vnf_fm_sub.keys())])
128 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/test_validators.py:
--------------------------------------------------------------------------------
1 | # Copyright 2014 NEC Corporation
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import testtools
17 |
18 | from tackerclient.common import exceptions
19 | from tackerclient.common import validators
20 |
21 |
22 | class FakeParsedArgs(object):
23 | pass
24 |
25 |
26 | class ValidatorTest(testtools.TestCase):
27 |
28 | def _test_validate_int(self, attr_val, attr_name='attr1',
29 | min_value=1, max_value=10):
30 | obj = FakeParsedArgs()
31 | setattr(obj, attr_name, attr_val)
32 | ret = validators.validate_int_range(obj, attr_name,
33 | min_value, max_value)
34 | # Come here only if there is no exception.
35 | self.assertIsNone(ret)
36 |
37 | def _test_validate_int_error(self, attr_val, expected_msg,
38 | attr_name='attr1', expected_exc=None,
39 | min_value=1, max_value=10):
40 | if expected_exc is None:
41 | expected_exc = exceptions.CommandError
42 | e = self.assertRaises(expected_exc,
43 | self._test_validate_int,
44 | attr_val, attr_name, min_value, max_value)
45 | self.assertEqual(expected_msg, str(e))
46 |
47 | def test_validate_int_min_max(self):
48 | self._test_validate_int(1)
49 | self._test_validate_int(10)
50 | self._test_validate_int('1')
51 | self._test_validate_int('10')
52 | self._test_validate_int('0x0a')
53 |
54 | self._test_validate_int_error(
55 | 0, 'attr1 "0" should be an integer [1:10].')
56 | self._test_validate_int_error(
57 | 11, 'attr1 "11" should be an integer [1:10].')
58 | self._test_validate_int_error(
59 | '0x10', 'attr1 "0x10" should be an integer [1:10].')
60 |
61 | def test_validate_int_min_only(self):
62 | self._test_validate_int(1, max_value=None)
63 | self._test_validate_int(10, max_value=None)
64 | self._test_validate_int(11, max_value=None)
65 | self._test_validate_int_error(
66 | 0, 'attr1 "0" should be an integer greater than or equal to 1.',
67 | max_value=None)
68 |
69 | def test_validate_int_max_only(self):
70 | self._test_validate_int(0, min_value=None)
71 | self._test_validate_int(1, min_value=None)
72 | self._test_validate_int(10, min_value=None)
73 | self._test_validate_int_error(
74 | 11, 'attr1 "11" should be an integer smaller than or equal to 10.',
75 | min_value=None)
76 |
77 | def test_validate_int_no_limit(self):
78 | self._test_validate_int(0, min_value=None, max_value=None)
79 | self._test_validate_int(1, min_value=None, max_value=None)
80 | self._test_validate_int(10, min_value=None, max_value=None)
81 | self._test_validate_int(11, min_value=None, max_value=None)
82 | self._test_validate_int_error(
83 | 'abc', 'attr1 "abc" should be an integer.',
84 | min_value=None, max_value=None)
85 |
86 | def _test_validate_subnet(self, attr_val, attr_name='attr1'):
87 | obj = FakeParsedArgs()
88 | setattr(obj, attr_name, attr_val)
89 | ret = validators.validate_ip_subnet(obj, attr_name)
90 | # Come here only if there is no exception.
91 | self.assertIsNone(ret)
92 |
93 | def test_validate_ip_subnet(self):
94 | self._test_validate_subnet('192.168.2.0/24')
95 | self._test_validate_subnet('192.168.2.3/20')
96 | self._test_validate_subnet('192.168.2.1')
97 |
98 | e = self.assertRaises(exceptions.CommandError,
99 | self._test_validate_subnet,
100 | '192.168.2.256')
101 | self.assertEqual('attr1 "192.168.2.256" is not a valid CIDR.', str(e))
102 |
--------------------------------------------------------------------------------
/tackerclient/osc/v1/vnflcm/samples/create_lccn_subscription_param_sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "filter": {
3 | "vnfInstanceSubscriptionFilter": {
4 | "vnfdIds": [
5 | "dummy-vnfdId-1",
6 | "dummy-vnfdId-2"
7 | ],
8 | "vnfProductsFromProviders": [
9 | {
10 | "vnfProvider": "dummy-vnfProvider-1",
11 | "vnfProducts": [
12 | {
13 | "vnfProductName": "dummy-vnfProductName-1-1",
14 | "versions": [
15 | {
16 | "vnfSoftwareVersion": "1.0",
17 | "vnfdVersions": ["1.0", "2.0"]
18 | },
19 | {
20 | "vnfSoftwareVersion": "1.1",
21 | "vnfdVersions": ["1.1", "2.1"]
22 | }
23 | ]
24 | },
25 | {
26 | "vnfProductName": "dummy-vnfProductName-1-2",
27 | "versions": [
28 | {
29 | "vnfSoftwareVersion": "1.0",
30 | "vnfdVersions": ["1.0", "2.0"]
31 | },
32 | {
33 | "vnfSoftwareVersion": "1.1",
34 | "vnfdVersions": ["1.1", "2.1"]
35 | }
36 | ]
37 | }
38 | ]
39 | },
40 | {
41 | "vnfProvider": "dummy-vnfProvider-2",
42 | "vnfProducts": [
43 | {
44 | "vnfProductName": "dummy-vnfProductName-2-1",
45 | "versions": [
46 | {
47 | "vnfSoftwareVersion": "1.0",
48 | "vnfdVersions": ["1.0", "2.0"]
49 | },
50 | {
51 | "vnfSoftwareVersion": "1.1",
52 | "vnfdVersions": ["1.1", "2.1"]
53 | }
54 | ]
55 | },
56 | {
57 | "vnfProductName": "dummy-vnfProductName-2-2",
58 | "versions": [
59 | {
60 | "vnfSoftwareVersion": "1.0",
61 | "vnfdVersions": ["1.0", "2.0"]
62 | },
63 | {
64 | "vnfSoftwareVersion": "1.1",
65 | "vnfdVersions": ["1.1", "2.1"]
66 | }
67 | ]
68 | }
69 | ]
70 | }
71 | ],
72 | "vnfInstanceIds": [
73 | "dummy-vnfInstanceId-1",
74 | "dummy-vnfInstanceId-2"
75 | ],
76 | "vnfInstanceNames": [
77 | "dummy-vnfInstanceName-1",
78 | "dummy-vnfInstanceName-2"
79 | ]
80 | },
81 | "notificationTypes": [
82 | "VnfLcmOperationOccurrenceNotification",
83 | "VnfIdentifierCreationNotification",
84 | "VnfIdentifierDeletionNotification"
85 | ],
86 | "operationTypes": [
87 | "INSTANTIATE",
88 | "SCALE",
89 | "TERMINATE",
90 | "HEAL",
91 | "MODIFY_INFO",
92 | "CHANGE_EXT_CONN"
93 | ],
94 | "operationStates": [
95 | "COMPLETED",
96 | "FAILED",
97 | "FAILED_TEMP",
98 | "PROCESSING",
99 | "ROLLING_BACK",
100 | "ROLLED_BACK",
101 | "STARTING"
102 | ]
103 | },
104 | "callbackUri": "http://localhost:9990/notification/callback/test",
105 | "authentication": {
106 | "authType": [
107 | "BASIC"
108 | ],
109 | "paramsBasic": {
110 | "password": "test_pass",
111 | "userName": "test_user"
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v2/vnffm_alarm_fakes.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2022 Fujitsu
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from oslo_utils import uuidutils
17 |
18 | from tackerclient.osc import utils as tacker_osc_utils
19 |
20 |
21 | def create_vnf_fm_alarms(count=2):
22 | """Create multiple fake vnf packages.
23 |
24 | :param int count:
25 | The number of vnf_fm_alarms to fake
26 | :return:
27 | A list of fake vnf fm alarms dictionary
28 | """
29 | vnf_fm_alarms = []
30 | for i in range(0, count):
31 | unique_id = uuidutils.generate_uuid()
32 | vnf_fm_alarms.append(vnf_fm_alarm_response(attrs={'id': unique_id}))
33 | return vnf_fm_alarms
34 |
35 |
36 | def vnf_fm_alarm_response(attrs=None, action=None):
37 | """Create a fake vnf fm alarm.
38 |
39 | :param Dictionary attrs:
40 | A dictionary with all attributes
41 | :return:
42 | A FakeVnfFmAlarm dict
43 | """
44 |
45 | if action == 'update':
46 | fake_vnf_fm_alarm = {
47 | "ackState": "UNACKNOWLEDGED"
48 | }
49 | return fake_vnf_fm_alarm
50 |
51 | attrs = attrs or {}
52 | # Set default attributes.
53 | fake_vnf_fm_alarm = {
54 | "id": "78a39661-60a8-4824-b989-88c1b0c3534a",
55 | "managedObjectId": "c61314d0-f583-4ab3-a457-46426bce02d3",
56 | "vnfcInstanceIds": "0e5f3086-4e79-47ed-a694-54c29155fa26",
57 | "rootCauseFaultyResource": {
58 | "faultyResource": {
59 | "vimConnectionId": "0d57e928-86a4-4445-a4bd-1634edae73f3",
60 | "resourceId": "4e6ccbe1-38ec-4b1b-a278-64de09ba01b3",
61 | "vimLevelResourceType": "OS::Nova::Server"
62 | },
63 | "faultyResourceType": "COMPUTE"
64 | },
65 | "alarmRaisedTime": "2021-09-03 10:21:03",
66 | "alarmChangedTime": "2021-09-04 10:21:03",
67 | "alarmClearedTime": "2021-09-05 10:21:03",
68 | "alarmAcknowledgedTime": "2021-09-06 10:21:03",
69 | "ackState": "UNACKNOWLEDGED",
70 | "perceivedSeverity": "WARNING",
71 | "eventTime": "2021-09-07 10:06:03",
72 | "eventType": "EQUIPMENT_ALARM",
73 | "faultType": "Fault Type",
74 | "probableCause": "The server cannot be connected.",
75 | "isRootCause": False,
76 | "correlatedAlarmIds": [
77 | "c88b624e-e997-4b17-b674-10ca2bab62e0",
78 | "c16d41fd-12e2-49a6-bb17-72faf702353f"
79 | ],
80 | "faultDetails": [
81 | "Fault",
82 | "Details"
83 | ],
84 | "_links": {
85 | "self": {
86 | "href": "/vnffm/v1/alarms/"
87 | "78a39661-60a8-4824-b989-88c1b0c3534a"
88 | },
89 | "objectInstance": {
90 | "href": "/vnflcm/v1/vnf_instances/"
91 | "0e5f3086-4e79-47ed-a694-54c29155fa26"
92 | }
93 | }
94 | }
95 |
96 | # Overwrite default attributes.
97 | fake_vnf_fm_alarm.update(attrs)
98 |
99 | return fake_vnf_fm_alarm
100 |
101 |
102 | def get_vnffm_alarm_data(vnf_fm_alarm, columns=None):
103 | """Get the vnffm alarm.
104 |
105 | :return:
106 | A tuple object sorted based on the name of the columns.
107 | """
108 | complex_attributes = [
109 | 'vnfcInstanceIds',
110 | 'rootCauseFaultyResource',
111 | 'correlatedAlarmIds',
112 | 'faultDetails',
113 | '_links'
114 | ]
115 |
116 | for attribute in complex_attributes:
117 | if vnf_fm_alarm.get(attribute):
118 | vnf_fm_alarm.update(
119 | {attribute: tacker_osc_utils.FormatComplexDataColumn(
120 | vnf_fm_alarm[attribute])})
121 |
122 | # return the list of data as per column order
123 | if columns:
124 | return tuple([vnf_fm_alarm[key] for key in columns])
125 |
126 | return tuple([vnf_fm_alarm[key] for key in sorted(
127 | vnf_fm_alarm.keys())])
128 |
--------------------------------------------------------------------------------
/tackerclient/osc/sdk_utils.py:
--------------------------------------------------------------------------------
1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 | # not use this file except in compliance with the License. You may obtain
3 | # a copy of the License at
4 | #
5 | # http://www.apache.org/licenses/LICENSE-2.0
6 | #
7 | # Unless required by applicable law or agreed to in writing, software
8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 | # License for the specific language governing permissions and limitations
11 | # under the License.
12 |
13 | import sys
14 |
15 | from oslo_utils import encodeutils
16 |
17 |
18 | def get_osc_show_columns_for_sdk_resource(
19 | sdk_resource,
20 | osc_column_map,
21 | invisible_columns=None
22 | ):
23 | """Get and filter the display and attribute columns for an SDK resource.
24 |
25 | Common utility function for preparing the output of an OSC show command.
26 | Some of the columns may need to get renamed, others made invisible.
27 |
28 | :param sdk_resource: An SDK resource
29 | :param osc_column_map: A hash of mappings for display column names
30 | :param invisible_columns: A list of invisible column names
31 |
32 | :returns: Two tuples containing the names of the display and attribute
33 | columns
34 | """
35 |
36 | if getattr(sdk_resource, 'allow_get', None) is not None:
37 | resource_dict = sdk_resource.to_dict(
38 | body=True, headers=False, ignore_none=False)
39 | else:
40 | resource_dict = sdk_resource
41 |
42 | # Build the OSC column names to display for the SDK resource.
43 | attr_map = {}
44 | display_columns = list(resource_dict.keys())
45 | invisible_columns = [] if invisible_columns is None else invisible_columns
46 | for col_name in invisible_columns:
47 | if col_name in display_columns:
48 | display_columns.remove(col_name)
49 | for sdk_attr, osc_attr in osc_column_map.items():
50 | if sdk_attr in display_columns:
51 | attr_map[osc_attr] = sdk_attr
52 | display_columns.remove(sdk_attr)
53 | if osc_attr not in display_columns:
54 | display_columns.append(osc_attr)
55 | sorted_display_columns = sorted(display_columns)
56 |
57 | # Build the SDK attribute names for the OSC column names.
58 | attr_columns = []
59 | for column in sorted_display_columns:
60 | new_column = attr_map[column] if column in attr_map else column
61 | attr_columns.append(new_column)
62 | return tuple(sorted_display_columns), tuple(attr_columns)
63 |
64 |
65 | class DictModel(dict):
66 | """Convert dict into an object that provides attribute access to values."""
67 |
68 | def __init__(self, *args, **kwargs):
69 | """Convert dict values to DictModel values."""
70 | super(DictModel, self).__init__(*args, **kwargs)
71 |
72 | def needs_upgrade(item):
73 | return isinstance(item, dict) and not isinstance(item, DictModel)
74 |
75 | def upgrade(item):
76 | """Upgrade item if it needs to be upgraded."""
77 | if needs_upgrade(item):
78 | return DictModel(item)
79 | else:
80 | return item
81 |
82 | for key, value in self.items():
83 | if isinstance(value, (list, tuple)):
84 | # Keep the same type but convert dicts to DictModels
85 | self[key] = type(value)(
86 | (upgrade(item) for item in value)
87 | )
88 | elif needs_upgrade(value):
89 | # Change dict instance values to DictModel instance values
90 | self[key] = DictModel(value)
91 |
92 | def __getattr__(self, name):
93 | try:
94 | return self[name]
95 | except KeyError as e:
96 | raise AttributeError(e)
97 |
98 | def __setattr__(self, name, value):
99 | self[name] = value
100 |
101 | def __delattr__(self, name):
102 | del self[name]
103 |
104 | def __str__(self):
105 | pairs = ['%s=%s' % (k, v) for k, v in self.items()]
106 | return ', '.join(sorted(pairs))
107 |
108 |
109 | def save_data(data, path):
110 | """Save data to the specified path.
111 |
112 | :param data: binary or string data
113 | :param path: file path to save data
114 | """
115 | if path is None:
116 | vnfpackage = getattr(sys.stdout, 'buffer', sys.stdout)
117 | else:
118 | mode = 'wb' if isinstance(data, bytes) else 'w'
119 | vnfpackage = open(path, mode)
120 | try:
121 | vnfpackage.write(data)
122 | finally:
123 | vnfpackage.close()
124 |
125 |
126 | def exit(msg=None, exit_code=1):
127 | if msg:
128 | print(encodeutils.safe_decode(msg))
129 | sys.exit(exit_code)
130 |
--------------------------------------------------------------------------------
/tackerclient/tacker/v1_0/nfvo/vim_utils.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 Brocade Communications Systems Inc
2 | # All Rights Reserved.
3 | #
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | from urllib import parse as urlparse
18 |
19 | from tackerclient.common import exceptions
20 |
21 |
22 | def args2body_vim(config_param, vim):
23 | """Create additional args to vim body
24 |
25 | :param vim: vim request object
26 | :return: vim body with args populated
27 | """
28 | vim_type = ['openstack', 'kubernetes']
29 | cert_verify_type = ['True', 'False']
30 |
31 | if 'type' in config_param:
32 | vim['type'] = config_param.pop('type', '')
33 | if not vim['type'] in vim_type:
34 | raise exceptions.TackerClientException(
35 | message='Supported VIM types: openstack, kubernetes',
36 | status_code=400)
37 | else:
38 | vim['type'] = 'openstack'
39 | if vim['type'] == 'openstack':
40 | vim['vim_project'] = {
41 | 'name': config_param.pop('project_name', ''),
42 | 'project_domain_name':
43 | config_param.pop('project_domain_name', '')}
44 | if not vim['vim_project']['name']:
45 | raise exceptions.TackerClientException(
46 | message='Project name must be specified',
47 | status_code=404)
48 | cert_verify = config_param.pop('cert_verify', 'True')
49 | if cert_verify not in cert_verify_type:
50 | raise exceptions.TackerClientException(
51 | message='Supported cert_verify types: True, False',
52 | status_code=400)
53 | vim['auth_cred'] = {'username': config_param.pop('username', ''),
54 | 'password': config_param.pop('password', ''),
55 | 'user_domain_name':
56 | config_param.pop('user_domain_name', ''),
57 | 'cert_verify': cert_verify}
58 | elif vim['type'] == 'kubernetes':
59 | vim['vim_project'] = {
60 | 'name': config_param.pop('project_name', '')}
61 | if not vim['vim_project']['name']:
62 | raise exceptions.TackerClientException(
63 | message='Project name must be specified in Kubernetes VIM,'
64 | 'it is namespace in Kubernetes environment',
65 | status_code=404)
66 | if 'oidc_token_url' in config_param:
67 | if ('username' not in config_param or
68 | 'password' not in config_param or
69 | 'client_id' not in config_param):
70 | # the username, password, client_id are required.
71 | # client_secret is not required when client type is public.
72 | raise exceptions.TackerClientException(
73 | message='oidc_token_url must be specified with username,'
74 | ' password, client_id, client_secret(optional).',
75 | status_code=404)
76 | vim['auth_cred'] = {
77 | 'oidc_token_url': config_param.pop('oidc_token_url'),
78 | 'username': config_param.pop('username'),
79 | 'password': config_param.pop('password'),
80 | 'client_id': config_param.pop('client_id')}
81 | if 'client_secret' in config_param:
82 | vim['auth_cred']['client_secret'] = config_param.pop(
83 | 'client_secret')
84 | elif ('username' in config_param) and ('password' in config_param):
85 | vim['auth_cred'] = {
86 | 'username': config_param.pop('username', ''),
87 | 'password': config_param.pop('password', '')}
88 | elif 'bearer_token' in config_param:
89 | vim['auth_cred'] = {
90 | 'bearer_token': config_param.pop('bearer_token', '')}
91 | else:
92 | raise exceptions.TackerClientException(
93 | message='username and password or bearer_token must be'
94 | 'provided',
95 | status_code=404)
96 | ssl_ca_cert = config_param.pop('ssl_ca_cert', '')
97 | if ssl_ca_cert:
98 | vim['auth_cred']['ssl_ca_cert'] = ssl_ca_cert
99 | if 'extra' in config_param:
100 | vim['extra'] = config_param.pop('extra')
101 |
102 |
103 | def validate_auth_url(url):
104 | url_parts = urlparse.urlparse(url)
105 | if not url_parts.scheme or not url_parts.netloc:
106 | raise exceptions.TackerClientException(message='Invalid auth URL')
107 | return url_parts
108 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/test_casual_args.py:
--------------------------------------------------------------------------------
1 | # Copyright 2012 OpenStack Foundation.
2 | # All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 | #
16 |
17 | import testtools
18 |
19 | from tackerclient.common import exceptions
20 | from tackerclient.tacker import v1_0 as tackerV10
21 |
22 |
23 | class CLITestArgs(testtools.TestCase):
24 |
25 | def test_empty(self):
26 | _mydict = tackerV10.parse_args_to_dict([])
27 | self.assertEqual({}, _mydict)
28 |
29 | def test_default_bool(self):
30 | _specs = ['--my_bool', '--arg1', 'value1']
31 | _mydict = tackerV10.parse_args_to_dict(_specs)
32 | self.assertTrue(_mydict['my_bool'])
33 |
34 | def test_bool_true(self):
35 | _specs = ['--my-bool', 'type=bool', 'true', '--arg1', 'value1']
36 | _mydict = tackerV10.parse_args_to_dict(_specs)
37 | self.assertTrue(_mydict['my_bool'])
38 |
39 | def test_bool_false(self):
40 | _specs = ['--my_bool', 'type=bool', 'false', '--arg1', 'value1']
41 | _mydict = tackerV10.parse_args_to_dict(_specs)
42 | self.assertFalse(_mydict['my_bool'])
43 |
44 | def test_nargs(self):
45 | _specs = ['--tag', 'x', 'y', '--arg1', 'value1']
46 | _mydict = tackerV10.parse_args_to_dict(_specs)
47 | self.assertIn('x', _mydict['tag'])
48 | self.assertIn('y', _mydict['tag'])
49 |
50 | def test_badarg(self):
51 | _specs = ['--tag=t', 'x', 'y', '--arg1', 'value1']
52 | self.assertRaises(exceptions.CommandError,
53 | tackerV10.parse_args_to_dict, _specs)
54 |
55 | def test_badarg_with_minus(self):
56 | _specs = ['--arg1', 'value1', '-D']
57 | self.assertRaises(exceptions.CommandError,
58 | tackerV10.parse_args_to_dict, _specs)
59 |
60 | def test_goodarg_with_minus_number(self):
61 | _specs = ['--arg1', 'value1', '-1', '-1.0']
62 | _mydict = tackerV10.parse_args_to_dict(_specs)
63 | self.assertEqual(['value1', '-1', '-1.0'],
64 | _mydict['arg1'])
65 |
66 | def test_badarg_duplicate(self):
67 | _specs = ['--tag=t', '--arg1', 'value1', '--arg1', 'value1']
68 | self.assertRaises(exceptions.CommandError,
69 | tackerV10.parse_args_to_dict, _specs)
70 |
71 | def test_badarg_early_type_specification(self):
72 | _specs = ['type=dict', 'key=value']
73 | self.assertRaises(exceptions.CommandError,
74 | tackerV10.parse_args_to_dict, _specs)
75 |
76 | def test_arg(self):
77 | _specs = ['--tag=t', '--arg1', 'value1']
78 | self.assertEqual('value1',
79 | tackerV10.parse_args_to_dict(_specs)['arg1'])
80 |
81 | def test_dict_arg(self):
82 | _specs = ['--tag=t', '--arg1', 'type=dict', 'key1=value1,key2=value2']
83 | arg1 = tackerV10.parse_args_to_dict(_specs)['arg1']
84 | self.assertEqual('value1', arg1['key1'])
85 | self.assertEqual('value2', arg1['key2'])
86 |
87 | def test_dict_arg_with_attribute_named_type(self):
88 | _specs = ['--tag=t', '--arg1', 'type=dict', 'type=value1,key2=value2']
89 | arg1 = tackerV10.parse_args_to_dict(_specs)['arg1']
90 | self.assertEqual('value1', arg1['type'])
91 | self.assertEqual('value2', arg1['key2'])
92 |
93 | def test_list_of_dict_arg(self):
94 | _specs = ['--tag=t', '--arg1', 'type=dict',
95 | 'list=true', 'key1=value1,key2=value2']
96 | arg1 = tackerV10.parse_args_to_dict(_specs)['arg1']
97 | self.assertEqual('value1', arg1[0]['key1'])
98 | self.assertEqual('value2', arg1[0]['key2'])
99 |
100 | def test_clear_action(self):
101 | _specs = ['--anyarg', 'action=clear']
102 | args = tackerV10.parse_args_to_dict(_specs)
103 | self.assertIsNone(args['anyarg'])
104 |
105 | def test_bad_values_str(self):
106 | _specs = ['--strarg', 'type=str']
107 | self.assertRaises(exceptions.CommandError,
108 | tackerV10.parse_args_to_dict, _specs)
109 |
110 | def test_bad_values_list(self):
111 | _specs = ['--listarg', 'list=true', 'type=str']
112 | self.assertRaises(exceptions.CommandError,
113 | tackerV10.parse_args_to_dict, _specs)
114 | _specs = ['--listarg', 'type=list']
115 | self.assertRaises(exceptions.CommandError,
116 | tackerV10.parse_args_to_dict, _specs)
117 | _specs = ['--listarg', 'type=list', 'action=clear']
118 | self.assertRaises(exceptions.CommandError,
119 | tackerV10.parse_args_to_dict, _specs)
120 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v2/test_vnfpm_report.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2022 Fujitsu
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import os
17 |
18 | from oslo_utils.fixture import uuidsentinel
19 | from unittest import mock
20 |
21 | from tackerclient.common import exceptions
22 | from tackerclient.osc.v2.vnfpm import vnfpm_report
23 | from tackerclient.tests.unit.osc import base
24 | from tackerclient.tests.unit.osc.v1.fixture_data import client
25 | from tackerclient.tests.unit.osc.v2 import vnfpm_report_fakes
26 |
27 |
28 | class TestVnfPmReport(base.FixturedTestCase):
29 | client_fixture_class = client.ClientFixture
30 |
31 | def setUp(self):
32 | super(TestVnfPmReport, self).setUp()
33 | self.url = client.TACKER_URL
34 | self.header = {'content-type': 'application/json'}
35 | self.app = mock.Mock()
36 | self.app_args = mock.Mock()
37 | self.client_manager = self.cs
38 | self.app.client_manager.tackerclient = self.client_manager
39 |
40 |
41 | def _get_columns_vnfpm_report():
42 | columns = ['Entries']
43 | return columns
44 |
45 |
46 | class TestShowVnfPmReport(TestVnfPmReport):
47 |
48 | def setUp(self):
49 | super(TestShowVnfPmReport, self).setUp()
50 | self.show_vnf_pm_reports = vnfpm_report.ShowVnfPmReport(
51 | self.app, self.app_args, cmd_name='vnfpm report show')
52 |
53 | def test_take_action(self):
54 | """Test of take_action()"""
55 | vnfpm_report_obj = vnfpm_report_fakes.vnf_pm_report_response()
56 | vnf_pm_job_id = uuidsentinel.vnf_pm_job_id
57 | vnf_pm_report_id = uuidsentinel.vnfpm_report_obj
58 | arg_list = [vnf_pm_job_id, vnf_pm_report_id]
59 | verify_list = [
60 | ('vnf_pm_job_id', vnf_pm_job_id),
61 | ('vnf_pm_report_id', vnf_pm_report_id)
62 | ]
63 |
64 | # command param
65 | parsed_args = self.check_parser(
66 | self.show_vnf_pm_reports, arg_list, verify_list)
67 | url = os.path.join(
68 | self.url, 'vnfpm/v2/pm_jobs', vnf_pm_job_id,
69 | 'reports', vnf_pm_report_id)
70 |
71 | self.requests_mock.register_uri(
72 | 'GET', url, headers=self.header, json=vnfpm_report_obj)
73 |
74 | columns, data = (self.show_vnf_pm_reports.take_action(parsed_args))
75 |
76 | self.assertCountEqual(_get_columns_vnfpm_report(), columns)
77 |
78 | _, attributes = vnfpm_report._get_columns(vnfpm_report_obj)
79 | expected_data = vnfpm_report_fakes.get_vnfpm_report_data(
80 | vnfpm_report_obj, columns=attributes)
81 |
82 | print(f'123, {expected_data}')
83 | print(f'456, {data}')
84 | self.assertListItemsEqual(expected_data, data)
85 |
86 | def test_take_action_vnf_pm_report_id_not_found(self):
87 | """Test if vnf-pm-report-id does not find."""
88 | vnf_pm_job_id = uuidsentinel.vnf_pm_job_id
89 | vnf_pm_report_id = uuidsentinel.vnf_pm_report_id
90 | arg_list = [vnf_pm_job_id, vnf_pm_report_id]
91 | verify_list = [
92 | ('vnf_pm_job_id', vnf_pm_job_id),
93 | ('vnf_pm_report_id', vnf_pm_report_id)
94 | ]
95 |
96 | # command param
97 | parsed_args = self.check_parser(
98 | self.show_vnf_pm_reports, arg_list, verify_list)
99 |
100 | url = os.path.join(
101 | self.url, 'vnfpm/v2/pm_jobs', vnf_pm_job_id,
102 | 'reports', vnf_pm_report_id)
103 | self.requests_mock.register_uri(
104 | 'GET', url, headers=self.header, status_code=404, json={})
105 |
106 | self.assertRaises(exceptions.TackerClientException,
107 | self.show_vnf_pm_reports.take_action,
108 | parsed_args)
109 |
110 | def test_take_action_internal_server_error(self):
111 | """Test for internal server error."""
112 | vnf_pm_job_id = uuidsentinel.vnf_pm_job_id
113 | vnf_pm_report_id = uuidsentinel.vnf_pm_report_id
114 | arg_list = [vnf_pm_job_id, vnf_pm_report_id]
115 | verify_list = [
116 | ('vnf_pm_job_id', vnf_pm_job_id),
117 | ('vnf_pm_report_id', vnf_pm_report_id)
118 | ]
119 | # command param
120 | parsed_args = self.check_parser(
121 | self.show_vnf_pm_reports, arg_list, verify_list)
122 |
123 | url = os.path.join(
124 | self.url, 'vnfpm/v2/pm_jobs', vnf_pm_job_id,
125 | 'reports', vnf_pm_report_id)
126 | self.requests_mock.register_uri(
127 | 'GET', url, headers=self.header, status_code=500, json={})
128 |
129 | self.assertRaises(exceptions.TackerClientException,
130 | self.show_vnf_pm_reports.take_action,
131 | parsed_args)
132 |
--------------------------------------------------------------------------------
/tackerclient/tacker/v1_0/nfvo/vim.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 Brocade Communications Systems Inc
2 | # All Rights Reserved.
3 | #
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | import yaml
18 |
19 | from oslo_utils import strutils
20 |
21 | from tackerclient.common import exceptions
22 | from tackerclient.i18n import _
23 | from tackerclient.tacker import v1_0 as tackerV10
24 | from tackerclient.tacker.v1_0.nfvo import vim_utils
25 |
26 | _VIM = "vim"
27 |
28 |
29 | class ListVIM(tackerV10.ListCommand):
30 | """List VIMs that belong to a given tenant."""
31 |
32 | resource = _VIM
33 | list_columns = ['id', 'tenant_id', 'name', 'type', 'is_default',
34 | 'placement_attr', 'status']
35 |
36 |
37 | class ShowVIM(tackerV10.ShowCommand):
38 | """Show information of a given VIM."""
39 |
40 | resource = _VIM
41 |
42 |
43 | class CreateVIM(tackerV10.CreateCommand):
44 | """Create a VIM."""
45 |
46 | resource = _VIM
47 |
48 | def add_known_arguments(self, parser):
49 | parser.add_argument(
50 | '--config-file',
51 | required=True,
52 | help=_('YAML file with VIM configuration parameters'))
53 | parser.add_argument(
54 | 'name', metavar='NAME',
55 | help=_('Set a name for the VIM'))
56 | parser.add_argument(
57 | '--description',
58 | help=_('Set a description for the VIM'))
59 | parser.add_argument(
60 | '--is-default',
61 | action='store_true',
62 | default=False,
63 | help=_('Set as default VIM'))
64 |
65 | def args2body(self, parsed_args):
66 | body = {self.resource: {}}
67 | if parsed_args.config_file:
68 | with open(parsed_args.config_file) as f:
69 | vim_config = f.read()
70 | try:
71 | config_param = yaml.load(vim_config,
72 | Loader=yaml.SafeLoader)
73 | except yaml.YAMLError as e:
74 | raise exceptions.InvalidInput(reason=e)
75 | vim_obj = body[self.resource]
76 | try:
77 | auth_url = config_param.pop('auth_url')
78 | except KeyError:
79 | raise exceptions.TackerClientException(message='Auth URL must be '
80 | 'specified',
81 | status_code=404)
82 | vim_obj['auth_url'] = vim_utils.validate_auth_url(auth_url).geturl()
83 | vim_utils.args2body_vim(config_param, vim_obj)
84 | tackerV10.update_dict(parsed_args, body[self.resource],
85 | ['tenant_id', 'name', 'description',
86 | 'is_default'])
87 | return body
88 |
89 |
90 | class UpdateVIM(tackerV10.UpdateCommand):
91 | """Update a given VIM."""
92 |
93 | resource = _VIM
94 |
95 | def add_known_arguments(self, parser):
96 | parser.add_argument(
97 | '--config-file',
98 | required=False,
99 | help=_('YAML file with VIM configuration parameters'))
100 | parser.add_argument(
101 | '--name',
102 | help=_('New name for the VIM'))
103 | parser.add_argument(
104 | '--description',
105 | help=_('New description for the VIM'))
106 | parser.add_argument(
107 | '--is-default',
108 | type=strutils.bool_from_string,
109 | metavar='{True,False}',
110 | help=_('Indicate whether the VIM is used as default'))
111 |
112 | def args2body(self, parsed_args):
113 | body = {self.resource: {}}
114 | config_param = None
115 | # config arg passed as data overrides config yaml when both args passed
116 | if parsed_args.config_file:
117 | with open(parsed_args.config_file) as f:
118 | config_yaml = f.read()
119 | try:
120 | config_param = yaml.load(config_yaml,
121 | Loader=yaml.SafeLoader)
122 | except yaml.YAMLError as e:
123 | raise exceptions.InvalidInput(reason=e)
124 | vim_obj = body[self.resource]
125 | if config_param is not None:
126 | vim_utils.args2body_vim(config_param, vim_obj)
127 | tackerV10.update_dict(parsed_args, body[self.resource],
128 | ['tenant_id', 'name', 'description',
129 | 'is_default'])
130 | # type attribute is read-only, it can't be updated, so remove it
131 | # in update method
132 | body['vim'].pop('type', None)
133 | return body
134 |
135 |
136 | class DeleteVIM(tackerV10.DeleteCommand):
137 | """Delete given VIM(s)."""
138 | resource = _VIM
139 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/test_utils.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Yahoo! Inc.
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import testtools
17 |
18 | from tackerclient.common import exceptions
19 | from tackerclient.common import utils
20 |
21 |
22 | class TestUtils(testtools.TestCase):
23 | def test_string_to_bool_true(self):
24 | self.assertTrue(utils.str2bool('true'))
25 |
26 | def test_string_to_bool_false(self):
27 | self.assertFalse(utils.str2bool('false'))
28 |
29 | def test_string_to_bool_None(self):
30 | self.assertIsNone(utils.str2bool(None))
31 |
32 | def test_string_to_dictionary(self):
33 | input_str = 'key1=value1,key2=value2'
34 | expected = {'key1': 'value1', 'key2': 'value2'}
35 | self.assertEqual(expected, utils.str2dict(input_str))
36 |
37 | def test_none_string_to_dictionary(self):
38 | input_str = ''
39 | expected = {}
40 | self.assertEqual(expected, utils.str2dict(input_str))
41 | input_str = None
42 | expected = {}
43 | self.assertEqual(expected, utils.str2dict(input_str))
44 |
45 | def test_get_dict_item_properties(self):
46 | item = {'name': 'test_name', 'id': 'test_id'}
47 | fields = ('name', 'id')
48 | actual = utils.get_item_properties(item=item, fields=fields)
49 | self.assertEqual(('test_name', 'test_id'), actual)
50 |
51 | def test_get_object_item_properties_mixed_case_fields(self):
52 | class Fake(object):
53 | def __init__(self):
54 | self.id = 'test_id'
55 | self.name = 'test_name'
56 | self.test_user = 'test'
57 |
58 | fields = ('name', 'id', 'test user')
59 | mixed_fields = ('test user', 'ID')
60 | item = Fake()
61 | actual = utils.get_item_properties(item, fields, mixed_fields)
62 | self.assertEqual(('test_name', 'test_id', 'test'), actual)
63 |
64 | def test_get_object_item_desired_fields_differ_from_item(self):
65 | class Fake(object):
66 | def __init__(self):
67 | self.id = 'test_id_1'
68 | self.name = 'test_name'
69 | self.test_user = 'test'
70 |
71 | fields = ('name', 'id', 'test user')
72 | item = Fake()
73 | actual = utils.get_item_properties(item, fields)
74 | self.assertNotEqual(('test_name', 'test_id', 'test'), actual)
75 |
76 | def test_get_object_item_desired_fields_is_empty(self):
77 | class Fake(object):
78 | def __init__(self):
79 | self.id = 'test_id_1'
80 | self.name = 'test_name'
81 | self.test_user = 'test'
82 |
83 | fields = []
84 | item = Fake()
85 | actual = utils.get_item_properties(item, fields)
86 | self.assertEqual((), actual)
87 |
88 | def test_get_object_item_with_formatters(self):
89 | class Fake(object):
90 | def __init__(self):
91 | self.id = 'test_id'
92 | self.name = 'test_name'
93 | self.test_user = 'test'
94 |
95 | class FakeCallable(object):
96 | def __call__(self, *args, **kwargs):
97 | return 'pass'
98 |
99 | fields = ('name', 'id', 'test user', 'is_public')
100 | formatters = {'is_public': FakeCallable()}
101 | item = Fake()
102 | act = utils.get_item_properties(item, fields, formatters=formatters)
103 | self.assertEqual(('test_name', 'test_id', 'test', 'pass'), act)
104 |
105 |
106 | class ImportClassTestCase(testtools.TestCase):
107 |
108 | def test_get_client_class_invalid_version(self):
109 | self.assertRaises(
110 | exceptions.UnsupportedVersion,
111 | utils.get_client_class, 'image', '2', {'image': '2'})
112 |
113 |
114 | class ContainsKeyValue(object):
115 | """Checks whether a key/value pair is in a dict parameter.
116 |
117 | The ContainsKeyValue class is a helper for mock.assert_*()
118 | method. It enables strict check than the built in mock.ANY
119 | helper, and is the equivalent of the mox.ContainsKeyValue()
120 | function from the legacy mox library
121 |
122 | Example usage could be:
123 |
124 | mock_some_method.assert_called_once_with(
125 | "hello",
126 | ContainsKeyValue('foo', bar),
127 | mock.ANY,
128 | "world",
129 | ContainsKeyValue('hello', world))
130 | """
131 | def __init__(self, wantkey, wantvalue):
132 | self.wantkey = wantkey
133 | self.wantvalue = wantvalue
134 |
135 | def __eq__(self, other):
136 | try:
137 | return other[self.wantkey] == self.wantvalue
138 | except (KeyError, TypeError):
139 | return False
140 |
141 | def __ne__(self, other):
142 | try:
143 | return other[self.wantkey] != self.wantvalue
144 | except (KeyError, TypeError):
145 | return True
146 |
147 | def __repr__(self):
148 | return ""
150 |
--------------------------------------------------------------------------------
/tackerclient/common/exceptions.py:
--------------------------------------------------------------------------------
1 | # Copyright 2011 VMware, Inc
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from tackerclient.i18n import _
17 |
18 | """
19 | Tacker base exception handling.
20 |
21 | Exceptions are classified into three categories:
22 | * Exceptions corresponding to exceptions from tacker server:
23 | This type of exceptions should inherit one of exceptions
24 | in HTTP_EXCEPTION_MAP.
25 | * Exceptions from client library:
26 | This type of exceptions should inherit TackerClientException.
27 | * Exceptions from CLI code:
28 | This type of exceptions should inherit TackerCLIError.
29 | """
30 |
31 |
32 | class TackerException(Exception):
33 | """Base Tacker Exception.
34 |
35 | To correctly use this class, inherit from it and define
36 | a 'message' property. That message will get printf'd
37 | with the keyword arguments provided to the constructor.
38 | """
39 | message = _("An unknown exception occurred.")
40 |
41 | def __init__(self, message=None, **kwargs):
42 | if message:
43 | self.message = message
44 | try:
45 | self._error_string = self.message % kwargs
46 | except Exception:
47 | # at least get the core message out if something happened
48 | self._error_string = self.message
49 |
50 | def __str__(self):
51 | return self._error_string
52 |
53 |
54 | class TackerClientException(TackerException):
55 | """Base exception which exceptions from Tacker are mapped into.
56 |
57 | NOTE: on the client side, we use different exception types in order
58 | to allow client library users to handle server exceptions in try...except
59 | blocks. The actual error message is the one generated on the server side.
60 | """
61 |
62 | status_code = 0
63 |
64 | def __init__(self, message=None, **kwargs):
65 | if 'status_code' in kwargs:
66 | self.status_code = kwargs['status_code']
67 | super(TackerClientException, self).__init__(message, **kwargs)
68 |
69 |
70 | # Base exceptions from Tacker
71 |
72 | class BadRequest(TackerClientException):
73 | status_code = 400
74 |
75 |
76 | class Unauthorized(TackerClientException):
77 | status_code = 401
78 | message = _("Unauthorized: bad credentials.")
79 |
80 |
81 | class Forbidden(TackerClientException):
82 | status_code = 403
83 | message = _("Forbidden: your credentials don't give you access to this "
84 | "resource.")
85 |
86 |
87 | class NotFound(TackerClientException):
88 | status_code = 404
89 |
90 |
91 | class Conflict(TackerClientException):
92 | status_code = 409
93 |
94 |
95 | class InternalServerError(TackerClientException):
96 | status_code = 500
97 |
98 |
99 | class ServiceUnavailable(TackerClientException):
100 | status_code = 503
101 |
102 |
103 | HTTP_EXCEPTION_MAP = {
104 | 400: BadRequest,
105 | 401: Unauthorized,
106 | 403: Forbidden,
107 | 404: NotFound,
108 | 409: Conflict,
109 | 500: InternalServerError,
110 | 503: ServiceUnavailable,
111 | }
112 |
113 |
114 | # Exceptions from client library
115 |
116 | class NoAuthURLProvided(Unauthorized):
117 | message = _("auth_url was not provided to the Tacker client")
118 |
119 |
120 | class EndpointNotFound(TackerClientException):
121 | message = _("Could not find Service or Region in Service Catalog.")
122 |
123 |
124 | class EndpointTypeNotFound(TackerClientException):
125 | message = _("Could not find endpoint type %(type_)s in Service Catalog.")
126 |
127 |
128 | class RequestURITooLong(TackerClientException):
129 | """Raised when a request fails with HTTP error 414."""
130 |
131 | def __init__(self, **kwargs):
132 | self.excess = kwargs.get('excess', 0)
133 | super(RequestURITooLong, self).__init__(**kwargs)
134 |
135 |
136 | class ConnectionFailed(TackerClientException):
137 | message = _("Connection to tacker failed: %(reason)s")
138 |
139 |
140 | class SslCertificateValidationError(TackerClientException):
141 | message = _("SSL certificate validation has failed: %(reason)s")
142 |
143 |
144 | class MalformedResponseBody(TackerClientException):
145 | message = _("Malformed response body: %(reason)s")
146 |
147 |
148 | class InvalidContentType(TackerClientException):
149 | message = _("Invalid content type %(content_type)s.")
150 |
151 |
152 | class InvalidInput(TackerClientException):
153 | message = _("Invalid input: %(reason)s")
154 |
155 |
156 | class EmptyInput(TackerClientException):
157 | message = _("Empty input: %(reason)s")
158 |
159 |
160 | class UnsupportedCommandVersion(TackerClientException):
161 | message = _("This command is not supported in version %(version)s")
162 |
163 |
164 | # Command line exceptions
165 |
166 | class TackerCLIError(TackerException):
167 | """Exception raised when command line parsing fails."""
168 | pass
169 |
170 |
171 | class CommandError(TackerCLIError):
172 | pass
173 |
174 |
175 | class UnsupportedVersion(TackerCLIError):
176 | """Unsupported Version.
177 |
178 | Indicates that the user is trying to use an unsupported version of
179 | the API.
180 | """
181 | pass
182 |
183 |
184 | class TackerClientNoUniqueMatch(TackerCLIError):
185 | message = _("Multiple %(resource)s matches found for name '%(name)s',"
186 | " use an ID to be more specific.")
187 |
--------------------------------------------------------------------------------
/tackerclient/common/utils.py:
--------------------------------------------------------------------------------
1 | # Copyright 2011, VMware, Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 | # not use this file except in compliance with the License. You may obtain
5 | # a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | # License for the specific language governing permissions and limitations
13 | # under the License.
14 | #
15 | # Borrowed from nova code base, more utilities will be added/borrowed as and
16 | # when needed.
17 |
18 | """Utilities and helper functions."""
19 |
20 | import argparse
21 | import logging
22 | import os
23 |
24 | from oslo_utils import encodeutils
25 | from oslo_utils import importutils
26 |
27 | from tackerclient.common import exceptions
28 | from tackerclient.i18n import _
29 |
30 |
31 | def env(*vars, **kwargs):
32 | """Returns the first environment variable set.
33 |
34 | If none are non-empty, defaults to '' or keyword arg default.
35 | """
36 | for v in vars:
37 | value = os.environ.get(v)
38 | if value:
39 | return value
40 | return kwargs.get('default', '')
41 |
42 |
43 | def get_client_class(api_name, version, version_map):
44 | """Returns the client class for the requested API version.
45 |
46 | :param api_name: the name of the API, e.g. 'compute', 'image', etc
47 | :param version: the requested API version
48 | :param version_map: a dict of client classes keyed by version
49 | :rtype: a client class for the requested API version
50 | """
51 | try:
52 | client_path = version_map[str(version)]
53 | except (KeyError, ValueError):
54 | msg = _("Invalid %(api_name)s client version '%(version)s'. must be "
55 | "one of: %(map_keys)s")
56 | msg = msg % {'api_name': api_name, 'version': version,
57 | 'map_keys': ', '.join(version_map.keys())}
58 | raise exceptions.UnsupportedVersion(message=msg)
59 |
60 | return importutils.import_class(client_path)
61 |
62 |
63 | def get_item_properties(item, fields, mixed_case_fields=(), formatters=None):
64 | """Return a tuple containing the item properties.
65 |
66 | :param item: a single item resource (e.g. Server, Tenant, etc)
67 | :param fields: tuple of strings with the desired field names
68 | :param mixed_case_fields: tuple of field names to preserve case
69 | :param formatters: dictionary mapping field names to callables
70 | to format the values
71 | """
72 | if formatters is None:
73 | formatters = {}
74 |
75 | row = []
76 |
77 | for field in fields:
78 | if field in formatters:
79 | row.append(formatters[field](item))
80 | else:
81 | if field in mixed_case_fields:
82 | field_name = field.replace(' ', '_')
83 | else:
84 | field_name = field.lower().replace(' ', '_')
85 | if not hasattr(item, field_name) and isinstance(item, dict):
86 | data = item[field_name]
87 | else:
88 | data = getattr(item, field_name, '')
89 | if data is None:
90 | data = ''
91 | row.append(data)
92 | return tuple(row)
93 |
94 |
95 | def str2bool(strbool):
96 | if strbool is None:
97 | return None
98 | return strbool.lower() == 'true'
99 |
100 |
101 | def str2dict(strdict):
102 | """Convert key1=value1,key2=value2,... string into dictionary.
103 |
104 | :param strdict: key1=value1,key2=value2
105 | """
106 | if not strdict:
107 | return {}
108 | return dict([kv.split('=', 1) for kv in strdict.split(',')])
109 |
110 |
111 | def http_log_req(_logger, args, kwargs):
112 | if not _logger.isEnabledFor(logging.DEBUG):
113 | return
114 |
115 | string_parts = ['curl -i']
116 | for element in args:
117 | if element in ('GET', 'POST', 'DELETE', 'PUT'):
118 | string_parts.append(' -X %s' % element)
119 | else:
120 | string_parts.append(' %s' % element)
121 |
122 | for element in kwargs['headers']:
123 | header = ' -H "%s: %s"' % (element, kwargs['headers'][element])
124 | string_parts.append(header)
125 |
126 | if 'body' in kwargs and kwargs['body']:
127 | string_parts.append(" -d '%s'" % (kwargs['body']))
128 | req = encodeutils.safe_encode("".join(string_parts))
129 | _logger.debug("\nREQ: %s\n", req)
130 |
131 |
132 | def http_log_resp(_logger, resp, body):
133 | if not _logger.isEnabledFor(logging.DEBUG):
134 | return
135 | _logger.debug("RESP:%(code)s %(headers)s %(body)s\n",
136 | {'code': resp.status_code,
137 | 'headers': resp.headers,
138 | 'body': body})
139 |
140 |
141 | def _safe_encode_without_obj(data):
142 | if isinstance(data, str):
143 | return encodeutils.safe_encode(data)
144 | return data
145 |
146 |
147 | def safe_encode_list(data):
148 | return list(map(_safe_encode_without_obj, data))
149 |
150 |
151 | def safe_encode_dict(data):
152 | def _encode_item(item):
153 | k, v = item
154 | if isinstance(v, list):
155 | return (k, safe_encode_list(v))
156 | elif isinstance(v, dict):
157 | return (k, safe_encode_dict(v))
158 | return (k, _safe_encode_without_obj(v))
159 |
160 | return dict(list(map(_encode_item, data.items())))
161 |
162 |
163 | def add_boolean_argument(parser, name, **kwargs):
164 | for keyword in ('metavar', 'choices'):
165 | kwargs.pop(keyword, None)
166 | default = kwargs.pop('default', argparse.SUPPRESS)
167 | parser.add_argument(
168 | name,
169 | metavar='{True,False}',
170 | choices=['True', 'true', 'False', 'false'],
171 | default=default,
172 | **kwargs)
173 |
174 |
175 | def get_file_path(filename):
176 | file_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
177 | '../%s' % filename))
178 | return file_path
179 |
--------------------------------------------------------------------------------
/tackerclient/tests/unit/osc/v1/vnflcm_fakes.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 NTT DATA
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | from oslo_utils.fixture import uuidsentinel
17 | from oslo_utils import uuidutils
18 |
19 | from tackerclient.osc import utils as tacker_osc_utils
20 |
21 |
22 | def vnf_instance_response(attrs=None, instantiation_state='NOT_INSTANTIATED'):
23 | """Create a fake vnf instance.
24 |
25 | :param Dictionary attrs:
26 | A dictionary with all attributes
27 | :return:
28 | A vnf instance dict
29 | """
30 | attrs = attrs or {}
31 |
32 | # Set default attributes.
33 | dummy_vnf_instance = {
34 | "id": uuidsentinel.vnf_instance_id,
35 | "vnfInstanceName": "Fake-VNF-Instance",
36 | "vnfInstanceDescription": "Fake VNF",
37 | "vnfdId": uuidsentinel.vnf_package_vnfd_id,
38 | "vnfProvider": "NTT NS lab",
39 | "vnfProductName": "Sample VNF",
40 | "vnfSoftwareVersion": "1.0",
41 | "vnfdVersion": "1.0",
42 | "vnfPkgId": uuidsentinel.uuid,
43 | "_links": "vnflcm/v1/vnf_instances/" + uuidsentinel.vnf_instance_id +
44 | "/instantiate",
45 | "instantiationState": instantiation_state,
46 | "vnfConfigurableProperties": {
47 | "test": "test_value"}}
48 | if instantiation_state == 'INSTANTIATED':
49 | dummy_vnf_instance.update({
50 | "vimConnectionInfo": [{
51 | 'id': uuidsentinel.uuid,
52 | 'vimId': uuidsentinel.vimId,
53 | 'vimType': 'openstack',
54 | 'interfaceInfo': {'k': 'v'},
55 | 'accessInfo': {'k': 'v'},
56 | 'extra': {'k': 'v'}
57 | }],
58 | "instantiatedVnfInfo": {
59 | "flavourId": uuidsentinel.flavourId,
60 | "vnfState": "STARTED",
61 | "extCpInfo": [{
62 | 'id': uuidsentinel.extCpInfo_uuid,
63 | 'cpdId': uuidsentinel.cpdId_uuid,
64 | 'cpProtocolInfo': [{
65 | 'layerProtocol': 'IP_OVER_ETHERNET',
66 | 'ipOverEthernet': '{}'
67 | }],
68 | 'extLinkPortId': uuidsentinel.extLinkPortId_uuid,
69 | 'metadata': {'k': 'v'},
70 | 'associatedVnfcCpId': uuidsentinel.associatedVnfcCpId_uuid
71 | }],
72 | "extVirtualLinkInfo": [{
73 | 'id': uuidsentinel.extVirtualLinkInfo_uuid,
74 | 'resourceHandle': {},
75 | 'extLinkPorts': []
76 | }],
77 | "extManagedVirtualLinkInfo": [{
78 | "id": uuidsentinel.extManagedVirtualLinkInfo_uuid,
79 | 'vnfVirtualLinkDescId': {},
80 | 'networkResource': {},
81 | 'vnfLinkPorts': []
82 | }],
83 | "vnfcResourceInfo": [{
84 | 'id': uuidsentinel.vnfcResourceInfo_uuid,
85 | 'vduId': uuidsentinel.vduId_uuid,
86 | 'computeResource': {},
87 | 'storageResourceIds': [],
88 | 'reservationId': uuidsentinel.reservationId,
89 | }],
90 | "vnfVirtualLinkResourceInfo": [{
91 | 'id': uuidsentinel.vnfVirtualLinkResourceInfo,
92 | 'vnfVirtualLinkDescId': 'VL4',
93 | 'networkResource': {},
94 | 'reservationId': uuidsentinel.reservationId,
95 | 'vnfLinkPorts': [],
96 | 'metadata': {'k': 'v'}
97 | }],
98 | "virtualStorageResourceInfo": [{
99 | 'id': uuidsentinel.virtualStorageResourceInfo,
100 | 'virtualStorageDescId': uuidsentinel.virtualStorageDescId,
101 | 'storageResource': {},
102 | 'reservationId': uuidsentinel.reservationId,
103 | 'metadata': {'k': 'v'}
104 | }]
105 | },
106 | "_links": {
107 | 'self': 'self_link',
108 | 'indicators': None,
109 | 'instantiate': 'instantiate_link'
110 | }
111 | })
112 |
113 | # Overwrite default attributes.
114 | dummy_vnf_instance.update(attrs)
115 |
116 | return dummy_vnf_instance
117 |
118 |
119 | def get_vnflcm_data(vnf_instance, list_action=False, columns=None):
120 | """Get the vnf instance data.
121 |
122 | :return:
123 | A tuple object sorted based on the name of the columns.
124 | """
125 | vnf = vnf_instance.copy()
126 | complex_attributes = ['vimConnectionInfo', 'instantiatedVnfInfo', '_links']
127 | for attribute in complex_attributes:
128 | if vnf.get(attribute):
129 | vnf.update(
130 | {attribute: tacker_osc_utils.FormatComplexDataColumn(
131 | vnf[attribute])})
132 |
133 | if list_action:
134 | for item in ['vnfInstanceDescription', 'vnfdVersion']:
135 | vnf.pop(item)
136 |
137 | # return the list of data as per column order
138 | if columns:
139 | return tuple([vnf[key] for key in columns])
140 |
141 | return tuple([vnf[key] for key in sorted(
142 | vnf.keys())])
143 |
144 |
145 | def create_vnf_instances(count=2):
146 | """Create multiple fake vnf instances.
147 |
148 | :param count: The number of vnf instances to fake
149 | :return:
150 | A list of fake vnf instances dictionary
151 | """
152 | vnf_instances = []
153 | for i in range(0, count):
154 | unique_id = uuidutils.generate_uuid()
155 | vnf_instances.append(vnf_instance_response(attrs={'id': unique_id}))
156 | return vnf_instances
157 |
--------------------------------------------------------------------------------
/tackerclient/osc/v2/vnffm/vnffm_sub.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2022 Fujitsu
2 | # All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | # not use this file except in compliance with the License. You may obtain
6 | # a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | # License for the specific language governing permissions and limitations
14 | # under the License.
15 |
16 | import logging
17 |
18 | from osc_lib.command import command
19 | from osc_lib import utils
20 |
21 | from tackerclient.common import exceptions
22 | from tackerclient.i18n import _
23 | from tackerclient.osc import sdk_utils
24 | from tackerclient.osc import utils as tacker_osc_utils
25 |
26 | LOG = logging.getLogger(__name__)
27 |
28 | _ATTR_MAP = (
29 | ('id', 'ID', tacker_osc_utils.LIST_BOTH),
30 | ('callbackUri', 'Callback Uri', tacker_osc_utils.LIST_BOTH)
31 | )
32 |
33 | _FORMATTERS = {
34 | 'filter': tacker_osc_utils.FormatComplexDataColumn,
35 | '_links': tacker_osc_utils.FormatComplexDataColumn
36 | }
37 |
38 | _MIXED_CASE_FIELDS = (
39 | 'callbackUri'
40 | )
41 |
42 | _VNF_FM_SUB_ID = 'vnf_fm_sub_id'
43 |
44 |
45 | def _get_columns(vnffm_sub_obj):
46 | column_map = {
47 | 'id': 'ID',
48 | 'filter': 'Filter',
49 | 'callbackUri': 'Callback Uri',
50 | '_links': 'Links'
51 | }
52 |
53 | return sdk_utils.get_osc_show_columns_for_sdk_resource(
54 | vnffm_sub_obj, column_map)
55 |
56 |
57 | class CreateVnfFmSub(command.ShowOne):
58 | _description = _("Create a new VNF FM subscription")
59 |
60 | def get_parser(self, prog_name):
61 | parser = super(CreateVnfFmSub, self).get_parser(prog_name)
62 | parser.add_argument(
63 | 'request_file',
64 | metavar="",
65 | help=_('Specify create VNF FM subscription request '
66 | 'parameters in a json file.'))
67 | return parser
68 |
69 | def take_action(self, parsed_args):
70 | client = self.app.client_manager.tackerclient
71 | vnf_fm_sub = client.create_vnf_fm_sub(
72 | tacker_osc_utils.jsonfile2body(parsed_args.request_file))
73 | display_columns, columns = _get_columns(vnf_fm_sub)
74 | data = utils.get_item_properties(
75 | sdk_utils.DictModel(vnf_fm_sub), columns,
76 | formatters=_FORMATTERS, mixed_case_fields=_MIXED_CASE_FIELDS)
77 | return (display_columns, data)
78 |
79 |
80 | class ListVnfFmSub(command.Lister):
81 | _description = _("List VNF FM subs")
82 |
83 | def get_parser(self, prog_name):
84 | LOG.debug('get_parser(%s)', prog_name)
85 | parser = super(ListVnfFmSub, self).get_parser(prog_name)
86 | parser.add_argument(
87 | "--filter",
88 | metavar="",
89 | help=_("Attribute-based-filtering parameters"),
90 | )
91 | return parser
92 |
93 | def take_action(self, parsed_args):
94 | _params = {}
95 | if parsed_args.filter:
96 | _params['filter'] = parsed_args.filter
97 |
98 | client = self.app.client_manager.tackerclient
99 | data = client.list_vnf_fm_subs(**_params)
100 | headers, columns = tacker_osc_utils.get_column_definitions(
101 | _ATTR_MAP, long_listing=True)
102 | return (headers,
103 | (utils.get_dict_properties(
104 | s, columns, formatters=_FORMATTERS,
105 | mixed_case_fields=_MIXED_CASE_FIELDS,
106 | ) for s in data['vnf_fm_subs']))
107 |
108 |
109 | class ShowVnfFmSub(command.ShowOne):
110 | _description = _("Display VNF FM subscription details")
111 |
112 | def get_parser(self, prog_name):
113 | parser = super(ShowVnfFmSub, self).get_parser(prog_name)
114 | parser.add_argument(
115 | _VNF_FM_SUB_ID,
116 | metavar="",
117 | help=_("VNF FM subscription ID to display"))
118 | return parser
119 |
120 | def take_action(self, parsed_args):
121 | client = self.app.client_manager.tackerclient
122 | obj = client.show_vnf_fm_sub(parsed_args.vnf_fm_sub_id)
123 | display_columns, columns = _get_columns(obj)
124 | data = utils.get_item_properties(
125 | sdk_utils.DictModel(obj), columns,
126 | mixed_case_fields=_MIXED_CASE_FIELDS,
127 | formatters=_FORMATTERS)
128 | return (display_columns, data)
129 |
130 |
131 | class DeleteVnfFmSub(command.Command):
132 | _description = _("Delete VNF FM subscription(s)")
133 |
134 | def get_parser(self, prog_name):
135 | parser = super(DeleteVnfFmSub, self).get_parser(prog_name)
136 | parser.add_argument(
137 | _VNF_FM_SUB_ID,
138 | metavar="",
139 | nargs="+",
140 | help=_("VNF FM subscription ID(s) to delete"))
141 | return parser
142 |
143 | def take_action(self, parsed_args):
144 | error_count = 0
145 | client = self.app.client_manager.tackerclient
146 | vnf_fm_sub_ids = parsed_args.vnf_fm_sub_id
147 |
148 | for sub_id in vnf_fm_sub_ids:
149 | try:
150 | client.delete_vnf_fm_sub(sub_id)
151 | except Exception as e:
152 | error_count += 1
153 | LOG.error(_("Failed to delete VNF FM subscription with "
154 | "ID '%(sub_id)s': %(e)s"),
155 | {'sub_id': sub_id, 'e': e})
156 |
157 | total = len(vnf_fm_sub_ids)
158 | if error_count > 0:
159 | msg = (_("Failed to delete %(error_count)s of %(total)s "
160 | "VNF FM subscriptions.") % {'error_count': error_count,
161 | 'total': total})
162 | raise exceptions.CommandError(message=msg)
163 |
164 | if total > 1:
165 | print(_('All specified VNF FM subscriptions are deleted '
166 | 'successfully'))
167 | else:
168 | print(_("VNF FM subscription '%s' deleted "
169 | "successfully") % vnf_fm_sub_ids[0])
170 |
--------------------------------------------------------------------------------
/doc/source/cli/commands.rst:
--------------------------------------------------------------------------------
1 | ..
2 | Licensed under the Apache License, Version 2.0 (the "License"); you may
3 | not use this file except in compliance with the License. You may obtain
4 | a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software
9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | License for the specific language governing permissions and limitations
12 | under the License.
13 |
14 | =============
15 | Command List
16 | =============
17 |
18 | The following list covers the extended commands for Tacker services
19 | available in **openstack** command.
20 |
21 | These commands can be referenced by doing **openstack help** and the detail
22 | of individual command can be referred by **openstack help **.
23 |
24 | .. code-block:: console
25 |
26 | [legacy]
27 | openstack vim list List VIM(s) that belong to a given tenant.
28 | openstack vim register Create a VIM.
29 | openstack vim show Show information of a given VIM.
30 | openstack vim set Update a given VIM.
31 | openstack vim delete Delete given VIM(s).
32 |
33 | [v1] --os-tacker-api-version 1
34 | openstack vnf package create Create a new individual VNF package resource.
35 | openstack vnf package delete Delete given VNF package(s).
36 | openstack vnf package list List all VNF packages.
37 | openstack vnf package show Show package details.
38 | openstack vnf package upload Upload a VNF package.
39 | openstack vnf package download Download a VNF package.
40 | openstack vnf package artifact download Download a VNF package artifact.
41 | openstack vnf package update Update a state of a VNF package.
42 | openstack vnflcm create Create a new VNF instance resource.
43 | openstack vnflcm instantiate Instantiate a VNF instance.
44 | openstack vnflcm list List VNF instance.
45 | openstack vnflcm show Show VNF instance.
46 | openstack vnflcm terminate Terminate a VNF instance.
47 | openstack vnflcm delete Delete a VNF instance resource.
48 | openstack vnflcm heal Heal a VNF instance.
49 | openstack vnflcm update Update information of a VNF instance.
50 | openstack vnflcm scale Scale a VNF instance.
51 | openstack vnflcm change-ext-conn Change external VNF connectivity.
52 | openstack vnflcm op rollback Rollback a VNF LCM operation occurrence.
53 | openstack vnflcm op retry Retry a VNF LCM operation occurrence.
54 | openstack vnflcm op fail Fail a VNF LCM operation occurrence.
55 | openstack vnflcm op list List VNF LCM operation occurrence.
56 | openstack vnflcm op show Show VNF LCM operation occurrence.
57 | openstack vnflcm op cancel Cancel a VNF LCM operation occurrence.
58 | openstack vnflcm versions Show VNF LCM API versions.
59 | openstack vnflcm subsc create Create new subscription.
60 | openstack vnflcm subsc delete Delete subscription.
61 | openstack vnflcm subsc list List subscription.
62 | openstack vnflcm subsc show Show subscription.
63 |
64 | [v2] --os-tacker-api-version 2
65 | openstack vnflcm create Create a new VNF instance resource.
66 | openstack vnflcm instantiate Instantiate a VNF instance.
67 | openstack vnflcm list List VNF instance.
68 | openstack vnflcm show Show VNF instance.
69 | openstack vnflcm terminate Terminate a VNF instance.
70 | openstack vnflcm delete Delete a VNF instance resource.
71 | openstack vnflcm heal Heal a VNF instance.
72 | openstack vnflcm update Update information of a VNF instance.
73 | openstack vnflcm scale Scale a VNF instance.
74 | openstack vnflcm change-ext-conn Change external VNF connectivity.
75 | openstack vnflcm change-vnfpkg Change current VNF package.
76 | openstack vnflcm op rollback Rollback a VNF LCM operation occurrence.
77 | openstack vnflcm op retry Retry a VNF LCM operation occurrence.
78 | openstack vnflcm op fail Fail a VNF LCM operation occurrence.
79 | openstack vnflcm op list List VNF LCM operation occurrence.
80 | openstack vnflcm op show Show VNF LCM operation occurrence.
81 | openstack vnflcm versions Show VNF LCM API versions.
82 | openstack vnflcm subsc create Create new subscription.
83 | openstack vnflcm subsc delete Delete subscription.
84 | openstack vnflcm subsc list List subscription.
85 | openstack vnflcm subsc show Show subscription.
86 | openstack vnffm alarm list List alarm.
87 | openstack vnffm alarm show Show alarm.
88 | openstack vnffm alarm update Update alarm.
89 | openstack vnffm sub create Create FM subscription.
90 | openstack vnffm sub list List FM subscription.
91 | openstack vnffm sub show Show FM subscription.
92 | openstack vnffm sub delete Delete FM subscription.
93 | openstack vnfpm job create Create PM job.
94 | openstack vnfpm job list List PM job.
95 | openstack vnfpm job show Show PM job.
96 | openstack vnfpm job update Update PM job.
97 | openstack vnfpm job delete Delete PM job.
98 | openstack vnfpm report show Show PM report.
99 | openstack vnfpm threshold create Create PM threshold.
100 | openstack vnfpm threshold list List PM threshold.
101 | openstack vnfpm threshold show Show PM threshold.
102 | openstack vnfpm threshold update Update PM threshold.
103 | openstack vnfpm threshold delete Delete PM threshold.
104 |
--------------------------------------------------------------------------------