Compare commits

...

81 commits

Author SHA1 Message Date
Zuul
efa0ccb944 Merge "Revert "Add Tap-as-a-Service client code"" 2025-12-12 17:29:15 +00:00
Zhan Zhang
8f72d77812 v2_0: Use 'bindings' when listing port bindings
This commit fixes a bug in v2_0 client's "list_port_bindings"
function, where it uses "port_bindings" to access Neutron's
response, instead of "bindings" [0].

[0]: https://docs.openstack.org/api-ref/network/v2/index.html#show-port-binding-of-a-port

Closes-Bug: #2130459
Change-Id: I32ef753ec212b55f698e3844e043f68b22992ead
Signed-off-by: Zhan Zhang <zzhang953@bloomberg.net>
2025-11-11 14:05:44 -05:00
Miro Tomaska
a991ac87c7 Revert "Add Tap-as-a-Service client code"
This reverts commit 01ffc4684a.

Reason for revert:
In the last PTG we decided that the best location for the stadium projects osc client code would be the openstackclient repo. A patch was proposed for tapaas, see depends-on link below. Other projects will follow

Change-Id: Iaad2080f0ef552a0c0a00635bea48130cfc327a4
Depends-On: https://review.opendev.org/c/openstack/python-openstackclient/+/963445
Signed-off-by: Miro Tomaska <mtomaska@redhat.com>
2025-11-06 21:39:01 +00:00
OpenStack Release Bot
01d0553ca4 reno: Update master for unmaintained/2024.1
Update the 2024.1 release notes configuration to build from
unmaintained/2024.1.

Change-Id: Ic2592d22b36b22f3cf48a21d81bfb0b41b31ae86
Signed-off-by: OpenStack Release Bot <infra-root@openstack.org>
Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/change_reno_branch_to_unmaintained.sh
2025-10-31 12:06:40 +00:00
Zuul
66ccb4569d Merge "Add Tap-as-a-Service client code" 2025-09-19 16:22:01 +00:00
Zuul
1aee34b246 Merge "Drop unused os-client-config" 2025-09-15 20:36:02 +00:00
Mohammed Naser
01ffc4684a Add Tap-as-a-Service client code
This commit adds the Tap-as-a-Service client code as-is based
on the discussion that it can now be included into the Neutron
client[1].

[1]: https://lists.openstack.org/archives/list/openstack-discuss@lists.openstack.org/message/PCITF3UPLEEVQB7EVJ2MB6FLAI3RFYSR/

Change-Id: I82b3229b3f9ac7ef57324d0a611527c77d26c3b6
Signed-off-by: Mohammed Naser <mnaser@vexxhost.com>
2025-09-12 11:37:06 -04:00
OpenStack Release Bot
2f170ce6aa Update master for stable/2025.2
Add file to the reno documentation build to show release notes for
stable/2025.2.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/2025.2.

Sem-Ver: feature
Change-Id: I97f7bba4f875b98d98f03ba60ee394a1aa64a3fd
Signed-off-by: OpenStack Release Bot <infra-root@openstack.org>
Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/add_release_note_page.sh
2025-09-04 13:44:40 +00:00
Takashi Kajinami
275924ecc8 Drop unused os-client-config
It was deprecated[1] after the code was merged into openstacksdk[2].
It's not actually used by any code in this repository.

[1] https://review.opendev.org/c/openstack/os-client-config/+/549307
[2] https://review.opendev.org/c/openstack/openstacksdk/+/518128

Change-Id: Ia93d2952ca09fc70a970a85789775441ed114d49
Signed-off-by: Takashi Kajinami <kajinamit@oss.nttdata.com>
2025-07-02 23:23:28 +09:00
Zuul
5f7d102f0e Merge "Add warning for using the python bindings" 2025-06-13 01:25:15 +00:00
Takashi Kajinami
905be917fe Drop explicit dependency on python-subunit
It is no longer directly used by any test code in this repository since
we switched to stestr[1].

It is now installed as a dependency of stestr.

[1] 259c386d42

Change-Id: Iacbdd3477a9e0b2d2bae3e09d20867d794586673
2025-06-10 12:12:18 +00:00
elajkat
857b4b233c Add warning for using the python bindings
The deprecation of python-neutronclient bindings
was discussed on the 2025.2 (Flamingo) PTG:
https://etherpad.opendev.org/p/apr2025-ptg-neutron#L163

Change-Id: Ieb08fc0884d7f386dc94090dce9d284d786d1ec2
2025-04-30 13:35:14 +02:00
OpenStack Release Bot
690bb97d9d Update master for stable/2025.1
Add file to the reno documentation build to show release notes for
stable/2025.1.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/2025.1.

Sem-Ver: feature
Change-Id: Ia1fb8c591c315404d4e758a657a4b35fe523dfff
2025-03-06 09:16:53 +00:00
Zuul
7d998d2525 Merge "Remove unnecessary direct dependency on iso8601" 2025-03-03 20:57:35 +00:00
Takashi Kajinami
370bd215c7 Remove unnecessary direct dependency on iso8601
Direct dependency on the library was removed by [1].

[1] 9c464ba53f

Change-Id: Id24f85b68c42977cb3f34c66934238a16e03a79c
2025-03-01 01:11:16 +09:00
Bodo Petermann
dc026cd3d6 vpnaas: add support for more ciphers (auth, encryption, pfs modes)
Extend the lists of choices for encryption algorithms, auth algorithms,
and PFS groups to include the additions made in neutron-vpnaas.

Encryption algorithms: add AES CCM mode and AES GCM mode variants
for 128/192/256 bit keys and 8/12/16 octet ICVs, add AES CTR modes
for 128/192/256 bit keys
Auth algorithms: add aes-xcbc and aes-cmac.
PFS: add Diffie Hellman groups 15 to 31.

Related-Bug: #1938284
Change-Id: I3fd17b93820da9d86b2fc4bc89058475d7629d5d
2025-02-26 16:02:25 +01:00
Zuul
1d7a13ab11 Merge "vpnaas: show external_vx_ip for vpn service show" 2024-11-20 17:34:37 +00:00
OpenStack Release Bot
636ac764d3 reno: Update master for unmaintained/2023.1
Update the 2023.1 release notes configuration to build from
unmaintained/2023.1.

Change-Id: Id69fb2c2e197e91d679473c52f556e378fa3ba1e
2024-11-14 10:35:43 +00:00
elajkat
b2107dc867 vpnaas: show external_vx_ip for vpn service show
Closes-Bug: #2086144
Change-Id: Ic8ae85ee62e35991e8bb0096cdc6785a0b04e545
2024-11-08 09:02:34 +01:00
Zuul
75e112bc9b Merge "Drop unused tempest from test requirements" 2024-11-04 20:43:19 +00:00
Zuul
1befb3cd08 Merge "tox: Drop envdir" 2024-10-30 10:50:03 +00:00
Takashi Kajinami
f882f1ddb6 Remove Python 3.8 support
Python 3.8 was removed from the tested runtimes for 2024.2[1] and has
not been tested since then.

Also add a few newer versions which are part of the tested runtimes for
2025.1.

[1] https://governance.openstack.org/tc/reference/runtimes/2024.2.html

Change-Id: Ic0c05be1ce22dc2a5c67c6eb2b215d50d57ff116
2024-10-24 21:19:15 +09:00
Takashi Kajinami
8a2f07683b tox: Drop envdir
tox now always recreates an env although the env is shared using envdir
options.
~~~
$ tox -e genpolicy
genpolicy: recreate env because env type changed from
{'name': 'genconfig', 'type': 'VirtualEnvRunner'} to
{'name': 'genpolicy', 'type': 'VirtualEnvRunner'}
~~~

According to the maintainer of tox, this functionality is not intended
to be supported.
https://github.com/tox-dev/tox/issues/425#issuecomment-1011944293

Change-Id: I496d3ffe65be13df80c29ac4582596be0aa4d909
2024-10-13 01:30:39 +09:00
Takashi Kajinami
5438377b9c Drop unused tempest from test requirements
None of the tests implemented in this repository depend on tempest.

In addition testscenarios is not used either, and can be removed.

Change-Id: I642f8a5093a6e2b5528e446a798270734c4ed30d
2024-10-12 00:06:07 +09:00
OpenStack Release Bot
d36a8a4a17 Update master for stable/2024.2
Add file to the reno documentation build to show release notes for
stable/2024.2.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/2024.2.

