Skip to content

Commit

Permalink
Merge pull request #15 from CCI-MOC/devel
Browse files Browse the repository at this point in the history
Teach esi.lib.nodes how to detach all ports
  • Loading branch information
tzumainn authored Jan 16, 2025
2 parents 194616a + 68a3562 commit 8d78f2f
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 13 deletions.
54 changes: 44 additions & 10 deletions esi/lib/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# under the License.

import concurrent.futures
import warnings

from openstack import exceptions

Expand Down Expand Up @@ -265,18 +266,38 @@ def network_attach(connection, node, attach_info):
}


def network_detach(connection, node, port=None):
def network_detach(
connection, node_name_or_uuid, port=None, port_names_or_uuids=None, all_ports=False
):
"""Detaches a node's bare metal port from a network port
:param port: The name or ID of a network port
:returns: ``True`` if the VIF was detached, otherwise ``False``
:returns: A list of ``(port_uuid, bool)`` tuples, where ``bool`` is ``True`` if the port was removed
successfully, ``False`` otherwise.
"""

node = connection.baremetal.get_node(node)
if port and port_names_or_uuids:
raise ValueError("do not set both port and port_names_or_uuids")

if (port or port_names_or_uuids) and all_ports:
raise ValueError("do not specify individual ports with all_ports=true")

if port:
port = connection.network.find_port(port, ignore_missing=False)
port_names_or_uuids = [port]
warnings.warn(
"The 'port' parameter is deprecated and will be removed in a future release.",
DeprecationWarning,
stacklevel=2,
)

node = connection.baremetal.get_node(node_name_or_uuid)
ports = []
if port_names_or_uuids:
ports = [
connection.network.find_port(port, ignore_missing=False)
for port in port_names_or_uuids
]
else:
bm_ports = connection.baremetal.ports(details=True, node=node.id)

Expand All @@ -290,13 +311,26 @@ def network_detach(connection, node, port=None):
raise exceptions.ResourceFailure(
"Node {0} is not associated with any port".format(node.name)
)

if all_ports:
ports = [
connection.network.find_port(
bmport.internal_info["tenant_vif_port_id"], ignore_missing=False
)
for bmport in mapped_node_port_list
]
elif len(mapped_node_port_list) > 1:
raise exceptions.ResourceFailure(
"Node {0} is associated with multiple ports. \
Port must be specified".format(node.name)
"Node {0} is associated with multiple ports. Port must be specified".format(
node.name
)
)
elif len(mapped_node_port_list) == 1:
port = mapped_node_port_list[0].internal_info["tenant_vif_port_id"]
port = connection.network.find_port(port, ignore_missing=False)

return connection.baremetal.detach_vif_from_node(node, port.id)
vif = mapped_node_port_list[0].internal_info["tenant_vif_port_id"]
port = connection.network.find_port(vif, ignore_missing=False)
ports = [port]

return [
(port.id, connection.baremetal.detach_vif_from_node(node, port.id))
for port in ports
]
56 changes: 53 additions & 3 deletions esi/tests/unit/lib/test_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,9 +999,9 @@ def test_take_action(self):
self.connection.baremetal.detach_vif_from_node.assert_called_once_with(
self.node, "neutron_port_uuid_1"
)
self.assertEqual(True, result)
self.assertEqual([("neutron_port_uuid_1", True)], result)

def test_take_multiple_port_action(self):
def test_take_action_node_has_multiple_ports(self):
self.connection.network.find_port.return_value = self.neutron_port1
self.connection.baremetal.ports.return_value = [self.port1, self.port2]

Expand All @@ -1010,7 +1010,7 @@ def test_take_multiple_port_action(self):
self.connection.baremetal.detach_vif_from_node.assert_called_once_with(
self.node, "neutron_port_uuid_1"
)
self.assertEqual(True, result)
self.assertEqual([("neutron_port_uuid_1", True)], result)

def test_take_action_port_exception(self):
self.connection.network.find_port.side_effect = exceptions.NotFoundException
Expand All @@ -1035,3 +1035,53 @@ def test_take_action_mutiple_port_exception(self):
self.assertRaises(
exceptions.ResourceFailure, nodes.network_detach, self.connection, "node1"
)

def test_take_action_detach_multiple_ports(self):
self.connection.network.find_port.side_effect = [
self.neutron_port1,
self.neutron_port2,
]
self.connection.baremetal.ports.return_value = [self.port1, self.port2]

result = nodes.network_detach(
self.connection,
"node1",
port_names_or_uuids=["neutron_port1", "neutron_port2"],
)

self.connection.baremetal.detach_vif_from_node.assert_has_calls(
[
mock.call(self.node, "neutron_port_uuid_1"),
mock.call(self.node, "neutron_port_uuid_2"),
]
)
self.assertEqual(
[("neutron_port_uuid_1", True), ("neutron_port_uuid_2", True)], result
)

def test_take_action_detach_all_ports(self):
self.connection.network.find_port.side_effect = [
self.neutron_port1,
self.neutron_port2,
]
self.connection.baremetal.ports.return_value = [
self.port1,
self.port2,
self.port3,
]

result = nodes.network_detach(
self.connection,
"node1",
all_ports=True,
)

self.connection.baremetal.detach_vif_from_node.assert_has_calls(
[
mock.call(self.node, "neutron_port_uuid_1"),
mock.call(self.node, "neutron_port_uuid_2"),
]
)
self.assertEqual(
[("neutron_port_uuid_1", True), ("neutron_port_uuid_2", True)], result
)

0 comments on commit 8d78f2f

Please sign in to comment.