Network tag support
Neutron tag mechanism now supports network, subnet, port, subnetpool and router. Tag support for more resources is planned. This commit introduces a common mixin class to implement tag operation and individual resource consumes it. To support tag remove, network unset command is added. Implements blueprint neutron-client-tag Change-Id: Iad59d052f46896d27d73c22d6d4bb3df889f2352
This commit is contained in:
parent
e889ba1524
commit
57e5840710
@ -32,6 +32,7 @@ Create new network
|
|||||||
[--provider-segment <provider-segment>]
|
[--provider-segment <provider-segment>]
|
||||||
[--qos-policy <qos-policy>]
|
[--qos-policy <qos-policy>]
|
||||||
[--transparent-vlan | --no-transparent-vlan]
|
[--transparent-vlan | --no-transparent-vlan]
|
||||||
|
[--tag <tag> | --no-tag]
|
||||||
<name>
|
<name>
|
||||||
|
|
||||||
.. option:: --project <project>
|
.. option:: --project <project>
|
||||||
@ -165,6 +166,18 @@ Create new network
|
|||||||
|
|
||||||
*Network version 2 only*
|
*Network version 2 only*
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the network (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
*Network version 2 only*
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
No tags associated with the network
|
||||||
|
|
||||||
|
*Network version 2 only*
|
||||||
|
|
||||||
.. _network_create-name:
|
.. _network_create-name:
|
||||||
.. describe:: <name>
|
.. describe:: <name>
|
||||||
|
|
||||||
@ -206,6 +219,8 @@ List networks
|
|||||||
[--provider-physical-network <provider-physical-network>]
|
[--provider-physical-network <provider-physical-network>]
|
||||||
[--provider-segment <provider-segment>]
|
[--provider-segment <provider-segment>]
|
||||||
[--agent <agent-id>]
|
[--agent <agent-id>]
|
||||||
|
[--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]]
|
||||||
|
[--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]]
|
||||||
|
|
||||||
.. option:: --external
|
.. option:: --external
|
||||||
|
|
||||||
@ -297,6 +312,32 @@ List networks
|
|||||||
|
|
||||||
List networks hosted by agent (ID only)
|
List networks hosted by agent (ID only)
|
||||||
|
|
||||||
|
*Network version 2 only*
|
||||||
|
|
||||||
|
.. option:: --tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List networks which have all given tag(s)
|
||||||
|
|
||||||
|
*Network version 2 only*
|
||||||
|
|
||||||
|
.. option:: --any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List networks which have any given tag(s)
|
||||||
|
|
||||||
|
*Network version 2 only*
|
||||||
|
|
||||||
|
.. option:: --not-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude networks which have all given tag(s)
|
||||||
|
|
||||||
|
*Network version 2 only*
|
||||||
|
|
||||||
|
.. option:: --not-any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude networks which have any given tag(s)
|
||||||
|
|
||||||
|
*Network version 2 only*
|
||||||
|
|
||||||
network set
|
network set
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
@ -318,6 +359,7 @@ Set network properties
|
|||||||
[--provider-physical-network <provider-physical-network>]
|
[--provider-physical-network <provider-physical-network>]
|
||||||
[--provider-segment <provider-segment>]
|
[--provider-segment <provider-segment>]
|
||||||
[--qos-policy <qos-policy> | --no-qos-policy]
|
[--qos-policy <qos-policy> | --no-qos-policy]
|
||||||
|
[--tag <tag>] [--no-tag]
|
||||||
<network>
|
<network>
|
||||||
|
|
||||||
.. option:: --name <name>
|
.. option:: --name <name>
|
||||||
@ -392,6 +434,15 @@ Set network properties
|
|||||||
|
|
||||||
Remove the QoS policy attached to this network
|
Remove the QoS policy attached to this network
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the network (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
Clear tags associated with the network. Specify both --tag
|
||||||
|
and --no-tag to overwrite current tags
|
||||||
|
|
||||||
.. _network_set-network:
|
.. _network_set-network:
|
||||||
.. describe:: <network>
|
.. describe:: <network>
|
||||||
|
|
||||||
@ -412,3 +463,31 @@ Display network details
|
|||||||
.. describe:: <network>
|
.. describe:: <network>
|
||||||
|
|
||||||
Network to display (name or ID)
|
Network to display (name or ID)
|
||||||
|
|
||||||
|
network unset
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Unset network properties
|
||||||
|
|
||||||
|
*Network version 2 only*
|
||||||
|
|
||||||
|
.. program:: network unset
|
||||||
|
.. code:: bash
|
||||||
|
|
||||||
|
openstack network unset
|
||||||
|
[--tag <tag> | --all-tag]
|
||||||
|
<network>
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be removed from the network
|
||||||
|
(repeat option to remove multiple tags)
|
||||||
|
|
||||||
|
.. option:: --all-tag
|
||||||
|
|
||||||
|
Clear all tags associated with the network
|
||||||
|
|
||||||
|
.. _network_unset-network:
|
||||||
|
.. describe:: <network>
|
||||||
|
|
||||||
|
Network to modify (name or ID)
|
||||||
|
@ -33,6 +33,7 @@ Create new port
|
|||||||
[--qos-policy <qos-policy>]
|
[--qos-policy <qos-policy>]
|
||||||
[--project <project> [--project-domain <project-domain>]]
|
[--project <project> [--project-domain <project-domain>]]
|
||||||
[--enable-port-security | --disable-port-security]
|
[--enable-port-security | --disable-port-security]
|
||||||
|
[--tag <tag> | --no-tag]
|
||||||
<name>
|
<name>
|
||||||
|
|
||||||
.. option:: --network <network>
|
.. option:: --network <network>
|
||||||
@ -126,6 +127,14 @@ Create new port
|
|||||||
|
|
||||||
Disable port security for this port
|
Disable port security for this port
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the port (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
No tags associated with the port
|
||||||
|
|
||||||
.. _port_create-name:
|
.. _port_create-name:
|
||||||
.. describe:: <name>
|
.. describe:: <name>
|
||||||
|
|
||||||
@ -163,6 +172,8 @@ List ports
|
|||||||
[--fixed-ip subnet=<subnet>,ip-address=<ip-address>]
|
[--fixed-ip subnet=<subnet>,ip-address=<ip-address>]
|
||||||
[--long]
|
[--long]
|
||||||
[--project <project> [--project-domain <project-domain>]]
|
[--project <project> [--project-domain <project-domain>]]
|
||||||
|
[--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]]
|
||||||
|
[--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]]
|
||||||
|
|
||||||
.. option:: --device-owner <device-owner>
|
.. option:: --device-owner <device-owner>
|
||||||
|
|
||||||
@ -204,6 +215,22 @@ List ports
|
|||||||
Domain the project belongs to (name or ID).
|
Domain the project belongs to (name or ID).
|
||||||
This can be used in case collisions between project names exist.
|
This can be used in case collisions between project names exist.
|
||||||
|
|
||||||
|
.. option:: --tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List ports which have all given tag(s)
|
||||||
|
|
||||||
|
.. option:: --any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List ports which have any given tag(s)
|
||||||
|
|
||||||
|
.. option:: --not-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude ports which have all given tag(s)
|
||||||
|
|
||||||
|
.. option:: --not-any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude ports which have any given tag(s)
|
||||||
|
|
||||||
port set
|
port set
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -233,6 +260,7 @@ Set port properties
|
|||||||
[--allowed-address ip-address=<ip-address>[,mac-address=<mac-address>]]
|
[--allowed-address ip-address=<ip-address>[,mac-address=<mac-address>]]
|
||||||
[--no-allowed-address]
|
[--no-allowed-address]
|
||||||
[--data-plane-status <status>]
|
[--data-plane-status <status>]
|
||||||
|
[--tag <tag>] [--no-tag]
|
||||||
<port>
|
<port>
|
||||||
|
|
||||||
.. option:: --description <description>
|
.. option:: --description <description>
|
||||||
@ -342,6 +370,15 @@ Set port properties
|
|||||||
Unset it to None with the 'port unset' command
|
Unset it to None with the 'port unset' command
|
||||||
(requires data plane status extension)
|
(requires data plane status extension)
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the port (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
Clear tags associated with the port. Specify both --tag
|
||||||
|
and --no-tag to overwrite current tags
|
||||||
|
|
||||||
.. _port_set-port:
|
.. _port_set-port:
|
||||||
.. describe:: <port>
|
.. describe:: <port>
|
||||||
|
|
||||||
@ -378,6 +415,7 @@ Unset port properties
|
|||||||
[--allowed-address ip-address=<ip-address>[,mac-address=<mac-address>] [...]]
|
[--allowed-address ip-address=<ip-address>[,mac-address=<mac-address>] [...]]
|
||||||
[--qos-policy]
|
[--qos-policy]
|
||||||
[--data-plane-status]
|
[--data-plane-status]
|
||||||
|
[--tag <tag> | --all-tag]
|
||||||
<port>
|
<port>
|
||||||
|
|
||||||
.. option:: --fixed-ip subnet=<subnet>,ip-address=<ip-address>
|
.. option:: --fixed-ip subnet=<subnet>,ip-address=<ip-address>
|
||||||
@ -410,6 +448,15 @@ Unset port properties
|
|||||||
|
|
||||||
Clear existing information of data plane status
|
Clear existing information of data plane status
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be removed from the port
|
||||||
|
(repeat option to remove multiple tags)
|
||||||
|
|
||||||
|
.. option:: --all-tag
|
||||||
|
|
||||||
|
Clear all tags associated with the port
|
||||||
|
|
||||||
.. _port_unset-port:
|
.. _port_unset-port:
|
||||||
.. describe:: <port>
|
.. describe:: <port>
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ Create new router
|
|||||||
[--ha | --no-ha]
|
[--ha | --no-ha]
|
||||||
[--description <description>]
|
[--description <description>]
|
||||||
[--availability-zone-hint <availability-zone>]
|
[--availability-zone-hint <availability-zone>]
|
||||||
|
[--tag <tag> | --no-tag]
|
||||||
<name>
|
<name>
|
||||||
|
|
||||||
.. option:: --project <project>
|
.. option:: --project <project>
|
||||||
@ -121,6 +122,14 @@ Create new router
|
|||||||
(Router Availability Zone extension required,
|
(Router Availability Zone extension required,
|
||||||
repeat option to set multiple availability zones)
|
repeat option to set multiple availability zones)
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the router (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
No tags associated with the router
|
||||||
|
|
||||||
.. _router_create-name:
|
.. _router_create-name:
|
||||||
.. describe:: <name>
|
.. describe:: <name>
|
||||||
|
|
||||||
@ -156,6 +165,8 @@ List routers
|
|||||||
[--long]
|
[--long]
|
||||||
[--project <project> [--project-domain <project-domain>]]
|
[--project <project> [--project-domain <project-domain>]]
|
||||||
[--agent <agent-id>]
|
[--agent <agent-id>]
|
||||||
|
[--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]]
|
||||||
|
[--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]]
|
||||||
|
|
||||||
.. option:: --agent <agent-id>
|
.. option:: --agent <agent-id>
|
||||||
|
|
||||||
@ -186,6 +197,22 @@ List routers
|
|||||||
Domain the project belongs to (name or ID).
|
Domain the project belongs to (name or ID).
|
||||||
This can be used in case collisions between project names exist.
|
This can be used in case collisions between project names exist.
|
||||||
|
|
||||||
|
.. option:: --tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List routers which have all given tag(s)
|
||||||
|
|
||||||
|
.. option:: --any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List routers which have any given tag(s)
|
||||||
|
|
||||||
|
.. option:: --not-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude routers which have all given tag(s)
|
||||||
|
|
||||||
|
.. option:: --not-any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude routers which have any given tag(s)
|
||||||
|
|
||||||
router remove port
|
router remove port
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
@ -246,6 +273,7 @@ Set router properties
|
|||||||
[--route destination=<subnet>,gateway=<ip-address> | --no-route]
|
[--route destination=<subnet>,gateway=<ip-address> | --no-route]
|
||||||
[--ha | --no-ha]
|
[--ha | --no-ha]
|
||||||
[--external-gateway <network> [--enable-snat|--disable-snat] [--fixed-ip subnet=<subnet>,ip-address=<ip-address>]]
|
[--external-gateway <network> [--enable-snat|--disable-snat] [--fixed-ip subnet=<subnet>,ip-address=<ip-address>]]
|
||||||
|
[--tag <tag>] [--no-tag]
|
||||||
<router>
|
<router>
|
||||||
|
|
||||||
.. option:: --name <name>
|
.. option:: --name <name>
|
||||||
@ -311,6 +339,15 @@ Set router properties
|
|||||||
subnet=<subnet>,ip-address=<ip-address>
|
subnet=<subnet>,ip-address=<ip-address>
|
||||||
(repeat option to set multiple fixed IP addresses)
|
(repeat option to set multiple fixed IP addresses)
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the router (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
Clear tags associated with the router. Specify both --tag
|
||||||
|
and --no-tag to overwrite current tags
|
||||||
|
|
||||||
.. _router_set-router:
|
.. _router_set-router:
|
||||||
.. describe:: <router>
|
.. describe:: <router>
|
||||||
|
|
||||||
@ -343,6 +380,7 @@ Unset router properties
|
|||||||
openstack router unset
|
openstack router unset
|
||||||
[--route destination=<subnet>,gateway=<ip-address>]
|
[--route destination=<subnet>,gateway=<ip-address>]
|
||||||
[--external-gateway]
|
[--external-gateway]
|
||||||
|
[--tag <tag> | --all-tag]
|
||||||
<router>
|
<router>
|
||||||
|
|
||||||
.. option:: --route destination=<subnet>,gateway=<ip-address>
|
.. option:: --route destination=<subnet>,gateway=<ip-address>
|
||||||
@ -356,6 +394,15 @@ Unset router properties
|
|||||||
|
|
||||||
Remove external gateway information from the router
|
Remove external gateway information from the router
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be removed from the router
|
||||||
|
(repeat option to remove multiple tags)
|
||||||
|
|
||||||
|
.. option:: --all-tag
|
||||||
|
|
||||||
|
Clear all tags associated with the router
|
||||||
|
|
||||||
.. _router_unset-router:
|
.. _router_unset-router:
|
||||||
.. describe:: <router>
|
.. describe:: <router>
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ Create subnet pool
|
|||||||
[--default | --no-default]
|
[--default | --no-default]
|
||||||
[--share | --no-share]
|
[--share | --no-share]
|
||||||
[--default-quota <num-ip-addresses>]
|
[--default-quota <num-ip-addresses>]
|
||||||
|
[--tag <tag> | --no-tag]
|
||||||
--pool-prefix <pool-prefix> [...]
|
--pool-prefix <pool-prefix> [...]
|
||||||
<name>
|
<name>
|
||||||
|
|
||||||
@ -79,6 +80,14 @@ Create subnet pool
|
|||||||
Set default quota for subnet pool as the number of
|
Set default quota for subnet pool as the number of
|
||||||
IP addresses allowed in a subnet
|
IP addresses allowed in a subnet
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the subnet pool (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
No tags associated with the subnet pool
|
||||||
|
|
||||||
.. option:: --pool-prefix <pool-prefix>
|
.. option:: --pool-prefix <pool-prefix>
|
||||||
|
|
||||||
Set subnet pool prefixes (in CIDR notation)
|
Set subnet pool prefixes (in CIDR notation)
|
||||||
@ -120,6 +129,8 @@ List subnet pools
|
|||||||
[--project <project> [--project-domain <project-domain>]]
|
[--project <project> [--project-domain <project-domain>]]
|
||||||
[--name <name>]
|
[--name <name>]
|
||||||
[--address-scope <address-scope>]
|
[--address-scope <address-scope>]
|
||||||
|
[--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]]
|
||||||
|
[--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]]
|
||||||
|
|
||||||
.. option:: --long
|
.. option:: --long
|
||||||
|
|
||||||
@ -158,6 +169,22 @@ List subnet pools
|
|||||||
|
|
||||||
List only subnet pools of given address scope in output (name or ID)
|
List only subnet pools of given address scope in output (name or ID)
|
||||||
|
|
||||||
|
.. option:: --tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List subnet pools which have all given tag(s)
|
||||||
|
|
||||||
|
.. option:: --any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List subnet pools which have any given tag(s)
|
||||||
|
|
||||||
|
.. option:: --not-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude subnet pools which have all given tag(s)
|
||||||
|
|
||||||
|
.. option:: --not-any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude subnet pools which have any given tag(s)
|
||||||
|
|
||||||
subnet pool set
|
subnet pool set
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
@ -176,6 +203,7 @@ Set subnet pool properties
|
|||||||
[--default | --no-default]
|
[--default | --no-default]
|
||||||
[--description <description>]
|
[--description <description>]
|
||||||
[--default-quota <num-ip-addresses>]
|
[--default-quota <num-ip-addresses>]
|
||||||
|
[--tag <tag>] [--no-tag]
|
||||||
<subnet-pool>
|
<subnet-pool>
|
||||||
|
|
||||||
.. option:: --name <name>
|
.. option:: --name <name>
|
||||||
@ -225,6 +253,15 @@ Set subnet pool properties
|
|||||||
Set default quota for subnet pool as the number of
|
Set default quota for subnet pool as the number of
|
||||||
IP addresses allowed in a subnet
|
IP addresses allowed in a subnet
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the subnet pool (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
Clear tags associated with the subnet pool. Specify both --tag
|
||||||
|
and --no-tag to overwrite current tags
|
||||||
|
|
||||||
.. _subnet_pool_set-subnet-pool:
|
.. _subnet_pool_set-subnet-pool:
|
||||||
.. describe:: <subnet-pool>
|
.. describe:: <subnet-pool>
|
||||||
|
|
||||||
@ -256,6 +293,7 @@ Unset subnet pool properties
|
|||||||
|
|
||||||
openstack subnet pool unset
|
openstack subnet pool unset
|
||||||
[--pool-prefix <pool-prefix> [...]]
|
[--pool-prefix <pool-prefix> [...]]
|
||||||
|
[--tag <tag> | --all-tag]
|
||||||
<subnet-pool>
|
<subnet-pool>
|
||||||
|
|
||||||
.. option:: --pool-prefix <pool-prefix>
|
.. option:: --pool-prefix <pool-prefix>
|
||||||
@ -263,6 +301,15 @@ Unset subnet pool properties
|
|||||||
Remove subnet pool prefixes (in CIDR notation).
|
Remove subnet pool prefixes (in CIDR notation).
|
||||||
(repeat option to unset multiple prefixes).
|
(repeat option to unset multiple prefixes).
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be removed from the subnet pool
|
||||||
|
(repeat option to remove multiple tags)
|
||||||
|
|
||||||
|
.. option:: --all-tag
|
||||||
|
|
||||||
|
Clear all tags associated with the subnet pool
|
||||||
|
|
||||||
.. _subnet_pool_unset-subnet-pool:
|
.. _subnet_pool_unset-subnet-pool:
|
||||||
.. describe:: <subnet-pool>
|
.. describe:: <subnet-pool>
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ Create new subnet
|
|||||||
[--ipv6-address-mode {dhcpv6-stateful,dhcpv6-stateless,slaac}]
|
[--ipv6-address-mode {dhcpv6-stateful,dhcpv6-stateless,slaac}]
|
||||||
[--network-segment <network-segment>]
|
[--network-segment <network-segment>]
|
||||||
[--service-type <service-type>]
|
[--service-type <service-type>]
|
||||||
|
[--tag <tag> | --no-tag]
|
||||||
--network <network>
|
--network <network>
|
||||||
<name>
|
<name>
|
||||||
|
|
||||||
@ -125,6 +126,14 @@ Create new subnet
|
|||||||
Must be a valid device owner value for a network port
|
Must be a valid device owner value for a network port
|
||||||
(repeat option to set multiple service types)
|
(repeat option to set multiple service types)
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the subnet (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
No tags associated with the subnet
|
||||||
|
|
||||||
.. option:: --network <network>
|
.. option:: --network <network>
|
||||||
|
|
||||||
Network this subnet belongs to (name or ID)
|
Network this subnet belongs to (name or ID)
|
||||||
@ -167,6 +176,8 @@ List subnets
|
|||||||
[--gateway <gateway>]
|
[--gateway <gateway>]
|
||||||
[--name <name>]
|
[--name <name>]
|
||||||
[--subnet-range <subnet-range>]
|
[--subnet-range <subnet-range>]
|
||||||
|
[--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]]
|
||||||
|
[--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]]
|
||||||
|
|
||||||
.. option:: --long
|
.. option:: --long
|
||||||
|
|
||||||
@ -218,6 +229,22 @@ List subnets
|
|||||||
List only subnets of given subnet range (in CIDR notation) in output
|
List only subnets of given subnet range (in CIDR notation) in output
|
||||||
e.g.: ``--subnet-range 10.10.0.0/16``
|
e.g.: ``--subnet-range 10.10.0.0/16``
|
||||||
|
|
||||||
|
.. option:: --tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List subnets which have all given tag(s)
|
||||||
|
|
||||||
|
.. option:: --any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
List subnets which have any given tag(s)
|
||||||
|
|
||||||
|
.. option:: --not-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude subnets which have all given tag(s)
|
||||||
|
|
||||||
|
.. option:: --not-any-tags <tag>[,<tag>,...]
|
||||||
|
|
||||||
|
Exclude subnets which have any given tag(s)
|
||||||
|
|
||||||
subnet set
|
subnet set
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -238,6 +265,7 @@ Set subnet properties
|
|||||||
[--service-type <service-type>]
|
[--service-type <service-type>]
|
||||||
[--name <new-name>]
|
[--name <new-name>]
|
||||||
[--description <description>]
|
[--description <description>]
|
||||||
|
[--tag <tag>] [--no-tag]
|
||||||
<subnet>
|
<subnet>
|
||||||
|
|
||||||
.. option:: --allocation-pool start=<ip-address>,end=<ip-address>
|
.. option:: --allocation-pool start=<ip-address>,end=<ip-address>
|
||||||
@ -305,6 +333,15 @@ Set subnet properties
|
|||||||
|
|
||||||
Updated name of the subnet
|
Updated name of the subnet
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be added to the subnet (repeat option to set multiple tags)
|
||||||
|
|
||||||
|
.. option:: --no-tag
|
||||||
|
|
||||||
|
Clear tags associated with the subnet. Specify both --tag
|
||||||
|
and --no-tag to overwrite current tags
|
||||||
|
|
||||||
.. _subnet_set-subnet:
|
.. _subnet_set-subnet:
|
||||||
.. describe:: <subnet>
|
.. describe:: <subnet>
|
||||||
|
|
||||||
@ -340,6 +377,7 @@ Unset subnet properties
|
|||||||
[--dns-nameserver <dns-nameserver> [...]]
|
[--dns-nameserver <dns-nameserver> [...]]
|
||||||
[--host-route destination=<subnet>,gateway=<ip-address> [...]]
|
[--host-route destination=<subnet>,gateway=<ip-address> [...]]
|
||||||
[--service-type <service-type>]
|
[--service-type <service-type>]
|
||||||
|
[--tag <tag> | --all-tag]
|
||||||
<subnet>
|
<subnet>
|
||||||
|
|
||||||
.. option:: --dns-nameserver <dns-nameserver>
|
.. option:: --dns-nameserver <dns-nameserver>
|
||||||
@ -368,6 +406,15 @@ Unset subnet properties
|
|||||||
Must be a valid device owner value for a network port
|
Must be a valid device owner value for a network port
|
||||||
(repeat option to unset multiple service types)
|
(repeat option to unset multiple service types)
|
||||||
|
|
||||||
|
.. option:: --tag <tag>
|
||||||
|
|
||||||
|
Tag to be removed from the subnet
|
||||||
|
(repeat option to remove multiple tags)
|
||||||
|
|
||||||
|
.. option:: --all-tag
|
||||||
|
|
||||||
|
Clear all tags associated with the subnet
|
||||||
|
|
||||||
.. _subnet_unset-subnet:
|
.. _subnet_unset-subnet:
|
||||||
.. describe:: <subnet>
|
.. describe:: <subnet>
|
||||||
|
|
||||||
|
134
openstackclient/network/v2/_tag.py
Normal file
134
openstackclient/network/v2/_tag.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
# 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 argparse
|
||||||
|
|
||||||
|
from openstackclient.i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
class _CommaListAction(argparse.Action):
|
||||||
|
|
||||||
|
def __call__(self, parser, namespace, values, option_string=None):
|
||||||
|
setattr(namespace, self.dest, values.split(','))
|
||||||
|
|
||||||
|
|
||||||
|
def add_tag_filtering_option_to_parser(parser, collection_name):
|
||||||
|
parser.add_argument(
|
||||||
|
'--tags',
|
||||||
|
metavar='<tag>[,<tag>,...]',
|
||||||
|
action=_CommaListAction,
|
||||||
|
help=_('List %s which have all given tag(s) '
|
||||||
|
'(Comma-separated list of tags)') % collection_name
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--any-tags',
|
||||||
|
metavar='<tag>[,<tag>,...]',
|
||||||
|
action=_CommaListAction,
|
||||||
|
help=_('List %s which have any given tag(s) '
|
||||||
|
'(Comma-separated list of tags)') % collection_name
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--not-tags',
|
||||||
|
metavar='<tag>[,<tag>,...]',
|
||||||
|
action=_CommaListAction,
|
||||||
|
help=_('Exclude %s which have all given tag(s) '
|
||||||
|
'(Comma-separated list of tags)') % collection_name
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--not-any-tags',
|
||||||
|
metavar='<tag>[,<tag>,...]',
|
||||||
|
action=_CommaListAction,
|
||||||
|
help=_('Exclude %s which have any given tag(s) '
|
||||||
|
'(Comma-separated list of tags)') % collection_name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_tag_filtering_args(parsed_args, args):
|
||||||
|
if parsed_args.tags:
|
||||||
|
args['tags'] = ','.join(parsed_args.tags)
|
||||||
|
if parsed_args.any_tags:
|
||||||
|
args['any_tags'] = ','.join(parsed_args.any_tags)
|
||||||
|
if parsed_args.not_tags:
|
||||||
|
args['not_tags'] = ','.join(parsed_args.not_tags)
|
||||||
|
if parsed_args.not_any_tags:
|
||||||
|
args['not_any_tags'] = ','.join(parsed_args.not_any_tags)
|
||||||
|
|
||||||
|
|
||||||
|
def add_tag_option_to_parser_for_create(parser, resource_name):
|
||||||
|
tag_group = parser.add_mutually_exclusive_group()
|
||||||
|
tag_group.add_argument(
|
||||||
|
'--tag',
|
||||||
|
action='append',
|
||||||
|
dest='tags',
|
||||||
|
metavar='<tag>',
|
||||||
|
help=_("Tag to be added to the %s "
|
||||||
|
"(repeat option to set multiple tags)") % resource_name
|
||||||
|
)
|
||||||
|
tag_group.add_argument(
|
||||||
|
'--no-tag',
|
||||||
|
action='store_true',
|
||||||
|
help=_("No tags associated with the %s") % resource_name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def add_tag_option_to_parser_for_set(parser, resource_name):
|
||||||
|
parser.add_argument(
|
||||||
|
'--tag',
|
||||||
|
action='append',
|
||||||
|
dest='tags',
|
||||||
|
metavar='<tag>',
|
||||||
|
help=_("Tag to be added to the %s "
|
||||||
|
"(repeat option to set multiple tags)") % resource_name
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--no-tag',
|
||||||
|
action='store_true',
|
||||||
|
help=_("Clear tags associated with the %s. Specify both "
|
||||||
|
"--tag and --no-tag to overwrite current tags") % resource_name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def update_tags_for_set(client, obj, parsed_args):
|
||||||
|
if parsed_args.no_tag:
|
||||||
|
tags = set()
|
||||||
|
else:
|
||||||
|
tags = set(obj.tags)
|
||||||
|
if parsed_args.tags:
|
||||||
|
tags |= set(parsed_args.tags)
|
||||||
|
if set(obj.tags) != tags:
|
||||||
|
client.set_tags(obj, list(tags))
|
||||||
|
|
||||||
|
|
||||||
|
def add_tag_option_to_parser_for_unset(parser, resource_name):
|
||||||
|
tag_group = parser.add_mutually_exclusive_group()
|
||||||
|
tag_group.add_argument(
|
||||||
|
'--tag',
|
||||||
|
action='append',
|
||||||
|
dest='tags',
|
||||||
|
metavar='<tag>',
|
||||||
|
help=_("Tag to be removed from the %s "
|
||||||
|
"(repeat option to remove multiple tags)") % resource_name)
|
||||||
|
tag_group.add_argument(
|
||||||
|
'--all-tag',
|
||||||
|
action='store_true',
|
||||||
|
help=_("Clear all tags associated with the %s") % resource_name)
|
||||||
|
|
||||||
|
|
||||||
|
def update_tags_for_unset(client, obj, parsed_args):
|
||||||
|
tags = set(obj.tags)
|
||||||
|
if parsed_args.all_tag:
|
||||||
|
tags = set()
|
||||||
|
if parsed_args.tags:
|
||||||
|
tags -= set(parsed_args.tags)
|
||||||
|
if set(obj.tags) != tags:
|
||||||
|
client.set_tags(obj, list(tags))
|
@ -20,6 +20,7 @@ from openstackclient.i18n import _
|
|||||||
from openstackclient.identity import common as identity_common
|
from openstackclient.identity import common as identity_common
|
||||||
from openstackclient.network import common
|
from openstackclient.network import common
|
||||||
from openstackclient.network import sdk_utils
|
from openstackclient.network import sdk_utils
|
||||||
|
from openstackclient.network.v2 import _tag
|
||||||
|
|
||||||
|
|
||||||
def _format_admin_state(item):
|
def _format_admin_state(item):
|
||||||
@ -280,6 +281,7 @@ class CreateNetwork(common.NetworkAndComputeShowOne):
|
|||||||
help=_("Do not make the network VLAN transparent"))
|
help=_("Do not make the network VLAN transparent"))
|
||||||
|
|
||||||
_add_additional_network_options(parser)
|
_add_additional_network_options(parser)
|
||||||
|
_tag.add_tag_option_to_parser_for_create(parser, _('network'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def update_parser_compute(self, parser):
|
def update_parser_compute(self, parser):
|
||||||
@ -299,6 +301,8 @@ class CreateNetwork(common.NetworkAndComputeShowOne):
|
|||||||
attrs['vlan_transparent'] = False
|
attrs['vlan_transparent'] = False
|
||||||
|
|
||||||
obj = client.create_network(**attrs)
|
obj = client.create_network(**attrs)
|
||||||
|
# tags cannot be set when created, so tags need to be set later.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
display_columns, columns = _get_columns_network(obj)
|
display_columns, columns = _get_columns_network(obj)
|
||||||
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
||||||
return (display_columns, data)
|
return (display_columns, data)
|
||||||
@ -424,7 +428,9 @@ class ListNetwork(common.NetworkAndComputeLister):
|
|||||||
'--agent',
|
'--agent',
|
||||||
metavar='<agent-id>',
|
metavar='<agent-id>',
|
||||||
dest='agent_id',
|
dest='agent_id',
|
||||||
help=_('List networks hosted by agent (ID only)'))
|
help=_('List networks hosted by agent (ID only)')
|
||||||
|
)
|
||||||
|
_tag.add_tag_filtering_option_to_parser(parser, _('networks'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action_network(self, client, parsed_args):
|
def take_action_network(self, client, parsed_args):
|
||||||
@ -441,6 +447,7 @@ class ListNetwork(common.NetworkAndComputeLister):
|
|||||||
'provider_network_type',
|
'provider_network_type',
|
||||||
'is_router_external',
|
'is_router_external',
|
||||||
'availability_zones',
|
'availability_zones',
|
||||||
|
'tags',
|
||||||
)
|
)
|
||||||
column_headers = (
|
column_headers = (
|
||||||
'ID',
|
'ID',
|
||||||
@ -453,6 +460,7 @@ class ListNetwork(common.NetworkAndComputeLister):
|
|||||||
'Network Type',
|
'Network Type',
|
||||||
'Router Type',
|
'Router Type',
|
||||||
'Availability Zones',
|
'Availability Zones',
|
||||||
|
'Tags',
|
||||||
)
|
)
|
||||||
elif parsed_args.agent_id:
|
elif parsed_args.agent_id:
|
||||||
columns = (
|
columns = (
|
||||||
@ -534,6 +542,8 @@ class ListNetwork(common.NetworkAndComputeLister):
|
|||||||
args['provider:segmentation_id'] = parsed_args.segmentation_id
|
args['provider:segmentation_id'] = parsed_args.segmentation_id
|
||||||
args['provider_segmentation_id'] = parsed_args.segmentation_id
|
args['provider_segmentation_id'] = parsed_args.segmentation_id
|
||||||
|
|
||||||
|
_tag.get_tag_filtering_args(parsed_args, args)
|
||||||
|
|
||||||
data = client.networks(**args)
|
data = client.networks(**args)
|
||||||
|
|
||||||
return (column_headers,
|
return (column_headers,
|
||||||
@ -656,6 +666,7 @@ class SetNetwork(command.Command):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
help=_("Remove the QoS policy attached to this network")
|
help=_("Remove the QoS policy attached to this network")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_set(parser, _('network'))
|
||||||
_add_additional_network_options(parser)
|
_add_additional_network_options(parser)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -664,8 +675,12 @@ class SetNetwork(command.Command):
|
|||||||
obj = client.find_network(parsed_args.network, ignore_missing=False)
|
obj = client.find_network(parsed_args.network, ignore_missing=False)
|
||||||
|
|
||||||
attrs = _get_attrs_network(self.app.client_manager, parsed_args)
|
attrs = _get_attrs_network(self.app.client_manager, parsed_args)
|
||||||
|
if attrs:
|
||||||
client.update_network(obj, **attrs)
|
client.update_network(obj, **attrs)
|
||||||
|
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
|
|
||||||
|
|
||||||
class ShowNetwork(common.NetworkAndComputeShowOne):
|
class ShowNetwork(common.NetworkAndComputeShowOne):
|
||||||
_description = _("Show network details")
|
_description = _("Show network details")
|
||||||
@ -689,3 +704,27 @@ class ShowNetwork(common.NetworkAndComputeShowOne):
|
|||||||
display_columns, columns = _get_columns_compute(obj)
|
display_columns, columns = _get_columns_compute(obj)
|
||||||
data = utils.get_dict_properties(obj, columns)
|
data = utils.get_dict_properties(obj, columns)
|
||||||
return (display_columns, data)
|
return (display_columns, data)
|
||||||
|
|
||||||
|
|
||||||
|
class UnsetNetwork(command.Command):
|
||||||
|
_description = _("Unset network properties")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(UnsetNetwork, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'network',
|
||||||
|
metavar="<network>",
|
||||||
|
help=_("Network to modify (name or ID)")
|
||||||
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_unset(parser, _('network'))
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
client = self.app.client_manager.network
|
||||||
|
obj = client.find_network(parsed_args.network, ignore_missing=False)
|
||||||
|
|
||||||
|
# NOTE: As of now, UnsetNetwork has no attributes which need
|
||||||
|
# to be updated by update_network().
|
||||||
|
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_unset(client, obj, parsed_args)
|
||||||
|
@ -26,6 +26,7 @@ from osc_lib import utils
|
|||||||
from openstackclient.i18n import _
|
from openstackclient.i18n import _
|
||||||
from openstackclient.identity import common as identity_common
|
from openstackclient.identity import common as identity_common
|
||||||
from openstackclient.network import sdk_utils
|
from openstackclient.network import sdk_utils
|
||||||
|
from openstackclient.network.v2 import _tag
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -47,6 +48,7 @@ _formatters = {
|
|||||||
'extra_dhcp_opts': utils.format_list_of_dicts,
|
'extra_dhcp_opts': utils.format_list_of_dicts,
|
||||||
'fixed_ips': utils.format_list_of_dicts,
|
'fixed_ips': utils.format_list_of_dicts,
|
||||||
'security_group_ids': utils.format_list,
|
'security_group_ids': utils.format_list,
|
||||||
|
'tags': utils.format_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -384,6 +386,7 @@ class CreatePort(command.ShowOne):
|
|||||||
"ip-address=<ip-address>[,mac-address=<mac-address>] "
|
"ip-address=<ip-address>[,mac-address=<mac-address>] "
|
||||||
"(repeat option to set multiple allowed-address pairs)")
|
"(repeat option to set multiple allowed-address pairs)")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_create(parser, _('port'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -416,6 +419,8 @@ class CreatePort(command.ShowOne):
|
|||||||
attrs['qos_policy_id'] = client.find_qos_policy(
|
attrs['qos_policy_id'] = client.find_qos_policy(
|
||||||
parsed_args.qos_policy, ignore_missing=False).id
|
parsed_args.qos_policy, ignore_missing=False).id
|
||||||
obj = client.create_port(**attrs)
|
obj = client.create_port(**attrs)
|
||||||
|
# tags cannot be set when created, so tags need to be set later.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
display_columns, columns = _get_columns(obj)
|
display_columns, columns = _get_columns(obj)
|
||||||
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
||||||
|
|
||||||
@ -512,6 +517,7 @@ class ListPort(command.Lister):
|
|||||||
"(name or ID): subnet=<subnet>,ip-address=<ip-address> "
|
"(name or ID): subnet=<subnet>,ip-address=<ip-address> "
|
||||||
"(repeat option to set multiple fixed IP addresses)"),
|
"(repeat option to set multiple fixed IP addresses)"),
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_filtering_option_to_parser(parser, _('ports'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -535,8 +541,8 @@ class ListPort(command.Lister):
|
|||||||
|
|
||||||
filters = {}
|
filters = {}
|
||||||
if parsed_args.long:
|
if parsed_args.long:
|
||||||
columns += ('security_group_ids', 'device_owner',)
|
columns += ('security_group_ids', 'device_owner', 'tags')
|
||||||
column_headers += ('Security Groups', 'Device Owner',)
|
column_headers += ('Security Groups', 'Device Owner', 'Tags')
|
||||||
if parsed_args.device_owner is not None:
|
if parsed_args.device_owner is not None:
|
||||||
filters['device_owner'] = parsed_args.device_owner
|
filters['device_owner'] = parsed_args.device_owner
|
||||||
if parsed_args.router:
|
if parsed_args.router:
|
||||||
@ -566,6 +572,8 @@ class ListPort(command.Lister):
|
|||||||
filters['fixed_ips'] = _prepare_filter_fixed_ips(
|
filters['fixed_ips'] = _prepare_filter_fixed_ips(
|
||||||
self.app.client_manager, parsed_args)
|
self.app.client_manager, parsed_args)
|
||||||
|
|
||||||
|
_tag.get_tag_filtering_args(parsed_args, filters)
|
||||||
|
|
||||||
data = network_client.ports(**filters)
|
data = network_client.ports(**filters)
|
||||||
|
|
||||||
return (column_headers,
|
return (column_headers,
|
||||||
@ -694,6 +702,7 @@ class SetPort(command.Command):
|
|||||||
"Unset it to None with the 'port unset' command "
|
"Unset it to None with the 'port unset' command "
|
||||||
"(requires data plane status extension)")
|
"(requires data plane status extension)")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_set(parser, _('port'))
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -750,8 +759,12 @@ class SetPort(command.Command):
|
|||||||
if parsed_args.data_plane_status:
|
if parsed_args.data_plane_status:
|
||||||
attrs['data_plane_status'] = parsed_args.data_plane_status
|
attrs['data_plane_status'] = parsed_args.data_plane_status
|
||||||
|
|
||||||
|
if attrs:
|
||||||
client.update_port(obj, **attrs)
|
client.update_port(obj, **attrs)
|
||||||
|
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
|
|
||||||
|
|
||||||
class ShowPort(command.ShowOne):
|
class ShowPort(command.ShowOne):
|
||||||
_description = _("Display port details")
|
_description = _("Display port details")
|
||||||
@ -834,6 +847,8 @@ class UnsetPort(command.Command):
|
|||||||
help=_("Clear existing information of data plane status")
|
help=_("Clear existing information of data plane status")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_tag.add_tag_option_to_parser_for_unset(parser, _('port'))
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -889,3 +904,6 @@ class UnsetPort(command.Command):
|
|||||||
|
|
||||||
if attrs:
|
if attrs:
|
||||||
client.update_port(obj, **attrs)
|
client.update_port(obj, **attrs)
|
||||||
|
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_unset(client, obj, parsed_args)
|
||||||
|
@ -26,6 +26,7 @@ from osc_lib import utils
|
|||||||
from openstackclient.i18n import _
|
from openstackclient.i18n import _
|
||||||
from openstackclient.identity import common as identity_common
|
from openstackclient.identity import common as identity_common
|
||||||
from openstackclient.network import sdk_utils
|
from openstackclient.network import sdk_utils
|
||||||
|
from openstackclient.network.v2 import _tag
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -57,6 +58,7 @@ _formatters = {
|
|||||||
'availability_zones': utils.format_list,
|
'availability_zones': utils.format_list,
|
||||||
'availability_zone_hints': utils.format_list,
|
'availability_zone_hints': utils.format_list,
|
||||||
'routes': _format_routes,
|
'routes': _format_routes,
|
||||||
|
'tags': utils.format_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -217,6 +219,7 @@ class CreateRouter(command.ShowOne):
|
|||||||
"(Router Availability Zone extension required, "
|
"(Router Availability Zone extension required, "
|
||||||
"repeat option to set multiple availability zones)")
|
"repeat option to set multiple availability zones)")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_create(parser, _('router'))
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -229,6 +232,8 @@ class CreateRouter(command.ShowOne):
|
|||||||
if parsed_args.no_ha:
|
if parsed_args.no_ha:
|
||||||
attrs['ha'] = False
|
attrs['ha'] = False
|
||||||
obj = client.create_router(**attrs)
|
obj = client.create_router(**attrs)
|
||||||
|
# tags cannot be set when created, so tags need to be set later.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
|
|
||||||
display_columns, columns = _get_columns(obj)
|
display_columns, columns = _get_columns(obj)
|
||||||
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
||||||
@ -310,6 +315,7 @@ class ListRouter(command.Lister):
|
|||||||
metavar='<agent-id>',
|
metavar='<agent-id>',
|
||||||
help=_("List routers hosted by an agent (ID only)")
|
help=_("List routers hosted by an agent (ID only)")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_filtering_option_to_parser(parser, _('routers'))
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -357,6 +363,8 @@ class ListRouter(command.Lister):
|
|||||||
args['tenant_id'] = project_id
|
args['tenant_id'] = project_id
|
||||||
args['project_id'] = project_id
|
args['project_id'] = project_id
|
||||||
|
|
||||||
|
_tag.get_tag_filtering_args(parsed_args, args)
|
||||||
|
|
||||||
if parsed_args.agent is not None:
|
if parsed_args.agent is not None:
|
||||||
agent = client.get_agent(parsed_args.agent)
|
agent = client.get_agent(parsed_args.agent)
|
||||||
data = client.agent_hosted_routers(agent)
|
data = client.agent_hosted_routers(agent)
|
||||||
@ -384,6 +392,8 @@ class ListRouter(command.Lister):
|
|||||||
column_headers = column_headers + (
|
column_headers = column_headers + (
|
||||||
'Availability zones',
|
'Availability zones',
|
||||||
)
|
)
|
||||||
|
columns = columns + ('tags',)
|
||||||
|
column_headers = column_headers + ('Tags',)
|
||||||
|
|
||||||
return (column_headers,
|
return (column_headers,
|
||||||
(utils.get_item_properties(
|
(utils.get_item_properties(
|
||||||
@ -567,6 +577,7 @@ class SetRouter(command.Command):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
help=_("Disable Source NAT on external gateway")
|
help=_("Disable Source NAT on external gateway")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_set(parser, _('router'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -625,7 +636,10 @@ class SetRouter(command.Command):
|
|||||||
ips.append(ip_spec)
|
ips.append(ip_spec)
|
||||||
gateway_info['external_fixed_ips'] = ips
|
gateway_info['external_fixed_ips'] = ips
|
||||||
attrs['external_gateway_info'] = gateway_info
|
attrs['external_gateway_info'] = gateway_info
|
||||||
|
if attrs:
|
||||||
client.update_router(obj, **attrs)
|
client.update_router(obj, **attrs)
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
|
|
||||||
|
|
||||||
class ShowRouter(command.ShowOne):
|
class ShowRouter(command.ShowOne):
|
||||||
@ -675,6 +689,7 @@ class UnsetRouter(command.Command):
|
|||||||
metavar="<router>",
|
metavar="<router>",
|
||||||
help=_("Router to modify (name or ID)")
|
help=_("Router to modify (name or ID)")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_unset(parser, _('router'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -695,3 +710,5 @@ class UnsetRouter(command.Command):
|
|||||||
attrs['external_gateway_info'] = {}
|
attrs['external_gateway_info'] = {}
|
||||||
if attrs:
|
if attrs:
|
||||||
client.update_router(obj, **attrs)
|
client.update_router(obj, **attrs)
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_unset(client, obj, parsed_args)
|
||||||
|
@ -24,6 +24,7 @@ from osc_lib import utils
|
|||||||
from openstackclient.i18n import _
|
from openstackclient.i18n import _
|
||||||
from openstackclient.identity import common as identity_common
|
from openstackclient.identity import common as identity_common
|
||||||
from openstackclient.network import sdk_utils
|
from openstackclient.network import sdk_utils
|
||||||
|
from openstackclient.network.v2 import _tag
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -55,6 +56,7 @@ _formatters = {
|
|||||||
'dns_nameservers': utils.format_list,
|
'dns_nameservers': utils.format_list,
|
||||||
'host_routes': _format_host_routes,
|
'host_routes': _format_host_routes,
|
||||||
'service_types': utils.format_list,
|
'service_types': utils.format_list,
|
||||||
|
'tags': utils.format_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -336,12 +338,15 @@ class CreateSubnet(command.ShowOne):
|
|||||||
help=_("Set subnet description")
|
help=_("Set subnet description")
|
||||||
)
|
)
|
||||||
_get_common_parse_arguments(parser)
|
_get_common_parse_arguments(parser)
|
||||||
|
_tag.add_tag_option_to_parser_for_create(parser, _('subnet'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
client = self.app.client_manager.network
|
client = self.app.client_manager.network
|
||||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||||
obj = client.create_subnet(**attrs)
|
obj = client.create_subnet(**attrs)
|
||||||
|
# tags cannot be set when created, so tags need to be set later.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
display_columns, columns = _get_columns(obj)
|
display_columns, columns = _get_columns(obj)
|
||||||
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
||||||
return (display_columns, data)
|
return (display_columns, data)
|
||||||
@ -454,6 +459,7 @@ class ListSubnet(command.Lister):
|
|||||||
"(in CIDR notation) in output "
|
"(in CIDR notation) in output "
|
||||||
"e.g.: --subnet-range 10.10.0.0/16")
|
"e.g.: --subnet-range 10.10.0.0/16")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_filtering_option_to_parser(parser, _('subnets'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -488,6 +494,7 @@ class ListSubnet(command.Lister):
|
|||||||
filters['name'] = parsed_args.name
|
filters['name'] = parsed_args.name
|
||||||
if parsed_args.subnet_range:
|
if parsed_args.subnet_range:
|
||||||
filters['cidr'] = parsed_args.subnet_range
|
filters['cidr'] = parsed_args.subnet_range
|
||||||
|
_tag.get_tag_filtering_args(parsed_args, filters)
|
||||||
data = network_client.subnets(**filters)
|
data = network_client.subnets(**filters)
|
||||||
|
|
||||||
headers = ('ID', 'Name', 'Network', 'Subnet')
|
headers = ('ID', 'Name', 'Network', 'Subnet')
|
||||||
@ -495,10 +502,10 @@ class ListSubnet(command.Lister):
|
|||||||
if parsed_args.long:
|
if parsed_args.long:
|
||||||
headers += ('Project', 'DHCP', 'Name Servers',
|
headers += ('Project', 'DHCP', 'Name Servers',
|
||||||
'Allocation Pools', 'Host Routes', 'IP Version',
|
'Allocation Pools', 'Host Routes', 'IP Version',
|
||||||
'Gateway', 'Service Types')
|
'Gateway', 'Service Types', 'Tags')
|
||||||
columns += ('project_id', 'is_dhcp_enabled', 'dns_nameservers',
|
columns += ('project_id', 'is_dhcp_enabled', 'dns_nameservers',
|
||||||
'allocation_pools', 'host_routes', 'ip_version',
|
'allocation_pools', 'host_routes', 'ip_version',
|
||||||
'gateway_ip', 'service_types')
|
'gateway_ip', 'service_types', 'tags')
|
||||||
|
|
||||||
return (headers,
|
return (headers,
|
||||||
(utils.get_item_properties(
|
(utils.get_item_properties(
|
||||||
@ -549,6 +556,7 @@ class SetSubnet(command.Command):
|
|||||||
metavar='<description>',
|
metavar='<description>',
|
||||||
help=_("Set subnet description")
|
help=_("Set subnet description")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_set(parser, _('subnet'))
|
||||||
_get_common_parse_arguments(parser, is_create=False)
|
_get_common_parse_arguments(parser, is_create=False)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -574,7 +582,10 @@ class SetSubnet(command.Command):
|
|||||||
attrs['allocation_pools'] = []
|
attrs['allocation_pools'] = []
|
||||||
if 'service_types' in attrs:
|
if 'service_types' in attrs:
|
||||||
attrs['service_types'] += obj.service_types
|
attrs['service_types'] += obj.service_types
|
||||||
|
if attrs:
|
||||||
client.update_subnet(obj, **attrs)
|
client.update_subnet(obj, **attrs)
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@ -643,6 +654,7 @@ class UnsetSubnet(command.Command):
|
|||||||
'Must be a valid device owner value for a network port '
|
'Must be a valid device owner value for a network port '
|
||||||
'(repeat option to unset multiple service types)')
|
'(repeat option to unset multiple service types)')
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_unset(parser, _('subnet'))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'subnet',
|
'subnet',
|
||||||
metavar="<subnet>",
|
metavar="<subnet>",
|
||||||
@ -678,3 +690,6 @@ class UnsetSubnet(command.Command):
|
|||||||
attrs['service_types'] = tmp_obj.service_types
|
attrs['service_types'] = tmp_obj.service_types
|
||||||
if attrs:
|
if attrs:
|
||||||
client.update_subnet(obj, **attrs)
|
client.update_subnet(obj, **attrs)
|
||||||
|
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_unset(client, obj, parsed_args)
|
||||||
|
@ -24,6 +24,7 @@ from osc_lib import utils
|
|||||||
from openstackclient.i18n import _
|
from openstackclient.i18n import _
|
||||||
from openstackclient.identity import common as identity_common
|
from openstackclient.identity import common as identity_common
|
||||||
from openstackclient.network import sdk_utils
|
from openstackclient.network import sdk_utils
|
||||||
|
from openstackclient.network.v2 import _tag
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -42,6 +43,7 @@ def _get_columns(item):
|
|||||||
|
|
||||||
_formatters = {
|
_formatters = {
|
||||||
'prefixes': utils.format_list,
|
'prefixes': utils.format_list,
|
||||||
|
'tags': utils.format_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -191,6 +193,7 @@ class CreateSubnetPool(command.ShowOne):
|
|||||||
metavar='<num-ip-addresses>',
|
metavar='<num-ip-addresses>',
|
||||||
help=_("Set default quota for subnet pool as the number of"
|
help=_("Set default quota for subnet pool as the number of"
|
||||||
"IP addresses allowed in a subnet")),
|
"IP addresses allowed in a subnet")),
|
||||||
|
_tag.add_tag_option_to_parser_for_create(parser, _('subnet pool'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -200,6 +203,8 @@ class CreateSubnetPool(command.ShowOne):
|
|||||||
if "prefixes" not in attrs:
|
if "prefixes" not in attrs:
|
||||||
attrs['prefixes'] = []
|
attrs['prefixes'] = []
|
||||||
obj = client.create_subnet_pool(**attrs)
|
obj = client.create_subnet_pool(**attrs)
|
||||||
|
# tags cannot be set when created, so tags need to be set later.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
display_columns, columns = _get_columns(obj)
|
display_columns, columns = _get_columns(obj)
|
||||||
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
||||||
return (display_columns, data)
|
return (display_columns, data)
|
||||||
@ -293,6 +298,7 @@ class ListSubnetPool(command.Lister):
|
|||||||
help=_("List only subnet pools of given address scope "
|
help=_("List only subnet pools of given address scope "
|
||||||
"in output (name or ID)")
|
"in output (name or ID)")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_filtering_option_to_parser(parser, _('subnet pools'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -324,15 +330,16 @@ class ListSubnetPool(command.Lister):
|
|||||||
parsed_args.address_scope,
|
parsed_args.address_scope,
|
||||||
ignore_missing=False)
|
ignore_missing=False)
|
||||||
filters['address_scope_id'] = address_scope.id
|
filters['address_scope_id'] = address_scope.id
|
||||||
|
_tag.get_tag_filtering_args(parsed_args, filters)
|
||||||
data = network_client.subnet_pools(**filters)
|
data = network_client.subnet_pools(**filters)
|
||||||
|
|
||||||
headers = ('ID', 'Name', 'Prefixes')
|
headers = ('ID', 'Name', 'Prefixes')
|
||||||
columns = ('id', 'name', 'prefixes')
|
columns = ('id', 'name', 'prefixes')
|
||||||
if parsed_args.long:
|
if parsed_args.long:
|
||||||
headers += ('Default Prefix Length', 'Address Scope',
|
headers += ('Default Prefix Length', 'Address Scope',
|
||||||
'Default Subnet Pool', 'Shared')
|
'Default Subnet Pool', 'Shared', 'Tags')
|
||||||
columns += ('default_prefix_length', 'address_scope_id',
|
columns += ('default_prefix_length', 'address_scope_id',
|
||||||
'is_default', 'is_shared')
|
'is_default', 'is_shared', 'tags')
|
||||||
|
|
||||||
return (headers,
|
return (headers,
|
||||||
(utils.get_item_properties(
|
(utils.get_item_properties(
|
||||||
@ -384,6 +391,8 @@ class SetSubnetPool(command.Command):
|
|||||||
metavar='<num-ip-addresses>',
|
metavar='<num-ip-addresses>',
|
||||||
help=_("Set default quota for subnet pool as the number of"
|
help=_("Set default quota for subnet pool as the number of"
|
||||||
"IP addresses allowed in a subnet")),
|
"IP addresses allowed in a subnet")),
|
||||||
|
_tag.add_tag_option_to_parser_for_set(parser, _('subnet pool'))
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -397,7 +406,10 @@ class SetSubnetPool(command.Command):
|
|||||||
if 'prefixes' in attrs:
|
if 'prefixes' in attrs:
|
||||||
attrs['prefixes'].extend(obj.prefixes)
|
attrs['prefixes'].extend(obj.prefixes)
|
||||||
|
|
||||||
|
if attrs:
|
||||||
client.update_subnet_pool(obj, **attrs)
|
client.update_subnet_pool(obj, **attrs)
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||||
|
|
||||||
|
|
||||||
class ShowSubnetPool(command.ShowOne):
|
class ShowSubnetPool(command.ShowOne):
|
||||||
@ -441,6 +453,7 @@ class UnsetSubnetPool(command.Command):
|
|||||||
metavar="<subnet-pool>",
|
metavar="<subnet-pool>",
|
||||||
help=_("Subnet pool to modify (name or ID)")
|
help=_("Subnet pool to modify (name or ID)")
|
||||||
)
|
)
|
||||||
|
_tag.add_tag_option_to_parser_for_unset(parser, _('subnet pool'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -461,3 +474,5 @@ class UnsetSubnetPool(command.Command):
|
|||||||
attrs['prefixes'] = tmp_prefixes
|
attrs['prefixes'] = tmp_prefixes
|
||||||
if attrs:
|
if attrs:
|
||||||
client.update_subnet_pool(obj, **attrs)
|
client.update_subnet_pool(obj, **attrs)
|
||||||
|
# tags is a subresource and it needs to be updated separately.
|
||||||
|
_tag.update_tags_for_unset(client, obj, parsed_args)
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import uuid
|
||||||
|
|
||||||
from openstackclient.tests.functional import base
|
from openstackclient.tests.functional import base
|
||||||
|
|
||||||
|
|
||||||
@ -20,3 +23,81 @@ class NetworkTests(base.TestCase):
|
|||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super(NetworkTests, cls).setUpClass()
|
super(NetworkTests, cls).setUpClass()
|
||||||
cls.haz_network = base.is_service_enabled('network')
|
cls.haz_network = base.is_service_enabled('network')
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkTagTests(NetworkTests):
|
||||||
|
"""Functional tests with tag operation"""
|
||||||
|
|
||||||
|
base_command = None
|
||||||
|
|
||||||
|
def test_tag_operation(self):
|
||||||
|
# Get project IDs
|
||||||
|
cmd_output = json.loads(self.openstack('token issue -f json '))
|
||||||
|
auth_project_id = cmd_output['project_id']
|
||||||
|
|
||||||
|
# Network create with no options
|
||||||
|
name1 = self._create_resource_and_tag_check('', [])
|
||||||
|
# Network create with tags
|
||||||
|
name2 = self._create_resource_and_tag_check('--tag red --tag blue',
|
||||||
|
['red', 'blue'])
|
||||||
|
# Network create with no tag explicitly
|
||||||
|
name3 = self._create_resource_and_tag_check('--no-tag', [])
|
||||||
|
|
||||||
|
self._set_resource_and_tag_check('set', name1, '--tag red --tag green',
|
||||||
|
['red', 'green'])
|
||||||
|
|
||||||
|
list_expected = ((name1, ['red', 'green']),
|
||||||
|
(name2, ['red', 'blue']),
|
||||||
|
(name3, []))
|
||||||
|
self._list_tag_check(auth_project_id, list_expected)
|
||||||
|
|
||||||
|
self._set_resource_and_tag_check('set', name1, '--tag blue',
|
||||||
|
['red', 'green', 'blue'])
|
||||||
|
self._set_resource_and_tag_check(
|
||||||
|
'set', name1,
|
||||||
|
'--no-tag --tag yellow --tag orange --tag purple',
|
||||||
|
['yellow', 'orange', 'purple'])
|
||||||
|
self._set_resource_and_tag_check('unset', name1, '--tag yellow',
|
||||||
|
['orange', 'purple'])
|
||||||
|
self._set_resource_and_tag_check('unset', name1, '--all-tag', [])
|
||||||
|
self._set_resource_and_tag_check('set', name2, '--no-tag', [])
|
||||||
|
|
||||||
|
def _assertTagsEqual(self, expected, actual):
|
||||||
|
# TODO(amotoki): Should migrate to cliff format columns.
|
||||||
|
# At now, unit test assert method needs to be replaced
|
||||||
|
# to handle format columns, so format_list() is used.
|
||||||
|
# NOTE: The order of tag is undeterminestic.
|
||||||
|
actual_tags = filter(bool, actual.split(', '))
|
||||||
|
self.assertEqual(set(expected), set(actual_tags))
|
||||||
|
|
||||||
|
def _list_tag_check(self, project_id, expected):
|
||||||
|
cmd_output = json.loads(self.openstack(
|
||||||
|
'{} list --long --project {} -f json'.format(self.base_command,
|
||||||
|
project_id)))
|
||||||
|
for name, tags in expected:
|
||||||
|
net = [n for n in cmd_output if n['Name'] == name][0]
|
||||||
|
self._assertTagsEqual(tags, net['Tags'])
|
||||||
|
|
||||||
|
def _create_resource_for_tag_test(self, name, args):
|
||||||
|
return json.loads(self.openstack(
|
||||||
|
'{} create -f json {} {}'.format(self.base_command, args, name)
|
||||||
|
))
|
||||||
|
|
||||||
|
def _create_resource_and_tag_check(self, args, expected):
|
||||||
|
name = uuid.uuid4().hex
|
||||||
|
cmd_output = self._create_resource_for_tag_test(name, args)
|
||||||
|
self.addCleanup(
|
||||||
|
self.openstack, '{} delete {}'.format(self.base_command, name))
|
||||||
|
self.assertIsNotNone(cmd_output["id"])
|
||||||
|
self._assertTagsEqual(expected, cmd_output['tags'])
|
||||||
|
return name
|
||||||
|
|
||||||
|
def _set_resource_and_tag_check(self, command, name, args, expected):
|
||||||
|
cmd_output = self.openstack(
|
||||||
|
'{} {} {} {}'.format(self.base_command, command, args, name)
|
||||||
|
)
|
||||||
|
self.assertFalse(cmd_output)
|
||||||
|
cmd_output = json.loads(self.openstack(
|
||||||
|
'{} show -f json {}'.format(self.base_command, name)
|
||||||
|
))
|
||||||
|
self._assertTagsEqual(expected, cmd_output['tags'])
|
||||||
|
@ -16,9 +16,11 @@ import uuid
|
|||||||
from openstackclient.tests.functional.network.v2 import common
|
from openstackclient.tests.functional.network.v2 import common
|
||||||
|
|
||||||
|
|
||||||
class NetworkTests(common.NetworkTests):
|
class NetworkTests(common.NetworkTagTests):
|
||||||
"""Functional tests for network"""
|
"""Functional tests for network"""
|
||||||
|
|
||||||
|
base_command = 'network'
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(NetworkTests, self).setUp()
|
super(NetworkTests, self).setUp()
|
||||||
# Nothing in this class works with Nova Network
|
# Nothing in this class works with Nova Network
|
||||||
|
@ -16,9 +16,14 @@ import uuid
|
|||||||
from openstackclient.tests.functional.network.v2 import common
|
from openstackclient.tests.functional.network.v2 import common
|
||||||
|
|
||||||
|
|
||||||
class PortTests(common.NetworkTests):
|
class PortTests(common.NetworkTagTests):
|
||||||
"""Functional tests for port"""
|
"""Functional tests for port"""
|
||||||
|
|
||||||
|
base_command = 'port'
|
||||||
|
|
||||||
|
NAME = uuid.uuid4().hex
|
||||||
|
NETWORK_NAME = uuid.uuid4().hex
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
common.NetworkTests.setUpClass()
|
common.NetworkTests.setUpClass()
|
||||||
@ -250,3 +255,9 @@ class PortTests(common.NetworkTests):
|
|||||||
sg_id2,
|
sg_id2,
|
||||||
json_output.get('security_group_ids'),
|
json_output.get('security_group_ids'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _create_resource_for_tag_test(self, name, args):
|
||||||
|
return json.loads(self.openstack(
|
||||||
|
'{} create -f json --network {} {} {}'
|
||||||
|
.format(self.base_command, self.NETWORK_NAME, args, name)
|
||||||
|
))
|
||||||
|
@ -16,9 +16,11 @@ import uuid
|
|||||||
from openstackclient.tests.functional.network.v2 import common
|
from openstackclient.tests.functional.network.v2 import common
|
||||||
|
|
||||||
|
|
||||||
class RouterTests(common.NetworkTests):
|
class RouterTests(common.NetworkTagTests):
|
||||||
"""Functional tests for router"""
|
"""Functional tests for router"""
|
||||||
|
|
||||||
|
base_command = 'router'
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(RouterTests, self).setUp()
|
super(RouterTests, self).setUp()
|
||||||
# Nothing in this class works with Nova Network
|
# Nothing in this class works with Nova Network
|
||||||
|
@ -17,9 +17,11 @@ import uuid
|
|||||||
from openstackclient.tests.functional.network.v2 import common
|
from openstackclient.tests.functional.network.v2 import common
|
||||||
|
|
||||||
|
|
||||||
class SubnetTests(common.NetworkTests):
|
class SubnetTests(common.NetworkTagTests):
|
||||||
"""Functional tests for subnet"""
|
"""Functional tests for subnet"""
|
||||||
|
|
||||||
|
base_command = 'subnet'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
common.NetworkTests.setUpClass()
|
common.NetworkTests.setUpClass()
|
||||||
@ -285,3 +287,9 @@ class SubnetTests(common.NetworkTests):
|
|||||||
# break and no longer retry if create successfully
|
# break and no longer retry if create successfully
|
||||||
break
|
break
|
||||||
return cmd_output
|
return cmd_output
|
||||||
|
|
||||||
|
def _create_resource_for_tag_test(self, name, args):
|
||||||
|
cmd = ('subnet create -f json --network ' +
|
||||||
|
self.NETWORK_NAME + ' ' + args +
|
||||||
|
' --subnet-range')
|
||||||
|
return self._subnet_create(cmd, name)
|
||||||
|
@ -17,9 +17,11 @@ import uuid
|
|||||||
from openstackclient.tests.functional.network.v2 import common
|
from openstackclient.tests.functional.network.v2 import common
|
||||||
|
|
||||||
|
|
||||||
class SubnetPoolTests(common.NetworkTests):
|
class SubnetPoolTests(common.NetworkTagTests):
|
||||||
"""Functional tests for subnet pool"""
|
"""Functional tests for subnet pool"""
|
||||||
|
|
||||||
|
base_command = 'subnet pool'
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(SubnetPoolTests, self).setUp()
|
super(SubnetPoolTests, self).setUp()
|
||||||
# Nothing in this class works with Nova Network
|
# Nothing in this class works with Nova Network
|
||||||
@ -321,3 +323,7 @@ class SubnetPoolTests(common.NetworkTests):
|
|||||||
break
|
break
|
||||||
|
|
||||||
return cmd_output, pool_prefix
|
return cmd_output, pool_prefix
|
||||||
|
|
||||||
|
def _create_resource_for_tag_test(self, name, args):
|
||||||
|
cmd_output, _pool_prefix = self._subnet_pool_create(args, name)
|
||||||
|
return cmd_output
|
||||||
|
190
openstackclient/tests/unit/network/v2/_test_tag.py
Normal file
190
openstackclient/tests/unit/network/v2/_test_tag.py
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
# 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 openstackclient.tests.unit import utils as tests_utils
|
||||||
|
|
||||||
|
|
||||||
|
class TestCreateTagMixin(object):
|
||||||
|
"""Test case mixin to test network tag operation for resource creation.
|
||||||
|
|
||||||
|
* Each test class must create a mock for self.network.set_tags
|
||||||
|
* If you test tag operation combined with other options,
|
||||||
|
you need to write test(s) directly in individual test cases.
|
||||||
|
* The following instance attributes must be defined:
|
||||||
|
|
||||||
|
* _tag_test_resource: Test resource returned by mocked create_<resource>.
|
||||||
|
* _tag_create_resource_mock: Mocked create_<resource> method of SDK.
|
||||||
|
* _tag_create_required_arglist: List of required arguments when creating
|
||||||
|
a resource with default options.
|
||||||
|
* _tag_create_required_verifylist: List of expected parsed_args params
|
||||||
|
when creating a resource with default options.
|
||||||
|
* _tag_create_required_attrs: Expected attributes passed to a mocked
|
||||||
|
create_resource method when creating a resource with default options.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _test_create_with_tag(self, add_tags=True):
|
||||||
|
arglist = self._tag_create_required_arglist[:]
|
||||||
|
if add_tags:
|
||||||
|
arglist += ['--tag', 'red', '--tag', 'blue']
|
||||||
|
else:
|
||||||
|
arglist += ['--no-tag']
|
||||||
|
verifylist = self._tag_create_required_verifylist[:]
|
||||||
|
if add_tags:
|
||||||
|
verifylist.append(('tags', ['red', 'blue']))
|
||||||
|
else:
|
||||||
|
verifylist.append(('no_tag', True))
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
columns, data = (self.cmd.take_action(parsed_args))
|
||||||
|
|
||||||
|
self._tag_create_resource_mock.assert_called_once_with(
|
||||||
|
**self._tag_create_required_attrs)
|
||||||
|
if add_tags:
|
||||||
|
self.network.set_tags.assert_called_once_with(
|
||||||
|
self._tag_test_resource,
|
||||||
|
tests_utils.CompareBySet(['red', 'blue']))
|
||||||
|
else:
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
|
def test_create_with_tags(self):
|
||||||
|
self._test_create_with_tag(add_tags=True)
|
||||||
|
|
||||||
|
def test_create_with_no_tag(self):
|
||||||
|
self._test_create_with_tag(add_tags=False)
|
||||||
|
|
||||||
|
|
||||||
|
class TestListTagMixin(object):
|
||||||
|
"""Test case mixin to test network tag operation for resource listing.
|
||||||
|
|
||||||
|
* A test resource returned by find_<resource> must contains
|
||||||
|
"red" and "green" tags.
|
||||||
|
* Each test class must create a mock for self.network.set_tags
|
||||||
|
* If you test tag operation combined with other options,
|
||||||
|
you need to write test(s) directly in individual test cases.
|
||||||
|
* The following instance attributes must be defined:
|
||||||
|
|
||||||
|
* _tag_create_resource_mock: Mocked list_<resource> method of SDK.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_list_with_tag_options(self):
|
||||||
|
arglist = [
|
||||||
|
'--tags', 'red,blue',
|
||||||
|
'--any-tags', 'red,green',
|
||||||
|
'--not-tags', 'orange,yellow',
|
||||||
|
'--not-any-tags', 'black,white',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('tags', ['red', 'blue']),
|
||||||
|
('any_tags', ['red', 'green']),
|
||||||
|
('not_tags', ['orange', 'yellow']),
|
||||||
|
('not_any_tags', ['black', 'white']),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self._tag_list_resource_mock.assert_called_once_with(
|
||||||
|
**{'tags': 'red,blue',
|
||||||
|
'any_tags': 'red,green',
|
||||||
|
'not_tags': 'orange,yellow',
|
||||||
|
'not_any_tags': 'black,white'}
|
||||||
|
)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
|
||||||
|
class TestSetTagMixin(object):
|
||||||
|
"""Test case mixin to test network tag operation for resource update.
|
||||||
|
|
||||||
|
* A test resource returned by find_<resource> must contains
|
||||||
|
"red" and "green" tags.
|
||||||
|
* Each test class must create a mock for self.network.set_tags
|
||||||
|
* If you test tag operation combined with other options,
|
||||||
|
you need to write test(s) directly in individual test cases.
|
||||||
|
* The following instance attributes must be defined:
|
||||||
|
|
||||||
|
* _tag_resource_name: positional arg name of a resource to be updated.
|
||||||
|
* _tag_test_resource: Test resource returned by mocked update_<resource>.
|
||||||
|
* _tag_update_resource_mock: Mocked update_<resource> method of SDK.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _test_set_tags(self, with_tags=True):
|
||||||
|
if with_tags:
|
||||||
|
arglist = ['--tag', 'red', '--tag', 'blue']
|
||||||
|
verifylist = [('tags', ['red', 'blue'])]
|
||||||
|
expected_args = ['red', 'blue', 'green']
|
||||||
|
else:
|
||||||
|
arglist = ['--no-tag']
|
||||||
|
verifylist = [('no_tag', True)]
|
||||||
|
expected_args = []
|
||||||
|
arglist.append(self._tag_test_resource.name)
|
||||||
|
verifylist.append(
|
||||||
|
(self._tag_resource_name, self._tag_test_resource.name))
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.assertFalse(self._tag_update_resource_mock.called)
|
||||||
|
self.network.set_tags.assert_called_once_with(
|
||||||
|
self._tag_test_resource,
|
||||||
|
tests_utils.CompareBySet(expected_args))
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_set_with_tags(self):
|
||||||
|
self._test_set_tags(with_tags=True)
|
||||||
|
|
||||||
|
def test_set_with_no_tag(self):
|
||||||
|
self._test_set_tags(with_tags=False)
|
||||||
|
|
||||||
|
|
||||||
|
class TestUnsetTagMixin(object):
|
||||||
|
"""Test case mixin to test network tag operation for resource update.
|
||||||
|
|
||||||
|
* Each test class must create a mock for self.network.set_tags
|
||||||
|
* If you test tag operation combined with other options,
|
||||||
|
you need to write test(s) directly in individual test cases.
|
||||||
|
* The following instance attributes must be defined:
|
||||||
|
|
||||||
|
* _tag_resource_name: positional arg name of a resource to be updated.
|
||||||
|
* _tag_test_resource: Test resource returned by mocked update_<resource>.
|
||||||
|
* _tag_update_resource_mock: Mocked update_<resource> method of SDK.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _test_unset_tags(self, with_tags=True):
|
||||||
|
if with_tags:
|
||||||
|
arglist = ['--tag', 'red', '--tag', 'blue']
|
||||||
|
verifylist = [('tags', ['red', 'blue'])]
|
||||||
|
expected_args = ['green']
|
||||||
|
else:
|
||||||
|
arglist = ['--all-tag']
|
||||||
|
verifylist = [('all_tag', True)]
|
||||||
|
expected_args = []
|
||||||
|
arglist.append(self._tag_test_resource.name)
|
||||||
|
verifylist.append(
|
||||||
|
(self._tag_resource_name, self._tag_test_resource.name))
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.assertFalse(self._tag_update_resource_mock.called)
|
||||||
|
self.network.set_tags.assert_called_once_with(
|
||||||
|
self._tag_test_resource,
|
||||||
|
tests_utils.CompareBySet(expected_args))
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_unset_with_tags(self):
|
||||||
|
self._test_unset_tags(with_tags=True)
|
||||||
|
|
||||||
|
def test_unset_with_all_tag(self):
|
||||||
|
self._test_unset_tags(with_tags=False)
|
@ -350,6 +350,7 @@ class FakeNetwork(object):
|
|||||||
'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
|
'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
|
||||||
'ipv4_address_scope': 'ipv4' + uuid.uuid4().hex,
|
'ipv4_address_scope': 'ipv4' + uuid.uuid4().hex,
|
||||||
'ipv6_address_scope': 'ipv6' + uuid.uuid4().hex,
|
'ipv6_address_scope': 'ipv6' + uuid.uuid4().hex,
|
||||||
|
'tags': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
# Overwrite default attributes.
|
# Overwrite default attributes.
|
||||||
@ -576,6 +577,7 @@ class FakePort(object):
|
|||||||
'status': 'ACTIVE',
|
'status': 'ACTIVE',
|
||||||
'tenant_id': 'project-id-' + uuid.uuid4().hex,
|
'tenant_id': 'project-id-' + uuid.uuid4().hex,
|
||||||
'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
|
'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
|
||||||
|
'tags': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
# Overwrite default attributes.
|
# Overwrite default attributes.
|
||||||
@ -1053,6 +1055,7 @@ class FakeRouter(object):
|
|||||||
'external_gateway_info': {},
|
'external_gateway_info': {},
|
||||||
'availability_zone_hints': [],
|
'availability_zone_hints': [],
|
||||||
'availability_zones': [],
|
'availability_zones': [],
|
||||||
|
'tags': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
# Overwrite default attributes.
|
# Overwrite default attributes.
|
||||||
@ -1294,6 +1297,7 @@ class FakeSubnet(object):
|
|||||||
'service_types': [],
|
'service_types': [],
|
||||||
'subnetpool_id': None,
|
'subnetpool_id': None,
|
||||||
'description': 'subnet-description-' + uuid.uuid4().hex,
|
'description': 'subnet-description-' + uuid.uuid4().hex,
|
||||||
|
'tags': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
# Overwrite default attributes.
|
# Overwrite default attributes.
|
||||||
@ -1544,6 +1548,7 @@ class FakeSubnetPool(object):
|
|||||||
'default_quota': None,
|
'default_quota': None,
|
||||||
'ip_version': '4',
|
'ip_version': '4',
|
||||||
'description': 'subnet-pool-description-' + uuid.uuid4().hex,
|
'description': 'subnet-pool-description-' + uuid.uuid4().hex,
|
||||||
|
'tags': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
# Overwrite default attributes.
|
# Overwrite default attributes.
|
||||||
|
@ -22,6 +22,7 @@ from openstackclient.network.v2 import network
|
|||||||
from openstackclient.tests.unit import fakes
|
from openstackclient.tests.unit import fakes
|
||||||
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes_v2
|
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes_v2
|
||||||
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
|
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
|
||||||
|
from openstackclient.tests.unit.network.v2 import _test_tag
|
||||||
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
||||||
from openstackclient.tests.unit import utils as tests_utils
|
from openstackclient.tests.unit import utils as tests_utils
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ class TestNetwork(network_fakes.TestNetworkV2):
|
|||||||
self.domains_mock = self.app.client_manager.identity.domains
|
self.domains_mock = self.app.client_manager.identity.domains
|
||||||
|
|
||||||
|
|
||||||
class TestCreateNetworkIdentityV3(TestNetwork):
|
class TestCreateNetworkIdentityV3(TestNetwork, _test_tag.TestCreateTagMixin):
|
||||||
|
|
||||||
project = identity_fakes_v3.FakeProject.create_one_project()
|
project = identity_fakes_v3.FakeProject.create_one_project()
|
||||||
domain = identity_fakes_v3.FakeDomain.create_one_domain()
|
domain = identity_fakes_v3.FakeDomain.create_one_domain()
|
||||||
@ -105,6 +106,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
|
|||||||
super(TestCreateNetworkIdentityV3, self).setUp()
|
super(TestCreateNetworkIdentityV3, self).setUp()
|
||||||
|
|
||||||
self.network.create_network = mock.Mock(return_value=self._network)
|
self.network.create_network = mock.Mock(return_value=self._network)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = network.CreateNetwork(self.app, self.namespace)
|
self.cmd = network.CreateNetwork(self.app, self.namespace)
|
||||||
@ -113,6 +115,22 @@ class TestCreateNetworkIdentityV3(TestNetwork):
|
|||||||
self.domains_mock.get.return_value = self.domain
|
self.domains_mock.get.return_value = self.domain
|
||||||
self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy)
|
self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy)
|
||||||
|
|
||||||
|
# TestCreateTagMixin
|
||||||
|
self._tag_test_resource = self._network
|
||||||
|
self._tag_create_resource_mock = self.network.create_network
|
||||||
|
self._tag_create_required_arglist = [self._network.name]
|
||||||
|
self._tag_create_required_verifylist = [
|
||||||
|
('name', self._network.name),
|
||||||
|
('enable', True),
|
||||||
|
('share', None),
|
||||||
|
('project', None),
|
||||||
|
('external', False),
|
||||||
|
]
|
||||||
|
self._tag_create_required_attrs = {
|
||||||
|
'admin_state_up': True,
|
||||||
|
'name': self._network.name,
|
||||||
|
}
|
||||||
|
|
||||||
def test_create_no_options(self):
|
def test_create_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = []
|
verifylist = []
|
||||||
@ -139,6 +157,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
|
|||||||
'admin_state_up': True,
|
'admin_state_up': True,
|
||||||
'name': self._network.name,
|
'name': self._network.name,
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
@ -287,6 +306,7 @@ class TestCreateNetworkIdentityV2(TestNetwork):
|
|||||||
super(TestCreateNetworkIdentityV2, self).setUp()
|
super(TestCreateNetworkIdentityV2, self).setUp()
|
||||||
|
|
||||||
self.network.create_network = mock.Mock(return_value=self._network)
|
self.network.create_network = mock.Mock(return_value=self._network)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = network.CreateNetwork(self.app, self.namespace)
|
self.cmd = network.CreateNetwork(self.app, self.namespace)
|
||||||
@ -328,6 +348,7 @@ class TestCreateNetworkIdentityV2(TestNetwork):
|
|||||||
'tenant_id': self.project.id,
|
'tenant_id': self.project.id,
|
||||||
'project_id': self.project.id,
|
'project_id': self.project.id,
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
@ -440,7 +461,7 @@ class TestDeleteNetwork(TestNetwork):
|
|||||||
self.network.delete_network.assert_has_calls(calls)
|
self.network.delete_network.assert_has_calls(calls)
|
||||||
|
|
||||||
|
|
||||||
class TestListNetwork(TestNetwork):
|
class TestListNetwork(TestNetwork, _test_tag.TestListTagMixin):
|
||||||
|
|
||||||
# The networks going to be listed up.
|
# The networks going to be listed up.
|
||||||
_network = network_fakes.FakeNetwork.create_networks(count=3)
|
_network = network_fakes.FakeNetwork.create_networks(count=3)
|
||||||
@ -461,6 +482,7 @@ class TestListNetwork(TestNetwork):
|
|||||||
'Network Type',
|
'Network Type',
|
||||||
'Router Type',
|
'Router Type',
|
||||||
'Availability Zones',
|
'Availability Zones',
|
||||||
|
'Tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
@ -484,6 +506,7 @@ class TestListNetwork(TestNetwork):
|
|||||||
net.provider_network_type,
|
net.provider_network_type,
|
||||||
network._format_router_external(net.is_router_external),
|
network._format_router_external(net.is_router_external),
|
||||||
utils.format_list(net.availability_zones),
|
utils.format_list(net.availability_zones),
|
||||||
|
utils.format_list(net.tags),
|
||||||
))
|
))
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -501,6 +524,9 @@ class TestListNetwork(TestNetwork):
|
|||||||
self.network.dhcp_agent_hosting_networks = mock.Mock(
|
self.network.dhcp_agent_hosting_networks = mock.Mock(
|
||||||
return_value=self._network)
|
return_value=self._network)
|
||||||
|
|
||||||
|
# TestListTagMixin
|
||||||
|
self._tag_list_resource_mock = self.network.networks
|
||||||
|
|
||||||
def test_network_list_no_options(self):
|
def test_network_list_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = [
|
verifylist = [
|
||||||
@ -795,10 +821,11 @@ class TestListNetwork(TestNetwork):
|
|||||||
self.assertEqual(list(data), list(self.data))
|
self.assertEqual(list(data), list(self.data))
|
||||||
|
|
||||||
|
|
||||||
class TestSetNetwork(TestNetwork):
|
class TestSetNetwork(TestNetwork, _test_tag.TestSetTagMixin):
|
||||||
|
|
||||||
# The network to set.
|
# The network to set.
|
||||||
_network = network_fakes.FakeNetwork.create_one_network()
|
_network = network_fakes.FakeNetwork.create_one_network(
|
||||||
|
{'tags': ['green', 'red']})
|
||||||
qos_policy = (network_fakes.FakeNetworkQosPolicy.
|
qos_policy = (network_fakes.FakeNetworkQosPolicy.
|
||||||
create_one_qos_policy(attrs={'id': _network.qos_policy_id}))
|
create_one_qos_policy(attrs={'id': _network.qos_policy_id}))
|
||||||
|
|
||||||
@ -806,6 +833,7 @@ class TestSetNetwork(TestNetwork):
|
|||||||
super(TestSetNetwork, self).setUp()
|
super(TestSetNetwork, self).setUp()
|
||||||
|
|
||||||
self.network.update_network = mock.Mock(return_value=None)
|
self.network.update_network = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
|
|
||||||
self.network.find_network = mock.Mock(return_value=self._network)
|
self.network.find_network = mock.Mock(return_value=self._network)
|
||||||
self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy)
|
self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy)
|
||||||
@ -813,6 +841,11 @@ class TestSetNetwork(TestNetwork):
|
|||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = network.SetNetwork(self.app, self.namespace)
|
self.cmd = network.SetNetwork(self.app, self.namespace)
|
||||||
|
|
||||||
|
# TestSetTagMixin
|
||||||
|
self._tag_resource_name = 'network'
|
||||||
|
self._tag_test_resource = self._network
|
||||||
|
self._tag_update_resource_mock = self.network.update_network
|
||||||
|
|
||||||
def test_set_this(self):
|
def test_set_this(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
self._network.name,
|
self._network.name,
|
||||||
@ -902,9 +935,8 @@ class TestSetNetwork(TestNetwork):
|
|||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
attrs = {}
|
self.assertFalse(self.network.update_network.called)
|
||||||
self.network.update_network.assert_called_once_with(
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self._network, **attrs)
|
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
|
||||||
@ -990,3 +1022,40 @@ class TestShowNetwork(TestNetwork):
|
|||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
|
|
||||||
|
class TestUnsetNetwork(TestNetwork, _test_tag.TestUnsetTagMixin):
|
||||||
|
|
||||||
|
# The network to set.
|
||||||
|
_network = network_fakes.FakeNetwork.create_one_network(
|
||||||
|
{'tags': ['green', 'red']})
|
||||||
|
qos_policy = (network_fakes.FakeNetworkQosPolicy.
|
||||||
|
create_one_qos_policy(attrs={'id': _network.qos_policy_id}))
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestUnsetNetwork, self).setUp()
|
||||||
|
|
||||||
|
self.network.update_network = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
|
|
||||||
|
self.network.find_network = mock.Mock(return_value=self._network)
|
||||||
|
self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy)
|
||||||
|
|
||||||
|
# Get the command object to test
|
||||||
|
self.cmd = network.UnsetNetwork(self.app, self.namespace)
|
||||||
|
|
||||||
|
# TestUnsetNetwork
|
||||||
|
self._tag_resource_name = 'network'
|
||||||
|
self._tag_test_resource = self._network
|
||||||
|
self._tag_update_resource_mock = self.network.update_network
|
||||||
|
|
||||||
|
def test_unset_nothing(self):
|
||||||
|
arglist = [self._network.name, ]
|
||||||
|
verifylist = [('network', self._network.name), ]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.assertFalse(self.network.update_network.called)
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
@ -21,6 +21,7 @@ from osc_lib import utils
|
|||||||
from openstackclient.network.v2 import port
|
from openstackclient.network.v2 import port
|
||||||
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
|
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
|
||||||
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
|
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
|
||||||
|
from openstackclient.tests.unit.network.v2 import _test_tag
|
||||||
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
||||||
from openstackclient.tests.unit import utils as tests_utils
|
from openstackclient.tests.unit import utils as tests_utils
|
||||||
|
|
||||||
@ -35,7 +36,8 @@ class TestPort(network_fakes.TestNetworkV2):
|
|||||||
# Get a shortcut to the ProjectManager Mock
|
# Get a shortcut to the ProjectManager Mock
|
||||||
self.projects_mock = self.app.client_manager.identity.projects
|
self.projects_mock = self.app.client_manager.identity.projects
|
||||||
|
|
||||||
def _get_common_cols_data(self, fake_port):
|
@staticmethod
|
||||||
|
def _get_common_cols_data(fake_port):
|
||||||
columns = (
|
columns = (
|
||||||
'admin_state_up',
|
'admin_state_up',
|
||||||
'allowed_address_pairs',
|
'allowed_address_pairs',
|
||||||
@ -61,6 +63,7 @@ class TestPort(network_fakes.TestNetworkV2):
|
|||||||
'qos_policy_id',
|
'qos_policy_id',
|
||||||
'security_group_ids',
|
'security_group_ids',
|
||||||
'status',
|
'status',
|
||||||
|
'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = (
|
data = (
|
||||||
@ -88,19 +91,22 @@ class TestPort(network_fakes.TestNetworkV2):
|
|||||||
fake_port.qos_policy_id,
|
fake_port.qos_policy_id,
|
||||||
utils.format_list(fake_port.security_group_ids),
|
utils.format_list(fake_port.security_group_ids),
|
||||||
fake_port.status,
|
fake_port.status,
|
||||||
|
utils.format_list(fake_port.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
class TestCreatePort(TestPort):
|
class TestCreatePort(TestPort, _test_tag.TestCreateTagMixin):
|
||||||
|
|
||||||
_port = network_fakes.FakePort.create_one_port()
|
_port = network_fakes.FakePort.create_one_port()
|
||||||
|
columns, data = TestPort._get_common_cols_data(_port)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestCreatePort, self).setUp()
|
super(TestCreatePort, self).setUp()
|
||||||
|
|
||||||
self.network.create_port = mock.Mock(return_value=self._port)
|
self.network.create_port = mock.Mock(return_value=self._port)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
fake_net = network_fakes.FakeNetwork.create_one_network({
|
fake_net = network_fakes.FakeNetwork.create_one_network({
|
||||||
'id': self._port.network_id,
|
'id': self._port.network_id,
|
||||||
})
|
})
|
||||||
@ -110,6 +116,24 @@ class TestCreatePort(TestPort):
|
|||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = port.CreatePort(self.app, self.namespace)
|
self.cmd = port.CreatePort(self.app, self.namespace)
|
||||||
|
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_test_resource = self._port
|
||||||
|
self._tag_create_resource_mock = self.network.create_port
|
||||||
|
self._tag_create_required_arglist = [
|
||||||
|
'--network', self._port.network_id,
|
||||||
|
'test-port',
|
||||||
|
]
|
||||||
|
self._tag_create_required_verifylist = [
|
||||||
|
('network', self._port.network_id,),
|
||||||
|
('enable', True),
|
||||||
|
('name', 'test-port'),
|
||||||
|
]
|
||||||
|
self._tag_create_required_attrs = {
|
||||||
|
'admin_state_up': True,
|
||||||
|
'network_id': self._port.network_id,
|
||||||
|
'name': 'test-port',
|
||||||
|
}
|
||||||
|
|
||||||
def test_create_default_options(self):
|
def test_create_default_options(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'--network', self._port.network_id,
|
'--network', self._port.network_id,
|
||||||
@ -129,10 +153,10 @@ class TestCreatePort(TestPort):
|
|||||||
'network_id': self._port.network_id,
|
'network_id': self._port.network_id,
|
||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_full_options(self):
|
def test_create_full_options(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -166,7 +190,6 @@ class TestCreatePort(TestPort):
|
|||||||
('network', self._port.network_id),
|
('network', self._port.network_id),
|
||||||
('dns_name', '8.8.8.8'),
|
('dns_name', '8.8.8.8'),
|
||||||
('name', 'test-port'),
|
('name', 'test-port'),
|
||||||
|
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
@ -187,9 +210,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_invalid_json_binding_profile(self):
|
def test_create_invalid_json_binding_profile(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -239,9 +261,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_with_security_group(self):
|
def test_create_with_security_group(self):
|
||||||
secgroup = network_fakes.FakeSecurityGroup.create_one_security_group()
|
secgroup = network_fakes.FakeSecurityGroup.create_one_security_group()
|
||||||
@ -269,9 +290,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_port_with_dns_name(self):
|
def test_create_port_with_dns_name(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -296,9 +316,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_with_security_groups(self):
|
def test_create_with_security_groups(self):
|
||||||
sg_1 = network_fakes.FakeSecurityGroup.create_one_security_group()
|
sg_1 = network_fakes.FakeSecurityGroup.create_one_security_group()
|
||||||
@ -327,9 +346,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_with_no_security_groups(self):
|
def test_create_with_no_security_groups(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -354,9 +372,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_port_with_allowed_address_pair_ipaddr(self):
|
def test_create_port_with_allowed_address_pair_ipaddr(self):
|
||||||
pairs = [{'ip_address': '192.168.1.123'},
|
pairs = [{'ip_address': '192.168.1.123'},
|
||||||
@ -385,9 +402,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_port_with_allowed_address_pair(self):
|
def test_create_port_with_allowed_address_pair(self):
|
||||||
pairs = [{'ip_address': '192.168.1.123',
|
pairs = [{'ip_address': '192.168.1.123',
|
||||||
@ -422,9 +438,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_port_with_qos(self):
|
def test_create_port_with_qos(self):
|
||||||
qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
|
qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
|
||||||
@ -451,9 +466,8 @@ class TestCreatePort(TestPort):
|
|||||||
'name': 'test-port',
|
'name': 'test-port',
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
def test_create_port_security_enabled(self):
|
def test_create_port_security_enabled(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -583,7 +597,7 @@ class TestDeletePort(TestPort):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestListPort(TestPort):
|
class TestListPort(TestPort, _test_tag.TestListTagMixin):
|
||||||
|
|
||||||
_ports = network_fakes.FakePort.create_ports(count=3)
|
_ports = network_fakes.FakePort.create_ports(count=3)
|
||||||
|
|
||||||
@ -603,6 +617,7 @@ class TestListPort(TestPort):
|
|||||||
'Status',
|
'Status',
|
||||||
'Security Groups',
|
'Security Groups',
|
||||||
'Device Owner',
|
'Device Owner',
|
||||||
|
'Tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
@ -625,6 +640,7 @@ class TestListPort(TestPort):
|
|||||||
prt.status,
|
prt.status,
|
||||||
utils.format_list(prt.security_group_ids),
|
utils.format_list(prt.security_group_ids),
|
||||||
prt.device_owner,
|
prt.device_owner,
|
||||||
|
utils.format_list(prt.tags),
|
||||||
))
|
))
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -642,6 +658,8 @@ class TestListPort(TestPort):
|
|||||||
self.network.find_router = mock.Mock(return_value=fake_router)
|
self.network.find_router = mock.Mock(return_value=fake_router)
|
||||||
self.network.find_network = mock.Mock(return_value=fake_network)
|
self.network.find_network = mock.Mock(return_value=fake_network)
|
||||||
self.app.client_manager.compute = mock.Mock()
|
self.app.client_manager.compute = mock.Mock()
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_list_resource_mock = self.network.ports
|
||||||
|
|
||||||
def test_port_list_no_options(self):
|
def test_port_list_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
@ -902,9 +920,9 @@ class TestListPort(TestPort):
|
|||||||
self.assertEqual(self.data, list(data))
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
|
||||||
class TestSetPort(TestPort):
|
class TestSetPort(TestPort, _test_tag.TestSetTagMixin):
|
||||||
|
|
||||||
_port = network_fakes.FakePort.create_one_port()
|
_port = network_fakes.FakePort.create_one_port({'tags': ['green', 'red']})
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestSetPort, self).setUp()
|
super(TestSetPort, self).setUp()
|
||||||
@ -912,9 +930,14 @@ class TestSetPort(TestPort):
|
|||||||
self.network.find_subnet = mock.Mock(return_value=self.fake_subnet)
|
self.network.find_subnet = mock.Mock(return_value=self.fake_subnet)
|
||||||
self.network.find_port = mock.Mock(return_value=self._port)
|
self.network.find_port = mock.Mock(return_value=self._port)
|
||||||
self.network.update_port = mock.Mock(return_value=None)
|
self.network.update_port = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = port.SetPort(self.app, self.namespace)
|
self.cmd = port.SetPort(self.app, self.namespace)
|
||||||
|
# TestSetTagMixin
|
||||||
|
self._tag_resource_name = 'port'
|
||||||
|
self._tag_test_resource = self._port
|
||||||
|
self._tag_update_resource_mock = self.network.update_port
|
||||||
|
|
||||||
def test_set_port_defaults(self):
|
def test_set_port_defaults(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -926,8 +949,8 @@ class TestSetPort(TestPort):
|
|||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
attrs = {}
|
self.assertFalse(self.network.update_port.called)
|
||||||
self.network.update_port.assert_called_once_with(self._port, **attrs)
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_set_port_fixed_ip(self):
|
def test_set_port_fixed_ip(self):
|
||||||
@ -1412,6 +1435,7 @@ class TestShowPort(TestPort):
|
|||||||
|
|
||||||
# The port to show.
|
# The port to show.
|
||||||
_port = network_fakes.FakePort.create_one_port()
|
_port = network_fakes.FakePort.create_one_port()
|
||||||
|
columns, data = TestPort._get_common_cols_data(_port)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestShowPort, self).setUp()
|
super(TestShowPort, self).setUp()
|
||||||
@ -1442,12 +1466,11 @@ class TestShowPort(TestPort):
|
|||||||
self.network.find_port.assert_called_once_with(
|
self.network.find_port.assert_called_once_with(
|
||||||
self._port.name, ignore_missing=False)
|
self._port.name, ignore_missing=False)
|
||||||
|
|
||||||
ref_columns, ref_data = self._get_common_cols_data(self._port)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(ref_columns, columns)
|
self.assertEqual(self.data, data)
|
||||||
self.assertEqual(ref_data, data)
|
|
||||||
|
|
||||||
|
|
||||||
class TestUnsetPort(TestPort):
|
class TestUnsetPort(TestPort, _test_tag.TestUnsetTagMixin):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestUnsetPort, self).setUp()
|
super(TestUnsetPort, self).setUp()
|
||||||
@ -1456,14 +1479,20 @@ class TestUnsetPort(TestPort):
|
|||||||
'ip_address': '0.0.0.1'},
|
'ip_address': '0.0.0.1'},
|
||||||
{'subnet_id': '042eb10a-3a18-4658-ab-cf47c8d03152',
|
{'subnet_id': '042eb10a-3a18-4658-ab-cf47c8d03152',
|
||||||
'ip_address': '1.0.0.0'}],
|
'ip_address': '1.0.0.0'}],
|
||||||
'binding:profile': {'batman': 'Joker', 'Superman': 'LexLuthor'}})
|
'binding:profile': {'batman': 'Joker', 'Superman': 'LexLuthor'},
|
||||||
|
'tags': ['green', 'red'], })
|
||||||
self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet(
|
self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet(
|
||||||
{'id': '042eb10a-3a18-4658-ab-cf47c8d03152'})
|
{'id': '042eb10a-3a18-4658-ab-cf47c8d03152'})
|
||||||
self.network.find_subnet = mock.Mock(return_value=self.fake_subnet)
|
self.network.find_subnet = mock.Mock(return_value=self.fake_subnet)
|
||||||
self.network.find_port = mock.Mock(return_value=self._testport)
|
self.network.find_port = mock.Mock(return_value=self._testport)
|
||||||
self.network.update_port = mock.Mock(return_value=None)
|
self.network.update_port = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = port.UnsetPort(self.app, self.namespace)
|
self.cmd = port.UnsetPort(self.app, self.namespace)
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_resource_name = 'port'
|
||||||
|
self._tag_test_resource = self._testport
|
||||||
|
self._tag_update_resource_mock = self.network.update_port
|
||||||
|
|
||||||
def test_unset_port_parameters(self):
|
def test_unset_port_parameters(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
|
@ -19,6 +19,7 @@ from osc_lib import utils as osc_utils
|
|||||||
|
|
||||||
from openstackclient.network.v2 import router
|
from openstackclient.network.v2 import router
|
||||||
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
|
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
|
||||||
|
from openstackclient.tests.unit.network.v2 import _test_tag
|
||||||
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
||||||
from openstackclient.tests.unit import utils as tests_utils
|
from openstackclient.tests.unit import utils as tests_utils
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ class TestAddSubnetToRouter(TestRouter):
|
|||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
|
||||||
class TestCreateRouter(TestRouter):
|
class TestCreateRouter(TestRouter, _test_tag.TestCreateTagMixin):
|
||||||
|
|
||||||
# The new router created.
|
# The new router created.
|
||||||
new_router = network_fakes.FakeRouter.create_one_router()
|
new_router = network_fakes.FakeRouter.create_one_router()
|
||||||
@ -129,6 +130,7 @@ class TestCreateRouter(TestRouter):
|
|||||||
'project_id',
|
'project_id',
|
||||||
'routes',
|
'routes',
|
||||||
'status',
|
'status',
|
||||||
|
'tags',
|
||||||
)
|
)
|
||||||
data = (
|
data = (
|
||||||
router._format_admin_state(new_router.admin_state_up),
|
router._format_admin_state(new_router.admin_state_up),
|
||||||
@ -143,22 +145,42 @@ class TestCreateRouter(TestRouter):
|
|||||||
new_router.tenant_id,
|
new_router.tenant_id,
|
||||||
router._format_routes(new_router.routes),
|
router._format_routes(new_router.routes),
|
||||||
new_router.status,
|
new_router.status,
|
||||||
|
osc_utils.format_list(new_router.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestCreateRouter, self).setUp()
|
super(TestCreateRouter, self).setUp()
|
||||||
|
|
||||||
self.network.create_router = mock.Mock(return_value=self.new_router)
|
self.network.create_router = mock.Mock(return_value=self.new_router)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = router.CreateRouter(self.app, self.namespace)
|
self.cmd = router.CreateRouter(self.app, self.namespace)
|
||||||
|
|
||||||
|
# TestCreateTagMixin
|
||||||
|
self._tag_test_resource = self.new_router
|
||||||
|
self._tag_create_resource_mock = self.network.create_router
|
||||||
|
self._tag_create_required_arglist = [
|
||||||
|
self.new_router.name,
|
||||||
|
]
|
||||||
|
self._tag_create_required_verifylist = [
|
||||||
|
('name', self.new_router.name),
|
||||||
|
('enable', True),
|
||||||
|
('distributed', False),
|
||||||
|
('ha', False),
|
||||||
|
]
|
||||||
|
self._tag_create_required_attrs = {
|
||||||
|
'admin_state_up': True,
|
||||||
|
'name': self.new_router.name,
|
||||||
|
}
|
||||||
|
|
||||||
def test_create_no_options(self):
|
def test_create_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = []
|
verifylist = []
|
||||||
|
|
||||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
||||||
self.cmd, arglist, verifylist)
|
self.cmd, arglist, verifylist)
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
|
|
||||||
def test_create_default_options(self):
|
def test_create_default_options(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -178,6 +200,7 @@ class TestCreateRouter(TestRouter):
|
|||||||
'admin_state_up': True,
|
'admin_state_up': True,
|
||||||
'name': self.new_router.name,
|
'name': self.new_router.name,
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
@ -345,7 +368,7 @@ class TestDeleteRouter(TestRouter):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestListRouter(TestRouter):
|
class TestListRouter(TestRouter, _test_tag.TestListTagMixin):
|
||||||
|
|
||||||
# The routers going to be listed up.
|
# The routers going to be listed up.
|
||||||
routers = network_fakes.FakeRouter.create_routers(count=3)
|
routers = network_fakes.FakeRouter.create_routers(count=3)
|
||||||
@ -363,11 +386,13 @@ class TestListRouter(TestRouter):
|
|||||||
columns_long = columns + (
|
columns_long = columns + (
|
||||||
'Routes',
|
'Routes',
|
||||||
'External gateway info',
|
'External gateway info',
|
||||||
'Availability zones'
|
'Availability zones',
|
||||||
|
'Tags',
|
||||||
)
|
)
|
||||||
columns_long_no_az = columns + (
|
columns_long_no_az = columns + (
|
||||||
'Routes',
|
'Routes',
|
||||||
'External gateway info',
|
'External gateway info',
|
||||||
|
'Tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
@ -404,6 +429,7 @@ class TestListRouter(TestRouter):
|
|||||||
router._format_routes(r.routes),
|
router._format_routes(r.routes),
|
||||||
router._format_external_gateway_info(r.external_gateway_info),
|
router._format_external_gateway_info(r.external_gateway_info),
|
||||||
osc_utils.format_list(r.availability_zones),
|
osc_utils.format_list(r.availability_zones),
|
||||||
|
osc_utils.format_list(r.tags),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
data_long_no_az = []
|
data_long_no_az = []
|
||||||
@ -413,6 +439,7 @@ class TestListRouter(TestRouter):
|
|||||||
data[i] + (
|
data[i] + (
|
||||||
router._format_routes(r.routes),
|
router._format_routes(r.routes),
|
||||||
router._format_external_gateway_info(r.external_gateway_info),
|
router._format_external_gateway_info(r.external_gateway_info),
|
||||||
|
osc_utils.format_list(r.tags),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -432,6 +459,9 @@ class TestListRouter(TestRouter):
|
|||||||
self.network.get_agent = mock.Mock(return_value=self._testagent)
|
self.network.get_agent = mock.Mock(return_value=self._testagent)
|
||||||
self.network.get_router = mock.Mock(return_value=self.routers[0])
|
self.network.get_router = mock.Mock(return_value=self.routers[0])
|
||||||
|
|
||||||
|
# TestListTagMixin
|
||||||
|
self._tag_list_resource_mock = self.network.routers
|
||||||
|
|
||||||
def test_router_list_no_options(self):
|
def test_router_list_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = [
|
verifylist = [
|
||||||
@ -684,26 +714,33 @@ class TestRemoveSubnetFromRouter(TestRouter):
|
|||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
|
||||||
class TestSetRouter(TestRouter):
|
class TestSetRouter(TestRouter, _test_tag.TestSetTagMixin):
|
||||||
|
|
||||||
# The router to set.
|
# The router to set.
|
||||||
_default_route = {'destination': '10.20.20.0/24', 'nexthop': '10.20.30.1'}
|
_default_route = {'destination': '10.20.20.0/24', 'nexthop': '10.20.30.1'}
|
||||||
_network = network_fakes.FakeNetwork.create_one_network()
|
_network = network_fakes.FakeNetwork.create_one_network()
|
||||||
_subnet = network_fakes.FakeSubnet.create_one_subnet()
|
_subnet = network_fakes.FakeSubnet.create_one_subnet()
|
||||||
_router = network_fakes.FakeRouter.create_one_router(
|
_router = network_fakes.FakeRouter.create_one_router(
|
||||||
attrs={'routes': [_default_route]}
|
attrs={'routes': [_default_route],
|
||||||
|
'tags': ['green', 'red']}
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestSetRouter, self).setUp()
|
super(TestSetRouter, self).setUp()
|
||||||
self.network.router_add_gateway = mock.Mock()
|
self.network.router_add_gateway = mock.Mock()
|
||||||
self.network.update_router = mock.Mock(return_value=None)
|
self.network.update_router = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
self.network.find_router = mock.Mock(return_value=self._router)
|
self.network.find_router = mock.Mock(return_value=self._router)
|
||||||
self.network.find_network = mock.Mock(return_value=self._network)
|
self.network.find_network = mock.Mock(return_value=self._network)
|
||||||
self.network.find_subnet = mock.Mock(return_value=self._subnet)
|
self.network.find_subnet = mock.Mock(return_value=self._subnet)
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = router.SetRouter(self.app, self.namespace)
|
self.cmd = router.SetRouter(self.app, self.namespace)
|
||||||
|
|
||||||
|
# TestSetTagMixin
|
||||||
|
self._tag_resource_name = 'router'
|
||||||
|
self._tag_test_resource = self._router
|
||||||
|
self._tag_update_resource_mock = self.network.update_router
|
||||||
|
|
||||||
def test_set_this(self):
|
def test_set_this(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
self._router.name,
|
self._router.name,
|
||||||
@ -902,9 +939,8 @@ class TestSetRouter(TestRouter):
|
|||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
attrs = {}
|
self.assertFalse(self.network.update_router.called)
|
||||||
self.network.update_router.assert_called_once_with(
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self._router, **attrs)
|
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_wrong_gateway_params(self):
|
def test_wrong_gateway_params(self):
|
||||||
@ -1030,6 +1066,7 @@ class TestShowRouter(TestRouter):
|
|||||||
'project_id',
|
'project_id',
|
||||||
'routes',
|
'routes',
|
||||||
'status',
|
'status',
|
||||||
|
'tags',
|
||||||
)
|
)
|
||||||
data = (
|
data = (
|
||||||
router._format_admin_state(_router.admin_state_up),
|
router._format_admin_state(_router.admin_state_up),
|
||||||
@ -1044,6 +1081,7 @@ class TestShowRouter(TestRouter):
|
|||||||
_router.tenant_id,
|
_router.tenant_id,
|
||||||
router._format_routes(_router.routes),
|
router._format_routes(_router.routes),
|
||||||
_router.status,
|
_router.status,
|
||||||
|
osc_utils.format_list(_router.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -1086,12 +1124,18 @@ class TestUnsetRouter(TestRouter):
|
|||||||
{'routes': [{"destination": "192.168.101.1/24",
|
{'routes': [{"destination": "192.168.101.1/24",
|
||||||
"nexthop": "172.24.4.3"},
|
"nexthop": "172.24.4.3"},
|
||||||
{"destination": "192.168.101.2/24",
|
{"destination": "192.168.101.2/24",
|
||||||
"nexthop": "172.24.4.3"}], })
|
"nexthop": "172.24.4.3"}],
|
||||||
|
'tags': ['green', 'red'], })
|
||||||
self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet()
|
self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet()
|
||||||
self.network.find_router = mock.Mock(return_value=self._testrouter)
|
self.network.find_router = mock.Mock(return_value=self._testrouter)
|
||||||
self.network.update_router = mock.Mock(return_value=None)
|
self.network.update_router = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = router.UnsetRouter(self.app, self.namespace)
|
self.cmd = router.UnsetRouter(self.app, self.namespace)
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_resource_name = 'router'
|
||||||
|
self._tag_test_resource = self._testrouter
|
||||||
|
self._tag_update_resource_mock = self.network.update_router
|
||||||
|
|
||||||
def test_unset_router_params(self):
|
def test_unset_router_params(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
|
@ -19,6 +19,7 @@ from osc_lib import utils
|
|||||||
|
|
||||||
from openstackclient.network.v2 import subnet as subnet_v2
|
from openstackclient.network.v2 import subnet as subnet_v2
|
||||||
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
|
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
|
||||||
|
from openstackclient.tests.unit.network.v2 import _test_tag
|
||||||
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
||||||
from openstackclient.tests.unit import utils as tests_utils
|
from openstackclient.tests.unit import utils as tests_utils
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ class TestSubnet(network_fakes.TestNetworkV2):
|
|||||||
self.domains_mock = self.app.client_manager.identity.domains
|
self.domains_mock = self.app.client_manager.identity.domains
|
||||||
|
|
||||||
|
|
||||||
class TestCreateSubnet(TestSubnet):
|
class TestCreateSubnet(TestSubnet, _test_tag.TestCreateTagMixin):
|
||||||
|
|
||||||
project = identity_fakes_v3.FakeProject.create_one_project()
|
project = identity_fakes_v3.FakeProject.create_one_project()
|
||||||
domain = identity_fakes_v3.FakeDomain.create_one_domain()
|
domain = identity_fakes_v3.FakeDomain.create_one_domain()
|
||||||
@ -125,6 +126,7 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
'segment_id',
|
'segment_id',
|
||||||
'service_types',
|
'service_types',
|
||||||
'subnetpool_id',
|
'subnetpool_id',
|
||||||
|
'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = (
|
data = (
|
||||||
@ -145,6 +147,7 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
_subnet.segment_id,
|
_subnet.segment_id,
|
||||||
utils.format_list(_subnet.service_types),
|
utils.format_list(_subnet.service_types),
|
||||||
_subnet.subnetpool_id,
|
_subnet.subnetpool_id,
|
||||||
|
utils.format_list(_subnet.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
data_subnet_pool = (
|
data_subnet_pool = (
|
||||||
@ -165,6 +168,7 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
_subnet_from_pool.segment_id,
|
_subnet_from_pool.segment_id,
|
||||||
utils.format_list(_subnet_from_pool.service_types),
|
utils.format_list(_subnet_from_pool.service_types),
|
||||||
_subnet_from_pool.subnetpool_id,
|
_subnet_from_pool.subnetpool_id,
|
||||||
|
utils.format_list(_subnet.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
data_ipv6 = (
|
data_ipv6 = (
|
||||||
@ -185,6 +189,7 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
_subnet_ipv6.segment_id,
|
_subnet_ipv6.segment_id,
|
||||||
utils.format_list(_subnet_ipv6.service_types),
|
utils.format_list(_subnet_ipv6.service_types),
|
||||||
_subnet_ipv6.subnetpool_id,
|
_subnet_ipv6.subnetpool_id,
|
||||||
|
utils.format_list(_subnet.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -197,6 +202,8 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
self.domains_mock.get.return_value = self.domain
|
self.domains_mock.get.return_value = self.domain
|
||||||
|
|
||||||
# Mock SDK calls for all tests.
|
# Mock SDK calls for all tests.
|
||||||
|
self.network.create_subnet = mock.Mock(return_value=self._subnet)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
self.network.find_network = mock.Mock(return_value=self._network)
|
self.network.find_network = mock.Mock(return_value=self._network)
|
||||||
self.network.find_segment = mock.Mock(
|
self.network.find_segment = mock.Mock(
|
||||||
return_value=self._network_segment
|
return_value=self._network_segment
|
||||||
@ -205,6 +212,28 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
return_value=self._subnet_pool
|
return_value=self._subnet_pool
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_test_resource = self._subnet
|
||||||
|
self._tag_create_resource_mock = self.network.create_subnet
|
||||||
|
self._tag_create_required_arglist = [
|
||||||
|
"--subnet-range", self._subnet.cidr,
|
||||||
|
"--network", self._subnet.network_id,
|
||||||
|
self._subnet.name,
|
||||||
|
]
|
||||||
|
self._tag_create_required_verifylist = [
|
||||||
|
('name', self._subnet.name),
|
||||||
|
('subnet_range', self._subnet.cidr),
|
||||||
|
('network', self._subnet.network_id),
|
||||||
|
('ip_version', self._subnet.ip_version),
|
||||||
|
('gateway', 'auto'),
|
||||||
|
]
|
||||||
|
self._tag_create_required_attrs = {
|
||||||
|
'cidr': self._subnet.cidr,
|
||||||
|
'ip_version': self._subnet.ip_version,
|
||||||
|
'name': self._subnet.name,
|
||||||
|
'network_id': self._subnet.network_id,
|
||||||
|
}
|
||||||
|
|
||||||
def test_create_no_options(self):
|
def test_create_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = []
|
verifylist = []
|
||||||
@ -213,10 +242,11 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
# throw a "ParserExecption"
|
# throw a "ParserExecption"
|
||||||
self.assertRaises(tests_utils.ParserException,
|
self.assertRaises(tests_utils.ParserException,
|
||||||
self.check_parser, self.cmd, arglist, verifylist)
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
self.assertFalse(self.network.create_subnet.called)
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
|
|
||||||
def test_create_default_options(self):
|
def test_create_default_options(self):
|
||||||
# Mock SDK calls for this test.
|
# Mock SDK calls for this test.
|
||||||
self.network.create_subnet = mock.Mock(return_value=self._subnet)
|
|
||||||
self._network.id = self._subnet.network_id
|
self._network.id = self._subnet.network_id
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -230,7 +260,6 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
('network', self._subnet.network_id),
|
('network', self._subnet.network_id),
|
||||||
('ip_version', self._subnet.ip_version),
|
('ip_version', self._subnet.ip_version),
|
||||||
('gateway', 'auto'),
|
('gateway', 'auto'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
@ -242,13 +271,14 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
'name': self._subnet.name,
|
'name': self._subnet.name,
|
||||||
'network_id': self._subnet.network_id,
|
'network_id': self._subnet.network_id,
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
def test_create_from_subnet_pool_options(self):
|
def test_create_from_subnet_pool_options(self):
|
||||||
# Mock SDK calls for this test.
|
# Mock SDK calls for this test.
|
||||||
self.network.create_subnet = \
|
self.network.create_subnet.return_value = self._subnet_from_pool
|
||||||
mock.Mock(return_value=self._subnet_from_pool)
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
self._network.id = self._subnet_from_pool.network_id
|
self._network.id = self._subnet_from_pool.network_id
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -309,7 +339,7 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
|
|
||||||
def test_create_options_subnet_range_ipv6(self):
|
def test_create_options_subnet_range_ipv6(self):
|
||||||
# Mock SDK calls for this test.
|
# Mock SDK calls for this test.
|
||||||
self.network.create_subnet = mock.Mock(return_value=self._subnet_ipv6)
|
self.network.create_subnet.return_value = self._subnet_ipv6
|
||||||
self._network.id = self._subnet_ipv6.network_id
|
self._network.id = self._subnet_ipv6.network_id
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -376,12 +406,12 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
'allocation_pools': self._subnet_ipv6.allocation_pools,
|
'allocation_pools': self._subnet_ipv6.allocation_pools,
|
||||||
'service_types': self._subnet_ipv6.service_types,
|
'service_types': self._subnet_ipv6.service_types,
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data_ipv6, data)
|
self.assertEqual(self.data_ipv6, data)
|
||||||
|
|
||||||
def test_create_with_network_segment(self):
|
def test_create_with_network_segment(self):
|
||||||
# Mock SDK calls for this test.
|
# Mock SDK calls for this test.
|
||||||
self.network.create_subnet = mock.Mock(return_value=self._subnet)
|
|
||||||
self._network.id = self._subnet.network_id
|
self._network.id = self._subnet.network_id
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -410,12 +440,12 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
'network_id': self._subnet.network_id,
|
'network_id': self._subnet.network_id,
|
||||||
'segment_id': self._network_segment.id,
|
'segment_id': self._network_segment.id,
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
def test_create_with_description(self):
|
def test_create_with_description(self):
|
||||||
# Mock SDK calls for this test.
|
# Mock SDK calls for this test.
|
||||||
self.network.create_subnet = mock.Mock(return_value=self._subnet)
|
|
||||||
self._network.id = self._subnet.network_id
|
self._network.id = self._subnet.network_id
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -444,6 +474,7 @@ class TestCreateSubnet(TestSubnet):
|
|||||||
'network_id': self._subnet.network_id,
|
'network_id': self._subnet.network_id,
|
||||||
'description': self._subnet.description,
|
'description': self._subnet.description,
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
@ -527,7 +558,7 @@ class TestDeleteSubnet(TestSubnet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestListSubnet(TestSubnet):
|
class TestListSubnet(TestSubnet, _test_tag.TestListTagMixin):
|
||||||
# The subnets going to be listed up.
|
# The subnets going to be listed up.
|
||||||
_subnet = network_fakes.FakeSubnet.create_subnets(count=3)
|
_subnet = network_fakes.FakeSubnet.create_subnets(count=3)
|
||||||
|
|
||||||
@ -546,6 +577,7 @@ class TestListSubnet(TestSubnet):
|
|||||||
'IP Version',
|
'IP Version',
|
||||||
'Gateway',
|
'Gateway',
|
||||||
'Service Types',
|
'Service Types',
|
||||||
|
'Tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
@ -572,6 +604,7 @@ class TestListSubnet(TestSubnet):
|
|||||||
subnet.ip_version,
|
subnet.ip_version,
|
||||||
subnet.gateway_ip,
|
subnet.gateway_ip,
|
||||||
utils.format_list(subnet.service_types),
|
utils.format_list(subnet.service_types),
|
||||||
|
utils.format_list(subnet.tags),
|
||||||
))
|
))
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -582,6 +615,9 @@ class TestListSubnet(TestSubnet):
|
|||||||
|
|
||||||
self.network.subnets = mock.Mock(return_value=self._subnet)
|
self.network.subnets = mock.Mock(return_value=self._subnet)
|
||||||
|
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_list_resource_mock = self.network.subnets
|
||||||
|
|
||||||
def test_subnet_list_no_options(self):
|
def test_subnet_list_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = [
|
verifylist = [
|
||||||
@ -802,15 +838,21 @@ class TestListSubnet(TestSubnet):
|
|||||||
self.assertEqual(self.data, list(data))
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
|
||||||
class TestSetSubnet(TestSubnet):
|
class TestSetSubnet(TestSubnet, _test_tag.TestSetTagMixin):
|
||||||
|
|
||||||
_subnet = network_fakes.FakeSubnet.create_one_subnet()
|
_subnet = network_fakes.FakeSubnet.create_one_subnet(
|
||||||
|
{'tags': ['green', 'red']})
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestSetSubnet, self).setUp()
|
super(TestSetSubnet, self).setUp()
|
||||||
self.network.update_subnet = mock.Mock(return_value=None)
|
self.network.update_subnet = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
self.network.find_subnet = mock.Mock(return_value=self._subnet)
|
self.network.find_subnet = mock.Mock(return_value=self._subnet)
|
||||||
self.cmd = subnet_v2.SetSubnet(self.app, self.namespace)
|
self.cmd = subnet_v2.SetSubnet(self.app, self.namespace)
|
||||||
|
# TestSetTagMixin
|
||||||
|
self._tag_resource_name = 'subnet'
|
||||||
|
self._tag_test_resource = self._subnet
|
||||||
|
self._tag_update_resource_mock = self.network.update_subnet
|
||||||
|
|
||||||
def test_set_this(self):
|
def test_set_this(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -867,8 +909,8 @@ class TestSetSubnet(TestSubnet):
|
|||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
attrs = {}
|
self.assertFalse(self.network.update_subnet.called)
|
||||||
self.network.update_subnet.assert_called_with(self._subnet, **attrs)
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_append_options(self):
|
def test_append_options(self):
|
||||||
@ -982,6 +1024,7 @@ class TestShowSubnet(TestSubnet):
|
|||||||
'segment_id',
|
'segment_id',
|
||||||
'service_types',
|
'service_types',
|
||||||
'subnetpool_id',
|
'subnetpool_id',
|
||||||
|
'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = (
|
data = (
|
||||||
@ -1002,6 +1045,7 @@ class TestShowSubnet(TestSubnet):
|
|||||||
_subnet.segment_id,
|
_subnet.segment_id,
|
||||||
utils.format_list(_subnet.service_types),
|
utils.format_list(_subnet.service_types),
|
||||||
_subnet.subnetpool_id,
|
_subnet.subnetpool_id,
|
||||||
|
utils.format_list(_subnet.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -1039,7 +1083,7 @@ class TestShowSubnet(TestSubnet):
|
|||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
|
|
||||||
class TestUnsetSubnet(TestSubnet):
|
class TestUnsetSubnet(TestSubnet, _test_tag.TestUnsetTagMixin):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestUnsetSubnet, self).setUp()
|
super(TestUnsetSubnet, self).setUp()
|
||||||
@ -1055,11 +1099,17 @@ class TestUnsetSubnet(TestSubnet):
|
|||||||
{'start': '8.8.8.160',
|
{'start': '8.8.8.160',
|
||||||
'end': '8.8.8.170'}],
|
'end': '8.8.8.170'}],
|
||||||
'service_types': ['network:router_gateway',
|
'service_types': ['network:router_gateway',
|
||||||
'network:floatingip_agent_gateway'], })
|
'network:floatingip_agent_gateway'],
|
||||||
|
'tags': ['green', 'red'], })
|
||||||
self.network.find_subnet = mock.Mock(return_value=self._testsubnet)
|
self.network.find_subnet = mock.Mock(return_value=self._testsubnet)
|
||||||
self.network.update_subnet = mock.Mock(return_value=None)
|
self.network.update_subnet = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = subnet_v2.UnsetSubnet(self.app, self.namespace)
|
self.cmd = subnet_v2.UnsetSubnet(self.app, self.namespace)
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_resource_name = 'subnet'
|
||||||
|
self._tag_test_resource = self._testsubnet
|
||||||
|
self._tag_update_resource_mock = self.network.update_subnet
|
||||||
|
|
||||||
def test_unset_subnet_params(self):
|
def test_unset_subnet_params(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
|
@ -20,6 +20,7 @@ from osc_lib import utils
|
|||||||
|
|
||||||
from openstackclient.network.v2 import subnet_pool
|
from openstackclient.network.v2 import subnet_pool
|
||||||
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
|
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
|
||||||
|
from openstackclient.tests.unit.network.v2 import _test_tag
|
||||||
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
|
||||||
from openstackclient.tests.unit import utils as tests_utils
|
from openstackclient.tests.unit import utils as tests_utils
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ class TestSubnetPool(network_fakes.TestNetworkV2):
|
|||||||
self.domains_mock = self.app.client_manager.identity.domains
|
self.domains_mock = self.app.client_manager.identity.domains
|
||||||
|
|
||||||
|
|
||||||
class TestCreateSubnetPool(TestSubnetPool):
|
class TestCreateSubnetPool(TestSubnetPool, _test_tag.TestCreateTagMixin):
|
||||||
|
|
||||||
project = identity_fakes_v3.FakeProject.create_one_project()
|
project = identity_fakes_v3.FakeProject.create_one_project()
|
||||||
domain = identity_fakes_v3.FakeDomain.create_one_domain()
|
domain = identity_fakes_v3.FakeDomain.create_one_domain()
|
||||||
@ -60,6 +61,7 @@ class TestCreateSubnetPool(TestSubnetPool):
|
|||||||
'prefixes',
|
'prefixes',
|
||||||
'project_id',
|
'project_id',
|
||||||
'shared',
|
'shared',
|
||||||
|
'tags',
|
||||||
)
|
)
|
||||||
data = (
|
data = (
|
||||||
_subnet_pool.address_scope_id,
|
_subnet_pool.address_scope_id,
|
||||||
@ -75,6 +77,7 @@ class TestCreateSubnetPool(TestSubnetPool):
|
|||||||
utils.format_list(_subnet_pool.prefixes),
|
utils.format_list(_subnet_pool.prefixes),
|
||||||
_subnet_pool.project_id,
|
_subnet_pool.project_id,
|
||||||
_subnet_pool.shared,
|
_subnet_pool.shared,
|
||||||
|
utils.format_list(_subnet_pool.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -82,6 +85,7 @@ class TestCreateSubnetPool(TestSubnetPool):
|
|||||||
|
|
||||||
self.network.create_subnet_pool = mock.Mock(
|
self.network.create_subnet_pool = mock.Mock(
|
||||||
return_value=self._subnet_pool)
|
return_value=self._subnet_pool)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = subnet_pool.CreateSubnetPool(self.app, self.namespace)
|
self.cmd = subnet_pool.CreateSubnetPool(self.app, self.namespace)
|
||||||
@ -92,12 +96,29 @@ class TestCreateSubnetPool(TestSubnetPool):
|
|||||||
self.projects_mock.get.return_value = self.project
|
self.projects_mock.get.return_value = self.project
|
||||||
self.domains_mock.get.return_value = self.domain
|
self.domains_mock.get.return_value = self.domain
|
||||||
|
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_test_resource = self._subnet_pool
|
||||||
|
self._tag_create_resource_mock = self.network.create_subnet_pool
|
||||||
|
self._tag_create_required_arglist = [
|
||||||
|
'--pool-prefix', '10.0.10.0/24',
|
||||||
|
self._subnet_pool.name,
|
||||||
|
]
|
||||||
|
self._tag_create_required_verifylist = [
|
||||||
|
('prefixes', ['10.0.10.0/24']),
|
||||||
|
('name', self._subnet_pool.name),
|
||||||
|
]
|
||||||
|
self._tag_create_required_attrs = {
|
||||||
|
'prefixes': ['10.0.10.0/24'],
|
||||||
|
'name': self._subnet_pool.name,
|
||||||
|
}
|
||||||
|
|
||||||
def test_create_no_options(self):
|
def test_create_no_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = []
|
verifylist = []
|
||||||
|
|
||||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
||||||
self.cmd, arglist, verifylist)
|
self.cmd, arglist, verifylist)
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
|
|
||||||
def test_create_no_pool_prefix(self):
|
def test_create_no_pool_prefix(self):
|
||||||
"""Make sure --pool-prefix is a required argument"""
|
"""Make sure --pool-prefix is a required argument"""
|
||||||
@ -127,6 +148,7 @@ class TestCreateSubnetPool(TestSubnetPool):
|
|||||||
'prefixes': ['10.0.10.0/24'],
|
'prefixes': ['10.0.10.0/24'],
|
||||||
'name': self._subnet_pool.name,
|
'name': self._subnet_pool.name,
|
||||||
})
|
})
|
||||||
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
@ -374,7 +396,7 @@ class TestDeleteSubnetPool(TestSubnetPool):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestListSubnetPool(TestSubnetPool):
|
class TestListSubnetPool(TestSubnetPool, _test_tag.TestListTagMixin):
|
||||||
# The subnet pools going to be listed up.
|
# The subnet pools going to be listed up.
|
||||||
_subnet_pools = network_fakes.FakeSubnetPool.create_subnet_pools(count=3)
|
_subnet_pools = network_fakes.FakeSubnetPool.create_subnet_pools(count=3)
|
||||||
|
|
||||||
@ -388,6 +410,7 @@ class TestListSubnetPool(TestSubnetPool):
|
|||||||
'Address Scope',
|
'Address Scope',
|
||||||
'Default Subnet Pool',
|
'Default Subnet Pool',
|
||||||
'Shared',
|
'Shared',
|
||||||
|
'Tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
@ -408,6 +431,7 @@ class TestListSubnetPool(TestSubnetPool):
|
|||||||
pool.address_scope_id,
|
pool.address_scope_id,
|
||||||
pool.is_default,
|
pool.is_default,
|
||||||
pool.shared,
|
pool.shared,
|
||||||
|
utils.format_list(pool.tags),
|
||||||
))
|
))
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -418,6 +442,9 @@ class TestListSubnetPool(TestSubnetPool):
|
|||||||
|
|
||||||
self.network.subnet_pools = mock.Mock(return_value=self._subnet_pools)
|
self.network.subnet_pools = mock.Mock(return_value=self._subnet_pools)
|
||||||
|
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_list_resource_mock = self.network.subnet_pools
|
||||||
|
|
||||||
def test_subnet_pool_list_no_option(self):
|
def test_subnet_pool_list_no_option(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
verifylist = [
|
verifylist = [
|
||||||
@ -585,11 +612,12 @@ class TestListSubnetPool(TestSubnetPool):
|
|||||||
self.assertEqual(self.data, list(data))
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
|
|
||||||
class TestSetSubnetPool(TestSubnetPool):
|
class TestSetSubnetPool(TestSubnetPool, _test_tag.TestSetTagMixin):
|
||||||
|
|
||||||
# The subnet_pool to set.
|
# The subnet_pool to set.
|
||||||
_subnet_pool = network_fakes.FakeSubnetPool.create_one_subnet_pool(
|
_subnet_pool = network_fakes.FakeSubnetPool.create_one_subnet_pool(
|
||||||
{'default_quota': 10},
|
{'default_quota': 10,
|
||||||
|
'tags': ['green', 'red']}
|
||||||
)
|
)
|
||||||
|
|
||||||
_address_scope = network_fakes.FakeAddressScope.create_one_address_scope()
|
_address_scope = network_fakes.FakeAddressScope.create_one_address_scope()
|
||||||
@ -598,6 +626,7 @@ class TestSetSubnetPool(TestSubnetPool):
|
|||||||
super(TestSetSubnetPool, self).setUp()
|
super(TestSetSubnetPool, self).setUp()
|
||||||
|
|
||||||
self.network.update_subnet_pool = mock.Mock(return_value=None)
|
self.network.update_subnet_pool = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
|
|
||||||
self.network.find_subnet_pool = mock.Mock(
|
self.network.find_subnet_pool = mock.Mock(
|
||||||
return_value=self._subnet_pool)
|
return_value=self._subnet_pool)
|
||||||
@ -608,6 +637,11 @@ class TestSetSubnetPool(TestSubnetPool):
|
|||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = subnet_pool.SetSubnetPool(self.app, self.namespace)
|
self.cmd = subnet_pool.SetSubnetPool(self.app, self.namespace)
|
||||||
|
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_resource_name = 'subnet_pool'
|
||||||
|
self._tag_test_resource = self._subnet_pool
|
||||||
|
self._tag_update_resource_mock = self.network.update_subnet_pool
|
||||||
|
|
||||||
def test_set_this(self):
|
def test_set_this(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'--name', 'noob',
|
'--name', 'noob',
|
||||||
@ -667,9 +701,8 @@ class TestSetSubnetPool(TestSubnetPool):
|
|||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
attrs = {}
|
self.assertFalse(self.network.update_subnet_pool.called)
|
||||||
self.network.update_subnet_pool.assert_called_once_with(
|
self.assertFalse(self.network.set_tags.called)
|
||||||
self._subnet_pool, **attrs)
|
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_set_len_negative(self):
|
def test_set_len_negative(self):
|
||||||
@ -854,6 +887,7 @@ class TestShowSubnetPool(TestSubnetPool):
|
|||||||
'prefixes',
|
'prefixes',
|
||||||
'project_id',
|
'project_id',
|
||||||
'shared',
|
'shared',
|
||||||
|
'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = (
|
data = (
|
||||||
@ -870,6 +904,7 @@ class TestShowSubnetPool(TestSubnetPool):
|
|||||||
utils.format_list(_subnet_pool.prefixes),
|
utils.format_list(_subnet_pool.prefixes),
|
||||||
_subnet_pool.tenant_id,
|
_subnet_pool.tenant_id,
|
||||||
_subnet_pool.shared,
|
_subnet_pool.shared,
|
||||||
|
utils.format_list(_subnet_pool.tags),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -908,26 +943,36 @@ class TestShowSubnetPool(TestSubnetPool):
|
|||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
|
|
||||||
class TestUnsetSubnetPool(TestSubnetPool):
|
class TestUnsetSubnetPool(TestSubnetPool, _test_tag.TestUnsetTagMixin):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestUnsetSubnetPool, self).setUp()
|
super(TestUnsetSubnetPool, self).setUp()
|
||||||
self._subnetpool = network_fakes.FakeSubnetPool.create_one_subnet_pool(
|
self._subnetpool = network_fakes.FakeSubnetPool.create_one_subnet_pool(
|
||||||
{'prefixes': ['10.0.10.0/24', '10.1.10.0/24',
|
{'prefixes': ['10.0.10.0/24', '10.1.10.0/24',
|
||||||
'10.2.10.0/24'], })
|
'10.2.10.0/24'],
|
||||||
|
'tags': ['green', 'red']})
|
||||||
self.network.find_subnet_pool = mock.Mock(
|
self.network.find_subnet_pool = mock.Mock(
|
||||||
return_value=self._subnetpool)
|
return_value=self._subnetpool)
|
||||||
self.network.update_subnet_pool = mock.Mock(return_value=None)
|
self.network.update_subnet_pool = mock.Mock(return_value=None)
|
||||||
|
self.network.set_tags = mock.Mock(return_value=None)
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = subnet_pool.UnsetSubnetPool(self.app, self.namespace)
|
self.cmd = subnet_pool.UnsetSubnetPool(self.app, self.namespace)
|
||||||
|
|
||||||
|
# TestUnsetTagMixin
|
||||||
|
self._tag_resource_name = 'subnet_pool'
|
||||||
|
self._tag_test_resource = self._subnetpool
|
||||||
|
self._tag_update_resource_mock = self.network.update_subnet_pool
|
||||||
|
|
||||||
def test_unset_subnet_pool(self):
|
def test_unset_subnet_pool(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'--pool-prefix', '10.0.10.0/24',
|
'--pool-prefix', '10.0.10.0/24',
|
||||||
'--pool-prefix', '10.1.10.0/24',
|
'--pool-prefix', '10.1.10.0/24',
|
||||||
self._subnetpool.name,
|
self._subnetpool.name,
|
||||||
]
|
]
|
||||||
verifylist = [('prefixes', ['10.0.10.0/24', '10.1.10.0/24'])]
|
verifylist = [
|
||||||
|
('prefixes', ['10.0.10.0/24', '10.1.10.0/24']),
|
||||||
|
('subnet_pool', self._subnetpool.name),
|
||||||
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
attrs = {'prefixes': ['10.2.10.0/24']}
|
attrs = {'prefixes': ['10.2.10.0/24']}
|
||||||
@ -940,7 +985,10 @@ class TestUnsetSubnetPool(TestSubnetPool):
|
|||||||
'--pool-prefix', '10.100.1.1/25',
|
'--pool-prefix', '10.100.1.1/25',
|
||||||
self._subnetpool.name,
|
self._subnetpool.name,
|
||||||
]
|
]
|
||||||
verifylist = [('prefixes', ['10.100.1.1/25'])]
|
verifylist = [
|
||||||
|
('prefixes', ['10.100.1.1/25']),
|
||||||
|
('subnet_pool', self._subnetpool.name),
|
||||||
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.assertRaises(exceptions.CommandError,
|
self.assertRaises(exceptions.CommandError,
|
||||||
self.cmd.take_action,
|
self.cmd.take_action,
|
||||||
|
@ -25,6 +25,12 @@ class ParserException(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CompareBySet(list):
|
||||||
|
"""Class to compare value using set."""
|
||||||
|
def __eq__(self, other):
|
||||||
|
return set(self) == set(other)
|
||||||
|
|
||||||
|
|
||||||
class TestCase(testtools.TestCase):
|
class TestCase(testtools.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added support for ``tags`` to the following resources:
|
||||||
|
``network``, ``subnet``, ``port``, ``router`` and ``subnet pool``.
|
||||||
|
[Blueprint :oscbp:`neutron-client-tag`]
|
||||||
|
|
||||||
|
- Add ``--tag`` and ``--no-tag`` options to corresponding "create" commands.
|
||||||
|
- Add ``--tag`` and ``--no-tag`` options to corresponding "set" commands.
|
||||||
|
- Add ``--tag`` and ``--all-tag`` options to corresponding "unset" commands.
|
||||||
|
(``network unset`` command is introduced to support the tag operation)
|
||||||
|
- Add ``--tags``, ``--any-tags``, ``--not-tags`` and ``--not-any-tags``
|
||||||
|
options to corresponding "list" commands.
|
@ -395,6 +395,7 @@ openstack.network.v2 =
|
|||||||
network_list = openstackclient.network.v2.network:ListNetwork
|
network_list = openstackclient.network.v2.network:ListNetwork
|
||||||
network_set = openstackclient.network.v2.network:SetNetwork
|
network_set = openstackclient.network.v2.network:SetNetwork
|
||||||
network_show = openstackclient.network.v2.network:ShowNetwork
|
network_show = openstackclient.network.v2.network:ShowNetwork
|
||||||
|
network_unset = openstackclient.network.v2.network:UnsetNetwork
|
||||||
|
|
||||||
network_meter_create = openstackclient.network.v2.network_meter:CreateMeter
|
network_meter_create = openstackclient.network.v2.network_meter:CreateMeter
|
||||||
network_meter_delete = openstackclient.network.v2.network_meter:DeleteMeter
|
network_meter_delete = openstackclient.network.v2.network_meter:DeleteMeter
|
||||||
|
Loading…
Reference in New Issue
Block a user