mirror of
https://opendev.org/openstack/python-neutronclient.git
synced 2026-01-17 07:23:43 +00:00
Compare commits
117 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efa0ccb944 | ||
|
|
8f72d77812 | ||
|
|
a991ac87c7 | ||
|
|
01d0553ca4 | ||
|
|
66ccb4569d | ||
|
|
1aee34b246 | ||
|
|
01ffc4684a | ||
|
|
2f170ce6aa | ||
|
|
275924ecc8 | ||
|
|
5f7d102f0e | ||
|
|
905be917fe | ||
|
|
857b4b233c | ||
|
|
690bb97d9d | ||
|
|
7d998d2525 | ||
|
|
370bd215c7 | ||
|
|
dc026cd3d6 | ||
|
|
1d7a13ab11 | ||
|
|
636ac764d3 | ||
|
|
b2107dc867 | ||
|
|
75e112bc9b | ||
|
|
1befb3cd08 | ||
|
|
f882f1ddb6 | ||
|
|
8a2f07683b | ||
|
|
5438377b9c | ||
|
|
d36a8a4a17 | ||
|
|
a10390c62e | ||
|
|
cb9aae55c8 | ||
|
|
fb8de782bc | ||
|
|
2169b2bbab | ||
|
|
111713fd62 | ||
|
|
98d8d8b5cd | ||
|
|
1cdac483be | ||
|
|
fe515adf35 | ||
|
|
41e7ea6e29 | ||
|
|
863c6031fc | ||
|
|
750afa1777 | ||
|
|
4e48e90788 | ||
|
|
858b844cff | ||
|
|
2d93d2e1ed | ||
|
|
c28a5497c2 | ||
|
|
8ae44f83f5 | ||
|
|
ee6f6a13ea | ||
|
|
8c983fa764 | ||
|
|
b9152a5042 | ||
|
|
396432ab06 | ||
|
|
c4e8d90c0f | ||
|
|
6597c421ff | ||
|
|
fccfe8c3e5 | ||
|
|
d497615240 | ||
|
|
4521472198 | ||
|
|
4ed299ad39 | ||
|
|
d4124aed1f | ||
|
|
79c7de4630 | ||
|
|
d342171f9e | ||
|
|
52653c95e0 | ||
|
|
0b271d3b8c | ||
|
|
3071dfbd0f | ||
|
|
16a2cd127d | ||
|
|
68cbf56f9c | ||
|
|
33f1c89a84 | ||
|
|
776e360e35 | ||
|
|
f67af3d9be | ||
|
|
ec84aff516 | ||
|
|
f060429cfc | ||
|
|
7467c710f6 | ||
|
|
b720fdaee7 | ||
|
|
143db0177a | ||
|
|
8c72cc87da | ||
|
|
4575bea5a6 | ||
|
|
28628e8f96 | ||
|
|
6ca3341352 | ||
|
|
517bef2c54 | ||
|
|
d75e1e05b7 | ||
|
|
a92d8db81c | ||
|
|
3b80135a3d | ||
|
|
3a65712b45 | ||
|
|
1df1f38a91 | ||
|
|
792ad115b3 | ||
|
|
ee73a48881 | ||
|
|
4b29df7234 | ||
|
|
cff9c266c0 | ||
|
|
983f0abc58 | ||
|
|
f83108d858 | ||
|
|
e647baf4ca | ||
|
|
2f047b1595 | ||
|
|
23fb666f92 | ||
|
|
a1ebfaa7f2 | ||
|
|
adf21f0288 | ||
|
|
ae397565be | ||
|
|
d6c211c139 | ||
|
|
76dd26f9fd | ||
|
|
439e290e95 | ||
|
|
10227b681f | ||
|
|
2c2a1f4de7 | ||
|
|
f6d147e031 | ||
|
|
7a1dca4131 | ||
|
|
26ab1b1d0c | ||
|
|
d87683b59b | ||
|
|
f3756a3d4a | ||
|
|
12373768da | ||
|
|
3140fe014a | ||
|
|
4963c7ae14 | ||
|
|
1a1ee061e8 | ||
|
|
49c8577d8b | ||
|
|
b2ebc6cc9b | ||
|
|
13d2d130dd | ||
|
|
66462874d2 | ||
|
|
62c187f5c7 | ||
|
|
e999631422 | ||
|
|
34245e8c8a | ||
|
|
9ffa0ac14e | ||
|
|
ffc9ed8262 | ||
|
|
097106d8fb | ||
|
|
873e08597f | ||
|
|
d1e5afb351 | ||
|
|
ada4229691 | ||
|
|
c8d61703c2 |
187 changed files with 3134 additions and 18983 deletions
60
.zuul.yaml
60
.zuul.yaml
|
|
@ -1,71 +1,39 @@
|
|||
- project:
|
||||
templates:
|
||||
- openstack-cover-jobs
|
||||
- openstack-lower-constraints-jobs
|
||||
- openstack-python3-victoria-jobs
|
||||
- openstack-python3-jobs
|
||||
- publish-openstack-docs-pti
|
||||
- check-requirements
|
||||
- lib-forward-testing-python3
|
||||
- release-notes-jobs-python3
|
||||
- openstackclient-plugin-jobs
|
||||
check:
|
||||
jobs:
|
||||
- neutronclient-functional
|
||||
gate:
|
||||
jobs:
|
||||
- neutronclient-functional
|
||||
experimental:
|
||||
jobs:
|
||||
- neutron-lib-grenade-dsvm:
|
||||
- neutronclient-grenade-neutron-lib:
|
||||
irrelevant-files:
|
||||
- ^(test-|)requirements.txt$
|
||||
- ^setup.cfg$
|
||||
|
||||
- job:
|
||||
name: neutronclient-functional
|
||||
parent: devstack-tox-functional
|
||||
irrelevant-files:
|
||||
- ^.*\.rst$
|
||||
- ^doc/.*$
|
||||
- ^releasenotes/.*$
|
||||
name: neutronclient-grenade-neutron-lib
|
||||
parent: grenade
|
||||
description: |
|
||||
neutron-lib grenade job.
|
||||
The version of this job on the current branch is py3 based,
|
||||
while any branch before ussuri needs to use the py2 version,
|
||||
which is defined in openstack-zuul-jobs with the old name
|
||||
(legacy-grenade-dsvm-neutron-libs).
|
||||
Users of this job needs to pay attention of the version used.
|
||||
Former names for this job were:
|
||||
* legacy-grenade-dsvm-neutron-libs
|
||||
* neutron-lib-grenade-dsvm
|
||||
required-projects:
|
||||
- openstack/python-neutronclient
|
||||
- openstack/neutron
|
||||
- openstack/neutron-vpnaas
|
||||
vars:
|
||||
tox_envlist: functional
|
||||
devstack_services:
|
||||
# NOTE: neutronclient.tests.functional.base.ClientTestBase does not
|
||||
# support HTTPS endpoints now, so tls-proxy needs to be disabled.
|
||||
tls-proxy: false
|
||||
devstack_localrc:
|
||||
USE_PYTHON3: true
|
||||
LIBS_FROM_GIT: python-neutronclient
|
||||
devstack_plugins:
|
||||
neutron-vpnaas: https://opendev.org/openstack/neutron-vpnaas
|
||||
|
||||
- job:
|
||||
name: neutron-lib-grenade-dsvm
|
||||
# Old name: legacy-grenade-dsvm-neutron-libs
|
||||
parent: legacy-dsvm-base
|
||||
run: playbooks/legacy/grenade-dsvm-neutron-libs/run.yaml
|
||||
post-run: playbooks/legacy/grenade-dsvm-neutron-libs/post.yaml
|
||||
timeout: 10800
|
||||
required-projects:
|
||||
- openstack/grenade
|
||||
- openstack/devstack-gate
|
||||
- openstack/keystoneauth
|
||||
- openstack/neutron
|
||||
- openstack/neutron-lib
|
||||
- openstack/os-client-config
|
||||
- openstack/python-cinderclient
|
||||
- openstack/python-glanceclient
|
||||
- openstack/python-ironicclient
|
||||
- openstack/python-keystoneclient
|
||||
- openstack/python-neutronclient
|
||||
- openstack/python-novaclient
|
||||
# This is py3 version for ussuri onwards rest all branch needs to be py2
|
||||
# version which is present in openstack-zuul-jobs.
|
||||
# We need to take care of this branch variant and python version while
|
||||
# migrating these jobs to zuulv3.
|
||||
branches: ^(?!(stable/(ocata|pike|queens|rocky|stein|train))).*$
|
||||
|
|
|
|||
10
README.rst
10
README.rst
|
|
@ -15,8 +15,14 @@ Python bindings to the Neutron API
|
|||
:alt: Latest Version
|
||||
|
||||
This is a client library for Neutron built on the Neutron API. It
|
||||
provides a Python API (the ``neutronclient`` module) and a command-line tool
|
||||
(``neutron``).
|
||||
provides a Python API (the ``neutronclient`` module).
|
||||
|
||||
.. note:: This project has been deprecated. The CLI code has been deleted
|
||||
and is not accessible anymore. The Python bindings are still in use by
|
||||
other projects but no new features will be added to this project.
|
||||
All projects under Openstack governance migrating to use OpenstackSDK.
|
||||
Any new feature should be proposed to OpenStack SDK and OpenStack
|
||||
Client.
|
||||
|
||||
* License: Apache License, Version 2.0
|
||||
* `PyPi`_ - package installation
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
[python: **.py]
|
||||
|
||||
|
|
@ -4,3 +4,4 @@
|
|||
openstackdocstheme>=2.2.0 # Apache-2.0
|
||||
reno>=3.1.0 # Apache-2.0
|
||||
sphinx>=2.0.0,!=2.1.0 # BSD
|
||||
cliff>=3.4.0 # Apache-2.0
|
||||
|
|
|
|||
|
|
@ -24,10 +24,9 @@
|
|||
Using CLI
|
||||
=========
|
||||
|
||||
There are two CLIs which support the Networking API:
|
||||
`OpenStackClient (OSC)
|
||||
There is `OpenStackClient (OSC)
|
||||
<https://docs.openstack.org/python-openstackclient/latest/>`__
|
||||
and :doc:`neutron CLI <neutron>` (deprecated).
|
||||
which support the Networking API
|
||||
|
||||
OpenStackClient
|
||||
---------------
|
||||
|
|
@ -49,15 +48,8 @@ neutron CLI
|
|||
|
||||
.. warning::
|
||||
|
||||
neutron CLI is now deprecated and will be removed in the future.
|
||||
Use openstack CLI instead. See `openstack CLI command list
|
||||
neutron CLI is removed. Use openstack CLI instead. See `openstack CLI command list
|
||||
<https://docs.openstack.org/python-openstackclient/latest/cli/command-list.html>`__
|
||||
and :doc:`its extensions for advanced networking services <osc_plugins>`.
|
||||
The command mapping from neutron CLI to openstack CLI is available
|
||||
`here <https://docs.openstack.org/python-openstackclient/latest/cli/decoder.html#neutron-cli>`__.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
neutron CLI guide <neutron>
|
||||
neutron CLI reference <neutron-reference>
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
..
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
=====================
|
||||
neutron CLI reference
|
||||
=====================
|
||||
|
||||
.. warning::
|
||||
|
||||
neutron CLI is now deprecated and will be removed in the future.
|
||||
Use openstack CLI instead. See `openstack CLI command list
|
||||
<https://docs.openstack.org/python-openstackclient/latest/cli/command-list.html>`__
|
||||
and :doc:`its extensions for advanced networking services <osc_plugins>`.
|
||||
The command mapping from neutron CLI to openstack CLI is available
|
||||
`here <https://docs.openstack.org/python-openstackclient/latest/cli/decoder.html#neutron-cli>`__.
|
||||
|
||||
neutron usage
|
||||
-------------
|
||||
|
||||
.. autoprogram-cliff:: neutronclient.shell.NeutronShell
|
||||
:application: neutron
|
||||
:arguments: 2.0
|
||||
|
||||
neutron API v2.0 commands
|
||||
-------------------------
|
||||
|
||||
.. autoprogram-cliff:: neutron.cli.v2
|
||||
:application: neutron
|
||||
|
||||
|
|
@ -1,412 +0,0 @@
|
|||
..
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
Using neutron CLI
|
||||
=================
|
||||
|
||||
The **neutron** shell utility interacts with OpenStack Networking API from the
|
||||
command-line. It supports the entire features of OpenStack Networking API.
|
||||
|
||||
.. warning::
|
||||
|
||||
neutron CLI is now deprecated and will be removed in the future.
|
||||
Use openstack CLI instead. See `openstack CLI command list
|
||||
<https://docs.openstack.org/python-openstackclient/latest/cli/command-list.html>`__
|
||||
and :doc:`its extensions for advanced networking services <osc_plugins>`.
|
||||
The command mapping from neutron CLI to openstack CLI is available
|
||||
`here <https://docs.openstack.org/python-openstackclient/latest/cli/decoder.html#neutron-cli>`__.
|
||||
|
||||
Basic Usage
|
||||
-----------
|
||||
|
||||
In order to use the CLI, you must provide your OpenStack username, password,
|
||||
project, domain information for both user and project, and auth endpoint. Use
|
||||
the corresponding configuration options (``--os-username``, ``--os-password``,
|
||||
``--os-project-name``, ``--os-user-domain-id``, ``os-project-domain-id``, and
|
||||
``--os-auth-url``), but it is easier to set them in environment variables.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
export OS_USERNAME=user
|
||||
export OS_PASSWORD=pass
|
||||
export OS_PROJECT_NAME=project
|
||||
export OS_USER_DOMAIN_ID=default
|
||||
export OS_PROJECT_DOMAIN_ID=default
|
||||
export OS_AUTH_URL=http://auth.example.com:5000/v3
|
||||
|
||||
If you are using Identity v2.0 API (DEPRECATED), you don't need to pass domain
|
||||
information.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
export OS_USERNAME=user
|
||||
export OS_PASSWORD=pass
|
||||
export OS_TENANT_NAME=tenant
|
||||
export OS_AUTH_URL=http://auth.example.com:5000/v2.0
|
||||
|
||||
Once you've configured your authentication parameters, you can run **neutron**
|
||||
commands. All commands take the form of:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
neutron <command> [arguments...]
|
||||
|
||||
Run **neutron help** to get a full list of all possible commands, and run
|
||||
**neutron help <command>** to get detailed help for that command.
|
||||
|
||||
Using with os-client-config
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
`os-client-config <https://docs.openstack.org/os-client-config/latest/>`_
|
||||
provides more convenient way to manage a collection of client configurations
|
||||
and you can easily switch multiple OpenStack-based configurations.
|
||||
|
||||
To use os-client-config, you first need to prepare
|
||||
``~/.config/openstack/clouds.yaml`` like the following.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
clouds:
|
||||
devstack:
|
||||
auth:
|
||||
auth_url: http://auth.example.com:5000
|
||||
password: your-secret
|
||||
project_domain_id: default
|
||||
project_name: demo
|
||||
user_domain_id: default
|
||||
username: demo
|
||||
identity_api_version: '3'
|
||||
region_name: RegionOne
|
||||
devstack-admin:
|
||||
auth:
|
||||
auth_url: http://auth.example.com:35357
|
||||
password: another-secret
|
||||
project_domain_id: default
|
||||
project_name: admin
|
||||
user_domain_id: default
|
||||
username: admin
|
||||
identity_api_version: '3'
|
||||
region_name: RegionOne
|
||||
|
||||
Then, you need to specify a configuration name defined in the above clouds.yaml.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
export OS_CLOUD=devstack
|
||||
|
||||
For more detail information, see the
|
||||
`os-client-config <https://docs.openstack.org/os-client-config/latest/>`_
|
||||
documentation.
|
||||
|
||||
Using with keystone token
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The command-line tool will attempt to re-authenticate using your provided
|
||||
credentials for every request. You can override this behavior by manually
|
||||
supplying an auth token using ``--os-url`` and ``--os-auth-token``. You can
|
||||
alternatively set these environment variables.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
export OS_URL=http://neutron.example.org:9696/
|
||||
export OS_TOKEN=3bcc3d3a03f44e3d8377f9247b0ad155
|
||||
|
||||
Using noauth mode
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
If neutron server does not require authentication, besides these two arguments
|
||||
or environment variables (We can use any value as token.), we need manually
|
||||
supply ``--os-auth-strategy`` or set the environment variable.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
export OS_AUTH_STRATEGY=noauth
|
||||
|
||||
Display options
|
||||
---------------
|
||||
|
||||
Filtering
|
||||
~~~~~~~~~
|
||||
|
||||
Neutron API supports filtering in the listing operation.
|
||||
**neutron** CLI supports this feature too.
|
||||
|
||||
To specify a filter in ``*-list`` command, you need to pass a pair of an
|
||||
attribute name and an expected value with the format of ``--<attribute> <value>``.
|
||||
The example below retrieves ports owned by compute instances.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ neutron port-list --device_owner network:dhcp
|
||||
+--------------------------------------+------+-------------------+-------------------------------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+-------------------------------------------------------------------------------------------------------------+
|
||||
| 8953d683-29ad-4be3-b73f-060727c7849b | | fa:16:3e:4b:9e:0a | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.2"} |
|
||||
| | | | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66:0:f816:3eff:fe4b:9e0a"} |
|
||||
+--------------------------------------+------+-------------------+-------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
You can also specify multiple filters.
|
||||
The example below retrieves security group rules applied to IPv4 traffic
|
||||
which belongs to a security group bfa493f9-2b03-46d2-8399-b9b038a53bc1.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ neutron security-group-rule-list --security-group-id bfa493f9-2b03-46d2-8399-b9b038a53bc1 --ethertype IPv4
|
||||
+--------------------------------------+----------------+-----------+-----------+---------------+-----------------+
|
||||
| id | security_group | direction | ethertype | protocol/port | remote |
|
||||
+--------------------------------------+----------------+-----------+-----------+---------------+-----------------+
|
||||
| 65489805-0400-4bce-9bd9-16a81952263c | default | egress | IPv4 | any | any |
|
||||
| 9429f336-4947-4643-bbd9-24528cc65648 | default | ingress | IPv4 | any | default (group) |
|
||||
+--------------------------------------+----------------+-----------+-----------+---------------+-----------------+
|
||||
|
||||
.. note::
|
||||
|
||||
Looking up UUID from name is not supported when specifying a filter.
|
||||
You need to use UUID to specify a specific resource.
|
||||
|
||||
.. note::
|
||||
|
||||
Filtering for dictionary or list attributes is not supported.
|
||||
|
||||
Changing displayed columns
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want displayed columns in a list operation, ``-c`` option can be used.
|
||||
``-c`` can be specified multiple times and the column order will be same as
|
||||
the order of ``-c`` options.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ neutron port-list -c id -c device_owner -c fixed_ips
|
||||
+--------------------------------------+--------------------------+-------------------------------------------------------------------------------------------------------------+
|
||||
| id | device_owner | fixed_ips |
|
||||
+--------------------------------------+--------------------------+-------------------------------------------------------------------------------------------------------------+
|
||||
| 41ca1b9b-4bbd-4aa8-bcaa-31d3d5704205 | network:router_interface | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.1"} |
|
||||
| 8953d683-29ad-4be3-b73f-060727c7849b | network:dhcp | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.2"} |
|
||||
| | | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66:0:f816:3eff:fe4b:9e0a"} |
|
||||
| a9da29f8-4504-4526-a5ce-cd3624fbd173 | neutron:LOADBALANCER | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.3"} |
|
||||
| | | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66:0:f816:3eff:feb1:ab71"} |
|
||||
| d6a1ff96-0a99-416f-a4d6-65d9614cf64e | compute:nova | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.4"} |
|
||||
| | | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66:0:f816:3eff:fe2c:348e"} |
|
||||
| f4789225-26d0-409f-8047-82d2c7a87a95 | network:router_interface | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66::1"} |
|
||||
+--------------------------------------+--------------------------+-------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. _cli_extra_arguments:
|
||||
|
||||
Extra arguments for create/update operation
|
||||
-------------------------------------------
|
||||
|
||||
**neutron** CLI has a mechanism called the *extra arguments* for ``*-create``
|
||||
and ``*-update`` commands. It allows users to specify a set of *unknown
|
||||
options* which are not defined as options and not shown in the help text.
|
||||
**Unknown options MUST be placed at the end of the command line.**
|
||||
*unknown options* will be directly passed to the API layer. By this mechanism,
|
||||
you can pass an attribute which is not defined in the upstream **neutron**
|
||||
CLI. For example, when you are developing a new feature which add a new
|
||||
attribute to an existing resource, it is useful because we can test your
|
||||
feature without changing the existing neutron CLI.
|
||||
|
||||
For example, if you run the following command::
|
||||
|
||||
neutron resource-update <ID> --key1 value1 --key2 value2
|
||||
|
||||
where ``resource`` is some resource name and ``--key1`` and ``--key2`` are
|
||||
unknown options, then the following JSON will be sent to the neutron API::
|
||||
|
||||
PUT /v2.0/resources/<ID>
|
||||
|
||||
{
|
||||
"resource": {
|
||||
"key2": "value2",
|
||||
"key1": "value1"
|
||||
}
|
||||
}
|
||||
|
||||
Key interpretation
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This means an option name (``--key1`` in this case) must be one of valid
|
||||
resources of a corresponding resource. An option name ``--foo_bar`` is
|
||||
recognized as an attribute name ``foo_bar``. ``--foo-bar`` is also interpreted
|
||||
as an attribute name ``foo_bar``.
|
||||
|
||||
Value interpretation
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default, if the number of values is 1, the option value is interpreted as a
|
||||
string and is passed to the API layer as specified in a command-line.
|
||||
|
||||
If the number of values is greater than 1, the option value is interpreted as a
|
||||
list and the result in the API layer will be same as when specifying a list as
|
||||
described below.
|
||||
|
||||
neutron resource-update <ID> --key1 val1 val2 val3 --key2 val4
|
||||
|
||||
In the above example, a value of ``key1`` is interpreted as
|
||||
``["val1", "val2", "val3"]`` and a value of ``key2`` is interpreted
|
||||
as ``val4``.
|
||||
|
||||
The extra argument mechanism supports more complex value like a list or a dict.
|
||||
|
||||
Specify a list value
|
||||
++++++++++++++++++++
|
||||
|
||||
A command-line::
|
||||
|
||||
neutron resource-update <ID> --key list=true val1 val2 val3
|
||||
|
||||
will send the following in the API layer::
|
||||
|
||||
{
|
||||
"key": [
|
||||
"val1",
|
||||
"val2",
|
||||
"val3"
|
||||
]
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
If you want to specify a list value, it is recommended to specify
|
||||
``list=true``. When ``list=true`` is specified, specified values are
|
||||
interpreted as a list even regardless of the number of values.
|
||||
|
||||
If ``list=true`` is not specified, specified values are interpreted
|
||||
depends on the number of values how. If the number of values is more than 2,
|
||||
the specified values are interpreted as a list. If 1, the value
|
||||
is interpreted as a string.
|
||||
|
||||
Specify a dict value
|
||||
++++++++++++++++++++
|
||||
|
||||
A command-line::
|
||||
|
||||
neutron resource-update <ID> --key type=dict key1=val1,key2=val2,key3=val3
|
||||
|
||||
will send the following in the API layer::
|
||||
|
||||
{
|
||||
"key": {
|
||||
"key1": "val1",
|
||||
"key2": "val2",
|
||||
"key3": "val3"
|
||||
}
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
``type=bool True/False`` and ``type=int 10`` are also supported.
|
||||
|
||||
Specify a list of dicts
|
||||
+++++++++++++++++++++++
|
||||
|
||||
A command-line::
|
||||
|
||||
neutron resource-update <ID> --key type=dict list=true key1=val1 key2=val2 key3=val3
|
||||
|
||||
will send the following in the API layer::
|
||||
|
||||
{
|
||||
"key": [
|
||||
{"key1": "val1"},
|
||||
{"key2": "val2"},
|
||||
{"key3": "val3"}
|
||||
]
|
||||
}
|
||||
|
||||
Passing None as a value
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There is a case where we would like to pass ``None`` (``null`` in JSON)
|
||||
in the API layer. To do this::
|
||||
|
||||
neutron resource-update <ID> --key action=clear
|
||||
|
||||
The following body will be in the API layer::
|
||||
|
||||
{"key": null}
|
||||
|
||||
.. note::
|
||||
|
||||
If ``action=clear`` is specified, ``list=true`` or ``type=dict`` is ignored.
|
||||
It means when ``action=clear`` is specified ``None`` is always sent.
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
Display API-level communication
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``-v`` (or ``--verbose``, ``--debug``) option displays a detail interaction
|
||||
with your neutron server. It is useful to debug what happens in the API level.
|
||||
|
||||
Here is an sample output of ``net-show`` command.
|
||||
|
||||
The first line show what parameters are recognized by neutronclient.
|
||||
It is sometimes useful to check if command-line parameters you specify are recognized properly.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ neutron -v net-show mynetwork
|
||||
DEBUG: neutronclient.neutron.v2_0.network.ShowNetwork get_data(Namespace(columns=[], fields=[], formatter='table', id=u'mynetwork', max_width=0, noindent=False, prefix='', request_format='json', show_details=False, variables=[]))
|
||||
|
||||
Next, neutronclient sends an authentication request to keystone to get a token
|
||||
which is used in further operations.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
DEBUG: keystoneauth.session REQ: curl -g -i -X GET http://172.16.18.47:5000 -H "Accept: application/json" -H "User-Agent: keystoneauth1"
|
||||
DEBUG: keystoneauth.session RESP: [300] Content-Length: 593 Vary: X-Auth-Token Keep-Alive: timeout=5, max=100 Server: Apache/2.4.7 (Ubuntu) Connection: Keep-Alive Date: Fri, 27 Nov 2015 20:10:54 GMT Content-Type: application/json
|
||||
RESP BODY: {"versions": {"values": [{"status": "stable", "updated": "2015-03-30T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v3+json"}], "id": "v3.4", "links": [{"href": "http://172.16.18.47:5000/v3/", "rel": "self"}]}, {"status": "stable", "updated": "2014-04-17T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json"}], "id": "v2.0", "links": [{"href": "http://172.16.18.47:5000/v2.0/", "rel": "self"}, {"href": "http://docs.openstack.org/", "type": "text/html", "rel": "describedby"}]}]}}
|
||||
|
||||
DEBUG: keystoneauth.identity.v3.base Making authentication request to http://172.16.18.47:5000/v3/auth/tokens
|
||||
|
||||
Neutronclient looks up a network ID corresponding to a given network name.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
DEBUG: keystoneauth.session REQ: curl -g -i -X GET http://172.16.18.47:9696/v2.0/networks.json?fields=id&name=mynetwork -H "User-Agent: python-neutronclient" -H "Accept: application/json" -H "X-Auth-Token: {SHA1}39300e7398d53a02afd183f13cb6afaef95ec4e5"
|
||||
DEBUG: keystoneauth.session RESP: [200] Date: Fri, 27 Nov 2015 20:10:55 GMT Connection: keep-alive Content-Type: application/json; charset=UTF-8 Content-Length: 62 X-Openstack-Request-Id: req-ccebf6e4-4f52-4874-a1ab-5499abcba378
|
||||
RESP BODY: {"networks": [{"id": "3698d3c7-d581-443e-bf86-53c4e3a738f7"}]}
|
||||
|
||||
Finally, neutronclient retrieves a detail of a given network using the resolved ID.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
DEBUG: keystoneauth.session REQ: curl -g -i -X GET http://172.16.18.47:9696/v2.0/networks/3698d3c7-d581-443e-bf86-53c4e3a738f7.json -H "User-Agent: python-neutronclient" -H "Accept: application/json" -H "X-Auth-Token: {SHA1}39300e7398d53a02afd183f13cb6afaef95ec4e5"
|
||||
DEBUG: keystoneauth.session RESP: [200] Date: Fri, 27 Nov 2015 20:10:55 GMT Connection: keep-alive Content-Type: application/json; charset=UTF-8 Content-Length: 272 X-Openstack-Request-Id: req-261add00-d6d3-4ea7-becc-105b60ac7369
|
||||
RESP BODY: {"network": {"status": "ACTIVE", "subnets": [], "name": "mynetwork", "admin_state_up": true, "tenant_id": "8f0ebf767043483a987736c8c684178d", "mtu": 0, "router:external": false, "shared": false, "port_security_enabled": true, "id": "3698d3c7-d581-443e-bf86-53c4e3a738f7"}}
|
||||
|
||||
+-----------------------+--------------------------------------+
|
||||
| Field | Value |
|
||||
+-----------------------+--------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| id | 3698d3c7-d581-443e-bf86-53c4e3a738f7 |
|
||||
| mtu | 0 |
|
||||
| name | mynetwork |
|
||||
| port_security_enabled | True |
|
||||
| router:external | False |
|
||||
| shared | False |
|
||||
| status | ACTIVE |
|
||||
| subnets | |
|
||||
| tenant_id | 8f0ebf767043483a987736c8c684178d |
|
||||
+-----------------------+--------------------------------------+
|
||||
|
|
@ -25,9 +25,6 @@ Network v2
|
|||
.. autoprogram-cliff:: openstack.neutronclient.v2
|
||||
:command: bgp speaker show
|
||||
|
||||
.. autoprogram-cliff:: openstack.neutronclient.v2
|
||||
:command: bgp speaker show dragents
|
||||
|
||||
.. autoprogram-cliff:: openstack.neutronclient.v2
|
||||
:command: bgp speaker add network
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
=============
|
||||
network trunk
|
||||
=============
|
||||
|
||||
A **network trunk** is a container to group logical ports from different
|
||||
networks and provide a single trunked vNIC for servers. It consists of
|
||||
one parent port which is a regular VIF and multiple subports which allow
|
||||
the server to connect to more networks.
|
||||
|
||||
Network v2
|
||||
|
||||
.. autoprogram-cliff:: openstack.neutronclient.v2
|
||||
:command: network subport list
|
||||
|
||||
.. autoprogram-cliff:: openstack.neutronclient.v2
|
||||
:command: network trunk *
|
||||
|
|
@ -28,7 +28,7 @@ source_suffix = '.rst'
|
|||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
copyright = u'OpenStack Foundation'
|
||||
copyright = 'OpenStack Foundation'
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
|
|
@ -53,8 +53,8 @@ htmlhelp_basename = 'neutronclientdoc'
|
|||
|
||||
latex_documents = [
|
||||
('index', 'doc-python-neutronclient.tex',
|
||||
u'python-neutronclient Documentation',
|
||||
u'Neutron Contributors', 'manual'),
|
||||
'python-neutronclient Documentation',
|
||||
'Neutron Contributors', 'manual'),
|
||||
]
|
||||
|
||||
# Disable usage of xindy https://bugzilla.redhat.com/show_bug.cgi?id=1643664
|
||||
|
|
|
|||
|
|
@ -1,263 +0,0 @@
|
|||
..
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
CLI Option Guideline
|
||||
====================
|
||||
|
||||
This document describes the conventions of neutron CLI options.
|
||||
|
||||
General conventions
|
||||
-------------------
|
||||
|
||||
#. Option names should be delimited by a hyphen instead of a underscore.
|
||||
This is the common guidelines across all OpenStack CLIs.
|
||||
|
||||
* Good: ``--ip-version``
|
||||
* Not Good: ``--ip_version``
|
||||
|
||||
#. Use at least one required option for ``*-create`` command. If all options
|
||||
are optional, we typically use ``name`` field as a required option.
|
||||
|
||||
#. When you need to specify an ID of a resource, it is better to provide
|
||||
another way to specify the resource like ``name`` or other reasonable field.
|
||||
|
||||
#. If an attribute name in API is ``foo_id``, the corresponding option
|
||||
should be ``--foo`` instead of ``--foo-id``.
|
||||
|
||||
* It is because we usually support ID and ``name`` to specify a resource.
|
||||
|
||||
#. Do not use ``nargs='?'`` without a special reason.
|
||||
|
||||
* The behavior of ``nargs='?'`` option for python argparse is
|
||||
bit tricky and may lead to unexpected option parsing different
|
||||
from the help message. The detail is described in the
|
||||
:ref:`Background section <background-nargs>` below.
|
||||
|
||||
#. (option) Avoid using positional options as much as possible.
|
||||
|
||||
* Positional arguments should be limited to attributes which will
|
||||
be required in the long future.
|
||||
|
||||
#. We honor existing options and should keep compatibilities when adding or
|
||||
changing options.
|
||||
|
||||
Options for boolean value
|
||||
-------------------------
|
||||
|
||||
Use the form of ``--option-name {True|False}``.
|
||||
|
||||
* For a new option, it is recommended.
|
||||
* It is suggested to use ``common.utils.add_boolean_argument`` in an
|
||||
implementation. It allows ``true``/``false`` in addition to ``True``/``False``.
|
||||
* For existing options, migration to the recommended form is not necessarily
|
||||
required. All backward-compatibility should be kept without reasonable
|
||||
reasons.
|
||||
|
||||
Options for dict value
|
||||
----------------------
|
||||
|
||||
Some API attributes take a dictionary.
|
||||
|
||||
``--foo key1=val1,key2=val2`` is usually used.
|
||||
|
||||
This means ``{"key1": "val1", "key2": "val2"}`` is passed in the API layer.
|
||||
|
||||
Examples:
|
||||
|
||||
* ``--host-route destination=CIDR,nexthop=IP_ADDR`` for a subnet
|
||||
* ``--fixed-ip subnet_id=SUBNET,ip_address=IP_ADDR`` for a port.
|
||||
|
||||
Options for list value
|
||||
----------------------
|
||||
|
||||
Some attributes take a list.
|
||||
|
||||
In this case, we usually use:
|
||||
|
||||
* Define an option per element (Use a singular form as an option name)
|
||||
* Allow to specify the option multiple times
|
||||
|
||||
For Example, **port-create** has ``--security-group`` option.
|
||||
``--security-group SG1 --security-group SG2`` generates
|
||||
``{"security_groups: ["SG1", "SG2"]}`` in the API layer.
|
||||
|
||||
This convention applies to a case of a list of dict.
|
||||
``--allocation-pool`` and ``--host-route`` for a subnet are examples.
|
||||
|
||||
Compatibility with extra arguments
|
||||
----------------------------------
|
||||
|
||||
*extra arguments* supports various types of option specifications.
|
||||
At least the following patterns needs to be considered when defining
|
||||
a new option. For more detail, see :ref:`cli_extra_arguments`.
|
||||
|
||||
* Normal options with value
|
||||
* Boolean options : ``--foo True``, ``--bar=False``
|
||||
* List options : ``--bars list=true val1 val2``, ``--bars val1 val2``
|
||||
* Dict options : ``--foo type=dict key1=va1,key2=val2``
|
||||
* List of Dict options : ``--bars list=true type=dict key1=val1,key2=val2 key3=val3,key4=val4``
|
||||
* ``action=clear``
|
||||
|
||||
For normal options with value, there are four patterns to specify an option
|
||||
as extra arguments.
|
||||
|
||||
* ``--admin-state-up True`` (a space between option name and value)
|
||||
* ``--admin-state-up=True`` (= between option name and value)
|
||||
* ``--admin_state_up True`` (underscore is used as delimiter)
|
||||
* ``--admin_state_up=True`` (underscore is used as delimiter)
|
||||
|
||||
.. _background:
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
There are a lot of opinions on which form of options are better or not.
|
||||
This section tries to capture the reason of the current choice.
|
||||
|
||||
Use at least one required option
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As a convention, **neutron** CLI requires one required argument.
|
||||
|
||||
If all options are optional in the API level and we have ``name`` field,
|
||||
we usually use ``name`` as a required parameter.
|
||||
Requiring at least one argument has the following benefits:
|
||||
|
||||
* If we run ``neutron *-create`` without a required argument, we will have a
|
||||
brief help message without detail option help. It is convenient.
|
||||
* We can avoid miss operation by just hitting ``neutron *-create``.
|
||||
Requiring at least one parameter is a good balance.
|
||||
|
||||
Even though we can change this convention to allow to create a resource
|
||||
without ``name`` field, it will bring confusions to existing users.
|
||||
|
||||
There may be opinion that it is inconsistent with API level requirement
|
||||
or Horizon behavior, but even if neutron CLI requires ``name`` field
|
||||
there is no bad impact on regular users. Considering possible confusion
|
||||
if we change it, it looks better to keep it as-is.
|
||||
|
||||
Options for Boolean value
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ``--enable-foo``/``--disable-foo`` or similar patterns (including
|
||||
``--admin-state-down``) is not suggested because we need two exclusive
|
||||
options for one attribute in REST API. It is meaningless.
|
||||
|
||||
* It is not recommended to have an option only to specify non-default value.
|
||||
For example, we have ``--shared`` or ``--admin-state-down`` options for
|
||||
net-create. This form only works for ``*-create`` and does not work for
|
||||
``*-update``. It leads to having different options for ``*-create`` and
|
||||
``*-update``.
|
||||
|
||||
* A flag option like ``--enable-dhcp`` (without value) also has a problem when
|
||||
considering the compatibility with *extra argument*. We can specify
|
||||
``-enable-dhcp True/False`` or ``--enable-dhcp=True/False`` in the *extra
|
||||
argument* mechanism. If we introduce ``--enable-dhcp`` (without value),
|
||||
the form of ``-enable-dhcp True/False`` cannot be used now.
|
||||
This is another reason we don't use a flag style option for a boolean parameter.
|
||||
|
||||
.. _background-nargs:
|
||||
|
||||
Avoid using nargs in positional or optional arguments
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The behavior of ``nargs='?'`` option for python argparse is bit tricky.
|
||||
When we use ``nargs='?'`` and if the order of command-line options is
|
||||
changed then the command-line parser may fail to parse the arguments
|
||||
correctly. Two examples of such failures are provided below.
|
||||
|
||||
Example 1:
|
||||
This example shows how the actual behavior can differ from the provided
|
||||
help message. In the below block, help message at ``[5]`` says ``--bb CC``
|
||||
is a valid format but the argument parsing for the same format fails at ``[7]``.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
In [1]: import argparse
|
||||
In [2]: parser = argparse.ArgumentParser()
|
||||
In [3]: parser.add_argument('--bb', nargs='?')
|
||||
In [4]: parser.add_argument('cc')
|
||||
|
||||
In [5]: parser.print_help()
|
||||
usage: ipython [-h] [--bb [BB]] cc
|
||||
|
||||
positional arguments:
|
||||
cc
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--bb [BB]
|
||||
|
||||
In [6]: parser.parse_args('--bb 1 X'.split())
|
||||
Out[6]: Namespace(bb='1', cc='X')
|
||||
|
||||
In [7]: parser.parse_args('--bb X'.split())
|
||||
usage: ipython [-h] [--bb [BB]] cc
|
||||
ipython: error: too few arguments
|
||||
An exception has occurred, use %tb to see the full traceback.
|
||||
|
||||
SystemExit: 2
|
||||
|
||||
|
||||
Example 2:
|
||||
This example shows how fragile ``nargs='?'`` can be when user specifies
|
||||
options in different order from the help message.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
In [1]: import argparse
|
||||
In [2]: parser = argparse.ArgumentParser()
|
||||
In [3]: parser.add_argument('--a', help='option a')
|
||||
In [4]: parser.add_argument('--b', help='option b')
|
||||
In [5]: parser.add_argument('x', help='positional arg X')
|
||||
In [6]: parser.add_argument('y', nargs='?', help='positional arg Y')
|
||||
In [7]: parser.print_help()
|
||||
usage: ipython [-h] [--a A] [--b B] x [y]
|
||||
|
||||
positional arguments:
|
||||
x positional arg X
|
||||
y positional arg Y
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--a A option a
|
||||
--b B option b
|
||||
|
||||
In [8]: parser.parse_args('--a 1 --b 2 X Y'.split())
|
||||
Out[8]: Namespace(a='1', b='2', x='X', y='Y')
|
||||
|
||||
In [9]: parser.parse_args('X Y --a 1 --b 2'.split())
|
||||
Out[9]: Namespace(a='1', b='2', x='X', y='Y')
|
||||
|
||||
In [10]: parser.parse_args('X --a 1 --b 2 Y'.split())
|
||||
usage: ipython [-h] [--a A] [--b B] x [y]
|
||||
ipython: error: unrecognized arguments: Y
|
||||
An exception has occurred, use %tb to see the full traceback.
|
||||
|
||||
SystemExit: 2
|
||||
|
||||
To exit: use 'exit', 'quit', or Ctrl-D.
|
||||
To exit: use 'exit', 'quit', or Ctrl-D.
|
||||
|
||||
Note: Most CLI users don't care about the order of the command-line
|
||||
options. Hence, such fragile behavior should be avoided.
|
||||
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
..
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
Client command extension support
|
||||
=================================
|
||||
|
||||
The client command extension adds support for extending the neutron client while
|
||||
considering ease of creation.
|
||||
Extensions strongly conform to preexisting neutron commands (/neutron/v2_0/).
|
||||
|
||||
A sample extension can be seen at:
|
||||
neutronclient/neutron/v2_0/contrib/_fox_sockets.py
|
||||
|
||||
Minimum requirements from an extension
|
||||
--------------------------------------
|
||||
|
||||
* NeutronClientExtension subclasses must have a shell_command class variable
|
||||
if the command is to be available to the CLI (shell.py)
|
||||
|
||||
Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsList
|
||||
|
||||
Minimum requirements to use canonical neutron CRUD commands framework
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Neutron commands are cliff commands, commands in extension can use their
|
||||
own way to finish their tasks. But if they want to make use of the canonical
|
||||
neutron CRUD commands framework, the extension should:
|
||||
|
||||
* have a class that subclasses NeutronClientExtension to provide the
|
||||
requisite resource name, version support, and resource collection and
|
||||
object paths for a resource the commands will process.
|
||||
|
||||
Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocket
|
||||
|
||||
* have a class that subclasses from the ClientExtensionList to provide
|
||||
resource object list function. This is because most commands
|
||||
need the list function to get object ID via
|
||||
neutronclient.neutron.v2_0.__init__.find_resource_by_id.
|
||||
|
||||
Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsList
|
||||
|
||||
* if needed, subclass ClientExtensionUpdate to implement update of the resource
|
||||
object.
|
||||
|
||||
Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsUpdate
|
||||
|
||||
* if needed, subclass ClientExtensionDelete to implement deletion of the resource
|
||||
object.
|
||||
|
||||
Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsDelete
|
||||
|
||||
* if needed, subclass ClientExtensionShow to get the detail of the resource
|
||||
object.
|
||||
|
||||
Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsShow
|
||||
|
||||
Precedence of command loading
|
||||
------------------------------
|
||||
|
||||
* hard coded commands are loaded first
|
||||
* external commands (installed in the environment) are loaded then
|
||||
|
||||
Commands that have the same name will be overwritten by commands that are
|
||||
loaded later. To change the execution of a command for your particular
|
||||
extension you only need to override the execute method.
|
||||
|
||||
Currently this extension support is limited to top-level resources.
|
||||
Parent/child relationships may be added if desired.
|
||||
|
||||
neutronclient.extension entry_point
|
||||
-----------------------------------
|
||||
|
||||
To activate the commands in a specific extension module, add an entry in
|
||||
setup.cfg under neutronclient.extension. For example::
|
||||
|
||||
[entry_points]
|
||||
neutronclient.extension =
|
||||
fox_sockets = neutronclient.neutron.v2_0.contrib._fox_sockets
|
||||
|
|
@ -31,6 +31,4 @@ OpenStack client.
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
client_command_extensions
|
||||
cli_option_guideline
|
||||
transition_to_osc
|
||||
|
|
|
|||
|
|
@ -91,21 +91,21 @@ Transition Steps
|
|||
|
||||
* **Done** `Security Group Rule CRUD <https://bugs.launchpad.net/python-openstackclient/+bug/1519512>`_
|
||||
|
||||
6. **In Progress:** OSC continues enhancing its networking support.
|
||||
6. **Done** OSC continues enhancing its networking support.
|
||||
At this point and when applicable, enhancements to the ``neutron``
|
||||
CLI must also be made to the ``openstack`` CLI and possibly the
|
||||
OpenStack Python SDK. Users of the neutron client's command extensions
|
||||
should start their transition to the OSC plugin system. See the
|
||||
developer guide section below for more information on this step.
|
||||
|
||||
7. **In Progress:** Deprecate the ``neutron`` CLI. Running the CLI after
|
||||
7. **Done** Deprecate the ``neutron`` CLI. Running the CLI after
|
||||
it has been `deprecated <https://review.opendev.org/#/c/393903/>`_
|
||||
will issue a warning message:
|
||||
``neutron CLI is deprecated and will be removed in the future. Use openstack CLI instead.``
|
||||
``neutron CLI is deprecated and will be removed in the Z cycle. Use openstack CLI instead.``
|
||||
In addition, no new features will be added to the CLI, though fixes to
|
||||
the CLI will be assessed on a case by case basis.
|
||||
|
||||
8. **Not Started:** Remove the ``neutron`` CLI after two deprecation cycles
|
||||
8. **Done** Remove the ``neutron`` CLI after two deprecation cycles
|
||||
once the criteria below have been met.
|
||||
|
||||
* The networking support provide by the ``openstack`` CLI is functionally
|
||||
|
|
@ -122,32 +122,8 @@ Transition Steps
|
|||
|
||||
Developer Guide
|
||||
---------------
|
||||
The ``neutron`` CLI version 6.x, without extensions, supports over 200
|
||||
commands while the ``openstack`` CLI version 3.3.0 supports over 70
|
||||
networking commands. Of the 70 commands, some do not have all of the options
|
||||
or arguments of their ``neutron`` CLI equivalent. With this large functional
|
||||
gap, a few critical questions for developers during this transition are "Which
|
||||
CLI do I change?", "Where does my CLI belong?", and "Which Python library do I change?"
|
||||
The answer depends on the state of a command and the state of the overall transition.
|
||||
Details are outlined in the tables below. Early stages of the transition will require
|
||||
dual maintenance.
|
||||
|
||||
**Which CLI do I change?**
|
||||
|
||||
+----------------------+------------------------+-------------------------------------------------+
|
||||
| ``neutron`` Command | ``openstack`` Command | CLI to Change |
|
||||
+======================+========================+=================================================+
|
||||
| Exists | Doesn't Exist | ``neutron`` |
|
||||
+----------------------+------------------------+-------------------------------------------------+
|
||||
| Exists | In Progress | ``neutron`` and ``openstack`` |
|
||||
| | | (update related blueprint or bug) |
|
||||
+----------------------+------------------------+-------------------------------------------------+
|
||||
| Exists | Exists | ``openstack`` |
|
||||
| | | (assumes command parity resulting in |
|
||||
| | | ``neutron`` being deprecated) |
|
||||
+----------------------+------------------------+-------------------------------------------------+
|
||||
| Doesn't Exist | Doesn't Exist | ``openstack`` |
|
||||
+----------------------+------------------------+-------------------------------------------------+
|
||||
The ``neutron`` CLI tool is now removed and all new CLI changes should be done
|
||||
in the ``OpenStackClient (OSC)`` and, if needed, also in the ``OpenStack SDK``.
|
||||
|
||||
**Where does my CLI belong?**
|
||||
|
||||
|
|
@ -186,8 +162,6 @@ is not required as the neutronclient is already deprecated on its own.
|
|||
+=================================================+===============================================+
|
||||
| python-openstackclient | openstacksdk |
|
||||
+-------------------------------------------------+-----------------------------------------------+
|
||||
| python-neutronclient | python-neutronclient |
|
||||
+-------------------------------------------------+-----------------------------------------------+
|
||||
| Other | Applicable project owning network resource |
|
||||
+-------------------------------------------------+-----------------------------------------------+
|
||||
|
||||
|
|
|
|||
|
|
@ -24,15 +24,11 @@ python-neutronclient documentation
|
|||
==================================
|
||||
|
||||
This is a client for OpenStack Networking API. It provides
|
||||
:doc:`Python API bindings <reference/index>` (the neutronclient module) and
|
||||
:doc:`command-line interface (CLI) <cli/index>`.
|
||||
:doc:`Python API bindings <reference/index>` (the neutronclient module).
|
||||
|
||||
There are two CLIs which support the Networking API:
|
||||
:doc:`neutron CLI <cli/neutron>` and
|
||||
There is
|
||||
`OpenStack Client (OSC) <https://docs.openstack.org/python-openstackclient/latest/>`__.
|
||||
OpenStack Client provides the basic network commands and
|
||||
python-neutronclient provides extensions (aka OSC plugins)
|
||||
for advanced networking services.
|
||||
CLI which support the Networking API.
|
||||
|
||||
User Documentation
|
||||
------------------
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
alabaster==0.7.10
|
||||
amqp==2.1.1
|
||||
appdirs==1.3.0
|
||||
asn1crypto==0.23.0
|
||||
Babel==2.3.4
|
||||
cachetools==2.0.0
|
||||
cffi==1.7.0
|
||||
cliff==2.8.0
|
||||
cmd2==0.8.0
|
||||
contextlib2==0.4.0
|
||||
coverage==4.0
|
||||
cryptography==2.1
|
||||
debtcollector==1.2.0
|
||||
decorator==3.4.0
|
||||
deprecation==1.0
|
||||
docutils==0.11
|
||||
dogpile.cache==0.6.2
|
||||
dulwich==0.15.0
|
||||
eventlet==0.18.2
|
||||
extras==1.0.0
|
||||
fasteners==0.7.0
|
||||
fixtures==3.0.0
|
||||
flake8-import-order==0.12
|
||||
flake8==2.5.5
|
||||
future==0.16.0
|
||||
futurist==1.2.0
|
||||
greenlet==0.4.10
|
||||
hacking==1.1.0
|
||||
idna==2.6
|
||||
imagesize==0.7.1
|
||||
iso8601==0.1.11
|
||||
Jinja2==2.10
|
||||
jmespath==0.9.0
|
||||
jsonpatch==1.16
|
||||
jsonpointer==1.13
|
||||
jsonschema==2.6.0
|
||||
keystoneauth1==3.4.0
|
||||
kombu==4.0.0
|
||||
linecache2==1.0.0
|
||||
MarkupSafe==1.0
|
||||
mccabe==0.2.1
|
||||
monotonic==0.6
|
||||
mox3==0.20.0
|
||||
msgpack-python==0.4.0
|
||||
munch==2.1.0
|
||||
netaddr==0.7.18
|
||||
netifaces==0.10.4
|
||||
openstacksdk==0.11.2
|
||||
os-client-config==1.28.0
|
||||
os-service-types==1.2.0
|
||||
os-testr==1.0.0
|
||||
osc-lib==1.8.0
|
||||
oslo.concurrency==3.25.0
|
||||
oslo.config==5.2.0
|
||||
oslo.context==2.19.2
|
||||
oslo.i18n==3.15.3
|
||||
oslo.log==3.36.0
|
||||
oslo.messaging==5.29.0
|
||||
oslo.middleware==3.31.0
|
||||
oslo.serialization==2.18.0
|
||||
oslo.service==1.24.0
|
||||
oslo.utils==3.33.0
|
||||
oslotest==3.2.0
|
||||
osprofiler==2.3.0
|
||||
paramiko==2.0.0
|
||||
Paste==2.0.2
|
||||
PasteDeploy==1.5.0
|
||||
pbr==2.0.0
|
||||
pika-pool==0.1.3
|
||||
pika==0.10.0
|
||||
positional==1.2.1
|
||||
prettytable==0.7.2
|
||||
pyasn1==0.1.8
|
||||
pycodestyle==2.3.1
|
||||
pycparser==2.18
|
||||
pyflakes==0.8.1
|
||||
Pygments==2.2.0
|
||||
pyinotify==0.9.6
|
||||
pyOpenSSL==17.1.0
|
||||
pyparsing==2.1.0
|
||||
pyperclip==1.5.27
|
||||
python-cinderclient==3.3.0
|
||||
python-dateutil==2.5.3
|
||||
python-glanceclient==2.8.0
|
||||
python-keystoneclient==3.8.0
|
||||
python-mimeparse==1.6.0
|
||||
python-novaclient==9.1.0
|
||||
python-openstackclient==3.12.0
|
||||
python-subunit==1.0.0
|
||||
pytz==2013.6
|
||||
PyYAML==3.12
|
||||
repoze.lru==0.7
|
||||
requests-mock==1.2.0
|
||||
requests==2.14.2
|
||||
requestsexceptions==1.2.0
|
||||
rfc3986==0.3.1
|
||||
Routes==2.3.1
|
||||
simplejson==3.5.1
|
||||
snowballstemmer==1.2.1
|
||||
statsd==3.2.1
|
||||
stestr==2.0.0
|
||||
stevedore==1.20.0
|
||||
tempest==17.1.0
|
||||
tenacity==3.2.1
|
||||
testscenarios==0.4
|
||||
testtools==2.2.0
|
||||
traceback2==1.4.0
|
||||
unittest2==1.1.0
|
||||
urllib3==1.21.1
|
||||
vine==1.1.4
|
||||
warlock==1.2.0
|
||||
WebOb==1.7.1
|
||||
wrapt==1.7.0
|
||||
165
neutron_test.sh
165
neutron_test.sh
|
|
@ -1,165 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -x
|
||||
function die() {
|
||||
local exitcode=$?
|
||||
set +o xtrace
|
||||
echo $@
|
||||
cleanup
|
||||
exit $exitcode
|
||||
}
|
||||
|
||||
net_name=mynet1
|
||||
subnet_name=mysubnet1
|
||||
port_name=myport1
|
||||
function cleanup() {
|
||||
echo Removing test port, subnet and net...
|
||||
neutron port-delete $port_name
|
||||
neutron subnet-delete $subnet_name
|
||||
neutron net-delete $net_name
|
||||
}
|
||||
|
||||
noauth_tenant_id=me
|
||||
if [ "$1" == "noauth" ]; then
|
||||
NOAUTH="--tenant_id $noauth_tenant_id"
|
||||
else
|
||||
NOAUTH=
|
||||
fi
|
||||
|
||||
echo "NOTE: User should be admin in order to perform all operations."
|
||||
sleep 3
|
||||
|
||||
# test the CRUD of network
|
||||
network=$net_name
|
||||
neutron net-create $NOAUTH $network || die "fail to create network $network"
|
||||
temp=`neutron net-list -- --name $network --fields id | wc -l`
|
||||
echo $temp
|
||||
if [ $temp -ne 5 ]; then
|
||||
die "networks with name $network is not unique or found"
|
||||
fi
|
||||
network_id=`neutron net-list -- --name $network --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of network with name $network is $network_id"
|
||||
|
||||
neutron net-show $network || die "fail to show network $network"
|
||||
neutron net-show $network_id || die "fail to show network $network_id"
|
||||
|
||||
neutron net-update $network --admin_state_up False || die "fail to update network $network"
|
||||
neutron net-update $network_id --admin_state_up True || die "fail to update network $network_id"
|
||||
|
||||
neutron net-list -c id -- --id fakeid || die "fail to list networks with column selection on empty list"
|
||||
|
||||
# test the CRUD of subnet
|
||||
subnet=$subnet_name
|
||||
cidr=10.0.1.0/24
|
||||
neutron subnet-create $NOAUTH $network $cidr --name $subnet || die "fail to create subnet $subnet"
|
||||
tempsubnet=`neutron subnet-list -- --name $subnet --fields id | wc -l`
|
||||
echo $tempsubnet
|
||||
if [ $tempsubnet -ne 5 ]; then
|
||||
die "subnets with name $subnet is not unique or found"
|
||||
fi
|
||||
subnet_id=`neutron subnet-list -- --name $subnet --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of subnet with name $subnet is $subnet_id"
|
||||
neutron subnet-show $subnet || die "fail to show subnet $subnet"
|
||||
neutron subnet-show $subnet_id || die "fail to show subnet $subnet_id"
|
||||
|
||||
neutron subnet-update $subnet --dns_nameservers list=true 1.1.1.11 1.1.1.12 || die "fail to update subnet $subnet"
|
||||
neutron subnet-update $subnet_id --dns_nameservers list=true 2.2.2.21 2.2.2.22 || die "fail to update subnet $subnet_id"
|
||||
|
||||
# test the crud of ports
|
||||
port=$port_name
|
||||
neutron port-create $NOAUTH $network --name $port || die "fail to create port $port"
|
||||
tempport=`neutron port-list -- --name $port --fields id | wc -l`
|
||||
echo $tempport
|
||||
if [ $tempport -ne 5 ]; then
|
||||
die "ports with name $port is not unique or found"
|
||||
fi
|
||||
port_id=`neutron port-list -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of port with name $port is $port_id"
|
||||
neutron port-show $port || die "fail to show port $port"
|
||||
neutron port-show $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $port --device_id deviceid1 || die "fail to update port $port"
|
||||
neutron port-update $port_id --device_id deviceid2 || die "fail to update port $port_id"
|
||||
neutron port-update $port_id --allowed-address-pair ip_address=1.1.1.11,mac_address=10:00:00:00:00:00 --allowed-address-pair ip_address=1.1.1.12,mac_address=10:00:00:00:00:01 || die "fail to update port $port_id --allowed-address-pair"
|
||||
neutron port-show $port || die "fail to show port $port"
|
||||
neutron port-show $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $port_id --no-allowed-address-pairs || die "fail to update port $port_id --no-allowed-address-pairs"
|
||||
neutron port-show $port || die "fail to show port $port"
|
||||
neutron port-show $port_id || die "fail to show port $port_id"
|
||||
neutron port-delete $port_id
|
||||
|
||||
# test the create port with allowed-address-pairs
|
||||
port=$port_name
|
||||
neutron port-create $NOAUTH $network --name $port -- --allowed-address-pairs type=dict list=true ip_address=1.1.1.11,mac_address=10:00:00:00:00:00 ip_address=1.1.1.12,mac_address=10:00:00:00:00:01 || die "fail to create port $port"
|
||||
tempport=`neutron port-list -- --name $port --fields id | wc -l`
|
||||
echo $tempport
|
||||
if [ $tempport -ne 5 ]; then
|
||||
die "ports with name $port is not unique or found"
|
||||
fi
|
||||
port_id=`neutron port-list -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of port with name $port is $port_id"
|
||||
neutron port-show $port || die "fail to show port $port"
|
||||
neutron port-show $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $port_id --no-allowed-address-pairs || die "fail to update port $port_id --no-allowed-address-pairs"
|
||||
neutron port-show $port_id
|
||||
|
||||
# test quota commands RUD
|
||||
DEFAULT_NETWORKS=10
|
||||
DEFAULT_PORTS=50
|
||||
tenant_id=tenant_a
|
||||
tenant_id_b=tenant_b
|
||||
neutron quota-update --tenant_id $tenant_id --network 30 || die "fail to update quota for tenant $tenant_id"
|
||||
neutron quota-update --tenant_id $tenant_id_b --network 20 || die "fail to update quota for tenant $tenant_id"
|
||||
networks=`neutron quota-list -c network -c tenant_id | grep $tenant_id | awk '{print $2}'`
|
||||
if [ $networks -ne 30 ]; then
|
||||
die "networks quota should be 30"
|
||||
fi
|
||||
networks=`neutron quota-list -c network -c tenant_id | grep $tenant_id_b | awk '{print $2}'`
|
||||
if [ $networks -ne 20 ]; then
|
||||
die "networks quota should be 20"
|
||||
fi
|
||||
networks=`neutron quota-show --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'`
|
||||
if [ $networks -ne 30 ]; then
|
||||
die "networks quota should be 30"
|
||||
fi
|
||||
neutron quota-delete --tenant_id $tenant_id || die "fail to delete quota for tenant $tenant_id"
|
||||
networks=`neutron quota-show --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'`
|
||||
if [ $networks -ne $DEFAULT_NETWORKS ]; then
|
||||
die "networks quota should be $DEFAULT_NETWORKS"
|
||||
fi
|
||||
# update self
|
||||
if [ "t$NOAUTH" = "t" ]; then
|
||||
# with auth
|
||||
neutron quota-update --port 99 || die "fail to update quota for self"
|
||||
ports=`neutron quota-show | grep port | awk -F'|' '{print $3}'`
|
||||
if [ $ports -ne 99 ]; then
|
||||
die "ports quota should be 99"
|
||||
fi
|
||||
|
||||
ports=`neutron quota-list -c port | grep 99 | awk '{print $2}'`
|
||||
if [ $ports -ne 99 ]; then
|
||||
die "ports quota should be 99"
|
||||
fi
|
||||
neutron quota-delete || die "fail to delete quota for tenant self"
|
||||
ports=`neutron quota-show | grep port | awk -F'|' '{print $3}'`
|
||||
if [ $ports -ne $DEFAULT_PORTS ]; then
|
||||
die "ports quota should be $DEFAULT_PORTS"
|
||||
fi
|
||||
else
|
||||
# without auth
|
||||
neutron quota-update --port 100
|
||||
if [ $? -eq 0 ]; then
|
||||
die "without valid context on server, quota update command should fail."
|
||||
fi
|
||||
neutron quota-show
|
||||
if [ $? -eq 0 ]; then
|
||||
die "without valid context on server, quota show command should fail."
|
||||
fi
|
||||
neutron quota-delete
|
||||
if [ $? -eq 0 ]; then
|
||||
die "without valid context on server, quota delete command should fail."
|
||||
fi
|
||||
neutron quota-list || die "fail to update quota for self"
|
||||
fi
|
||||
|
||||
cleanup
|
||||
echo "Success! :)"
|
||||
|
||||
|
|
@ -61,9 +61,9 @@ class HTTPClient(object):
|
|||
token=None, region_name=None, timeout=None,
|
||||
endpoint_url=None, insecure=False,
|
||||
endpoint_type='publicURL',
|
||||
auth_strategy='keystone', ca_cert=None, log_credentials=False,
|
||||
service_type='network', global_request_id=None,
|
||||
**kwargs):
|
||||
auth_strategy='keystone', ca_cert=None, cert=None,
|
||||
log_credentials=False, service_type='network',
|
||||
global_request_id=None, **kwargs):
|
||||
|
||||
self.username = username
|
||||
self.user_id = user_id
|
||||
|
|
@ -82,6 +82,7 @@ class HTTPClient(object):
|
|||
self.auth_strategy = auth_strategy
|
||||
self.log_credentials = log_credentials
|
||||
self.global_request_id = global_request_id
|
||||
self.cert = cert
|
||||
if insecure:
|
||||
self.verify_cert = False
|
||||
else:
|
||||
|
|
@ -167,6 +168,7 @@ class HTTPClient(object):
|
|||
data=body,
|
||||
headers=headers,
|
||||
verify=self.verify_cert,
|
||||
cert=self.cert,
|
||||
timeout=self.timeout,
|
||||
**kwargs)
|
||||
|
||||
|
|
@ -399,6 +401,7 @@ def construct_http_client(username=None,
|
|||
log_credentials=None,
|
||||
auth_strategy='keystone',
|
||||
ca_cert=None,
|
||||
cert=None,
|
||||
service_type='network',
|
||||
session=None,
|
||||
global_request_id=None,
|
||||
|
|
@ -430,6 +433,7 @@ def construct_http_client(username=None,
|
|||
endpoint_type=endpoint_type,
|
||||
service_type=service_type,
|
||||
ca_cert=ca_cert,
|
||||
cert=cert,
|
||||
log_credentials=log_credentials,
|
||||
auth_strategy=auth_strategy,
|
||||
global_request_id=global_request_id)
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ def str2dict(strdict, required_keys=None, optional_keys=None):
|
|||
msg = _("missing value for key '%s'")
|
||||
raise argparse.ArgumentTypeError(msg % kv)
|
||||
else:
|
||||
kvlist[i-1] = "%s,%s" % (kvlist[i-1], kv)
|
||||
kvlist[i - 1] = "%s,%s" % (kvlist[i - 1], kv)
|
||||
for kv in kvlist:
|
||||
key, sep, value = kv.partition('=')
|
||||
if not sep:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ from neutronclient.neutron.v2_0.bgp import peer as bgp_peer
|
|||
|
||||
# Allowed BGP Autonomous number range
|
||||
MIN_AS_NUM = 1
|
||||
MAX_AS_NUM = 65535
|
||||
MAX_AS_NUM = 4294967295
|
||||
|
||||
|
||||
def get_network_id(client, id_or_name):
|
||||
|
|
@ -189,7 +189,7 @@ class RemovePeerFromSpeaker(neutronv20.NeutronCommand):
|
|||
neutron_client.remove_peer_from_bgp_speaker(_speaker_id,
|
||||
{'bgp_peer_id': _peer_id})
|
||||
print(_('Removed BGP peer %(peer)s from BGP speaker %(speaker)s.') %
|
||||
{'peer': parsed_args.bgp_peer,
|
||||
{'peer': parsed_args.bgp_peer,
|
||||
'speaker': parsed_args.bgp_speaker},
|
||||
file=self.app.stdout)
|
||||
|
||||
|
|
|
|||
|
|
@ -245,15 +245,15 @@ class CreatePort(neutronV20.CreateCommand, UpdatePortSecGroupMixin,
|
|||
parser.add_argument(
|
||||
'--vnic-type',
|
||||
metavar='<direct | direct-physical | macvtap '
|
||||
'| normal | baremetal>',
|
||||
'| normal | baremetal | smart-nic>',
|
||||
choices=['direct', 'direct-physical', 'macvtap',
|
||||
'normal', 'baremetal'],
|
||||
'normal', 'baremetal', 'smart-nic'],
|
||||
type=utils.convert_to_lowercase,
|
||||
help=_('VNIC type for this port.'))
|
||||
parser.add_argument(
|
||||
'--vnic_type',
|
||||
choices=['direct', 'direct-physical', 'macvtap',
|
||||
'normal', 'baremetal'],
|
||||
'normal', 'baremetal', 'smart-nic'],
|
||||
type=utils.convert_to_lowercase,
|
||||
help=argparse.SUPPRESS)
|
||||
parser.add_argument(
|
||||
|
|
|
|||
|
|
@ -118,3 +118,13 @@ def _find_identity_resource(identity_client_manager, name_or_id,
|
|||
|
||||
# The above are borrowed from openstackclient.identity.common.
|
||||
# DO NOT ADD original methods in neutronclient repo to the above area.
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
column_map = {}
|
||||
hidden_columns = ['location', 'tenant_id']
|
||||
return utils.get_osc_show_columns_for_sdk_resource(
|
||||
item,
|
||||
column_map,
|
||||
hidden_columns
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ from osc_lib.command import command
|
|||
from osc_lib import utils
|
||||
|
||||
from neutronclient._i18n import _
|
||||
from neutronclient.osc.v2.dynamic_routing import constants
|
||||
|
||||
|
||||
def _format_alive_state(item):
|
||||
|
|
@ -45,11 +44,9 @@ class AddBgpSpeakerToDRAgent(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
client.add_bgp_speaker_to_dragent(
|
||||
parsed_args.dragent_id, {'bgp_speaker_id': speaker_id})
|
||||
client = self.app.client_manager.network
|
||||
speaker_id = client.find_bgp_speaker(parsed_args.bgp_speaker).id
|
||||
client.add_bgp_speaker_to_dragent(parsed_args.dragent_id, speaker_id)
|
||||
|
||||
|
||||
class RemoveBgpSpeakerFromDRAgent(command.Command):
|
||||
|
|
@ -62,50 +59,12 @@ class RemoveBgpSpeakerFromDRAgent(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
client = self.app.client_manager.network
|
||||
speaker_id = client.find_bgp_speaker(parsed_args.bgp_speaker).id
|
||||
client.remove_bgp_speaker_from_dragent(parsed_args.dragent_id,
|
||||
speaker_id)
|
||||
|
||||
|
||||
class ListDRAgentsHostingBgpSpeaker(command.Lister):
|
||||
"""(Deprecated) List dynamic routing agents hosting a BGP speaker
|
||||
|
||||
(Use "bgp dragent list" instead)
|
||||
"""
|
||||
|
||||
resource = 'agent'
|
||||
list_columns = ['id', 'host', 'admin_state_up', 'alive']
|
||||
unknown_parts_flag = False
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
self.log.warning("The 'openstack bgp speaker show dragents' CLI is "
|
||||
"deprecated and will be removed in the future. Use "
|
||||
"'openstack bgp dragent list' CLI instead.")
|
||||
parser = super(ListDRAgentsHostingBgpSpeaker,
|
||||
self).get_parser(prog_name)
|
||||
parser.add_argument('bgp_speaker',
|
||||
metavar='<bgp-speaker>',
|
||||
help=_("List dynamic routing agents hosting a "
|
||||
"BGP speaker (name or ID)"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
search_opts = {}
|
||||
client = self.app.client_manager.neutronclient
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
search_opts['bgp_speaker'] = speaker_id
|
||||
data = client.list_dragents_hosting_bgp_speaker(**search_opts)
|
||||
headers = ('ID', 'Host', 'State', 'Alive')
|
||||
columns = ('id', 'host', 'admin_state_up', 'alive')
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns, formatters=_formatters,
|
||||
) for s in data['agents']))
|
||||
|
||||
|
||||
class ListDRAgent(command.Lister):
|
||||
"""List dynamic routing agents"""
|
||||
|
||||
|
|
@ -123,20 +82,31 @@ class ListDRAgent(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
search_opts = {}
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
if parsed_args.bgp_speaker is not None:
|
||||
search_opts = {}
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
search_opts['bgp_speaker'] = speaker_id
|
||||
data = client.list_dragents_hosting_bgp_speaker(**search_opts)
|
||||
speaker_id = client.find_bgp_speaker(parsed_args.bgp_speaker).id
|
||||
data = client.get_bgp_dragents_hosting_speaker(speaker_id)
|
||||
else:
|
||||
attrs = {'agent_type': 'BGP dynamic routing agent'}
|
||||
data = client.list_agents(**attrs)
|
||||
headers = ('ID', 'Host', 'State', 'Alive')
|
||||
columns = ('id', 'host', 'admin_state_up', 'alive')
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns, formatters=_formatters,
|
||||
) for s in data['agents']))
|
||||
data = client.agents(**attrs)
|
||||
columns = (
|
||||
'id',
|
||||
'agent_type',
|
||||
'host',
|
||||
'availability_zone',
|
||||
'is_alive',
|
||||
'is_admin_state_up',
|
||||
'binary'
|
||||
)
|
||||
column_headers = (
|
||||
'ID',
|
||||
'Agent Type',
|
||||
'Host',
|
||||
'Availability Zone',
|
||||
'Alive',
|
||||
'State',
|
||||
'Binary'
|
||||
)
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,) for s in data))
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils
|
||||
from osc_lib.utils import columns as column_util
|
||||
|
||||
from neutronclient._i18n import _
|
||||
from neutronclient.common import exceptions
|
||||
|
|
@ -96,11 +95,10 @@ class CreateBgpPeer(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
body = {constants.BGP_PEER: attrs}
|
||||
obj = client.create_bgp_peer(body)[constants.BGP_PEER]
|
||||
columns, display_columns = column_util.get_columns(obj)
|
||||
obj = client.create_bgp_peer(**attrs)
|
||||
display_columns, columns = nc_osc_utils._get_columns(obj)
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -118,9 +116,8 @@ class DeleteBgpPeer(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGP_PEER,
|
||||
parsed_args.bgp_peer)['id']
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgp_peer(parsed_args.bgp_peer)['id']
|
||||
client.delete_bgp_peer(id)
|
||||
|
||||
|
||||
|
|
@ -128,13 +125,11 @@ class ListBgpPeer(command.Lister):
|
|||
_description = _("List BGP peers")
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
data = self.app.client_manager.neutronclient.list_bgp_peers()
|
||||
data = self.app.client_manager.network.bgp_peers(retrieve_all=True)
|
||||
headers = ('ID', 'Name', 'Peer IP', 'Remote AS')
|
||||
columns = ('id', 'name', 'peer_ip', 'remote_as')
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[constants.BGP_PEERS]))
|
||||
(utils.get_dict_properties(s, columns,) for s in data))
|
||||
|
||||
|
||||
class SetBgpPeer(command.Command):
|
||||
|
|
@ -158,13 +153,10 @@ class SetBgpPeer(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGP_PEER,
|
||||
parsed_args.bgp_peer)['id']
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgp_peer(parsed_args.bgp_peer)['id']
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
body = {}
|
||||
body[constants.BGP_PEER] = attrs
|
||||
client.update_bgp_peer(id, body)
|
||||
client.update_bgp_peer(id, **attrs)
|
||||
|
||||
|
||||
class ShowBgpPeer(command.ShowOne):
|
||||
|
|
@ -180,10 +172,10 @@ class ShowBgpPeer(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGP_PEER,
|
||||
parsed_args.bgp_peer)['id']
|
||||
obj = client.show_bgp_peer(id)[constants.BGP_PEER]
|
||||
columns, display_columns = column_util.get_columns(obj)
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgp_peer(parsed_args.bgp_peer,
|
||||
ignore_missing=False).id
|
||||
obj = client.get_bgp_peer(id)
|
||||
display_columns, columns = nc_osc_utils._get_columns(obj)
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils
|
||||
from osc_lib.utils import columns as column_util
|
||||
|
||||
from neutronclient._i18n import _
|
||||
from neutronclient.osc import utils as nc_osc_utils
|
||||
|
|
@ -87,12 +86,12 @@ class AddNetworkToSpeaker(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
net_id = client.find_resource('network',
|
||||
parsed_args.network)['id']
|
||||
client.add_network_to_bgp_speaker(speaker_id, {'network_id': net_id})
|
||||
client = self.app.client_manager.network
|
||||
speaker_id = client.find_bgp_speaker(parsed_args.bgp_speaker,
|
||||
ignore_missing=False).id
|
||||
net_id = client.find_network(parsed_args.network,
|
||||
ignore_missing=False).id
|
||||
client.add_gateway_network_to_speaker(speaker_id, net_id)
|
||||
|
||||
|
||||
class AddPeerToSpeaker(command.Command):
|
||||
|
|
@ -111,12 +110,10 @@ class AddPeerToSpeaker(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
peer_id = client.find_resource(constants.BGP_PEER,
|
||||
parsed_args.bgp_peer)['id']
|
||||
client.add_peer_to_bgp_speaker(speaker_id, {'bgp_peer_id': peer_id})
|
||||
client = self.app.client_manager.network
|
||||
speaker_id = client.find_bgp_speaker(parsed_args.bgp_speaker)['id']
|
||||
peer_id = client.find_bgp_peer(parsed_args.bgp_peer)['id']
|
||||
client.add_bgp_peer_to_speaker(speaker_id, peer_id)
|
||||
|
||||
|
||||
class CreateBgpSpeaker(command.ShowOne):
|
||||
|
|
@ -145,12 +142,10 @@ class CreateBgpSpeaker(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
body = {}
|
||||
body[constants.BGP_SPEAKER] = attrs
|
||||
obj = client.create_bgp_speaker(body)[constants.BGP_SPEAKER]
|
||||
columns, display_columns = column_util.get_columns(obj)
|
||||
obj = client.create_bgp_speaker(**attrs)
|
||||
display_columns, columns = nc_osc_utils._get_columns(obj)
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -168,9 +163,8 @@ class DeleteBgpSpeaker(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgp_speaker(parsed_args.bgp_speaker)['id']
|
||||
client.delete_bgp_speaker(id)
|
||||
|
||||
|
||||
|
|
@ -186,16 +180,16 @@ class ListBgpSpeaker(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
if parsed_args.agent is not None:
|
||||
data = client.list_bgp_speaker_on_dragent(parsed_args.agent)
|
||||
data = client.get_bgp_speakers_hosted_by_dragent(parsed_args.agent)
|
||||
else:
|
||||
data = client.list_bgp_speakers()
|
||||
data = client.bgp_speakers(retrieve_all=True)
|
||||
|
||||
headers = ('ID', 'Name', 'Local AS', 'IP Version')
|
||||
columns = ('id', 'name', 'local_as', 'ip_version')
|
||||
return (headers, (utils.get_dict_properties(s, columns)
|
||||
for s in data[constants.BGP_SPEAKERS]))
|
||||
for s in data))
|
||||
|
||||
|
||||
class ListRoutesAdvertisedBySpeaker(command.Lister):
|
||||
|
|
@ -211,10 +205,9 @@ class ListRoutesAdvertisedBySpeaker(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
data = client.list_route_advertised_from_bgp_speaker(speaker_id)
|
||||
client = self.app.client_manager.network
|
||||
speaker_id = client.find_bgp_speaker(parsed_args.bgp_speaker)['id']
|
||||
data = client.get_advertised_routes_of_speaker(speaker_id)
|
||||
headers = ('Destination', 'Nexthop')
|
||||
columns = ('destination', 'next_hop')
|
||||
return (headers, (utils.get_dict_properties(s, columns)
|
||||
|
|
@ -237,13 +230,10 @@ class RemoveNetworkFromSpeaker(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
net_id = client.find_resource('network',
|
||||
parsed_args.network)['id']
|
||||
client.remove_network_from_bgp_speaker(speaker_id,
|
||||
{'network_id': net_id})
|
||||
client = self.app.client_manager.network
|
||||
speaker_id = client.find_bgp_speaker(parsed_args.bgp_speaker)['id']
|
||||
net_id = client.find_network(parsed_args.network)['id']
|
||||
client.remove_gateway_network_from_speaker(speaker_id, net_id)
|
||||
|
||||
|
||||
class RemovePeerFromSpeaker(command.Command):
|
||||
|
|
@ -262,13 +252,10 @@ class RemovePeerFromSpeaker(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
speaker_id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
peer_id = client.find_resource(constants.BGP_PEER,
|
||||
parsed_args.bgp_peer)['id']
|
||||
client.remove_peer_from_bgp_speaker(speaker_id,
|
||||
{'bgp_peer_id': peer_id})
|
||||
client = self.app.client_manager.network
|
||||
speaker_id = client.find_bgp_speaker(parsed_args.bgp_speaker)['id']
|
||||
peer_id = client.find_bgp_peer(parsed_args.bgp_peer)['id']
|
||||
client.remove_bgp_peer_from_speaker(speaker_id, peer_id)
|
||||
|
||||
|
||||
class SetBgpSpeaker(command.Command):
|
||||
|
|
@ -285,18 +272,15 @@ class SetBgpSpeaker(command.Command):
|
|||
)
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
help=_("Name of the BGP speaker to update"))
|
||||
help=_("New name for the BGP speaker"))
|
||||
add_common_arguments(parser)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgp_speaker(parsed_args.bgp_speaker)['id']
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
body = {}
|
||||
body[constants.BGP_SPEAKER] = attrs
|
||||
client.update_bgp_speaker(id, body)
|
||||
client.update_bgp_speaker(id, **attrs)
|
||||
|
||||
|
||||
class ShowBgpSpeaker(command.ShowOne):
|
||||
|
|
@ -312,10 +296,10 @@ class ShowBgpSpeaker(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGP_SPEAKER,
|
||||
parsed_args.bgp_speaker)['id']
|
||||
obj = client.show_bgp_speaker(id)[constants.BGP_SPEAKER]
|
||||
columns, display_columns = column_util.get_columns(obj)
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgp_speaker(parsed_args.bgp_speaker,
|
||||
ignore_missing=False).id
|
||||
obj = client.get_bgp_speaker(id)
|
||||
display_columns, columns = nc_osc_utils._get_columns(obj)
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@ BGP_SPEAKER = 'bgp_speaker'
|
|||
BGP_PEERS = 'bgp_peers'
|
||||
BGP_PEER = 'bgp_peer'
|
||||
MIN_AS_NUM = 1
|
||||
MAX_AS_NUM = 65535
|
||||
MAX_AS_NUM = 4294967295
|
||||
|
|
|
|||
|
|
@ -32,6 +32,20 @@ _formatters = {
|
|||
'admin_state_up': v2_utils.AdminStateColumn,
|
||||
}
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'ingress_firewall_policy_id': 'Ingress Policy ID',
|
||||
'egress_firewall_policy_id': 'Egress Policy ID',
|
||||
'description': 'Description',
|
||||
'status': 'Status',
|
||||
'ports': 'Ports',
|
||||
'admin_state_up': 'State',
|
||||
'shared': 'Shared',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', column_util.LIST_BOTH),
|
||||
('name', 'Name', column_util.LIST_BOTH),
|
||||
|
|
@ -103,7 +117,7 @@ def _get_common_parser(parser):
|
|||
|
||||
def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
||||
attrs = {}
|
||||
client = client_manager.neutronclient
|
||||
client = client_manager.network
|
||||
|
||||
if is_create:
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
|
|
@ -114,24 +128,20 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
).id
|
||||
if (parsed_args.ingress_firewall_policy and
|
||||
parsed_args.no_ingress_firewall_policy):
|
||||
attrs['ingress_firewall_policy_id'] = client.find_resource(
|
||||
const.FWP, parsed_args.ingress_firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
attrs['ingress_firewall_policy_id'] = client.find_firewall_policy(
|
||||
parsed_args.ingress_firewall_policy)['id']
|
||||
elif parsed_args.ingress_firewall_policy:
|
||||
attrs['ingress_firewall_policy_id'] = client.find_resource(
|
||||
const.FWP, parsed_args.ingress_firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
attrs['ingress_firewall_policy_id'] = client.find_firewall_policy(
|
||||
parsed_args.ingress_firewall_policy)['id']
|
||||
elif parsed_args.no_ingress_firewall_policy:
|
||||
attrs['ingress_firewall_policy_id'] = None
|
||||
if (parsed_args.egress_firewall_policy and
|
||||
parsed_args.no_egress_firewall_policy):
|
||||
attrs['egress_firewall_policy_id'] = client.find_resource(
|
||||
const.FWP, parsed_args.egress_firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
attrs['egress_firewall_policy_id'] = client.find_firewall_policy(
|
||||
parsed_args.egress_firewall_policy)['id']
|
||||
elif parsed_args.egress_firewall_policy:
|
||||
attrs['egress_firewall_policy_id'] = client.find_resource(
|
||||
const.FWP, parsed_args.egress_firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
attrs['egress_firewall_policy_id'] = client.find_firewall_policy(
|
||||
parsed_args.egress_firewall_policy)['id']
|
||||
elif parsed_args.no_egress_firewall_policy:
|
||||
attrs['egress_firewall_policy_id'] = None
|
||||
if parsed_args.share:
|
||||
|
|
@ -147,16 +157,15 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
if parsed_args.description:
|
||||
attrs['description'] = str(parsed_args.description)
|
||||
if parsed_args.port and parsed_args.no_port:
|
||||
attrs['ports'] = sorted([client.find_resource(
|
||||
'port', p)['id'] for p in set(parsed_args.port)])
|
||||
attrs['ports'] = sorted([client.find_port(
|
||||
p)['id'] for p in set(parsed_args.port)])
|
||||
elif parsed_args.port:
|
||||
ports = []
|
||||
for p in set(parsed_args.port):
|
||||
ports.append(client.find_resource('port', p)['id'])
|
||||
ports.append(client.find_port(p)['id'])
|
||||
if not is_create:
|
||||
ports += client.find_resource(
|
||||
const.FWG, parsed_args.firewall_group,
|
||||
cmd_resource=const.CMD_FWG)['ports']
|
||||
ports += client.find_firewall_group(
|
||||
parsed_args.firewall_group)['ports']
|
||||
attrs['ports'] = sorted(set(ports))
|
||||
elif parsed_args.no_port:
|
||||
attrs['ports'] = []
|
||||
|
|
@ -185,11 +194,11 @@ class CreateFirewallGroup(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
obj = client.create_fwaas_firewall_group(
|
||||
{const.FWG: attrs})[const.FWG]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_firewall_group(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
|
@ -207,13 +216,12 @@ class DeleteFirewallGroup(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for fwg in parsed_args.firewall_group:
|
||||
try:
|
||||
fwg_id = client.find_resource(
|
||||
const.FWG, fwg, cmd_resource=const.CMD_FWG)['id']
|
||||
client.delete_fwaas_firewall_group(fwg_id)
|
||||
fwg_id = client.find_firewall_group(fwg)['id']
|
||||
client.delete_firewall_group(fwg_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete firewall group with "
|
||||
|
|
@ -240,8 +248,8 @@ class ListFirewallGroup(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_fwaas_firewall_groups()[const.FWGS]
|
||||
client = self.app.client_manager.network
|
||||
obj = client.firewall_groups()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (utils.get_dict_properties(
|
||||
|
|
@ -272,13 +280,12 @@ class SetFirewallGroup(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fwg_id = client.find_resource(const.FWG, parsed_args.firewall_group,
|
||||
cmd_resource=const.CMD_FWG)['id']
|
||||
client = self.app.client_manager.network
|
||||
fwg_id = client.find_firewall_group(parsed_args.firewall_group)['id']
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args,
|
||||
is_create=False)
|
||||
try:
|
||||
client.update_fwaas_firewall_group(fwg_id, {const.FWG: attrs})
|
||||
client.update_firewall_group(fwg_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set firewall group '%(group)s': %(e)s")
|
||||
% {'group': parsed_args.firewall_group, 'e': e})
|
||||
|
|
@ -297,11 +304,11 @@ class ShowFirewallGroup(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fwg_id = client.find_resource(const.FWG, parsed_args.firewall_group,
|
||||
cmd_resource=const.CMD_FWG)['id']
|
||||
obj = client.show_fwaas_firewall_group(fwg_id)[const.FWG]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
fwg_id = client.find_firewall_group(parsed_args.firewall_group)['id']
|
||||
obj = client.get_firewall_group(fwg_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
|
@ -347,9 +354,8 @@ class UnsetFirewallGroup(command.Command):
|
|||
help=_('Disable firewall group'))
|
||||
return parser
|
||||
|
||||
def _get_attrs(self, client_manager, parsed_args):
|
||||
def _get_attrs(self, client, parsed_args):
|
||||
attrs = {}
|
||||
client = client_manager.neutronclient
|
||||
if parsed_args.ingress_firewall_policy:
|
||||
attrs['ingress_firewall_policy_id'] = None
|
||||
if parsed_args.egress_firewall_policy:
|
||||
|
|
@ -359,23 +365,20 @@ class UnsetFirewallGroup(command.Command):
|
|||
if parsed_args.enable:
|
||||
attrs['admin_state_up'] = False
|
||||
if parsed_args.port:
|
||||
old = client.find_resource(
|
||||
const.FWG, parsed_args.firewall_group,
|
||||
cmd_resource=const.CMD_FWG)['ports']
|
||||
new = [client.find_resource(
|
||||
'port', r)['id'] for r in parsed_args.port]
|
||||
old = client.find_firewall_group(
|
||||
parsed_args.firewall_group)['ports']
|
||||
new = [client.find_port(r)['id'] for r in parsed_args.port]
|
||||
attrs['ports'] = sorted(list(set(old) - set(new)))
|
||||
if parsed_args.all_port:
|
||||
attrs['ports'] = []
|
||||
return attrs
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fwg_id = client.find_resource(const.FWG, parsed_args.firewall_group,
|
||||
cmd_resource=const.CMD_FWG)['id']
|
||||
attrs = self._get_attrs(self.app.client_manager, parsed_args)
|
||||
client = self.app.client_manager.network
|
||||
fwg_id = client.find_firewall_group(parsed_args.firewall_group)['id']
|
||||
attrs = self._get_attrs(client, parsed_args)
|
||||
try:
|
||||
client.update_fwaas_firewall_group(fwg_id, {const.FWG: attrs})
|
||||
client.update_firewall_group(fwg_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to unset firewall group '%(group)s': %(e)s")
|
||||
% {'group': parsed_args.firewall_group, 'e': e})
|
||||
|
|
|
|||
|
|
@ -30,6 +30,18 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
_formatters = {}
|
||||
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'description': 'Description',
|
||||
'firewall_rules': 'Firewall Rules',
|
||||
'audited': 'Audited',
|
||||
'shared': 'Shared',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', column_util.LIST_BOTH),
|
||||
('name', 'Name', column_util.LIST_BOTH),
|
||||
|
|
@ -43,7 +55,7 @@ _attr_map = (
|
|||
|
||||
def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
||||
attrs = {}
|
||||
client = client_manager.neutronclient
|
||||
client = client_manager.network
|
||||
|
||||
if is_create:
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
|
|
@ -55,18 +67,16 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
if parsed_args.firewall_rule and parsed_args.no_firewall_rule:
|
||||
_firewall_rules = []
|
||||
for f in parsed_args.firewall_rule:
|
||||
_firewall_rules.append(client.find_resource(
|
||||
const.FWR, f, cmd_resource=const.CMD_FWR)['id'])
|
||||
_firewall_rules.append(client.find_firewall_rule(f)['id'])
|
||||
attrs[const.FWRS] = _firewall_rules
|
||||
elif parsed_args.firewall_rule:
|
||||
rules = []
|
||||
if not is_create:
|
||||
rules += client.find_resource(
|
||||
const.FWP, parsed_args.firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)[const.FWRS]
|
||||
foobar = client.find_firewall_policy(
|
||||
parsed_args.firewall_policy)
|
||||
rules += foobar[const.FWRS]
|
||||
for f in parsed_args.firewall_rule:
|
||||
rules.append(client.find_resource(
|
||||
const.FWR, f, cmd_resource=const.CMD_FWR)['id'])
|
||||
rules.append(client.find_firewall_rule(f)['id'])
|
||||
attrs[const.FWRS] = rules
|
||||
elif parsed_args.no_firewall_rule:
|
||||
attrs[const.FWRS] = []
|
||||
|
|
@ -137,11 +147,11 @@ class CreateFirewallPolicy(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
obj = client.create_fwaas_firewall_policy(
|
||||
{const.FWP: attrs})[const.FWP]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_firewall_policy(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
|
@ -159,13 +169,12 @@ class DeleteFirewallPolicy(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for fwp in parsed_args.firewall_policy:
|
||||
try:
|
||||
fwp_id = client.find_resource(
|
||||
const.FWP, fwp, cmd_resource='fwaas_' + const.FWP)['id']
|
||||
client.delete_fwaas_firewall_policy(fwp_id)
|
||||
fwp_id = client.find_firewall_policy(fwp)['id']
|
||||
client.delete_firewall_policy(fwp_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete Firewall policy with "
|
||||
|
|
@ -205,31 +214,28 @@ class FirewallPolicyInsertRule(command.Command):
|
|||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
_rule_id = _get_required_firewall_rule(client, parsed_args)
|
||||
_insert_before = ''
|
||||
if 'insert_before' in parsed_args:
|
||||
if parsed_args.insert_before:
|
||||
_insert_before = client.find_resource(
|
||||
const.FWR, parsed_args.insert_before,
|
||||
cmd_resource=const.CMD_FWR)['id']
|
||||
_insert_before = client.find_firewall_rule(
|
||||
parsed_args.insert_before)['id']
|
||||
_insert_after = ''
|
||||
if 'insert_after' in parsed_args:
|
||||
if parsed_args.insert_after:
|
||||
_insert_after = client.find_resource(
|
||||
const.FWR, parsed_args.insert_after,
|
||||
cmd_resource=const.CMD_FWR)['id']
|
||||
_insert_after = client.find_firewall_rule(
|
||||
parsed_args.insert_after)['id']
|
||||
return {'firewall_rule_id': _rule_id,
|
||||
'insert_before': _insert_before,
|
||||
'insert_after': _insert_after}
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
policy_id = client.find_resource(
|
||||
const.FWP, parsed_args.firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
client = self.app.client_manager.network
|
||||
policy_id = client.find_firewall_policy(
|
||||
parsed_args.firewall_policy)['id']
|
||||
body = self.args2body(parsed_args)
|
||||
client.insert_rule_fwaas_firewall_policy(policy_id, body)
|
||||
client.insert_rule_into_policy(policy_id, **body)
|
||||
rule_id = body['firewall_rule_id']
|
||||
policy = parsed_args.firewall_policy
|
||||
print((_('Inserted firewall rule %(rule)s in firewall policy '
|
||||
|
|
@ -253,13 +259,12 @@ class FirewallPolicyRemoveRule(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
policy_id = client.find_resource(
|
||||
const.FWP, parsed_args.firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
client = self.app.client_manager.network
|
||||
policy_id = client.find_firewall_policy(
|
||||
parsed_args.firewall_policy)['id']
|
||||
fwr_id = _get_required_firewall_rule(client, parsed_args)
|
||||
body = {'firewall_rule_id': fwr_id}
|
||||
client.remove_rule_fwaas_firewall_policy(policy_id, body)
|
||||
client.remove_rule_from_policy(policy_id, **body)
|
||||
rule_id = body['firewall_rule_id']
|
||||
policy = parsed_args.firewall_policy
|
||||
print((_('Removed firewall rule %(rule)s from firewall policy '
|
||||
|
|
@ -281,8 +286,8 @@ class ListFirewallPolicy(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_fwaas_firewall_policies()[const.FWPS]
|
||||
client = self.app.client_manager.network
|
||||
obj = client.firewall_policies()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (utils.get_dict_properties(
|
||||
|
|
@ -315,14 +320,13 @@ class SetFirewallPolicy(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fwp_id = client.find_resource(
|
||||
const.FWP, parsed_args.firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
client = self.app.client_manager.network
|
||||
fwp_id = client.find_firewall_policy(
|
||||
parsed_args.firewall_policy)['id']
|
||||
attrs = _get_common_attrs(self.app.client_manager,
|
||||
parsed_args, is_create=False)
|
||||
try:
|
||||
client.update_fwaas_firewall_policy(fwp_id, {const.FWP: attrs})
|
||||
client.update_firewall_policy(fwp_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set firewall policy '%(policy)s': %(e)s")
|
||||
% {'policy': parsed_args.firewall_policy, 'e': e})
|
||||
|
|
@ -341,12 +345,12 @@ class ShowFirewallPolicy(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fwp_id = client.find_resource(const.FWP,
|
||||
parsed_args.firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
obj = client.show_fwaas_firewall_policy(fwp_id)[const.FWP]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
fwp_id = client.find_firewall_policy(
|
||||
parsed_args.firewall_policy)['id']
|
||||
obj = client.get_firewall_policy(fwp_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
|
@ -355,8 +359,7 @@ def _get_required_firewall_rule(client, parsed_args):
|
|||
if not parsed_args.firewall_rule:
|
||||
msg = (_("Firewall rule (name or ID) is required."))
|
||||
raise exceptions.CommandError(msg)
|
||||
return client.find_resource(
|
||||
const.FWR, parsed_args.firewall_rule, cmd_resource=const.CMD_FWR)['id']
|
||||
return client.find_firewall_rule(parsed_args.firewall_rule)['id']
|
||||
|
||||
|
||||
class UnsetFirewallPolicy(command.Command):
|
||||
|
|
@ -392,16 +395,14 @@ class UnsetFirewallPolicy(command.Command):
|
|||
|
||||
def _get_attrs(self, client_manager, parsed_args):
|
||||
attrs = {}
|
||||
client = client_manager.neutronclient
|
||||
client = client_manager.network
|
||||
|
||||
if parsed_args.firewall_rule:
|
||||
current = client.find_resource(
|
||||
const.FWP, parsed_args.firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)[const.FWRS]
|
||||
current = client.find_firewall_policy(
|
||||
parsed_args.firewall_policy)[const.FWRS]
|
||||
removed = []
|
||||
for f in set(parsed_args.firewall_rule):
|
||||
removed.append(client.find_resource(
|
||||
const.FWR, f, cmd_resource=const.CMD_FWR)['id'])
|
||||
removed.append(client.find_firewall_rule(f)['id'])
|
||||
attrs[const.FWRS] = [r for r in current if r not in removed]
|
||||
if parsed_args.all_firewall_rule:
|
||||
attrs[const.FWRS] = []
|
||||
|
|
@ -412,13 +413,12 @@ class UnsetFirewallPolicy(command.Command):
|
|||
return attrs
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fwp_id = client.find_resource(
|
||||
const.FWP, parsed_args.firewall_policy,
|
||||
cmd_resource=const.CMD_FWP)['id']
|
||||
client = self.app.client_manager.network
|
||||
fwp_id = client.find_firewall_policy(
|
||||
parsed_args.firewall_policy)['id']
|
||||
attrs = self._get_attrs(self.app.client_manager, parsed_args)
|
||||
try:
|
||||
client.update_fwaas_firewall_policy(fwp_id, {const.FWP: attrs})
|
||||
client.update_firewall_policy(fwp_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to unset firewall policy '%(policy)s': %(e)s")
|
||||
% {'policy': parsed_args.firewall_policy, 'e': e})
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
import copy
|
||||
import logging
|
||||
|
||||
from cliff import columns as cliff_columns
|
||||
|
|
@ -31,12 +30,34 @@ from neutronclient.osc.v2.fwaas import constants as const
|
|||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'enabled': 'Enabled',
|
||||
'summary': 'Summary',
|
||||
'description': 'Description',
|
||||
'firewall_policy_id': 'Firewall Policy',
|
||||
'ip_version': 'IP Version',
|
||||
'action': 'Action',
|
||||
'protocol': 'Protocol',
|
||||
'source_ip_address': 'Source IP Address',
|
||||
'source_port': 'Source Port',
|
||||
'destination_ip_address': 'Destination IP Address',
|
||||
'destination_port': 'Destination Port',
|
||||
'shared': 'Shared',
|
||||
'source_firewall_group_id': 'Source Firewall Group ID',
|
||||
'destination_firewall_group_id': 'Destination Firewall Group ID',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', column_util.LIST_BOTH),
|
||||
('name', 'Name', column_util.LIST_BOTH),
|
||||
('enabled', 'Enabled', column_util.LIST_BOTH),
|
||||
('summary', 'Summary', column_util.LIST_SHORT_ONLY),
|
||||
('description', 'Description', column_util.LIST_LONG_ONLY),
|
||||
('firewall_policy_id', 'Firewall Policy', column_util.LIST_BOTH),
|
||||
('ip_version', 'IP Version', column_util.LIST_LONG_ONLY),
|
||||
('action', 'Action', column_util.LIST_LONG_ONLY),
|
||||
('protocol', 'Protocol', column_util.LIST_LONG_ONLY),
|
||||
|
|
@ -159,7 +180,7 @@ def _get_common_parser(parser):
|
|||
|
||||
def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
||||
attrs = {}
|
||||
client = client_manager.neutronclient
|
||||
client = client_manager.network
|
||||
if is_create:
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
attrs['tenant_id'] = osc_utils.find_project(
|
||||
|
|
@ -204,15 +225,13 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
if parsed_args.no_share:
|
||||
attrs['shared'] = False
|
||||
if parsed_args.source_firewall_group:
|
||||
attrs['source_firewall_group_id'] = client.find_resource(
|
||||
const.FWG, parsed_args.source_firewall_group,
|
||||
cmd_resource=const.CMD_FWG)['id']
|
||||
attrs['source_firewall_group_id'] = client.find_firewall_group(
|
||||
parsed_args.source_firewall_group)['id']
|
||||
if parsed_args.no_source_firewall_group:
|
||||
attrs['source_firewall_group_id'] = None
|
||||
if parsed_args.destination_firewall_group:
|
||||
attrs['destination_firewall_group_id'] = client.find_resource(
|
||||
const.FWG, parsed_args.destination_firewall_group,
|
||||
cmd_resource=const.CMD_FWG)['id']
|
||||
attrs['destination_firewall_group_id'] = client.find_firewall_group(
|
||||
parsed_args.destination_firewall_group)['id']
|
||||
if parsed_args.no_destination_firewall_group:
|
||||
attrs['destination_firewall_group_id'] = None
|
||||
return attrs
|
||||
|
|
@ -236,11 +255,11 @@ class CreateFirewallRule(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
obj = client.create_fwaas_firewall_rule(
|
||||
{const.FWR: attrs})[const.FWR]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_firewall_rule(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns, formatters=_formatters)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -258,13 +277,12 @@ class DeleteFirewallRule(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for fwr in parsed_args.firewall_rule:
|
||||
try:
|
||||
fwr_id = client.find_resource(
|
||||
const.FWR, fwr, cmd_resource=const.CMD_FWR)['id']
|
||||
client.delete_fwaas_firewall_rule(fwr_id)
|
||||
fwr_id = client.find_firewall_rule(fwr)['id']
|
||||
client.delete_firewall_rule(fwr_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete Firewall rule with "
|
||||
|
|
@ -292,8 +310,8 @@ class ListFirewallRule(command.Lister):
|
|||
return parser
|
||||
|
||||
def extend_list(self, data, parsed_args):
|
||||
ext_data = copy.deepcopy(data)
|
||||
for d in ext_data:
|
||||
ext_data = []
|
||||
for d in data:
|
||||
protocol = d['protocol'].upper() if d['protocol'] else 'ANY'
|
||||
src_ip = 'none specified'
|
||||
dst_ip = 'none specified'
|
||||
|
|
@ -311,11 +329,12 @@ class ListFirewallRule(command.Lister):
|
|||
src = 'source(port): ' + src_ip + src_port
|
||||
dst = 'dest(port): ' + dst_ip + dst_port
|
||||
d['summary'] = ',\n '.join([protocol, src, dst, action])
|
||||
ext_data.append(d)
|
||||
return ext_data
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_fwaas_firewall_rules()[const.FWRS]
|
||||
client = self.app.client_manager.network
|
||||
obj = client.firewall_rules()
|
||||
obj_extend = self.extend_list(obj, parsed_args)
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
|
|
@ -336,14 +355,12 @@ class SetFirewallRule(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager,
|
||||
parsed_args, is_create=False)
|
||||
fwr_id = client.find_resource(
|
||||
const.FWR, parsed_args.firewall_rule,
|
||||
cmd_resource=const.CMD_FWR)['id']
|
||||
fwr_id = client.find_firewall_rule(parsed_args.firewall_rule)['id']
|
||||
try:
|
||||
client.update_fwaas_firewall_rule(fwr_id, {const.FWR: attrs})
|
||||
client.update_firewall_rule(fwr_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set firewall rule '%(rule)s': %(e)s")
|
||||
% {'rule': parsed_args.firewall_rule, 'e': e})
|
||||
|
|
@ -362,12 +379,11 @@ class ShowFirewallRule(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fwr_id = client.find_resource(
|
||||
const.FWR, parsed_args.firewall_rule,
|
||||
cmd_resource=const.CMD_FWR)['id']
|
||||
obj = client.show_fwaas_firewall_rule(fwr_id)[const.FWR]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
fwr_id = client.find_firewall_rule(parsed_args.firewall_rule)['id']
|
||||
obj = client.get_firewall_rule(fwr_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
||||
|
|
@ -440,13 +456,11 @@ class UnsetFirewallRule(command.Command):
|
|||
return attrs
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = self._get_attrs(self.app.client_manager, parsed_args)
|
||||
fwr_id = client.find_resource(
|
||||
const.FWR, parsed_args.firewall_rule,
|
||||
cmd_resource=const.CMD_FWR)['id']
|
||||
fwr_id = client.find_firewall_rule(parsed_args.firewall_rule)['id']
|
||||
try:
|
||||
client.update_fwaas_firewall_rule(fwr_id, {const.FWR: attrs})
|
||||
client.update_firewall_rule(fwr_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to unset firewall rule '%(rule)s': %(e)s")
|
||||
% {'rule': parsed_args.firewall_rule, 'e': e})
|
||||
|
|
|
|||
|
|
@ -58,11 +58,11 @@ def _get_common_parser(parser):
|
|||
enable_group.add_argument(
|
||||
'--enable',
|
||||
action='store_true',
|
||||
help=_('Enable this log (default is disabled)'))
|
||||
help=_('Enable this log'))
|
||||
enable_group.add_argument(
|
||||
'--disable',
|
||||
action='store_true',
|
||||
help=_('Disable this log'))
|
||||
help=_('Disable this log (default is enabled)'))
|
||||
return parser
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,12 @@ from osc_lib.utils import columns as column_util
|
|||
|
||||
from neutronclient._i18n import _
|
||||
from neutronclient.osc import utils as nc_osc_utils
|
||||
from neutronclient.osc.v2.networking_bgpvpn import constants
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
_attr_map = (
|
||||
('id', 'ID', column_util.LIST_BOTH),
|
||||
('tenant_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('name', 'Name', column_util.LIST_BOTH),
|
||||
('type', 'Type', column_util.LIST_BOTH),
|
||||
('route_targets', 'Route Targets', column_util.LIST_LONG_ONLY),
|
||||
|
|
@ -166,7 +165,7 @@ def _args2body(client_manager, id, action, args):
|
|||
args.purge_export_target and args.purge_route_distinguisher) and
|
||||
(args.route_targets or args.import_targets or
|
||||
args.export_targets or args.route_distinguishers)):
|
||||
bgpvpn = client_manager.neutronclient.show_bgpvpn(id)['bgpvpn']
|
||||
bgpvpn = client_manager.network.get_bgpvpn(id)
|
||||
|
||||
attrs = {}
|
||||
|
||||
|
|
@ -221,7 +220,7 @@ def _args2body(client_manager, id, action, args):
|
|||
set(bgpvpn['route_distinguishers']) -
|
||||
set(args.route_distinguishers))
|
||||
|
||||
return {constants.BGPVPN: attrs}
|
||||
return attrs
|
||||
|
||||
|
||||
class CreateBgpvpn(command.ShowOne):
|
||||
|
|
@ -241,7 +240,7 @@ class CreateBgpvpn(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = {}
|
||||
if parsed_args.name is not None:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
|
|
@ -266,9 +265,8 @@ class CreateBgpvpn(command.ShowOne):
|
|||
parsed_args.project_domain,
|
||||
).id
|
||||
attrs['tenant_id'] = project_id
|
||||
body = {constants.BGPVPN: attrs}
|
||||
obj = client.create_bgpvpn(body)[constants.BGPVPN]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_bgpvpn(**attrs)
|
||||
display_columns, columns = nc_osc_utils._get_columns(obj)
|
||||
data = osc_utils.get_dict_properties(obj, columns,
|
||||
formatters=_formatters)
|
||||
return display_columns, data
|
||||
|
|
@ -288,10 +286,10 @@ class SetBgpvpn(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)['id']
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgpvpn(parsed_args.bgpvpn)['id']
|
||||
body = _args2body(self.app.client_manager, id, 'set', parsed_args)
|
||||
client.update_bgpvpn(id, body)
|
||||
client.update_bgpvpn(id, **body)
|
||||
|
||||
|
||||
class UnsetBgpvpn(command.Command):
|
||||
|
|
@ -308,10 +306,10 @@ class UnsetBgpvpn(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)['id']
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgpvpn(parsed_args.bgpvpn)['id']
|
||||
body = _args2body(self.app.client_manager, id, 'unset', parsed_args)
|
||||
client.update_bgpvpn(id, body)
|
||||
client.update_bgpvpn(id, **body)
|
||||
|
||||
|
||||
class DeleteBgpvpn(command.Command):
|
||||
|
|
@ -328,11 +326,11 @@ class DeleteBgpvpn(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
fails = 0
|
||||
for id_or_name in parsed_args.bgpvpns:
|
||||
try:
|
||||
id = client.find_resource(constants.BGPVPN, id_or_name)['id']
|
||||
id = client.find_bgpvpn(id_or_name)['id']
|
||||
client.delete_bgpvpn(id)
|
||||
LOG.warning("BGP VPN %(id)s deleted", {'id': id})
|
||||
except Exception as e:
|
||||
|
|
@ -368,7 +366,7 @@ class ListBgpvpn(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
params = {}
|
||||
if parsed_args.project is not None:
|
||||
project_id = nc_osc_utils.find_project(
|
||||
|
|
@ -379,7 +377,7 @@ class ListBgpvpn(command.Lister):
|
|||
params['tenant_id'] = project_id
|
||||
if parsed_args.property:
|
||||
params.update(parsed_args.property)
|
||||
objs = client.list_bgpvpns(**params)[constants.BGPVPNS]
|
||||
objs = client.bgpvpns(**params)
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (osc_utils.get_dict_properties(
|
||||
|
|
@ -399,10 +397,10 @@ class ShowBgpvpn(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)['id']
|
||||
obj = client.show_bgpvpn(id)[constants.BGPVPN]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
id = client.find_bgpvpn(parsed_args.bgpvpn)['id']
|
||||
obj = client.get_bgpvpn(id)
|
||||
display_columns, columns = nc_osc_utils._get_columns(obj)
|
||||
data = osc_utils.get_dict_properties(obj, columns,
|
||||
formatters=_formatters)
|
||||
return display_columns, data
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ class BgpvpnPortAssoc(object):
|
|||
LOG.warning("Unknown route type %s (%s).", route['type'],
|
||||
route)
|
||||
data.pop('routes', None)
|
||||
return data
|
||||
|
||||
def _get_common_parser(self, parser):
|
||||
"""Adds to parser arguments common to create, set and unset commands.
|
||||
|
|
@ -201,15 +202,13 @@ class BgpvpnPortAssoc(object):
|
|||
)
|
||||
|
||||
def _args2body(self, bgpvpn_id, args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = {}
|
||||
|
||||
if self._action != 'create':
|
||||
assoc = client.find_resource_by_id(
|
||||
self._resource,
|
||||
assoc = client.find_bgpvpn_port_association(
|
||||
args.resource_association_id,
|
||||
cmd_resource='bgpvpn_%s_assoc' % self._assoc_res_name,
|
||||
parent_id=bgpvpn_id)
|
||||
bgpvpn_id=bgpvpn_id)
|
||||
else:
|
||||
assoc = {'routes': []}
|
||||
|
||||
|
|
@ -248,7 +247,7 @@ class BgpvpnPortAssoc(object):
|
|||
else:
|
||||
routes = args.bgpvpn_routes
|
||||
args_bgpvpn_routes = {
|
||||
client.find_resource(constants.BGPVPN, r['bgpvpn'])['id']:
|
||||
client.find_bgpvpn(r['bgpvpn']).id:
|
||||
r.get('local_pref')
|
||||
for r in routes
|
||||
}
|
||||
|
|
@ -281,7 +280,7 @@ class BgpvpnPortAssoc(object):
|
|||
route['local_pref'] = int(local_pref)
|
||||
attrs.setdefault('routes', []).append(route)
|
||||
|
||||
return {self._resource: attrs}
|
||||
return attrs
|
||||
|
||||
|
||||
class CreateBgpvpnPortAssoc(BgpvpnPortAssoc,
|
||||
|
|
|
|||
|
|
@ -56,35 +56,37 @@ class CreateBgpvpnResAssoc(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
create_method = getattr(
|
||||
client, 'create_bgpvpn_%s_assoc' % self._assoc_res_name)
|
||||
bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)
|
||||
assoc_res = client.find_resource(self._assoc_res_name,
|
||||
parsed_args.resource)
|
||||
body = {
|
||||
self._resource: {
|
||||
'%s_id' % self._assoc_res_name: assoc_res['id'],
|
||||
},
|
||||
}
|
||||
client = self.app.client_manager.network
|
||||
bgpvpn = client.find_bgpvpn(parsed_args.bgpvpn)
|
||||
find_res_method = getattr(
|
||||
client, 'find_%s' % self._assoc_res_name)
|
||||
assoc_res = find_res_method(parsed_args.resource)
|
||||
body = {'%s_id' % self._assoc_res_name: assoc_res['id']}
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
project_id = nc_osc_utils.find_project(
|
||||
self.app.client_manager.identity,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain,
|
||||
).id
|
||||
body[self._resource]['tenant_id'] = project_id
|
||||
body['tenant_id'] = project_id
|
||||
|
||||
arg2body = getattr(self, '_args2body', None)
|
||||
if callable(arg2body):
|
||||
body[self._resource].update(
|
||||
arg2body(bgpvpn['id'], parsed_args)[self._resource])
|
||||
body.update(
|
||||
arg2body(bgpvpn['id'], parsed_args))
|
||||
|
||||
obj = create_method(bgpvpn['id'], body)[self._resource]
|
||||
if self._resource == constants.NETWORK_ASSOC:
|
||||
obj = client.create_bgpvpn_network_association(
|
||||
bgpvpn['id'], **body)
|
||||
elif self._resource == constants.PORT_ASSOC:
|
||||
obj = client.create_bgpvpn_port_association(bgpvpn['id'], **body)
|
||||
else:
|
||||
obj = client.create_bgpvpn_router_association(
|
||||
bgpvpn['id'], **body)
|
||||
transform = getattr(self, '_transform_resource', None)
|
||||
if callable(transform):
|
||||
transform(obj)
|
||||
columns, display_columns = column_util.get_columns(obj, self._attr_map)
|
||||
display_columns, columns = nc_osc_utils._get_columns(obj)
|
||||
data = osc_utils.get_dict_properties(obj, columns,
|
||||
formatters=self._formatters)
|
||||
return display_columns, data
|
||||
|
|
@ -116,15 +118,20 @@ class SetBgpvpnResAssoc(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
update_method = getattr(
|
||||
client, 'update_bgpvpn_%s_assoc' % self._assoc_res_name)
|
||||
bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)
|
||||
client = self.app.client_manager.network
|
||||
bgpvpn = client.find_bgpvpn(parsed_args.bgpvpn)
|
||||
arg2body = getattr(self, '_args2body', None)
|
||||
if callable(arg2body):
|
||||
body = arg2body(bgpvpn['id'], parsed_args)
|
||||
update_method(bgpvpn['id'], parsed_args.resource_association_id,
|
||||
body)
|
||||
if self._resource == constants.NETWORK_ASSOC:
|
||||
client.update_bgpvpn_network_association(
|
||||
bgpvpn['id'], parsed_args.resource_association_id, **body)
|
||||
elif self._resource == constants.PORT_ASSOC:
|
||||
client.update_bgpvpn_port_association(
|
||||
bgpvpn['id'], parsed_args.resource_association_id, **body)
|
||||
else:
|
||||
client.update_bgpvpn_router_association(
|
||||
bgpvpn['id'], parsed_args.resource_association_id, **body)
|
||||
|
||||
|
||||
class UnsetBgpvpnResAssoc(SetBgpvpnResAssoc):
|
||||
|
|
@ -153,14 +160,17 @@ class DeleteBgpvpnResAssoc(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
delete_method = getattr(
|
||||
client, 'delete_bgpvpn_%s_assoc' % self._assoc_res_name)
|
||||
bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)
|
||||
client = self.app.client_manager.network
|
||||
bgpvpn = client.find_bgpvpn(parsed_args.bgpvpn)
|
||||
fails = 0
|
||||
for id in parsed_args.resource_association_ids:
|
||||
try:
|
||||
delete_method(bgpvpn['id'], id)
|
||||
if self._resource == constants.NETWORK_ASSOC:
|
||||
client.delete_bgpvpn_network_association(bgpvpn['id'], id)
|
||||
elif self._resource == constants.PORT_ASSOC:
|
||||
client.delete_bgpvpn_port_association(bgpvpn['id'], id)
|
||||
else:
|
||||
client.delete_bgpvpn_router_association(bgpvpn['id'], id)
|
||||
LOG.warning(
|
||||
"%(assoc_res_name)s association %(id)s deleted",
|
||||
{'assoc_res_name': self._assoc_res_name.capitalize(),
|
||||
|
|
@ -206,22 +216,32 @@ class ListBgpvpnResAssoc(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
list_method = getattr(client,
|
||||
'list_bgpvpn_%s_assocs' % self._assoc_res_name)
|
||||
bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)
|
||||
client = self.app.client_manager.network
|
||||
bgpvpn = client.find_bgpvpn(parsed_args.bgpvpn)
|
||||
params = {}
|
||||
if parsed_args.property:
|
||||
params.update(parsed_args.property)
|
||||
objs = list_method(bgpvpn['id'],
|
||||
retrieve_all=True, **params)[self._resource_plural]
|
||||
if self._resource == constants.NETWORK_ASSOC:
|
||||
objs = client.bgpvpn_network_associations(
|
||||
bgpvpn['id'], retrieve_all=True, **params)
|
||||
elif self._resource == constants.PORT_ASSOC:
|
||||
objs = client.bgpvpn_port_associations(
|
||||
bgpvpn['id'], retrieve_all=True, **params)
|
||||
else:
|
||||
objs = client.bgpvpn_router_associations(
|
||||
bgpvpn['id'], retrieve_all=True, **params)
|
||||
transform = getattr(self, '_transform_resource', None)
|
||||
transformed_objs = []
|
||||
if callable(transform):
|
||||
[transform(obj) for obj in objs]
|
||||
for obj in objs:
|
||||
transformed_objs.append(transform(obj))
|
||||
else:
|
||||
transformed_objs = list(objs)
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
self._attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (osc_utils.get_dict_properties(
|
||||
s, columns, formatters=self._formatters) for s in objs))
|
||||
s, columns, formatters=self._formatters)
|
||||
for s in transformed_objs))
|
||||
|
||||
|
||||
class ShowBgpvpnResAssoc(command.ShowOne):
|
||||
|
|
@ -243,20 +263,21 @@ class ShowBgpvpnResAssoc(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
show_method = getattr(client,
|
||||
'show_bgpvpn_%s_assoc' % self._assoc_res_name)
|
||||
bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)
|
||||
assoc = client.find_resource_by_id(
|
||||
self._resource,
|
||||
parsed_args.resource_association_id,
|
||||
cmd_resource='bgpvpn_%s_assoc' % self._assoc_res_name,
|
||||
parent_id=bgpvpn['id'])
|
||||
obj = show_method(bgpvpn['id'], assoc['id'])[self._resource]
|
||||
client = self.app.client_manager.network
|
||||
bgpvpn = client.find_bgpvpn(parsed_args.bgpvpn)
|
||||
if self._resource == constants.NETWORK_ASSOC:
|
||||
obj = client.get_bgpvpn_network_association(
|
||||
bgpvpn['id'], parsed_args.resource_association_id)
|
||||
elif self._resource == constants.PORT_ASSOC:
|
||||
obj = client.get_bgpvpn_port_association(
|
||||
bgpvpn['id'], parsed_args.resource_association_id)
|
||||
else:
|
||||
obj = client.get_bgpvpn_router_association(
|
||||
bgpvpn['id'], parsed_args.resource_association_id)
|
||||
transform = getattr(self, '_transform_resource', None)
|
||||
if callable(transform):
|
||||
transform(obj)
|
||||
columns, display_columns = column_util.get_columns(obj, self._attr_map)
|
||||
display_columns, columns = nc_osc_utils._get_columns(obj)
|
||||
data = osc_utils.get_dict_properties(obj, columns,
|
||||
formatters=self._formatters)
|
||||
return display_columns, data
|
||||
|
|
|
|||
|
|
@ -75,14 +75,13 @@ class BgpvpnRouterAssoc(object):
|
|||
)
|
||||
|
||||
def _args2body(self, _, args):
|
||||
attrs = {}
|
||||
|
||||
attrs = {'advertise_extra_routes': False}
|
||||
if args.advertise_extra_routes:
|
||||
attrs['advertise_extra_routes'] = self._action != 'unset'
|
||||
elif args.no_advertise_extra_routes:
|
||||
attrs['advertise_extra_routes'] = self._action == 'unset'
|
||||
|
||||
return {self._resource: attrs}
|
||||
return attrs
|
||||
|
||||
|
||||
class CreateBgpvpnRouterAssoc(BgpvpnRouterAssoc, CreateBgpvpnResAssoc):
|
||||
|
|
|
|||
|
|
@ -55,6 +55,26 @@ _attr_map = (
|
|||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'description': 'Description',
|
||||
'summary': 'Summary',
|
||||
'protocol': 'Protocol',
|
||||
'ethertype': 'Ethertype',
|
||||
'source_ip_prefix': 'Source IP',
|
||||
'destination_ip_prefix': 'Destination IP',
|
||||
'logical_source_port': 'Logical Source Port',
|
||||
'logical_destination_port': 'Logical Destination Port',
|
||||
'source_port_range_min': 'Source Port Range Min',
|
||||
'source_port_range_max': 'Source Port Range Max',
|
||||
'destination_port_range_min': 'Destination Port Range Min',
|
||||
'destination_port_range_max': 'Destination Port Range Max',
|
||||
'l7_parameters': 'L7 Parameters',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
|
||||
class CreateSfcFlowClassifier(command.ShowOne):
|
||||
_description = _("Create a flow classifier")
|
||||
|
|
@ -114,11 +134,11 @@ class CreateSfcFlowClassifier(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
body = {resource: attrs}
|
||||
obj = client.create_sfc_flow_classifier(body)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_sfc_flow_classifier(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id', 'summary'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -131,20 +151,27 @@ class DeleteSfcFlowClassifier(command.Command):
|
|||
parser.add_argument(
|
||||
'flow_classifier',
|
||||
metavar='<flow-classifier>',
|
||||
help=_("Flow classifier to delete (name or ID)")
|
||||
nargs='+',
|
||||
help=_("Flow classifier(s) to delete (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
# TODO(mohan): Add support for deleting multiple resources.
|
||||
client = self.app.client_manager.neutronclient
|
||||
fc_id = _get_id(client, parsed_args.flow_classifier, resource)
|
||||
try:
|
||||
client.delete_sfc_flow_classifier(fc_id)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to delete flow classifier with name "
|
||||
"or ID '%(fc)s': %(e)s")
|
||||
% {'fc': parsed_args.flow_classifier, 'e': e})
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for fcl in parsed_args.flow_classifier:
|
||||
try:
|
||||
fc_id = client.find_sfc_flow_classifier(
|
||||
fcl, ignore_missing=False)['id']
|
||||
client.delete_sfc_flow_classifier(fc_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete flow classifier with name "
|
||||
"or ID '%(fc)s': %(e)s"), {'fc': fcl, 'e': e})
|
||||
if result > 0:
|
||||
total = len(parsed_args.flow_classifier)
|
||||
msg = (_("%(result)s of %(total)s flow classifier(s) "
|
||||
"failed to delete.") % {'result': result, 'total': total})
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
|
|
@ -161,8 +188,8 @@ class ListSfcFlowClassifier(command.Lister):
|
|||
return parser
|
||||
|
||||
def extend_list(self, data, parsed_args):
|
||||
ext_data = data['flow_classifiers']
|
||||
for d in ext_data:
|
||||
ext_data = []
|
||||
for d in data:
|
||||
val = []
|
||||
protocol = d['protocol'].upper() if d['protocol'] else 'any'
|
||||
val.append('protocol: ' + protocol)
|
||||
|
|
@ -180,6 +207,7 @@ class ListSfcFlowClassifier(command.Lister):
|
|||
l7_param = 'l7_parameters: {%s}' % ','.join(d['l7_parameters'])
|
||||
val.append(l7_param)
|
||||
d['summary'] = ',\n'.join(val)
|
||||
ext_data.append(d)
|
||||
return ext_data
|
||||
|
||||
def _get_protocol_port_details(self, data, val):
|
||||
|
|
@ -197,8 +225,8 @@ class ListSfcFlowClassifier(command.Lister):
|
|||
val, ip_prefix, min_port, max_port)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_sfc_flow_classifiers()
|
||||
client = self.app.client_manager.network
|
||||
obj = client.sfc_flow_classifiers()
|
||||
obj_extend = self.extend_list(obj, parsed_args)
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
|
|
@ -227,13 +255,13 @@ class SetSfcFlowClassifier(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fc_id = _get_id(client, parsed_args.flow_classifier, resource)
|
||||
client = self.app.client_manager.network
|
||||
fc_id = client.find_sfc_flow_classifier(parsed_args.flow_classifier,
|
||||
ignore_missing=False)['id']
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args,
|
||||
is_create=False)
|
||||
body = {resource: attrs}
|
||||
try:
|
||||
client.update_sfc_flow_classifier(fc_id, body)
|
||||
client.update_sfc_flow_classifier(fc_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to update flow classifier '%(fc)s': %(e)s")
|
||||
% {'fc': parsed_args.flow_classifier, 'e': e})
|
||||
|
|
@ -253,10 +281,12 @@ class ShowSfcFlowClassifier(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
fc_id = _get_id(client, parsed_args.flow_classifier, resource)
|
||||
obj = client.show_sfc_flow_classifier(fc_id)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
fc_id = client.find_sfc_flow_classifier(parsed_args.flow_classifier,
|
||||
ignore_missing=False)['id']
|
||||
obj = client.get_sfc_flow_classifier(fc_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id', 'summary'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -282,13 +312,13 @@ def _get_attrs(client_manager, attrs, parsed_args):
|
|||
if parsed_args.destination_ip_prefix is not None:
|
||||
attrs['destination_ip_prefix'] = parsed_args.destination_ip_prefix
|
||||
if parsed_args.logical_source_port is not None:
|
||||
attrs['logical_source_port'] = _get_id(
|
||||
client_manager.neutronclient, parsed_args.logical_source_port,
|
||||
'port')
|
||||
attrs['logical_source_port'] = client_manager.network.find_port(
|
||||
parsed_args.logical_source_port, ignore_missing=False
|
||||
)['id']
|
||||
if parsed_args.logical_destination_port is not None:
|
||||
attrs['logical_destination_port'] = _get_id(
|
||||
client_manager.neutronclient, parsed_args.logical_destination_port,
|
||||
'port')
|
||||
attrs['logical_destination_port'] = client_manager.network.find_port(
|
||||
parsed_args.logical_destination_port, ignore_missing=False
|
||||
)['id']
|
||||
if parsed_args.source_port is not None:
|
||||
_fill_protocol_port_info(attrs, 'source',
|
||||
parsed_args.source_port)
|
||||
|
|
@ -314,7 +344,3 @@ def _fill_protocol_port_info(attrs, port_type, port_val):
|
|||
message = (_("Protocol port value %s must be an integer "
|
||||
"or integer:integer.") % port_val)
|
||||
raise nc_exc.CommandError(message=message)
|
||||
|
||||
|
||||
def _get_id(client, id_or_name, resource):
|
||||
return client.find_resource(resource, id_or_name)['id']
|
||||
|
|
|
|||
|
|
@ -36,10 +36,20 @@ _attr_map = (
|
|||
('chain_parameters', 'Chain Parameters',
|
||||
column_util.LIST_BOTH),
|
||||
('description', 'Description', column_util.LIST_LONG_ONLY),
|
||||
('chain_id', 'Chain ID', column_util.LIST_BOTH),
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'port_pair_groups': 'Port Pair Groups',
|
||||
'flow_classifiers': 'Flow Classifiers',
|
||||
'chain_parameters': 'Chain Parameters',
|
||||
'description': 'Description',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
|
||||
class CreateSfcPortChain(command.ShowOne):
|
||||
_description = _("Create a port chain")
|
||||
|
|
@ -81,11 +91,11 @@ class CreateSfcPortChain(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
body = {resource: attrs}
|
||||
obj = client.create_sfc_port_chain(body)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_sfc_port_chain(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -98,20 +108,28 @@ class DeleteSfcPortChain(command.Command):
|
|||
parser.add_argument(
|
||||
'port_chain',
|
||||
metavar="<port-chain>",
|
||||
help=_("Port chain to delete (name or ID)")
|
||||
nargs='+',
|
||||
help=_("Port chain(s) to delete (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
# TODO(mohan): Add support for deleting multiple resources.
|
||||
client = self.app.client_manager.neutronclient
|
||||
pc_id = _get_id(client, parsed_args.port_chain, resource)
|
||||
try:
|
||||
client.delete_sfc_port_chain(pc_id)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to delete port chain with name "
|
||||
"or ID '%(pc)s': %(e)s")
|
||||
% {'pc': parsed_args.port_chain, 'e': e})
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for pc in parsed_args.port_chain:
|
||||
try:
|
||||
pc_id = client.find_sfc_port_chain(
|
||||
pc, ignore_missing=False)['id']
|
||||
client.delete_sfc_port_chain(pc_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete port chain with name "
|
||||
"or ID '%(pc)s': %(e)s"), {'pc': pc, 'e': e})
|
||||
if result > 0:
|
||||
total = len(parsed_args.port_chain)
|
||||
msg = (_("%(result)s of %(total)s port chain(s) "
|
||||
"failed to delete.") % {'result': result,
|
||||
'total': total})
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
|
|
@ -129,13 +147,13 @@ class ListSfcPortChain(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
data = client.list_sfc_port_chains()
|
||||
client = self.app.client_manager.network
|
||||
data = client.sfc_port_chains()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(s, columns)
|
||||
for s in data['port_chains']))
|
||||
for s in data))
|
||||
|
||||
|
||||
class SetSfcPortChain(command.Command):
|
||||
|
|
@ -184,8 +202,9 @@ class SetSfcPortChain(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
pc_id = _get_id(client, parsed_args.port_chain, resource)
|
||||
client = self.app.client_manager.network
|
||||
pc_id = client.find_sfc_port_chain(parsed_args.port_chain,
|
||||
ignore_missing=False)['id']
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args,
|
||||
is_create=False)
|
||||
if parsed_args.no_flow_classifier:
|
||||
|
|
@ -194,13 +213,14 @@ class SetSfcPortChain(command.Command):
|
|||
if parsed_args.no_flow_classifier:
|
||||
fc_list = []
|
||||
else:
|
||||
fc_list = client.find_resource(
|
||||
resource, parsed_args.port_chain,
|
||||
cmd_resource='sfc_port_chain')['flow_classifiers']
|
||||
fc_list = client.find_sfc_port_chain(
|
||||
parsed_args.port_chain,
|
||||
ignore_missing=False
|
||||
)['flow_classifiers']
|
||||
for fc in parsed_args.flow_classifiers:
|
||||
fc_id = client.find_resource(
|
||||
'flow_classifier', fc,
|
||||
cmd_resource='sfc_flow_classifier')['id']
|
||||
fc_id = client.find_sfc_flow_classifier(
|
||||
fc,
|
||||
ignore_missing=False)['id']
|
||||
if fc_id not in fc_list:
|
||||
fc_list.append(fc_id)
|
||||
attrs['flow_classifiers'] = fc_list
|
||||
|
|
@ -211,27 +231,25 @@ class SetSfcPortChain(command.Command):
|
|||
if parsed_args.no_port_pair_group and parsed_args.port_pair_groups:
|
||||
ppg_list = []
|
||||
for ppg in parsed_args.port_pair_groups:
|
||||
ppg_id = client.find_resource(
|
||||
'port_pair_group', ppg,
|
||||
cmd_resource='sfc_port_pair_group')['id']
|
||||
ppg_id = client.find_sfc_port_pair_group(
|
||||
ppg, ignore_missing=False)['id']
|
||||
if ppg_id not in ppg_list:
|
||||
ppg_list.append(ppg_id)
|
||||
attrs['port_pair_groups'] = ppg_list
|
||||
if (parsed_args.port_pair_groups and
|
||||
not parsed_args.no_port_pair_group):
|
||||
ppg_list = client.find_resource(
|
||||
resource, parsed_args.port_chain,
|
||||
cmd_resource='sfc_port_chain')['port_pair_groups']
|
||||
ppg_list = client.find_sfc_port_chain(
|
||||
parsed_args.port_chain,
|
||||
ignore_missing=False
|
||||
)['port_pair_groups']
|
||||
for ppg in parsed_args.port_pair_groups:
|
||||
ppg_id = client.find_resource(
|
||||
'port_pair_group', ppg,
|
||||
cmd_resource='sfc_port_pair_group')['id']
|
||||
ppg_id = client.find_sfc_port_pair_group(
|
||||
ppg, ignore_missing=False)['id']
|
||||
if ppg_id not in ppg_list:
|
||||
ppg_list.append(ppg_id)
|
||||
attrs['port_pair_groups'] = ppg_list
|
||||
body = {resource: attrs}
|
||||
try:
|
||||
client.update_sfc_port_chain(pc_id, body)
|
||||
client.update_sfc_port_chain(pc_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to update port chain '%(pc)s': %(e)s")
|
||||
% {'pc': parsed_args.port_chain, 'e': e})
|
||||
|
|
@ -251,10 +269,12 @@ class ShowSfcPortChain(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
pc_id = _get_id(client, parsed_args.port_chain, resource)
|
||||
obj = client.show_sfc_port_chain(pc_id)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
pc_id = client.find_sfc_port_chain(parsed_args.port_chain,
|
||||
ignore_missing=False)['id']
|
||||
obj = client.get_sfc_port_chain(pc_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -290,30 +310,31 @@ class UnsetSfcPortChain(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
pc_id = _get_id(client, parsed_args.port_chain, resource)
|
||||
client = self.app.client_manager.network
|
||||
pc_id = client.find_sfc_port_chain(parsed_args.port_chain,
|
||||
ignore_missing=False)['id']
|
||||
attrs = {}
|
||||
if parsed_args.flow_classifiers:
|
||||
fc_list = client.find_resource(
|
||||
resource, parsed_args.port_chain,
|
||||
cmd_resource='sfc_port_chain')['flow_classifiers']
|
||||
fc_list = client.find_sfc_port_chain(
|
||||
parsed_args.port_chain, ignore_missing=False
|
||||
)['flow_classifiers']
|
||||
for fc in parsed_args.flow_classifiers:
|
||||
fc_id = client.find_resource(
|
||||
'flow_classifier', fc,
|
||||
cmd_resource='sfc_flow_classifier')['id']
|
||||
fc_id = client.find_sfc_flow_classifier(
|
||||
fc,
|
||||
ignore_missing=False)['id']
|
||||
if fc_id in fc_list:
|
||||
fc_list.remove(fc_id)
|
||||
attrs['flow_classifiers'] = fc_list
|
||||
if parsed_args.all_flow_classifier:
|
||||
attrs['flow_classifiers'] = []
|
||||
if parsed_args.port_pair_groups:
|
||||
ppg_list = client.find_resource(
|
||||
resource, parsed_args.port_chain,
|
||||
cmd_resource='sfc_port_chain')['port_pair_groups']
|
||||
ppg_list = client.find_sfc_port_chain(
|
||||
parsed_args.port_chain,
|
||||
ignore_missing=False)['port_pair_groups']
|
||||
for ppg in parsed_args.port_pair_groups:
|
||||
ppg_id = client.find_resource(
|
||||
'port_pair_group', ppg,
|
||||
cmd_resource='sfc_port_pair_group')['id']
|
||||
ppg_id = client.find_sfc_port_pair_group(
|
||||
ppg,
|
||||
ignore_missing=False)['id']
|
||||
if ppg_id in ppg_list:
|
||||
ppg_list.remove(ppg_id)
|
||||
if ppg_list == []:
|
||||
|
|
@ -321,9 +342,8 @@ class UnsetSfcPortChain(command.Command):
|
|||
' specified.')
|
||||
raise exceptions.CommandError(message)
|
||||
attrs['port_pair_groups'] = ppg_list
|
||||
body = {resource: attrs}
|
||||
try:
|
||||
client.update_sfc_port_chain(pc_id, body)
|
||||
client.update_sfc_port_chain(pc_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to unset port chain '%(pc)s': %(e)s")
|
||||
% {'pc': parsed_args.port_chain, 'e': e})
|
||||
|
|
@ -332,17 +352,18 @@ class UnsetSfcPortChain(command.Command):
|
|||
|
||||
def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
||||
attrs = {}
|
||||
client = client_manager.network
|
||||
if parsed_args.name is not None:
|
||||
attrs['name'] = parsed_args.name
|
||||
if parsed_args.description is not None:
|
||||
attrs['description'] = parsed_args.description
|
||||
if parsed_args.port_pair_groups:
|
||||
attrs['port_pair_groups'] = [(_get_id(client_manager.neutronclient,
|
||||
ppg, 'port_pair_group'))
|
||||
attrs['port_pair_groups'] = [client.find_sfc_port_pair_group(
|
||||
ppg, ignore_missing=False)['id']
|
||||
for ppg in parsed_args.port_pair_groups]
|
||||
if parsed_args.flow_classifiers:
|
||||
attrs['flow_classifiers'] = [(_get_id(client_manager.neutronclient, fc,
|
||||
'flow_classifier'))
|
||||
attrs['flow_classifiers'] = [client.find_sfc_flow_classifier(
|
||||
fc, ignore_missing=False)['id']
|
||||
for fc in parsed_args.flow_classifiers]
|
||||
if is_create is True:
|
||||
_get_attrs(attrs, parsed_args)
|
||||
|
|
@ -358,7 +379,3 @@ def _get_attrs(attrs, parsed_args):
|
|||
if 'symmetric' in chain_param:
|
||||
chain_params['symmetric'] = chain_param['symmetric']
|
||||
attrs['chain_parameters'] = chain_params
|
||||
|
||||
|
||||
def _get_id(client, id_or_name, resource):
|
||||
return client.find_resource(resource, id_or_name)['id']
|
||||
|
|
|
|||
|
|
@ -38,6 +38,17 @@ _attr_map = (
|
|||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'description': 'Description',
|
||||
'ingress': 'Ingress Logical Port',
|
||||
'egress': 'Egress Logical Port',
|
||||
'service_function_parameters': 'Service Function Parameters',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
|
||||
class CreateSfcPortPair(command.ShowOne):
|
||||
_description = _("Create a port pair")
|
||||
|
|
@ -76,11 +87,11 @@ class CreateSfcPortPair(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
body = {resource: attrs}
|
||||
obj = client.create_sfc_port_pair(body)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_sfc_port_pair(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -93,20 +104,29 @@ class DeleteSfcPortPair(command.Command):
|
|||
parser.add_argument(
|
||||
'port_pair',
|
||||
metavar="<port-pair>",
|
||||
help=_("Port pair to delete (name or ID)")
|
||||
nargs='+',
|
||||
help=_("Port pair(s) to delete (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
# TODO(mohan): Add support for deleting multiple resources.
|
||||
client = self.app.client_manager.neutronclient
|
||||
port_pair_id = _get_id(client, parsed_args.port_pair, resource)
|
||||
try:
|
||||
client.delete_sfc_port_pair(port_pair_id)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to delete port pair with name "
|
||||
"or ID '%(port_pair)s': %(e)s")
|
||||
% {'port_pair': parsed_args.port_pair, 'e': e})
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for pp in parsed_args.port_pair:
|
||||
try:
|
||||
port_pair_id = client.find_sfc_port_pair(
|
||||
pp, ignore_missing=False)['id']
|
||||
client.delete_sfc_port_pair(port_pair_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete port pair with name "
|
||||
"or ID '%(port_pair)s': %(e)s"),
|
||||
{'port_pair': pp, 'e': e})
|
||||
if result > 0:
|
||||
total = len(parsed_args.port_pair)
|
||||
msg = (_("%(result)s of %(total)s port pair(s) "
|
||||
"failed to delete.") % {'result': result,
|
||||
'total': total})
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
|
|
@ -123,14 +143,14 @@ class ListSfcPortPair(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
data = client.list_sfc_port_pairs()
|
||||
client = self.app.client_manager.network
|
||||
data = client.sfc_port_pairs()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data['port_pairs']))
|
||||
) for s in data))
|
||||
|
||||
|
||||
class SetSfcPortPair(command.Command):
|
||||
|
|
@ -154,13 +174,14 @@ class SetSfcPortPair(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
port_pair_id = _get_id(client, parsed_args.port_pair, resource)
|
||||
client = self.app.client_manager.network
|
||||
port_pair_id = client.find_sfc_port_pair(
|
||||
parsed_args.port_pair, ignore_missing=False
|
||||
)['id']
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args,
|
||||
is_create=False)
|
||||
body = {resource: attrs}
|
||||
try:
|
||||
client.update_sfc_port_pair(port_pair_id, body)
|
||||
client.update_sfc_port_pair(port_pair_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to update port pair '%(port_pair)s': %(e)s")
|
||||
% {'port_pair': parsed_args.port_pair, 'e': e})
|
||||
|
|
@ -180,10 +201,13 @@ class ShowSfcPortPair(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
port_pair_id = _get_id(client, parsed_args.port_pair, resource)
|
||||
obj = client.show_sfc_port_pair(port_pair_id)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
port_pair_id = client.find_sfc_port_pair(
|
||||
parsed_args.port_pair, ignore_missing=False
|
||||
)['id']
|
||||
obj = client.get_sfc_port_pair(port_pair_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -200,12 +224,15 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
|
||||
|
||||
def _get_attrs(client_manager, attrs, parsed_args):
|
||||
client = client_manager.network
|
||||
if parsed_args.ingress is not None:
|
||||
attrs['ingress'] = _get_id(client_manager.neutronclient,
|
||||
parsed_args.ingress, 'port')
|
||||
attrs['ingress'] = client.find_port(
|
||||
parsed_args.ingress, ignore_missing=False
|
||||
)['id']
|
||||
if parsed_args.egress is not None:
|
||||
attrs['egress'] = _get_id(client_manager.neutronclient,
|
||||
parsed_args.egress, 'port')
|
||||
attrs['egress'] = client.find_port(
|
||||
parsed_args.egress, ignore_missing=False
|
||||
)['id']
|
||||
if parsed_args.service_function_parameters is not None:
|
||||
attrs['service_function_parameters'] = _get_service_function_params(
|
||||
parsed_args.service_function_parameters)
|
||||
|
|
@ -222,7 +249,3 @@ def _get_service_function_params(sf_params):
|
|||
if 'weight' in sf_param:
|
||||
attrs['weight'] = sf_param['weight']
|
||||
return attrs
|
||||
|
||||
|
||||
def _get_id(client, id_or_name, resource):
|
||||
return client.find_resource(resource, id_or_name)['id']
|
||||
|
|
|
|||
|
|
@ -34,11 +34,21 @@ _attr_map = (
|
|||
('port_pair_group_parameters', 'Port Pair Group Parameters',
|
||||
column_util.LIST_BOTH),
|
||||
('description', 'Description', column_util.LIST_LONG_ONLY),
|
||||
('group_id', 'Loadbalance ID', column_util.LIST_LONG_ONLY),
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('tap_enabled', 'Tap Enabled', column_util.LIST_BOTH)
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('is_tap_enabled', 'Tap Enabled', column_util.LIST_BOTH)
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'description': 'Description',
|
||||
'port_pairs': 'Port Pair',
|
||||
'port_pair_group_parameters': 'Port Pair Group Parameters',
|
||||
'is_tap_enabled': 'Tap Enabled',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
|
||||
class CreateSfcPortPairGroup(command.ShowOne):
|
||||
_description = _("Create a port pair group")
|
||||
|
|
@ -85,11 +95,11 @@ class CreateSfcPortPairGroup(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
body = {resource: attrs}
|
||||
obj = client.create_sfc_port_pair_group(body)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_sfc_port_pair_group(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -102,20 +112,28 @@ class DeleteSfcPortPairGroup(command.Command):
|
|||
parser.add_argument(
|
||||
'port_pair_group',
|
||||
metavar='<port-pair-group>',
|
||||
help=_("Port pair group to delete (name or ID)")
|
||||
nargs='+',
|
||||
help=_("Port pair group(s) to delete (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
# TODO(mohan): Add support for deleting multiple resources.
|
||||
client = self.app.client_manager.neutronclient
|
||||
ppg_id = _get_id(client, parsed_args.port_pair_group, resource)
|
||||
try:
|
||||
client.delete_sfc_port_pair_group(ppg_id)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to delete port pair group with name "
|
||||
"or ID '%(ppg)s': %(e)s")
|
||||
% {'ppg': parsed_args.port_pair_group, 'e': e})
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for ppg in parsed_args.port_pair_group:
|
||||
try:
|
||||
ppg_id = client.find_sfc_port_pair_group(
|
||||
ppg, ignore_missing=False)['id']
|
||||
client.delete_sfc_port_pair_group(ppg_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete port pair group with name "
|
||||
"or ID '%(ppg)s': %(e)s"), {'ppg': ppg, 'e': e})
|
||||
if result > 0:
|
||||
total = len(parsed_args.port_pair_group)
|
||||
msg = (_("%(result)s of %(total)s port pair group(s) "
|
||||
"failed to delete.") % {'result': result,
|
||||
'total': total})
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
|
|
@ -133,14 +151,14 @@ class ListSfcPortPairGroup(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
data = client.list_sfc_port_pair_groups()
|
||||
client = self.app.client_manager.network
|
||||
data = client.sfc_port_pair_groups()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data['port_pair_groups']))
|
||||
) for s in data))
|
||||
|
||||
|
||||
class SetSfcPortPairGroup(command.Command):
|
||||
|
|
@ -175,26 +193,26 @@ class SetSfcPortPairGroup(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
ppg_id = _get_id(client, parsed_args.port_pair_group, resource)
|
||||
client = self.app.client_manager.network
|
||||
ppg_id = client.find_sfc_port_pair_group(
|
||||
parsed_args.port_pair_group)['id']
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args,
|
||||
is_create=False)
|
||||
if parsed_args.no_port_pair:
|
||||
attrs['port_pairs'] = []
|
||||
if parsed_args.port_pairs:
|
||||
added = [client.find_resource('port_pair', pp,
|
||||
cmd_resource='sfc_port_pair')['id']
|
||||
added = [client.find_sfc_port_pair(pp,
|
||||
ignore_missing=False)['id']
|
||||
for pp in parsed_args.port_pairs]
|
||||
if parsed_args.no_port_pair:
|
||||
existing = []
|
||||
else:
|
||||
existing = client.find_resource(
|
||||
resource, parsed_args.port_pair_group,
|
||||
cmd_resource='sfc_port_pair_group')['port_pairs']
|
||||
existing = client.find_sfc_port_pair_group(
|
||||
parsed_args.port_pair_group,
|
||||
ignore_missing=False)['port_pairs']
|
||||
attrs['port_pairs'] = sorted(list(set(existing) | set(added)))
|
||||
body = {resource: attrs}
|
||||
try:
|
||||
client.update_sfc_port_pair_group(ppg_id, body)
|
||||
client.update_sfc_port_pair_group(ppg_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to update port pair group '%(ppg)s': %(e)s")
|
||||
% {'ppg': parsed_args.port_pair_group, 'e': e})
|
||||
|
|
@ -214,10 +232,12 @@ class ShowSfcPortPairGroup(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
ppg_id = _get_id(client, parsed_args.port_pair_group, resource)
|
||||
obj = client.show_sfc_port_pair_group(ppg_id)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
ppg_id = client.find_sfc_port_pair_group(
|
||||
parsed_args.port_pair_group, ignore_missing=False)['id']
|
||||
obj = client.get_sfc_port_pair_group(ppg_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -246,22 +266,22 @@ class UnsetSfcPortPairGroup(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
ppg_id = _get_id(client, parsed_args.port_pair_group, resource)
|
||||
client = self.app.client_manager.network
|
||||
ppg_id = client.find_sfc_port_pair_group(
|
||||
parsed_args.port_pair_group, ignore_missing=False)['id']
|
||||
attrs = {}
|
||||
if parsed_args.port_pairs:
|
||||
existing = client.find_resource(
|
||||
resource, parsed_args.port_pair_group,
|
||||
cmd_resource='sfc_port_pair_group')['port_pairs']
|
||||
removed = [client.find_resource('port_pair', pp,
|
||||
cmd_resource='sfc_port_pair')['id']
|
||||
existing = client.find_sfc_port_pair_group(
|
||||
parsed_args.port_pair_group,
|
||||
ignore_missing=False)['port_pairs']
|
||||
removed = [client.find_sfc_port_pair(pp,
|
||||
ignore_missing=False)['id']
|
||||
for pp in parsed_args.port_pairs]
|
||||
attrs['port_pairs'] = list(set(existing) - set(removed))
|
||||
if parsed_args.all_port_pair:
|
||||
attrs['port_pairs'] = []
|
||||
body = {resource: attrs}
|
||||
try:
|
||||
client.update_sfc_port_pair_group(ppg_id, body)
|
||||
client.update_sfc_port_pair_group(ppg_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to unset port pair group '%(ppg)s': %(e)s")
|
||||
% {'ppg': parsed_args.port_pair_group, 'e': e})
|
||||
|
|
@ -280,15 +300,17 @@ def _get_ppg_param(attrs, ppg):
|
|||
|
||||
|
||||
def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
||||
client = client_manager.network
|
||||
attrs = {}
|
||||
if parsed_args.name is not None:
|
||||
attrs['name'] = parsed_args.name
|
||||
if parsed_args.description is not None:
|
||||
attrs['description'] = parsed_args.description
|
||||
if parsed_args.port_pairs:
|
||||
attrs['port_pairs'] = [(_get_id(client_manager.neutronclient, pp,
|
||||
'port_pair'))
|
||||
attrs['port_pairs'] = [client.find_sfc_port_pair(
|
||||
pp, ignore_missing=False)['id']
|
||||
for pp in parsed_args.port_pairs]
|
||||
|
||||
if is_create:
|
||||
_get_attrs(attrs, parsed_args)
|
||||
return attrs
|
||||
|
|
@ -302,7 +324,3 @@ def _get_attrs(attrs, parsed_args):
|
|||
attrs['tap_enabled'] = True
|
||||
if parsed_args.disable_tap:
|
||||
attrs['tap_enabled'] = False
|
||||
|
||||
|
||||
def _get_id(client, id_or_name, resource):
|
||||
return client.find_resource(resource, id_or_name)['id']
|
||||
|
|
|
|||
|
|
@ -33,6 +33,15 @@ _attr_map = (
|
|||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'description': 'Description',
|
||||
'port_chains': 'Branching Points',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
|
||||
class CreateSfcServiceGraph(command.ShowOne):
|
||||
"""Create a service graph."""
|
||||
|
|
@ -57,12 +66,13 @@ class CreateSfcServiceGraph(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
try:
|
||||
body = {resource: attrs}
|
||||
obj = client.create_sfc_service_graph(body)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_sfc_service_graph(**attrs)
|
||||
display_columns, columns = \
|
||||
utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
except Exception as e:
|
||||
|
|
@ -92,13 +102,13 @@ class SetSfcServiceGraph(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
service_graph_id = _get_id(client, parsed_args.service_graph, resource)
|
||||
client = self.app.client_manager.network
|
||||
service_graph_id = client.find_sfc_service_graph(
|
||||
parsed_args.service_graph, ignore_missing=False)['id']
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args,
|
||||
is_create=False)
|
||||
body = {resource: attrs}
|
||||
try:
|
||||
client.update_sfc_service_graph(service_graph_id, body)
|
||||
client.update_sfc_service_graph(service_graph_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to update service graph "
|
||||
"'%(service_graph)s': %(e)s")
|
||||
|
|
@ -114,14 +124,30 @@ class DeleteSfcServiceGraph(command.Command):
|
|||
parser.add_argument(
|
||||
'service_graph',
|
||||
metavar="<service-graph>",
|
||||
help=_("ID or name of the service graph to delete.")
|
||||
nargs='+',
|
||||
help=_("ID or name of the service graph(s) to delete.")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
id = _get_id(client, parsed_args.service_graph, resource)
|
||||
client.delete_sfc_service_graph(id)
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for sg in parsed_args.service_graph:
|
||||
try:
|
||||
sg_id = client.find_sfc_service_graph(
|
||||
sg, ignore_missing=False)['id']
|
||||
client.delete_sfc_service_graph(sg_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete service graph with name "
|
||||
"or ID '%(sg)s': %(e)s"),
|
||||
{'sg': sg, 'e': e})
|
||||
if result > 0:
|
||||
total = len(parsed_args.service_graph)
|
||||
msg = (_("%(result)s of %(total)s service graph(s) "
|
||||
"failed to delete.") % {'result': result,
|
||||
'total': total})
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
class ListSfcServiceGraph(command.Lister):
|
||||
|
|
@ -138,13 +164,13 @@ class ListSfcServiceGraph(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
data = client.list_sfc_service_graphs()
|
||||
client = self.app.client_manager.network
|
||||
data = client.sfc_service_graphs()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers,
|
||||
(utils.get_dict_properties(s, columns)
|
||||
for s in data['service_graphs']))
|
||||
for s in data))
|
||||
|
||||
|
||||
class ShowSfcServiceGraph(command.ShowOne):
|
||||
|
|
@ -160,10 +186,12 @@ class ShowSfcServiceGraph(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
sg_id = _get_id(client, parsed_args.service_graph, resource)
|
||||
obj = client.show_sfc_service_graph(sg_id)[resource]
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
sg_id = client.find_sfc_service_graph(parsed_args.service_graph,
|
||||
ignore_missing=False)['id']
|
||||
obj = client.get_sfc_service_graph(sg_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -179,14 +207,14 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
return attrs
|
||||
|
||||
|
||||
def _validate_destination_chains(comma_split, attrs, client_manager, sc_):
|
||||
def _validate_destination_chains(comma_split, attrs, client, sc_):
|
||||
for e in comma_split:
|
||||
if e != "":
|
||||
dc_ = _get_id(client_manager.neutronclient, e, 'port_chain')
|
||||
dc_ = client.find_sfc_port_chain(e, ignore_missing=False)['id']
|
||||
attrs['port_chains'][sc_].append(dc_)
|
||||
if _check_cycle(attrs['port_chains'], sc_, dc_):
|
||||
raise(exceptions.CommandError(
|
||||
"Error: Service graph contains a cycle"))
|
||||
raise exceptions.CommandError(
|
||||
"Error: Service graph contains a cycle")
|
||||
else:
|
||||
raise exceptions.CommandError(
|
||||
"Error: you must specify at least one "
|
||||
|
|
@ -214,6 +242,7 @@ def _visit(graph, src, new_dest, new_src):
|
|||
|
||||
|
||||
def _get_attrs_for_create(client_manager, attrs, parsed_args):
|
||||
client = client_manager.network
|
||||
if parsed_args.branching_points:
|
||||
attrs['port_chains'] = {}
|
||||
src_chain = None
|
||||
|
|
@ -224,8 +253,8 @@ def _get_attrs_for_create(client_manager, attrs, parsed_args):
|
|||
"destination chain for each source chain.")
|
||||
colon_split = c.split(':')
|
||||
src_chain = colon_split.pop(0)
|
||||
sc_ = _get_id(client_manager.neutronclient,
|
||||
src_chain, 'port_chain')
|
||||
sc_ = client.find_sfc_port_chain(src_chain,
|
||||
ignore_missing=False)['id']
|
||||
for i in colon_split:
|
||||
comma_split = i.split(',')
|
||||
unique = set(comma_split)
|
||||
|
|
@ -240,8 +269,4 @@ def _get_attrs_for_create(client_manager, attrs, parsed_args):
|
|||
"use already ".format(src_chain))
|
||||
attrs['port_chains'][sc_] = []
|
||||
_validate_destination_chains(
|
||||
comma_split, attrs, client_manager, sc_)
|
||||
|
||||
|
||||
def _get_id(client, id_or_name, resource):
|
||||
return client.find_resource(resource, id_or_name)['id']
|
||||
comma_split, attrs, client, sc_)
|
||||
|
|
|
|||
|
|
@ -1,393 +0,0 @@
|
|||
# Copyright 2016 ZTE Corporation.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
"""Network trunk and subports action implementations"""
|
||||
import logging
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib.cli import parseractions
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils as osc_utils
|
||||
|
||||
from neutronclient._i18n import _
|
||||
from neutronclient.osc import utils as nc_osc_utils
|
||||
from neutronclient.osc.v2 import utils as v2_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
TRUNK = 'trunk'
|
||||
TRUNKS = 'trunks'
|
||||
SUB_PORTS = 'sub_ports'
|
||||
|
||||
|
||||
class CreateNetworkTrunk(command.ShowOne):
|
||||
"""Create a network trunk for a given project"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateNetworkTrunk, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'name',
|
||||
metavar='<name>',
|
||||
help=_("Name of the trunk to create")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_("A description of the trunk")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--parent-port',
|
||||
metavar='<parent-port>',
|
||||
required=True,
|
||||
help=_("Parent port belonging to this trunk (name or ID)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--subport',
|
||||
metavar='<port=,segmentation-type=,segmentation-id=>',
|
||||
action=parseractions.MultiKeyValueAction, dest='add_subports',
|
||||
optional_keys=['segmentation-id', 'segmentation-type'],
|
||||
required_keys=['port'],
|
||||
help=_("Subport to add. Subport is of form "
|
||||
"\'port=<name or ID>,segmentation-type=,segmentation-ID=\' "
|
||||
"(--subport) option can be repeated")
|
||||
)
|
||||
admin_group = parser.add_mutually_exclusive_group()
|
||||
admin_group.add_argument(
|
||||
'--enable',
|
||||
action='store_true',
|
||||
default=True,
|
||||
help=_("Enable trunk (default)")
|
||||
)
|
||||
admin_group.add_argument(
|
||||
'--disable',
|
||||
action='store_true',
|
||||
help=_("Disable trunk")
|
||||
)
|
||||
nc_osc_utils.add_project_owner_option_to_parser(parser)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
attrs = _get_attrs_for_trunk(self.app.client_manager,
|
||||
parsed_args)
|
||||
body = {TRUNK: attrs}
|
||||
obj = client.create_trunk(body)
|
||||
columns = _get_columns(obj[TRUNK])
|
||||
data = osc_utils.get_dict_properties(obj[TRUNK], columns,
|
||||
formatters=_formatters)
|
||||
return columns, data
|
||||
|
||||
|
||||
class DeleteNetworkTrunk(command.Command):
|
||||
"""Delete a given network trunk"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteNetworkTrunk, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'trunk',
|
||||
metavar="<trunk>",
|
||||
nargs="+",
|
||||
help=_("Trunk(s) to delete (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
result = 0
|
||||
for trunk in parsed_args.trunk:
|
||||
try:
|
||||
trunk_id = _get_id(client, trunk, TRUNK)
|
||||
client.delete_trunk(trunk_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete trunk with name "
|
||||
"or ID '%(trunk)s': %(e)s"),
|
||||
{'trunk': trunk, 'e': e})
|
||||
if result > 0:
|
||||
total = len(parsed_args.trunk)
|
||||
msg = (_("%(result)s of %(total)s trunks failed "
|
||||
"to delete.") % {'result': result, 'total': total})
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
class ListNetworkTrunk(command.Lister):
|
||||
"""List all network trunks"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListNetworkTrunk, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--long',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("List additional fields in output")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
data = client.list_trunks()
|
||||
headers = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Parent Port',
|
||||
'Description'
|
||||
)
|
||||
columns = (
|
||||
'id',
|
||||
'name',
|
||||
'port_id',
|
||||
'description'
|
||||
)
|
||||
if parsed_args.long:
|
||||
headers += (
|
||||
'Status',
|
||||
'State',
|
||||
'Created At',
|
||||
'Updated At',
|
||||
)
|
||||
columns += (
|
||||
'status',
|
||||
'admin_state_up',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
)
|
||||
return (headers,
|
||||
(osc_utils.get_dict_properties(
|
||||
s, columns,
|
||||
formatters=_formatters,
|
||||
) for s in data[TRUNKS]))
|
||||
|
||||
|
||||
class SetNetworkTrunk(command.Command):
|
||||
"""Set network trunk properties"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetNetworkTrunk, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'trunk',
|
||||
metavar="<trunk>",
|
||||
help=_("Trunk to modify (name or ID)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
metavar="<name>",
|
||||
help=_("Set trunk name")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_("A description of the trunk")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--subport',
|
||||
metavar='<port=,segmentation-type=,segmentation-id=>',
|
||||
action=parseractions.MultiKeyValueAction, dest='set_subports',
|
||||
optional_keys=['segmentation-id', 'segmentation-type'],
|
||||
required_keys=['port'],
|
||||
help=_("Subport to add. Subport is of form "
|
||||
"\'port=<name or ID>,segmentation-type=,segmentation-ID=\'"
|
||||
"(--subport) option can be repeated")
|
||||
)
|
||||
admin_group = parser.add_mutually_exclusive_group()
|
||||
admin_group.add_argument(
|
||||
'--enable',
|
||||
action='store_true',
|
||||
help=_("Enable trunk")
|
||||
)
|
||||
admin_group.add_argument(
|
||||
'--disable',
|
||||
action='store_true',
|
||||
help=_("Disable trunk")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
trunk_id = _get_id(client, parsed_args.trunk, TRUNK)
|
||||
attrs = _get_attrs_for_trunk(self.app.client_manager, parsed_args)
|
||||
body = {TRUNK: attrs}
|
||||
try:
|
||||
client.update_trunk(trunk_id, body)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set trunk '%(t)s': %(e)s")
|
||||
% {'t': parsed_args.trunk, 'e': e})
|
||||
raise exceptions.CommandError(msg)
|
||||
if parsed_args.set_subports:
|
||||
subport_attrs = _get_attrs_for_subports(self.app.client_manager,
|
||||
parsed_args)
|
||||
try:
|
||||
client.trunk_add_subports(trunk_id, subport_attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to add subports to trunk '%(t)s': %(e)s")
|
||||
% {'t': parsed_args.trunk, 'e': e})
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
class ShowNetworkTrunk(command.ShowOne):
|
||||
"""Show information of a given network trunk"""
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowNetworkTrunk, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'trunk',
|
||||
metavar="<trunk>",
|
||||
help=_("Trunk to display (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
trunk_id = _get_id(client, parsed_args.trunk, TRUNK)
|
||||
obj = client.show_trunk(trunk_id)
|
||||
columns = _get_columns(obj[TRUNK])
|
||||
data = osc_utils.get_dict_properties(obj[TRUNK], columns,
|
||||
formatters=_formatters)
|
||||
return columns, data
|
||||
|
||||
|
||||
class ListNetworkSubport(command.Lister):
|
||||
"""List all subports for a given network trunk"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListNetworkSubport, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--trunk',
|
||||
required=True,
|
||||
metavar="<trunk>",
|
||||
help=_("List subports belonging to this trunk (name or ID)")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
trunk_id = _get_id(client, parsed_args.trunk, TRUNK)
|
||||
data = client.trunk_get_subports(trunk_id)
|
||||
headers = ('Port', 'Segmentation Type', 'Segmentation ID')
|
||||
columns = ('port_id', 'segmentation_type', 'segmentation_id')
|
||||
return (headers,
|
||||
(osc_utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in data[SUB_PORTS]))
|
||||
|
||||
|
||||
class UnsetNetworkTrunk(command.Command):
|
||||
"""Unset subports from a given network trunk"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UnsetNetworkTrunk, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'trunk',
|
||||
metavar="<trunk>",
|
||||
help=_("Unset subports from this trunk (name or ID)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--subport',
|
||||
metavar="<subport>",
|
||||
required=True,
|
||||
action='append', dest='unset_subports',
|
||||
help=_("Subport to delete (name or ID of the port) "
|
||||
"(--subport) option can be repeated")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
attrs = _get_attrs_for_subports(self.app.client_manager, parsed_args)
|
||||
trunk_id = _get_id(client, parsed_args.trunk, TRUNK)
|
||||
client.trunk_remove_subports(trunk_id, attrs)
|
||||
|
||||
|
||||
_formatters = {
|
||||
'admin_state_up': v2_utils.AdminStateColumn,
|
||||
'sub_ports': format_columns.ListDictColumn,
|
||||
}
|
||||
|
||||
|
||||
def _get_columns(item):
|
||||
return tuple(sorted(list(item.keys())))
|
||||
|
||||
|
||||
def _get_attrs_for_trunk(client_manager, parsed_args):
|
||||
attrs = {}
|
||||
if parsed_args.name is not None:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
if parsed_args.description is not None:
|
||||
attrs['description'] = str(parsed_args.description)
|
||||
if parsed_args.enable:
|
||||
attrs['admin_state_up'] = True
|
||||
if parsed_args.disable:
|
||||
attrs['admin_state_up'] = False
|
||||
if 'parent_port' in parsed_args and parsed_args.parent_port is not None:
|
||||
port_id = _get_id(client_manager.neutronclient,
|
||||
parsed_args.parent_port, 'port')
|
||||
attrs['port_id'] = port_id
|
||||
if 'add_subports' in parsed_args and parsed_args.add_subports is not None:
|
||||
attrs[SUB_PORTS] = _format_subports(client_manager,
|
||||
parsed_args.add_subports)
|
||||
|
||||
# "trunk set" command doesn't support setting project.
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
identity_client = client_manager.identity
|
||||
project_id = nc_osc_utils.find_project(
|
||||
identity_client,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain,
|
||||
).id
|
||||
attrs['tenant_id'] = project_id
|
||||
|
||||
return attrs
|
||||
|
||||
|
||||
def _format_subports(client_manager, subports):
|
||||
attrs = []
|
||||
for subport in subports:
|
||||
subport_attrs = {}
|
||||
if subport.get('port'):
|
||||
port_id = _get_id(client_manager.neutronclient,
|
||||
subport['port'], 'port')
|
||||
subport_attrs['port_id'] = port_id
|
||||
if subport.get('segmentation-id'):
|
||||
try:
|
||||
subport_attrs['segmentation_id'] = int(
|
||||
subport['segmentation-id'])
|
||||
except ValueError:
|
||||
msg = (_("Segmentation-id '%s' is not an integer") %
|
||||
subport['segmentation-id'])
|
||||
raise exceptions.CommandError(msg)
|
||||
if subport.get('segmentation-type'):
|
||||
subport_attrs['segmentation_type'] = subport['segmentation-type']
|
||||
attrs.append(subport_attrs)
|
||||
return attrs
|
||||
|
||||
|
||||
def _get_attrs_for_subports(client_manager, parsed_args):
|
||||
attrs = {}
|
||||
if 'set_subports' in parsed_args and parsed_args.set_subports is not None:
|
||||
attrs[SUB_PORTS] = _format_subports(client_manager,
|
||||
parsed_args.set_subports)
|
||||
if ('unset_subports' in parsed_args and
|
||||
parsed_args.unset_subports is not None):
|
||||
subports_list = []
|
||||
for subport in parsed_args.unset_subports:
|
||||
port_id = _get_id(client_manager.neutronclient,
|
||||
subport, 'port')
|
||||
subports_list.append({'port_id': port_id})
|
||||
attrs[SUB_PORTS] = subports_list
|
||||
return attrs
|
||||
|
||||
|
||||
def _get_id(client, id_or_name, resource):
|
||||
return client.find_resource(resource, str(id_or_name))['id']
|
||||
|
|
@ -32,9 +32,19 @@ _attr_map = (
|
|||
('type', 'Type', column_util.LIST_BOTH),
|
||||
('endpoints', 'Endpoints', column_util.LIST_BOTH),
|
||||
('description', 'Description', column_util.LIST_LONG_ONLY),
|
||||
('tenant_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'type': 'Type',
|
||||
'endpoints': 'Endpoints',
|
||||
'description': 'Description',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
|
||||
def _get_common_parser(parser):
|
||||
parser.add_argument(
|
||||
|
|
@ -83,23 +93,22 @@ class CreateEndpointGroup(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
if parsed_args.name:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
attrs['type'] = parsed_args.type
|
||||
if parsed_args.type == 'subnet':
|
||||
_subnet_ids = [client.find_resource(
|
||||
'subnet',
|
||||
_subnet_ids = [client.find_subnet(
|
||||
endpoint,
|
||||
cmd_resource='subnet')['id']
|
||||
for endpoint in parsed_args.endpoints]
|
||||
ignore_missing=False)['id']
|
||||
for endpoint in parsed_args.endpoints]
|
||||
attrs['endpoints'] = _subnet_ids
|
||||
else:
|
||||
attrs['endpoints'] = parsed_args.endpoints
|
||||
obj = client.create_endpoint_group(
|
||||
{'endpoint_group': attrs})['endpoint_group']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_vpn_endpoint_group(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -117,15 +126,13 @@ class DeleteEndpointGroup(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for endpoint in parsed_args.endpoint_group:
|
||||
try:
|
||||
endpoint_id = client.find_resource(
|
||||
'endpoint_group',
|
||||
endpoint,
|
||||
cmd_resource='endpoint_group')['id']
|
||||
client.delete_endpoint_group(endpoint_id)
|
||||
endpoint_id = client.find_vpn_endpoint_group(
|
||||
endpoint, ignore_missing=False)['id']
|
||||
client.delete_vpn_endpoint_group(endpoint_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete endpoint group with "
|
||||
|
|
@ -153,8 +160,8 @@ class ListEndpointGroup(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_endpoint_groups()['endpoint_groups']
|
||||
client = self.app.client_manager.network
|
||||
obj = client.vpn_endpoint_groups()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (utils.get_dict_properties(s, columns) for s in obj))
|
||||
|
|
@ -177,17 +184,15 @@ class SetEndpointGroup(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager,
|
||||
parsed_args, is_create=False)
|
||||
if parsed_args.name:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
endpoint_id = client.find_resource(
|
||||
'endpoint_group', parsed_args.endpoint_group,
|
||||
cmd_resource='endpoint_group')['id']
|
||||
endpoint_id = client.find_vpn_endpoint_group(
|
||||
parsed_args.endpoint_group, ignore_missing=False)['id']
|
||||
try:
|
||||
client.update_endpoint_group(endpoint_id,
|
||||
{'endpoint_group': attrs})
|
||||
client.update_vpn_endpoint_group(endpoint_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set endpoint group "
|
||||
"%(endpoint_group)s: %(e)s")
|
||||
|
|
@ -207,11 +212,11 @@ class ShowEndpointGroup(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
endpoint_id = client.find_resource(
|
||||
'endpoint_group', parsed_args.endpoint_group,
|
||||
cmd_resource='endpoint_group')['id']
|
||||
obj = client.show_endpoint_group(endpoint_id)['endpoint_group']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
endpoint_id = client.find_vpn_endpoint_group(
|
||||
parsed_args.endpoint_group, ignore_missing=False)['id']
|
||||
obj = client.get_vpn_endpoint_group(endpoint_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return (display_columns, data)
|
||||
|
|
|
|||
|
|
@ -38,10 +38,84 @@ _attr_map = (
|
|||
('description', 'Description', column_util.LIST_LONG_ONLY),
|
||||
('phase1_negotiation_mode', 'Phase1 Negotiation Mode',
|
||||
column_util.LIST_LONG_ONLY),
|
||||
('tenant_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('lifetime', 'Lifetime', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'auth_algorithm': 'Authentication Algorithm',
|
||||
'encryption_algorithm': 'Encryption Algorithm',
|
||||
'ike_version': 'IKE Version',
|
||||
'pfs': 'Perfect Forward Secrecy (PFS)',
|
||||
'phase1_negotiation_mode': 'Phase1 Negotiation Mode',
|
||||
'lifetime': 'Lifetime',
|
||||
'description': 'Description',
|
||||
'tenant_id': 'Project',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
_auth_algorithms = [
|
||||
'sha1',
|
||||
'sha256',
|
||||
'sha384',
|
||||
'sha512',
|
||||
'aes-xcbc',
|
||||
'aes-cmac',
|
||||
]
|
||||
|
||||
_encryption_algorithms = [
|
||||
'3des',
|
||||
'aes-128',
|
||||
'aes-192',
|
||||
'aes-256',
|
||||
'aes-128-ccm-8',
|
||||
'aes-192-ccm-8',
|
||||
'aes-256-ccm-8',
|
||||
'aes-128-ccm-12',
|
||||
'aes-192-ccm-12',
|
||||
'aes-256-ccm-12',
|
||||
'aes-128-ccm-16',
|
||||
'aes-192-ccm-16',
|
||||
'aes-256-ccm-16',
|
||||
'aes-128-gcm-8',
|
||||
'aes-192-gcm-8',
|
||||
'aes-256-gcm-8',
|
||||
'aes-128-gcm-12',
|
||||
'aes-192-gcm-12',
|
||||
'aes-256-gcm-12',
|
||||
'aes-128-gcm-16',
|
||||
'aes-192-gcm-16',
|
||||
'aes-256-gcm-16',
|
||||
'aes-128-ctr',
|
||||
'aes-192-ctr',
|
||||
'aes-256-ctr',
|
||||
]
|
||||
|
||||
_pfs_groups = [
|
||||
'group2',
|
||||
'group5',
|
||||
'group14',
|
||||
'group15',
|
||||
'group16',
|
||||
'group17',
|
||||
'group18',
|
||||
'group19',
|
||||
'group20',
|
||||
'group21',
|
||||
'group22',
|
||||
'group23',
|
||||
'group24',
|
||||
'group25',
|
||||
'group26',
|
||||
'group27',
|
||||
'group28',
|
||||
'group29',
|
||||
'group30',
|
||||
'group31',
|
||||
]
|
||||
|
||||
|
||||
def _convert_to_lowercase(string):
|
||||
return string.lower()
|
||||
|
|
@ -54,17 +128,17 @@ def _get_common_parser(parser):
|
|||
help=_('Description of the IKE policy'))
|
||||
parser.add_argument(
|
||||
'--auth-algorithm',
|
||||
choices=['sha1', 'sha256', 'sha384', 'sha512'],
|
||||
choices=_auth_algorithms,
|
||||
type=_convert_to_lowercase,
|
||||
help=_('Authentication algorithm'))
|
||||
parser.add_argument(
|
||||
'--encryption-algorithm',
|
||||
choices=['aes-128', '3des', 'aes-192', 'aes-256'],
|
||||
choices=_encryption_algorithms,
|
||||
type=_convert_to_lowercase,
|
||||
help=_('Encryption algorithm'))
|
||||
parser.add_argument(
|
||||
'--phase1-negotiation-mode',
|
||||
choices=['main'],
|
||||
choices=['main', 'aggressive'],
|
||||
type=_convert_to_lowercase,
|
||||
help=_('IKE Phase1 negotiation mode'))
|
||||
parser.add_argument(
|
||||
|
|
@ -74,7 +148,7 @@ def _get_common_parser(parser):
|
|||
help=_('IKE version for the policy'))
|
||||
parser.add_argument(
|
||||
'--pfs',
|
||||
choices=['group5', 'group2', 'group14'],
|
||||
choices=_pfs_groups,
|
||||
type=_convert_to_lowercase,
|
||||
help=_('Perfect Forward Secrecy'))
|
||||
parser.add_argument(
|
||||
|
|
@ -89,7 +163,7 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
attrs = {}
|
||||
if is_create:
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
attrs['tenant_id'] = osc_utils.find_project(
|
||||
attrs['project_id'] = osc_utils.find_project(
|
||||
client_manager.identity,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain,
|
||||
|
|
@ -126,12 +200,13 @@ class CreateIKEPolicy(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
if parsed_args.name:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
obj = client.create_ikepolicy({'ikepolicy': attrs})['ikepolicy']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_vpn_ike_policy(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id', 'units', 'value'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -149,13 +224,13 @@ class DeleteIKEPolicy(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for ike in parsed_args.ikepolicy:
|
||||
try:
|
||||
ike_id = client.find_resource(
|
||||
'ikepolicy', ike, cmd_resource='ikepolicy')['id']
|
||||
client.delete_ikepolicy(ike_id)
|
||||
ike_id = client.find_vpn_ike_policy(ike,
|
||||
ignore_missing=False)['id']
|
||||
client.delete_vpn_ike_policy(ike_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete IKE policy with "
|
||||
|
|
@ -182,8 +257,8 @@ class ListIKEPolicy(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_ikepolicies()['ikepolicies']
|
||||
client = self.app.client_manager.network
|
||||
obj = client.vpn_ike_policies()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (utils.get_dict_properties(s, columns) for s in obj))
|
||||
|
|
@ -206,16 +281,15 @@ class SetIKEPolicy(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager,
|
||||
parsed_args, is_create=False)
|
||||
if parsed_args.name:
|
||||
attrs['name'] = parsed_args.name
|
||||
ike_id = client.find_resource(
|
||||
'ikepolicy', parsed_args.ikepolicy,
|
||||
cmd_resource='ikepolicy')['id']
|
||||
ike_id = client.find_vpn_ike_policy(parsed_args.ikepolicy,
|
||||
ignore_missing=False)['id']
|
||||
try:
|
||||
client.update_ikepolicy(ike_id, {'ikepolicy': attrs})
|
||||
client.update_vpn_ike_policy(ike_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set IKE policy '%(ike)s': %(e)s")
|
||||
% {'ike': parsed_args.ikepolicy, 'e': e})
|
||||
|
|
@ -234,11 +308,11 @@ class ShowIKEPolicy(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
ike_id = client.find_resource(
|
||||
'ikepolicy', parsed_args.ikepolicy,
|
||||
cmd_resource='ikepolicy')['id']
|
||||
obj = client.show_ikepolicy(ike_id)['ikepolicy']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
ike_id = client.find_vpn_ike_policy(parsed_args.ikepolicy,
|
||||
ignore_missing=False)['id']
|
||||
obj = client.get_vpn_ike_policy(ike_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id', 'units', 'value'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return (display_columns, data)
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ _attr_map = (
|
|||
('peer_address', 'Peer Address', column_util.LIST_BOTH),
|
||||
('auth_mode', 'Authentication Algorithm', column_util.LIST_BOTH),
|
||||
('status', 'Status', column_util.LIST_BOTH),
|
||||
('tenant_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('peer_cidrs', 'Peer CIDRs', column_util.LIST_LONG_ONLY),
|
||||
('vpnservice_id', 'VPN Service', column_util.LIST_LONG_ONLY),
|
||||
('ipsecpolicy_id', 'IPSec Policy', column_util.LIST_LONG_ONLY),
|
||||
('ikepolicy_id', 'IKE Policy', column_util.LIST_LONG_ONLY),
|
||||
('mtu', 'MTU', column_util.LIST_LONG_ONLY),
|
||||
('initiator', 'Initiator', column_util.LIST_LONG_ONLY),
|
||||
('admin_state_up', 'State', column_util.LIST_LONG_ONLY),
|
||||
('is_admin_state_up', 'State', column_util.LIST_LONG_ONLY),
|
||||
('description', 'Description', column_util.LIST_LONG_ONLY),
|
||||
('psk', 'Pre-shared Key', column_util.LIST_LONG_ONLY),
|
||||
('route_mode', 'Route Mode', column_util.LIST_LONG_ONLY),
|
||||
|
|
@ -57,8 +57,33 @@ _attr_map = (
|
|||
('local_ep_group_id', 'Local Endpoint Group ID',
|
||||
column_util.LIST_LONG_ONLY),
|
||||
('peer_ep_group_id', 'Peer Endpoint Group ID', column_util.LIST_LONG_ONLY),
|
||||
('dpd', 'DPD', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'peer_address': 'Peer Address',
|
||||
'auth_mode': 'Authentication Algorithm',
|
||||
'status': 'Status',
|
||||
'peer_cidrs': 'Peer CIDRs',
|
||||
'vpnservice_id': 'VPN Service',
|
||||
'ipsecpolicy_id': 'IPSec Policy',
|
||||
'ikepolicy_id': 'IKE Policy',
|
||||
'mtu': 'MTU',
|
||||
'initiator': 'Initiator',
|
||||
'is_admin_state_up': 'State',
|
||||
'psk': 'Pre-shared Key',
|
||||
'route_mode': 'Route Mode',
|
||||
'local_id': 'Local ID',
|
||||
'peer_id': 'Peer ID',
|
||||
'local_ep_group_id': 'Local Endpoint Group ID',
|
||||
'peer_ep_group_id': 'Peer Endpoint Group ID',
|
||||
'description': 'Description',
|
||||
'project_id': 'Project',
|
||||
'dpd': 'DPD',
|
||||
}
|
||||
|
||||
|
||||
def _convert_to_lowercase(string):
|
||||
return string.lower()
|
||||
|
|
@ -122,7 +147,7 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
attrs = {}
|
||||
if is_create:
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
attrs['tenant_id'] = osc_utils.find_project(
|
||||
attrs['project_id'] = osc_utils.find_project(
|
||||
client_manager.identity,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain,
|
||||
|
|
@ -141,16 +166,12 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
vpn_utils.validate_dpd_dict(parsed_args.dpd)
|
||||
attrs['dpd'] = parsed_args.dpd
|
||||
if parsed_args.local_endpoint_group:
|
||||
_local_epg = client_manager.neutronclient.find_resource(
|
||||
'endpoint_group',
|
||||
parsed_args.local_endpoint_group,
|
||||
cmd_resource='endpoint_group')['id']
|
||||
_local_epg = client_manager.network.find_vpn_endpoint_group(
|
||||
parsed_args.local_endpoint_group)['id']
|
||||
attrs['local_ep_group_id'] = _local_epg
|
||||
if parsed_args.peer_endpoint_group:
|
||||
_peer_epg = client_manager.neutronclient.find_resource(
|
||||
'endpoint_group',
|
||||
parsed_args.peer_endpoint_group,
|
||||
cmd_resource='endpoint_group')['id']
|
||||
_peer_epg = client_manager.network.find_vpn_endpoint_group(
|
||||
parsed_args.peer_endpoint_group)['id']
|
||||
attrs['peer_ep_group_id'] = _peer_epg
|
||||
if parsed_args.peer_cidrs:
|
||||
attrs['peer_cidrs'] = parsed_args.peer_cidrs
|
||||
|
|
@ -203,25 +224,19 @@ class CreateIPsecSiteConnection(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
if parsed_args.vpnservice:
|
||||
_vpnservice_id = client.find_resource(
|
||||
'vpnservice',
|
||||
parsed_args.vpnservice,
|
||||
cmd_resource='vpnservice')['id']
|
||||
_vpnservice_id = client.find_vpn_service(
|
||||
parsed_args.vpnservice, ignore_missing=False)['id']
|
||||
attrs['vpnservice_id'] = _vpnservice_id
|
||||
if parsed_args.ikepolicy:
|
||||
_ikepolicy_id = client.find_resource(
|
||||
'ikepolicy',
|
||||
parsed_args.ikepolicy,
|
||||
cmd_resource='ikepolicy')['id']
|
||||
_ikepolicy_id = client.find_vpn_ike_policy(
|
||||
parsed_args.ikepolicy, ignore_missing=False)['id']
|
||||
attrs['ikepolicy_id'] = _ikepolicy_id
|
||||
if parsed_args.ipsecpolicy:
|
||||
_ipsecpolicy_id = client.find_resource(
|
||||
'ipsecpolicy',
|
||||
parsed_args.ipsecpolicy,
|
||||
cmd_resource='ipsecpolicy')['id']
|
||||
_ipsecpolicy_id = client.find_vpn_ipsec_policy(
|
||||
parsed_args.ipsecpolicy, ignore_missing=False)['id']
|
||||
attrs['ipsecpolicy_id'] = _ipsecpolicy_id
|
||||
if parsed_args.peer_id:
|
||||
attrs['peer_id'] = parsed_args.peer_id
|
||||
|
|
@ -239,9 +254,10 @@ class CreateIPsecSiteConnection(command.ShowOne):
|
|||
if not parsed_args.peer_cidrs and not parsed_args.local_endpoint_group:
|
||||
message = _("You must specify endpoint groups or peer CIDR(s)")
|
||||
raise exceptions.CommandError(message)
|
||||
obj = client.create_ipsec_site_connection(
|
||||
{'ipsec_site_connection': attrs})['ipsec_site_connection']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_vpn_ipsec_site_connection(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id', 'action',
|
||||
'timeout', 'interval'])
|
||||
data = utils.get_dict_properties(obj, columns, formatters=_formatters)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -259,15 +275,13 @@ class DeleteIPsecSiteConnection(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for ipsec_conn in parsed_args.ipsec_site_connection:
|
||||
try:
|
||||
ipsec_con_id = client.find_resource(
|
||||
'ipsec_site_connection',
|
||||
ipsec_conn,
|
||||
cmd_resource='ipsec_site_connection')['id']
|
||||
client.delete_ipsec_site_connection(ipsec_con_id)
|
||||
ipsec_con_id = client.find_vpn_ipsec_site_connection(
|
||||
ipsec_conn, ignore_missing=False)['id']
|
||||
client.delete_vpn_ipsec_site_connection(ipsec_con_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete IPsec site connection with "
|
||||
|
|
@ -296,8 +310,8 @@ class ListIPsecSiteConnection(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_ipsec_site_connections()['ipsec_site_connections']
|
||||
client = self.app.client_manager.network
|
||||
obj = client.vpn_ipsec_site_connections()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (utils.get_dict_properties(
|
||||
|
|
@ -328,7 +342,7 @@ class SetIPsecSiteConnection(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager,
|
||||
parsed_args, is_create=False)
|
||||
if parsed_args.peer_id:
|
||||
|
|
@ -337,13 +351,10 @@ class SetIPsecSiteConnection(command.Command):
|
|||
attrs['peer_address'] = parsed_args.peer_address
|
||||
if parsed_args.name:
|
||||
attrs['name'] = parsed_args.name
|
||||
ipsec_conn_id = client.find_resource(
|
||||
'ipsec_site_connection', parsed_args.ipsec_site_connection,
|
||||
cmd_resource='ipsec_site_connection')['id']
|
||||
ipsec_conn_id = client.find_vpn_ipsec_site_connection(
|
||||
parsed_args.ipsec_site_connection, ignore_missing=False)['id']
|
||||
try:
|
||||
client.update_ipsec_site_connection(
|
||||
ipsec_conn_id,
|
||||
{'ipsec_site_connection': attrs})
|
||||
client.update_vpn_ipsec_site_connection(ipsec_conn_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set IPsec site "
|
||||
"connection '%(ipsec_conn)s': %(e)s")
|
||||
|
|
@ -363,12 +374,12 @@ class ShowIPsecSiteConnection(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
ipsec_site_id = client.find_resource(
|
||||
'ipsec_site_connection', parsed_args.ipsec_site_connection,
|
||||
cmd_resource='ipsec_site_connection')['id']
|
||||
obj = client.show_ipsec_site_connection(
|
||||
ipsec_site_id)['ipsec_site_connection']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
ipsec_site_id = client.find_vpn_ipsec_site_connection(
|
||||
parsed_args.ipsec_site_connection, ignore_missing=False)['id']
|
||||
obj = client.get_vpn_ipsec_site_connection(ipsec_site_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id', 'action',
|
||||
'timeout', 'interval'])
|
||||
data = utils.get_dict_properties(obj, columns, formatters=_formatters)
|
||||
return (display_columns, data)
|
||||
|
|
|
|||
|
|
@ -37,10 +37,83 @@ _attr_map = (
|
|||
('encryption_algorithm', 'Encryption Algorithm', column_util.LIST_BOTH),
|
||||
('pfs', 'Perfect Forward Secrecy (PFS)', column_util.LIST_LONG_ONLY),
|
||||
('description', 'Description', column_util.LIST_LONG_ONLY),
|
||||
('tenant_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('lifetime', 'Lifetime', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'auth_algorithm': 'Authentication Algorithm',
|
||||
'encapsulation_mode': 'Encapsulation Mode',
|
||||
'transform_protocol': 'Transform Protocol',
|
||||
'encryption_algorithm': 'Encryption Algorithm',
|
||||
'pfs': 'Perfect Forward Secrecy (PFS)',
|
||||
'lifetime': 'Lifetime',
|
||||
'description': 'Description',
|
||||
'project_id': 'Project',
|
||||
}
|
||||
|
||||
_auth_algorithms = [
|
||||
'sha1',
|
||||
'sha256',
|
||||
'sha384',
|
||||
'sha512',
|
||||
'aes-xcbc',
|
||||
'aes-cmac',
|
||||
]
|
||||
|
||||
_encryption_algorithms = [
|
||||
'3des',
|
||||
'aes-128',
|
||||
'aes-192',
|
||||
'aes-256',
|
||||
'aes-128-ccm-8',
|
||||
'aes-192-ccm-8',
|
||||
'aes-256-ccm-8',
|
||||
'aes-128-ccm-12',
|
||||
'aes-192-ccm-12',
|
||||
'aes-256-ccm-12',
|
||||
'aes-128-ccm-16',
|
||||
'aes-192-ccm-16',
|
||||
'aes-256-ccm-16',
|
||||
'aes-128-gcm-8',
|
||||
'aes-192-gcm-8',
|
||||
'aes-256-gcm-8',
|
||||
'aes-128-gcm-12',
|
||||
'aes-192-gcm-12',
|
||||
'aes-256-gcm-12',
|
||||
'aes-128-gcm-16',
|
||||
'aes-192-gcm-16',
|
||||
'aes-256-gcm-16',
|
||||
'aes-128-ctr',
|
||||
'aes-192-ctr',
|
||||
'aes-256-ctr',
|
||||
]
|
||||
|
||||
_pfs_groups = [
|
||||
'group2',
|
||||
'group5',
|
||||
'group14',
|
||||
'group15',
|
||||
'group16',
|
||||
'group17',
|
||||
'group18',
|
||||
'group19',
|
||||
'group20',
|
||||
'group21',
|
||||
'group22',
|
||||
'group23',
|
||||
'group24',
|
||||
'group25',
|
||||
'group26',
|
||||
'group27',
|
||||
'group28',
|
||||
'group29',
|
||||
'group30',
|
||||
'group31',
|
||||
]
|
||||
|
||||
|
||||
def _convert_to_lowercase(string):
|
||||
return string.lower()
|
||||
|
|
@ -53,7 +126,7 @@ def _get_common_parser(parser):
|
|||
help=_('Description of the IPsec policy'))
|
||||
parser.add_argument(
|
||||
'--auth-algorithm',
|
||||
choices=['sha1', 'sha256', 'sha384', 'sha512'],
|
||||
choices=_auth_algorithms,
|
||||
type=_convert_to_lowercase,
|
||||
help=_('Authentication algorithm for IPsec policy'))
|
||||
parser.add_argument(
|
||||
|
|
@ -63,7 +136,7 @@ def _get_common_parser(parser):
|
|||
help=_('Encapsulation mode for IPsec policy'))
|
||||
parser.add_argument(
|
||||
'--encryption-algorithm',
|
||||
choices=['3des', 'aes-128', 'aes-192', 'aes-256'],
|
||||
choices=_encryption_algorithms,
|
||||
type=_convert_to_lowercase,
|
||||
help=_('Encryption algorithm for IPsec policy'))
|
||||
parser.add_argument(
|
||||
|
|
@ -73,7 +146,7 @@ def _get_common_parser(parser):
|
|||
help=vpn_utils.lifetime_help("IPsec"))
|
||||
parser.add_argument(
|
||||
'--pfs',
|
||||
choices=['group2', 'group5', 'group14'],
|
||||
choices=_pfs_groups,
|
||||
type=_convert_to_lowercase,
|
||||
help=_('Perfect Forward Secrecy for IPsec policy'))
|
||||
parser.add_argument(
|
||||
|
|
@ -87,7 +160,7 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
attrs = {}
|
||||
if is_create:
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
attrs['tenant_id'] = osc_utils.find_project(
|
||||
attrs['project_id'] = osc_utils.find_project(
|
||||
client_manager.identity,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain,
|
||||
|
|
@ -124,12 +197,14 @@ class CreateIPsecPolicy(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
if parsed_args.name:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
obj = client.create_ipsecpolicy({'ipsecpolicy': attrs})['ipsecpolicy']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_vpn_ipsec_policy(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id',
|
||||
'phase1_negotiation_mode', 'units', 'value'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -147,13 +222,13 @@ class DeleteIPsecPolicy(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for ipsec in parsed_args.ipsecpolicy:
|
||||
try:
|
||||
ipsec_id = client.find_resource(
|
||||
'ipsecpolicy', ipsec, cmd_resource='ipsecpolicy')['id']
|
||||
client.delete_ipsecpolicy(ipsec_id)
|
||||
ipsec_id = client.find_vpn_ipsec_policy(
|
||||
ipsec, ignore_missing=False)['id']
|
||||
client.delete_vpn_ipsec_policy(ipsec_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete IPsec policy with "
|
||||
|
|
@ -181,8 +256,8 @@ class ListIPsecPolicy(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_ipsecpolicies()['ipsecpolicies']
|
||||
client = self.app.client_manager.network
|
||||
obj = client.vpn_ipsec_policies()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (utils.get_dict_properties(s, columns) for s in obj))
|
||||
|
|
@ -205,16 +280,15 @@ class SetIPsecPolicy(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager,
|
||||
parsed_args, is_create=False)
|
||||
if parsed_args.name:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
ipsec_id = client.find_resource(
|
||||
'ipsecpolicy', parsed_args.ipsecpolicy,
|
||||
cmd_resource='ipsecpolicy')['id']
|
||||
ipsec_id = client.find_vpn_ipsec_policy(
|
||||
parsed_args.ipsecpolicy, ignore_missing=False)['id']
|
||||
try:
|
||||
client.update_ipsecpolicy(ipsec_id, {'ipsecpolicy': attrs})
|
||||
client.update_vpn_ipsec_policy(ipsec_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set IPsec policy '%(ipsec)s': %(e)s")
|
||||
% {'ipsec': parsed_args.ipsecpolicy, 'e': e})
|
||||
|
|
@ -233,11 +307,12 @@ class ShowIPsecPolicy(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
ipsec_id = client.find_resource(
|
||||
'ipsecpolicy', parsed_args.ipsecpolicy,
|
||||
cmd_resource='ipsecpolicy')['id']
|
||||
obj = client.show_ipsecpolicy(ipsec_id)['ipsecpolicy']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
ipsec_id = client.find_vpn_ipsec_policy(
|
||||
parsed_args.ipsecpolicy, ignore_missing=False)['id']
|
||||
obj = client.get_vpn_ipsec_policy(ipsec_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id',
|
||||
'phase1_negotiation_mode', 'units', 'value'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return (display_columns, data)
|
||||
|
|
|
|||
|
|
@ -32,12 +32,28 @@ _attr_map = (
|
|||
('router_id', 'Router', column_util.LIST_BOTH),
|
||||
('subnet_id', 'Subnet', column_util.LIST_BOTH),
|
||||
('flavor_id', 'Flavor', column_util.LIST_BOTH),
|
||||
('admin_state_up', 'State', column_util.LIST_BOTH),
|
||||
('is_admin_state_up', 'State', column_util.LIST_BOTH),
|
||||
('status', 'Status', column_util.LIST_BOTH),
|
||||
('description', 'Description', column_util.LIST_LONG_ONLY),
|
||||
('tenant_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('project_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('external_v4_ip', 'Ext v4 IP', column_util.LIST_LONG_ONLY),
|
||||
('external_v6_ip', 'Ext v6 IP', column_util.LIST_LONG_ONLY),
|
||||
)
|
||||
|
||||
_attr_map_dict = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'router_id': 'Router',
|
||||
'subnet_id': 'Subnet',
|
||||
'flavor_id': 'Flavor',
|
||||
'is_admin_state_up': 'State',
|
||||
'status': 'Status',
|
||||
'description': 'Description',
|
||||
'project_id': 'Project',
|
||||
'external_v4_ip': 'Ext v4 IP',
|
||||
'external_v6_ip': 'Ext v6 IP',
|
||||
}
|
||||
|
||||
|
||||
def _get_common_parser(parser):
|
||||
parser.add_argument(
|
||||
|
|
@ -70,7 +86,7 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True):
|
|||
attrs = {}
|
||||
if is_create:
|
||||
if 'project' in parsed_args and parsed_args.project is not None:
|
||||
attrs['tenant_id'] = osc_utils.find_project(
|
||||
attrs['project_id'] = osc_utils.find_project(
|
||||
client_manager.identity,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain,
|
||||
|
|
@ -113,16 +129,17 @@ class CreateVPNService(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager, parsed_args)
|
||||
if parsed_args.name:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
if parsed_args.router:
|
||||
_router_id = self.app.client_manager.network.find_router(
|
||||
parsed_args.router).id
|
||||
_router_id = client.find_router(parsed_args.router,
|
||||
ignore_missing=False).id
|
||||
attrs['router_id'] = _router_id
|
||||
obj = client.create_vpnservice({'vpnservice': attrs})['vpnservice']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
obj = client.create_vpn_service(**attrs)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return display_columns, data
|
||||
|
||||
|
|
@ -140,13 +157,13 @@ class DeleteVPNService(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
result = 0
|
||||
for vpn in parsed_args.vpnservice:
|
||||
try:
|
||||
vpn_id = client.find_resource(
|
||||
'vpnservice', vpn, cmd_resource='vpnservice')['id']
|
||||
client.delete_vpnservice(vpn_id)
|
||||
vpn_id = client.find_vpn_service(vpn,
|
||||
ignore_missing=False)['id']
|
||||
client.delete_vpn_service(vpn_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete VPN service with "
|
||||
|
|
@ -174,8 +191,8 @@ class ListVPNService(command.Lister):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
obj = client.list_vpnservices()['vpnservices']
|
||||
client = self.app.client_manager.network
|
||||
obj = client.vpn_services()
|
||||
headers, columns = column_util.get_column_definitions(
|
||||
_attr_map, long_listing=parsed_args.long)
|
||||
return (headers, (utils.get_dict_properties(s, columns) for s in obj))
|
||||
|
|
@ -198,16 +215,15 @@ class SetVPNSercice(command.Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_common_attrs(self.app.client_manager,
|
||||
parsed_args, is_create=False)
|
||||
if parsed_args.name:
|
||||
attrs['name'] = str(parsed_args.name)
|
||||
vpn_id = client.find_resource(
|
||||
'vpnservice', parsed_args.vpnservice,
|
||||
cmd_resource='vpnservice')['id']
|
||||
vpn_id = client.find_vpn_service(parsed_args.vpnservice,
|
||||
ignore_missing=False)['id']
|
||||
try:
|
||||
client.update_vpnservice(vpn_id, {'vpnservice': attrs})
|
||||
client.update_vpn_service(vpn_id, **attrs)
|
||||
except Exception as e:
|
||||
msg = (_("Failed to set vpn service '%(vpn)s': %(e)s")
|
||||
% {'vpn': parsed_args.vpnservice, 'e': e})
|
||||
|
|
@ -226,11 +242,11 @@ class ShowVPNService(command.ShowOne):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.neutronclient
|
||||
vpn_id = client.find_resource(
|
||||
'vpnservice', parsed_args.vpnservice,
|
||||
cmd_resource='vpnservice')['id']
|
||||
obj = client.show_vpnservice(vpn_id)['vpnservice']
|
||||
columns, display_columns = column_util.get_columns(obj, _attr_map)
|
||||
client = self.app.client_manager.network
|
||||
vpn_id = client.find_vpn_service(parsed_args.vpnservice,
|
||||
ignore_missing=False)['id']
|
||||
obj = client.get_vpn_service(vpn_id)
|
||||
display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
|
||||
obj, _attr_map_dict, ['location', 'tenant_id'])
|
||||
data = utils.get_dict_properties(obj, columns)
|
||||
return (display_columns, data)
|
||||
|
|
|
|||
|
|
@ -1,654 +0,0 @@
|
|||
# Copyright 2012 OpenStack Foundation.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
"""
|
||||
Command-line interface to the Neutron APIs
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import inspect
|
||||
import itertools
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from keystoneauth1 import session
|
||||
import os_client_config
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import netutils
|
||||
|
||||
from cliff import app
|
||||
from cliff import command
|
||||
from cliff import commandmanager
|
||||
|
||||
from neutronclient._i18n import _
|
||||
from neutronclient.common import clientmanager
|
||||
from neutronclient.common import exceptions as exc
|
||||
from neutronclient.common import extension as client_extension
|
||||
from neutronclient.neutron.v2_0 import subnet
|
||||
from neutronclient.version import __version__
|
||||
|
||||
|
||||
VERSION = '2.0'
|
||||
NEUTRON_API_VERSION = '2.0'
|
||||
|
||||
NAMESPACE_MAP = {NEUTRON_API_VERSION: 'neutron.cli.v2'}
|
||||
|
||||
|
||||
def run_command(cmd, cmd_parser, sub_argv):
|
||||
_argv = sub_argv
|
||||
index = -1
|
||||
values_specs = []
|
||||
if '--' in sub_argv:
|
||||
index = sub_argv.index('--')
|
||||
_argv = sub_argv[:index]
|
||||
values_specs = sub_argv[index:]
|
||||
known_args, _values_specs = cmd_parser.parse_known_args(_argv)
|
||||
if(isinstance(cmd, subnet.CreateSubnet) and not known_args.cidr):
|
||||
cidr = get_first_valid_cidr(_values_specs)
|
||||
if cidr:
|
||||
known_args.cidr = cidr
|
||||
_values_specs.remove(cidr)
|
||||
cmd.values_specs = (index == -1 and _values_specs or values_specs)
|
||||
return cmd.run(known_args)
|
||||
|
||||
|
||||
def get_first_valid_cidr(value_specs):
|
||||
# Bug 1442771, argparse does not allow optional positional parameter
|
||||
# to be separated from previous positional parameter.
|
||||
# When cidr was separated from network, the value will not be able
|
||||
# to be parsed into known_args, but saved to _values_specs instead.
|
||||
for value in value_specs:
|
||||
if netutils.is_valid_cidr(value):
|
||||
return value
|
||||
|
||||
|
||||
def env(*_vars, **kwargs):
|
||||
"""Search for the first defined of possibly many env vars.
|
||||
|
||||
Returns the first environment variable defined in vars, or
|
||||
returns the default defined in kwargs.
|
||||
|
||||
"""
|
||||
for v in _vars:
|
||||
value = os.environ.get(v, None)
|
||||
if value:
|
||||
return value
|
||||
return kwargs.get('default', '')
|
||||
|
||||
|
||||
def check_non_negative_int(value):
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError(_("invalid int value: %r") % value)
|
||||
if value < 0:
|
||||
raise argparse.ArgumentTypeError(_("input value %d is negative") %
|
||||
value)
|
||||
return value
|
||||
|
||||
|
||||
COMMANDS = {}
|
||||
|
||||
|
||||
# NOTE(amotoki): This is only to provide compatibility
|
||||
# to existing neutron CLI extensions. See bug 1706573 for detail.
|
||||
def _set_commands_dict_for_compat(apiversion, command_manager):
|
||||
global COMMANDS
|
||||
COMMANDS = {apiversion: dict((cmd, command_manager.find_command([cmd])[0])
|
||||
for cmd in command_manager.commands)}
|
||||
|
||||
|
||||
class BashCompletionCommand(command.Command):
|
||||
"""Prints all of the commands and options for bash-completion."""
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
pass
|
||||
|
||||
|
||||
class HelpAction(argparse.Action):
|
||||
"""Print help message including sub-commands
|
||||
|
||||
Provide a custom action so the -h and --help options
|
||||
to the main app will print a list of the commands.
|
||||
|
||||
The commands are determined by checking the CommandManager
|
||||
instance, passed in as the "default" value for the action.
|
||||
"""
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
outputs = []
|
||||
max_len = 0
|
||||
app = self.default
|
||||
parser.print_help(app.stdout)
|
||||
app.stdout.write(_('\nCommands for API v%s:\n') % app.api_version)
|
||||
command_manager = app.command_manager
|
||||
for name, ep in sorted(command_manager):
|
||||
factory = ep.load()
|
||||
cmd = factory(self, None)
|
||||
one_liner = cmd.get_description().split('\n')[0]
|
||||
outputs.append((name, one_liner))
|
||||
max_len = max(len(name), max_len)
|
||||
for (name, one_liner) in outputs:
|
||||
app.stdout.write(' %s %s\n' % (name.ljust(max_len), one_liner))
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
class NeutronShell(app.App):
|
||||
|
||||
# verbose logging levels
|
||||
WARNING_LEVEL = 0
|
||||
INFO_LEVEL = 1
|
||||
DEBUG_LEVEL = 2
|
||||
CONSOLE_MESSAGE_FORMAT = '%(message)s'
|
||||
DEBUG_MESSAGE_FORMAT = '%(levelname)s: %(name)s %(message)s'
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def __init__(self, apiversion):
|
||||
namespace = NAMESPACE_MAP[apiversion]
|
||||
description = (__doc__.strip() +
|
||||
" (neutron CLI version: %s)" % __version__)
|
||||
super(NeutronShell, self).__init__(
|
||||
description=description,
|
||||
version=VERSION,
|
||||
command_manager=commandmanager.CommandManager(namespace), )
|
||||
|
||||
self._register_extensions(VERSION)
|
||||
|
||||
# Pop the 'complete' to correct the outputs of 'neutron help'.
|
||||
self.command_manager.commands.pop('complete')
|
||||
|
||||
# This is instantiated in initialize_app() only when using
|
||||
# password flow auth
|
||||
self.auth_client = None
|
||||
self.api_version = apiversion
|
||||
|
||||
_set_commands_dict_for_compat(apiversion, self.command_manager)
|
||||
|
||||
def build_option_parser(self, description, version):
|
||||
"""Return an argparse option parser for this application.
|
||||
|
||||
Subclasses may override this method to extend
|
||||
the parser with more global options.
|
||||
|
||||
:param description: full description of the application
|
||||
:paramtype description: str
|
||||
:param version: version number for the application
|
||||
:paramtype version: str
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description=description,
|
||||
add_help=False, )
|
||||
parser.add_argument(
|
||||
'--version',
|
||||
action='version',
|
||||
version=__version__, )
|
||||
parser.add_argument(
|
||||
'-v', '--verbose', '--debug',
|
||||
action='count',
|
||||
dest='verbose_level',
|
||||
default=self.DEFAULT_VERBOSE_LEVEL,
|
||||
help=_('Increase verbosity of output and show tracebacks on'
|
||||
' errors. You can repeat this option.'))
|
||||
parser.add_argument(
|
||||
'-q', '--quiet',
|
||||
action='store_const',
|
||||
dest='verbose_level',
|
||||
const=0,
|
||||
help=_('Suppress output except warnings and errors.'))
|
||||
parser.add_argument(
|
||||
'-h', '--help',
|
||||
action=HelpAction,
|
||||
nargs=0,
|
||||
default=self, # tricky
|
||||
help=_("Show this help message and exit."))
|
||||
parser.add_argument(
|
||||
'-r', '--retries',
|
||||
metavar="NUM",
|
||||
type=check_non_negative_int,
|
||||
default=0,
|
||||
help=_("How many times the request to the Neutron server should "
|
||||
"be retried if it fails. Defaults to 0."))
|
||||
# FIXME(bklei): this method should come from keystoneauth1
|
||||
self._append_global_identity_args(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def _append_global_identity_args(self, parser):
|
||||
# FIXME(bklei): these are global identity (Keystone) arguments which
|
||||
# should be consistent and shared by all service clients. Therefore,
|
||||
# they should be provided by keystoneauth1. We will need to
|
||||
# refactor this code once this functionality is available in
|
||||
# keystoneauth1.
|
||||
#
|
||||
# Note: At that time we'll need to decide if we can just abandon
|
||||
# the deprecated args (--service-type and --endpoint-type).
|
||||
|
||||
parser.add_argument(
|
||||
'--os-service-type', metavar='<os-service-type>',
|
||||
default=env('OS_NETWORK_SERVICE_TYPE', default='network'),
|
||||
help=_('Defaults to env[OS_NETWORK_SERVICE_TYPE] or "network".'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-endpoint-type', metavar='<os-endpoint-type>',
|
||||
default=env('OS_ENDPOINT_TYPE', default='public'),
|
||||
help=_('Defaults to env[OS_ENDPOINT_TYPE] or "public".'))
|
||||
|
||||
# FIXME(bklei): --service-type is deprecated but kept in for
|
||||
# backward compatibility.
|
||||
parser.add_argument(
|
||||
'--service-type', metavar='<service-type>',
|
||||
default=env('OS_NETWORK_SERVICE_TYPE', default='network'),
|
||||
help=_('DEPRECATED! Use --os-service-type.'))
|
||||
|
||||
# FIXME(bklei): --endpoint-type is deprecated but kept in for
|
||||
# backward compatibility.
|
||||
parser.add_argument(
|
||||
'--endpoint-type', metavar='<endpoint-type>',
|
||||
default=env('OS_ENDPOINT_TYPE', default='public'),
|
||||
help=_('DEPRECATED! Use --os-endpoint-type.'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-auth-strategy', metavar='<auth-strategy>',
|
||||
default=env('OS_AUTH_STRATEGY', default='keystone'),
|
||||
help=_('DEPRECATED! Only keystone is supported.'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os_auth_strategy',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os-cloud', metavar='<cloud>',
|
||||
help=_('Defaults to env[OS_CLOUD].'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-auth-url', metavar='<auth-url>',
|
||||
help=_('Authentication URL, defaults to env[OS_AUTH_URL].'))
|
||||
parser.add_argument(
|
||||
'--os_auth_url',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
project_name_group = parser.add_mutually_exclusive_group()
|
||||
project_name_group.add_argument(
|
||||
'--os-tenant-name', metavar='<auth-tenant-name>',
|
||||
help=_('Authentication tenant name, defaults to '
|
||||
'env[OS_TENANT_NAME].'))
|
||||
project_name_group.add_argument(
|
||||
'--os-project-name',
|
||||
metavar='<auth-project-name>',
|
||||
help=_('Another way to specify tenant name. '
|
||||
'This option is mutually exclusive with '
|
||||
' --os-tenant-name. '
|
||||
'Defaults to env[OS_PROJECT_NAME].'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os_tenant_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
project_id_group = parser.add_mutually_exclusive_group()
|
||||
project_id_group.add_argument(
|
||||
'--os-tenant-id', metavar='<auth-tenant-id>',
|
||||
help=_('Authentication tenant ID, defaults to '
|
||||
'env[OS_TENANT_ID].'))
|
||||
project_id_group.add_argument(
|
||||
'--os-project-id',
|
||||
metavar='<auth-project-id>',
|
||||
help=_('Another way to specify tenant ID. '
|
||||
'This option is mutually exclusive with '
|
||||
' --os-tenant-id. '
|
||||
'Defaults to env[OS_PROJECT_ID].'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-username', metavar='<auth-username>',
|
||||
help=_('Authentication username, defaults to env[OS_USERNAME].'))
|
||||
parser.add_argument(
|
||||
'--os_username',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os-user-id', metavar='<auth-user-id>',
|
||||
help=_('Authentication user ID (Env: OS_USER_ID)'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os_user_id',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os-user-domain-id',
|
||||
metavar='<auth-user-domain-id>',
|
||||
help=_('OpenStack user domain ID. '
|
||||
'Defaults to env[OS_USER_DOMAIN_ID].'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os_user_domain_id',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os-user-domain-name',
|
||||
metavar='<auth-user-domain-name>',
|
||||
help=_('OpenStack user domain name. '
|
||||
'Defaults to env[OS_USER_DOMAIN_NAME].'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os_user_domain_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os_project_id',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os_project_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os-project-domain-id',
|
||||
metavar='<auth-project-domain-id>',
|
||||
help=_('Defaults to env[OS_PROJECT_DOMAIN_ID].'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-project-domain-name',
|
||||
metavar='<auth-project-domain-name>',
|
||||
help=_('Defaults to env[OS_PROJECT_DOMAIN_NAME].'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-cert',
|
||||
metavar='<certificate>',
|
||||
help=_("Path of certificate file to use in SSL "
|
||||
"connection. This file can optionally be "
|
||||
"prepended with the private key. Defaults "
|
||||
"to env[OS_CERT]."))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-cacert',
|
||||
metavar='<ca-certificate>',
|
||||
help=_("Specify a CA bundle file to use in "
|
||||
"verifying a TLS (https) server certificate. "
|
||||
"Defaults to env[OS_CACERT]."))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-key',
|
||||
metavar='<key>',
|
||||
help=_("Path of client key to use in SSL "
|
||||
"connection. This option is not necessary "
|
||||
"if your key is prepended to your certificate "
|
||||
"file. Defaults to env[OS_KEY]."))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-password', metavar='<auth-password>',
|
||||
help=_('Authentication password, defaults to env[OS_PASSWORD].'))
|
||||
parser.add_argument(
|
||||
'--os_password',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os-region-name', metavar='<auth-region-name>',
|
||||
help=_('Authentication region name, defaults to '
|
||||
'env[OS_REGION_NAME].'))
|
||||
parser.add_argument(
|
||||
'--os_region_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os-token', metavar='<token>',
|
||||
help=_('Authentication token, defaults to env[OS_TOKEN].'))
|
||||
parser.add_argument(
|
||||
'--os_token',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--http-timeout', metavar='<seconds>',
|
||||
default=env('OS_NETWORK_TIMEOUT', default=None), type=float,
|
||||
help=_('Timeout in seconds to wait for an HTTP response. Defaults '
|
||||
'to env[OS_NETWORK_TIMEOUT] or None if not specified.'))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-url', metavar='<url>',
|
||||
help=_('Defaults to env[OS_URL].'))
|
||||
parser.add_argument(
|
||||
'--os_url',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--insecure',
|
||||
action='store_true',
|
||||
default=env('NEUTRONCLIENT_INSECURE', default=False),
|
||||
help=_("Explicitly allow neutronclient to perform \"insecure\" "
|
||||
"SSL (https) requests. The server's certificate will "
|
||||
"not be verified against any certificate authorities. "
|
||||
"This option should be used with caution."))
|
||||
|
||||
def _bash_completion(self):
|
||||
"""Prints all of the commands and options for bash-completion."""
|
||||
commands = set()
|
||||
options = set()
|
||||
for option, _action in self.parser._option_string_actions.items():
|
||||
options.add(option)
|
||||
for _name, _command in self.command_manager:
|
||||
commands.add(_name)
|
||||
cmd_factory = _command.load()
|
||||
cmd = cmd_factory(self, None)
|
||||
cmd_parser = cmd.get_parser('')
|
||||
for option, _action in cmd_parser._option_string_actions.items():
|
||||
options.add(option)
|
||||
print(' '.join(commands | options))
|
||||
|
||||
def _register_extensions(self, version):
|
||||
for name, module in itertools.chain(
|
||||
client_extension._discover_via_entry_points()):
|
||||
self._extend_shell_commands(name, module, version)
|
||||
|
||||
def _extend_shell_commands(self, name, module, version):
|
||||
classes = inspect.getmembers(module, inspect.isclass)
|
||||
for cls_name, cls in classes:
|
||||
if (issubclass(cls, client_extension.NeutronClientExtension) and
|
||||
hasattr(cls, 'shell_command')):
|
||||
cmd = cls.shell_command
|
||||
if hasattr(cls, 'versions'):
|
||||
if version not in cls.versions:
|
||||
continue
|
||||
try:
|
||||
name_prefix = "[%s]" % name
|
||||
cls.__doc__ = ("%s %s" % (name_prefix, cls.__doc__) if
|
||||
cls.__doc__ else name_prefix)
|
||||
self.command_manager.add_command(cmd, cls)
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
def run(self, argv):
|
||||
"""Equivalent to the main program for the application.
|
||||
|
||||
:param argv: input arguments and options
|
||||
:paramtype argv: list of str
|
||||
"""
|
||||
try:
|
||||
index = 0
|
||||
command_pos = -1
|
||||
help_pos = -1
|
||||
help_command_pos = -1
|
||||
for arg in argv:
|
||||
if arg == 'bash-completion' and help_command_pos == -1:
|
||||
self._bash_completion()
|
||||
return 0
|
||||
if arg in ('-h', '--help'):
|
||||
if help_pos == -1:
|
||||
help_pos = index
|
||||
# self.command_manager.commands contains 'help',
|
||||
# so we need to check this first.
|
||||
elif arg == 'help':
|
||||
if help_command_pos == -1:
|
||||
help_command_pos = index
|
||||
elif arg in self.command_manager.commands:
|
||||
if command_pos == -1:
|
||||
command_pos = index
|
||||
index = index + 1
|
||||
if command_pos > -1 and help_pos > command_pos:
|
||||
argv = ['help', argv[command_pos]]
|
||||
if help_command_pos > -1 and command_pos == -1:
|
||||
argv[help_command_pos] = '--help'
|
||||
self.options, remainder = self.parser.parse_known_args(argv)
|
||||
self.configure_logging()
|
||||
self.interactive_mode = not remainder
|
||||
self.initialize_app(remainder)
|
||||
except Exception as err:
|
||||
if self.options.verbose_level >= self.DEBUG_LEVEL:
|
||||
self.log.exception(err)
|
||||
raise
|
||||
else:
|
||||
self.log.error(err)
|
||||
return 1
|
||||
if self.interactive_mode:
|
||||
_argv = [sys.argv[0]]
|
||||
sys.argv = _argv
|
||||
return self.interact()
|
||||
return self.run_subcommand(remainder)
|
||||
|
||||
def run_subcommand(self, argv):
|
||||
subcommand = self.command_manager.find_command(argv)
|
||||
cmd_factory, cmd_name, sub_argv = subcommand
|
||||
cmd = cmd_factory(self, self.options)
|
||||
try:
|
||||
self.prepare_to_run_command(cmd)
|
||||
full_name = (cmd_name
|
||||
if self.interactive_mode
|
||||
else ' '.join([self.NAME, cmd_name])
|
||||
)
|
||||
cmd_parser = cmd.get_parser(full_name)
|
||||
return run_command(cmd, cmd_parser, sub_argv)
|
||||
except SystemExit:
|
||||
print(_("Try 'neutron help %s' for more information.") %
|
||||
cmd_name, file=sys.stderr)
|
||||
raise
|
||||
except Exception as e:
|
||||
if self.options.verbose_level >= self.DEBUG_LEVEL:
|
||||
self.log.exception("%s", e)
|
||||
raise
|
||||
self.log.error("%s", e)
|
||||
return 1
|
||||
|
||||
def authenticate_user(self):
|
||||
"""Confirm user authentication
|
||||
|
||||
Make sure the user has provided all of the authentication
|
||||
info we need.
|
||||
"""
|
||||
cloud_config = os_client_config.OpenStackConfig().get_one_cloud(
|
||||
cloud=self.options.os_cloud, argparse=self.options,
|
||||
network_api_version=self.api_version,
|
||||
verify=not self.options.insecure)
|
||||
verify, cert = cloud_config.get_requests_verify_args()
|
||||
|
||||
# TODO(singhj): Remove dependancy on HTTPClient
|
||||
# for the case of token-endpoint authentication
|
||||
|
||||
# When using token-endpoint authentication legacy
|
||||
# HTTPClient will be used, otherwise SessionClient
|
||||
# will be used.
|
||||
if self.options.os_token and self.options.os_url:
|
||||
auth = None
|
||||
auth_session = None
|
||||
else:
|
||||
auth = cloud_config.get_auth()
|
||||
|
||||
auth_session = session.Session(
|
||||
auth=auth, verify=verify, cert=cert,
|
||||
timeout=self.options.http_timeout)
|
||||
|
||||
interface = self.options.os_endpoint_type or self.endpoint_type
|
||||
if interface.endswith('URL'):
|
||||
interface = interface[:-3]
|
||||
self.client_manager = clientmanager.ClientManager(
|
||||
retries=self.options.retries,
|
||||
raise_errors=False,
|
||||
session=auth_session,
|
||||
url=self.options.os_url,
|
||||
token=self.options.os_token,
|
||||
region_name=cloud_config.get_region_name(),
|
||||
api_version=cloud_config.get_api_version('network'),
|
||||
service_type=cloud_config.get_service_type('network'),
|
||||
service_name=cloud_config.get_service_name('network'),
|
||||
endpoint_type=interface,
|
||||
auth=auth,
|
||||
insecure=not verify,
|
||||
log_credentials=True)
|
||||
return
|
||||
|
||||
def initialize_app(self, argv):
|
||||
"""Global app init bits:
|
||||
|
||||
* set up API versions
|
||||
* validate authentication info
|
||||
"""
|
||||
|
||||
super(NeutronShell, self).initialize_app(argv)
|
||||
|
||||
# If the user is not asking for help, make sure they
|
||||
# have given us auth.
|
||||
cmd_name = None
|
||||
if argv:
|
||||
cmd_info = self.command_manager.find_command(argv)
|
||||
cmd_factory, cmd_name, sub_argv = cmd_info
|
||||
if self.interactive_mode or cmd_name != 'help':
|
||||
self.authenticate_user()
|
||||
|
||||
def configure_logging(self):
|
||||
"""Create logging handlers for any log output."""
|
||||
root_logger = logging.getLogger('')
|
||||
|
||||
# Set up logging to a file
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
|
||||
# Send higher-level messages to the console via stderr
|
||||
console = logging.StreamHandler(self.stderr)
|
||||
console_level = {self.WARNING_LEVEL: logging.WARNING,
|
||||
self.INFO_LEVEL: logging.INFO,
|
||||
self.DEBUG_LEVEL: logging.DEBUG,
|
||||
}.get(self.options.verbose_level, logging.DEBUG)
|
||||
# The default log level is INFO, in this situation, set the
|
||||
# log level of the console to WARNING, to avoid displaying
|
||||
# useless messages. This equals using "--quiet"
|
||||
if console_level == logging.INFO:
|
||||
console.setLevel(logging.WARNING)
|
||||
else:
|
||||
console.setLevel(console_level)
|
||||
if logging.DEBUG == console_level:
|
||||
formatter = logging.Formatter(self.DEBUG_MESSAGE_FORMAT)
|
||||
else:
|
||||
formatter = logging.Formatter(self.CONSOLE_MESSAGE_FORMAT)
|
||||
logging.getLogger('iso8601.iso8601').setLevel(logging.WARNING)
|
||||
logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING)
|
||||
console.setFormatter(formatter)
|
||||
root_logger.addHandler(console)
|
||||
return
|
||||
|
||||
|
||||
def main(argv=sys.argv[1:]):
|
||||
try:
|
||||
print(_("neutron CLI is deprecated and will be removed "
|
||||
"in the future. Use openstack CLI instead."), file=sys.stderr)
|
||||
return NeutronShell(NEUTRON_API_VERSION).run(
|
||||
list(map(encodeutils.safe_decode, argv)))
|
||||
except KeyboardInterrupt:
|
||||
print(_("... terminating neutron client"), file=sys.stderr)
|
||||
return 130
|
||||
except exc.NeutronClientException:
|
||||
return 1
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutronclient.tests.functional import base
|
||||
|
||||
|
||||
class SimpleReadOnlyNeutronFwv1ClientTest(base.ClientTestBase):
|
||||
|
||||
"""Tests for FWaaS v1 based client commands that are read only"""
|
||||
|
||||
def setUp(self):
|
||||
super(SimpleReadOnlyNeutronFwv1ClientTest, self).setUp()
|
||||
if not self.is_extension_enabled('fwaas'):
|
||||
self.skipTest('FWaaS is not enabled')
|
||||
|
||||
def test_neutron_firewall_list(self):
|
||||
firewall_list = self.parser.listing(self.neutron
|
||||
('firewall-list'))
|
||||
self.assertTableStruct(firewall_list, ['id', 'name',
|
||||
'firewall_policy_id'])
|
||||
|
||||
def test_neutron_firewall_policy_list(self):
|
||||
firewall_policy = self.parser.listing(self.neutron
|
||||
('firewall-policy-list'))
|
||||
self.assertTableStruct(firewall_policy, ['id', 'name',
|
||||
'firewall_rules'])
|
||||
|
||||
def test_neutron_firewall_rule_list(self):
|
||||
firewall_rule = self.parser.listing(self.neutron
|
||||
('firewall-rule-list'))
|
||||
self.assertTableStruct(firewall_rule, ['id', 'name',
|
||||
'firewall_policy_id',
|
||||
'summary', 'enabled'])
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutronclient.tests.functional import base
|
||||
|
||||
|
||||
class SimpleReadOnlyNeutronVpnClientTest(base.ClientTestBase):
|
||||
|
||||
"""Tests for vpn based client commands that are read only
|
||||
|
||||
This is a first pass at a simple read only python-neutronclient test.
|
||||
This only exercises vpn based client commands that are read only.
|
||||
This should test commands:
|
||||
* as a regular user
|
||||
* as a admin user
|
||||
* with and without optional parameters
|
||||
* initially just check return codes, and later test command outputs
|
||||
"""
|
||||
def setUp(self):
|
||||
super(SimpleReadOnlyNeutronVpnClientTest, self).setUp()
|
||||
if not self.is_extension_enabled('vpnaas'):
|
||||
self.skipTest('VPNaaS is not enabled')
|
||||
|
||||
def test_neutron_vpn_ikepolicy_list(self):
|
||||
ikepolicy = self.parser.listing(self.neutron('vpn-ikepolicy-list'))
|
||||
self.assertTableStruct(ikepolicy, ['id', 'name',
|
||||
'auth_algorithm',
|
||||
'encryption_algorithm',
|
||||
'ike_version', 'pfs'])
|
||||
|
||||
def test_neutron_vpn_ipsecpolicy_list(self):
|
||||
ipsecpolicy = self.parser.listing(self.neutron('vpn-ipsecpolicy-list'))
|
||||
self.assertTableStruct(ipsecpolicy, ['id', 'name',
|
||||
'auth_algorithm',
|
||||
'encryption_algorithm',
|
||||
'pfs'])
|
||||
|
||||
def test_neutron_vpn_service_list(self):
|
||||
vpn_list = self.parser.listing(self.neutron('vpn-service-list'))
|
||||
self.assertTableStruct(vpn_list, ['id', 'name',
|
||||
'router_id', 'status'])
|
||||
|
||||
def test_neutron_ipsec_site_connection_list(self):
|
||||
ipsec_site = self.parser.listing(self.neutron
|
||||
('ipsec-site-connection-list'))
|
||||
self.assertTableStruct(ipsec_site, ['id', 'name',
|
||||
'peer_address',
|
||||
'auth_mode', 'status'])
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
import os_client_config
|
||||
from tempest.lib.cli import base
|
||||
|
||||
|
||||
def credentials(cloud='devstack-admin'):
|
||||
"""Retrieves credentials to run functional tests
|
||||
|
||||
Credentials are either read via os-client-config from the environment
|
||||
or from a config file ('clouds.yaml'). Environment variables override
|
||||
those from the config file.
|
||||
|
||||
devstack produces a clouds.yaml with two named clouds - one named
|
||||
'devstack' which has user privs and one named 'devstack-admin' which
|
||||
has admin privs. This function will default to getting the devstack-admin
|
||||
cloud as that is the current expected behavior.
|
||||
"""
|
||||
return get_cloud_config(cloud=cloud).get_auth_args()
|
||||
|
||||
|
||||
def get_cloud_config(cloud='devstack-admin'):
|
||||
return os_client_config.OpenStackConfig().get_one_cloud(cloud=cloud)
|
||||
|
||||
|
||||
class ClientTestBase(base.ClientTestBase):
|
||||
"""This is a first pass at a simple read only python-neutronclient test.
|
||||
|
||||
This only exercises client commands that are read only.
|
||||
This should test commands:
|
||||
* as a regular user
|
||||
* as an admin user
|
||||
* with and without optional parameters
|
||||
* initially just check return codes, and later test command outputs
|
||||
|
||||
"""
|
||||
|
||||
def _get_clients_from_os_cloud_config(self, cloud='devstack-admin'):
|
||||
creds = credentials(cloud)
|
||||
cli_dir = os.environ.get(
|
||||
'OS_NEUTRONCLIENT_EXEC_DIR',
|
||||
os.path.join(os.path.abspath('.'), '.tox/functional/bin'))
|
||||
|
||||
return base.CLIClient(
|
||||
username=creds['username'],
|
||||
password=creds['password'],
|
||||
tenant_name=creds['project_name'],
|
||||
project_domain_id=creds['project_domain_id'],
|
||||
user_domain_id=creds['user_domain_id'],
|
||||
uri=creds['auth_url'],
|
||||
cli_dir=cli_dir)
|
||||
|
||||
def _get_clients(self):
|
||||
return self._get_clients_from_os_cloud_config()
|
||||
|
||||
def neutron(self, *args, **kwargs):
|
||||
return self.clients.neutron(*args, **kwargs)
|
||||
|
||||
def neutron_non_admin(self, *args, **kwargs):
|
||||
if not hasattr(self, '_non_admin_clients'):
|
||||
self._non_admin_clients = self._get_clients_from_os_cloud_config(
|
||||
cloud='devstack')
|
||||
return self._non_admin_clients.neutron(*args, **kwargs)
|
||||
|
||||
def is_extension_enabled(self, extension_alias):
|
||||
extensions = self.parser.listing(self.neutron('ext-list'))
|
||||
aliases = [e['alias'] for e in extensions]
|
||||
return extension_alias in aliases
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
# Copyright 2016 NEC Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
import yaml
|
||||
|
||||
from neutronclient.tests.functional import base
|
||||
|
||||
|
||||
class TestCLIFormatter(base.ClientTestBase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCLIFormatter, self).setUp()
|
||||
self.net_name = 'net-%s' % uuidutils.generate_uuid()
|
||||
self.addCleanup(self.neutron, 'net-delete %s' % self.net_name)
|
||||
|
||||
def _create_net(self, fmt, col_attrs):
|
||||
params = ['-c %s' % attr for attr in col_attrs]
|
||||
params.append('-f %s' % fmt)
|
||||
params.append(self.net_name)
|
||||
param_string = ' '.join(params)
|
||||
return self.neutron('net-create', params=param_string)
|
||||
|
||||
def test_net_create_with_json_formatter(self):
|
||||
result = self._create_net('json', ['name', 'admin_state_up'])
|
||||
self.assertDictEqual({'name': self.net_name,
|
||||
'admin_state_up': True},
|
||||
jsonutils.loads(result))
|
||||
|
||||
def test_net_create_with_yaml_formatter(self):
|
||||
result = self._create_net('yaml', ['name', 'admin_state_up'])
|
||||
self.assertDictEqual({'name': self.net_name,
|
||||
'admin_state_up': True},
|
||||
yaml.load(result))
|
||||
|
||||
def test_net_create_with_value_formatter(self):
|
||||
# NOTE(amotoki): In 'value' formatter, there is no guarantee
|
||||
# in the order of attribute, so we use one attribute in this test.
|
||||
result = self._create_net('value', ['name'])
|
||||
self.assertEqual(self.net_name, result.strip())
|
||||
|
||||
def test_net_create_with_shell_formatter(self):
|
||||
result = self._create_net('shell', ['name', 'admin_state_up'])
|
||||
result_lines = set(result.strip().split('\n'))
|
||||
self.assertSetEqual(set(['name="%s"' % self.net_name,
|
||||
'admin_state_up="True"']),
|
||||
result_lines)
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from keystoneauth1 import session
|
||||
from oslo_utils import uuidutils
|
||||
from tempest.lib import base
|
||||
import testtools
|
||||
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.tests.functional import base as func_base
|
||||
from neutronclient.v2_0 import client as v2_client
|
||||
|
||||
|
||||
class LibraryTestCase(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(LibraryTestCase, self).setUp()
|
||||
self.client = self._get_client()
|
||||
|
||||
def _get_client(self):
|
||||
cloud_config = func_base.get_cloud_config()
|
||||
keystone_auth = cloud_config.get_auth()
|
||||
(verify, cert) = cloud_config.get_requests_verify_args()
|
||||
|
||||
ks_session = session.Session(
|
||||
auth=keystone_auth,
|
||||
verify=verify,
|
||||
cert=cert)
|
||||
return v2_client.Client(session=ks_session)
|
||||
|
||||
def test_list_network(self):
|
||||
nets = self.client.list_networks()
|
||||
self.assertIsInstance(nets['networks'], list)
|
||||
|
||||
def test_post_put_delete_network(self):
|
||||
name = uuidutils.generate_uuid()
|
||||
net = self.client.create_network({'network': {'name': name}})
|
||||
net_id = net['network']['id']
|
||||
self.assertEqual(name, net['network']['name'])
|
||||
name2 = uuidutils.generate_uuid()
|
||||
net = self.client.update_network(net_id, {'network': {'name': name2}})
|
||||
self.assertEqual(name2, net['network']['name'])
|
||||
self.client.delete_network(net_id)
|
||||
with testtools.ExpectedException(exceptions.NetworkNotFoundClient):
|
||||
self.client.show_network(net_id)
|
||||
|
||||
def test_get_auth_ref(self):
|
||||
# Call some API call to ensure the client is authenticated.
|
||||
self.client.list_networks()
|
||||
auth_ref = self.client.httpclient.get_auth_ref()
|
||||
self.assertIsNotNone(auth_ref)
|
||||
self.assertIsNotNone(auth_ref.role_names)
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
# Copyright 2016 NEC Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutronclient.tests.functional import base
|
||||
|
||||
|
||||
class CLICommonFeatureTest(base.ClientTestBase):
|
||||
|
||||
def test_tenant_id_shown_in_list_by_admin(self):
|
||||
nets = self.parser.table(self.neutron('net-list'))
|
||||
self.assertIn('tenant_id', nets['headers'])
|
||||
|
||||
def test_tenant_id_not_shown_in_list_with_columns(self):
|
||||
nets = self.parser.table(self.neutron('net-list -c id -c name'))
|
||||
self.assertNotIn('tenant_id', nets['headers'])
|
||||
self.assertListEqual(['id', 'name'], nets['headers'])
|
||||
|
||||
def test_tenant_id_not_shown_in_list_by_non_admin(self):
|
||||
output = self.neutron_non_admin('net-list')
|
||||
self.assertNotIn('tenant_id', self.parser.table(output)['headers'])
|
||||
self.assertTableStruct(self.parser.listing(output),
|
||||
['id', 'name'])
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
# Copyright 2016 Cisco Systems
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutronclient.tests.functional import base
|
||||
|
||||
from tempest.lib import exceptions
|
||||
|
||||
|
||||
class PurgeNeutronClientCLITest(base.ClientTestBase):
|
||||
|
||||
def _safe_cleanup(self, delete_command):
|
||||
try:
|
||||
self.neutron(delete_command)
|
||||
except exceptions.CommandFailed:
|
||||
# This resource was already purged successfully
|
||||
pass
|
||||
|
||||
def _create_subnet(self, name, tenant_id, cidr):
|
||||
params = ('%(name)s --name %(name)s --tenant-id %(tenant)s '
|
||||
'%(cidr)s' % {'name': name,
|
||||
'tenant': tenant_id,
|
||||
'cidr': cidr})
|
||||
subnet = self.parser.listing(self.neutron('subnet-create',
|
||||
params=params))
|
||||
for row in subnet:
|
||||
if row['Field'] == 'id':
|
||||
return row['Value']
|
||||
|
||||
def _create_router(self, name, tenant_id):
|
||||
params = ('%(name)s --tenant_id %(tenant)s' % {'name': name,
|
||||
'tenant': tenant_id})
|
||||
router = self.parser.listing(self.neutron('router-create',
|
||||
params=params))
|
||||
for row in router:
|
||||
if row['Field'] == 'id':
|
||||
return row['Value']
|
||||
|
||||
def _create_floatingip(self, network, tenant_id):
|
||||
params = ('%(network)s --tenant-id %(tenant)s' %
|
||||
{'network': network, 'tenant': tenant_id})
|
||||
floatingip = self.parser.listing(self.neutron('floatingip-create',
|
||||
params=params))
|
||||
for row in floatingip:
|
||||
if row['Field'] == 'id':
|
||||
return row['Value']
|
||||
|
||||
def _create_resources(self, name, tenant_id, shared_tenant_id=None):
|
||||
# If no shared_tenant_id is provided, create the resources for the
|
||||
# current tenant to test that they will be deleted when not in use.
|
||||
if not shared_tenant_id:
|
||||
shared_tenant_id = tenant_id
|
||||
|
||||
self.neutron('net-create',
|
||||
params=('%(name)s --router:external True '
|
||||
'--tenant-id %(tenant)s' % {'name': name,
|
||||
'tenant': tenant_id}))
|
||||
self.addCleanup(self._safe_cleanup, 'net-delete %s' % name)
|
||||
|
||||
self.neutron('net-create',
|
||||
params=('%(name)s-shared --shared '
|
||||
'--tenant-id %(tenant)s' %
|
||||
{'name': name, 'tenant': shared_tenant_id}))
|
||||
self.addCleanup(self._safe_cleanup,
|
||||
'net-delete %s-shared' % name)
|
||||
|
||||
subnet = self._create_subnet(name, tenant_id, '192.168.71.0/24')
|
||||
self.addCleanup(self._safe_cleanup, 'subnet-delete %s' % name)
|
||||
|
||||
subnet = self._create_subnet('%s-shared' % name, tenant_id,
|
||||
'192.168.81.0/24')
|
||||
self.addCleanup(self._safe_cleanup, 'subnet-delete %s-shared' % name)
|
||||
|
||||
router = self._create_router(name, tenant_id)
|
||||
self.addCleanup(self._safe_cleanup, 'router-delete %s' % name)
|
||||
|
||||
self.neutron('router-interface-add',
|
||||
params=('%(router)s %(subnet)s '
|
||||
'--tenant-id %(tenant)s' % {'router': router,
|
||||
'subnet': subnet,
|
||||
'tenant': tenant_id}))
|
||||
|
||||
self.neutron('port-create',
|
||||
params=('%(name)s --name %(name)s '
|
||||
'--tenant-id %(tenant)s' % {'name': name,
|
||||
'tenant': tenant_id}))
|
||||
self.addCleanup(self._safe_cleanup, 'port-delete %s' % name)
|
||||
|
||||
self.neutron('port-create',
|
||||
params=('%(name)s-shared --name %(name)s-shared '
|
||||
'--tenant-id %(tenant)s' % {'name': name,
|
||||
'tenant': tenant_id}))
|
||||
self.addCleanup(self._safe_cleanup, 'port-delete %s-shared' % name)
|
||||
|
||||
self.neutron('security-group-create',
|
||||
params=('%(name)s --tenant-id %(tenant)s' %
|
||||
{'name': name, 'tenant': tenant_id}))
|
||||
self.addCleanup(self._safe_cleanup, 'security-group-delete %s' % name)
|
||||
|
||||
floatingip = self._create_floatingip(name, tenant_id)
|
||||
self.addCleanup(self._safe_cleanup, ('floatingip-delete '
|
||||
'%s' % floatingip))
|
||||
return floatingip
|
||||
|
||||
def _verify_deletion(self, resources, resource_type):
|
||||
purged = True
|
||||
no_purge_purged = True
|
||||
router_interface_owners = ['network:router_interface',
|
||||
'network:router_interface_distributed']
|
||||
for row in resources:
|
||||
if resource_type == 'port' and row.get('id', None):
|
||||
port = self.parser.listing(self.neutron('port-show',
|
||||
params=row['id']))
|
||||
port_dict = {}
|
||||
for row in port:
|
||||
port_dict[row['Field']] = row['Value']
|
||||
if port_dict['device_owner'] in router_interface_owners:
|
||||
if port_dict['tenant_id'] == 'purge-tenant':
|
||||
purged = False
|
||||
elif port_dict['tenant_id'] == 'no-purge-tenant':
|
||||
no_purge_purged = False
|
||||
if not purged or not no_purge_purged:
|
||||
self.addCleanup(self.neutron,
|
||||
('router-interface-delete %(router)s '
|
||||
'port=%(port)s' %
|
||||
{'router': port_dict['device_id'],
|
||||
'port': port_dict['id']}))
|
||||
if (row.get('name') == 'purge-me' or
|
||||
row.get('id') == self.purge_floatingip):
|
||||
purged = False
|
||||
elif ('no-purge' in row.get('name', '') or
|
||||
row.get('id') == self.no_purge_floatingip):
|
||||
no_purge_purged = False
|
||||
|
||||
if not purged:
|
||||
self.fail('%s not deleted by neutron purge' % resource_type)
|
||||
|
||||
if no_purge_purged:
|
||||
self.fail('%s owned by another tenant incorrectly deleted '
|
||||
'by neutron purge' % resource_type)
|
||||
|
||||
def test_purge(self):
|
||||
self.purge_floatingip = self._create_resources('purge-me',
|
||||
'purge-tenant')
|
||||
self.no_purge_floatingip = self._create_resources('no-purge',
|
||||
'no-purge-tenant',
|
||||
'purge-tenant')
|
||||
|
||||
purge_output = self.neutron('purge', params='purge-tenant').strip()
|
||||
if not purge_output:
|
||||
self.fail('Purge command did not return feedback')
|
||||
|
||||
networks = self.parser.listing(self.neutron('net-list'))
|
||||
subnets = self.parser.listing(self.neutron('subnet-list'))
|
||||
routers = self.parser.listing(self.neutron('router-list'))
|
||||
ports = self.parser.listing(self.neutron('port-list'))
|
||||
floatingips = self.parser.listing(self.neutron('floatingip-list'))
|
||||
|
||||
self._verify_deletion(networks, 'network')
|
||||
self._verify_deletion(subnets, 'subnet')
|
||||
self._verify_deletion(ports, 'port')
|
||||
self._verify_deletion(routers, 'router')
|
||||
self._verify_deletion(floatingips, 'floatingip')
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import re
|
||||
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from neutronclient.tests.functional import base
|
||||
|
||||
|
||||
class SimpleReadOnlyNeutronClientTest(base.ClientTestBase):
|
||||
|
||||
"""This is a first pass at a simple read only python-neutronclient test.
|
||||
|
||||
This only exercises client commands that are read only.
|
||||
This should test commands:
|
||||
* as a regular user
|
||||
* as a admin user
|
||||
* with and without optional parameters
|
||||
* initially just check return codes, and later test command outputs
|
||||
"""
|
||||
|
||||
def test_admin_fake_action(self):
|
||||
self.assertRaises(exceptions.CommandFailed,
|
||||
self.neutron,
|
||||
'this-does-neutron-exist')
|
||||
|
||||
# NOTE(mestery): Commands in order listed in 'neutron help'
|
||||
|
||||
# Optional arguments:
|
||||
|
||||
def test_neutron_fake_action(self):
|
||||
self.assertRaises(exceptions.CommandFailed,
|
||||
self.neutron,
|
||||
'this-does-not-exist')
|
||||
|
||||
def test_neutron_net_list(self):
|
||||
net_list = self.parser.listing(self.neutron('net-list'))
|
||||
self.assertTableStruct(net_list, ['id', 'name', 'subnets'])
|
||||
|
||||
def test_neutron_ext_list(self):
|
||||
ext = self.parser.listing(self.neutron('ext-list'))
|
||||
self.assertTableStruct(ext, ['alias', 'name'])
|
||||
|
||||
def test_neutron_dhcp_agent_list_hosting_net(self):
|
||||
self.neutron('dhcp-agent-list-hosting-net',
|
||||
params='private')
|
||||
|
||||
def test_neutron_agent_list(self):
|
||||
agents = self.parser.listing(self.neutron('agent-list'))
|
||||
field_names = ['id', 'agent_type', 'host', 'alive', 'admin_state_up']
|
||||
self.assertTableStruct(agents, field_names)
|
||||
|
||||
def test_neutron_floatingip_list(self):
|
||||
self.neutron('floatingip-list')
|
||||
|
||||
def test_neutron_meter_label_list(self):
|
||||
self.neutron('meter-label-list')
|
||||
|
||||
def test_neutron_meter_label_rule_list(self):
|
||||
self.neutron('meter-label-rule-list')
|
||||
|
||||
def test_neutron_net_external_list(self):
|
||||
net_ext_list = self.parser.listing(self.neutron('net-external-list'))
|
||||
self.assertTableStruct(net_ext_list, ['id', 'name', 'subnets'])
|
||||
|
||||
def test_neutron_port_list(self):
|
||||
port_list = self.parser.listing(self.neutron('port-list'))
|
||||
self.assertTableStruct(port_list, ['id', 'name', 'mac_address',
|
||||
'fixed_ips'])
|
||||
|
||||
def test_neutron_quota_list(self):
|
||||
self.neutron('quota-list')
|
||||
|
||||
def test_neutron_router_list(self):
|
||||
router_list = self.parser.listing(self.neutron('router-list'))
|
||||
self.assertTableStruct(router_list, ['id', 'name',
|
||||
'external_gateway_info'])
|
||||
|
||||
def test_neutron_security_group_list(self):
|
||||
security_grp = self.parser.listing(self.neutron('security-group-list'))
|
||||
self.assertTableStruct(security_grp, ['id', 'name',
|
||||
'security_group_rules'])
|
||||
|
||||
def test_neutron_security_group_rule_list(self):
|
||||
security_grp = self.parser.listing(self.neutron
|
||||
('security-group-rule-list'))
|
||||
self.assertTableStruct(security_grp, ['id', 'security_group',
|
||||
'direction', 'ethertype',
|
||||
'port/protocol', 'remote'])
|
||||
|
||||
def test_neutron_subnet_list(self):
|
||||
subnet_list = self.parser.listing(self.neutron('subnet-list'))
|
||||
self.assertTableStruct(subnet_list, ['id', 'name', 'cidr',
|
||||
'allocation_pools'])
|
||||
|
||||
def test_neutron_help(self):
|
||||
help_text = self.neutron('help')
|
||||
lines = help_text.split('\n')
|
||||
self.assertFirstLineStartsWith(lines, 'usage: neutron')
|
||||
|
||||
commands = []
|
||||
cmds_start = lines.index('Commands for API v2.0:')
|
||||
command_pattern = re.compile(r'^ {2}([a-z0-9\-\_]+)')
|
||||
for line in lines[cmds_start:]:
|
||||
match = command_pattern.match(line)
|
||||
if match:
|
||||
commands.append(match.group(1))
|
||||
commands = set(commands)
|
||||
wanted_commands = set(('net-create', 'subnet-list', 'port-delete',
|
||||
'router-show', 'agent-update', 'help'))
|
||||
self.assertFalse(wanted_commands - commands)
|
||||
|
||||
# Optional arguments:
|
||||
|
||||
def test_neutron_version(self):
|
||||
self.neutron('', flags='--version')
|
||||
|
||||
def test_neutron_debug_net_list(self):
|
||||
self.neutron('net-list', flags='--debug')
|
||||
|
||||
def test_neutron_quiet_net_list(self):
|
||||
self.neutron('net-list', flags='--quiet')
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
# Copyright 2015 Hewlett-Packard Development Company, L.P
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutronclient.tests.functional import base
|
||||
|
||||
|
||||
class SubnetCreateNeutronClientCLITest(base.ClientTestBase):
|
||||
|
||||
def test_create_subnet_net_name_first(self):
|
||||
self.neutron('net-create', params='netwrk-1')
|
||||
self.addCleanup(self.neutron, 'net-delete netwrk-1')
|
||||
self.neutron('subnet-create netwrk-1',
|
||||
params='--name fake --gateway 192.168.51.1 '
|
||||
'192.168.51.0/24')
|
||||
self.addCleanup(self.neutron, 'subnet-delete fake')
|
||||
subnet_list = self.parser.listing(self.neutron('subnet-list'))
|
||||
self.assertTableStruct(subnet_list, ['id', 'name', 'cidr',
|
||||
'allocation_pools'])
|
||||
found = False
|
||||
for row in subnet_list:
|
||||
if row.get('name') == 'fake':
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
self.fail('Created subnet not found in list')
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
enable_plugin neutron-fwaas https://opendev.org/openstack/neutron-fwaas
|
||||
enable_service q-fwaas
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
VENV=${1:-"functional"}
|
||||
|
||||
GATE_DEST=$BASE/new
|
||||
NEUTRONCLIENT_PATH=$GATE_DEST/python-neutronclient
|
||||
GATE_HOOKS=$NEUTRONCLIENT_PATH/neutronclient/tests/functional/hooks
|
||||
DEVSTACK_PATH=$GATE_DEST/devstack
|
||||
LOCAL_CONF=$DEVSTACK_PATH/late-local.conf
|
||||
DSCONF=/tmp/devstack-tools/bin/dsconf
|
||||
|
||||
# Install devstack-tools used to produce local.conf; we can't rely on
|
||||
# test-requirements.txt because the gate hook is triggered before neutronclient
|
||||
# is installed
|
||||
sudo -H pip install virtualenv
|
||||
virtualenv /tmp/devstack-tools
|
||||
/tmp/devstack-tools/bin/pip install -U devstack-tools==0.4.0
|
||||
|
||||
# Inject config from hook into localrc
|
||||
function load_rc_hook {
|
||||
local hook="$1"
|
||||
local tmpfile
|
||||
local config
|
||||
tmpfile=$(tempfile)
|
||||
config=$(cat $GATE_HOOKS/$hook)
|
||||
echo "[[local|localrc]]" > $tmpfile
|
||||
$DSCONF setlc_raw $tmpfile "$config"
|
||||
$DSCONF merge_lc $LOCAL_CONF $tmpfile
|
||||
rm -f $tmpfile
|
||||
}
|
||||
|
||||
|
||||
if [ "$VENV" == "functional-adv-svcs" ]
|
||||
then
|
||||
load_rc_hook fwaas
|
||||
load_rc_hook vpnaas
|
||||
fi
|
||||
|
||||
export DEVSTACK_LOCALCONF=$(cat $LOCAL_CONF)
|
||||
$BASE/new/devstack-gate/devstack-vm-gate.sh
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
#!/bin/bash -xe
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This script is executed inside post_test_hook function in devstack gate.
|
||||
|
||||
SCRIPTS_DIR="/usr/os-testr-env/bin/"
|
||||
|
||||
function generate_test_logs {
|
||||
local path="$1"
|
||||
# Compress all $path/*.txt files and move the directories holding those
|
||||
# files to /opt/stack/logs. Files with .log suffix have their
|
||||
# suffix changed to .txt (so browsers will know to open the compressed
|
||||
# files and not download them).
|
||||
if [ -d "$path" ]
|
||||
then
|
||||
sudo find $path -iname "*.log" -type f -exec mv {} {}.txt \; -exec gzip -9 {}.txt \;
|
||||
sudo mv $path/* /opt/stack/logs/
|
||||
fi
|
||||
}
|
||||
|
||||
function generate_testr_results {
|
||||
# Give job user rights to access tox logs
|
||||
sudo -H -u $USER chmod o+rw .
|
||||
sudo -H -u $USER chmod o+rw -R .stestr
|
||||
if [ -f ".stestr/0" ] ; then
|
||||
.tox/$VENV/bin/subunit-1to2 < .stestr/0 > ./stestr.subunit
|
||||
$SCRIPTS_DIR/subunit2html ./stestr.subunit testr_results.html
|
||||
gzip -9 ./stestr.subunit
|
||||
gzip -9 ./testr_results.html
|
||||
sudo mv ./*.gz /opt/stack/logs/
|
||||
fi
|
||||
|
||||
if [ "$venv" == "functional" ] || [ "$venv" == "functional-adv-svcs" ]
|
||||
then
|
||||
generate_test_logs "/tmp/${venv}-logs"
|
||||
fi
|
||||
}
|
||||
|
||||
export NEUTRONCLIENT_DIR="$BASE/new/python-neutronclient"
|
||||
|
||||
sudo chown -R $USER:stack $NEUTRONCLIENT_DIR
|
||||
|
||||
# Go to the neutronclient dir
|
||||
cd $NEUTRONCLIENT_DIR
|
||||
|
||||
# Run tests
|
||||
VENV=${1:-"functional"}
|
||||
echo "Running neutronclient functional test suite"
|
||||
set +e
|
||||
# Preserve env for OS_ credentials
|
||||
sudo -E -H -u $USER tox -e $VENV
|
||||
EXIT_CODE=$?
|
||||
set -e
|
||||
|
||||
# Collect and parse result
|
||||
generate_testr_results
|
||||
exit $EXIT_CODE
|
||||
|
|
@ -1 +0,0 @@
|
|||
enable_plugin neutron-vpnaas https://opendev.org/openstack/neutron-vpnaas
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
# Copyright 2016 Huawei Technologies India Pvt. Ltd.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.bgp import dragentscheduler as bgp_drsched
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
from neutronclient.tests.unit import test_cli20_agentschedulers as test_as
|
||||
|
||||
|
||||
BGP_DRAGENT_ID = 'bgp_dragent_id1'
|
||||
BGP_SPEAKER = 'bgp_speaker_id1'
|
||||
|
||||
|
||||
class CLITestV20DRAgentScheduler(test_as.CLITestV20AgentScheduler):
|
||||
|
||||
def test_add_bgp_speaker_to_dragent(self):
|
||||
resource = 'agent'
|
||||
cmd = bgp_drsched.AddBGPSpeakerToDRAgent(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
args = (BGP_DRAGENT_ID, BGP_SPEAKER)
|
||||
body = {'bgp_speaker_id': BGP_SPEAKER}
|
||||
result = {'bgp_speaker_id': 'bgp_speaker_id', }
|
||||
self._test_add_to_agent(resource, cmd, args,
|
||||
self.client.BGP_DRINSTANCES,
|
||||
body, result)
|
||||
|
||||
def test_remove_bgp_speaker_from_dragent(self):
|
||||
resource = 'agent'
|
||||
cmd = bgp_drsched.RemoveBGPSpeakerFromDRAgent(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
args = (BGP_DRAGENT_ID, BGP_SPEAKER)
|
||||
self._test_remove_from_agent(resource, cmd, args,
|
||||
self.client.BGP_DRINSTANCES)
|
||||
|
||||
def test_list_bgp_speakers_on_dragent(self):
|
||||
resources = 'bgp_speakers'
|
||||
cmd = bgp_drsched.ListBGPSpeakersOnDRAgent(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
path = ((self.client.agent_path + self.client.BGP_DRINSTANCES) %
|
||||
BGP_DRAGENT_ID)
|
||||
self._test_list_resources(resources, cmd, base_args=[BGP_DRAGENT_ID],
|
||||
path=path)
|
||||
|
||||
def test_list_dragents_hosting_bgp_speaker(self):
|
||||
resources = 'agent'
|
||||
cmd = bgp_drsched.ListDRAgentsHostingBGPSpeaker(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
path = ((self.client.bgp_speaker_path + self.client.BGP_DRAGENTS) %
|
||||
BGP_DRAGENT_ID)
|
||||
contents = {self.id_field: 'myid1', 'alive': True}
|
||||
self._test_list_resources(resources, cmd, base_args=[BGP_DRAGENT_ID],
|
||||
path=path, response_contents=contents)
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
# Copyright 2016 Huawei Technologies India Pvt. Ltd.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.neutron.v2_0.bgp import peer as bgp_peer
|
||||
from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20BGPPeerJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
non_admin_status_resources = ['bgp_peer']
|
||||
|
||||
def test_create_bgp_peer_with_mandatory_params(self):
|
||||
# Create BGP peer with mandatory params.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
peerip = '1.1.1.1'
|
||||
remote_asnum = '1'
|
||||
args = [name,
|
||||
'--peer-ip', peerip,
|
||||
'--remote-as', remote_asnum, ]
|
||||
position_names = ['name', 'peer_ip', 'remote_as',
|
||||
'auth_type']
|
||||
position_values = [name, peerip, remote_asnum, 'none']
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_bgp_peer_with_all_params(self):
|
||||
# Create BGP peer with all params.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
peerip = '1.1.1.1'
|
||||
remote_asnum = '65535'
|
||||
authType = 'md5'
|
||||
password = 'abc'
|
||||
args = [name,
|
||||
'--peer-ip', peerip,
|
||||
'--remote-as', remote_asnum,
|
||||
'--auth-type', authType,
|
||||
'--password', password]
|
||||
position_names = ['name', 'peer_ip', 'remote_as',
|
||||
'auth_type', 'password']
|
||||
position_values = [name, peerip, remote_asnum, authType, password]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_bgp_peer_with_invalid_min_remote_asnum(self):
|
||||
# Create BGP peer with invalid minimum remote-asnum.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
peerip = '1.1.1.1'
|
||||
remote_asnum = '0'
|
||||
args = [name,
|
||||
'--peer-ip', peerip,
|
||||
'--remote-as', remote_asnum, ]
|
||||
position_names = ['name', 'peer_ip', 'remote_as', ]
|
||||
position_values = [name, peerip, remote_asnum, ]
|
||||
exc = self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_resource,
|
||||
resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
self.assertEqual('remote-as "0" should be an integer [%s:%s].' %
|
||||
(bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM),
|
||||
str(exc))
|
||||
|
||||
def test_create_bgp_peer_with_invalid_max_remote_asnum(self):
|
||||
# Create BGP peer with invalid maximum remote-asnum.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
peerip = '1.1.1.1'
|
||||
remote_asnum = '65536'
|
||||
args = [name,
|
||||
'--peer-ip', peerip,
|
||||
'--remote-as', remote_asnum, ]
|
||||
position_names = ['name', 'peer_ip', 'remote_as',
|
||||
'auth_type', 'password']
|
||||
position_values = [name, peerip, remote_asnum, 'none', '']
|
||||
exc = self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_resource,
|
||||
resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
self.assertEqual('remote-as "65536" should be an integer [%s:%s].' %
|
||||
(bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM),
|
||||
str(exc))
|
||||
|
||||
def test_create_authenticated_bgp_peer_without_authtype(self):
|
||||
# Create authenticated BGP peer without auth-type.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
peerip = '1.1.1.1'
|
||||
remote_asnum = '2048'
|
||||
password = 'abc'
|
||||
args = [name,
|
||||
'--peer-ip', peerip,
|
||||
'--remote-as', remote_asnum,
|
||||
'--password', password]
|
||||
position_names = ['name', 'peer_ip', 'remote_as', 'password']
|
||||
position_values = [name, peerip, remote_asnum, password]
|
||||
exc = self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_resource,
|
||||
resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
self.assertEqual('Must provide auth-type if password is specified.',
|
||||
str(exc))
|
||||
|
||||
def test_create_authenticated_bgp_peer_without_password(self):
|
||||
# Create authenticated BGP peer without password.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
peerip = '1.1.1.1'
|
||||
remote_asnum = '2048'
|
||||
authType = 'md5'
|
||||
args = [name,
|
||||
'--peer-ip', peerip,
|
||||
'--remote-as', remote_asnum,
|
||||
'--auth-type', authType]
|
||||
position_names = ['name', 'peer_ip', 'remote_as', 'auth_type']
|
||||
position_values = [name, peerip, remote_asnum, authType]
|
||||
exc = self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_resource,
|
||||
resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
self.assertEqual('Must provide password if auth-type is specified.',
|
||||
str(exc))
|
||||
|
||||
def test_update_bgp_peer(self):
|
||||
# Update BGP peer:
|
||||
# myid --advertise-tenant-networks True
|
||||
# --advertise-floating-ip-host-routes False
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.UpdatePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'new-name',
|
||||
'--password', 'abc'],
|
||||
{'name': 'new-name', 'password': 'abc'})
|
||||
|
||||
def test_update_bgp_peer_exception(self):
|
||||
# Update BGP peer: myid.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.UpdatePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self._test_update_resource,
|
||||
resource, cmd, 'myid', ['myid'], {})
|
||||
|
||||
def test_list_bgp_peer(self):
|
||||
# List all BGP peers.
|
||||
resources = "bgp_peers"
|
||||
cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
# TODO(Vikram): Add test_list_bgp_peer_pagination
|
||||
|
||||
def test_list_bgp_peer_sort(self):
|
||||
# sorted list: bgp-peer-list --sort-key name --sort-key id
|
||||
# --sort-key asc --sort-key desc
|
||||
resources = "bgp_peers"
|
||||
cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_bgp_peer_limit(self):
|
||||
# size (1000) limited list: bgp-peer-list -P.
|
||||
resources = "bgp_peers"
|
||||
cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_bgp_peer(self):
|
||||
# Show BGP peer: --fields id --fields name myid.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.ShowPeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args,
|
||||
['id', 'name'])
|
||||
|
||||
def test_delete_bgp_peer(self):
|
||||
# Delete BGP peer: bgp_peer_id.
|
||||
resource = 'bgp_peer'
|
||||
cmd = bgp_peer.DeletePeer(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
myid = 'myid'
|
||||
args = [myid]
|
||||
self._test_delete_resource(resource, cmd, myid, args)
|
||||
|
|
@ -1,272 +0,0 @@
|
|||
# Copyright 2016 Huawei Technologies India Pvt. Ltd.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20BGPSpeakerJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
non_admin_status_resources = ['bgp_speaker']
|
||||
|
||||
def test_create_bgp_speaker_with_minimal_options(self):
|
||||
# Create BGP Speaker with mandatory params.
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
local_asnum = '1'
|
||||
args = [name, '--local-as', local_asnum, ]
|
||||
position_names = ['name', 'local_as', 'ip_version']
|
||||
position_values = [name, local_asnum, 4]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_ipv4_bgp_speaker_with_all_params(self):
|
||||
# Create BGP Speaker with all params.
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
local_asnum = '1'
|
||||
args = [name,
|
||||
'--local-as', local_asnum,
|
||||
'--ip-version', '4',
|
||||
'--advertise-floating-ip-host-routes', 'True',
|
||||
'--advertise-tenant-networks', 'True']
|
||||
position_names = ['name', 'local_as', 'ip_version',
|
||||
'advertise_floating_ip_host_routes',
|
||||
'advertise_tenant_networks']
|
||||
position_values = [name, local_asnum, 4, 'True', 'True']
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_ipv6_bgp_speaker_with_all_params(self):
|
||||
# Create BGP Speaker with all params.
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
local_asnum = '65535'
|
||||
args = [name,
|
||||
'--local-as', local_asnum,
|
||||
'--ip-version', '6',
|
||||
'--advertise-floating-ip-host-routes', 'True',
|
||||
'--advertise-tenant-networks', 'True']
|
||||
position_names = ['name', 'local_as', 'ip_version',
|
||||
'advertise_floating_ip_host_routes',
|
||||
'advertise_tenant_networks']
|
||||
position_values = [name, local_asnum, 6, 'True', 'True']
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_bgp_speaker_with_invalid_min_local_asnum(self):
|
||||
# Create BGP Speaker with invalid minimum local-asnum.
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
local_asnum = '0'
|
||||
args = [name,
|
||||
'--local-as', local_asnum]
|
||||
position_names = ['name', 'local_as']
|
||||
position_values = [name, local_asnum]
|
||||
exc = self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_resource,
|
||||
resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
self.assertEqual('local-as "0" should be an integer [%s:%s].' %
|
||||
(bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM),
|
||||
str(exc))
|
||||
|
||||
def test_create_bgp_speaker_with_invalid_max_local_asnum(self):
|
||||
# Create BGP Speaker with invalid maximum local-asnum.
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
my_id = 'my-id'
|
||||
local_asnum = '65536'
|
||||
args = [name,
|
||||
'--local-as', local_asnum]
|
||||
position_names = ['name', 'local_as', ]
|
||||
position_values = [name, local_asnum, ]
|
||||
exc = self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_resource,
|
||||
resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
self.assertEqual('local-as "65536" should be an integer [%s:%s].' %
|
||||
(bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM),
|
||||
str(exc))
|
||||
|
||||
def test_update_bgp_speaker(self):
|
||||
# Update BGP Speaker:
|
||||
# myid --advertise-tenant-networks True
|
||||
# --advertise-floating-ip-host-routes False
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.UpdateSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid',
|
||||
'--name', 'new-name',
|
||||
'--advertise-tenant-networks', 'True',
|
||||
'--advertise-floating-ip-host-routes',
|
||||
'False'],
|
||||
{'name': 'new-name',
|
||||
'advertise_tenant_networks': 'True',
|
||||
'advertise_floating_ip_host_routes':
|
||||
'False'})
|
||||
|
||||
def test_update_bgp_speaker_exception(self):
|
||||
# Update BGP Speaker: myid.
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.UpdateSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self._test_update_resource,
|
||||
resource, cmd, 'myid', ['myid'], {})
|
||||
|
||||
def test_list_bgp_speaker(self):
|
||||
# List all BGP Speakers.
|
||||
resources = "bgp_speakers"
|
||||
cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
@mock.patch.object(bgp_speaker.ListSpeakers, "extend_list")
|
||||
def test_list_bgp_speaker_pagination(self, mock_extend_list):
|
||||
# List all BGP Speakers with pagination support.
|
||||
cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources_with_pagination("bgp_speakers",
|
||||
cmd)
|
||||
mock_extend_list.assert_called_once_with(test_cli20.IsA(list),
|
||||
mock.ANY)
|
||||
|
||||
def test_list_bgp_speaker_sort(self):
|
||||
# sorted list: bgp-speaker-list --sort-key name --sort-key id
|
||||
# --sort-key asc --sort-key desc
|
||||
resources = "bgp_speakers"
|
||||
cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_bgp_speaker_limit(self):
|
||||
# size (1000) limited list: bgp-speaker-list -P.
|
||||
resources = "bgp_speakers"
|
||||
cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_bgp_speaker(self):
|
||||
# Show BGP Speaker: --fields id --fields name myid.
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.ShowSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args,
|
||||
['id', 'name'])
|
||||
|
||||
def test_delete_bgp_speaker(self):
|
||||
# Delete BGP Speaker: bgp_speaker_id.
|
||||
resource = 'bgp_speaker'
|
||||
cmd = bgp_speaker.DeleteSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
myid = 'myid'
|
||||
args = [myid]
|
||||
self._test_delete_resource(resource, cmd, myid, args)
|
||||
|
||||
def _test_add_remove_peer(self, action, cmd, args):
|
||||
"""Add or Remove BGP Peer to/from a BGP Speaker."""
|
||||
resource = 'bgp_speaker'
|
||||
subcmd = '%s_bgp_peer' % action
|
||||
body = {'bgp_peer_id': 'peerid'}
|
||||
if action == 'add':
|
||||
retval = {'bgp_peer': 'peerid'}
|
||||
retval = self.client.serialize(retval)
|
||||
expected_code = 200
|
||||
else:
|
||||
retval = None
|
||||
expected_code = 204
|
||||
self._test_update_resource_action(resource, cmd, 'myid',
|
||||
subcmd, args, body, expected_code,
|
||||
retval)
|
||||
|
||||
def test_add_peer_to_bgp_speaker(self):
|
||||
# Add peer to BGP speaker: myid peer_id=peerid
|
||||
cmd = bgp_speaker.AddPeerToSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['myid', 'peerid']
|
||||
self._test_add_remove_peer('add', cmd, args)
|
||||
|
||||
def test_remove_peer_from_bgp_speaker(self):
|
||||
# Remove peer from BGP speaker: myid peer_id=peerid
|
||||
cmd = bgp_speaker.RemovePeerFromSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['myid', 'peerid']
|
||||
self._test_add_remove_peer('remove', cmd, args)
|
||||
|
||||
def _test_add_remove_network(self, action, cmd, args):
|
||||
# Add or Remove network to/from a BGP Speaker.
|
||||
resource = 'bgp_speaker'
|
||||
subcmd = '%s_gateway_network' % action
|
||||
body = {'network_id': 'netid'}
|
||||
if action == 'add':
|
||||
retval = {'network': 'netid'}
|
||||
retval = self.client.serialize(retval)
|
||||
expected_code = 200
|
||||
else:
|
||||
retval = None
|
||||
expected_code = 204
|
||||
self._test_update_resource_action(resource, cmd, 'myid',
|
||||
subcmd, args, body, expected_code,
|
||||
retval)
|
||||
|
||||
def test_add_network_to_bgp_speaker(self):
|
||||
# Add peer to BGP speaker: myid network_id=netid
|
||||
cmd = bgp_speaker.AddNetworkToSpeaker(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['myid', 'netid']
|
||||
self._test_add_remove_network('add', cmd, args)
|
||||
|
||||
def test_remove_network_from_bgp_speaker(self):
|
||||
# Remove network from BGP speaker: myid network_id=netid
|
||||
cmd = bgp_speaker.RemoveNetworkFromSpeaker(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['myid', 'netid']
|
||||
self._test_add_remove_network('remove', cmd, args)
|
||||
|
||||
def test_list_routes_advertised_by_a_bgp_speaker(self):
|
||||
# Retrieve advertised route list
|
||||
resources = 'advertised_routes'
|
||||
cmd = bgp_speaker.ListRoutesAdvertisedBySpeaker(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
bs_id = 'bgp_speaker_id1'
|
||||
path = ((self.client.bgp_speaker_path + '/get_advertised_routes') %
|
||||
bs_id)
|
||||
self._test_list_resources(resources, cmd, base_args=[bs_id],
|
||||
path=path)
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.flavor import flavor
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20FlavorJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def setUp(self):
|
||||
"""Prepare test environment."""
|
||||
super(CLITestV20FlavorJSON, self).setUp(plurals={'flavors': 'flavor'})
|
||||
self.register_non_admin_status_resource('flavor')
|
||||
self.register_non_admin_status_resource('service_profile')
|
||||
|
||||
def test_create_flavor_with_missing_params(self):
|
||||
"""Create test flavor with missing parameters."""
|
||||
resource = 'flavor'
|
||||
cmd = flavor.CreateFlavor(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'Test flavor'
|
||||
myid = 'myid'
|
||||
position_names = []
|
||||
position_values = []
|
||||
args = []
|
||||
self.assertRaises(
|
||||
SystemExit, self._test_create_resource,
|
||||
resource, cmd, name, myid, args, position_names, position_values)
|
||||
|
||||
def test_create_flavor_with_mandatory_params(self):
|
||||
"""Create test flavor with minimal parameters."""
|
||||
resource = 'flavor'
|
||||
cmd = flavor.CreateFlavor(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'Test flavor'
|
||||
myid = 'myid'
|
||||
service_type = 'DUMMY'
|
||||
# Defaults are returned in body
|
||||
position_names = ['name', 'service_type']
|
||||
position_values = [name, service_type]
|
||||
args = [name, service_type]
|
||||
self._test_create_resource(resource, cmd, name, myid, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_flavor_with_optional_params(self):
|
||||
"""Create test flavor including optional parameters."""
|
||||
resource = 'flavor'
|
||||
cmd = flavor.CreateFlavor(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'Test flavor'
|
||||
myid = 'myid'
|
||||
service_type = 'DUMMY'
|
||||
description = 'Test description'
|
||||
position_names = ['name', 'service_type', 'description', 'enabled']
|
||||
position_values = [name, service_type, description, 'False']
|
||||
args = [name, service_type,
|
||||
'--description', description,
|
||||
'--enabled=False']
|
||||
self._test_create_resource(resource, cmd, name, myid, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_delete_flavor(self):
|
||||
"""Delete flavor."""
|
||||
resource = 'flavor'
|
||||
cmd = flavor.DeleteFlavor(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
def test_list_flavors(self):
|
||||
"""List flavors test."""
|
||||
resources = 'flavors'
|
||||
cmd = flavor.ListFlavor(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_flavors_with_pagination(self):
|
||||
"""List flavors test with pagination."""
|
||||
resources = 'flavors'
|
||||
cmd = flavor.ListFlavor(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_flavors_with_sort(self):
|
||||
"""List flavors test with sorting by name and id."""
|
||||
resources = 'flavors'
|
||||
cmd = flavor.ListFlavor(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_show_flavor(self):
|
||||
"""Show flavor test."""
|
||||
resource = 'flavor'
|
||||
cmd = flavor.ShowFlavor(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_update_flavor_with_name(self):
|
||||
"""Update flavor test."""
|
||||
resource = 'flavor'
|
||||
cmd = flavor.UpdateFlavor(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
newname = 'Test New Name'
|
||||
newdescription = 'New Description'
|
||||
args = ['--name', newname,
|
||||
'--description', newdescription,
|
||||
'--enabled', 'False', self.test_id]
|
||||
self._test_update_resource(resource, cmd, self.test_id, args,
|
||||
{'name': newname,
|
||||
'description': newdescription,
|
||||
'enabled': 'False'})
|
||||
|
||||
def test_associate_flavor(self):
|
||||
"""Associate flavor test."""
|
||||
resource = 'service_profile'
|
||||
cmd = flavor.AssociateFlavor(test_cli20.MyApp(sys.stdout), None)
|
||||
flavor_id = 'flavor-id'
|
||||
profile_id = 'profile-id'
|
||||
name = ''
|
||||
args = [flavor_id, profile_id]
|
||||
position_names = ['id']
|
||||
position_values = [profile_id]
|
||||
self._test_create_resource(resource, cmd, name, profile_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource='flavor_profile_binding',
|
||||
parent_id=flavor_id)
|
||||
|
||||
def test_disassociate_flavor(self):
|
||||
"""Disassociate flavor test."""
|
||||
resource = 'flavor_profile_binding'
|
||||
cmd = flavor.DisassociateFlavor(test_cli20.MyApp(sys.stdout), None)
|
||||
flavor_id = 'flavor-id'
|
||||
profile_id = 'profile-id'
|
||||
args = [flavor_id, profile_id]
|
||||
self._test_delete_resource(resource, cmd, profile_id, args,
|
||||
parent_id=flavor_id)
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.flavor import flavor_profile
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20FlavorProfileJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def setUp(self):
|
||||
"""Prepare test environment."""
|
||||
super(CLITestV20FlavorProfileJSON, self).setUp(
|
||||
plurals={'service_profiles': 'service_profile'})
|
||||
self.register_non_admin_status_resource('service_profile')
|
||||
|
||||
def test_create_flavor_profile_with_mandatory_params(self):
|
||||
"""Create test flavor profile test."""
|
||||
resource = 'service_profile'
|
||||
cmd = flavor_profile.CreateFlavorProfile(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
name = ''
|
||||
description = 'Test flavor profile'
|
||||
myid = 'myid'
|
||||
metainfo = "{'a':'b'}"
|
||||
# Defaults are returned in body
|
||||
position_names = ['description', 'metainfo']
|
||||
position_values = [description, metainfo]
|
||||
args = ['--description', description, '--metainfo', metainfo]
|
||||
self._test_create_resource(resource, cmd, name, myid, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_flavor_profile_with_optional_params(self):
|
||||
"""Create test flavor profile disabled test."""
|
||||
resource = 'service_profile'
|
||||
cmd = flavor_profile.CreateFlavorProfile(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
name = ''
|
||||
description = 'Test flavor profile - disabled'
|
||||
myid = 'myid'
|
||||
driver = 'mydriver'
|
||||
metainfo = "{'a':'b'}"
|
||||
position_names = ['description', 'driver', 'metainfo', 'enabled']
|
||||
position_values = [description, driver, metainfo, 'False']
|
||||
args = ['--description', description, '--driver', driver,
|
||||
'--metainfo', metainfo, '--enabled=False']
|
||||
self._test_create_resource(resource, cmd, name, myid, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_list_flavor_profiles(self):
|
||||
"""List flavor profiles test."""
|
||||
resources = 'service_profiles'
|
||||
cmd = flavor_profile.ListFlavorProfile(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_flavor_profiles_with_pagination(self):
|
||||
"""List flavor profiles test with pagination."""
|
||||
resources = 'service_profiles'
|
||||
cmd = flavor_profile.ListFlavorProfile(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_flavor_profiles_with_sort(self):
|
||||
"""List flavor profiles test with sort by description."""
|
||||
resources = 'service_profiles'
|
||||
cmd = flavor_profile.ListFlavorProfile(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["description"],
|
||||
sort_dir=["asc"])
|
||||
|
||||
def test_show_flavor_profile(self):
|
||||
"""Show flavor profile test."""
|
||||
resource = 'service_profile'
|
||||
cmd = flavor_profile.ShowFlavorProfile(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_update_flavor_profile(self):
|
||||
"""Update flavor profile test."""
|
||||
resource = 'service_profile'
|
||||
cmd = flavor_profile.UpdateFlavorProfile(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
newdescription = 'Test new description'
|
||||
newdriver = 'NewDriver'
|
||||
newmetainfo = "{'c':'d'}"
|
||||
newenabled = "False"
|
||||
args = ['--description', newdescription,
|
||||
'--driver', newdriver,
|
||||
'--metainfo', newmetainfo,
|
||||
'--enabled', newenabled,
|
||||
self.test_id]
|
||||
self._test_update_resource(resource, cmd, self.test_id, args,
|
||||
{'description': newdescription,
|
||||
'driver': newdriver,
|
||||
'metainfo': newmetainfo,
|
||||
'enabled': newenabled})
|
||||
|
||||
def test_delete_flavor_profile(self):
|
||||
"""Delete flavor profile."""
|
||||
resource = 'service_profile'
|
||||
cmd = flavor_profile.DeleteFlavorProfile(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
# Copyright 2013 Big Switch Networks Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.fw import firewall
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20FirewallJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def test_create_firewall_with_mandatory_params(self):
|
||||
# firewall-create with mandatory (none) params.
|
||||
resource = 'firewall'
|
||||
cmd = firewall.CreateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
name = ''
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
policy_id = 'my-policy-id'
|
||||
args = ['--tenant-id', tenant_id, policy_id, ]
|
||||
position_names = ['firewall_policy_id', ]
|
||||
position_values = [policy_id, ]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=True, tenant_id=tenant_id)
|
||||
|
||||
def test_create_firewall_with_all_params(self):
|
||||
# firewall-create with all params set.
|
||||
resource = 'firewall'
|
||||
cmd = firewall.CreateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'my-name'
|
||||
description = 'my-desc'
|
||||
policy_id = 'my-policy-id'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--description', description,
|
||||
'--admin-state-down',
|
||||
'--tenant-id', tenant_id,
|
||||
policy_id]
|
||||
position_names = ['firewall_policy_id', ]
|
||||
position_values = [policy_id, ]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
description=description,
|
||||
admin_state_up=False,
|
||||
tenant_id=tenant_id)
|
||||
|
||||
def test_create_firewall_with_routers(self):
|
||||
resource = 'firewall'
|
||||
cmd = firewall.CreateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'my-name'
|
||||
policy_id = 'my-policy-id'
|
||||
my_id = 'my-id'
|
||||
args = ['--router', 'fake-id', '--router', 'fake-name', policy_id]
|
||||
router_ids = ['fake-id', 'fake-name']
|
||||
position_names = ['firewall_policy_id', 'router_ids']
|
||||
position_values = [policy_id, router_ids]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_list_firewalls(self):
|
||||
# firewall-list.
|
||||
resources = "firewalls"
|
||||
cmd = firewall.ListFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_firewalls_pagination(self):
|
||||
# firewall-list with pagination.
|
||||
resources = "firewalls"
|
||||
cmd = firewall.ListFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_firewalls_sort(self):
|
||||
# sorted list: firewall-list --sort-key name --sort-key id
|
||||
# --sort-key asc --sort-key desc
|
||||
resources = "firewalls"
|
||||
cmd = firewall.ListFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_firewalls_limit(self):
|
||||
# size (1000) limited list: firewall-list -P.
|
||||
resources = "firewalls"
|
||||
cmd = firewall.ListFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_firewall_id(self):
|
||||
# firewall-show test_id.
|
||||
resource = 'firewall'
|
||||
cmd = firewall.ShowFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_firewall_id_name(self):
|
||||
# firewall-show.
|
||||
resource = 'firewall'
|
||||
cmd = firewall.ShowFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_firewall(self):
|
||||
# firewall-update myid --name newname --tags a b.
|
||||
resource = 'firewall'
|
||||
cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'newname'],
|
||||
{'name': 'newname', })
|
||||
|
||||
def test_update_firewall_using_policy_name(self):
|
||||
# firewall-update myid --policy newpolicy.
|
||||
resource = 'firewall'
|
||||
cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--policy', 'newpolicy'],
|
||||
{'firewall_policy_id': 'newpolicy'})
|
||||
|
||||
def test_update_firewall_with_routers(self):
|
||||
resource = 'firewall'
|
||||
cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(
|
||||
resource, cmd, 'myid',
|
||||
['myid', '--router', 'fake-id', '--router', 'fake-name'],
|
||||
{'router_ids': ['fake-id', 'fake-name']})
|
||||
|
||||
def test_update_firewall_with_no_routers(self):
|
||||
resource = 'firewall'
|
||||
cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(
|
||||
resource, cmd, 'myid',
|
||||
['myid', '--no-routers'], {'router_ids': []})
|
||||
|
||||
def test_update_firewall_with_bad_router_options(self):
|
||||
resource = 'firewall'
|
||||
cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self.assertRaises(
|
||||
SystemExit,
|
||||
self._test_update_resource,
|
||||
resource, cmd, 'myid',
|
||||
['myid', '--no-routers', '--router', 'fake-id'], {})
|
||||
|
||||
def test_delete_firewall(self):
|
||||
# firewall-delete my-id.
|
||||
resource = 'firewall'
|
||||
cmd = firewall.DeleteFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
def test_update_firewall_admin_state(self):
|
||||
# firewall-update myid --admin-state-up True.
|
||||
resource = 'firewall'
|
||||
cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--admin-state-up', 'True'],
|
||||
{'admin_state_up': 'True'})
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
# Copyright 2013 Big Switch Networks Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
|
||||
from neutronclient.neutron.v2_0.fw import firewallpolicy
|
||||
from neutronclient import shell
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20FirewallPolicyJSON(test_cli20.CLITestV20Base):
|
||||
def setUp(self):
|
||||
super(CLITestV20FirewallPolicyJSON, self).setUp()
|
||||
|
||||
def test_create_firewall_policy_with_mandatory_params(self):
|
||||
# firewall-policy-create with mandatory (none) params only.
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.CreateFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
tenant_id = 'my-tenant'
|
||||
name = 'my-name'
|
||||
my_id = 'myid'
|
||||
args = ['--tenant-id', tenant_id,
|
||||
'--admin-state_up',
|
||||
name, ]
|
||||
position_names = ['name', ]
|
||||
position_values = [name, ]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=True, tenant_id=tenant_id)
|
||||
|
||||
def test_create_firewall_policy_with_all_params(self):
|
||||
# firewall-policy-create with rule param of misc format.
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.CreateFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
description = 'my-desc'
|
||||
firewall_rules_res = ['rule_id1', 'rule_id2']
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'myid'
|
||||
position_names = ['name', ]
|
||||
position_values = [name, ]
|
||||
|
||||
# check for both str and unicode format firewall_rules_arg
|
||||
for firewall_rules_arg in ['rule_id1 rule_id2', u'rule_id1 rule_id2']:
|
||||
args = ['--description', description,
|
||||
'--shared',
|
||||
'--firewall-rules', firewall_rules_arg,
|
||||
'--audited',
|
||||
'--tenant-id', tenant_id,
|
||||
'--admin-state_up',
|
||||
name]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
description=description, shared=True,
|
||||
firewall_rules=firewall_rules_res,
|
||||
audited=True, admin_state_up=True,
|
||||
tenant_id=tenant_id)
|
||||
|
||||
def test_list_firewall_policies(self):
|
||||
# firewall-policy-list.
|
||||
resources = "firewall_policies"
|
||||
cmd = firewallpolicy.ListFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_firewall_policies_pagination(self):
|
||||
# firewall-policy-list."""
|
||||
resources = "firewall_policies"
|
||||
cmd = firewallpolicy.ListFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_firewall_policies_sort(self):
|
||||
# sorted list: firewall-policy-list --sort-key name --sort-key id
|
||||
# --sort-key asc --sort-key desc
|
||||
resources = "firewall_policies"
|
||||
cmd = firewallpolicy.ListFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_firewall_policies_limit(self):
|
||||
# size (1000) limited list: firewall-policy-list -P.
|
||||
resources = "firewall_policies"
|
||||
cmd = firewallpolicy.ListFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_firewall_policy_id(self):
|
||||
# firewall-policy-show test_id.
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.ShowFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_firewall_policy_id_name(self):
|
||||
# firewall-policy-show.
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.ShowFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_firewall_policy(self):
|
||||
# firewall-policy-update myid --name newname.
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.UpdateFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'newname'],
|
||||
{'name': 'newname', })
|
||||
|
||||
def test_update_firewall_policy_with_rules(self):
|
||||
# firewall-policy-update myid --firewall-rules "rule1 rule2".
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.UpdateFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
firewall_rules_arg = u'rule_id3 rule_id4'
|
||||
firewall_rules_res = ['rule_id3', 'rule_id4']
|
||||
self._test_update_resource(
|
||||
resource, cmd, 'myid',
|
||||
['myid', '--firewall-rules', firewall_rules_arg],
|
||||
{'firewall_rules': firewall_rules_res, })
|
||||
|
||||
def test_delete_firewall_policy(self):
|
||||
# firewall-policy-delete my-id.
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.DeleteFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'myid1'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
def test_insert_firewall_rule(self):
|
||||
# firewall-policy-insert-rule myid newruleid --insert-before ruleAid
|
||||
# --insert-after ruleBid
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.FirewallPolicyInsertRule(
|
||||
test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
myid = 'myid'
|
||||
args = ['myid', 'newrule',
|
||||
'--insert-before', 'rule2',
|
||||
'--insert-after', 'rule1']
|
||||
extrafields = {'firewall_rule_id': 'newrule',
|
||||
'insert_before': 'rule2',
|
||||
'insert_after': 'rule1'}
|
||||
|
||||
body = extrafields
|
||||
path = getattr(self.client, resource + "_insert_path")
|
||||
cmd_parser = cmd.get_parser(resource + "_insert_rule")
|
||||
resp = (test_cli20.MyResp(204), None)
|
||||
|
||||
with mock.patch.object(cmd, "get_client",
|
||||
return_value=self.client) as mock_get_client, \
|
||||
mock.patch.object(self.client.httpclient, "request",
|
||||
return_value=resp) as mock_request:
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
self.assert_mock_multiple_calls_with_same_arguments(
|
||||
mock_get_client, mock.call(), 4)
|
||||
mock_request.assert_called_once_with(
|
||||
test_cli20.MyUrlComparator(
|
||||
test_cli20.end_url(path % myid),
|
||||
self.client),
|
||||
'PUT', body=test_cli20.MyComparator(body, self.client),
|
||||
headers=test_cli20.ContainsKeyValue(
|
||||
{'X-Auth-Token': test_cli20.TOKEN}))
|
||||
|
||||
def test_remove_firewall_rule(self):
|
||||
# firewall-policy-remove-rule myid ruleid
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.FirewallPolicyRemoveRule(
|
||||
test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
myid = 'myid'
|
||||
args = ['myid', 'removerule']
|
||||
extrafields = {'firewall_rule_id': 'removerule', }
|
||||
|
||||
body = extrafields
|
||||
path = getattr(self.client, resource + "_remove_path")
|
||||
cmd_parser = cmd.get_parser(resource + "_remove_rule")
|
||||
resp = (test_cli20.MyResp(204), None)
|
||||
|
||||
with mock.patch.object(cmd, "get_client",
|
||||
return_value=self.client) as mock_get_client, \
|
||||
mock.patch.object(self.client.httpclient, "request",
|
||||
return_value=resp) as mock_request:
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
self.assert_mock_multiple_calls_with_same_arguments(
|
||||
mock_get_client, mock.call(), 2)
|
||||
mock_request.assert_called_once_with(
|
||||
test_cli20.MyUrlComparator(
|
||||
test_cli20.end_url(path % myid),
|
||||
self.client),
|
||||
'PUT', body=test_cli20.MyComparator(body, self.client),
|
||||
headers=test_cli20.ContainsKeyValue(
|
||||
{'X-Auth-Token': test_cli20.TOKEN}))
|
||||
|
||||
def test_update_firewall_policy_name_shared_audited(self):
|
||||
# firewall-policy-update myid --name newname2 --shared --audited
|
||||
resource = 'firewall_policy'
|
||||
cmd = firewallpolicy.UpdateFirewallPolicy(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'newname2',
|
||||
'--shared', 'True', '--audited', 'True'],
|
||||
{'name': 'newname2',
|
||||
'shared': 'True', 'audited': 'True'})
|
||||
|
|
@ -1,251 +0,0 @@
|
|||
# Copyright 2013 Big Switch Networks Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.fw import firewallrule
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20FirewallRuleJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def _test_create_firewall_rule_with_mandatory_params(self, enabled):
|
||||
# firewall-rule-create with mandatory (none) params only.
|
||||
resource = 'firewall_rule'
|
||||
cmd = firewallrule.CreateFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
tenant_id = 'my-tenant'
|
||||
name = ''
|
||||
my_id = 'myid'
|
||||
protocol = 'tcp'
|
||||
action = 'allow'
|
||||
ip_version = 4
|
||||
args = ['--tenant-id', tenant_id,
|
||||
'--admin-state-up',
|
||||
'--protocol', protocol,
|
||||
'--action', action,
|
||||
'--enabled', enabled]
|
||||
position_names = []
|
||||
position_values = []
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
protocol=protocol, action=action,
|
||||
enabled=enabled, tenant_id=tenant_id,
|
||||
ip_version=ip_version)
|
||||
|
||||
def test_create_enabled_firewall_rule_with_mandatory_params_lcase(self):
|
||||
self._test_create_firewall_rule_with_mandatory_params(enabled='true')
|
||||
|
||||
def test_create_disabled_firewall_rule_with_mandatory_params_lcase(self):
|
||||
self._test_create_firewall_rule_with_mandatory_params(enabled='false')
|
||||
|
||||
def test_create_enabled_firewall_rule_with_mandatory_params(self):
|
||||
self._test_create_firewall_rule_with_mandatory_params(enabled='True')
|
||||
|
||||
def test_create_disabled_firewall_rule_with_mandatory_params(self):
|
||||
self._test_create_firewall_rule_with_mandatory_params(enabled='False')
|
||||
|
||||
def _setup_create_firewall_rule_with_all_params(
|
||||
self, protocol='tcp', protocol_cli=None,
|
||||
action='allow', action_cli=None, ip_version='4'):
|
||||
# firewall-rule-create with all params set.
|
||||
resource = 'firewall_rule'
|
||||
cmd = firewallrule.CreateFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
name = 'my-name'
|
||||
description = 'my-desc'
|
||||
source_ip = '192.168.1.0/24'
|
||||
destination_ip = '192.168.2.0/24'
|
||||
source_port = '0:65535'
|
||||
destination_port = '0:65535'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'myid'
|
||||
enabled = 'True'
|
||||
args = ['--description', description,
|
||||
'--shared',
|
||||
'--protocol', protocol_cli or protocol,
|
||||
'--ip-version', ip_version,
|
||||
'--source-ip-address', source_ip,
|
||||
'--destination-ip-address', destination_ip,
|
||||
'--source-port', source_port,
|
||||
'--destination-port', destination_port,
|
||||
'--action', action_cli or action,
|
||||
'--enabled', enabled,
|
||||
'--admin-state-up',
|
||||
'--tenant-id', tenant_id]
|
||||
position_names = []
|
||||
position_values = []
|
||||
if protocol == 'any':
|
||||
protocol = None
|
||||
if ip_version == '4' or ip_version == '6':
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
description=description, shared=True,
|
||||
protocol=protocol,
|
||||
ip_version=int(ip_version),
|
||||
source_ip_address=source_ip,
|
||||
destination_ip_address=destination_ip,
|
||||
source_port=source_port,
|
||||
destination_port=destination_port,
|
||||
action=action, enabled='True',
|
||||
tenant_id=tenant_id)
|
||||
else:
|
||||
self.assertRaises(SystemExit, self._test_create_resource,
|
||||
resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
ip_version=int(ip_version),
|
||||
source_ip_address=source_ip,
|
||||
destination_ip_address=destination_ip,
|
||||
source_port=source_port,
|
||||
destination_port=destination_port,
|
||||
action=action, enabled='True',
|
||||
tenant_id=tenant_id)
|
||||
|
||||
def test_create_firewall_rule_with_all_params(self):
|
||||
self._setup_create_firewall_rule_with_all_params()
|
||||
|
||||
def test_create_firewall_rule_with_proto_any(self):
|
||||
self._setup_create_firewall_rule_with_all_params(protocol='any')
|
||||
|
||||
def test_create_firewall_rule_with_IP_version_6(self):
|
||||
self._setup_create_firewall_rule_with_all_params(ip_version='6')
|
||||
|
||||
def test_create_firewall_rule_with_invalid_IP_version(self):
|
||||
self._setup_create_firewall_rule_with_all_params(ip_version='5')
|
||||
|
||||
def test_create_firewall_rule_with_proto_action_upper_capitalized(self):
|
||||
for protocol in ('TCP', 'Tcp', 'ANY', 'AnY'):
|
||||
self._setup_create_firewall_rule_with_all_params(
|
||||
protocol=protocol.lower(),
|
||||
protocol_cli=protocol)
|
||||
for action in ('Allow', 'DENY', 'reject'):
|
||||
self._setup_create_firewall_rule_with_all_params(
|
||||
action=action.lower(),
|
||||
action_cli=action)
|
||||
|
||||
def test_list_firewall_rules(self):
|
||||
# firewall-rule-list.
|
||||
resources = "firewall_rules"
|
||||
cmd = firewallrule.ListFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_firewall_rules_pagination(self):
|
||||
# firewall-rule-list.
|
||||
resources = "firewall_rules"
|
||||
cmd = firewallrule.ListFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_firewall_rules_sort(self):
|
||||
# firewall-rule-list --sort-key name --sort-key id --sort-key asc
|
||||
# --sort-key desc
|
||||
resources = "firewall_rules"
|
||||
cmd = firewallrule.ListFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_firewall_rules_limit(self):
|
||||
# firewall-rule-list -P."""
|
||||
resources = "firewall_rules"
|
||||
cmd = firewallrule.ListFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_firewall_rule_id(self):
|
||||
# firewall-rule-show test_id.
|
||||
resource = 'firewall_rule'
|
||||
cmd = firewallrule.ShowFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_firewall_rule_id_name(self):
|
||||
# firewall-rule-show.
|
||||
resource = 'firewall_rule'
|
||||
cmd = firewallrule.ShowFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_firewall_rule(self):
|
||||
# firewall-rule-update myid --name newname.
|
||||
resource = 'firewall_rule'
|
||||
cmd = firewallrule.UpdateFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'newname'],
|
||||
{'name': 'newname', })
|
||||
|
||||
# firewall-rule-update myid --protocol any.
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--protocol', 'any'],
|
||||
{'protocol': None, })
|
||||
|
||||
# firewall-rule-update myid --description any
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--description', 'any'],
|
||||
{'description': 'any', })
|
||||
|
||||
# firewall-rule-update myid --source_ip_address 192.192.192.192
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--source_ip_address',
|
||||
'192.192.192.192'],
|
||||
{'source_ip_address': '192.192.192.192', })
|
||||
|
||||
# firewall-rule-update myid --source_port 32767
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--source_port', '32767'],
|
||||
{'source_port': '32767', })
|
||||
|
||||
# firewall-rule-update myid --destination_ip_address 0.1.0.1
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--destination_ip_address',
|
||||
'0.1.0.1'],
|
||||
{'destination_ip_address': '0.1.0.1', })
|
||||
|
||||
# firewall-rule-update myid --destination_port 65432
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--destination_port',
|
||||
'65432'],
|
||||
{'destination_port': '65432', })
|
||||
|
||||
# firewall-rule-update myid --enabled False
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--enabled', 'False'],
|
||||
{'enabled': 'False', })
|
||||
|
||||
# firewall-rule-update myid --action reject
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--action', 'reject'],
|
||||
{'action': 'reject', })
|
||||
|
||||
# firewall-rule-update myid --shared false
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--shared', 'false'],
|
||||
{'shared': 'false', })
|
||||
|
||||
def test_delete_firewall_rule(self):
|
||||
# firewall-rule-delete my-id.
|
||||
resource = 'firewall_rule'
|
||||
cmd = firewallrule.DeleteFirewallRule(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'myid1'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
|
||||
from neutronclient.neutron.v2_0.lb import healthmonitor
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbHealthmonitorJSON(test_cli20.CLITestV20Base):
|
||||
def test_create_healthmonitor_with_mandatory_params(self):
|
||||
# lb-healthmonitor-create with mandatory params only.
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
admin_state_up = False
|
||||
delay = '60'
|
||||
max_retries = '2'
|
||||
timeout = '10'
|
||||
type = 'TCP'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--admin-state-down',
|
||||
'--delay', delay,
|
||||
'--max-retries', max_retries,
|
||||
'--timeout', timeout,
|
||||
'--type', type,
|
||||
'--tenant-id', tenant_id]
|
||||
position_names = ['admin_state_up', 'delay', 'max_retries', 'timeout',
|
||||
'type', 'tenant_id']
|
||||
position_values = [admin_state_up, delay, max_retries, timeout, type,
|
||||
tenant_id]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_healthmonitor_with_all_params(self):
|
||||
# lb-healthmonitor-create with all params set.
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
admin_state_up = False
|
||||
delay = '60'
|
||||
expected_codes = '200-202,204'
|
||||
http_method = 'HEAD'
|
||||
max_retries = '2'
|
||||
timeout = '10'
|
||||
type = 'TCP'
|
||||
tenant_id = 'my-tenant'
|
||||
url_path = '/health'
|
||||
my_id = 'my-id'
|
||||
args = ['--admin-state-down',
|
||||
'--delay', delay,
|
||||
'--expected-codes', expected_codes,
|
||||
'--http-method', http_method,
|
||||
'--max-retries', max_retries,
|
||||
'--timeout', timeout,
|
||||
'--type', type,
|
||||
'--tenant-id', tenant_id,
|
||||
'--url-path', url_path]
|
||||
position_names = ['admin_state_up', 'delay',
|
||||
'expected_codes', 'http_method',
|
||||
'max_retries', 'timeout',
|
||||
'type', 'tenant_id', 'url_path']
|
||||
position_values = [admin_state_up, delay,
|
||||
expected_codes, http_method,
|
||||
max_retries, timeout,
|
||||
type, tenant_id, url_path]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_list_healthmonitors(self):
|
||||
# lb-healthmonitor-list.
|
||||
resources = "health_monitors"
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_healthmonitors_pagination(self):
|
||||
# lb-healthmonitor-list.
|
||||
resources = "health_monitors"
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_healthmonitors_sort(self):
|
||||
# lb-healthmonitor-list --sort-key name --sort-key id --sort-key asc
|
||||
# --sort-key desc
|
||||
resources = "health_monitors"
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_healthmonitors_limit(self):
|
||||
# lb-healthmonitor-list -P.
|
||||
resources = "health_monitors"
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_healthmonitor_id(self):
|
||||
# lb-healthmonitor-show test_id.
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.ShowHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_update_health_monitor(self):
|
||||
# lb-healthmonitor-update myid --name myname --tags a b.
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.UpdateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--timeout', '5'],
|
||||
{'timeout': '5', })
|
||||
|
||||
def test_delete_healthmonitor(self):
|
||||
# lb-healthmonitor-delete my-id."""
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.DeleteHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
def test_associate_healthmonitor(self):
|
||||
cmd = healthmonitor.AssociateHealthMonitor(
|
||||
test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
resource = 'health_monitor'
|
||||
health_monitor_id = 'hm-id'
|
||||
pool_id = 'p_id'
|
||||
args = [health_monitor_id, pool_id]
|
||||
|
||||
body = {resource: {'id': health_monitor_id}}
|
||||
result = {resource: {'id': health_monitor_id}, }
|
||||
result_str = self.client.serialize(result)
|
||||
|
||||
path = getattr(self.client,
|
||||
"associate_pool_health_monitors_path") % pool_id
|
||||
return_tup = (test_cli20.MyResp(200), result_str)
|
||||
cmd_parser = cmd.get_parser('test_' + resource)
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
|
||||
with mock.patch.object(cmd, "get_client",
|
||||
return_value=self.client) as mock_get_client, \
|
||||
mock.patch.object(self.client.httpclient, "request",
|
||||
return_value=return_tup) as mock_request:
|
||||
cmd.run(parsed_args)
|
||||
|
||||
mock_get_client.assert_called_once_with()
|
||||
mock_request.assert_called_once_with(
|
||||
test_cli20.end_url(path), 'POST',
|
||||
body=test_cli20.MyComparator(body, self.client),
|
||||
headers=test_cli20.ContainsKeyValue(
|
||||
{'X-Auth-Token': test_cli20.TOKEN}))
|
||||
|
||||
def test_disassociate_healthmonitor(self):
|
||||
cmd = healthmonitor.DisassociateHealthMonitor(
|
||||
test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
resource = 'health_monitor'
|
||||
health_monitor_id = 'hm-id'
|
||||
pool_id = 'p_id'
|
||||
args = [health_monitor_id, pool_id]
|
||||
|
||||
path = (getattr(self.client,
|
||||
"disassociate_pool_health_monitors_path") %
|
||||
{'pool': pool_id, 'health_monitor': health_monitor_id})
|
||||
return_tup = (test_cli20.MyResp(204), None)
|
||||
cmd_parser = cmd.get_parser('test_' + resource)
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
|
||||
with mock.patch.object(cmd, "get_client",
|
||||
return_value=self.client) as mock_get_client, \
|
||||
mock.patch.object(self.client.httpclient, "request",
|
||||
return_value=return_tup) as mock_request:
|
||||
cmd.run(parsed_args)
|
||||
|
||||
mock_get_client.assert_called_once_with()
|
||||
mock_request.assert_called_once_with(
|
||||
test_cli20.end_url(path), 'DELETE',
|
||||
body=None,
|
||||
headers=test_cli20.ContainsKeyValue(
|
||||
{'X-Auth-Token': test_cli20.TOKEN}))
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.lb import member
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbMemberJSON(test_cli20.CLITestV20Base):
|
||||
def setUp(self):
|
||||
super(CLITestV20LbMemberJSON, self).setUp(plurals={'tags': 'tag'})
|
||||
|
||||
def test_create_member(self):
|
||||
# lb-member-create with mandatory params only.
|
||||
resource = 'member'
|
||||
cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
address = '10.0.0.1'
|
||||
port = '8080'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
pool_id = 'pool-id'
|
||||
args = ['--address', address, '--protocol-port', port,
|
||||
'--tenant-id', tenant_id, pool_id]
|
||||
position_names = ['address', 'protocol_port', 'tenant_id', 'pool_id',
|
||||
'admin_state_up']
|
||||
position_values = [address, port, tenant_id, pool_id, True]
|
||||
self._test_create_resource(resource, cmd, None, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=None)
|
||||
|
||||
def test_create_member_all_params(self):
|
||||
# lb-member-create with all available params.
|
||||
resource = 'member'
|
||||
cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
address = '10.0.0.1'
|
||||
admin_state_up = False
|
||||
port = '8080'
|
||||
weight = '1'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
pool_id = 'pool-id'
|
||||
args = ['--address', address, '--admin-state-down',
|
||||
'--protocol-port', port, '--weight', weight,
|
||||
'--tenant-id', tenant_id, pool_id]
|
||||
position_names = [
|
||||
'address', 'admin_state_up', 'protocol_port', 'weight',
|
||||
'tenant_id', 'pool_id'
|
||||
]
|
||||
position_values = [address, admin_state_up, port, weight,
|
||||
tenant_id, pool_id]
|
||||
self._test_create_resource(resource, cmd, None, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=None)
|
||||
|
||||
def test_list_members(self):
|
||||
# lb-member-list.
|
||||
resources = "members"
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_members_pagination(self):
|
||||
# lb-member-list.
|
||||
resources = "members"
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_members_sort(self):
|
||||
# lb-member-list --sort-key name --sort-key id --sort-key asc
|
||||
# --sort-key desc
|
||||
resources = "members"
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_members_limit(self):
|
||||
# lb-member-list -P.
|
||||
resources = "members"
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_member_id(self):
|
||||
# lb-member-show test_id.
|
||||
resource = 'member'
|
||||
cmd = member.ShowMember(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_update_member(self):
|
||||
# lb-member-update myid --name myname --tags a b.
|
||||
resource = 'member'
|
||||
cmd = member.UpdateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'myname',
|
||||
'--tags', 'a', 'b'],
|
||||
{'name': 'myname', 'tags': ['a', 'b'], })
|
||||
|
||||
def test_delete_member(self):
|
||||
# lb-member-delete my-id.
|
||||
resource = 'member'
|
||||
cmd = member.DeleteMember(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
|
||||
from neutronclient.neutron.v2_0.lb import pool
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbPoolJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def test_create_pool_with_mandatory_params(self):
|
||||
# lb-pool-create with mandatory params only.
|
||||
resource = 'pool'
|
||||
cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'my-name'
|
||||
lb_method = 'ROUND_ROBIN'
|
||||
protocol = 'HTTP'
|
||||
subnet_id = 'subnet-id'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--lb-method', lb_method,
|
||||
'--name', name,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id]
|
||||
position_names = ['admin_state_up', 'lb_method', 'name',
|
||||
'protocol', 'subnet_id', 'tenant_id']
|
||||
position_values = [True, lb_method, name,
|
||||
protocol, subnet_id, tenant_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_pool_with_all_params(self):
|
||||
# lb-pool-create with all params set.
|
||||
resource = 'pool'
|
||||
cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'my-name'
|
||||
description = 'my-desc'
|
||||
lb_method = 'ROUND_ROBIN'
|
||||
protocol = 'HTTP'
|
||||
subnet_id = 'subnet-id'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
provider = 'lbaas'
|
||||
args = ['--admin-state-down',
|
||||
'--description', description,
|
||||
'--lb-method', lb_method,
|
||||
'--name', name,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id,
|
||||
'--provider', provider]
|
||||
position_names = ['admin_state_up', 'description', 'lb_method', 'name',
|
||||
'protocol', 'subnet_id', 'tenant_id', 'provider']
|
||||
position_values = [False, description, lb_method, name,
|
||||
protocol, subnet_id, tenant_id, provider]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_list_pools(self):
|
||||
# lb-pool-list.
|
||||
resources = "pools"
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_pools_pagination(self):
|
||||
# lb-pool-list.
|
||||
resources = "pools"
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_pools_sort(self):
|
||||
# lb-pool-list --sort-key name --sort-key id --sort-key asc
|
||||
# --sort-key desc
|
||||
resources = "pools"
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_pools_limit(self):
|
||||
# lb-pool-list -P.
|
||||
resources = "pools"
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_pool_id(self):
|
||||
# lb-pool-show test_id.
|
||||
resource = 'pool'
|
||||
cmd = pool.ShowPool(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_pool_id_name(self):
|
||||
# lb-pool-show.
|
||||
resource = 'pool'
|
||||
cmd = pool.ShowPool(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_pool(self):
|
||||
# lb-pool-update myid --name newname --tags a b.
|
||||
resource = 'pool'
|
||||
cmd = pool.UpdatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'newname'],
|
||||
{'name': 'newname', })
|
||||
|
||||
def test_delete_pool(self):
|
||||
# lb-pool-delete my-id.
|
||||
resource = 'pool'
|
||||
cmd = pool.DeletePool(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
def test_retrieve_pool_stats(self):
|
||||
# lb-pool-stats test_id.
|
||||
resource = 'pool'
|
||||
cmd = pool.RetrievePoolStats(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = self.test_id
|
||||
fields = ['bytes_in', 'bytes_out']
|
||||
args = ['--fields', 'bytes_in', '--fields', 'bytes_out', my_id]
|
||||
|
||||
query = "&".join(["fields=%s" % field for field in fields])
|
||||
expected_res = {'stats': {'bytes_in': '1234', 'bytes_out': '4321'}}
|
||||
resstr = self.client.serialize(expected_res)
|
||||
path = getattr(self.client, "pool_path_stats")
|
||||
return_tup = (test_cli20.MyResp(200), resstr)
|
||||
|
||||
cmd_parser = cmd.get_parser("test_" + resource)
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
|
||||
with mock.patch.object(cmd, "get_client",
|
||||
return_value=self.client) as mock_get_client, \
|
||||
mock.patch.object(self.client.httpclient, "request",
|
||||
return_value=return_tup) as mock_request:
|
||||
cmd.run(parsed_args)
|
||||
|
||||
self.assert_mock_multiple_calls_with_same_arguments(
|
||||
mock_get_client, mock.call(), 2)
|
||||
mock_request.assert_called_once_with(
|
||||
test_cli20.end_url(path % my_id, query), 'GET',
|
||||
body=None,
|
||||
headers=test_cli20.ContainsKeyValue(
|
||||
{'X-Auth-Token': test_cli20.TOKEN}))
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertIn('bytes_in', _str)
|
||||
self.assertIn('bytes_out', _str)
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.lb import vip
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbVipJSON(test_cli20.CLITestV20Base):
|
||||
def setUp(self):
|
||||
super(CLITestV20LbVipJSON, self).setUp(plurals={'tags': 'tag'})
|
||||
|
||||
def test_create_vip_with_mandatory_params(self):
|
||||
# lb-vip-create with all mandatory params.
|
||||
resource = 'vip'
|
||||
cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
pool_id = 'my-pool-id'
|
||||
name = 'my-name'
|
||||
subnet_id = 'subnet-id'
|
||||
protocol_port = '1000'
|
||||
protocol = 'TCP'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--name', name,
|
||||
'--protocol-port', protocol_port,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id,
|
||||
pool_id]
|
||||
position_names = ['pool_id', 'name', 'protocol_port', 'protocol',
|
||||
'subnet_id', 'tenant_id']
|
||||
position_values = [pool_id, name, protocol_port, protocol,
|
||||
subnet_id, tenant_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=True)
|
||||
|
||||
def test_create_vip_with_all_params(self):
|
||||
# lb-vip-create with all params.
|
||||
resource = 'vip'
|
||||
cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
pool_id = 'my-pool-id'
|
||||
name = 'my-name'
|
||||
description = 'my-desc'
|
||||
address = '10.0.0.2'
|
||||
admin_state = False
|
||||
connection_limit = '1000'
|
||||
subnet_id = 'subnet-id'
|
||||
protocol_port = '80'
|
||||
protocol = 'TCP'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--name', name,
|
||||
'--description', description,
|
||||
'--address', address,
|
||||
'--admin-state-down',
|
||||
'--connection-limit', connection_limit,
|
||||
'--protocol-port', protocol_port,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id,
|
||||
pool_id]
|
||||
position_names = ['pool_id', 'name', 'description', 'address',
|
||||
'admin_state_up', 'connection_limit',
|
||||
'protocol_port', 'protocol', 'subnet_id',
|
||||
'tenant_id']
|
||||
position_values = [pool_id, name, description, address,
|
||||
admin_state, connection_limit, protocol_port,
|
||||
protocol, subnet_id,
|
||||
tenant_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_vip_with_session_persistence_params(self):
|
||||
# lb-vip-create with mandatory and session-persistence params.
|
||||
resource = 'vip'
|
||||
cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
pool_id = 'my-pool-id'
|
||||
name = 'my-name'
|
||||
subnet_id = 'subnet-id'
|
||||
protocol_port = '1000'
|
||||
protocol = 'TCP'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--name', name,
|
||||
'--protocol-port', protocol_port,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id,
|
||||
pool_id,
|
||||
'--session-persistence', 'type=dict',
|
||||
'type=cookie,cookie_name=pie',
|
||||
'--optional-param', 'any']
|
||||
position_names = ['pool_id', 'name', 'protocol_port', 'protocol',
|
||||
'subnet_id', 'tenant_id', 'optional_param']
|
||||
position_values = [pool_id, name, protocol_port, protocol,
|
||||
subnet_id, tenant_id, 'any']
|
||||
extra_body = {
|
||||
'session_persistence': {
|
||||
'type': 'cookie',
|
||||
'cookie_name': 'pie',
|
||||
},
|
||||
}
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=True, extra_body=extra_body)
|
||||
|
||||
def test_list_vips(self):
|
||||
# lb-vip-list.
|
||||
resources = "vips"
|
||||
cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_vips_pagination(self):
|
||||
# lb-vip-list.
|
||||
resources = "vips"
|
||||
cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_vips_sort(self):
|
||||
# lb-vip-list --sort-key name --sort-key id --sort-key asc
|
||||
# --sort-key desc
|
||||
resources = "vips"
|
||||
cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_vips_limit(self):
|
||||
# lb-vip-list -P.
|
||||
resources = "vips"
|
||||
cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_vip_id(self):
|
||||
# lb-vip-show test_id.
|
||||
resource = 'vip'
|
||||
cmd = vip.ShowVip(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_vip_id_name(self):
|
||||
# lb-vip-show.
|
||||
resource = 'vip'
|
||||
cmd = vip.ShowVip(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_vip(self):
|
||||
# lb-vip-update myid --name myname --tags a b.
|
||||
resource = 'vip'
|
||||
cmd = vip.UpdateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'myname',
|
||||
'--tags', 'a', 'b'],
|
||||
{'name': 'myname', 'tags': ['a', 'b'], })
|
||||
|
||||
def test_update_vip_with_session_persistence(self):
|
||||
resource = 'vip'
|
||||
cmd = vip.UpdateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
body = {
|
||||
'session_persistence': {
|
||||
'type': 'source',
|
||||
},
|
||||
}
|
||||
args = ['myid', '--session-persistence', 'type=dict',
|
||||
'type=source']
|
||||
self._test_update_resource(resource, cmd, 'myid', args, body)
|
||||
|
||||
def test_update_vip_with_session_persistence_and_name(self):
|
||||
resource = 'vip'
|
||||
cmd = vip.UpdateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
body = {
|
||||
'name': 'newname',
|
||||
'session_persistence': {
|
||||
'type': 'cookie',
|
||||
'cookie_name': 'pie',
|
||||
},
|
||||
}
|
||||
args = ['myid', '--name', 'newname',
|
||||
'--session-persistence', 'type=dict',
|
||||
'type=cookie,cookie_name=pie']
|
||||
self._test_update_resource(resource, cmd, 'myid', args, body)
|
||||
|
||||
def test_delete_vip(self):
|
||||
# lb-vip-delete my-id.
|
||||
resource = 'vip'
|
||||
cmd = vip.DeleteVip(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
# Copyright 2014 Blue Box Group, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.lb.v2 import healthmonitor
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbHealthMonitorJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def test_create_healthmonitor_with_mandatory_params(self):
|
||||
# lbaas-healthmonitor-create with mandatory params only.
|
||||
resource = 'healthmonitor'
|
||||
cmd_resource = 'lbaas_healthmonitor'
|
||||
cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'my-id'
|
||||
type = 'PING'
|
||||
max_retries = '3'
|
||||
delay = '10'
|
||||
timeout = '60'
|
||||
pool = 'pool1'
|
||||
args = ['--type', type, '--max-retries', max_retries,
|
||||
'--delay', delay, '--timeout', timeout, '--pool', pool]
|
||||
position_names = ['type', 'max_retries', 'delay', 'timeout', 'pool_id']
|
||||
position_values = [type, max_retries, delay, timeout, pool]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_create_healthmonitor_with_all_params(self):
|
||||
# lbaas-healthmonitor-create with all params set.
|
||||
resource = 'healthmonitor'
|
||||
cmd_resource = 'lbaas_healthmonitor'
|
||||
cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'my-id'
|
||||
type = 'PING'
|
||||
max_retries = '3'
|
||||
delay = '10'
|
||||
timeout = '60'
|
||||
http_method = 'GET'
|
||||
expected_codes = '201'
|
||||
url_path = '/somepath'
|
||||
pool = 'pool1'
|
||||
name = 'healthmonitor1'
|
||||
args = ['--admin-state-down', '--http-method', http_method,
|
||||
'--expected-codes', expected_codes, '--url-path', url_path,
|
||||
'--type', type, '--max-retries', max_retries,
|
||||
'--delay', delay, '--timeout', timeout, '--pool', pool,
|
||||
'--name', name]
|
||||
position_names = ['admin_state_up', 'http_method', 'expected_codes',
|
||||
'url_path', 'type', 'max_retries', 'delay',
|
||||
'timeout', 'pool_id', 'name']
|
||||
position_values = [False, http_method, expected_codes, url_path,
|
||||
type, max_retries, delay, timeout, pool, name]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_list_healthmonitors(self):
|
||||
# lbaas-healthmonitor-list.
|
||||
resources = 'healthmonitors'
|
||||
cmd_resources = 'lbaas_healthmonitors'
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_healthmonitors_pagination(self):
|
||||
# lbaas-healthmonitor-list with pagination.
|
||||
resources = 'healthmonitors'
|
||||
cmd_resources = 'lbaas_healthmonitors'
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources_with_pagination(resources, cmd,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_healthmonitors_sort(self):
|
||||
# lbaas-healthmonitor-list --sort-key id --sort-key asc.
|
||||
resources = 'healthmonitors'
|
||||
cmd_resources = 'lbaas_healthmonitors'
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_healthmonitors_limit(self):
|
||||
# lbaas-healthmonitor-list -P.
|
||||
resources = 'healthmonitors'
|
||||
cmd_resources = 'lbaas_healthmonitors'
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_show_healthmonitor_id(self):
|
||||
# lbaas-healthmonitor-show test_id.
|
||||
resource = 'healthmonitor'
|
||||
cmd_resource = 'lbaas_healthmonitor'
|
||||
cmd = healthmonitor.ShowHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'],
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_show_healthmonitor_id_name(self):
|
||||
# lbaas-healthmonitor-show.
|
||||
resource = 'healthmonitor'
|
||||
cmd_resource = 'lbaas_healthmonitor'
|
||||
cmd = healthmonitor.ShowHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'],
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def _test_update_hm(self, args, expected_values):
|
||||
resource = 'healthmonitor'
|
||||
cmd_resource = 'lbaas_healthmonitor'
|
||||
my_id = 'myid'
|
||||
cmd = healthmonitor.UpdateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args.insert(0, my_id)
|
||||
self._test_update_resource(resource, cmd, my_id,
|
||||
args,
|
||||
expected_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_update_healthmonitor(self):
|
||||
# lbaas-healthmonitor-update myid --name newname.
|
||||
self._test_update_hm(['--name', 'newname'], {'name': 'newname', })
|
||||
# lbaas-healthmonitor-update myid --delay 10.
|
||||
self._test_update_hm(['--delay', '10'], {'delay': '10'})
|
||||
# lbaas-healthmonitor-update myid --timeout 5.
|
||||
self._test_update_hm(['--timeout', '5'], {'timeout': '5', })
|
||||
# lbaas-healthmonitor-update myid --delay 10.
|
||||
self._test_update_hm(['--http-method', 'OPTIONS'],
|
||||
{'http_method': 'OPTIONS'})
|
||||
# lbaas-healthmonitor-update myid --url-path /test/string .
|
||||
self._test_update_hm(['--url-path', '/test/string'],
|
||||
{'url_path': '/test/string', })
|
||||
# lbaas-healthmonitor-update myid --max-retries 5
|
||||
self._test_update_hm(['--max-retries', '5'], {'max_retries': '5'})
|
||||
# lbaas-healthmonitor-update myid --expected-codes 201
|
||||
self._test_update_hm(['--expected-codes', '201'],
|
||||
{'expected_codes': '201'})
|
||||
# lbaas-healthmonitor-update myid --admin-state-up False
|
||||
self._test_update_hm(['--admin-state-up', 'False'],
|
||||
{'admin_state_up': 'False'})
|
||||
|
||||
def test_delete_healthmonitor(self):
|
||||
# lbaas-healthmonitor-delete my-id.
|
||||
resource = 'healthmonitor'
|
||||
cmd_resource = 'lbaas_healthmonitor'
|
||||
cmd = healthmonitor.DeleteHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
# Copyright 2016 Radware LTD.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.neutron.v2_0.lb.v2 import l7policy
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
"""Structure for mapping cli and api arguments
|
||||
|
||||
The structure maps cli arguments and a list of its
|
||||
api argument name, default cli value and default api value.
|
||||
It helps to make tests more general for different argument types.
|
||||
"""
|
||||
args_conf = {
|
||||
'name': ['name', 'test_policy', 'test_policy'],
|
||||
'description': ['description', 'test policy', 'test policy'],
|
||||
'listener': ['listener_id', 'test_listener', 'test_listener'],
|
||||
'admin-state-up': ['admin_state_up', True, True],
|
||||
'admin-state-down': ['admin_state_up', None, False],
|
||||
'action': ['action', 'REJECT', 'REJECT'],
|
||||
'redirect-url': ['redirect_url', 'http://url', 'http://url'],
|
||||
'redirect-pool': ['redirect_pool_id', 'test_pool', 'test_pool'],
|
||||
'position': ['position', '1', 1]}
|
||||
|
||||
|
||||
class CLITestV20LbL7PolicyJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def _get_test_args(self, *args, **kwargs):
|
||||
"""Function for generically building testing arguments"""
|
||||
cli_args = []
|
||||
api_args = {}
|
||||
for arg in args:
|
||||
cli_args.append('--' + arg)
|
||||
if not args_conf[arg][1]:
|
||||
pass
|
||||
elif arg in kwargs:
|
||||
cli_args.append(str(kwargs[arg]))
|
||||
else:
|
||||
cli_args.append(args_conf[arg][1])
|
||||
|
||||
if arg in kwargs:
|
||||
api_args[args_conf[arg][0]] = kwargs[arg]
|
||||
else:
|
||||
api_args[args_conf[arg][0]] = args_conf[arg][2]
|
||||
|
||||
return cli_args, api_args
|
||||
|
||||
def _test_create_policy(self, *args, **kwargs):
|
||||
resource = 'l7policy'
|
||||
cmd_resource = 'lbaas_l7policy'
|
||||
cmd = l7policy.CreateL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
cli_args, api_args = self._get_test_args(*args, **kwargs)
|
||||
position_names = list(api_args.keys())
|
||||
position_values = list(api_args.values())
|
||||
self._test_create_resource(resource, cmd, None, 'test_id',
|
||||
cli_args, position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def _test_update_policy(self, *args, **kwargs):
|
||||
resource = 'l7policy'
|
||||
cmd_resource = 'lbaas_l7policy'
|
||||
cmd = l7policy.UpdateL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
cli_args, api_args = self._get_test_args(*args, **kwargs)
|
||||
cli_args.append('test_id')
|
||||
self._test_update_resource(resource, cmd, 'test_id',
|
||||
cli_args, api_args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_create_policy_with_mandatory_params(self):
|
||||
# lbaas-l7policy-create with mandatory params only.
|
||||
self._test_create_policy('action', 'listener')
|
||||
|
||||
def test_create_policy_with_all_params(self):
|
||||
# lbaas-l7policy-create REJECT policy.
|
||||
self._test_create_policy('name', 'description',
|
||||
'action', 'listener',
|
||||
'position')
|
||||
|
||||
def test_create_disabled_policy(self):
|
||||
# lbaas-l7policy-create disabled REJECT policy.
|
||||
self._test_create_policy('action', 'listener', 'admin-state-down')
|
||||
|
||||
def test_create_url_redirect_policy(self):
|
||||
# lbaas-l7policy-create REDIRECT_TO_URL policy.
|
||||
self._test_create_policy('name', 'description',
|
||||
'action', 'listener',
|
||||
'redirect-url',
|
||||
action='REDIRECT_TO_URL')
|
||||
|
||||
def test_create_url_redirect_policy_no_url(self):
|
||||
# lbaas-l7policy-create REDIRECT_TO_URL policy without url argument.
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_policy,
|
||||
'name', 'description',
|
||||
'action', 'listener',
|
||||
action='REDIRECT_TO_URL')
|
||||
|
||||
def test_create_pool_redirect_policy(self):
|
||||
# lbaas-l7policy-create REDIRECT_TO_POOL policy.
|
||||
self._test_create_policy('name', 'description',
|
||||
'action', 'listener',
|
||||
'redirect-pool',
|
||||
action='REDIRECT_TO_POOL')
|
||||
|
||||
def test_create_pool_redirect_policy_no_pool(self):
|
||||
# lbaas-l7policy-create REDIRECT_TO_POOL policy without pool argument.
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_policy,
|
||||
'name', 'description',
|
||||
'action', 'listener',
|
||||
action='REDIRECT_TO_POOL')
|
||||
|
||||
def test_create_reject_policy_with_url(self):
|
||||
# lbaas-l7policy-create REJECT policy while specifying url argument.
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_policy,
|
||||
'action', 'listener',
|
||||
'redirect-url')
|
||||
|
||||
def test_create_reject_policy_with_pool(self):
|
||||
# lbaas-l7policy-create REJECT policy while specifying pool argument.
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_policy,
|
||||
'action', 'listener',
|
||||
'redirect-pool')
|
||||
|
||||
def test_create_pool_redirect_policy_with_url(self):
|
||||
# lbaas-l7policy-create REDIRECT_TO_POOL policy with url argument.
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_policy,
|
||||
'action', 'listener',
|
||||
'redirect-pool', 'redirect-url',
|
||||
action='REDIRECT_TO_POOL')
|
||||
|
||||
def test_create_url_redirect_policy_with_pool(self):
|
||||
# lbaas-l7policy-create REDIRECT_TO_URL policy with pool argument.
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self._test_create_policy,
|
||||
'action', 'listener',
|
||||
'redirect-pool', 'redirect-url',
|
||||
action='REDIRECT_TO_URL')
|
||||
|
||||
def test_list_policies(self):
|
||||
# lbaas-l7policy-list.
|
||||
|
||||
resources = 'l7policies'
|
||||
cmd_resources = 'lbaas_l7policies'
|
||||
cmd = l7policy.ListL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_policies_pagination(self):
|
||||
# lbaas-l7policy-list with pagination.
|
||||
|
||||
resources = 'l7policies'
|
||||
cmd_resources = 'lbaas_l7policies'
|
||||
cmd = l7policy.ListL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(
|
||||
resources, cmd, cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_policies_sort(self):
|
||||
# lbaas-l7policy-list --sort-key id --sort-key asc.
|
||||
|
||||
resources = 'l7policies'
|
||||
cmd_resources = 'lbaas_l7policies'
|
||||
cmd = l7policy.ListL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(
|
||||
resources, cmd, True, cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_policies_limit(self):
|
||||
# lbaas-l7policy-list -P.
|
||||
|
||||
resources = 'l7policies'
|
||||
cmd_resources = 'lbaas_l7policies'
|
||||
cmd = l7policy.ListL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(
|
||||
resources, cmd, page_size=1000, cmd_resources=cmd_resources)
|
||||
|
||||
def test_show_policy_id(self):
|
||||
# lbaas-l7policy-show test_id.
|
||||
|
||||
resource = 'l7policy'
|
||||
cmd_resource = 'lbaas_l7policy'
|
||||
cmd = l7policy.ShowL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'test_id', self.test_id]
|
||||
self._test_show_resource(
|
||||
resource, cmd, self.test_id, args,
|
||||
['test_id'], cmd_resource=cmd_resource)
|
||||
|
||||
def test_show_policy_id_name(self):
|
||||
# lbaas-l7policy-show.
|
||||
|
||||
resource = 'l7policy'
|
||||
cmd_resource = 'lbaas_l7policy'
|
||||
cmd = l7policy.ShowL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'test_id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(
|
||||
resource, cmd, self.test_id, args,
|
||||
['test_id', 'name'], cmd_resource=cmd_resource)
|
||||
|
||||
def test_disable_policy(self):
|
||||
# lbaas-l7policy-update test_id --admin-state-up False.
|
||||
|
||||
self._test_update_policy('admin-state-up',
|
||||
**{'admin-state-up': 'False'})
|
||||
|
||||
def test_update_policy_name_and_description(self):
|
||||
# lbaas-l7policy-update test_id --name other --description other_desc.
|
||||
|
||||
self._test_update_policy('name', 'description',
|
||||
name='name',
|
||||
description='other desc')
|
||||
|
||||
def test_update_pool_redirect_policy(self):
|
||||
# lbaas-l7policy-update test_id --action REDIRECT_TO_POOL
|
||||
# --redirect-pool id.
|
||||
|
||||
self._test_update_policy('action', 'redirect-pool',
|
||||
**{'action': 'REDIRECT_TO_POOL',
|
||||
'redirect-pool': 'id'})
|
||||
|
||||
def test_update_url_redirect_policy(self):
|
||||
# lbaas-l7policy-update test_id --action REDIRECT_TO_URL
|
||||
# --redirect-url http://other_url.
|
||||
|
||||
self._test_update_policy('action', 'redirect-url',
|
||||
**{'action': 'REDIRECT_TO_URL',
|
||||
'redirect-url': 'http://other_url'})
|
||||
|
||||
def test_update_policy_position(self):
|
||||
# lbaas-l7policy-update test_id --position 2.
|
||||
|
||||
self._test_update_policy('position',
|
||||
position=2)
|
||||
|
||||
def test_delete_policy(self):
|
||||
# lbaas-l7policy-delete test_id.
|
||||
|
||||
resource = 'l7policy'
|
||||
cmd_resource = 'lbaas_l7policy'
|
||||
cmd = l7policy.DeleteL7Policy(test_cli20.MyApp(sys.stdout), None)
|
||||
test_id = 'test_id'
|
||||
args = [test_id]
|
||||
self._test_delete_resource(resource, cmd, test_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
# Copyright 2016 Radware LTD.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.lb.v2 import l7rule
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
"""Structure for mapping cli and api arguments
|
||||
|
||||
The structure maps cli arguments and a list of its
|
||||
api argument name, default cli value and default api value.
|
||||
It helps to make tests more general for different argument types.
|
||||
"""
|
||||
args_conf = {
|
||||
'admin-state-up': ['admin_state_up', True, True],
|
||||
'admin-state-down': ['admin_state_up', None, False],
|
||||
'type': ['type', 'HOST_NAME', 'HOST_NAME'],
|
||||
'compare-type': ['compare_type', 'EQUAL_TO', 'EQUAL_TO'],
|
||||
'invert-compare': ['invert', None, True],
|
||||
'key': ['key', 'key', 'key'],
|
||||
'value': ['value', 'value', 'value']}
|
||||
|
||||
|
||||
class CLITestV20LbL7RuleJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def _get_test_args(self, *args, **kwargs):
|
||||
"""Function for generically building testing arguments"""
|
||||
cli_args = []
|
||||
api_args = {}
|
||||
for arg in args:
|
||||
cli_args.append('--' + arg)
|
||||
if not args_conf[arg][1]:
|
||||
pass
|
||||
elif arg in kwargs:
|
||||
cli_args.append(str(kwargs[arg]))
|
||||
else:
|
||||
cli_args.append(args_conf[arg][1])
|
||||
|
||||
if arg in kwargs:
|
||||
api_args[args_conf[arg][0]] = kwargs[arg]
|
||||
else:
|
||||
api_args[args_conf[arg][0]] = args_conf[arg][2]
|
||||
|
||||
if 'invert' not in api_args:
|
||||
api_args['invert'] = False
|
||||
return cli_args, api_args
|
||||
|
||||
def _test_create_rule(self, *args, **kwargs):
|
||||
resource = 'rule'
|
||||
cmd_resource = 'lbaas_l7rule'
|
||||
cmd = l7rule.CreateL7Rule(test_cli20.MyApp(sys.stdout), None)
|
||||
cli_args, api_args = self._get_test_args(*args, **kwargs)
|
||||
position_names = list(api_args.keys())
|
||||
position_values = list(api_args.values())
|
||||
cli_args.append('test_policy')
|
||||
self._test_create_resource(resource, cmd, None, 'test_id',
|
||||
cli_args, position_names, position_values,
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id='test_policy')
|
||||
|
||||
def _test_update_rule(self, *args, **kwargs):
|
||||
resource = 'rule'
|
||||
cmd_resource = 'lbaas_l7rule'
|
||||
cmd = l7rule.UpdateL7Rule(test_cli20.MyApp(sys.stdout), None)
|
||||
cli_args, api_args = self._get_test_args(*args, **kwargs)
|
||||
cli_args.append('test_id')
|
||||
cli_args.append('test_policy')
|
||||
self._test_update_resource(resource, cmd, 'test_id',
|
||||
cli_args, api_args,
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id='test_policy')
|
||||
|
||||
def test_create_rule_with_mandatory_params(self):
|
||||
# lbaas-l7rule-create with mandatory params only.
|
||||
|
||||
self._test_create_rule('type', 'compare-type',
|
||||
'value')
|
||||
|
||||
def test_create_disabled_rule(self):
|
||||
# lbaas-l7rule-create disabled rule.
|
||||
|
||||
self._test_create_rule('type', 'compare-type',
|
||||
'value', 'admin-state-down')
|
||||
|
||||
def test_create_rule_with_all_params(self):
|
||||
# lbaas-l7rule-create with all params set.
|
||||
|
||||
self._test_create_rule('type', 'compare-type',
|
||||
'invert-compare', 'key', 'value',
|
||||
type='HEADER', compare_type='CONTAINS',
|
||||
key='other_key', value='other_value')
|
||||
|
||||
def test_create_rule_with_inverted_compare(self):
|
||||
# lbaas-l7rule-create with invertted compare type.
|
||||
|
||||
self._test_create_rule('type', 'compare-type',
|
||||
'invert-compare', 'value')
|
||||
|
||||
def test_list_rules(self):
|
||||
# lbaas-l7rule-list.
|
||||
|
||||
resources = 'rules'
|
||||
cmd_resources = 'lbaas_l7rules'
|
||||
cmd = l7rule.ListL7Rule(test_cli20.MyApp(sys.stdout), None)
|
||||
|
||||
policy_id = 'policy_id'
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
base_args=[policy_id],
|
||||
cmd_resources=cmd_resources,
|
||||
parent_id=policy_id,
|
||||
query="l7policy_id=%s" % policy_id)
|
||||
|
||||
def test_list_rules_pagination(self):
|
||||
# lbaas-l7rule-list with pagination.
|
||||
|
||||
resources = 'rules'
|
||||
cmd_resources = 'lbaas_l7rules'
|
||||
cmd = l7rule.ListL7Rule(test_cli20.MyApp(sys.stdout), None)
|
||||
policy_id = 'policy_id'
|
||||
self._test_list_resources_with_pagination(
|
||||
resources, cmd, base_args=[policy_id],
|
||||
cmd_resources=cmd_resources, parent_id=policy_id,
|
||||
query="l7policy_id=%s" % policy_id)
|
||||
|
||||
def test_list_rules_sort(self):
|
||||
# lbaas-l7rule-list --sort-key id --sort-key asc.
|
||||
|
||||
resources = 'rules'
|
||||
cmd_resources = 'lbaas_l7rules'
|
||||
cmd = l7rule.ListL7Rule(test_cli20.MyApp(sys.stdout), None)
|
||||
policy_id = 'policy_id'
|
||||
self._test_list_resources(
|
||||
resources, cmd, True, base_args=[policy_id],
|
||||
cmd_resources=cmd_resources, parent_id=policy_id,
|
||||
query="l7policy_id=%s" % policy_id)
|
||||
|
||||
def test_list_rules_limit(self):
|
||||
# lbaas-l7rule-list -P.
|
||||
|
||||
resources = 'rules'
|
||||
cmd_resources = 'lbaas_l7rules'
|
||||
cmd = l7rule.ListL7Rule(test_cli20.MyApp(sys.stdout), None)
|
||||
policy_id = 'policy_id'
|
||||
self._test_list_resources(resources, cmd, page_size=1000,
|
||||
base_args=[policy_id],
|
||||
cmd_resources=cmd_resources,
|
||||
parent_id=policy_id,
|
||||
query="l7policy_id=%s" % policy_id)
|
||||
|
||||
def test_show_rule_id(self):
|
||||
# lbaas-l7rule-show test_id.
|
||||
|
||||
resource = 'rule'
|
||||
cmd_resource = 'lbaas_l7rule'
|
||||
policy_id = 'policy_id'
|
||||
cmd = l7rule.ShowL7Rule(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id, policy_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'],
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=policy_id)
|
||||
|
||||
def test_update_rule_type(self):
|
||||
# lbaas-l7rule-update test_id --type HEADER test_policy
|
||||
|
||||
self._test_update_rule('type', type='HEADER')
|
||||
|
||||
def test_update_rule_compare_type(self):
|
||||
# lbaas-l7rule-update test_id --compare-type CONTAINS test_policy.
|
||||
|
||||
self._test_update_rule('compare-type',
|
||||
**{'compare-type': 'CONTAINS'})
|
||||
|
||||
def test_update_rule_inverted_compare_type(self):
|
||||
# lbaas-l7rule-update test_id --invert-compare test_policy.
|
||||
|
||||
self._test_update_rule('invert-compare')
|
||||
|
||||
def test_update_rule_key_value(self):
|
||||
# lbaas-l7rule-update test_id --key other --value other test_policy.
|
||||
|
||||
self._test_update_rule('key', 'value',
|
||||
key='other', value='other')
|
||||
|
||||
def test_delete_rule(self):
|
||||
# lbaas-l7rule-delete test_id policy_id.
|
||||
|
||||
resource = 'rule'
|
||||
cmd_resource = 'lbaas_l7rule'
|
||||
policy_id = 'policy_id'
|
||||
test_id = 'test_id'
|
||||
cmd = l7rule.DeleteL7Rule(test_cli20.MyApp(sys.stdout), None)
|
||||
args = [test_id, policy_id]
|
||||
self._test_delete_resource(resource, cmd, test_id, args,
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=policy_id)
|
||||
|
|
@ -1,194 +0,0 @@
|
|||
# Copyright 2014 Blue Box Group, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.neutron.v2_0.lb.v2 import listener
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbListenerJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def test_create_listener_with_loadbalancer(self):
|
||||
# lbaas-listener-create with --loadbalancer
|
||||
resource = 'listener'
|
||||
cmd_resource = 'lbaas_listener'
|
||||
cmd = listener.CreateListener(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
loadbalancer_id = 'loadbalancer'
|
||||
protocol = 'TCP'
|
||||
protocol_port = '80'
|
||||
args = ['--protocol', protocol, '--protocol-port', protocol_port,
|
||||
'--loadbalancer', loadbalancer_id]
|
||||
position_names = ['protocol', 'protocol_port', 'loadbalancer_id']
|
||||
position_values = [protocol, protocol_port, loadbalancer_id,
|
||||
True]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_create_listener_with_default_pool(self):
|
||||
# lbaas-listener-create with --default-pool and no --loadbalancer.
|
||||
resource = 'listener'
|
||||
cmd_resource = 'lbaas_listener'
|
||||
cmd = listener.CreateListener(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
default_pool_id = 'default-pool'
|
||||
protocol = 'TCP'
|
||||
protocol_port = '80'
|
||||
args = ['--protocol', protocol, '--protocol-port', protocol_port,
|
||||
'--default-pool', default_pool_id]
|
||||
position_names = ['protocol', 'protocol_port', 'default_pool_id']
|
||||
position_values = [protocol, protocol_port, default_pool_id,
|
||||
True]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_create_listener_with_no_loadbalancer_or_default_pool(self):
|
||||
# lbaas-listener-create without --default-pool or --loadbalancer.
|
||||
resource = 'listener'
|
||||
cmd_resource = 'lbaas_listener'
|
||||
cmd = listener.CreateListener(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
protocol = 'TCP'
|
||||
protocol_port = '80'
|
||||
args = ['--protocol', protocol, '--protocol-port', protocol_port]
|
||||
position_names = ['protocol', 'protocol_port']
|
||||
position_values = [protocol, protocol_port, True]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource,
|
||||
no_api_call=True,
|
||||
expected_exception=exceptions.CommandError)
|
||||
|
||||
def test_create_listener_with_all_params(self):
|
||||
# lbaas-listener-create with all params set.
|
||||
resource = 'listener'
|
||||
cmd_resource = 'lbaas_listener'
|
||||
cmd = listener.CreateListener(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
loadbalancer = 'loadbalancer'
|
||||
default_pool_id = 'default-pool'
|
||||
protocol = 'TCP'
|
||||
protocol_port = '80'
|
||||
connection_limit = 10
|
||||
def_tls_cont_ref = '11111'
|
||||
args = ['--admin-state-down',
|
||||
'--protocol', protocol, '--protocol-port', protocol_port,
|
||||
'--loadbalancer', loadbalancer,
|
||||
'--default-pool', default_pool_id,
|
||||
'--default-tls-container-ref', def_tls_cont_ref,
|
||||
'--sni-container-refs', '1111', '2222', '3333',
|
||||
'--connection-limit', '10']
|
||||
position_names = ['admin_state_up',
|
||||
'protocol', 'protocol_port', 'loadbalancer_id',
|
||||
'default_pool_id',
|
||||
'default_tls_container_ref', 'sni_container_refs',
|
||||
'connection_limit']
|
||||
position_values = [False, protocol, protocol_port, loadbalancer,
|
||||
default_pool_id,
|
||||
def_tls_cont_ref, ['1111', '2222', '3333'],
|
||||
connection_limit]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_list_listeners(self):
|
||||
# lbaas-listener-list.
|
||||
resources = 'listeners'
|
||||
cmd_resources = 'lbaas_listeners'
|
||||
cmd = listener.ListListener(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_listeners_pagination(self):
|
||||
# lbaas-listener-list with pagination.
|
||||
resources = 'listeners'
|
||||
cmd_resources = 'lbaas_listeners'
|
||||
cmd = listener.ListListener(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_listeners_sort(self):
|
||||
# lbaas-listener-list --sort-key id --sort-key asc.
|
||||
resources = 'listeners'
|
||||
cmd_resources = 'lbaas_listeners'
|
||||
cmd = listener.ListListener(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_listeners_limit(self):
|
||||
# lbaas-listener-list -P.
|
||||
resources = 'listeners'
|
||||
cmd_resources = 'lbaas_listeners'
|
||||
cmd = listener.ListListener(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_show_listener_id(self):
|
||||
# lbaas-listener-show test_id.
|
||||
resource = 'listener'
|
||||
cmd_resource = 'lbaas_listener'
|
||||
cmd = listener.ShowListener(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'],
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_show_listener_id_name(self):
|
||||
# lbaas-listener-show.
|
||||
resource = 'listener'
|
||||
cmd_resource = 'lbaas_listener'
|
||||
cmd = listener.ShowListener(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'],
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def _test_update_listener(self, args, expected_values):
|
||||
resource = 'listener'
|
||||
cmd_resource = 'lbaas_listener'
|
||||
my_id = 'myid'
|
||||
args.insert(0, my_id)
|
||||
cmd = listener.UpdateListener(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, my_id,
|
||||
args, expected_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_update_listener(self):
|
||||
# lbaas-listener-update myid --name newname.
|
||||
self._test_update_listener(['--name', 'newname'],
|
||||
{'name': 'newname', })
|
||||
# lbaas-listener-update myid --description check.
|
||||
self._test_update_listener(['--description', 'check'],
|
||||
{'description': 'check', })
|
||||
# lbaas-listener-update myid --connection-limit -1
|
||||
self._test_update_listener(['--connection-limit', '-1'],
|
||||
{'connection_limit': -1, })
|
||||
# lbaas-listener-update myid --admin-state-up False.
|
||||
self._test_update_listener(['--admin-state-up', 'False'],
|
||||
{'admin_state_up': 'False', })
|
||||
|
||||
def test_delete_listener(self):
|
||||
# lbaas-listener-delete my-id.
|
||||
resource = 'listener'
|
||||
cmd_resource = 'lbaas_listener'
|
||||
cmd = listener.DeleteListener(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
# Copyright 2014 Blue Box Group, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
|
||||
from neutronclient.neutron.v2_0.lb.v2 import loadbalancer as lb
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbLoadBalancerJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def test_create_loadbalancer_with_mandatory_params(self):
|
||||
# lbaas-loadbalancer-create with mandatory params only.
|
||||
resource = 'loadbalancer'
|
||||
cmd_resource = 'lbaas_loadbalancer'
|
||||
cmd = lb.CreateLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'lbaas-loadbalancer-name'
|
||||
vip_subnet_id = 'vip-subnet'
|
||||
my_id = 'my-id'
|
||||
args = [vip_subnet_id]
|
||||
position_names = ['vip_subnet_id']
|
||||
position_values = [vip_subnet_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_create_loadbalancer_with_all_params(self):
|
||||
# lbaas-loadbalancer-create with all params set.
|
||||
resource = 'loadbalancer'
|
||||
cmd_resource = 'lbaas_loadbalancer'
|
||||
cmd = lb.CreateLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'lbaas-loadbalancer-name'
|
||||
description = 'lbaas-loadbalancer-desc'
|
||||
flavor_id = 'lbaas-loadbalancer-flavor'
|
||||
vip_subnet_id = 'vip-subnet'
|
||||
my_id = 'my-id'
|
||||
args = ['--admin-state-down', '--description', description,
|
||||
'--name', name, '--flavor', flavor_id, vip_subnet_id]
|
||||
position_names = ['admin_state_up', 'description', 'name',
|
||||
'flavor_id', 'vip_subnet_id']
|
||||
position_values = [False, description, name, flavor_id, vip_subnet_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_list_loadbalancers(self):
|
||||
# lbaas-loadbalancer-list.
|
||||
resources = 'loadbalancers'
|
||||
cmd_resources = 'lbaas_loadbalancers'
|
||||
cmd = lb.ListLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_loadbalancers_pagination(self):
|
||||
# lbaas-loadbalancer-list with pagination.
|
||||
resources = 'loadbalancers'
|
||||
cmd_resources = 'lbaas_loadbalancers'
|
||||
cmd = lb.ListLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_loadbalancers_sort(self):
|
||||
# lbaas-loadbalancer-list --sort-key name --sort-key id --sort-key asc
|
||||
# --sort-key desc
|
||||
resources = 'loadbalancers'
|
||||
cmd_resources = 'lbaas_loadbalancers'
|
||||
cmd = lb.ListLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"],
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_loadbalancers_limit(self):
|
||||
# lbaas-loadbalancer-list -P.
|
||||
resources = 'loadbalancers'
|
||||
cmd_resources = 'lbaas_loadbalancers'
|
||||
cmd = lb.ListLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_show_loadbalancer_id(self):
|
||||
# lbaas-loadbalancer-loadbalancer-show test_id.
|
||||
resource = 'loadbalancer'
|
||||
cmd_resource = 'lbaas_loadbalancer'
|
||||
cmd = lb.ShowLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'],
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_show_loadbalancer_id_name(self):
|
||||
# lbaas-loadbalancer-loadbalancer-show.
|
||||
resource = 'loadbalancer'
|
||||
cmd_resource = 'lbaas_loadbalancer'
|
||||
cmd = lb.ShowLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'],
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def _test_update_lb(self, args, expected_values):
|
||||
resource = 'loadbalancer'
|
||||
cmd_resource = 'lbaas_loadbalancer'
|
||||
my_id = 'myid'
|
||||
args.insert(0, my_id)
|
||||
cmd = lb.UpdateLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, my_id,
|
||||
args, expected_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_update_loadbalancer(self):
|
||||
# lbaas-loadbalancer-update myid --name newname.
|
||||
self._test_update_lb(['--name', 'newname'], {'name': 'newname', })
|
||||
# lbaas-loadbalancer-update myid --description check.
|
||||
self._test_update_lb(['--description', 'check'],
|
||||
{'description': 'check', })
|
||||
# lbaas-loadbalancer-update myid --admin-state-up False.
|
||||
self._test_update_lb(['--admin-state-up', 'False'],
|
||||
{'admin_state_up': 'False', })
|
||||
|
||||
def test_delete_loadbalancer(self):
|
||||
# lbaas-loadbalancer-loadbalancer-delete my-id.
|
||||
resource = 'loadbalancer'
|
||||
cmd_resource = 'lbaas_loadbalancer'
|
||||
cmd = lb.DeleteLoadBalancer(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_retrieve_loadbalancer_stats(self):
|
||||
# lbaas-loadbalancer-stats test_id.
|
||||
resource = 'loadbalancer'
|
||||
cmd = lb.RetrieveLoadBalancerStats(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = self.test_id
|
||||
fields = ['bytes_in', 'bytes_out']
|
||||
args = ['--fields', 'bytes_in', '--fields', 'bytes_out', my_id]
|
||||
|
||||
query = "&".join(["fields=%s" % field for field in fields])
|
||||
expected_res = {'stats': {'bytes_in': '1234', 'bytes_out': '4321'}}
|
||||
resstr = self.client.serialize(expected_res)
|
||||
path = getattr(self.client, "lbaas_loadbalancer_path_stats")
|
||||
return_tup = (test_cli20.MyResp(200), resstr)
|
||||
|
||||
cmd_parser = cmd.get_parser("test_" + resource)
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
with mock.patch.object(cmd, "get_client",
|
||||
return_value=self.client) as mock_get_client, \
|
||||
mock.patch.object(self.client.httpclient, "request",
|
||||
return_value=return_tup) as mock_request:
|
||||
cmd.run(parsed_args)
|
||||
|
||||
self.assert_mock_multiple_calls_with_same_arguments(
|
||||
mock_get_client, mock.call(), 2)
|
||||
mock_request.assert_called_once_with(
|
||||
test_cli20.end_url(path % my_id, query), 'GET',
|
||||
body=None,
|
||||
headers=test_cli20.ContainsKeyValue(
|
||||
{'X-Auth-Token': test_cli20.TOKEN}))
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertIn('bytes_in', _str)
|
||||
self.assertIn('1234', _str)
|
||||
self.assertIn('bytes_out', _str)
|
||||
self.assertIn('4321', _str)
|
||||
|
||||
def test_get_loadbalancer_statuses(self):
|
||||
# lbaas-loadbalancer-status test_id.
|
||||
resource = 'loadbalancer'
|
||||
cmd = lb.RetrieveLoadBalancerStatus(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = self.test_id
|
||||
args = [my_id]
|
||||
|
||||
expected_res = {'statuses': {'operating_status': 'ONLINE',
|
||||
'provisioning_status': 'ACTIVE'}}
|
||||
|
||||
resstr = self.client.serialize(expected_res)
|
||||
|
||||
path = getattr(self.client, "lbaas_loadbalancer_path_status")
|
||||
return_tup = (test_cli20.MyResp(200), resstr)
|
||||
|
||||
cmd_parser = cmd.get_parser("test_" + resource)
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
with mock.patch.object(cmd, "get_client",
|
||||
return_value=self.client) as mock_get_client, \
|
||||
mock.patch.object(self.client.httpclient, "request",
|
||||
return_value=return_tup) as mock_request:
|
||||
cmd.run(parsed_args)
|
||||
|
||||
mock_get_client.assert_called_once_with()
|
||||
mock_request.assert_called_once_with(
|
||||
test_cli20.end_url(path % my_id), 'GET',
|
||||
body=None,
|
||||
headers=test_cli20.ContainsKeyValue(
|
||||
{'X-Auth-Token': test_cli20.TOKEN}))
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertIn('operating_status', _str)
|
||||
self.assertIn('ONLINE', _str)
|
||||
self.assertIn('provisioning_status', _str)
|
||||
self.assertIn('ACTIVE', _str)
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
# Copyright 2014 Blue Box Group, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.neutron.v2_0.lb.v2 import member
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbMemberJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def test_create_member_with_mandatory_params(self):
|
||||
# lbaas-member-create with mandatory params only.
|
||||
resource = 'member'
|
||||
cmd_resource = 'lbaas_member'
|
||||
cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
address = '10.1.1.1'
|
||||
protocol_port = '80'
|
||||
pool_id = 'pool-id'
|
||||
subnet_id = 'subnet-id'
|
||||
args = ['--address', address, '--protocol-port', protocol_port,
|
||||
'--subnet', subnet_id, pool_id]
|
||||
position_names = ['admin_state_up', 'address',
|
||||
'protocol_port', 'subnet_id']
|
||||
position_values = [True, address, protocol_port, subnet_id]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=pool_id)
|
||||
|
||||
def test_create_member_with_all_params(self):
|
||||
# lbaas-member-create with all params set.
|
||||
resource = 'member'
|
||||
cmd_resource = 'lbaas_member'
|
||||
cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
address = '10.1.1.1'
|
||||
protocol_port = '80'
|
||||
pool_id = 'pool-id'
|
||||
subnet_id = 'subnet-id'
|
||||
weight = '100'
|
||||
name = 'member1'
|
||||
args = ['--address', address, '--protocol-port', protocol_port,
|
||||
'--subnet', subnet_id, pool_id, '--weight', weight,
|
||||
'--admin-state-down', '--name', name]
|
||||
position_names = ['admin_state_up', 'address', 'protocol_port',
|
||||
'subnet_id', 'weight', 'name']
|
||||
position_values = [False, address, protocol_port,
|
||||
subnet_id, weight, name]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=pool_id)
|
||||
|
||||
def test_list_members(self):
|
||||
# lbaas-member-list.
|
||||
resources = 'members'
|
||||
cmd_resources = 'lbaas_members'
|
||||
pool_id = 'pool-id'
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True, base_args=[pool_id],
|
||||
cmd_resources=cmd_resources,
|
||||
parent_id=pool_id,
|
||||
query="pool_id=%s" % pool_id)
|
||||
|
||||
def test_list_members_pagination(self):
|
||||
# lbaas-member-list with pagination.
|
||||
resources = 'members'
|
||||
cmd_resources = 'lbaas_members'
|
||||
pool_id = 'pool-id'
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd,
|
||||
base_args=[pool_id],
|
||||
cmd_resources=cmd_resources,
|
||||
parent_id=pool_id,
|
||||
query="pool_id=%s" % pool_id)
|
||||
|
||||
def test_list_members_sort(self):
|
||||
# lbaas-member-list --sort-key id --sort-key asc.
|
||||
resources = 'members'
|
||||
cmd_resources = 'lbaas_members'
|
||||
pool_id = 'pool-id'
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True, base_args=[pool_id],
|
||||
cmd_resources=cmd_resources,
|
||||
parent_id=pool_id,
|
||||
query="pool_id=%s" % pool_id)
|
||||
|
||||
def test_list_members_limit(self):
|
||||
# lbaas-member-list -P.
|
||||
resources = 'members'
|
||||
cmd_resources = 'lbaas_members'
|
||||
pool_id = 'pool-id'
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000,
|
||||
base_args=[pool_id],
|
||||
cmd_resources=cmd_resources,
|
||||
parent_id=pool_id,
|
||||
query="pool_id=%s" % pool_id)
|
||||
|
||||
def test_show_member_id(self):
|
||||
# lbaas-member-show test_id.
|
||||
resource = 'member'
|
||||
cmd_resource = 'lbaas_member'
|
||||
pool_id = 'pool-id'
|
||||
cmd = member.ShowMember(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id, pool_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'],
|
||||
cmd_resource=cmd_resource, parent_id=pool_id)
|
||||
|
||||
def test_show_member_id_name(self):
|
||||
# lbaas-member-show.
|
||||
resource = 'member'
|
||||
cmd_resource = 'lbaas_member'
|
||||
pool_id = 'pool-id'
|
||||
cmd = member.ShowMember(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id, pool_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'],
|
||||
cmd_resource=cmd_resource, parent_id=pool_id)
|
||||
|
||||
def test_update_member(self):
|
||||
# lbaas-member-update myid --name newname.
|
||||
resource = 'member'
|
||||
cmd_resource = 'lbaas_member'
|
||||
my_id = 'my-id'
|
||||
pool_id = 'pool-id'
|
||||
args = [my_id, pool_id, '--name', 'newname']
|
||||
cmd = member.UpdateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, my_id, args,
|
||||
{'name': 'newname', },
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=pool_id)
|
||||
# lbaas-member-update myid --weight 100.
|
||||
args = [my_id, pool_id, '--weight', '100']
|
||||
self._test_update_resource(resource, cmd, my_id, args,
|
||||
{'weight': '100', },
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=pool_id)
|
||||
# lbaas-member-update myid --admin-state-up False
|
||||
args = [my_id, pool_id, '--admin-state-up', 'False']
|
||||
self._test_update_resource(resource, cmd, my_id, args,
|
||||
{'admin_state_up': 'False', },
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=pool_id)
|
||||
|
||||
def test_delete_member(self):
|
||||
# lbaas-member-delete my-id.
|
||||
resource = 'member'
|
||||
cmd_resource = 'lbaas_member'
|
||||
cmd = member.DeleteMember(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
pool_id = 'pool-id'
|
||||
args = [my_id, pool_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=pool_id)
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
# Copyright 2014 Blue Box Group, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.neutron.v2_0.lb.v2 import pool
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbPoolJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def test_create_pool_with_listener(self):
|
||||
# lbaas-pool-create with listener
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
lb_algorithm = 'ROUND_ROBIN'
|
||||
listener = 'listener'
|
||||
protocol = 'TCP'
|
||||
args = ['--lb-algorithm', lb_algorithm, '--protocol', protocol,
|
||||
'--listener', listener]
|
||||
position_names = ['admin_state_up', 'lb_algorithm', 'protocol',
|
||||
'listener_id']
|
||||
position_values = [True, lb_algorithm, protocol, listener]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_create_pool_with_loadbalancer_no_listener(self):
|
||||
"""lbaas-pool-create with loadbalancer, no listener."""
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
lb_algorithm = 'ROUND_ROBIN'
|
||||
loadbalancer = 'loadbalancer'
|
||||
protocol = 'TCP'
|
||||
args = ['--lb-algorithm', lb_algorithm, '--protocol', protocol,
|
||||
'--loadbalancer', loadbalancer]
|
||||
position_names = ['admin_state_up', 'lb_algorithm', 'protocol',
|
||||
'loadbalancer_id']
|
||||
position_values = [True, lb_algorithm, protocol, loadbalancer]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_create_pool_with_no_listener_or_loadbalancer(self):
|
||||
"""lbaas-pool-create with no listener or loadbalancer."""
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
lb_algorithm = 'ROUND_ROBIN'
|
||||
protocol = 'TCP'
|
||||
args = ['--lb-algorithm', lb_algorithm, '--protocol', protocol]
|
||||
position_names = ['admin_state_up', 'lb_algorithm', 'protocol']
|
||||
position_values = [True, lb_algorithm, protocol]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource,
|
||||
no_api_call=True,
|
||||
expected_exception=exceptions.CommandError)
|
||||
|
||||
def test_create_pool_with_all_params(self):
|
||||
# lbaas-pool-create with all params set.
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
lb_algorithm = 'ROUND_ROBIN'
|
||||
listener = 'listener'
|
||||
loadbalancer = 'loadbalancer'
|
||||
protocol = 'TCP'
|
||||
description = 'description'
|
||||
session_persistence_str = 'type=APP_COOKIE,cookie_name=1234'
|
||||
session_persistence = {'type': 'APP_COOKIE',
|
||||
'cookie_name': '1234'}
|
||||
name = 'my-pool'
|
||||
args = ['--lb-algorithm', lb_algorithm, '--protocol', protocol,
|
||||
'--description', description, '--session-persistence',
|
||||
session_persistence_str, '--admin-state-down', '--name', name,
|
||||
'--listener', listener, '--loadbalancer', loadbalancer]
|
||||
position_names = ['lb_algorithm', 'protocol', 'description',
|
||||
'session_persistence', 'admin_state_up', 'name',
|
||||
'listener_id', 'loadbalancer_id']
|
||||
position_values = [lb_algorithm, protocol, description,
|
||||
session_persistence, False, name, listener,
|
||||
loadbalancer]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_list_pools(self):
|
||||
# lbaas-pool-list.
|
||||
resources = 'pools'
|
||||
cmd_resources = 'lbaas_pools'
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_pools_pagination(self):
|
||||
# lbaas-pool-list with pagination.
|
||||
resources = 'pools'
|
||||
cmd_resources = 'lbaas_pools'
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_pools_sort(self):
|
||||
# lbaas-pool-list --sort-key id --sort-key asc.
|
||||
resources = 'pools'
|
||||
cmd_resources = 'lbaas_pools'
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_list_pools_limit(self):
|
||||
# lbaas-pool-list -P.
|
||||
resources = 'pools'
|
||||
cmd_resources = 'lbaas_pools'
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000,
|
||||
cmd_resources=cmd_resources)
|
||||
|
||||
def test_show_pool_id(self):
|
||||
# lbaas-pool-show test_id.
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.ShowPool(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'],
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_show_pool_id_name(self):
|
||||
# lbaas-pool-show.
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.ShowPool(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'],
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_update_pool(self):
|
||||
# lbaas-pool-update myid --name newname --description SuperPool
|
||||
# --lb-algorithm SOURCE_IP --admin-state-up
|
||||
# --session-persistence type=dict,type=HTTP_COOKIE,cookie_name=pie
|
||||
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.UpdatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['myid', '--name', 'newname',
|
||||
'--description', 'SuperPool', '--lb-algorithm', "SOURCE_IP",
|
||||
'--admin-state-up', 'True',
|
||||
'--session-persistence', 'type=dict,'
|
||||
'type=HTTP_COOKIE,cookie_name=pie']
|
||||
body = {'name': 'newname',
|
||||
"description": "SuperPool",
|
||||
"lb_algorithm": "SOURCE_IP",
|
||||
"admin_state_up": 'True',
|
||||
'session_persistence': {
|
||||
'type': 'HTTP_COOKIE',
|
||||
'cookie_name': 'pie',
|
||||
}, }
|
||||
self._test_update_resource(resource, cmd, 'myid', args, body,
|
||||
cmd_resource=cmd_resource)
|
||||
# lbaas-pool-update myid --name Name
|
||||
# --no-session-persistence
|
||||
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.UpdatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['myid', '--name', 'Name', '--no-session-persistence']
|
||||
body = {'name': "Name",
|
||||
"session_persistence": None, }
|
||||
self._test_update_resource(resource, cmd, 'myid', args, body,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
def test_delete_pool(self):
|
||||
# lbaas-pool-delete my-id.
|
||||
resource = 'pool'
|
||||
cmd_resource = 'lbaas_pool'
|
||||
cmd = pool.DeletePool(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
|
@ -10,10 +10,12 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
from unittest import mock
|
||||
import uuid
|
||||
|
||||
from openstack.network.v2 import agent as _agent
|
||||
from openstack.network.v2 import bgp_peer as _bgp_peer
|
||||
from openstack.network.v2 import bgp_speaker as _bgp_speaker
|
||||
|
||||
from neutronclient.tests.unit.osc.v2 import fakes
|
||||
|
||||
|
|
@ -26,6 +28,17 @@ class TestNeutronDynamicRoutingOSCV2(fakes.TestNeutronClientOSCV2):
|
|||
cmd_resource=None, parent_id=None, fields=None:
|
||||
{'id': name_or_id})
|
||||
|
||||
self.networkclient.find_bgp_speaker = mock.Mock(
|
||||
side_effect=lambda name_or_id, project_id=None,
|
||||
cmd_resource=None, parent_id=None, fields=None,
|
||||
ignore_missing=False:
|
||||
_bgp_speaker.BgpSpeaker(id=name_or_id))
|
||||
self.networkclient.find_bgp_peer = mock.Mock(
|
||||
side_effect=lambda name_or_id, project_id=None,
|
||||
cmd_resource=None, parent_id=None, fields=None,
|
||||
ignore_missing=False:
|
||||
_bgp_peer.BgpPeer(id=name_or_id))
|
||||
|
||||
|
||||
class FakeBgpSpeaker(object):
|
||||
"""Fake one or more bgp speakers."""
|
||||
|
|
@ -48,8 +61,9 @@ class FakeBgpSpeaker(object):
|
|||
|
||||
# Overwrite default attributes.
|
||||
bgp_speaker_attrs.update(attrs)
|
||||
ret_bgp_speaker = _bgp_speaker.BgpSpeaker(**bgp_speaker_attrs)
|
||||
|
||||
return copy.deepcopy(bgp_speaker_attrs)
|
||||
return ret_bgp_speaker
|
||||
|
||||
@staticmethod
|
||||
def create_bgp_speakers(attrs=None, count=1):
|
||||
|
|
@ -61,7 +75,7 @@ class FakeBgpSpeaker(object):
|
|||
bgp_speaker = FakeBgpSpeaker.create_one_bgp_speaker(attrs)
|
||||
bgp_speakers.append(bgp_speaker)
|
||||
|
||||
return {'bgp_speakers': bgp_speakers}
|
||||
return bgp_speakers
|
||||
|
||||
|
||||
class FakeBgpPeer(object):
|
||||
|
|
@ -82,8 +96,9 @@ class FakeBgpPeer(object):
|
|||
|
||||
# Overwrite default attributes.
|
||||
bgp_peer_attrs.update(attrs)
|
||||
ret_bgp_peer = _bgp_peer.BgpPeer(**bgp_peer_attrs)
|
||||
|
||||
return copy.deepcopy(bgp_peer_attrs)
|
||||
return ret_bgp_peer
|
||||
|
||||
@staticmethod
|
||||
def create_bgp_peers(attrs=None, count=1):
|
||||
|
|
@ -93,7 +108,7 @@ class FakeBgpPeer(object):
|
|||
bgp_peer = FakeBgpPeer.create_one_bgp_peer(attrs)
|
||||
bgp_peers.append(bgp_peer)
|
||||
|
||||
return {'bgp_peers': bgp_peers}
|
||||
return bgp_peers
|
||||
|
||||
|
||||
class FakeDRAgent(object):
|
||||
|
|
@ -106,6 +121,7 @@ class FakeDRAgent(object):
|
|||
dragent_attrs = {
|
||||
'binary': 'neutron-bgp-dragent',
|
||||
'admin_state_up': True,
|
||||
'availability_zone': None,
|
||||
'alive': True,
|
||||
'topic': 'bgp_dragent',
|
||||
'host': 'network-' + uuid.uuid4().hex,
|
||||
|
|
@ -116,8 +132,7 @@ class FakeDRAgent(object):
|
|||
|
||||
# Overwrite default attributes.
|
||||
dragent_attrs.update(attrs)
|
||||
|
||||
return copy.deepcopy(dragent_attrs)
|
||||
return _agent.Agent(**dragent_attrs)
|
||||
|
||||
@staticmethod
|
||||
def create_dragents(attrs=None, count=1):
|
||||
|
|
@ -127,4 +142,4 @@ class FakeDRAgent(object):
|
|||
agent = FakeDRAgent.create_one_dragent(attrs)
|
||||
agents.append(agent)
|
||||
|
||||
return {'agents': agents}
|
||||
return agents
|
||||
|
|
|
|||
|
|
@ -39,15 +39,14 @@ class TestAddBgpSpeakerToDRAgent(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
with mock.patch.object(self.neutronclient,
|
||||
with mock.patch.object(self.networkclient,
|
||||
"add_bgp_speaker_to_dragent",
|
||||
return_value=None):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.neutronclient.add_bgp_speaker_to_dragent.\
|
||||
self.networkclient.add_bgp_speaker_to_dragent.\
|
||||
assert_called_once_with(
|
||||
self._bgp_dragent_id,
|
||||
{'bgp_speaker_id': self._bgp_speaker_id})
|
||||
self._bgp_dragent_id, self._bgp_speaker_id)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
|
|
@ -75,49 +74,11 @@ class TestRemoveBgpSpeakerFromDRAgent(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
with mock.patch.object(self.neutronclient,
|
||||
with mock.patch.object(self.networkclient,
|
||||
"remove_bgp_speaker_from_dragent",
|
||||
return_value=None):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.neutronclient.remove_bgp_speaker_from_dragent.\
|
||||
self.networkclient.remove_bgp_speaker_from_dragent.\
|
||||
assert_called_once_with(self._bgp_dragent_id,
|
||||
self._bgp_speaker_id)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
class TestListDRAgentsHostingBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
||||
_bgp_speaker = fakes.FakeBgpSpeaker.create_one_bgp_speaker()
|
||||
_bgp_speaker_id = _bgp_speaker['id']
|
||||
attrs = {'bgp_speaker_id': _bgp_speaker_id}
|
||||
_bgp_dragents = fakes.FakeDRAgent.create_dragents(attrs)
|
||||
columns = ('ID', 'Host', 'State', 'Alive')
|
||||
data = [(_bgp_dragent['id'],
|
||||
_bgp_dragent['host'],
|
||||
_bgp_dragent['admin_state_up'],
|
||||
':-)' if _bgp_dragent['alive'] else 'XXX')
|
||||
for _bgp_dragent in _bgp_dragents['agents']]
|
||||
|
||||
def setUp(self):
|
||||
super(TestListDRAgentsHostingBgpSpeaker, self).setUp()
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = bgp_dragent.ListDRAgent(self.app, self.namespace)
|
||||
|
||||
def test_list_dragents_hosting_bgp_speaker(self):
|
||||
arglist = [
|
||||
'--bgp-speaker', self._bgp_speaker_id,
|
||||
]
|
||||
verifylist = [
|
||||
('bgp_speaker', self._bgp_speaker_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
with mock.patch.object(self.neutronclient,
|
||||
"list_dragents_hosting_bgp_speaker",
|
||||
return_value=self._bgp_dragents):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
attrs = {'bgp_speaker': self._bgp_speaker_id}
|
||||
self.neutronclient.list_dragents_hosting_bgp_speaker.\
|
||||
assert_called_once_with(**attrs)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertListEqual(self.data, list(data))
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class TestListBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
_bgp_peers = fakes.FakeBgpPeer.create_bgp_peers(count=1)
|
||||
columns = ('ID', 'Name', 'Peer IP', 'Remote AS')
|
||||
data = []
|
||||
for _bgp_peer in _bgp_peers['bgp_peers']:
|
||||
for _bgp_peer in _bgp_peers:
|
||||
data.append((
|
||||
_bgp_peer['id'],
|
||||
_bgp_peer['name'],
|
||||
|
|
@ -30,7 +30,7 @@ class TestListBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
def setUp(self):
|
||||
super(TestListBgpPeer, self).setUp()
|
||||
|
||||
self.neutronclient.list_bgp_peers = mock.Mock(
|
||||
self.networkclient.bgp_peers = mock.Mock(
|
||||
return_value=self._bgp_peers
|
||||
)
|
||||
|
||||
|
|
@ -41,7 +41,8 @@ class TestListBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, [], [])
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.neutronclient.list_bgp_peers.assert_called_once_with()
|
||||
self.networkclient.bgp_peers.assert_called_once_with(
|
||||
retrieve_all=True)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, list(data))
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ class TestDeleteBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
def setUp(self):
|
||||
super(TestDeleteBgpPeer, self).setUp()
|
||||
|
||||
self.neutronclient.delete_bgp_peer = mock.Mock(return_value=None)
|
||||
self.networkclient.delete_bgp_peer = mock.Mock(return_value=None)
|
||||
|
||||
self.cmd = bgp_peer.DeleteBgpPeer(self.app, self.namespace)
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ class TestDeleteBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.delete_bgp_peer.assert_called_once_with(
|
||||
self.networkclient.delete_bgp_peer.assert_called_once_with(
|
||||
self._bgp_peer['name'])
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
|
@ -80,31 +81,30 @@ class TestShowBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
_one_bgp_peer['id'],
|
||||
_one_bgp_peer['name'],
|
||||
_one_bgp_peer['peer_ip'],
|
||||
_one_bgp_peer['tenant_id'],
|
||||
_one_bgp_peer['remote_as'],
|
||||
_one_bgp_peer['tenant_id']
|
||||
)
|
||||
_bgp_peer = {'bgp_peer': _one_bgp_peer}
|
||||
_bgp_peer = _one_bgp_peer
|
||||
_bgp_peer_name = _one_bgp_peer['name']
|
||||
columns = (
|
||||
'auth_type',
|
||||
'id',
|
||||
'name',
|
||||
'peer_ip',
|
||||
'project_id',
|
||||
'remote_as',
|
||||
'tenant_id'
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(TestShowBgpPeer, self).setUp()
|
||||
|
||||
self.neutronclient.show_bgp_peer = mock.Mock(
|
||||
self.networkclient.get_bgp_peer = mock.Mock(
|
||||
return_value=self._bgp_peer
|
||||
)
|
||||
bgp_peer.get_bgp_peer_id = mock.Mock(return_value=self._bgp_peer_name)
|
||||
# Get the command object to test
|
||||
self.cmd = bgp_peer.ShowBgpPeer(self.app, self.namespace)
|
||||
|
||||
def test_bgp_peer_list(self):
|
||||
def test_bgp_peer_show(self):
|
||||
arglist = [
|
||||
self._bgp_peer_name,
|
||||
]
|
||||
|
|
@ -114,7 +114,7 @@ class TestShowBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
data = self.cmd.take_action(parsed_args)
|
||||
self.neutronclient.show_bgp_peer.assert_called_once_with(
|
||||
self.networkclient.get_bgp_peer.assert_called_once_with(
|
||||
self._bgp_peer_name)
|
||||
self.assertEqual(self.columns, data[0])
|
||||
self.assertEqual(self.data, data[1])
|
||||
|
|
@ -126,7 +126,7 @@ class TestSetBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
|
||||
def setUp(self):
|
||||
super(TestSetBgpPeer, self).setUp()
|
||||
self.neutronclient.update_bgp_peer = mock.Mock(return_value=None)
|
||||
self.networkclient.update_bgp_peer = mock.Mock(return_value=None)
|
||||
bgp_peer.get_bgp_peer_id = mock.Mock(return_value=self._bgp_peer_name)
|
||||
|
||||
self.cmd = bgp_peer.SetBgpPeer(self.app, self.namespace)
|
||||
|
|
@ -144,10 +144,7 @@ class TestSetBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
attrs = {'bgp_peer': {
|
||||
'name': 'noob',
|
||||
'password': None}
|
||||
}
|
||||
self.neutronclient.update_bgp_peer.assert_called_once_with(
|
||||
self._bgp_peer_name, attrs)
|
||||
attrs = {'name': 'noob', 'password': None}
|
||||
self.networkclient.update_bgp_peer.assert_called_once_with(
|
||||
self._bgp_peer_name, **attrs)
|
||||
self.assertIsNone(result)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class TestListBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
_bgp_speakers = fakes.FakeBgpSpeaker.create_bgp_speakers()
|
||||
columns = ('ID', 'Name', 'Local AS', 'IP Version')
|
||||
data = []
|
||||
for _bgp_speaker in _bgp_speakers['bgp_speakers']:
|
||||
for _bgp_speaker in _bgp_speakers:
|
||||
data.append((
|
||||
_bgp_speaker['id'],
|
||||
_bgp_speaker['name'],
|
||||
|
|
@ -30,7 +30,7 @@ class TestListBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
def setUp(self):
|
||||
super(TestListBgpSpeaker, self).setUp()
|
||||
|
||||
self.neutronclient.list_bgp_speakers = mock.Mock(
|
||||
self.networkclient.bgp_speakers = mock.Mock(
|
||||
return_value=self._bgp_speakers
|
||||
)
|
||||
|
||||
|
|
@ -41,7 +41,9 @@ class TestListBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, [], [])
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.neutronclient.list_bgp_speakers.assert_called_once_with()
|
||||
self.networkclient.bgp_speakers.assert_called_once_with(
|
||||
retrieve_all=True)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, list(data))
|
||||
|
||||
|
|
@ -53,7 +55,7 @@ class TestDeleteBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
def setUp(self):
|
||||
super(TestDeleteBgpSpeaker, self).setUp()
|
||||
|
||||
self.neutronclient.delete_bgp_speaker = mock.Mock(return_value=None)
|
||||
self.networkclient.delete_bgp_speaker = mock.Mock(return_value=None)
|
||||
|
||||
self.cmd = bgp_speaker.DeleteBgpSpeaker(self.app, self.namespace)
|
||||
|
||||
|
|
@ -68,7 +70,7 @@ class TestDeleteBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.delete_bgp_speaker.assert_called_once_with(
|
||||
self.networkclient.delete_bgp_speaker.assert_called_once_with(
|
||||
self._bgp_speaker['name'])
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
|
@ -86,7 +88,7 @@ class TestShowBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
_one_bgp_speaker['peers'],
|
||||
_one_bgp_speaker['tenant_id']
|
||||
)
|
||||
_bgp_speaker = {'bgp_speaker': _one_bgp_speaker}
|
||||
_bgp_speaker = _one_bgp_speaker
|
||||
_bgp_speaker_name = _one_bgp_speaker['name']
|
||||
columns = (
|
||||
'advertise_floating_ip_host_routes',
|
||||
|
|
@ -97,13 +99,13 @@ class TestShowBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
'name',
|
||||
'networks',
|
||||
'peers',
|
||||
'tenant_id'
|
||||
'project_id'
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(TestShowBgpSpeaker, self).setUp()
|
||||
|
||||
self.neutronclient.show_bgp_speaker = mock.Mock(
|
||||
self.networkclient.get_bgp_speaker = mock.Mock(
|
||||
return_value=self._bgp_speaker
|
||||
)
|
||||
# Get the command object to test
|
||||
|
|
@ -119,7 +121,7 @@ class TestShowBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
data = self.cmd.take_action(parsed_args)
|
||||
self.neutronclient.show_bgp_speaker.assert_called_once_with(
|
||||
self.networkclient.get_bgp_speaker.assert_called_once_with(
|
||||
self._bgp_speaker_name)
|
||||
self.assertEqual(self.columns, data[0])
|
||||
self.assertEqual(self.data, data[1])
|
||||
|
|
@ -131,7 +133,7 @@ class TestSetBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
|
||||
def setUp(self):
|
||||
super(TestSetBgpSpeaker, self).setUp()
|
||||
self.neutronclient.update_bgp_speaker = mock.Mock(
|
||||
self.networkclient.update_bgp_speaker = mock.Mock(
|
||||
return_value=None)
|
||||
|
||||
self.cmd = bgp_speaker.SetBgpSpeaker(self.app, self.namespace)
|
||||
|
|
@ -149,9 +151,7 @@ class TestSetBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
attrs = {'bgp_speaker': {
|
||||
'name': 'noob'}
|
||||
}
|
||||
self.neutronclient.update_bgp_speaker.assert_called_once_with(
|
||||
self._bgp_speaker_name, attrs)
|
||||
attrs = {'name': 'noob'}
|
||||
self.networkclient.update_bgp_speaker.assert_called_once_with(
|
||||
self._bgp_speaker_name, **attrs)
|
||||
self.assertIsNone(result)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ class TestNeutronClientOSCV2(utils.TestCommand):
|
|||
self.app.client_manager.session = mock.Mock()
|
||||
self.app.client_manager.neutronclient = mock.Mock()
|
||||
self.neutronclient = self.app.client_manager.neutronclient
|
||||
|
||||
self.app.client_manager.network = mock.Mock()
|
||||
self.networkclient = self.app.client_manager.network
|
||||
|
||||
self.addCleanup(mock.patch.stopall)
|
||||
|
||||
# TODO(amotoki): Move this to osc_lib
|
||||
|
|
|
|||
|
|
@ -42,23 +42,20 @@ class TestListFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
|
||||
self.mocked.assert_called_once_with()
|
||||
self.assertEqual(list(self.headers), headers)
|
||||
self.assertListItemEqual([self.data], list(data))
|
||||
|
||||
|
||||
class TestShowFWaaS(test_fakes.TestNeutronClientOSCV2):
|
||||
|
||||
def test_show_filtered_by_id_or_name(self):
|
||||
target = self.resource['id']
|
||||
headers, data = None, None
|
||||
|
||||
def _mock_fwaas(*args, **kwargs):
|
||||
# Find specified ingress_firewall_policy
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.assertEqual(self.res, args[0])
|
||||
self.assertEqual(self.resource['id'], args[1])
|
||||
self.assertEqual({'cmd_resource': 'fwaas_' + self.res}, kwargs)
|
||||
return {'id': args[1]}
|
||||
return {'id': args[0]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_fwaas
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_fwaas
|
||||
self.networkclient.find_firewall_group.side_effect = _mock_fwaas
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_fwaas
|
||||
|
||||
arglist = [target]
|
||||
verifylist = [(self.res, target)]
|
||||
|
|
@ -67,7 +64,6 @@ class TestShowFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
|
||||
self.mocked.assert_called_once_with(target)
|
||||
self.assertEqual(self.ordered_headers, headers)
|
||||
self.assertItemEqual(self.ordered_data, data)
|
||||
|
||||
|
||||
class TestCreateFWaaS(test_fakes.TestNeutronClientOSCV2):
|
||||
|
|
@ -87,8 +83,7 @@ class TestSetFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'name': update}})
|
||||
self.mocked.assert_called_once_with(target, **{'name': update})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_description(self):
|
||||
|
|
@ -102,8 +97,7 @@ class TestSetFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'description': update}})
|
||||
self.mocked.assert_called_once_with(target, **{'description': update})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_shared(self):
|
||||
|
|
@ -116,8 +110,7 @@ class TestSetFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'shared': True}})
|
||||
self.mocked.assert_called_once_with(target, **{'shared': True})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_duplicate_shared(self):
|
||||
|
|
@ -130,8 +123,7 @@ class TestSetFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'shared': True}})
|
||||
self.mocked.assert_called_once_with(target, **{'shared': True})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_share(self):
|
||||
|
|
@ -144,8 +136,7 @@ class TestSetFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'shared': False}})
|
||||
self.mocked.assert_called_once_with(target, **{'shared': False})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_duplicate_no_share(self):
|
||||
|
|
@ -158,8 +149,7 @@ class TestSetFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'shared': False}})
|
||||
self.mocked.assert_called_once_with(target, **{'shared': False})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_share_and_shared(self):
|
||||
|
|
@ -215,6 +205,14 @@ class TestDeleteFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
|
||||
def test_delete_with_one_resource(self):
|
||||
target = self.resource['id']
|
||||
|
||||
def _mock_fwaas(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_group.side_effect = _mock_fwaas
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_fwaas
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_fwaas
|
||||
|
||||
arglist = [target]
|
||||
verifylist = [(self.res, [target])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
|
@ -226,12 +224,11 @@ class TestDeleteFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
def test_delete_with_multiple_resources(self):
|
||||
|
||||
def _mock_fwaas(*args, **kwargs):
|
||||
self.assertEqual(self.res, args[0])
|
||||
self.assertIsNotNone(args[1])
|
||||
self.assertEqual({'cmd_resource': 'fwaas_' + self.res}, kwargs)
|
||||
return {'id': args[1]}
|
||||
return {'id': args[0]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_fwaas
|
||||
self.networkclient.find_firewall_group.side_effect = _mock_fwaas
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_fwaas
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_fwaas
|
||||
|
||||
target1 = 'target1'
|
||||
target2 = 'target2'
|
||||
|
|
@ -244,7 +241,7 @@ class TestDeleteFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
|
||||
self.assertEqual(2, self.mocked.call_count)
|
||||
for idx, reference in enumerate([target1, target2]):
|
||||
actual = ''.join(self.mocked.call_args_list[idx][0])
|
||||
actual = ''.join(self.mocked.call_args_list[idx][0][0])
|
||||
self.assertEqual(reference, actual)
|
||||
|
||||
def test_delete_multiple_with_exception(self):
|
||||
|
|
@ -252,7 +249,7 @@ class TestDeleteFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
arglist = [target1]
|
||||
verifylist = [(self.res, [target1])]
|
||||
|
||||
self.neutronclient.find_resource.side_effect = [
|
||||
self.networkclient.find_firewall_group.side_effect = [
|
||||
target1, exceptions.CommandError
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
|
@ -277,8 +274,7 @@ class TestUnsetFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'shared': False}})
|
||||
self.mocked.assert_called_once_with(target, **{'shared': False})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_shared_and_no_shared(self):
|
||||
|
|
@ -304,6 +300,5 @@ class TestUnsetFWaaS(test_fakes.TestNeutronClientOSCV2):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'shared': False}})
|
||||
self.mocked.assert_called_once_with(target, **{'shared': False})
|
||||
self.assertIsNone(result)
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@
|
|||
#
|
||||
|
||||
import collections
|
||||
import copy
|
||||
from unittest import mock
|
||||
|
||||
from openstack.network.v2 import firewall_group as fw_group
|
||||
from openstack.network.v2 import firewall_policy as fw_policy
|
||||
from openstack.network.v2 import firewall_rule as fw_rule
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
|
||||
|
|
@ -32,7 +34,22 @@ class FakeFWaaS(object):
|
|||
A OrderedDict faking the fwaas resource
|
||||
"""
|
||||
self.ordered.update(attrs)
|
||||
return copy.deepcopy(self.ordered)
|
||||
if 'FirewallGroup' == self.__class__.__name__:
|
||||
return fw_group.FirewallGroup(**self.ordered)
|
||||
if 'FirewallPolicy' == self.__class__.__name__:
|
||||
return fw_policy.FirewallPolicy(**self.ordered)
|
||||
if 'FirewallRule' == self.__class__.__name__:
|
||||
fw_r = fw_rule.FirewallRule(**self.ordered)
|
||||
protocol = fw_r['protocol'].upper() if fw_r['protocol'] else 'ANY'
|
||||
src_ip = str(fw_r['source_ip_address']).lower()
|
||||
src_port = '(' + str(fw_r['source_port']).lower() + ')'
|
||||
dst_ip = str(fw_r['destination_ip_address']).lower()
|
||||
dst_port = '(' + str(fw_r['destination_port']).lower() + ')'
|
||||
src = 'source(port): ' + src_ip + src_port
|
||||
dst = 'dest(port): ' + dst_ip + dst_port
|
||||
action = fw_r['action'] if fw_r.get('action') else 'no-action'
|
||||
fw_r['summary'] = ',\n '.join([protocol, src, dst, action])
|
||||
return fw_r
|
||||
|
||||
def bulk_create(self, attrs=None, count=2):
|
||||
"""Create multiple fake fwaas resources
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ from osc_lib import exceptions
|
|||
from osc_lib.tests import utils
|
||||
|
||||
from neutronclient.osc import utils as osc_utils
|
||||
from neutronclient.osc.v2.fwaas import constants as const
|
||||
from neutronclient.osc.v2.fwaas import firewallgroup
|
||||
from neutronclient.osc.v2 import utils as v2_utils
|
||||
from neutronclient.tests.unit.osc.v2 import fakes as test_fakes
|
||||
|
|
@ -52,12 +51,12 @@ def _generate_response(ordered_dict=None, data=None):
|
|||
if data:
|
||||
up.append(data)
|
||||
source.update(up)
|
||||
return tuple(source[key] for key in source)
|
||||
return source
|
||||
|
||||
|
||||
def _generate_req_and_res(verifylist):
|
||||
request = dict(verifylist)
|
||||
response = copy.deepcopy(_fwg)
|
||||
response = _fwg
|
||||
for key, val in verifylist:
|
||||
del request[key]
|
||||
if re.match('^no_', key) and val is True:
|
||||
|
|
@ -66,6 +65,10 @@ def _generate_req_and_res(verifylist):
|
|||
new_value = True
|
||||
elif key == 'disable' and val:
|
||||
new_value = False
|
||||
elif val is True or val is False:
|
||||
new_value = val
|
||||
elif key in ('name', 'description'):
|
||||
new_value = val
|
||||
else:
|
||||
new_value = val
|
||||
converted = CONVERT_MAP.get(key, key)
|
||||
|
|
@ -78,20 +81,19 @@ class TestFirewallGroup(test_fakes.TestNeutronClientOSCV2):
|
|||
|
||||
def check_results(self, headers, data, exp_req, is_list=False):
|
||||
if is_list:
|
||||
req_body = {self.res_plural: [exp_req]}
|
||||
req_body = {self.res_plural: list(exp_req)}
|
||||
else:
|
||||
req_body = {self.res: exp_req}
|
||||
self.mocked.assert_called_once_with(req_body)
|
||||
self.assertEqual(self.ordered_headers, headers)
|
||||
self.assertItemEqual(self.ordered_data, data)
|
||||
req_body = exp_req
|
||||
self.mocked.assert_called_once_with(**req_body)
|
||||
self.assertEqual(self.ordered_headers, tuple(sorted(headers)))
|
||||
|
||||
def setUp(self):
|
||||
super(TestFirewallGroup, self).setUp()
|
||||
|
||||
def _find_resource(*args, **kwargs):
|
||||
return {'id': args[1], 'ports': _fwg['ports']}
|
||||
return {'id': args[0], 'ports': _fwg['ports']}
|
||||
|
||||
self.neutronclient.find_resource = mock.Mock(
|
||||
self.networkclient.find_firewall_group = mock.Mock(
|
||||
side_effect=_find_resource)
|
||||
osc_utils.find_project = mock.Mock()
|
||||
osc_utils.find_project.id = _fwg['tenant_id']
|
||||
|
|
@ -120,7 +122,7 @@ class TestFirewallGroup(test_fakes.TestNeutronClientOSCV2):
|
|||
))
|
||||
self.data = _generate_response()
|
||||
self.ordered_headers = copy.deepcopy(tuple(sorted(self.headers)))
|
||||
self.ordered_data = (
|
||||
self.expected_data = (
|
||||
_fwg['description'],
|
||||
_fwg['egress_firewall_policy_id'],
|
||||
_fwg['id'],
|
||||
|
|
@ -151,9 +153,9 @@ class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS):
|
|||
def setUp(self):
|
||||
# Mock objects
|
||||
super(TestCreateFirewallGroup, self).setUp()
|
||||
self.neutronclient.create_fwaas_firewall_group = mock.Mock(
|
||||
return_value={self.res: _fwg})
|
||||
self.mocked = self.neutronclient.create_fwaas_firewall_group
|
||||
self.networkclient.create_firewall_group = mock.Mock(
|
||||
return_value=_fwg)
|
||||
self.mocked = self.networkclient.create_firewall_group
|
||||
self.cmd = firewallgroup.CreateFirewallGroup(self.app, self.namespace)
|
||||
|
||||
def _update_expect_response(self, request, response):
|
||||
|
|
@ -165,14 +167,11 @@ class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS):
|
|||
A OrderedDict of request body
|
||||
"""
|
||||
# Update response body
|
||||
self.neutronclient.create_fwaas_firewall_group.return_value = \
|
||||
{self.res: dict(response)}
|
||||
self.networkclient.create_firewall_group.return_value = response
|
||||
osc_utils.find_project.return_value.id = response['tenant_id']
|
||||
# Update response(finally returns 'data')
|
||||
self.data = _generate_response(ordered_dict=response)
|
||||
self.ordered_data = tuple(
|
||||
response[column] for column in self.ordered_columns
|
||||
)
|
||||
self.expected_data = response
|
||||
|
||||
def test_create_with_no_option(self):
|
||||
# firewall_group-create with mandatory (none) params.
|
||||
|
|
@ -180,12 +179,16 @@ class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS):
|
|||
verifylist = []
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
self.assertEqual(self.ordered_headers, headers)
|
||||
self.assertItemEqual(self.ordered_data, data)
|
||||
self.assertEqual(self.ordered_headers, tuple(sorted(headers)))
|
||||
|
||||
def test_create_with_port(self):
|
||||
# firewall_group-create with 'port'
|
||||
port_id = 'id_for_port'
|
||||
|
||||
def _mock_find(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_port.side_effect = _mock_find
|
||||
arglist = ['--port', port_id]
|
||||
verifylist = [('port', [port_id])]
|
||||
request, response = _generate_req_and_res(verifylist)
|
||||
|
|
@ -200,9 +203,9 @@ class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS):
|
|||
ingress_policy = 'my-ingress-policy'
|
||||
|
||||
def _mock_port_fwg(*args, **kwargs):
|
||||
return {'id': args[1]}
|
||||
return {'id': args[0]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_port_fwg
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_port_fwg
|
||||
|
||||
arglist = ['--ingress-firewall-policy', ingress_policy]
|
||||
verifylist = [('ingress_firewall_policy', ingress_policy)]
|
||||
|
|
@ -211,18 +214,19 @@ class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS):
|
|||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
self.neutronclient.find_resource.assert_called_once_with(
|
||||
'firewall_policy', ingress_policy, cmd_resource=const.CMD_FWP)
|
||||
self.networkclient.find_firewall_policy.assert_called_once_with(
|
||||
ingress_policy)
|
||||
|
||||
self.check_results(headers, data, request)
|
||||
|
||||
def test_create_with_egress_policy(self):
|
||||
egress_policy = 'my-egress-policy'
|
||||
|
||||
def _mock_port_fwg(*args, **kwargs):
|
||||
return {'id': args[1]}
|
||||
def _mock_find(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_port_fwg
|
||||
self.networkclient.find_firewall_group.side_effect = _mock_find
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_find
|
||||
|
||||
arglist = ['--egress-firewall-policy', egress_policy]
|
||||
verifylist = [('egress_firewall_policy', egress_policy)]
|
||||
|
|
@ -231,8 +235,8 @@ class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.find_resource.assert_called_once_with(
|
||||
'firewall_policy', egress_policy, cmd_resource=const.CMD_FWP)
|
||||
self.networkclient.find_firewall_policy.assert_called_once_with(
|
||||
egress_policy)
|
||||
self.check_results(headers, data, request)
|
||||
|
||||
def test_create_with_all_params(self):
|
||||
|
|
@ -240,7 +244,13 @@ class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS):
|
|||
description = 'my-desc'
|
||||
ingress_policy = 'my-ingress-policy'
|
||||
egress_policy = 'my-egress-policy'
|
||||
|
||||
def _mock_find(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_find
|
||||
port = 'port'
|
||||
self.networkclient.find_port.side_effect = _mock_find
|
||||
tenant_id = 'my-tenant'
|
||||
arglist = [
|
||||
'--name', name,
|
||||
|
|
@ -330,9 +340,9 @@ class TestListFirewallGroup(TestFirewallGroup, common.TestListFWaaS):
|
|||
def setUp(self):
|
||||
super(TestListFirewallGroup, self).setUp()
|
||||
# Mock objects
|
||||
self.neutronclient.list_fwaas_firewall_groups = mock.Mock(
|
||||
return_value={self.res_plural: [_fwg]})
|
||||
self.mocked = self.neutronclient.list_fwaas_firewall_groups
|
||||
self.networkclient.firewall_groups = mock.Mock(
|
||||
return_value=[_fwg])
|
||||
self.mocked = self.networkclient.firewall_groups
|
||||
self.cmd = firewallgroup.ListFirewallGroup(self.app, self.namespace)
|
||||
|
||||
|
||||
|
|
@ -341,9 +351,9 @@ class TestShowFirewallGroup(TestFirewallGroup, common.TestShowFWaaS):
|
|||
def setUp(self):
|
||||
super(TestShowFirewallGroup, self).setUp()
|
||||
# Mock objects
|
||||
self.neutronclient.show_fwaas_firewall_group = mock.Mock(
|
||||
return_value={self.res: _fwg})
|
||||
self.mocked = self.neutronclient.show_fwaas_firewall_group
|
||||
self.networkclient.get_firewall_group = mock.Mock(
|
||||
return_value=_fwg)
|
||||
self.mocked = self.networkclient.get_firewall_group
|
||||
self.cmd = firewallgroup.ShowFirewallGroup(self.app, self.namespace)
|
||||
|
||||
|
||||
|
|
@ -353,9 +363,15 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
super(TestSetFirewallGroup, self).setUp()
|
||||
# Mock objects
|
||||
_fwg['ports'] = ['old_port']
|
||||
self.neutronclient.update_fwaas_firewall_group = mock.Mock(
|
||||
self.networkclient.update_firewall_group = mock.Mock(
|
||||
return_value={self.res: _fwg})
|
||||
self.mocked = self.neutronclient.update_fwaas_firewall_group
|
||||
self.mocked = self.networkclient.update_firewall_group
|
||||
|
||||
def _mock_find_port(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_port.side_effect = _mock_find_port
|
||||
|
||||
self.cmd = firewallgroup.SetFirewallGroup(self.app, self.namespace)
|
||||
|
||||
def _update_expect_response(self, request, response):
|
||||
|
|
@ -380,22 +396,21 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
|
||||
def _mock_fwg_policy(*args, **kwargs):
|
||||
# 1. Find specified firewall_group
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWG)
|
||||
if self.networkclient.find_firewall_group.call_count == 1:
|
||||
self.networkclient.find_firewall_group.assert_called_with(
|
||||
target)
|
||||
# 2. Find specified 'ingress_firewall_policy'
|
||||
if self.neutronclient.find_resource.call_count == 2:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_policy', ingress_policy,
|
||||
cmd_resource=const.CMD_FWP)
|
||||
if self.networkclient.find_firewall_policy.call_count == 1:
|
||||
self.networkclient.find_firewall_policy.assert_called_with(
|
||||
ingress_policy)
|
||||
# 3. Find specified 'ingress_firewall_policy'
|
||||
if self.neutronclient.find_resource.call_count == 3:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_policy', egress_policy,
|
||||
cmd_resource=const.CMD_FWP)
|
||||
return {'id': args[1]}
|
||||
if self.networkclient.find_firewall_policy.call_count == 2:
|
||||
self.networkclient.find_firewall_policy.assert_called_with(
|
||||
egress_policy)
|
||||
return {'id': args[0]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_fwg_policy
|
||||
self.networkclient.find_firewall_group.side_effect = _mock_fwg_policy
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_fwg_policy
|
||||
|
||||
arglist = [
|
||||
target,
|
||||
|
|
@ -411,8 +426,8 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'ingress_firewall_policy_id': ingress_policy,
|
||||
'egress_firewall_policy_id': egress_policy}})
|
||||
target, **{'ingress_firewall_policy_id': ingress_policy,
|
||||
'egress_firewall_policy_id': egress_policy})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_port(self):
|
||||
|
|
@ -422,27 +437,21 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
|
||||
def _mock_port_fwg(*args, **kwargs):
|
||||
# 1. Find specified firewall_group
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWG)
|
||||
return {'id': args[1]}
|
||||
if self.networkclient.find_firewall_group.call_count in [1, 2]:
|
||||
self.networkclient.find_firewall_group.assert_called_with(
|
||||
target)
|
||||
return {'id': args[0], 'ports': _fwg['ports']}
|
||||
# 2. Find specified 'port' #1
|
||||
if self.neutronclient.find_resource.call_count == 2:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'port', args[1])
|
||||
return {'id': args[1]}
|
||||
if self.networkclient.find_port.call_count == 1:
|
||||
self.networkclient.find_port.assert_called_with(args)
|
||||
return {'id': args[0]}
|
||||
# 3. Find specified 'port' #2
|
||||
if self.neutronclient.find_resource.call_count == 3:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'port', args[1])
|
||||
return {'id': args[1]}
|
||||
# 4. Find specified firewall_group and refer 'ports' attribute
|
||||
if self.neutronclient.find_resource.call_count == 4:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWG)
|
||||
return {'ports': _fwg['ports']}
|
||||
if self.networkclient.find_port.call_count == 2:
|
||||
self.networkclient.find_port.assert_called_with(args)
|
||||
return {'id': args[0]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_port_fwg
|
||||
self.networkclient.find_fireall_group.side_effect = _mock_port_fwg
|
||||
self.networkclient.find_port.side_effect = _mock_port_fwg
|
||||
|
||||
arglist = [
|
||||
target,
|
||||
|
|
@ -457,8 +466,8 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
expect = {'ports': sorted(_fwg['ports'] + [port1, port2])}
|
||||
self.mocked.assert_called_once_with(target, {self.res: expect})
|
||||
self.assertEqual(4, self.neutronclient.find_resource.call_count)
|
||||
self.mocked.assert_called_once_with(target, **expect)
|
||||
self.assertEqual(2, self.networkclient.find_firewall_group.call_count)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_port(self):
|
||||
|
|
@ -473,7 +482,7 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'ports': []}})
|
||||
target, **{'ports': []})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_admin_state(self):
|
||||
|
|
@ -487,12 +496,18 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'admin_state_up': True}})
|
||||
target, **{'admin_state_up': True})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_egress_policy(self):
|
||||
target = self.resource['id']
|
||||
policy = 'egress_policy'
|
||||
|
||||
def _mock_find_policy(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_find_policy
|
||||
|
||||
arglist = [target, '--egress-firewall-policy', policy]
|
||||
verifylist = [
|
||||
(self.res, target),
|
||||
|
|
@ -502,7 +517,7 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'egress_firewall_policy_id': policy}})
|
||||
target, **{'egress_firewall_policy_id': policy})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_ingress_policies(self):
|
||||
|
|
@ -516,7 +531,7 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'ingress_firewall_policy_id': None}})
|
||||
target, **{'ingress_firewall_policy_id': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_egress_policies(self):
|
||||
|
|
@ -530,7 +545,7 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'egress_firewall_policy_id': None}})
|
||||
target, **{'egress_firewall_policy_id': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_port_and_no_port(self):
|
||||
|
|
@ -549,7 +564,7 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'ports': [port]}})
|
||||
target, **{'ports': [port]})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_ingress_policy_and_no_ingress_policy(self):
|
||||
|
|
@ -585,7 +600,7 @@ class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS):
|
|||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_set_and_raises(self):
|
||||
self.neutronclient.update_fwaas_firewall_group = mock.Mock(
|
||||
self.networkclient.update_firewall_group = mock.Mock(
|
||||
side_effect=Exception)
|
||||
target = self.resource['id']
|
||||
arglist = [target, '--name', 'my-name']
|
||||
|
|
@ -601,8 +616,8 @@ class TestDeleteFirewallGroup(TestFirewallGroup, common.TestDeleteFWaaS):
|
|||
def setUp(self):
|
||||
super(TestDeleteFirewallGroup, self).setUp()
|
||||
# Mock objects
|
||||
self.neutronclient.delete_fwaas_firewall_group = mock.Mock()
|
||||
self.mocked = self.neutronclient.delete_fwaas_firewall_group
|
||||
self.networkclient.delete_firewall_group = mock.Mock()
|
||||
self.mocked = self.networkclient.delete_firewall_group
|
||||
self.cmd = firewallgroup.DeleteFirewallGroup(self.app, self.namespace)
|
||||
|
||||
|
||||
|
|
@ -612,8 +627,8 @@ class TestUnsetFirewallGroup(TestFirewallGroup, common.TestUnsetFWaaS):
|
|||
super(TestUnsetFirewallGroup, self).setUp()
|
||||
_fwg['ports'] = ['old_port']
|
||||
# Mock objects
|
||||
self.neutronclient.update_fwaas_firewall_group = mock.Mock()
|
||||
self.mocked = self.neutronclient.update_fwaas_firewall_group
|
||||
self.networkclient.update_firewall_group = mock.Mock()
|
||||
self.mocked = self.networkclient.update_firewall_group
|
||||
self.cmd = firewallgroup.UnsetFirewallGroup(self.app, self.namespace)
|
||||
|
||||
def test_unset_ingress_policy(self):
|
||||
|
|
@ -629,7 +644,7 @@ class TestUnsetFirewallGroup(TestFirewallGroup, common.TestUnsetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'ingress_firewall_policy_id': None}})
|
||||
target, **{'ingress_firewall_policy_id': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_egress_policy(self):
|
||||
|
|
@ -645,7 +660,7 @@ class TestUnsetFirewallGroup(TestFirewallGroup, common.TestUnsetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'egress_firewall_policy_id': None}})
|
||||
target, **{'egress_firewall_policy_id': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_enable(self):
|
||||
|
|
@ -661,7 +676,7 @@ class TestUnsetFirewallGroup(TestFirewallGroup, common.TestUnsetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'admin_state_up': False}})
|
||||
target, **{'admin_state_up': False})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_port(self):
|
||||
|
|
@ -670,23 +685,21 @@ class TestUnsetFirewallGroup(TestFirewallGroup, common.TestUnsetFWaaS):
|
|||
|
||||
def _mock_port_fwg(*args, **kwargs):
|
||||
# 1. Find specified firewall_group
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWG)
|
||||
return {'id': args[1]}
|
||||
if self.networkclient.find_firewall_group.call_count in [1, 2]:
|
||||
self.networkclient.find_firewall_group.assert_called_with(
|
||||
target)
|
||||
return {'id': args[0], 'ports': _fwg['ports']}
|
||||
# 2. Find specified firewall_group and refer 'ports' attribute
|
||||
if self.neutronclient.find_resource.call_count == 2:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWG)
|
||||
if self.networkclient.find_port.call_count == 2:
|
||||
self.networkclient.find_port.assert_called_with(target)
|
||||
return {'ports': _fwg['ports']}
|
||||
# 3. Find specified 'port'
|
||||
if self.neutronclient.find_resource.call_count == 3:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'port', port)
|
||||
return {'id': args[1]}
|
||||
if self.networkclient.find_port.call_count == 3:
|
||||
self.networkclient.find_port.assert_called_with(port)
|
||||
return {'id': args[0]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = mock.Mock(
|
||||
side_effect=_mock_port_fwg)
|
||||
self.networkclient.find_firewall_group.side_effect = _mock_port_fwg
|
||||
self.networkclient.find_port.side_effect = _mock_port_fwg
|
||||
|
||||
arglist = [
|
||||
target,
|
||||
|
|
@ -698,7 +711,7 @@ class TestUnsetFirewallGroup(TestFirewallGroup, common.TestUnsetFWaaS):
|
|||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.mocked.assert_called_once_with(target, {self.res: {'ports': []}})
|
||||
self.mocked.assert_called_once_with(target, **{'ports': []})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_all_port(self):
|
||||
|
|
@ -713,5 +726,5 @@ class TestUnsetFirewallGroup(TestFirewallGroup, common.TestUnsetFWaaS):
|
|||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.mocked.assert_called_once_with(target, {self.res: {'ports': []}})
|
||||
self.mocked.assert_called_once_with(target, **{'ports': []})
|
||||
self.assertIsNone(result)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
# under the License.
|
||||
#
|
||||
|
||||
import copy
|
||||
import re
|
||||
from unittest import mock
|
||||
|
||||
|
|
@ -22,7 +21,6 @@ from osc_lib import exceptions
|
|||
from osc_lib.tests import utils
|
||||
|
||||
from neutronclient.osc import utils as osc_utils
|
||||
from neutronclient.osc.v2.fwaas import constants as const
|
||||
from neutronclient.osc.v2.fwaas import firewallpolicy
|
||||
from neutronclient.tests.unit.osc.v2 import fakes as test_fakes
|
||||
from neutronclient.tests.unit.osc.v2.fwaas import common
|
||||
|
|
@ -51,7 +49,7 @@ def _generate_data(ordered_dict=None, data=None):
|
|||
|
||||
def _generate_req_and_res(verifylist):
|
||||
request = dict(verifylist)
|
||||
response = copy.deepcopy(_fwp)
|
||||
response = _fwp
|
||||
for key, val in verifylist:
|
||||
converted = CONVERT_MAP.get(key, key)
|
||||
del request[key]
|
||||
|
|
@ -61,6 +59,10 @@ def _generate_req_and_res(verifylist):
|
|||
new_value = True
|
||||
elif key == 'disable' and val:
|
||||
new_value = False
|
||||
elif val is True or val is False:
|
||||
new_value = val
|
||||
elif key in ('name', 'description'):
|
||||
new_value = val
|
||||
else:
|
||||
new_value = val
|
||||
request[converted] = new_value
|
||||
|
|
@ -74,23 +76,13 @@ class TestFirewallPolicy(test_fakes.TestNeutronClientOSCV2):
|
|||
if is_list:
|
||||
req_body = {self.res_plural: [exp_req]}
|
||||
else:
|
||||
req_body = {self.res: exp_req}
|
||||
self.mocked.assert_called_once_with(req_body)
|
||||
self.assertEqual(self.ordered_headers, headers)
|
||||
self.assertEqual(self.ordered_data, data)
|
||||
req_body = exp_req
|
||||
self.mocked.assert_called_once_with(**req_body)
|
||||
self.assertEqual(self.ordered_headers, tuple(sorted(headers)))
|
||||
|
||||
def setUp(self):
|
||||
super(TestFirewallPolicy, self).setUp()
|
||||
|
||||
def _find_resource(*args, **kwargs):
|
||||
rule_id = args[1]
|
||||
rules = []
|
||||
if self.res in args[0]:
|
||||
rules = _fwp['firewall_rules']
|
||||
return {'id': rule_id, 'firewall_rules': rules}
|
||||
|
||||
self.neutronclient.find_resource = mock.Mock(
|
||||
side_effect=_find_resource)
|
||||
osc_utils.find_project = mock.Mock()
|
||||
osc_utils.find_project.id = _fwp['tenant_id']
|
||||
self.res = 'firewall_policy'
|
||||
|
|
@ -146,9 +138,9 @@ class TestCreateFirewallPolicy(TestFirewallPolicy, common.TestCreateFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestCreateFirewallPolicy, self).setUp()
|
||||
self.neutronclient.create_fwaas_firewall_policy = mock.Mock(
|
||||
self.networkclient.create_firewall_policy = mock.Mock(
|
||||
return_value={self.res: _fwp})
|
||||
self.mocked = self.neutronclient.create_fwaas_firewall_policy
|
||||
self.mocked = self.networkclient.create_firewall_policy
|
||||
self.cmd = firewallpolicy.CreateFirewallPolicy(self.app,
|
||||
self.namespace)
|
||||
|
||||
|
|
@ -161,8 +153,7 @@ class TestCreateFirewallPolicy(TestFirewallPolicy, common.TestCreateFWaaS):
|
|||
A OrderedDict of request body
|
||||
"""
|
||||
# Update response body
|
||||
self.neutronclient.create_fwaas_firewall_policy.return_value = \
|
||||
{self.res: dict(response)}
|
||||
self.networkclient.create_firewall_policy.return_value = response
|
||||
osc_utils.find_project.return_value.id = response['tenant_id']
|
||||
# Update response(finally returns 'data')
|
||||
self.data = _generate_data(data=response)
|
||||
|
|
@ -199,11 +190,9 @@ class TestCreateFirewallPolicy(TestFirewallPolicy, common.TestCreateFWaaS):
|
|||
rule2 = 'rule2'
|
||||
|
||||
def _mock_policy(*args, **kwargs):
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_rule', args[1], cmd_resource=const.CMD_FWR)
|
||||
return {'id': args[1]}
|
||||
return {'id': args[0]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_policy
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_policy
|
||||
|
||||
arglist = [
|
||||
name,
|
||||
|
|
@ -218,7 +207,7 @@ class TestCreateFirewallPolicy(TestFirewallPolicy, common.TestCreateFWaaS):
|
|||
self._update_expect_response(request, response)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
self.assertEqual(2, self.neutronclient.find_resource.call_count)
|
||||
self.assertEqual(2, self.networkclient.find_firewall_rule.call_count)
|
||||
|
||||
self.check_results(headers, data, request)
|
||||
|
||||
|
|
@ -228,6 +217,16 @@ class TestCreateFirewallPolicy(TestFirewallPolicy, common.TestCreateFWaaS):
|
|||
rule1 = 'rule1'
|
||||
rule2 = 'rule2'
|
||||
project = 'my-tenant'
|
||||
|
||||
def _mock_find(*args, **kwargs):
|
||||
if self.res in args[0]:
|
||||
rules = _fwp['firewall_rules']
|
||||
return {'id': args[0], 'firewall_rules': rules}
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_find
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_find
|
||||
|
||||
arglist = [
|
||||
name,
|
||||
'--description', desc,
|
||||
|
|
@ -308,9 +307,9 @@ class TestListFirewallPolicy(TestFirewallPolicy, common.TestListFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestListFirewallPolicy, self).setUp()
|
||||
self.neutronclient.list_fwaas_firewall_policies = mock.Mock(
|
||||
return_value={'firewall_policies': [_fwp]})
|
||||
self.mocked = self.neutronclient.list_fwaas_firewall_policies
|
||||
self.networkclient.firewall_policies = mock.Mock(
|
||||
return_value=[_fwp])
|
||||
self.mocked = self.networkclient.firewall_policies
|
||||
self.cmd = firewallpolicy.ListFirewallPolicy(self.app, self.namespace)
|
||||
|
||||
|
||||
|
|
@ -318,9 +317,9 @@ class TestShowFirewallPolicy(TestFirewallPolicy, common.TestShowFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestShowFirewallPolicy, self).setUp()
|
||||
self.neutronclient.show_fwaas_firewall_policy = mock.Mock(
|
||||
return_value={self.res: _fwp})
|
||||
self.mocked = self.neutronclient.show_fwaas_firewall_policy
|
||||
self.networkclient.get_firewall_policy = mock.Mock(
|
||||
return_value=_fwp)
|
||||
self.mocked = self.networkclient.get_firewall_policy
|
||||
self.cmd = firewallpolicy.ShowFirewallPolicy(self.app, self.namespace)
|
||||
|
||||
|
||||
|
|
@ -328,38 +327,26 @@ class TestSetFirewallPolicy(TestFirewallPolicy, common.TestSetFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestSetFirewallPolicy, self).setUp()
|
||||
self.neutronclient.update_fwaas_firewall_policy = mock.Mock(
|
||||
return_value={self.res: _fwp})
|
||||
self.mocked = self.neutronclient.update_fwaas_firewall_policy
|
||||
self.networkclient.update_firewall_policy = mock.Mock(
|
||||
return_value=_fwp)
|
||||
self.mocked = self.networkclient.update_firewall_policy
|
||||
|
||||
def _mock_find_rule(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
def _mock_find_policy(*args, **kwargs):
|
||||
return {'id': args[0],
|
||||
'firewall_rules': _fwp['firewall_rules']}
|
||||
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_find_policy
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_find_rule
|
||||
|
||||
self.cmd = firewallpolicy.SetFirewallPolicy(self.app, self.namespace)
|
||||
|
||||
def test_set_rules(self):
|
||||
target = self.resource['id']
|
||||
rule1 = 'new_rule1'
|
||||
rule2 = 'new_rule2'
|
||||
|
||||
def _mock_policy(*args, **kwargs):
|
||||
# 1. Find specified firewall_policy
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWP)
|
||||
# 2. Find specified firewall_policy's 'firewall_rules' attribute
|
||||
if self.neutronclient.find_resource.call_count == 2:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, args[1], cmd_resource=const.CMD_FWP)
|
||||
return {'firewall_rules': _fwp['firewall_rules']}
|
||||
# 3. Find specified firewall_rule
|
||||
if self.neutronclient.find_resource.call_count == 3:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_rule', args[1], cmd_resource=const.CMD_FWR)
|
||||
# 4. Find specified firewall_rule
|
||||
if self.neutronclient.find_resource.call_count == 4:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_rule', args[1], cmd_resource=const.CMD_FWR)
|
||||
return {'id': args[1]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_policy
|
||||
|
||||
arglist = [
|
||||
target,
|
||||
'--firewall-rule', rule1,
|
||||
|
|
@ -373,9 +360,10 @@ class TestSetFirewallPolicy(TestFirewallPolicy, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
expect = _fwp['firewall_rules'] + [rule1, rule2]
|
||||
body = {self.res: {'firewall_rules': expect}}
|
||||
self.mocked.assert_called_once_with(target, body)
|
||||
self.assertEqual(4, self.neutronclient.find_resource.call_count)
|
||||
body = {'firewall_rules': expect}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertEqual(2, self.networkclient.find_firewall_rule.call_count)
|
||||
self.assertEqual(2, self.networkclient.find_firewall_policy.call_count)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_rules(self):
|
||||
|
|
@ -388,8 +376,8 @@ class TestSetFirewallPolicy(TestFirewallPolicy, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
body = {self.res: {'firewall_rules': []}}
|
||||
self.mocked.assert_called_once_with(target, body)
|
||||
body = {'firewall_rules': []}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_rules_and_no_rules(self):
|
||||
|
|
@ -408,9 +396,10 @@ class TestSetFirewallPolicy(TestFirewallPolicy, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
body = {self.res: {'firewall_rules': [rule1]}}
|
||||
self.mocked.assert_called_once_with(target, body)
|
||||
self.assertEqual(2, self.neutronclient.find_resource.call_count)
|
||||
body = {'firewall_rules': [rule1]}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertEqual(1, self.networkclient.find_firewall_rule.call_count)
|
||||
self.assertEqual(1, self.networkclient.find_firewall_policy.call_count)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_audited(self):
|
||||
|
|
@ -424,7 +413,7 @@ class TestSetFirewallPolicy(TestFirewallPolicy, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(target, {self.res: body})
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_audited(self):
|
||||
|
|
@ -438,7 +427,7 @@ class TestSetFirewallPolicy(TestFirewallPolicy, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(target, {self.res: body})
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_audited_and_no_audited(self):
|
||||
|
|
@ -458,9 +447,10 @@ class TestSetFirewallPolicy(TestFirewallPolicy, common.TestSetFWaaS):
|
|||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_set_and_raises(self):
|
||||
self.neutronclient.update_fwaas_firewall_policy = mock.Mock(
|
||||
self.networkclient.update_firewall_policy = mock.Mock(
|
||||
side_effect=Exception)
|
||||
target = self.resource['id']
|
||||
|
||||
arglist = [target, '--name', 'my-name']
|
||||
verifylist = [(self.res, target), ('name', 'my-name')]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
|
@ -473,9 +463,9 @@ class TestDeleteFirewallPolicy(TestFirewallPolicy, common.TestDeleteFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestDeleteFirewallPolicy, self).setUp()
|
||||
self.neutronclient.delete_fwaas_firewall_policy = mock.Mock(
|
||||
self.networkclient.delete_firewall_policy = mock.Mock(
|
||||
return_value={self.res: _fwp})
|
||||
self.mocked = self.neutronclient.delete_fwaas_firewall_policy
|
||||
self.mocked = self.networkclient.delete_firewall_policy
|
||||
self.cmd = firewallpolicy.DeleteFirewallPolicy(
|
||||
self.app, self.namespace)
|
||||
|
||||
|
|
@ -484,9 +474,16 @@ class TestFirewallPolicyInsertRule(TestFirewallPolicy):
|
|||
|
||||
def setUp(self):
|
||||
super(TestFirewallPolicyInsertRule, self).setUp()
|
||||
self.neutronclient.insert_rule_fwaas_firewall_policy = mock.Mock(
|
||||
self.networkclient.insert_rule_firewall_policy = mock.Mock(
|
||||
return_value={self.res: _fwp})
|
||||
self.mocked = self.neutronclient.insert_rule_fwaas_firewall_policy
|
||||
self.mocked = self.networkclient.insert_rule_into_policy
|
||||
|
||||
def _mock_find_policy(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_find_policy
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_find_policy
|
||||
|
||||
self.cmd = firewallpolicy.FirewallPolicyInsertRule(self.app,
|
||||
self.namespace)
|
||||
|
||||
|
|
@ -495,28 +492,6 @@ class TestFirewallPolicyInsertRule(TestFirewallPolicy):
|
|||
rule = 'new-rule'
|
||||
before = 'before'
|
||||
after = 'after'
|
||||
|
||||
def _mock_policy(*args, **kwargs):
|
||||
# 1. Find specified firewall_policy
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWP)
|
||||
# 2. Find specified firewall_rule
|
||||
if self.neutronclient.find_resource.call_count == 2:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_rule', args[1], cmd_resource=const.CMD_FWR)
|
||||
# 3. Find specified firewall_rule as 'before'
|
||||
if self.neutronclient.find_resource.call_count == 3:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_rule', args[1], cmd_resource=const.CMD_FWR)
|
||||
# 4. Find specified firewall_rule as 'after'
|
||||
if self.neutronclient.find_resource.call_count == 4:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_rule', args[1], cmd_resource=const.CMD_FWR)
|
||||
return {'id': args[1]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_policy
|
||||
|
||||
arglist = [
|
||||
target,
|
||||
rule,
|
||||
|
|
@ -532,14 +507,15 @@ class TestFirewallPolicyInsertRule(TestFirewallPolicy):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {
|
||||
'firewall_rule_id': rule,
|
||||
'insert_before': before,
|
||||
'insert_after': after
|
||||
})
|
||||
body = {
|
||||
'firewall_rule_id': rule,
|
||||
'insert_before': before,
|
||||
'insert_after': after
|
||||
}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual(4, self.neutronclient.find_resource.call_count)
|
||||
self.assertEqual(1, self.networkclient.find_firewall_policy.call_count)
|
||||
self.assertEqual(3, self.networkclient.find_firewall_rule.call_count)
|
||||
|
||||
def test_insert_with_no_firewall_rule(self):
|
||||
target = self.resource['id']
|
||||
|
|
@ -558,30 +534,22 @@ class TestFirewallPolicyRemoveRule(TestFirewallPolicy):
|
|||
|
||||
def setUp(self):
|
||||
super(TestFirewallPolicyRemoveRule, self).setUp()
|
||||
self.neutronclient.remove_rule_fwaas_firewall_policy = mock.Mock(
|
||||
self.networkclient.remove_rule_firewall_policy = mock.Mock(
|
||||
return_value={self.res: _fwp})
|
||||
self.mocked = self.neutronclient.remove_rule_fwaas_firewall_policy
|
||||
self.mocked = self.networkclient.remove_rule_from_policy
|
||||
|
||||
def _mock_find_policy(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_find_policy
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_find_policy
|
||||
|
||||
self.cmd = firewallpolicy.FirewallPolicyRemoveRule(self.app,
|
||||
self.namespace)
|
||||
|
||||
def test_remove_firewall_rule(self):
|
||||
target = self.resource['id']
|
||||
rule = 'remove-rule'
|
||||
|
||||
def _mock_policy(*args, **kwargs):
|
||||
# 1. Find specified firewall_policy
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWP)
|
||||
# 2. Find specified firewall_rule
|
||||
if self.neutronclient.find_resource.call_count == 2:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_rule', rule, cmd_resource=const.CMD_FWR)
|
||||
return {'id': args[1]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = mock.Mock(
|
||||
side_effect=_mock_policy)
|
||||
|
||||
arglist = [
|
||||
target,
|
||||
rule,
|
||||
|
|
@ -592,10 +560,11 @@ class TestFirewallPolicyRemoveRule(TestFirewallPolicy):
|
|||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {'firewall_rule_id': rule})
|
||||
body = {'firewall_rule_id': rule}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual(2, self.neutronclient.find_resource.call_count)
|
||||
self.assertEqual(1, self.networkclient.find_firewall_policy.call_count)
|
||||
self.assertEqual(1, self.networkclient.find_firewall_rule.call_count)
|
||||
|
||||
def test_remove_with_no_firewall_rule(self):
|
||||
target = self.resource['id']
|
||||
|
|
@ -614,9 +583,19 @@ class TestUnsetFirewallPolicy(TestFirewallPolicy, common.TestUnsetFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestUnsetFirewallPolicy, self).setUp()
|
||||
self.neutronclient.update_fwaas_firewall_policy = mock.Mock(
|
||||
self.networkclient.update_firewall_policy = mock.Mock(
|
||||
return_value={self.res: _fwp})
|
||||
self.mocked = self.neutronclient.update_fwaas_firewall_policy
|
||||
self.mocked = self.networkclient.update_firewall_policy
|
||||
|
||||
def _mock_find_rule(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
def _mock_find_policy(*args, **kwargs):
|
||||
return {'id': args[0], 'firewall_rules': _fwp['firewall_rules']}
|
||||
|
||||
self.networkclient.find_firewall_policy.side_effect = _mock_find_policy
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_find_rule
|
||||
|
||||
self.cmd = firewallpolicy.UnsetFirewallPolicy(self.app, self.namespace)
|
||||
|
||||
def test_unset_audited(self):
|
||||
|
|
@ -632,8 +611,8 @@ class TestUnsetFirewallPolicy(TestFirewallPolicy, common.TestUnsetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
body = {self.res: {'audited': False}}
|
||||
self.mocked.assert_called_once_with(target, body)
|
||||
body = {'audited': False}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_firewall_rule_not_matched(self):
|
||||
|
|
@ -651,33 +630,14 @@ class TestUnsetFirewallPolicy(TestFirewallPolicy, common.TestUnsetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
body = {self.res: {'firewall_rules': _fwp['firewall_rules']}}
|
||||
self.mocked.assert_called_once_with(target, body)
|
||||
body = {'firewall_rules': _fwp['firewall_rules']}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_firewall_rule_matched(self):
|
||||
_fwp['firewall_rules'] = ['rule1', 'rule2']
|
||||
target = self.resource['id']
|
||||
rule = 'rule1'
|
||||
|
||||
def _mock_policy(*args, **kwargs):
|
||||
# 1. Find specified firewall_policy
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWP)
|
||||
# 2. Find 'firewall_rules' attribute from specified firewall_policy
|
||||
if self.neutronclient.find_resource.call_count == 2:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
self.res, target, cmd_resource=const.CMD_FWP)
|
||||
return {'firewall_rules': _fwp['firewall_rules']}
|
||||
# 3. Find specified 'firewall_rule'
|
||||
if self.neutronclient.find_resource.call_count == 3:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
'firewall_rule', rule, cmd_resource=const.CMD_FWR)
|
||||
return {'id': args[1]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = _mock_policy
|
||||
|
||||
arglist = [
|
||||
target,
|
||||
'--firewall-rule', rule,
|
||||
|
|
@ -689,10 +649,11 @@ class TestUnsetFirewallPolicy(TestFirewallPolicy, common.TestUnsetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
body = {self.res: {'firewall_rules': ['rule2']}}
|
||||
self.mocked.assert_called_once_with(target, body)
|
||||
body = {'firewall_rules': ['rule2']}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
self.assertEqual(3, self.neutronclient.find_resource.call_count)
|
||||
self.assertEqual(2, self.networkclient.find_firewall_policy.call_count)
|
||||
self.assertEqual(1, self.networkclient.find_firewall_rule.call_count)
|
||||
|
||||
def test_unset_all_firewall_rule(self):
|
||||
target = self.resource['id']
|
||||
|
|
@ -707,6 +668,6 @@ class TestUnsetFirewallPolicy(TestFirewallPolicy, common.TestUnsetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
body = {self.res: {'firewall_rules': []}}
|
||||
self.mocked.assert_called_once_with(target, body)
|
||||
body = {'firewall_rules': []}
|
||||
self.mocked.assert_called_once_with(target, **body)
|
||||
self.assertIsNone(result)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
# under the License.
|
||||
#
|
||||
|
||||
import copy
|
||||
import re
|
||||
from unittest import mock
|
||||
|
||||
|
|
@ -23,7 +22,6 @@ from osc_lib.tests import utils
|
|||
import testtools
|
||||
|
||||
from neutronclient.osc import utils as osc_utils
|
||||
from neutronclient.osc.v2.fwaas import constants as const
|
||||
from neutronclient.osc.v2.fwaas import firewallrule
|
||||
from neutronclient.tests.unit.osc.v2 import fakes as test_fakes
|
||||
from neutronclient.tests.unit.osc.v2.fwaas import common
|
||||
|
|
@ -48,7 +46,8 @@ def _generate_data(ordered_dict=None, data=None):
|
|||
source = ordered_dict if ordered_dict else _fwr
|
||||
if data:
|
||||
source.update(data)
|
||||
return tuple(_replace_display_columns(key, source[key]) for key in source)
|
||||
ret = tuple(_replace_display_columns(key, source[key]) for key in source)
|
||||
return ret
|
||||
|
||||
|
||||
def _replace_display_columns(key, val):
|
||||
|
|
@ -59,7 +58,7 @@ def _replace_display_columns(key, val):
|
|||
|
||||
def _generate_req_and_res(verifylist):
|
||||
request = dict(verifylist)
|
||||
response = copy.deepcopy(_fwr)
|
||||
response = _fwr
|
||||
for key, val in verifylist:
|
||||
converted = CONVERT_MAP.get(key, key)
|
||||
del request[key]
|
||||
|
|
@ -71,6 +70,10 @@ def _generate_req_and_res(verifylist):
|
|||
new_value = False
|
||||
elif (key == 'protocol' and val and val.lower() == 'any'):
|
||||
new_value = None
|
||||
elif val is True or val is False:
|
||||
new_value = val
|
||||
elif key in ('name', 'description'):
|
||||
new_value = val
|
||||
else:
|
||||
new_value = val
|
||||
request[converted] = new_value
|
||||
|
|
@ -80,25 +83,20 @@ def _generate_req_and_res(verifylist):
|
|||
|
||||
class TestFirewallRule(test_fakes.TestNeutronClientOSCV2):
|
||||
|
||||
def check_results(self, headers, data, exp_req, is_list=False):
|
||||
def check_results(self, headers, data, exp_req=None, is_list=False):
|
||||
if is_list:
|
||||
req_body = {self.res_plural: [exp_req]}
|
||||
else:
|
||||
req_body = {self.res: exp_req}
|
||||
self.mocked.assert_called_once_with(req_body)
|
||||
req_body = exp_req
|
||||
if not exp_req:
|
||||
self.mocked.assert_called_once_with()
|
||||
else:
|
||||
self.mocked.assert_called_once_with(**req_body)
|
||||
self.assertEqual(self.ordered_headers, headers)
|
||||
self.assertItemEqual(self.ordered_data, data)
|
||||
|
||||
def setUp(self):
|
||||
super(TestFirewallRule, self).setUp()
|
||||
|
||||
def _mock_fwr(*args, **kwargs):
|
||||
self.neutronclient.find_resource.assert_called_once_with(
|
||||
self.res, self.resource['id'], cmd_resource=const.CMD_FWR)
|
||||
return {'id': args[1]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = mock.Mock(
|
||||
side_effect=_mock_fwr)
|
||||
osc_utils.find_project = mock.Mock()
|
||||
osc_utils.find_project.id = _fwr['tenant_id']
|
||||
self.res = 'firewall_rule'
|
||||
|
|
@ -109,6 +107,7 @@ class TestFirewallRule(test_fakes.TestNeutronClientOSCV2):
|
|||
'Name',
|
||||
'Enabled',
|
||||
'Description',
|
||||
'Firewall Policy',
|
||||
'IP Version',
|
||||
'Action',
|
||||
'Protocol',
|
||||
|
|
@ -129,6 +128,7 @@ class TestFirewallRule(test_fakes.TestNeutronClientOSCV2):
|
|||
'Destination IP Address',
|
||||
'Destination Port',
|
||||
'Enabled',
|
||||
'Firewall Policy',
|
||||
'ID',
|
||||
'IP Version',
|
||||
'Name',
|
||||
|
|
@ -138,6 +138,7 @@ class TestFirewallRule(test_fakes.TestNeutronClientOSCV2):
|
|||
'Source Firewall Group ID',
|
||||
'Source IP Address',
|
||||
'Source Port',
|
||||
'Summary',
|
||||
)
|
||||
self.ordered_data = (
|
||||
_fwr['action'],
|
||||
|
|
@ -145,6 +146,7 @@ class TestFirewallRule(test_fakes.TestNeutronClientOSCV2):
|
|||
_fwr['destination_firewall_group_id'],
|
||||
_fwr['destination_ip_address'],
|
||||
_fwr['destination_port'],
|
||||
_fwr['firewall_policy_id'],
|
||||
_fwr['enabled'],
|
||||
_fwr['id'],
|
||||
_fwr['ip_version'],
|
||||
|
|
@ -179,9 +181,15 @@ class TestCreateFirewallRule(TestFirewallRule, common.TestCreateFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestCreateFirewallRule, self).setUp()
|
||||
self.neutronclient.create_fwaas_firewall_rule = mock.Mock(
|
||||
return_value={self.res: _fwr})
|
||||
self.mocked = self.neutronclient.create_fwaas_firewall_rule
|
||||
self.networkclient.create_firewall_rule = mock.Mock(
|
||||
return_value=_fwr)
|
||||
self.mocked = self.networkclient.create_firewall_rule
|
||||
|
||||
def _mock_find_group(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_group.side_effect = _mock_find_group
|
||||
|
||||
self.cmd = firewallrule.CreateFirewallRule(self.app, self.namespace)
|
||||
|
||||
def _update_expect_response(self, request, response):
|
||||
|
|
@ -193,8 +201,7 @@ class TestCreateFirewallRule(TestFirewallRule, common.TestCreateFWaaS):
|
|||
A OrderedDict of request body
|
||||
"""
|
||||
# Update response body
|
||||
self.neutronclient.create_fwaas_firewall_rule.return_value = \
|
||||
{self.res: dict(response)}
|
||||
self.networkclient.create_firewall_rule.return_value = response
|
||||
osc_utils.find_project.return_value.id = response['tenant_id']
|
||||
# Update response(finally returns 'data')
|
||||
self.data = _generate_data(ordered_dict=response)
|
||||
|
|
@ -254,17 +261,6 @@ class TestCreateFirewallRule(TestFirewallRule, common.TestCreateFWaaS):
|
|||
return arglist, verifylist
|
||||
|
||||
def _test_create_with_all_params(self, args={}):
|
||||
def _mock_fwr(*args, **kwargs):
|
||||
if self.neutronclient.find_resource.call_count == 1:
|
||||
self.neutronclient.find_resource.assert_called_once_with(
|
||||
const.FWG, 'my-src-fwg', cmd_resource=const.CMD_FWG)
|
||||
if self.neutronclient.find_resource.call_count == 2:
|
||||
self.neutronclient.find_resource.assert_called_with(
|
||||
const.FWG, 'my-dst-fwg', cmd_resource=const.CMD_FWG)
|
||||
return {'id': args[1]}
|
||||
|
||||
self.neutronclient.find_resource.side_effect = mock.Mock(
|
||||
side_effect=_mock_fwr)
|
||||
arglist, verifylist = self._set_all_params(args)
|
||||
request, response = _generate_req_and_res(verifylist)
|
||||
self._update_expect_response(request, response)
|
||||
|
|
@ -279,7 +275,7 @@ class TestCreateFirewallRule(TestFirewallRule, common.TestCreateFWaaS):
|
|||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
self.check_results(headers, data, {})
|
||||
self.check_results(headers, data, None)
|
||||
|
||||
def test_create_with_all_params(self):
|
||||
self._test_create_with_all_params()
|
||||
|
|
@ -349,19 +345,19 @@ class TestListFirewallRule(TestFirewallRule):
|
|||
if expect:
|
||||
if expect.get('protocol'):
|
||||
protocol = expect['protocol']
|
||||
if expect.get('source'):
|
||||
src = expect['source']
|
||||
if expect.get('dest'):
|
||||
dst = expect['dest']
|
||||
if expect.get('source_ip_address'):
|
||||
src_ip = expect['source_ip_address']
|
||||
if expect.get('source_port'):
|
||||
src_port = expect['source_port']
|
||||
if expect.get('destination_ip_address'):
|
||||
dst_ip = expect['destination_ip_address']
|
||||
if expect.get('destination_port'):
|
||||
dst_port = expect['destination_port']
|
||||
if expect.get('action'):
|
||||
action = expect['action']
|
||||
summary = ',\n '.join([protocol, src, dst, action])
|
||||
self.short_data = (
|
||||
_fwr['id'],
|
||||
_fwr['name'],
|
||||
_fwr['enabled'],
|
||||
summary
|
||||
)
|
||||
src = 'source(port): ' + src_ip + '(' + src_port + ')'
|
||||
dst = 'dest(port): ' + dst_ip + '(' + dst_port + ')'
|
||||
return ',\n '.join([protocol, src, dst, action])
|
||||
|
||||
def setUp(self):
|
||||
super(TestListFirewallRule, self).setUp()
|
||||
|
|
@ -372,11 +368,21 @@ class TestListFirewallRule(TestFirewallRule):
|
|||
'Name',
|
||||
'Enabled',
|
||||
'Summary',
|
||||
'Firewall Policy',
|
||||
)
|
||||
self._setup_summary()
|
||||
self.neutronclient.list_fwaas_firewall_rules = mock.Mock(
|
||||
return_value={self.res_plural: [_fwr]})
|
||||
self.mocked = self.neutronclient.list_fwaas_firewall_rules
|
||||
|
||||
summary = self._setup_summary(_fwr)
|
||||
|
||||
self.short_data = (
|
||||
_fwr['id'],
|
||||
_fwr['name'],
|
||||
_fwr['enabled'],
|
||||
summary,
|
||||
_fwr['firewall_policy_id']
|
||||
)
|
||||
self.networkclient.firewall_rules = mock.Mock(
|
||||
return_value=[_fwr])
|
||||
self.mocked = self.networkclient.firewall_rules
|
||||
|
||||
def test_list_with_long_option(self):
|
||||
arglist = ['--long']
|
||||
|
|
@ -386,8 +392,6 @@ class TestListFirewallRule(TestFirewallRule):
|
|||
|
||||
self.mocked.assert_called_once_with()
|
||||
self.assertEqual(list(self.headers), headers)
|
||||
m = list(data)
|
||||
self.assertListItemEqual([self.data], m)
|
||||
|
||||
def test_list_with_no_option(self):
|
||||
arglist = []
|
||||
|
|
@ -404,9 +408,9 @@ class TestShowFirewallRule(TestFirewallRule, common.TestShowFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestShowFirewallRule, self).setUp()
|
||||
self.neutronclient.show_fwaas_firewall_rule = mock.Mock(
|
||||
return_value={self.res: _fwr})
|
||||
self.mocked = self.neutronclient.show_fwaas_firewall_rule
|
||||
self.networkclient.get_firewall_rule = mock.Mock(
|
||||
return_value=_fwr)
|
||||
self.mocked = self.networkclient.get_firewall_rule
|
||||
self.cmd = firewallrule.ShowFirewallRule(self.app, self.namespace)
|
||||
|
||||
|
||||
|
|
@ -414,9 +418,15 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestSetFirewallRule, self).setUp()
|
||||
self.neutronclient.update_fwaas_firewall_rule = mock.Mock(
|
||||
return_value={self.res: _fwr})
|
||||
self.mocked = self.neutronclient.update_fwaas_firewall_rule
|
||||
self.networkclient.update_firewall_rule = mock.Mock(
|
||||
return_value=_fwr)
|
||||
self.mocked = self.networkclient.update_firewall_rule
|
||||
|
||||
def _mock_find_rule(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_find_rule
|
||||
|
||||
self.cmd = firewallrule.SetFirewallRule(self.app, self.namespace)
|
||||
|
||||
def test_set_protocol_with_any(self):
|
||||
|
|
@ -430,8 +440,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'protocol': None}})
|
||||
self.mocked.assert_called_once_with(target, **{'protocol': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_protocol_with_udp(self):
|
||||
|
|
@ -445,8 +454,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'protocol': protocol}})
|
||||
self.mocked.assert_called_once_with(target, **{'protocol': protocol})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_source_ip_address(self):
|
||||
|
|
@ -461,7 +469,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'source_ip_address': src_ip}})
|
||||
target, **{'source_ip_address': src_ip})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_source_port(self):
|
||||
|
|
@ -476,7 +484,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'source_port': src_port}})
|
||||
target, **{'source_port': src_port})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_destination_ip_address(self):
|
||||
|
|
@ -491,7 +499,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'destination_ip_address': dst_ip}})
|
||||
target, **{'destination_ip_address': dst_ip})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_destination_port(self):
|
||||
|
|
@ -506,7 +514,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'destination_port': dst_port}})
|
||||
target, **{'destination_port': dst_port})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_enable_rule(self):
|
||||
|
|
@ -519,8 +527,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'enabled': True}})
|
||||
self.mocked.assert_called_once_with(target, **{'enabled': True})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_disable_rule(self):
|
||||
|
|
@ -533,8 +540,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'enabled': False}})
|
||||
self.mocked.assert_called_once_with(target, **{'enabled': False})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_action(self):
|
||||
|
|
@ -548,8 +554,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'action': action}})
|
||||
self.mocked.assert_called_once_with(target, **{'action': action})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_enable_rule_and_disable_rule(self):
|
||||
|
|
@ -578,7 +583,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'source_ip_address': None}})
|
||||
target, **{'source_ip_address': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_source_port(self):
|
||||
|
|
@ -594,8 +599,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'source_port': None}})
|
||||
self.mocked.assert_called_once_with(target, **{'source_port': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_destination_ip_address(self):
|
||||
|
|
@ -612,7 +616,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'destination_ip_address': None}})
|
||||
target, **{'destination_ip_address': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_destination_port(self):
|
||||
|
|
@ -629,7 +633,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'destination_port': None}})
|
||||
target, **{'destination_port': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_source_ip_address_and_no(self):
|
||||
|
|
@ -697,7 +701,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_set_and_raises(self):
|
||||
self.neutronclient.update_fwaas_firewall_rule = mock.Mock(
|
||||
self.networkclient.update_firewall_rule = mock.Mock(
|
||||
side_effect=Exception)
|
||||
target = self.resource['id']
|
||||
arglist = [target, '--name', 'my-name']
|
||||
|
|
@ -721,7 +725,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'destination_firewall_group_id': None}})
|
||||
target, **{'destination_firewall_group_id': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_no_source_fwg(self):
|
||||
|
|
@ -738,7 +742,7 @@ class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'source_firewall_group_id': None}})
|
||||
target, **{'source_firewall_group_id': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_create_with_src_fwg_and_no(self):
|
||||
|
|
@ -780,13 +784,19 @@ class TestUnsetFirewallRule(TestFirewallRule, common.TestUnsetFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestUnsetFirewallRule, self).setUp()
|
||||
self.neutronclient.update_fwaas_firewall_rule = mock.Mock(
|
||||
self.networkclient.update_firewall_rule = mock.Mock(
|
||||
return_value={self.res: _fwr})
|
||||
self.mocked = self.neutronclient.update_fwaas_firewall_rule
|
||||
self.mocked = self.networkclient.update_firewall_rule
|
||||
|
||||
def _mock_find_rule(*args, **kwargs):
|
||||
return {'id': args[0]}
|
||||
|
||||
self.networkclient.find_firewall_rule.side_effect = _mock_find_rule
|
||||
|
||||
self.cmd = firewallrule.UnsetFirewallRule(self.app, self.namespace)
|
||||
|
||||
def test_unset_protocol_and_raise(self):
|
||||
self.neutronclient.update_fwaas_firewall_rule.side_effect = Exception
|
||||
self.networkclient.update_firewall_rule.side_effect = Exception
|
||||
target = self.resource['id']
|
||||
arglist = [
|
||||
target,
|
||||
|
|
@ -813,7 +823,7 @@ class TestUnsetFirewallRule(TestFirewallRule, common.TestUnsetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'source_port': None}})
|
||||
target, **{'source_port': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_destination_port(self):
|
||||
|
|
@ -830,7 +840,7 @@ class TestUnsetFirewallRule(TestFirewallRule, common.TestUnsetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'destination_port': None}})
|
||||
target, **{'destination_port': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_source_ip_address(self):
|
||||
|
|
@ -847,7 +857,7 @@ class TestUnsetFirewallRule(TestFirewallRule, common.TestUnsetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'source_ip_address': None}})
|
||||
target, **{'source_ip_address': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_destination_ip_address(self):
|
||||
|
|
@ -864,7 +874,7 @@ class TestUnsetFirewallRule(TestFirewallRule, common.TestUnsetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'destination_ip_address': None}})
|
||||
target, **{'destination_ip_address': None})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_enable_rule(self):
|
||||
|
|
@ -881,7 +891,7 @@ class TestUnsetFirewallRule(TestFirewallRule, common.TestUnsetFWaaS):
|
|||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.mocked.assert_called_once_with(
|
||||
target, {self.res: {'enabled': False}})
|
||||
target, **{'enabled': False})
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
|
|
@ -889,7 +899,6 @@ class TestDeleteFirewallRule(TestFirewallRule, common.TestDeleteFWaaS):
|
|||
|
||||
def setUp(self):
|
||||
super(TestDeleteFirewallRule, self).setUp()
|
||||
self.neutronclient.delete_fwaas_firewall_rule = mock.Mock(
|
||||
return_value={self.res: _fwr})
|
||||
self.mocked = self.neutronclient.delete_fwaas_firewall_rule
|
||||
self.networkclient.delete_firewall_rule = mock.Mock(return_value=_fwr)
|
||||
self.mocked = self.networkclient.delete_firewall_rule
|
||||
self.cmd = firewallrule.DeleteFirewallRule(self.app, self.namespace)
|
||||
|
|
|
|||
|
|
@ -17,10 +17,11 @@
|
|||
import copy
|
||||
from unittest import mock
|
||||
|
||||
from openstack.network.v2 import bgpvpn as _bgpvpn
|
||||
from openstack import resource as sdk_resource
|
||||
from osc_lib.utils import columns as column_util
|
||||
|
||||
from neutronclient.osc import utils as nc_osc_utils
|
||||
from neutronclient.osc.v2.networking_bgpvpn import constants
|
||||
from neutronclient.osc.v2.networking_bgpvpn.resource_association import\
|
||||
CreateBgpvpnResAssoc
|
||||
from neutronclient.osc.v2.networking_bgpvpn.resource_association import\
|
||||
|
|
@ -61,50 +62,45 @@ class TestNeutronClientBgpvpn(test_fakes.TestNeutronClientOSCV2):
|
|||
side_effect=lambda _, name_or_id, __: mock.Mock(id=name_or_id))
|
||||
|
||||
|
||||
class FakeBgpvpn(object):
|
||||
"""Fake BGP VPN with attributes."""
|
||||
def create_one_bgpvpn(attrs=None):
|
||||
"""Create a fake BGP VPN."""
|
||||
|
||||
@staticmethod
|
||||
def create_one_bgpvpn(attrs=None):
|
||||
"""Create a fake BGP VPN."""
|
||||
attrs = attrs or {}
|
||||
|
||||
attrs = attrs or {}
|
||||
# Set default attributes.
|
||||
bgpvpn_attrs = {
|
||||
'id': 'fake_bgpvpn_id',
|
||||
'tenant_id': _FAKE_PROJECT_ID,
|
||||
'name': '',
|
||||
'type': 'l3',
|
||||
'route_targets': [],
|
||||
'import_targets': [],
|
||||
'export_targets': [],
|
||||
'route_distinguishers': [],
|
||||
'networks': [],
|
||||
'routers': [],
|
||||
'ports': [],
|
||||
'vni': 100,
|
||||
'local_pref': 777,
|
||||
}
|
||||
|
||||
# Set default attributes.
|
||||
bgpvpn_attrs = {
|
||||
'id': 'fake_bgpvpn_id',
|
||||
'tenant_id': _FAKE_PROJECT_ID,
|
||||
'name': '',
|
||||
'type': 'l3',
|
||||
'route_targets': [],
|
||||
'import_targets': [],
|
||||
'export_targets': [],
|
||||
'route_distinguishers': [],
|
||||
'networks': [],
|
||||
'routers': [],
|
||||
'ports': [],
|
||||
'vni': 100,
|
||||
'local_pref': 777,
|
||||
}
|
||||
# Overwrite default attributes.
|
||||
bgpvpn_attrs.update(attrs)
|
||||
return _bgpvpn.BgpVpn(**bgpvpn_attrs)
|
||||
|
||||
# Overwrite default attributes.
|
||||
bgpvpn_attrs.update(attrs)
|
||||
|
||||
return copy.deepcopy(bgpvpn_attrs)
|
||||
def create_bgpvpns(attrs=None, count=1):
|
||||
"""Create multiple fake BGP VPN."""
|
||||
|
||||
@staticmethod
|
||||
def create_bgpvpns(attrs=None, count=1):
|
||||
"""Create multiple fake BGP VPN."""
|
||||
bgpvpns = []
|
||||
for i in range(0, count):
|
||||
if attrs is None:
|
||||
attrs = {'id': 'fake_id%d' % i}
|
||||
elif getattr(attrs, 'id', None) is None:
|
||||
attrs['id'] = 'fake_id%d' % i
|
||||
bgpvpns.append(create_one_bgpvpn(attrs))
|
||||
|
||||
bgpvpns = []
|
||||
for i in range(0, count):
|
||||
if attrs is None:
|
||||
attrs = {'id': 'fake_id%d' % i}
|
||||
elif getattr(attrs, 'id', None) is None:
|
||||
attrs['id'] = 'fake_id%d' % i
|
||||
bgpvpns.append(FakeBgpvpn.create_one_bgpvpn(attrs))
|
||||
|
||||
return {constants.BGPVPNS: bgpvpns}
|
||||
return bgpvpns
|
||||
|
||||
|
||||
class BgpvpnFakeAssoc(object):
|
||||
|
|
@ -114,9 +110,10 @@ class BgpvpnFakeAssoc(object):
|
|||
|
||||
_attr_map = (
|
||||
('id', 'ID', column_util.LIST_BOTH),
|
||||
('tenant_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('%s_id' % _assoc_res_name, '%s ID' % _assoc_res_name.capitalize(),
|
||||
column_util.LIST_BOTH),
|
||||
('name', 'Name', column_util.LIST_BOTH),
|
||||
('project_id', 'Project ID', column_util.LIST_BOTH),
|
||||
)
|
||||
_formatters = {}
|
||||
|
||||
|
|
@ -152,11 +149,12 @@ class BgpvpnFakeRouterAssoc(object):
|
|||
|
||||
_attr_map = (
|
||||
('id', 'ID', column_util.LIST_BOTH),
|
||||
('tenant_id', 'Project', column_util.LIST_LONG_ONLY),
|
||||
('%s_id' % _assoc_res_name, '%s ID' % _assoc_res_name.capitalize(),
|
||||
column_util.LIST_BOTH),
|
||||
('advertise_extra_routes', 'Advertise extra routes',
|
||||
column_util.LIST_LONG_ONLY),
|
||||
('name', 'Name', column_util.LIST_BOTH),
|
||||
('project_id', 'Project ID', column_util.LIST_BOTH),
|
||||
)
|
||||
_formatters = {}
|
||||
|
||||
|
|
@ -174,71 +172,99 @@ class ShowBgpvpnFakeRouterAssoc(BgpvpnFakeRouterAssoc, ShowBgpvpnRouterAssoc):
|
|||
pass
|
||||
|
||||
|
||||
class FakeResource(object):
|
||||
"""Fake resource with minimal attributes."""
|
||||
class FakeResource(sdk_resource.Resource):
|
||||
resource_key = 'fakeresource'
|
||||
resources_key = 'fakeresources'
|
||||
base_path = '/bgpvpn/fakeresources'
|
||||
|
||||
@staticmethod
|
||||
def create_one_resource(attrs=None):
|
||||
"""Create a fake resource."""
|
||||
_allow_unknown_attrs_in_body = True
|
||||
|
||||
attrs = attrs or {}
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_fetch = True
|
||||
allow_commit = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
# Set default attributes.
|
||||
res_attrs = {
|
||||
'id': 'fake_resource_id',
|
||||
'tenant_id': _FAKE_PROJECT_ID,
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
res_attrs.update(attrs)
|
||||
return copy.deepcopy(res_attrs)
|
||||
|
||||
@staticmethod
|
||||
def create_resources(attrs=None, count=1):
|
||||
"""Create multiple fake resources."""
|
||||
|
||||
resources = []
|
||||
for i in range(0, count):
|
||||
if attrs is None:
|
||||
attrs = {'id': 'fake_id%d' % i}
|
||||
elif getattr(attrs, 'id', None) is None:
|
||||
attrs['id'] = 'fake_id%d' % i
|
||||
resources.append(FakeResource.create_one_resource(attrs))
|
||||
|
||||
return {'%ss' % BgpvpnFakeAssoc._assoc_res_name: resources}
|
||||
id = sdk_resource.Body('id')
|
||||
tenant_id = sdk_resource.Body('tenant_id', deprecated=True)
|
||||
project_id = sdk_resource.Body('project_id', alias='tenant_id')
|
||||
|
||||
|
||||
class FakeResAssoc(object):
|
||||
"""Fake resource association with minimal attributes."""
|
||||
class FakeResoureAssociation(sdk_resource.Resource):
|
||||
resource_key = 'fakeresourceassociation'
|
||||
resources_key = 'fakeresourceassociations'
|
||||
base_path = '/bgpvpn/fakeresourceassociations'
|
||||
|
||||
@staticmethod
|
||||
def create_one_resource_association(resource, attrs=None):
|
||||
"""Create a fake resource association."""
|
||||
_allow_unknown_attrs_in_body = True
|
||||
|
||||
attrs = attrs or {}
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_fetch = True
|
||||
allow_commit = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
id = sdk_resource.Body('id')
|
||||
tenant_id = sdk_resource.Body('tenant_id', deprecated=True)
|
||||
project_id = sdk_resource.Body('project_id', alias='tenant_id')
|
||||
|
||||
|
||||
def create_one_resource(attrs=None):
|
||||
"""Create a fake resource."""
|
||||
attrs = attrs or {}
|
||||
|
||||
# Set default attributes.
|
||||
res_attrs = {
|
||||
'id': 'fake_resource_id',
|
||||
'tenant_id': _FAKE_PROJECT_ID,
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
res_attrs.update(attrs)
|
||||
return FakeResource(**res_attrs)
|
||||
|
||||
|
||||
def create_resources(attrs=None, count=1):
|
||||
"""Create multiple fake resources."""
|
||||
|
||||
resources = []
|
||||
for i in range(0, count):
|
||||
if attrs is None:
|
||||
attrs = {'id': 'fake_id%d' % i}
|
||||
elif getattr(attrs, 'id', None) is None:
|
||||
attrs['id'] = 'fake_id%d' % i
|
||||
resources.append(create_one_resource(attrs))
|
||||
|
||||
return resources
|
||||
|
||||
|
||||
def create_one_resource_association(resource, attrs=None):
|
||||
"""Create a fake resource association."""
|
||||
|
||||
attrs = attrs or {}
|
||||
|
||||
res_assoc_attrs = {
|
||||
'id': 'fake_association_id',
|
||||
'tenant_id': resource['tenant_id'],
|
||||
'fake_resource_id': resource['id'],
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
res_assoc_attrs.update(attrs)
|
||||
return FakeResoureAssociation(**res_assoc_attrs)
|
||||
|
||||
|
||||
def create_resource_associations(resources):
|
||||
"""Create multiple fake resource associations."""
|
||||
|
||||
res_assocs = []
|
||||
for idx, resource in enumerate(resources):
|
||||
res_assoc_attrs = {
|
||||
'id': 'fake_association_id',
|
||||
'id': 'fake_association_id%d' % idx,
|
||||
'tenant_id': resource['tenant_id'],
|
||||
'fake_resource_id': resource['id'],
|
||||
}
|
||||
res_assocs.append(copy.deepcopy(res_assoc_attrs))
|
||||
|
||||
# Overwrite default attributes.
|
||||
res_assoc_attrs.update(attrs)
|
||||
return copy.deepcopy(res_assoc_attrs)
|
||||
|
||||
@staticmethod
|
||||
def create_resource_associations(resources):
|
||||
"""Create multiple fake resource associations."""
|
||||
|
||||
res_assocs = []
|
||||
for idx, resource in enumerate(
|
||||
resources['%ss' % BgpvpnFakeAssoc._assoc_res_name]):
|
||||
res_assoc_attrs = {
|
||||
'id': 'fake_association_id%d' % idx,
|
||||
'tenant_id': resource['tenant_id'],
|
||||
'fake_resource_id': resource['id'],
|
||||
}
|
||||
res_assocs.append(copy.deepcopy(res_assoc_attrs))
|
||||
|
||||
return {BgpvpnFakeAssoc._resource_plural: res_assocs}
|
||||
return res_assocs
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ from osc_lib import utils as osc_utils
|
|||
from osc_lib.utils import columns as column_util
|
||||
|
||||
from neutronclient.osc.v2.networking_bgpvpn import bgpvpn
|
||||
from neutronclient.osc.v2.networking_bgpvpn import constants
|
||||
from neutronclient.tests.unit.osc.v2.networking_bgpvpn import fakes
|
||||
|
||||
|
||||
|
|
@ -55,9 +54,9 @@ class TestCreateBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
self.cmd = bgpvpn.CreateBgpvpn(self.app, self.namespace)
|
||||
|
||||
def test_create_bgpvpn_with_no_args(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
self.neutronclient.create_bgpvpn = mock.Mock(
|
||||
return_value={constants.BGPVPN: fake_bgpvpn})
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
self.networkclient.create_bgpvpn = mock.Mock(
|
||||
return_value=fake_bgpvpn)
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('project', None),
|
||||
|
|
@ -75,10 +74,10 @@ class TestCreateBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
cols, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.create_bgpvpn.assert_called_once_with(
|
||||
{constants.BGPVPN: {'type': 'l3'}})
|
||||
self.assertEqual(sorted_headers, cols)
|
||||
self.assertItemEqual(_get_data(fake_bgpvpn), data)
|
||||
self.networkclient.create_bgpvpn.assert_called_once_with(
|
||||
**{'type': 'l3'})
|
||||
|
||||
self.assertEqual(sorted(sorted_columns), sorted(cols))
|
||||
|
||||
def test_create_bgpvpn_with_all_args(self):
|
||||
attrs = {
|
||||
|
|
@ -92,9 +91,9 @@ class TestCreateBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
'export_targets': ['fake_ert1', 'fake_ert2', 'fake_ert3'],
|
||||
'route_distinguishers': ['fake_rd1', 'fake_rd2', 'fake_rd3'],
|
||||
}
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn(attrs)
|
||||
self.neutronclient.create_bgpvpn = mock.Mock(
|
||||
return_value={constants.BGPVPN: fake_bgpvpn})
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn(attrs)
|
||||
self.networkclient.create_bgpvpn = mock.Mock(
|
||||
return_value=fake_bgpvpn)
|
||||
arglist = [
|
||||
'--project', fake_bgpvpn['tenant_id'],
|
||||
'--name', fake_bgpvpn['name'],
|
||||
|
|
@ -126,21 +125,18 @@ class TestCreateBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
cols, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
fake_bgpvpn_call = copy.deepcopy(fake_bgpvpn)
|
||||
fake_bgpvpn_call.pop('id')
|
||||
fake_bgpvpn_call.pop('networks')
|
||||
fake_bgpvpn_call.pop('routers')
|
||||
fake_bgpvpn_call.pop('ports')
|
||||
fake_bgpvpn_call = copy.deepcopy(attrs)
|
||||
|
||||
self.neutronclient.create_bgpvpn.assert_called_once_with(
|
||||
{constants.BGPVPN: fake_bgpvpn_call})
|
||||
self.assertEqual(sorted_headers, cols)
|
||||
self.assertItemEqual(_get_data(fake_bgpvpn), data)
|
||||
self.networkclient.create_bgpvpn.assert_called_once_with(
|
||||
**fake_bgpvpn_call)
|
||||
self.assertEqual(sorted(sorted_columns), sorted(cols))
|
||||
|
||||
|
||||
class TestSetBgpvpn(fakes.TestNeutronClientBgpvpn):
|
||||
def setUp(self):
|
||||
super(TestSetBgpvpn, self).setUp()
|
||||
self.networkclient.find_bgpvpn = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
self.cmd = bgpvpn.SetBgpvpn(self.app, self.namespace)
|
||||
|
||||
def test_set_bgpvpn(self):
|
||||
|
|
@ -150,10 +146,10 @@ class TestSetBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
'export_targets': ['set_ert1', 'set_ert2', 'set_ert3'],
|
||||
'route_distinguishers': ['set_rd1', 'set_rd2', 'set_rd3'],
|
||||
}
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn(attrs)
|
||||
self.neutronclient.show_bgpvpn = mock.Mock(
|
||||
return_value={constants.BGPVPN: fake_bgpvpn})
|
||||
self.neutronclient.update_bgpvpn = mock.Mock()
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn(attrs)
|
||||
self.networkclient.get_bgpvpn = mock.Mock(
|
||||
return_value=fake_bgpvpn)
|
||||
self.networkclient.update_bgpvpn = mock.Mock()
|
||||
arglist = [
|
||||
fake_bgpvpn['id'],
|
||||
'--name', 'set_name',
|
||||
|
|
@ -190,14 +186,14 @@ class TestSetBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
'route_distinguishers': list(
|
||||
set(fake_bgpvpn['route_distinguishers']) | set(['set_rd1'])),
|
||||
}
|
||||
self.neutronclient.update_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'], {constants.BGPVPN: attrs})
|
||||
self.networkclient.update_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'], **attrs)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_set_bgpvpn_with_purge_list(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
self.neutronclient.show_bgpvpn = mock.Mock(
|
||||
return_value={constants.BGPVPN: fake_bgpvpn})
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
self.networkclient.get_bgpvpn = mock.Mock(
|
||||
return_value=fake_bgpvpn)
|
||||
self.neutronclient.update_bgpvpn = mock.Mock()
|
||||
arglist = [
|
||||
fake_bgpvpn['id'],
|
||||
|
|
@ -232,14 +228,16 @@ class TestSetBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
'export_targets': [],
|
||||
'route_distinguishers': [],
|
||||
}
|
||||
self.neutronclient.update_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'], {constants.BGPVPN: attrs})
|
||||
self.networkclient.update_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'], **attrs)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
class TestUnsetBgpvpn(fakes.TestNeutronClientBgpvpn):
|
||||
def setUp(self):
|
||||
super(TestUnsetBgpvpn, self).setUp()
|
||||
self.networkclient.find_bgpvpn = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
self.cmd = bgpvpn.UnsetBgpvpn(self.app, self.namespace)
|
||||
|
||||
def test_unset_bgpvpn(self):
|
||||
|
|
@ -249,10 +247,10 @@ class TestUnsetBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
'export_targets': ['unset_ert1', 'unset_ert2', 'unset_ert3'],
|
||||
'route_distinguishers': ['unset_rd1', 'unset_rd2', 'unset_rd3'],
|
||||
}
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn(attrs)
|
||||
self.neutronclient.show_bgpvpn = mock.Mock(
|
||||
return_value={constants.BGPVPN: fake_bgpvpn})
|
||||
self.neutronclient.update_bgpvpn = mock.Mock()
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn(attrs)
|
||||
self.networkclient.get_bgpvpn = mock.Mock(
|
||||
return_value=fake_bgpvpn)
|
||||
self.networkclient.update_bgpvpn = mock.Mock()
|
||||
arglist = [
|
||||
fake_bgpvpn['id'],
|
||||
'--route-target', 'unset_rt1',
|
||||
|
|
@ -286,14 +284,14 @@ class TestUnsetBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
'route_distinguishers': list(
|
||||
set(fake_bgpvpn['route_distinguishers']) - set(['unset_rd1'])),
|
||||
}
|
||||
self.neutronclient.update_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'], {constants.BGPVPN: attrs})
|
||||
self.networkclient.update_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'], **attrs)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_unset_bgpvpn_with_purge_list(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
self.neutronclient.show_bgpvpn = mock.Mock(
|
||||
return_value={constants.BGPVPN: fake_bgpvpn})
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
self.networkclient.show_bgpvpn = mock.Mock(
|
||||
return_value=fake_bgpvpn)
|
||||
self.neutronclient.update_bgpvpn = mock.Mock()
|
||||
arglist = [
|
||||
fake_bgpvpn['id'],
|
||||
|
|
@ -328,21 +326,21 @@ class TestUnsetBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
'export_targets': [],
|
||||
'route_distinguishers': [],
|
||||
}
|
||||
self.neutronclient.update_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'], {constants.BGPVPN: attrs})
|
||||
self.networkclient.update_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'], **attrs)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
class TestDeleteBgpvpn(fakes.TestNeutronClientBgpvpn):
|
||||
def setUp(self):
|
||||
super(TestDeleteBgpvpn, self).setUp()
|
||||
self.neutronclient.find_resource = mock.Mock(
|
||||
side_effect=lambda _, name_or_id: {'id': name_or_id})
|
||||
self.networkclient.find_bgpvpn = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
self.cmd = bgpvpn.DeleteBgpvpn(self.app, self.namespace)
|
||||
|
||||
def test_delete_one_bgpvpn(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
self.neutronclient.delete_bgpvpn = mock.Mock()
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
self.networkclient.delete_bgpvpn = mock.Mock()
|
||||
arglist = [
|
||||
fake_bgpvpn['id'],
|
||||
]
|
||||
|
|
@ -354,15 +352,14 @@ class TestDeleteBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.delete_bgpvpn.assert_called_once_with(
|
||||
self.networkclient.delete_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'])
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multi_bpgvpn(self):
|
||||
fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=3)
|
||||
fake_bgpvpn_ids = [fake_bgpvpn['id'] for fake_bgpvpn in
|
||||
fake_bgpvpns[constants.BGPVPNS]]
|
||||
self.neutronclient.delete_bgpvpn = mock.Mock()
|
||||
fake_bgpvpns = fakes.create_bgpvpns(count=3)
|
||||
fake_bgpvpn_ids = [fake_bgpvpn['id'] for fake_bgpvpn in fake_bgpvpns]
|
||||
self.networkclient.delete_bgpvpn = mock.Mock()
|
||||
arglist = fake_bgpvpn_ids
|
||||
verifylist = [
|
||||
('bgpvpns', fake_bgpvpn_ids),
|
||||
|
|
@ -372,20 +369,19 @@ class TestDeleteBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.delete_bgpvpn.assert_has_calls(
|
||||
self.networkclient.delete_bgpvpn.assert_has_calls(
|
||||
[mock.call(id) for id in fake_bgpvpn_ids])
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multi_bpgvpn_with_unknown(self):
|
||||
count = 3
|
||||
fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count)
|
||||
fake_bgpvpn_ids = [fake_bgpvpn['id'] for fake_bgpvpn in
|
||||
fake_bgpvpns[constants.BGPVPNS]]
|
||||
fake_bgpvpns = fakes.create_bgpvpns(count=count)
|
||||
fake_bgpvpn_ids = [fake_bgpvpn['id'] for fake_bgpvpn in fake_bgpvpns]
|
||||
|
||||
def raise_unknonw_resource(resource_path, name_or_id):
|
||||
if str(count - 2) in name_or_id:
|
||||
raise Exception()
|
||||
self.neutronclient.delete_bgpvpn = mock.Mock(
|
||||
self.networkclient.delete_bgpvpn = mock.Mock(
|
||||
side_effect=raise_unknonw_resource)
|
||||
arglist = fake_bgpvpn_ids
|
||||
verifylist = [
|
||||
|
|
@ -397,7 +393,7 @@ class TestDeleteBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
self.neutronclient.delete_bgpvpn.assert_has_calls(
|
||||
self.networkclient.delete_bgpvpn.assert_has_calls(
|
||||
[mock.call(id) for id in fake_bgpvpn_ids])
|
||||
|
||||
|
||||
|
|
@ -408,8 +404,8 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
def test_list_all_bgpvpn(self):
|
||||
count = 3
|
||||
fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count)
|
||||
self.neutronclient.list_bgpvpns = mock.Mock(return_value=fake_bgpvpns)
|
||||
fake_bgpvpns = fakes.create_bgpvpns(count=count)
|
||||
self.networkclient.bgpvpns = mock.Mock(return_value=fake_bgpvpns)
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
|
|
@ -417,17 +413,17 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.list_bgpvpns.assert_called_once()
|
||||
self.networkclient.bgpvpns.assert_called_once()
|
||||
self.assertEqual(headers, list(headers_short))
|
||||
self.assertListItemEqual(
|
||||
list(data),
|
||||
[_get_data(fake_bgpvpn, columns_short) for fake_bgpvpn
|
||||
in fake_bgpvpns[constants.BGPVPNS]])
|
||||
in fake_bgpvpns])
|
||||
|
||||
def test_list_all_bgpvpn_long_mode(self):
|
||||
count = 3
|
||||
fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count)
|
||||
self.neutronclient.list_bgpvpns = mock.Mock(return_value=fake_bgpvpns)
|
||||
fake_bgpvpns = fakes.create_bgpvpns(count=count)
|
||||
self.networkclient.bgpvpns = mock.Mock(return_value=fake_bgpvpns)
|
||||
arglist = [
|
||||
'--long',
|
||||
]
|
||||
|
|
@ -439,20 +435,20 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.list_bgpvpns.assert_called_once()
|
||||
self.networkclient.bgpvpns.assert_called_once()
|
||||
self.assertEqual(headers, list(headers_long))
|
||||
self.assertListItemEqual(
|
||||
list(data),
|
||||
[_get_data(fake_bgpvpn, columns_long) for fake_bgpvpn
|
||||
in fake_bgpvpns[constants.BGPVPNS]])
|
||||
in fake_bgpvpns])
|
||||
|
||||
def test_list_project_bgpvpn(self):
|
||||
count = 3
|
||||
project_id = 'list_fake_project_id'
|
||||
attrs = {'tenant_id': project_id}
|
||||
fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count,
|
||||
attrs=attrs)
|
||||
self.neutronclient.list_bgpvpns = mock.Mock(return_value=fake_bgpvpns)
|
||||
fake_bgpvpns = fakes.create_bgpvpns(count=count,
|
||||
attrs=attrs)
|
||||
self.networkclient.bgpvpns = mock.Mock(return_value=fake_bgpvpns)
|
||||
arglist = [
|
||||
'--project', project_id,
|
||||
]
|
||||
|
|
@ -464,24 +460,23 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.list_bgpvpns.assert_called_once_with(
|
||||
self.networkclient.bgpvpns.assert_called_once_with(
|
||||
tenant_id=project_id)
|
||||
self.assertEqual(headers, list(headers_short))
|
||||
self.assertListItemEqual(
|
||||
list(data),
|
||||
[_get_data(fake_bgpvpn, columns_short) for fake_bgpvpn
|
||||
in fake_bgpvpns[constants.BGPVPNS]])
|
||||
in fake_bgpvpns])
|
||||
|
||||
def test_list_bgpvpn_with_filters(self):
|
||||
count = 3
|
||||
name = 'fake_id0'
|
||||
layer_type = 'l2'
|
||||
attrs = {'type': layer_type}
|
||||
fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count,
|
||||
attrs=attrs)
|
||||
returned_bgpvpn = fake_bgpvpns[constants.BGPVPNS][0]
|
||||
self.neutronclient.list_bgpvpns = mock.Mock(
|
||||
return_value={constants.BGPVPNS: [returned_bgpvpn]})
|
||||
fake_bgpvpns = fakes.create_bgpvpns(count=count,
|
||||
attrs=attrs)
|
||||
returned_bgpvpn = fake_bgpvpns[0]
|
||||
self.networkclient.bgpvpns = mock.Mock(return_value=[returned_bgpvpn])
|
||||
arglist = [
|
||||
'--property', 'name=%s' % name,
|
||||
'--property', 'type=%s' % layer_type,
|
||||
|
|
@ -494,7 +489,7 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.list_bgpvpns.assert_called_once_with(
|
||||
self.networkclient.bgpvpns.assert_called_once_with(
|
||||
name=name,
|
||||
type=layer_type)
|
||||
self.assertEqual(headers, list(headers_short))
|
||||
|
|
@ -506,11 +501,13 @@ class TestShowBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
def setUp(self):
|
||||
super(TestShowBgpvpn, self).setUp()
|
||||
self.cmd = bgpvpn.ShowBgpvpn(self.app, self.namespace)
|
||||
self.networkclient.find_bgpvpn = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
|
||||
def test_show_bgpvpn(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
self.neutronclient.show_bgpvpn = mock.Mock(
|
||||
return_value={constants.BGPVPN: fake_bgpvpn})
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
self.networkclient.get_bgpvpn = mock.Mock(
|
||||
return_value=fake_bgpvpn)
|
||||
arglist = [
|
||||
fake_bgpvpn['id'],
|
||||
]
|
||||
|
|
@ -522,7 +519,6 @@ class TestShowBgpvpn(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.show_bgpvpn.assert_called_once_with(
|
||||
self.networkclient.get_bgpvpn.assert_called_once_with(
|
||||
fake_bgpvpn['id'])
|
||||
self.assertEqual(sorted_headers, headers)
|
||||
self.assertItemEqual(_get_data(fake_bgpvpn), data)
|
||||
self.assertEqual(sorted(sorted_columns), sorted(headers))
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
# under the License.
|
||||
#
|
||||
|
||||
import copy
|
||||
import operator
|
||||
from unittest import mock
|
||||
|
||||
|
|
@ -55,15 +54,21 @@ def _get_data(attrs, columns=sorted_columns):
|
|||
class TestCreateResAssoc(fakes.TestNeutronClientBgpvpn):
|
||||
def setUp(self):
|
||||
super(TestCreateResAssoc, self).setUp()
|
||||
self.networkclient.find_bgpvpn = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
self.networkclient.find_fake_resource = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
self.cmd = fakes.CreateBgpvpnFakeResAssoc(self.app, self.namespace)
|
||||
|
||||
def test_create_resource_association(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
fake_res = fakes.FakeResource.create_one_resource()
|
||||
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
fake_res = fakes.create_one_resource()
|
||||
fake_res_assoc = fakes.create_one_resource_association(
|
||||
fake_res)
|
||||
self.neutronclient.create_bgpvpn_fake_resource_assoc = mock.Mock(
|
||||
return_value={fakes.BgpvpnFakeAssoc._resource: fake_res_assoc})
|
||||
self.networkclient.create_bgpvpn_router_association = mock.Mock(
|
||||
return_value=fake_res_assoc)
|
||||
self.networkclient.find_bgpvpn_fake_resource_association = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
arglist = [
|
||||
fake_bgpvpn['id'],
|
||||
fake_res['id'],
|
||||
|
|
@ -79,14 +84,16 @@ class TestCreateResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
cols, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
fake_res_assoc_call = copy.deepcopy(fake_res_assoc)
|
||||
fake_res_assoc_call.pop('id')
|
||||
fake_res_assoc_call = {
|
||||
'fake_resource_id': 'fake_resource_id',
|
||||
'tenant_id': 'fake_project_id'
|
||||
}
|
||||
|
||||
self.neutronclient.create_bgpvpn_fake_resource_assoc.\
|
||||
self.networkclient.create_bgpvpn_router_association.\
|
||||
assert_called_once_with(
|
||||
fake_bgpvpn['id'],
|
||||
{fakes.BgpvpnFakeAssoc._resource: fake_res_assoc_call})
|
||||
self.assertEqual(sorted_headers, cols)
|
||||
**fake_res_assoc_call)
|
||||
self.assertEqual(sorted_columns, cols)
|
||||
self.assertEqual(_get_data(fake_res_assoc), data)
|
||||
|
||||
|
||||
|
|
@ -96,11 +103,11 @@ class TestSetResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
self.cmd = fakes.SetBgpvpnFakeResAssoc(self.app, self.namespace)
|
||||
|
||||
def test_set_resource_association(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
fake_res = fakes.FakeResource.create_one_resource()
|
||||
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
fake_res = fakes.create_one_resource()
|
||||
fake_res_assoc = fakes.create_one_resource_association(
|
||||
fake_res)
|
||||
self.neutronclient.update_bgpvpn_fake_resource_assoc = mock.Mock(
|
||||
self.networkclient.update_bgpvpn_router_association = mock.Mock(
|
||||
return_value={fakes.BgpvpnFakeAssoc._resource: fake_res_assoc})
|
||||
arglist = [
|
||||
fake_res_assoc['id'],
|
||||
|
|
@ -115,7 +122,7 @@ class TestSetResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.update_bgpvpn_fake_resource_assoc.\
|
||||
self.networkclient.update_bgpvpn_router_association.\
|
||||
assert_not_called()
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
|
@ -123,14 +130,17 @@ class TestSetResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
class TestDeleteResAssoc(fakes.TestNeutronClientBgpvpn):
|
||||
def setUp(self):
|
||||
super(TestDeleteResAssoc, self).setUp()
|
||||
self.networkclient.find_bgpvpn = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
self.cmd = fakes.DeleteBgpvpnFakeResAssoc(self.app, self.namespace)
|
||||
|
||||
def test_delete_one_association(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
fake_res = fakes.FakeResource.create_one_resource()
|
||||
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
fake_res = fakes.create_one_resource()
|
||||
fake_res_assoc = fakes.create_one_resource_association(
|
||||
fake_res)
|
||||
self.neutronclient.delete_bgpvpn_fake_resource_assoc = mock.Mock()
|
||||
self.networkclient.delete_bgpvpn_router_association = \
|
||||
mock.Mock()
|
||||
arglist = [
|
||||
fake_res_assoc['id'],
|
||||
fake_bgpvpn['id'],
|
||||
|
|
@ -144,21 +154,21 @@ class TestDeleteResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.delete_bgpvpn_fake_resource_assoc.\
|
||||
self.networkclient.delete_bgpvpn_router_association.\
|
||||
assert_called_once_with(fake_bgpvpn['id'], fake_res_assoc['id'])
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multi_bpgvpn(self):
|
||||
count = 3
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
fake_res = fakes.FakeResource.create_resources(count=count)
|
||||
fake_res_assocs = fakes.FakeResAssoc.create_resource_associations(
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
fake_res = fakes.create_resources(count=count)
|
||||
fake_res_assocs = fakes.create_resource_associations(
|
||||
fake_res)
|
||||
fake_res_assoc_ids = [
|
||||
fake_res_assoc['id'] for fake_res_assoc in
|
||||
fake_res_assocs[fakes.BgpvpnFakeAssoc._resource_plural]
|
||||
fake_res_assoc['id'] for fake_res_assoc in fake_res_assocs
|
||||
]
|
||||
self.neutronclient.delete_bgpvpn_fake_resource_assoc = mock.Mock()
|
||||
self.networkclient.delete_bgpvpn_router_association = \
|
||||
mock.Mock()
|
||||
arglist = \
|
||||
fake_res_assoc_ids + [
|
||||
fake_bgpvpn['id']
|
||||
|
|
@ -172,25 +182,26 @@ class TestDeleteResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.delete_bgpvpn_fake_resource_assoc.assert_has_calls(
|
||||
[mock.call(fake_bgpvpn['id'], id) for id in fake_res_assoc_ids])
|
||||
self.networkclient.delete_bgpvpn_router_association.\
|
||||
assert_has_calls([
|
||||
mock.call(
|
||||
fake_bgpvpn['id'], id) for id in fake_res_assoc_ids])
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multi_bpgvpn_with_unknown(self):
|
||||
count = 3
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
fake_res = fakes.FakeResource.create_resources(count=count)
|
||||
fake_res_assocs = fakes.FakeResAssoc.create_resource_associations(
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
fake_res = fakes.create_resources(count=count)
|
||||
fake_res_assocs = fakes.create_resource_associations(
|
||||
fake_res)
|
||||
fake_res_assoc_ids = [
|
||||
fake_res_assoc['id'] for fake_res_assoc in
|
||||
fake_res_assocs[fakes.BgpvpnFakeAssoc._resource_plural]
|
||||
fake_res_assoc['id'] for fake_res_assoc in fake_res_assocs
|
||||
]
|
||||
|
||||
def raise_unknonw_resource(resource_path, name_or_id):
|
||||
if str(count - 2) in name_or_id:
|
||||
raise Exception()
|
||||
self.neutronclient.delete_bgpvpn_fake_resource_assoc = mock.Mock(
|
||||
self.networkclient.delete_bgpvpn_router_association = mock.Mock(
|
||||
side_effect=raise_unknonw_resource)
|
||||
arglist = \
|
||||
fake_res_assoc_ids + [
|
||||
|
|
@ -206,22 +217,26 @@ class TestDeleteResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
self.neutronclient.delete_bgpvpn_fake_resource_assoc.assert_has_calls(
|
||||
[mock.call(fake_bgpvpn['id'], id) for id in fake_res_assoc_ids])
|
||||
self.networkclient.delete_bgpvpn_router_association.\
|
||||
assert_has_calls([
|
||||
mock.call(fake_bgpvpn['id'], id) for id in fake_res_assoc_ids]
|
||||
)
|
||||
|
||||
|
||||
class TestListResAssoc(fakes.TestNeutronClientBgpvpn):
|
||||
def setUp(self):
|
||||
super(TestListResAssoc, self).setUp()
|
||||
self.networkclient.find_bgpvpn = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
self.cmd = fakes.ListBgpvpnFakeResAssoc(self.app, self.namespace)
|
||||
|
||||
def test_list_bgpvpn_associations(self):
|
||||
count = 3
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
fake_res = fakes.FakeResource.create_resources(count=count)
|
||||
fake_res_assocs = fakes.FakeResAssoc.create_resource_associations(
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
fake_res = fakes.create_resources(count=count)
|
||||
fake_res_assocs = fakes.create_resource_associations(
|
||||
fake_res)
|
||||
self.neutronclient.list_bgpvpn_fake_resource_assocs = mock.Mock(
|
||||
self.networkclient.bgpvpn_router_associations = mock.Mock(
|
||||
return_value=fake_res_assocs)
|
||||
arglist = [
|
||||
fake_bgpvpn['id'],
|
||||
|
|
@ -234,21 +249,21 @@ class TestListResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.list_bgpvpn_fake_resource_assocs.\
|
||||
self.networkclient.bgpvpn_router_associations.\
|
||||
assert_called_once_with(fake_bgpvpn['id'], retrieve_all=True)
|
||||
self.assertEqual(headers, list(headers_short))
|
||||
self.assertEqual(
|
||||
list(data),
|
||||
[_get_data(fake_res_assoc, columns_short) for fake_res_assoc
|
||||
in fake_res_assocs[fakes.BgpvpnFakeAssoc._resource_plural]])
|
||||
in fake_res_assocs])
|
||||
|
||||
def test_list_bgpvpn_associations_long_mode(self):
|
||||
count = 3
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
fake_res = fakes.FakeResource.create_resources(count=count)
|
||||
fake_res_assocs = fakes.FakeResAssoc.create_resource_associations(
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
fake_res = fakes.create_resources(count=count)
|
||||
fake_res_assocs = fakes.create_resource_associations(
|
||||
fake_res)
|
||||
self.neutronclient.list_bgpvpn_fake_resource_assocs = mock.Mock(
|
||||
self.networkclient.bgpvpn_router_associations = mock.Mock(
|
||||
return_value=fake_res_assocs)
|
||||
arglist = [
|
||||
'--long',
|
||||
|
|
@ -263,27 +278,29 @@ class TestListResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.list_bgpvpn_fake_resource_assocs.\
|
||||
self.networkclient.bgpvpn_router_associations.\
|
||||
assert_called_once_with(fake_bgpvpn['id'], retrieve_all=True)
|
||||
self.assertEqual(headers, list(headers_long))
|
||||
self.assertEqual(
|
||||
list(data),
|
||||
[_get_data(fake_res_assoc, columns_long) for fake_res_assoc
|
||||
in fake_res_assocs[fakes.BgpvpnFakeAssoc._resource_plural]])
|
||||
in fake_res_assocs])
|
||||
|
||||
|
||||
class TestShowResAssoc(fakes.TestNeutronClientBgpvpn):
|
||||
def setUp(self):
|
||||
super(TestShowResAssoc, self).setUp()
|
||||
self.networkclient.find_bgpvpn = mock.Mock(
|
||||
side_effect=lambda name_or_id: {'id': name_or_id})
|
||||
self.cmd = fakes.ShowBgpvpnFakeResAssoc(self.app, self.namespace)
|
||||
|
||||
def test_show_resource_association(self):
|
||||
fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
|
||||
fake_res = fakes.FakeResource.create_one_resource()
|
||||
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
|
||||
fake_bgpvpn = fakes.create_one_bgpvpn()
|
||||
fake_res = fakes.create_one_resource()
|
||||
fake_res_assoc = fakes.create_one_resource_association(
|
||||
fake_res)
|
||||
self.neutronclient.show_bgpvpn_fake_resource_assoc = mock.Mock(
|
||||
return_value={fakes.BgpvpnFakeAssoc._resource: fake_res_assoc})
|
||||
self.networkclient.get_bgpvpn_router_association = mock.Mock(
|
||||
return_value=fake_res_assoc)
|
||||
arglist = [
|
||||
fake_res_assoc['id'],
|
||||
fake_bgpvpn['id'],
|
||||
|
|
@ -295,9 +312,9 @@ class TestShowResAssoc(fakes.TestNeutronClientBgpvpn):
|
|||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
headers, data = self.cmd.take_action(parsed_args)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.neutronclient.show_bgpvpn_fake_resource_assoc.\
|
||||
self.networkclient.get_bgpvpn_router_association.\
|
||||
assert_called_once_with(fake_bgpvpn['id'], fake_res_assoc['id'])
|
||||
self.assertEqual(sorted_headers, headers)
|
||||
self.assertEqual(sorted_columns, columns)
|
||||
self.assertEqual(data, _get_data(fake_res_assoc))
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue