Skip to content

Commit eb36df1

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Add support to delete the ports"
2 parents 5dbca5f + 3168e22 commit eb36df1

7 files changed

Lines changed: 200 additions & 0 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
====
2+
port
3+
====
4+
5+
Network v2
6+
7+
port delete
8+
-----------
9+
10+
Delete port(s)
11+
12+
.. program:: port delete
13+
.. code:: bash
14+
15+
os port delete
16+
<port> [<port> ...]
17+
18+
.. _port_delete-port:
19+
.. describe:: <port>
20+
21+
Port(s) to delete (name or ID)

doc/source/commands.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ referring to both Compute and Volume quotas.
101101
* ``network``: (**Network**) - a virtual network for connecting servers and other resources
102102
* ``object``: (**Object Storage**) a single file in the Object Storage
103103
* ``policy``: (**Identity**) determines authorization
104+
* ``port``: (**Network**) - a virtual port for connecting servers and other resources to a network
104105
* ``project``: (**Identity**) owns a group of resources
105106
* ``quota``: (**Compute**, **Volume**) resource usage restrictions
106107
* ``region``: (**Identity**) a subset of an OpenStack deployment

openstackclient/network/v2/port.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
14+
"""Port action implementations"""
15+
16+
import logging
17+
18+
from cliff import command
19+
20+
21+
class DeletePort(command.Command):
22+
"""Delete port(s)"""
23+
24+
log = logging.getLogger(__name__ + '.DeletePort')
25+
26+
def get_parser(self, prog_name):
27+
parser = super(DeletePort, self).get_parser(prog_name)
28+
parser.add_argument(
29+
'port',
30+
metavar="<port>",
31+
nargs="+",
32+
help=("Port(s) to delete (name or ID)")
33+
)
34+
return parser
35+
36+
def take_action(self, parsed_args):
37+
self.log.debug('take_action(%s)' % parsed_args)
38+
client = self.app.client_manager.network
39+
40+
for port in parsed_args.port:
41+
res = client.find_port(port)
42+
client.delete_port(res)

openstackclient/tests/network/v2/fakes.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,83 @@ def get_networks(networks=None, count=2):
145145
return mock.MagicMock(side_effect=networks)
146146

147147

148+
class FakePort(object):
149+
"""Fake one or more ports."""
150+
151+
@staticmethod
152+
def create_one_port(attrs={}, methods={}):
153+
"""Create a fake port.
154+
155+
:param Dictionary attrs:
156+
A dictionary with all attributes
157+
:param Dictionary methods:
158+
A dictionary with all methods
159+
:return:
160+
A FakeResource object, with id, name, admin_state_up,
161+
status, tenant_id
162+
"""
163+
# Set default attributes.
164+
port_attrs = {
165+
'id': 'port-id-' + uuid.uuid4().hex,
166+
'name': 'port-name-' + uuid.uuid4().hex,
167+
'status': 'ACTIVE',
168+
'admin_state_up': True,
169+
'tenant_id': 'project-id-' + uuid.uuid4().hex,
170+
}
171+
172+
# Overwrite default attributes.
173+
port_attrs.update(attrs)
174+
175+
# Set default methods.
176+
port_methods = {}
177+
178+
# Overwrite default methods.
179+
port_methods.update(methods)
180+
181+
port = fakes.FakeResource(info=copy.deepcopy(port_attrs),
182+
methods=copy.deepcopy(port_methods),
183+
loaded=True)
184+
return port
185+
186+
@staticmethod
187+
def create_ports(attrs={}, methods={}, count=2):
188+
"""Create multiple fake ports.
189+
190+
:param Dictionary attrs:
191+
A dictionary with all attributes
192+
:param Dictionary methods:
193+
A dictionary with all methods
194+
:param int count:
195+
The number of ports to fake
196+
:return:
197+
A list of FakeResource objects faking the ports
198+
"""
199+
ports = []
200+
for i in range(0, count):
201+
ports.append(FakePort.create_one_port(attrs, methods))
202+
203+
return ports
204+
205+
@staticmethod
206+
def get_ports(ports=None, count=2):
207+
"""Get an iterable MagicMock object with a list of faked ports.
208+
209+
If ports list is provided, then initialize the Mock object with the
210+
list. Otherwise create one.
211+
212+
:param List ports:
213+
A list of FakeResource objects faking ports
214+
:param int count:
215+
The number of ports to fake
216+
:return:
217+
An iterable Mock object with side_effect set to a list of faked
218+
ports
219+
"""
220+
if ports is None:
221+
ports = FakePort.create_ports(count)
222+
return mock.MagicMock(side_effect=ports)
223+
224+
148225
class FakeRouter(object):
149226
"""Fake one or more routers."""
150227

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
14+
import mock
15+
16+
from openstackclient.network.v2 import port
17+
from openstackclient.tests.network.v2 import fakes as network_fakes
18+
19+
20+
class TestPort(network_fakes.TestNetworkV2):
21+
22+
def setUp(self):
23+
super(TestPort, self).setUp()
24+
25+
# Get a shortcut to the network client
26+
self.network = self.app.client_manager.network
27+
28+
29+
class TestDeletePort(TestPort):
30+
31+
# The port to delete.
32+
_port = network_fakes.FakePort.create_one_port()
33+
34+
def setUp(self):
35+
super(TestDeletePort, self).setUp()
36+
37+
self.network.delete_port = mock.Mock(return_value=None)
38+
self.network.find_port = mock.Mock(return_value=self._port)
39+
# Get the command object to test
40+
self.cmd = port.DeletePort(self.app, self.namespace)
41+
42+
def test_delete(self):
43+
arglist = [
44+
self._port.name,
45+
]
46+
verifylist = [
47+
('port', [self._port.name]),
48+
]
49+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
50+
51+
result = self.cmd.take_action(parsed_args)
52+
self.network.delete_port.assert_called_with(self._port)
53+
self.assertIsNone(result)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
features:
3+
- |
4+
Add support for the ``port delete`` command.
5+
[Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ openstack.network.v2 =
333333
network_list = openstackclient.network.v2.network:ListNetwork
334334
network_set = openstackclient.network.v2.network:SetNetwork
335335
network_show = openstackclient.network.v2.network:ShowNetwork
336+
port_delete = openstackclient.network.v2.port:DeletePort
336337
router_create = openstackclient.network.v2.router:CreateRouter
337338
router_delete = openstackclient.network.v2.router:DeleteRouter
338339
router_list = openstackclient.network.v2.router:ListRouter

0 commit comments

Comments
 (0)