Sem-Ver: feature
Change-Id: I02c3547991a272afcc3a8902476949cd0bd1ce74
2024-09-05 16:02:19 +00:00
Zuul
a10390c62e Merge "Fix insert and remove rule from firewall policy" 2024-05-20 11:19:44 +00:00
Valentin Chassignol
cb9aae55c8 BGPVPN: Fix resource comparison
This patch updates the resource comparison to accurately differentiate
between the manipulation of networks, ports, and router associations.
Introduced in I84fe4bb45d24c2f4a7a0246e2b9fb50354a715e0, the previous
implementation contained incorrect variable names, leading to
inconsistent results. This fix ensures that each resource type is
properly identified during comparison.

Closes-Bug: #2064286
Change-Id: Ieb87174296240f8f76ec10b39007935545b1bd3f
2024-05-06 14:22:08 +00:00
OpenStack Release Bot
fb8de782bc reno: Update master for unmaintained/zed
Update the zed release notes configuration to build from
unmaintained/zed.

Change-Id: I73aa32050dfaa378dd7455846e994560851c0e54
2024-04-30 08:54:59 +00:00
Benjamin Reichel
2169b2bbab Fix insert and remove rule from firewall policy
This change fixes the incompatability with the openstacksdk
for inserting and removing rules from firewall policiese.

Closes-Bug: #2057816
Change-Id: I8db7b4cc61b810887b0a675efa562f089821e8ec
2024-04-12 10:42:12 +02:00
Zuul
111713fd62 Merge "reno: Update master for unmaintained/victoria" 2024-04-02 18:36:50 +00:00
Zuul
98d8d8b5cd Merge "reno: Update master for unmaintained/wallaby" 2024-04-02 18:36:08 +00:00
Zuul
1cdac483be Merge "reno: Update master for unmaintained/xena" 2024-04-02 18:34:58 +00:00
OpenStack Release Bot
fe515adf35 Update master for stable/2024.1
Add file to the reno documentation build to show release notes for
stable/2024.1.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/2024.1.

Sem-Ver: feature
Change-Id: I074213d853338f1e087b59f14f3c66ea449e5536
2024-03-07 15:38:58 +00:00
OpenStack Release Bot
41e7ea6e29 reno: Update master for unmaintained/xena
Update the xena release notes configuration to build from
unmaintained/xena.

Change-Id: I074395b7079588a5dd2f6188a04b5d48b10e124b
2024-03-06 12:21:58 +00:00
OpenStack Release Bot
863c6031fc reno: Update master for unmaintained/wallaby
Update the wallaby release notes configuration to build from
unmaintained/wallaby.

Change-Id: Ia81995fae56aef0951004ab1c7340a38f24a66f0
2024-03-06 12:14:08 +00:00
OpenStack Release Bot
750afa1777 reno: Update master for unmaintained/victoria
Update the victoria release notes configuration to build from
unmaintained/victoria.

Change-Id: I27ad08ec3327a9a9984223f7d9319129537040e4
2024-03-06 12:04:19 +00:00
Zuul
4e48e90788 Merge "Bump hacking" 2024-02-08 17:04:32 +00:00
OpenStack Release Bot
858b844cff reno: Update master for unmaintained/yoga
Update the yoga release notes configuration to build from
unmaintained/yoga.

Change-Id: Id65b43b5bd59567cec599aae48e962c6ac40b427
2024-02-05 16:47:19 +00:00
Takashi Kajinami
2d93d2e1ed Bump hacking
hacking 3.0.x is too old.

This also pulls the hacking options from neutron.

Change-Id: Ic1a428a05131f98d5a9050b83613c5478904f202
2024-01-30 18:09:53 +09:00
Rodolfo Alonso Hernandez
c28a5497c2 Add note to prevent new features to be added (CLI and Python bindings)
Change-Id: I19fb7426d91d6d7f27fee0507b7c28541ecaf344
2024-01-18 14:18:17 +00:00
Zuul
8ae44f83f5 Merge "Drop unused simplejson" 2023-11-13 19:30:17 +00:00
Takashi Kajinami
ee6f6a13ea Drop unused simplejson
This library no longer import simplejson directly since [1] was merged.

[1] 1f35b8f25c

Change-Id: I5689ed9f7852cc2bec3cf8035a773e63fb10e3d5
2023-11-05 18:32:33 +09:00
OpenStack Proposal Bot
8c983fa764 Imported Translations from Zanata
For more information about this automatic import see:
https://docs.openstack.org/i18n/latest/reviewing-translation-import.html

Change-Id: Ida432a5df2f6cc9453f546ad8e66b0e52c5d1b80
2023-09-09 03:54:47 +00:00
elajkat
b9152a5042 OSC: Remove SFC V2 calls to neutronclient
Change SFC CLI to use SDK instead of deprecated neutronclient
python bindings.
Add possibility to delete multiple resources as it is common
for other delete commands.
Bump SDK minimum version to 1.5.0.

Depends-On: https://review.opendev.org/c/openstack/openstacksdk/+/887387
Actually the new SDK release is the dependency.
Related-Bug: #1999774
Change-Id: Ic22b8163155904113db8a4acf1fe7d75ae100a84
2023-09-08 15:54:02 +02:00
elajkat
396432ab06 OSC: Remove VPNAAS V2 calls to neutronclient
Depends-On: https://review.opendev.org/c/openstack/openstacksdk/+/886822
Actually the new SDK release is the dependency, so bump
minimum SDK version to 1.5.0.

Change-Id: I1933dceb3dc28b464e6e9c4ce468abbd03a00ba4
Related-Bug: #1999774
2023-09-08 15:53:44 +02:00
Zuul
c4e8d90c0f Merge "OSC: Remove FWAAS V2 calls to neutronclient" 2023-09-08 11:37:32 +00:00
OpenStack Release Bot
6597c421ff Update master for stable/2023.2
Add file to the reno documentation build to show release notes for
stable/2023.2.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/2023.2.

Sem-Ver: feature
Change-Id: I7d5138a0e6bbbd33dd2bb737f865e54e4541a279
2023-09-07 09:42:55 +00:00
elajkat
fccfe8c3e5 OSC: Remove FWAAS V2 calls to neutronclient
Bump SDK min version to 1.5.0.

Depends-On: https://review.opendev.org/c/openstack/openstacksdk/+/883859
Related-Bug: #1999774
Change-Id: I1588ffa8035c2a4f558c6d3a630287542c718be4
2023-09-06 10:22:20 +02:00
Zuul
d497615240 Merge "BGPVPN: make resource_association method calls logic simpler" 2023-06-22 16:03:42 +00:00
Zuul
4521472198 Merge "Remove 'bgp speaker show dragents'" 2023-05-29 14:38:18 +00:00
elajkat
4ed299ad39 BGPVPN: make resource_association method calls logic simpler
This is a FUP based on the following comment:
https://review.opendev.org/c/openstack/python-neutronclient/+/875728/comment/c2f44683_82cffdbc/

Change-Id: I84fe4bb45d24c2f4a7a0246e2b9fb50354a715e0
Related-Bug: #1999774
2023-05-24 13:23:01 +02:00
elajkat
d4124aed1f OSC: Remove BGPVPN calls to neutronclient
With [1] the python binding code in Neutronclient prints warning
about future deprecation, change networking-bgpvpn osc client
code to use totally OpenstackSDK.

[1]: https://review.opendev.org/c/openstack/python-neutronclient/+/862371

Change-Id: Iae1378ffabda3d30257e35a6148e205a9f495eb5
Related-Bug: #1999774
Depends-On: https://review.opendev.org/c/openstack/openstacksdk/+/875530
2023-05-24 11:53:33 +02:00
Stephen Finucane
79c7de4630 Remove 'bgp speaker show dragents'
This has been deprecated for ages and generates an annoying warning when
building OSC docs. Time to cull it.

Change-Id: I76e4c7ab742d0bf27fecfda8fab41035618a4e24
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
2023-05-17 13:04:37 +01:00
Zuul
d342171f9e Merge "OSC: Remove BGP calls to neutronclient" 2023-05-02 15:49:07 +00:00
Slawek Kaplonski
52653c95e0 Remove the CLI code from the Neutron client.
This project no longer provides CLI support. All code has been
removed. Please use openstack CLI instead

This patch removes entry point for neutron CLI too, bash completion
script and CLI related functional and unit tests but it
still keeps neutronclient/neutron/v2_0 module as this is used by e.g.
Nova.

Co-Authored-By: Slawek Kaplonski <skaplons@redhat.com>

Closes-Bug: #2003861
Change-Id: I5b6c735d1ff931d7991a42b262e7faa47b75edeb
2023-04-11 13:12:45 +02:00
elajkat
0b271d3b8c OSC: Remove BGP calls to neutronclient
With [1] the python binding code in Neutronclient prints warning
about future deprecation, change neutron-dynamic-routing osc client
code to use totally OpenstackSDK.

[1]: https://review.opendev.org/c/openstack/python-neutronclient/+/862371

Related-Bug: #1999774
Depends-On: https://review.opendev.org/c/openstack/openstacksdk/+/869485
Depends-On: https://review.opendev.org/c/openstack/requirements/+/873598
Change-Id: I5dd143e670b70cc42a2ae48fe4bac0cf09416cb5
2023-03-03 13:16:15 +00:00
OpenStack Release Bot
3071dfbd0f Update master for stable/2023.1
Add file to the reno documentation build to show release notes for
stable/2023.1.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/2023.1.

Sem-Ver: feature
Change-Id: I194c39a2bbfde10c65912835019a8c2f21464569
2023-03-02 13:26:42 +00:00
Rodolfo Alonso Hernandez
16a2cd127d Remove CLI warning message
This warning was added in [1]. This patch is partially reverting it
but we keep the release note. This warning message could be a bit
intrusive for those users still using it. In any case, the
recommendation to move to OSC is something already known and
publicly requested.

[1]https://review.opendev.org/c/openstack/python-neutronclient/+/862371

Change-Id: I0c2fba3e45a9de1eba09efcf8919661a855c7e89
2023-02-14 08:30:20 +01:00
elajkat
68cbf56f9c Move network trunk commands from python-neutronclient
The depends-on patch adds trunk commands to OSC, as we can
long consider trunk operations as core Networking operations.

Change-Id: Ie557a5d541cf117d20f3f2b548620a74dbadb383
Depends-On: https://review.opendev.org/c/openstack/python-openstackclient/+/869447
Related-Bug: #1999774
2023-01-16 14:18:27 +01:00
elajkat
33f1c89a84 Tox4: add allowlist_externals where necessary
With tox4 allowlist_externals is more strictly checked, so
fix it where necessary and fix pylint version.

Depends-On: https://review.opendev.org/c/zuul/zuul-jobs/+/866943
Related-Bug: #1999558

Change-Id: Id115a436b95b3ede5a1f3102b4bb9e3ade75c970
2023-01-16 08:34:36 +00:00
Elvira García
776e360e35 Fix help sentence in network log create --enable
As the documentation states [1], the default in network log objects is
to be enabled, not disabled.

[1] https://docs.openstack.org/neutron/latest/admin/config-logging.html

Change-Id: I13e9d1132fc38104e6e85d9c8442bc7506adc2fd
2022-11-25 15:32:46 +01:00
elajkat
f67af3d9be Add warning and reno for SDK
On the 2023.1 (Antelope) PTG we discussed the status of the python
binding (SDK) code in python-neutronclient and decided to not allow new
features to this repo (see [1]), and make users to use openstacksdk.
Let's add a warning log message and a releasenote to make it visible.

[1]: https://etherpad.opendev.org/p/neutron-antelope-ptg#L163

Change-Id: I03317179bd0d30a69b91eef6e451b8e40eb28191
2022-10-21 16:40:38 +02:00
OpenStack Release Bot
ec84aff516 Switch to 2023.1 Python3 unit tests and generic template name
This is an automatically generated patch to ensure unit testing
is in place for all the of the tested runtimes for antelope. Also,
updating the template name to generic one.

See also the PTI in governance [1].

[1]: https://governance.openstack.org/tc/reference/project-testing-interface.html

Change-Id: I026505ff0d277fd4f15329ed26a5cecf1d573f68
2022-09-14 09:26:48 +00:00
OpenStack Release Bot
f060429cfc Update master for stable/zed
Add file to the reno documentation build to show release notes for
stable/zed.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/zed.

Sem-Ver: feature
Change-Id: Ie6a0efba406cd26606168ce5b6dbc8ee7ae759ed
2022-09-09 11:48:19 +00:00
Pedro Henrique
7467c710f6 Add support to floating ip port forwarding
To extend Horizon to allow users to create
port forwarding rules for their floating ips,
we need to extend this client to allow it,
as Horizon uses this client.

This patch is the one of a series of patches
to implement floating ip port forwarding with
port ranges.

The specification is defined in:
https://github.com/openstack/neutron-specs/blob/master/specs/wallaby/port-forwarding-port-ranges.rst

Implements: blueprint floatingips-portforwarding-ranges
Related-Bug: #1885921
Change-Id: I3f616dba5e2ebe301cf6ce4bed8c2e6e4da2da9b
2022-07-15 10:06:03 -03:00
Ghanshyam Mann
b720fdaee7 Update python testing as per zed cycle teting runtime
In Zed cycle, we have dropped the python 3.6/3.7[1] testing
and its support. Add release notes, move py36 jobs to py38|9,
and update the python classifier for the same.

[1] https://governance.openstack.org/tc/reference/runtimes/zed.html

Change-Id: Ibeee0b16ee1ea95f05127563a9cb08ffd0f04e2b
2022-05-11 22:25:31 -05:00
Ghanshyam Mann
143db0177a Drop lower-constraints.txt and its testing
As discussed in TC PTG[1] and TC resolution[2], we are
dropping the lower-constraints.txt file and its testing.
We will keep lower bounds in the requirements.txt file but
with a note that these are not tested lower bounds and we
try our best to keep them updated.

[1] https://etherpad.opendev.org/p/tc-zed-ptg#L326
[2] https://governance.openstack.org/tc/resolutions/20220414-drop-lower-constraints.html#proposal

Change-Id: I9a985c439675dc3aa6120a0d9734b8cdeaedccf8
2022-04-30 20:28:29 -05:00
Zuul
8c72cc87da Merge "Update master for stable/yoga" 2022-03-08 12:02:40 +00:00
OpenStack Release Bot
4575bea5a6 Update master for stable/yoga
Add file to the reno documentation build to show release notes for
stable/yoga.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/yoga.

Sem-Ver: feature
Change-Id: I3f709510026817ae2f36d646ca3fe9487637b717
2022-03-03 10:52:26 +00:00
Rodolfo Alonso Hernandez
28628e8f96 Skip B105 pep8 error: hardcoded passwords
Skip B105 pep8 error:
* https://bandit.readthedocs.io/en/latest/plugins/b105_hardcoded_password_string.html
* https://cwe.mitre.org/data/definitions/259.html

Trivial-Fix

Change-Id: I8e58da2d88d727018c8d5af5949e34f8c0893c1f
2022-03-03 00:26:29 +00:00
Zuul
6ca3341352 Merge "Add support for 'smart-nic' vnic-type" 2022-01-19 23:35:59 +00:00
dengzhaosen
517bef2c54 Update python testing classifier
Yoga testing runtime[1] has been updated to add py39
testing as voting. Unit tests update are handled by the
job template change in openstack-zuul-job

- https://review.opendev.org/c/openstack/openstack-zuul-jobs/+/820286

this commit updates the classifier in setup.cfg file.

[1] https://governance.openstack.org/tc/reference/runtimes/yoga.html

Change-Id: Iedb1c345df99ae9be5cce22ab930c6de7a5e7832
2021-12-24 09:36:50 +08:00
Zuul
d75e1e05b7 Merge "Add CURD actions for packet rate limit rule" 2021-12-06 15:32:48 +00:00
LIU Yulong
a92d8db81c Add CURD actions for packet rate limit rule
Neutron added new QoS rule [1] for packet rate limit.
Neutron fullstack test cases [2] rely on the neutron client
to interact with the neutron-server (API), so for new QoS rule
`packet rate limit`, we add the needed methods for new
cases of the QoS driver testing.

[1] https://docs.openstack.org/api-ref/network/v2/index.html#qos-packet-rate-limit-rules
[2] https://github.com/openstack/neutron/blob/master/neutron/tests/fullstack/resources/process.py#L24

Change-Id: I0ad236c9e585a25fbd405813ac48898a2df897d2
2021-11-24 00:23:08 +00:00
Przemyslaw Szczerbik
3b80135a3d Add support for minimum packet rate rule to the client
With the introduction of QoS minimum packet rate rule in Neutron,
it's important to ensure that tools like Heat support it as well.
Unfortunately, Heat still depends on python-neutronclient instead
of python-openstackclient. So even though QoS minimum packet rate
rule support have been proposed for python-openstackclient [1] and
openstacksdk [2], it's still necessary to extend python-neutronclient
code. Since Heat uses only the client part, can skip CLI support.

[1] https://review.opendev.org/c/openstack/python-openstackclient/+/810559
[2] https://review.opendev.org/c/openstack/openstacksdk/+/810364

Partial-Bug: #1922237
See-Also: https://review.opendev.org/785236
Change-Id: I4f16b963a202a476cd3cd2b69c1dd4e4ee6f0fc7
2021-11-19 08:05:56 +01:00
elajkat
3a65712b45 Fix lower-constraints and neutronclient-functional job
Change decorator in l-c.txt from 3.4.0 to 4.1.0
add neutron as devstack plugin to neutronclient-functional job.

Change-Id: Ib4b98f4e9e70f058ba5c7c43f559ab888edf1a88
2021-11-18 16:25:43 +01:00
Frode Nordahl
1df1f38a91 Add support for 'smart-nic' vnic-type
The 'smart-nic' vnic_type was added in the Train time frame in
I91f63810626ce4e054e358f5de5e46434c4da131.  This vnic_type will
also be used to support off-path SmartNIC port binding with OVN,
and it is expected that the user will create ports with this
vnic_type as part of the workflow.

As such the client must allow users to interact with this
vnic_type and this patch addresses that.

Partial-Bug: #1932154
Change-Id: I7f80bb47db7f8608db4d6a646b0f4b0ef6d6fb48
2021-09-14 14:31:24 +02:00
OpenStack Release Bot
792ad115b3 Add Python3 yoga unit tests
This is an automatically generated patch to ensure unit testing
is in place for all the of the tested runtimes for yoga.

See also the PTI in governance [1].

[1]: https://governance.openstack.org/tc/reference/project-testing-interface.html

Change-Id: Ib343cb56e2512862d5b23482a9861ba7b3ce6373
2021-09-10 14:33:53 +00:00
OpenStack Release Bot
ee73a48881 Update master for stable/xena
Add file to the reno documentation build to show release notes for
stable/xena.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/xena.

Sem-Ver: feature
Change-Id: If1185e64ff9e9c2a622f7a41df3993b3fe414b96
2021-09-10 14:33:52 +00:00
Zuul
4b29df7234 Merge "Replace deprecated assertDictContainsSubset" 2021-09-06 12:27:22 +00:00
Takashi Kajinami
cff9c266c0 Replace deprecated assertDictContainsSubset
The method is deprecated since Python 3.2[1] and shows the following
DeprecationWarning.

/usr/lib/python3.9/unittest/case.py:1134: DeprecationWarning:
assertDictContainsSubset is deprecated
  warnings.warn('assertDictContainsSubset is deprecated',

[1] https://docs.python.org/3/whatsnew/3.2.html#unittest

Closes-Bug: #1938103
Change-Id: I1d0ee6c77476707a7e4fe4fbf2b979bf34550d05
2021-09-05 00:56:38 +09:00
177 changed files with 3035 additions and 18883 deletions

View file

@ -1,19 +1,12 @@
- project:
templates:
- openstack-cover-jobs
- openstack-lower-constraints-jobs
- openstack-python3-xena-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:
- neutronclient-grenade-neutron-lib:
@ -21,51 +14,6 @@
- ^(test-|)requirements.txt$
- ^setup.cfg$
- job:
name: neutronclient-functional
parent: devstack-tox-functional
irrelevant-files:
- ^.*\.rst$
- ^doc/.*$
- ^releasenotes/.*$
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
# Disable OVN services
br-ex-tcpdump: false
br-int-flows: false
ovn-controller: false
ovn-northd: false
ovs-vswitchd: false
ovsdb-server: false
q-ovn-metadata-agent: false
# Neutron services
q-agt: true
q-dhcp: true
q-l3: true
q-meta: true
neutron-network-segment-range: true
neutron-segments: true
q-metering: true
q-qos: true
neutron-tag-ports-during-bulk-creation: true
neutron-conntrack-helper: true
devstack_localrc:
USE_PYTHON3: true
LIBS_FROM_GIT: python-neutronclient
Q_AGENT: openvswitch
Q_ML2_TENANT_NETWORK_TYPE: vxlan
Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
devstack_plugins:
neutron-vpnaas: https://opendev.org/openstack/neutron-vpnaas
- job:
name: neutronclient-grenade-neutron-lib
parent: grenade
@ -83,7 +31,6 @@
- openstack/keystoneauth
- openstack/neutron
- openstack/neutron-lib
- openstack/os-client-config
- openstack/python-cinderclient
- openstack/python-glanceclient
- openstack/python-ironicclient

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -31,6 +31,4 @@ OpenStack client.
.. toctree::
:maxdepth: 2
client_command_extensions
cli_option_guideline
transition_to_osc

View file

@ -105,7 +105,7 @@ Transition Steps
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 |
+-------------------------------------------------+-----------------------------------------------+

View file

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

View file

@ -1,111 +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.14.0
cliff==3.4.0
cmd2==0.8.0
contextlib2==0.4.0
coverage==4.0
cryptography==2.7
debtcollector==1.2.0
decorator==3.4.0
deprecation==1.0
docutils==0.11
dogpile.cache==0.6.5
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==3.6.0
future==0.16.0
futurist==1.2.0
greenlet==0.4.10
hacking==3.0.1
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.8.0
kombu==4.0.0
linecache2==1.0.0
MarkupSafe==1.0
mccabe==0.6.0
monotonic==0.6
msgpack-python==0.4.0
munch==2.1.0
netaddr==0.7.18
netifaces==0.10.4
openstacksdk==0.15.0
os-client-config==1.28.0
os-service-types==1.2.0
osc-lib==1.12.0
oslo.concurrency==3.26.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.4.0
pycparser==2.18
pyflakes==2.0.0
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==5.3.1
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==2.0.1
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

View file

@ -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! :)"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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):
@ -290,13 +277,10 @@ class SetBgpSpeaker(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']
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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,12 +128,12 @@ 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(
@ -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)

View file

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

View file

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

View file

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

View file

@ -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 Z cycle. 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:]))

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,136 +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):
if not self.is_extension_enabled('metering'):
self.skipTest('metering is not enabled')
self.neutron('meter-label-list')
def test_neutron_meter_label_rule_list(self):
if not self.is_extension_enabled('metering'):
self.skipTest('metering is not enabled')
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')

View file

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

View file

@ -1,2 +0,0 @@
enable_plugin neutron-fwaas https://opendev.org/openstack/neutron-fwaas
enable_service q-fwaas

View file

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

View file

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

View file

@ -1 +0,0 @@
enable_plugin neutron-vpnaas https://opendev.org/openstack/neutron-vpnaas

View file

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

View file

@ -1,224 +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 = '4294967296'
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 "4294967296" 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)

View file

@ -1,273 +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 = '4294967296'
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 "4294967296" 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)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -14,7 +14,6 @@
# under the License.
#
import copy
import operator
from unittest import mock
@ -56,8 +55,12 @@ class TestCreateRouterAssoc(fakes.TestNeutronClientBgpvpn):
def setUp(self):
super(TestCreateRouterAssoc, self).setUp()
self.cmd = fakes.CreateBgpvpnFakeRouterAssoc(self.app, self.namespace)
self.fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
self.fake_router = fakes.FakeResource.create_one_resource()
self.fake_bgpvpn = fakes.create_one_bgpvpn()
self.fake_router = fakes.create_one_resource()
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})
def _build_args(self, param=None):
arglist_base = [
@ -89,20 +92,26 @@ class TestCreateRouterAssoc(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'
}
for key, value in verifylist:
if value not in fake_res_assoc_call.values():
fake_res_assoc_call[key] = value
fake_res_assoc_call.pop('bgpvpn')
self.neutronclient.create_bgpvpn_fake_resource_assoc.\
self.networkclient.create_bgpvpn_router_association.\
assert_called_once_with(
self.fake_bgpvpn['id'],
{fakes.BgpvpnFakeRouterAssoc._resource: fake_res_assoc_call})
**fake_res_assoc_call)
return cols, data
def test_create_router_association(self):
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
fake_res_assoc = fakes.create_one_resource_association(
self.fake_router)
self.neutronclient.create_bgpvpn_fake_resource_assoc = mock.Mock(
self.networkclient.create_bgpvpn_router_association = mock.Mock(
return_value={
fakes.BgpvpnFakeRouterAssoc._resource: fake_res_assoc,
'advertise_extra_routes': True})
@ -116,37 +125,35 @@ class TestCreateRouterAssoc(fakes.TestNeutronClientBgpvpn):
fake_res_assoc, arglist, verifylist)
def test_create_router_association_advertise(self):
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
fake_res_assoc = fakes.create_one_resource_association(
self.fake_router,
{'advertise_extra_routes': True})
self.neutronclient.create_bgpvpn_fake_resource_assoc = mock.Mock(
return_value={
fakes.BgpvpnFakeRouterAssoc._resource: fake_res_assoc})
self.networkclient.create_bgpvpn_router_association = mock.Mock(
return_value=fake_res_assoc)
arglist = self._build_args('--advertise_extra_routes')
verifylist = self._build_verify_list(('advertise_extra_routes', True))
cols, data = self._exec_create_router_association(
fake_res_assoc, arglist, verifylist)
self.assertEqual(sorted_headers, cols)
self.assertEqual(sorted_columns, cols)
self.assertEqual(_get_data(fake_res_assoc), data)
def test_create_router_association_no_advertise(self):
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
fake_res_assoc = fakes.create_one_resource_association(
self.fake_router,
{'advertise_extra_routes': False})
self.neutronclient.create_bgpvpn_fake_resource_assoc = mock.Mock(
return_value={
fakes.BgpvpnFakeRouterAssoc._resource: fake_res_assoc})
self.networkclient.create_bgpvpn_router_association = mock.Mock(
return_value=fake_res_assoc)
arglist = self._build_args('--no-advertise_extra_routes')
verifylist = self._build_verify_list(('advertise_extra_routes', False))
cols, data = self._exec_create_router_association(
fake_res_assoc, arglist, verifylist)
self.assertEqual(sorted_headers, cols)
self.assertEqual(sorted_columns, cols)
self.assertEqual(_get_data(fake_res_assoc), data)
def test_create_router_association_advertise_fault(self):
@ -172,8 +179,10 @@ class TestSetRouterAssoc(fakes.TestNeutronClientBgpvpn):
def setUp(self):
super(TestSetRouterAssoc, self).setUp()
self.cmd = fakes.SetBgpvpnFakeRouterAssoc(self.app, self.namespace)
self.fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn()
self.fake_router = fakes.FakeResource.create_one_resource()
self.fake_bgpvpn = fakes.create_one_bgpvpn()
self.fake_router = fakes.create_one_resource()
self.networkclient.find_bgpvpn = mock.Mock(
side_effect=lambda name_or_id: {'id': name_or_id})
def _build_args(self, fake_res_assoc, param=None):
arglist_base = [
@ -197,10 +206,11 @@ class TestSetRouterAssoc(fakes.TestNeutronClientBgpvpn):
return verifylist
def test_set_router_association_no_advertise(self):
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
fake_res_assoc = fakes.create_one_resource_association(
self.fake_router,
{'advertise_extra_routes': True})
self.neutronclient.update_bgpvpn_fake_resource_assoc = mock.Mock()
self.networkclient.update_bgpvpn_router_association = \
mock.Mock()
arglist = self._build_args(
fake_res_assoc,
@ -213,25 +223,20 @@ class TestSetRouterAssoc(fakes.TestNeutronClientBgpvpn):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
fake_res_assoc_call = copy.deepcopy(fake_res_assoc)
fake_res_assoc_call.pop('id')
self.neutronclient.update_bgpvpn_fake_resource_assoc.\
self.networkclient.update_bgpvpn_router_association.\
assert_called_once_with(
self.fake_bgpvpn['id'],
fake_res_assoc['id'],
{
fakes.BgpvpnFakeRouterAssoc._resource: {
'advertise_extra_routes': False
}
})
**{'advertise_extra_routes': False}
)
self.assertIsNone(result)
def test_set_router_association_advertise(self):
fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association(
fake_res_assoc = fakes.create_one_resource_association(
self.fake_router,
{'advertise_extra_routes': False})
self.neutronclient.update_bgpvpn_fake_resource_assoc = mock.Mock()
self.networkclient.update_bgpvpn_router_association = \
mock.Mock()
arglist = self._build_args(
fake_res_assoc,
@ -244,18 +249,12 @@ class TestSetRouterAssoc(fakes.TestNeutronClientBgpvpn):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
fake_res_assoc_call = copy.deepcopy(fake_res_assoc)
fake_res_assoc_call.pop('id')
self.neutronclient.update_bgpvpn_fake_resource_assoc.\
self.networkclient.update_bgpvpn_router_association.\
assert_called_once_with(
self.fake_bgpvpn['id'],
fake_res_assoc['id'],
{
fakes.BgpvpnFakeRouterAssoc._resource: {
'advertise_extra_routes': True
}
})
**{'advertise_extra_routes': True}
)
self.assertIsNone(result)
@ -263,15 +262,17 @@ class TestShowRouterAssoc(fakes.TestNeutronClientBgpvpn):
def setUp(self):
super(TestShowRouterAssoc, self).setUp()
self.cmd = fakes.ShowBgpvpnFakeRouterAssoc(self.app, self.namespace)
self.networkclient.find_bgpvpn = mock.Mock(
side_effect=lambda name_or_id: {'id': name_or_id})
def test_show_router_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,
{'advertise_extra_routes': True})
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'],
@ -283,9 +284,9 @@ class TestShowRouterAssoc(fakes.TestNeutronClientBgpvpn):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
headers, data = self.cmd.take_action(parsed_args)
cols, 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, cols)
self.assertEqual(data, _get_data(fake_res_assoc))

View file

@ -14,13 +14,18 @@
# under the License.
import argparse
import copy
from unittest import mock
from osc_lib.tests import utils
from oslo_utils import uuidutils
from openstack.network.v2 import sfc_flow_classifier as flow_classifier
from openstack.network.v2 import sfc_port_chain as port_chain
from openstack.network.v2 import sfc_port_pair as port_pair
from openstack.network.v2 import sfc_port_pair_group as port_pair_group
from openstack.network.v2 import sfc_service_graph as service_graph
class TestNeutronClientOSCV2(utils.TestCommand):
@ -28,12 +33,32 @@ class TestNeutronClientOSCV2(utils.TestCommand):
super(TestNeutronClientOSCV2, self).setUp()
self.namespace = argparse.Namespace()
self.app.client_manager.session = mock.Mock()
self.app.client_manager.neutronclient = mock.Mock()
self.neutronclient = self.app.client_manager.neutronclient
self.neutronclient.find_resource = mock.Mock(
side_effect=lambda resource, name_or_id, project_id=None,
cmd_resource=None, parent_id=None, fields=None:
{'id': name_or_id})
self.app.client_manager.network = mock.Mock()
self.network = self.app.client_manager.network
self.network.find_sfc_flow_classifier = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id}
)
self.network.find_sfc_port_chain = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id}
)
self.network.find_sfc_port_pair = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id}
)
self.network.find_sfc_port_pair_group = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id}
)
self.network.find_sfc_service_graph = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id}
)
self.network.find_port = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id}
)
class FakeSfcPortPair(object):
@ -58,13 +83,14 @@ class FakeSfcPortPair(object):
'id': uuidutils.generate_uuid(),
'ingress': uuidutils.generate_uuid(),
'name': 'port-pair-name',
'service_function_parameters': 'correlation=None,weight=1',
'service_function_parameters': [('correlation', None),
('weight', 1)],
'project_id': uuidutils.generate_uuid(),
}
# Overwrite default attributes.
port_pair_attrs.update(attrs)
return copy.deepcopy(port_pair_attrs)
return port_pair.SfcPortPair(**port_pair_attrs)
@staticmethod
def create_port_pairs(attrs=None, count=1):
@ -102,18 +128,16 @@ class FakeSfcPortPairGroup(object):
# Set default attributes.
port_pair_group_attrs = {
'id': uuidutils.generate_uuid(),
'group_id': uuidutils.generate_uuid(),
'name': 'port-pair-group-name',
'description': 'description',
'port_pairs': uuidutils.generate_uuid(),
'port_pair_group_parameters': '{"lb_fields": []}',
'port_pair_group_parameters': {"lb_fields": []},
'project_id': uuidutils.generate_uuid(),
'tap_enabled': False
}
# port_pair_group_attrs default attributes.
port_pair_group_attrs.update(attrs)
return copy.deepcopy(port_pair_group_attrs)
return port_pair_group.SfcPortPairGroup(**port_pair_group_attrs)
@staticmethod
def create_port_pair_groups(attrs=None, count=1):
@ -164,10 +188,10 @@ class FakeSfcFlowClassifier(object):
'source_port_range_max': '20',
'source_port_range_min': '10',
'project_id': uuidutils.generate_uuid(),
'l7_parameters': '{}'
'l7_parameters': {}
}
flow_classifier_attrs.update(attrs)
return copy.deepcopy(flow_classifier_attrs)
return flow_classifier.SfcFlowClassifier(**flow_classifier_attrs)
@staticmethod
def create_flow_classifiers(attrs=None, count=1):
@ -205,18 +229,16 @@ class FakeSfcPortChain(object):
# Set default attributes.
port_chain_attrs = {
'id': uuidutils.generate_uuid(),
'chain_id': uuidutils.generate_uuid(),
'name': 'port-chain-name',
'description': 'description',
'port_pair_groups': uuidutils.generate_uuid(),
'flow_classifiers': uuidutils.generate_uuid(),
'chain_parameters': '{"correlation": mpls}',
'chain_parameters': {"correlation": "mpls", "symmetric": False},
'project_id': uuidutils.generate_uuid(),
}
# port_pair_group_attrs default attributes.
port_chain_attrs.update(attrs)
return copy.deepcopy(port_chain_attrs)
return port_chain.SfcPortChain(**port_chain_attrs)
@staticmethod
def create_port_chains(attrs=None, count=1):
@ -260,7 +282,7 @@ class FakeSfcServiceGraph(object):
}
service_graph_attrs.update(attrs)
return copy.deepcopy(service_graph_attrs)
return service_graph.SfcServiceGraph(**service_graph_attrs)
@staticmethod
def create_sfc_service_graphs(attrs=None, count=1):

View file

@ -15,15 +15,12 @@
from unittest import mock
from osc_lib import exceptions
import testtools
from neutronclient.osc.v2.sfc import sfc_flow_classifier
from neutronclient.tests.unit.osc.v2.sfc import fakes
get_id = 'neutronclient.osc.v2.sfc.sfc_flow_classifier._get_id'
def _get_id(client, id_or_name, resource):
return id_or_name
class TestCreateSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
@ -43,7 +40,8 @@ class TestCreateSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
'Protocol',
'Source IP',
'Source Port Range Max',
'Source Port Range Min')
'Source Port Range Min',
'Summary',)
def get_data(self):
return (
@ -66,9 +64,8 @@ class TestCreateSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestCreateSfcFlowClassifier, self).setUp()
mock.patch(get_id, new=_get_id).start()
self.neutronclient.create_sfc_flow_classifier = mock.Mock(
return_value={'flow_classifier': self._fc})
self.network.create_sfc_flow_classifier = mock.Mock(
return_value=self._fc)
self.data = self.get_data()
# Get the command object to test
@ -90,14 +87,13 @@ class TestCreateSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = (self.cmd.take_action(parsed_args))
self.neutronclient.create_sfc_flow_classifier.assert_called_once_with({
'flow_classifier': {
'name': self._fc['name'],
'logical_source_port': self._fc['logical_source_port'],
'ethertype': self._fc['ethertype']}
})
self.network.create_sfc_flow_classifier.assert_called_once_with(
**{'name': self._fc['name'],
'logical_source_port': self._fc['logical_source_port'],
'ethertype': self._fc['ethertype']
}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
def test_create_flow_classifier(self):
arglist = [
@ -129,8 +125,8 @@ class TestCreateSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = (self.cmd.take_action(parsed_args))
self.neutronclient.create_sfc_flow_classifier.assert_called_once_with({
'flow_classifier': {
self.network.create_sfc_flow_classifier.assert_called_once_with(
**{
'name': self._fc['name'],
'description': self._fc['description'],
'ethertype': self._fc['ethertype'],
@ -141,10 +137,9 @@ class TestCreateSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
'logical_destination_port':
self._fc['logical_destination_port'],
'l7_parameters': param
}
})
}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
class TestDeleteSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
@ -154,20 +149,19 @@ class TestDeleteSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestDeleteSfcFlowClassifier, self).setUp()
mock.patch(get_id, new=_get_id).start()
self.neutronclient.delete_sfc_flow_classifier = mock.Mock(
self.network.delete_sfc_flow_classifier = mock.Mock(
return_value=None)
self.cmd = sfc_flow_classifier.DeleteSfcFlowClassifier(self.app,
self.namespace)
def test_delete_flow_classifier(self):
client = self.app.client_manager.neutronclient
client = self.app.client_manager.network
mock_flow_classifier_delete = client.delete_sfc_flow_classifier
arglist = [
self._flow_classifier[0]['id'],
]
verifylist = [
('flow_classifier', self._flow_classifier[0]['id']),
('flow_classifier', [self._flow_classifier[0]['id']]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
@ -175,6 +169,22 @@ class TestDeleteSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
self._flow_classifier[0]['id'])
self.assertIsNone(result)
def test_delete_multiple_flow_classifiers_with_exception(self):
client = self.app.client_manager.network
target1 = self._flow_classifier[0]['id']
arglist = [target1]
verifylist = [('flow_classifier', [target1])]
client.find_sfc_flow_classifier.side_effect = [
target1, exceptions.CommandError
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
msg = "1 of 2 flow classifier(s) failed to delete."
with testtools.ExpectedException(exceptions.CommandError) as e:
self.cmd.take_action(parsed_args)
self.assertEqual(msg, str(e))
class TestSetSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
_flow_classifier = fakes.FakeSfcFlowClassifier.create_flow_classifier()
@ -183,14 +193,13 @@ class TestSetSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestSetSfcFlowClassifier, self).setUp()
mock.patch(get_id, new=_get_id).start()
self.neutronclient.update_sfc_flow_classifier = mock.Mock(
self.network.update_sfc_flow_classifier = mock.Mock(
return_value=None)
self.cmd = sfc_flow_classifier.SetSfcFlowClassifier(self.app,
self.namespace)
def test_set_flow_classifier(self):
client = self.app.client_manager.neutronclient
client = self.app.client_manager.network
mock_flow_classifier_update = client.update_sfc_flow_classifier
arglist = [
self._flow_classifier_name,
@ -206,11 +215,11 @@ class TestSetSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
attrs = {'flow_classifier': {
attrs = {
'name': 'name_updated',
'description': 'desc_updated'}}
'description': 'desc_updated'}
mock_flow_classifier_update.assert_called_once_with(
self._flow_classifier_name, attrs)
self._flow_classifier_name, **attrs)
self.assertIsNone(result)
@ -234,7 +243,7 @@ class TestShowSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
_fc['source_port_range_max'],
_fc['source_port_range_min']
)
_flow_classifier = {'flow_classifier': _fc}
_flow_classifier = _fc
_flow_classifier_id = _fc['id']
columns = ('Description',
'Destination IP',
@ -250,12 +259,12 @@ class TestShowSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
'Protocol',
'Source IP',
'Source Port Range Max',
'Source Port Range Min')
'Source Port Range Min',
'Summary',)
def setUp(self):
super(TestShowSfcFlowClassifier, self).setUp()
mock.patch(get_id, new=_get_id).start()
self.neutronclient.show_sfc_flow_classifier = mock.Mock(
self.network.get_sfc_flow_classifier = mock.Mock(
return_value=self._flow_classifier
)
# Get the command object to test
@ -263,8 +272,8 @@ class TestShowSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
self.namespace)
def test_show_flow_classifier(self):
client = self.app.client_manager.neutronclient
mock_flow_classifier_show = client.show_sfc_flow_classifier
client = self.app.client_manager.network
mock_flow_classifier_show = client.get_sfc_flow_classifier
arglist = [
self._flow_classifier_id,
]
@ -277,7 +286,6 @@ class TestShowSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
mock_flow_classifier_show.assert_called_once_with(
self._flow_classifier_id)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
class TestListSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
@ -324,9 +332,8 @@ class TestListSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestListSfcFlowClassifier, self).setUp()
mock.patch(get_id, new=_get_id).start()
self.neutronclient.list_sfc_flow_classifiers = mock.Mock(
return_value={'flow_classifiers': self._fc}
self.network.sfc_flow_classifiers = mock.Mock(
return_value=self._fc
)
# Get the command object to test
self.cmd = sfc_flow_classifier.ListSfcFlowClassifier(self.app,
@ -337,8 +344,7 @@ class TestListSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns = self.cmd.take_action(parsed_args)
fcs = self.neutronclient \
.list_sfc_flow_classifiers()['flow_classifiers']
fcs = self.network.sfc_flow_classifiers()
fc = fcs[0]
data = [
fc['id'],
@ -355,8 +361,7 @@ class TestListSfcFlowClassifier(fakes.TestNeutronClientOSCV2):
def test_list_with_long_option(self):
arglist = ['--long']
verifylist = [('long', True)]
fcs = self.neutronclient \
.list_sfc_flow_classifiers()['flow_classifiers']
fcs = self.network.sfc_flow_classifiers()
fc = fcs[0]
data = [
fc['id'],

View file

@ -16,6 +16,7 @@
from unittest import mock
from osc_lib import exceptions
import testtools
from neutronclient.osc.v2.sfc import sfc_port_chain
from neutronclient.tests.unit.osc.v2.sfc import fakes
@ -29,8 +30,7 @@ class TestCreateSfcPortChain(fakes.TestNeutronClientOSCV2):
# The new port_chain created
_port_chain = fakes.FakeSfcPortChain.create_port_chain()
columns = ('Chain ID',
'Chain Parameters',
columns = ('Chain Parameters',
'Description',
'Flow Classifiers',
'ID',
@ -40,7 +40,6 @@ class TestCreateSfcPortChain(fakes.TestNeutronClientOSCV2):
def get_data(self):
return (
self._port_chain['chain_id'],
self._port_chain['chain_parameters'],
self._port_chain['description'],
self._port_chain['flow_classifiers'],
@ -48,15 +47,12 @@ class TestCreateSfcPortChain(fakes.TestNeutronClientOSCV2):
self._port_chain['name'],
self._port_chain['port_pair_groups'],
self._port_chain['project_id'],
)
)
def setUp(self):
super(TestCreateSfcPortChain, self).setUp()
mock.patch(
'neutronclient.osc.v2.sfc.sfc_port_chain._get_id',
new=_get_id).start()
self.neutronclient.create_sfc_port_chain = mock.Mock(
return_value={'port_chain': self._port_chain})
self.network.create_sfc_port_chain = mock.Mock(
return_value=self._port_chain)
self.data = self.get_data()
# Get the command object to test
@ -77,11 +73,12 @@ class TestCreateSfcPortChain(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = (self.cmd.take_action(parsed_args))
self.neutronclient.create_sfc_port_chain.assert_called_once_with({
'port_chain': {
self.network.create_sfc_port_chain.assert_called_once_with(
**{
'name': self._port_chain['name'],
'port_pair_groups': [self._port_chain['port_pair_groups']]}
})
'port_pair_groups': [self._port_chain['port_pair_groups']]
}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
@ -107,15 +104,15 @@ class TestCreateSfcPortChain(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = (self.cmd.take_action(parsed_args))
self.neutronclient.create_sfc_port_chain.assert_called_once_with({
'port_chain': {
self.network.create_sfc_port_chain.assert_called_once_with(
**{
'name': self._port_chain['name'],
'port_pair_groups': [self._port_chain['port_pair_groups']],
'description': self._port_chain['description'],
'flow_classifiers': [self._port_chain['flow_classifiers']],
'chain_parameters': cp
}
})
}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
@ -126,20 +123,17 @@ class TestDeleteSfcPortChain(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestDeleteSfcPortChain, self).setUp()
mock.patch(
'neutronclient.osc.v2.sfc.sfc_port_chain._get_id',
new=_get_id).start()
self.neutronclient.delete_sfc_port_chain = mock.Mock(return_value=None)
self.network.delete_sfc_port_chain = mock.Mock(return_value=None)
self.cmd = sfc_port_chain.DeleteSfcPortChain(self.app, self.namespace)
def test_delete_port_chain(self):
client = self.app.client_manager.neutronclient
client = self.app.client_manager.network
mock_port_chain_delete = client.delete_sfc_port_chain
arglist = [
self._port_chain[0]['id'],
]
verifylist = [
('port_chain', self._port_chain[0]['id']),
('port_chain', [self._port_chain[0]['id']]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
@ -147,13 +141,29 @@ class TestDeleteSfcPortChain(fakes.TestNeutronClientOSCV2):
self._port_chain[0]['id'])
self.assertIsNone(result)
def test_delete_multiple_port_chains_with_exception(self):
client = self.app.client_manager.network
target1 = self._port_chain[0]['id']
arglist = [target1]
verifylist = [('port_chain', [target1])]
client.find_sfc_port_chain.side_effect = [
target1, exceptions.CommandError
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
msg = "1 of 2 port chain(s) failed to delete."
with testtools.ExpectedException(exceptions.CommandError) as e:
self.cmd.take_action(parsed_args)
self.assertEqual(msg, str(e))
class TestListSfcPortChain(fakes.TestNeutronClientOSCV2):
_port_chains = fakes.FakeSfcPortChain.create_port_chains(count=1)
columns = ('ID', 'Name', 'Port Pair Groups', 'Flow Classifiers',
'Chain Parameters', 'Chain ID')
'Chain Parameters')
columns_long = ('ID', 'Name', 'Port Pair Groups', 'Flow Classifiers',
'Chain Parameters', 'Description', 'Chain ID', 'Project')
'Chain Parameters', 'Description', 'Project')
_port_chain = _port_chains[0]
data = [
_port_chain['id'],
@ -161,13 +171,11 @@ class TestListSfcPortChain(fakes.TestNeutronClientOSCV2):
_port_chain['port_pair_groups'],
_port_chain['flow_classifiers'],
_port_chain['chain_parameters'],
_port_chain['chain_id']
]
data_long = [
_port_chain['id'],
_port_chain['name'],
_port_chain['project_id'],
_port_chain['chain_id'],
_port_chain['port_pair_groups'],
_port_chain['flow_classifiers'],
_port_chain['chain_parameters'],
@ -178,11 +186,8 @@ class TestListSfcPortChain(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestListSfcPortChain, self).setUp()
mock.patch(
'neutronclient.osc.v2.sfc.sfc_port_chain._get_id',
new=_get_id).start()
self.neutronclient.list_sfc_port_chains = mock.Mock(
return_value={'port_chains': self._port_chains}
self.network.sfc_port_chains = mock.Mock(
return_value=self._port_chains
)
# Get the command object to test
self.cmd = sfc_port_chain.ListSfcPortChain(self.app, self.namespace)
@ -192,7 +197,7 @@ class TestListSfcPortChain(fakes.TestNeutronClientOSCV2):
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns = self.cmd.take_action(parsed_args)[0]
pcs = self.neutronclient.list_sfc_port_chains()['port_chains']
pcs = self.network.sfc_port_chains()
pc = pcs[0]
data = [
pc['id'],
@ -200,7 +205,6 @@ class TestListSfcPortChain(fakes.TestNeutronClientOSCV2):
pc['port_pair_groups'],
pc['flow_classifiers'],
pc['chain_parameters'],
pc['chain_id']
]
self.assertEqual(list(self.columns), columns)
self.assertEqual(self.data, data)
@ -210,13 +214,12 @@ class TestListSfcPortChain(fakes.TestNeutronClientOSCV2):
verifylist = [('long', True)]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns = self.cmd.take_action(parsed_args)[0]
pcs = self.neutronclient.list_sfc_port_chains()['port_chains']
pcs = self.network.sfc_port_chains()
pc = pcs[0]
data = [
pc['id'],
pc['name'],
pc['project_id'],
pc['chain_id'],
pc['port_pair_groups'],
pc['flow_classifiers'],
pc['chain_parameters'],
@ -237,14 +240,11 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestSetSfcPortChain, self).setUp()
mock.patch(
'neutronclient.osc.v2.sfc.sfc_port_chain._get_id',
new=_get_id).start()
self.mocked = self.neutronclient.update_sfc_port_chain
self.mocked = self.network.update_sfc_port_chain
self.cmd = sfc_port_chain.SetSfcPortChain(self.app, self.namespace)
def test_set_port_chain(self):
client = self.app.client_manager.neutronclient
client = self.app.client_manager.network
mock_port_chain_update = client.update_sfc_port_chain
arglist = [
self._port_chain_name,
@ -258,10 +258,9 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
attrs = {'port_chain': {'name': 'name_updated',
'description': 'desc_updated'}}
attrs = {'name': 'name_updated', 'description': 'desc_updated'}
mock_port_chain_update.assert_called_once_with(self._port_chain_name,
attrs)
**attrs)
self.assertIsNone(result)
def test_set_flow_classifiers(self):
@ -269,23 +268,12 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
fc1 = 'flow_classifier1'
fc2 = 'flow_classifier2'
def _mock_flow_classifier(*args, **kwargs):
if self.neutronclient.find_resource.call_count == 1:
self.neutronclient.find_resource.assert_called_with(
self.res, target, cmd_resource='sfc_port_chain')
return {'flow_classifiers': [self.pc_fc]}
if self.neutronclient.find_resource.call_count == 2:
self.neutronclient.find_resource.assert_called_with(
'flow_classifier', fc1, cmd_resource='sfc_flow_classifier')
return {'id': args[1]}
if self.neutronclient.find_resource.call_count == 3:
self.neutronclient.find_resource.assert_called_with(
'flow_classifier', fc2, cmd_resource='sfc_flow_classifier')
return {'id': args[1]}
self.neutronclient.find_resource.side_effect = _mock_flow_classifier
self.network.find_sfc_port_chain = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id, 'flow_classifiers': [self.pc_fc]}
)
self.network.find_sfc_flow_classifier.side_effect = \
lambda name_or_id, ignore_missing=False: {'id': name_or_id}
arglist = [
target,
'--flow-classifier', fc1,
@ -298,12 +286,11 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
expect = {'flow_classifiers': [self.pc_fc, fc1, fc2]}
self.mocked.assert_called_once_with(target, {self.res: expect})
self.assertEqual(3, self.neutronclient.find_resource.call_count)
self.mocked.assert_called_once_with(target, **expect)
self.assertIsNone(result)
def test_set_no_flow_classifier(self):
client = self.app.client_manager.neutronclient
client = self.app.client_manager.network
mock_port_chain_update = client.update_sfc_port_chain
arglist = [
self._port_chain_name,
@ -315,9 +302,9 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
attrs = {'port_chain': {'flow_classifiers': []}}
attrs = {'flow_classifiers': []}
mock_port_chain_update.assert_called_once_with(self._port_chain_name,
attrs)
**attrs)
self.assertIsNone(result)
def test_set_port_pair_groups(self):
@ -326,25 +313,10 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
ppg1 = 'port_pair_group1'
ppg2 = 'port_pair_group2'
def _mock_flow_classifier(*args, **kwargs):
if self.neutronclient.find_resource.call_count == 1:
self.neutronclient.find_resource.assert_called_with(
self.res, target, cmd_resource='sfc_port_chain')
return {'port_pair_groups': [self.pc_ppg]}
if self.neutronclient.find_resource.call_count == 2:
self.neutronclient.find_resource.assert_called_with(
'port_pair_group', ppg1,
cmd_resource='sfc_port_pair_group')
return {'id': args[1]}
if self.neutronclient.find_resource.call_count == 3:
self.neutronclient.find_resource.assert_called_with(
'port_pair_group', ppg2,
cmd_resource='sfc_port_pair_group')
return {'id': args[1]}
self.neutronclient.find_resource.side_effect = _mock_flow_classifier
self.network.find_sfc_port_chain = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id, 'port_pair_groups': [self.pc_ppg]}
)
arglist = [
target,
'--port-pair-group', ppg1,
@ -357,22 +329,13 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
expect = {'port_pair_groups': [existing_ppg, ppg1, ppg2]}
self.mocked.assert_called_once_with(target, {self.res: expect})
self.assertEqual(3, self.neutronclient.find_resource.call_count)
self.mocked.assert_called_once_with(target, **expect)
self.assertIsNone(result)
def test_set_no_port_pair_group(self):
target = self.resource['id']
ppg1 = 'port_pair_group1'
def _mock_port_pair_group(*args, **kwargs):
if self.neutronclient.find_resource.call_count == 1:
self.neutronclient.find_resource.assert_called_with(
'port_pair_group', ppg1,
cmd_resource='sfc_port_pair_group')
return {'id': args[1]}
self.neutronclient.find_resource.side_effect = _mock_port_pair_group
arglist = [
target,
'--no-port-pair-group',
@ -386,8 +349,7 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
expect = {'port_pair_groups': [ppg1]}
self.mocked.assert_called_once_with(target, {self.res: expect})
self.assertEqual(1, self.neutronclient.find_resource.call_count)
self.mocked.assert_called_once_with(target, **expect)
self.assertIsNone(result)
def test_set_only_no_port_pair_group(self):
@ -395,7 +357,7 @@ class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2):
arglist = [
target,
'--no-port-pair-group',
]
]
verifylist = [
(self.res, target),
('no_port_pair_group', True),
@ -409,7 +371,6 @@ class TestShowSfcPortChain(fakes.TestNeutronClientOSCV2):
_pc = fakes.FakeSfcPortChain.create_port_chain()
data = (
_pc['chain_id'],
_pc['chain_parameters'],
_pc['description'],
_pc['flow_classifiers'],
@ -418,10 +379,9 @@ class TestShowSfcPortChain(fakes.TestNeutronClientOSCV2):
_pc['port_pair_groups'],
_pc['project_id']
)
_port_chain = {'port_chain': _pc}
_port_chain = _pc
_port_chain_id = _pc['id']
columns = ('Chain ID',
'Chain Parameters',
columns = ('Chain Parameters',
'Description',
'Flow Classifiers',
'ID',
@ -431,18 +391,15 @@ class TestShowSfcPortChain(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestShowSfcPortChain, self).setUp()
mock.patch(
'neutronclient.osc.v2.sfc.sfc_port_chain._get_id',
new=_get_id).start()
self.neutronclient.show_sfc_port_chain = mock.Mock(
self.network.get_sfc_port_chain = mock.Mock(
return_value=self._port_chain
)
# Get the command object to test
self.cmd = sfc_port_chain.ShowSfcPortChain(self.app, self.namespace)
def test_show_port_chain(self):
client = self.app.client_manager.neutronclient
mock_port_chain_show = client.show_sfc_port_chain
client = self.app.client_manager.network
mock_port_chain_show = client.get_sfc_port_chain
arglist = [
self._port_chain_id,
]
@ -468,34 +425,21 @@ class TestUnsetSfcPortChain(fakes.TestNeutronClientOSCV2):
def setUp(self):
super(TestUnsetSfcPortChain, self).setUp()
mock.patch(
'neutronclient.osc.v2.sfc.sfc_port_chain._get_id',
new=_get_id).start()
self.neutronclient.update_sfc_port_chain = mock.Mock(
self.network.update_sfc_port_chain = mock.Mock(
return_value=None)
self.mocked = self.neutronclient.update_sfc_port_chain
self.mocked = self.network.update_sfc_port_chain
self.cmd = sfc_port_chain.UnsetSfcPortChain(self.app, self.namespace)
def test_unset_port_pair_group(self):
target = self.resource['id']
ppg1 = 'port_pair_group1'
def _mock_port_pair_group(*args, **kwargs):
if self.neutronclient.find_resource.call_count == 1:
self.neutronclient.find_resource.assert_called_with(
self.res, target, cmd_resource='sfc_port_chain')
return {'port_pair_groups': [self.pc_ppg]}
if self.neutronclient.find_resource.call_count == 2:
self.neutronclient.find_resource.assert_called_with(
'port_pair_group', ppg1,
cmd_resource='sfc_port_pair_group')
return {'id': args[1]}
if self.neutronclient.find_resource.call_count == 3:
self.neutronclient.find_resource.assert_called_with(
self.res, target, cmd_resource='sfc_port_chain')
return {'id': args[1]}
self.neutronclient.find_resource.side_effect = _mock_port_pair_group
self.network.find_sfc_port_chain = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id, 'port_pair_groups': [self.pc_ppg]}
)
self.network.find_sfc_port_pair_group.side_effect = \
lambda name_or_id, ignore_missing=False: {'id': name_or_id}
arglist = [
target,
@ -508,24 +452,18 @@ class TestUnsetSfcPortChain(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
expect = {'port_pair_groups': [self.pc_ppg]}
self.mocked.assert_called_once_with(target, {self.res: expect})
self.mocked.assert_called_once_with(target, **expect)
self.assertIsNone(result)
def test_unset_flow_classifier(self):
target = self.resource['id']
fc1 = 'flow_classifier1'
def _mock_flow_classifier(*args, **kwargs):
if self.neutronclient.find_resource.call_count == 1:
self.neutronclient.find_resource.assert_called_with(
self.res, target, cmd_resource='sfc_port_chain')
return {'flow_classifiers': [self.pc_fc]}
if self.neutronclient.find_resource.call_count == 2:
self.neutronclient.find_resource.assert_called_with(
'flow_classifier', fc1, cmd_resource='sfc_flow_classifier')
return {'id': args[1]}
self.neutronclient.find_resource.side_effect = _mock_flow_classifier
self.network.find_sfc_port_chain = mock.Mock(
side_effect=lambda name_or_id, ignore_missing=False:
{'id': name_or_id, 'flow_classifiers': [self.pc_fc]}
)
self.network.find_sfc_flow_classifier.side_effect = \
lambda name_or_id, ignore_missing=False: {'id': name_or_id}
arglist = [
target,
@ -538,11 +476,11 @@ class TestUnsetSfcPortChain(fakes.TestNeutronClientOSCV2):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
expect = {'flow_classifiers': [self.pc_fc]}
self.mocked.assert_called_once_with(target, {self.res: expect})
self.mocked.assert_called_once_with(target, **expect)
self.assertIsNone(result)
def test_unset_all_flow_classifier(self):
client = self.app.client_manager.neutronclient
client = self.app.client_manager.network
target = self.resource['id']
mock_port_chain_update = client.update_sfc_port_chain
arglist = [
@ -557,5 +495,5 @@ class TestUnsetSfcPortChain(fakes.TestNeutronClientOSCV2):
result = self.cmd.take_action(parsed_args)
expect = {'flow_classifiers': []}
mock_port_chain_update.assert_called_once_with(target,
{self.res: expect})
**expect)
self.assertIsNone(result)

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