Skip to content

Commit

Permalink
Merge pull request #61 from tzumainn/undeploy
Browse files Browse the repository at this point in the history
Add undeploy commands
  • Loading branch information
tzumainn committed Dec 8, 2023
2 parents 4bf6994 + 1498205 commit 0f45137
Show file tree
Hide file tree
Showing 9 changed files with 514 additions and 19 deletions.
42 changes: 42 additions & 0 deletions esiclient/tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,3 +554,45 @@ def test_create_trunk(self):
'segmentation_id': 333}
]
)


class TestDeleteTrunk(TestCase):

def setUp(self):
super(TestDeleteTrunk, self).setUp()

self.trunk = test_utils.create_mock_object({
"id": "trunk_uuid",
"name": "trunk",
"port_id": "port_uuid_1",
"sub_ports": [
{
"port_id": 'port_uuid_2',
"segmentation_id": '222',
"segmentation_type": 'vlan'
},
{
"port_id": 'port_uuid_3',
"segmentation_id": '333',
"segmentation_type": 'vlan'
}
]
})

self.neutron_client = mock.Mock()
self.neutron_client.delete_trunk.\
return_value = None
self.neutron_client.delete_port.\
return_value = None

def test_delete_trunk(self):
utils.delete_trunk(self.neutron_client, self.trunk)

self.neutron_client.delete_trunk.\
assert_called_once_with("trunk_uuid")
self.neutron_client.delete_port.\
assert_has_calls([
mock.call("port_uuid_2"),
mock.call("port_uuid_3"),
mock.call("port_uuid_1"),
])
125 changes: 125 additions & 0 deletions esiclient/tests/unit/v1/orchestrator/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,128 @@ def test_take_action_invalid_provisioning_type(self, mock_load):
fields=["uuid", "name", "resource_class"],
provision_state='available'
)


class TestUndeploy(base.TestCommand):

def setUp(self):
super(TestUndeploy, self).setUp()
self.cmd = cluster.Undeploy(self.app, None)

self.port1 = utils.create_mock_object({
"id": "port_uuid_1",
"name": "esi-node2-network2",
"network_id": "network_uuid_1",
})
self.port2 = utils.create_mock_object({
"id": "port_uuid_2",
"name": "esi-node3-network2",
"network_id": "network_uuid_2",
})
self.network1 = utils.create_mock_object({
"id": "network_uuid_1",
"name": "network1",
})
self.network2 = utils.create_mock_object({
"id": "network_uuid_2",
"name": "network2",
})
self.trunk = utils.create_mock_object({
"id": "trunk_uuid_1",
"name": "trunk",
})

def mock_find_network(name):
if name == "network1":
return self.network1
if name == "network2":
return self.network2
return None
self.app.client_manager.network.find_network.\
side_effect = mock_find_network

def mock_find_port(name):
if name == "esi-node2-network2":
return self.port1
if name == "esi-node3-network2":
return self.port2
return None
self.app.client_manager.network.find_port.\
side_effect = mock_find_port
self.app.client_manager.network.delete_port.\
return_value = None

self.app.client_manager.network.find_trunk.return_value = \
self.trunk

self.app.client_manager.baremetal.node.set_provision_state.\
return_value = None

@mock.patch(
'esiclient.utils.delete_trunk',
autospec=True)
@mock.patch('time.sleep', autospec=True)
@mock.patch('json.load', autospec=True)
def test_take_action(self, mock_load, mock_sleep, mock_dt):
mock_load.return_value = {
"node_configs": [
{
"nodes": {
"node_uuids": ["node1"]
},
"network": {
"network_uuid": "network1",
"tagged_network_uuids": ["network2"],
"fip_network_uuid": "external_network"
},
"provisioning": {
"provisioning_type": "image",
"image_uuid": "image_uuid",
"ssh_key": "/path/to/ssh/key"
}
},
{
"nodes": {
"node_uuids": ["node2", "node3"]
},
"network": {
"network_uuid": "network2"
},
"provisioning": {
"provisioning_type": "image_url",
"url": "https://image.url"
}
}
]
}

arglist = ['config.json']
verifylist = []

parsed_args = self.check_parser(self.cmd, arglist, verifylist)

with patch("builtins.open"):
self.cmd.take_action(parsed_args)

self.app.client_manager.network.find_network.assert_has_calls([
call('network1'),
call('network2')
])
self.app.client_manager.baremetal.node.set_provision_state.\
assert_has_calls([
call('node1', 'deleted'),
call('node2', 'deleted'),
call('node3', 'deleted')
])
self.app.client_manager.network.find_trunk.\
assert_called_once_with('esi-node1-trunk')
mock_dt.assert_called_once_with(
self.app.client_manager.network, self.trunk)
self.app.client_manager.network.find_port.assert_has_calls([
call('esi-node2-network2'),
call('esi-node3-network2')
])
self.app.client_manager.network.delete_port.assert_has_calls([
call('port_uuid_1'),
call('port_uuid_2')
])
158 changes: 158 additions & 0 deletions esiclient/tests/unit/v1/orchestrator/test_openshift.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,3 +526,161 @@ def test_take_action_missing_pull_secret(self, mock_load):
openshift.OrchestrationException,
'Please export PULL_SECRET',
self.cmd.take_action, parsed_args)


class TestUndeploy(base.TestCommand):

def setUp(self):
super(TestUndeploy, self).setUp()
self.cmd = openshift.Undeploy(self.app, None)

self.provisioning_port1 = utils.create_mock_object({
"id": "provisioning_port_uuid_1",
"network_id": "network_uuid_2",
})
self.provisioning_port2 = utils.create_mock_object({
"id": "provisioning_port_uuid_2",
"network_id": "network_uuid_2",
})
self.provisioning_port3 = utils.create_mock_object({
"id": "provisioning_port_uuid_3",
"network_id": "network_uuid_2",
})
self.private_port1 = utils.create_mock_object({
"id": "private_port_uuid_1",
"network_id": "network_uuid_1",
})
self.private_port2 = utils.create_mock_object({
"id": "private_port_uuid_2",
"network_id": "network_uuid_1",
})
self.private_port3 = utils.create_mock_object({
"id": "private_port_uuid_3",
"network_id": "network_uuid_1",
})

def mock_find_port(uuid):
if uuid == "esi-node1-provisioning_network":
return self.provisioning_port1
if uuid == "esi-node2-provisioning_network":
return self.provisioning_port2
if uuid == "esi-node3-provisioning_network":
return self.provisioning_port3
if uuid == "esi-node1-private_network":
return self.private_port1
if uuid == "esi-node2-private_network":
return self.private_port2
if uuid == "esi-node3-private_network":
return self.private_port3
return None
self.app.client_manager.network.find_port.\
side_effect = mock_find_port

self.api_port = utils.create_mock_object({
"id": "api_port_uuid_1",
"network_id": "network_uuid_1",
})
self.apps_port = utils.create_mock_object({
"id": "apps_port_uuid_1",
"network_id": "network_uuid_1",
})

def mock_ports(fixed_ips=None):
if fixed_ips == "ip_address=1.1.1.1":
return [self.api_port]
if fixed_ips == "ip_address=2.2.2.2":
return [self.apps_port]
return []
self.app.client_manager.network.ports.\
side_effect = mock_ports
self.app.client_manager.network.delete_port.\
return_value = None

self.api_fip = utils.create_mock_object({
"id": "fip_uuid_1",
"floating_ip_address": "3.3.3.3"
})
self.apps_fip = utils.create_mock_object({
"id": "fip_uuid_2",
"floating_ip_address": "4.4.4.4"
})

def mock_ips(fixed_ip_address=None):
if fixed_ip_address == "1.1.1.1":
return [self.api_fip]
if fixed_ip_address == "2.2.2.2":
return [self.apps_fip]
return []
self.app.client_manager.network.ips.\
side_effect = mock_ips
self.app.client_manager.network.delete_ip.\
return_value = None

self.app.client_manager.baremetal.node.set_provision_state.\
return_value = None

@mock.patch('time.sleep', autospec=True)
@mock.patch('json.loads', autospec=True)
@mock.patch('json.load', autospec=True)
@mock.patch.dict(os.environ, {"PULL_SECRET": "pull_secret_file",
"API_TOKEN": "api-token"})
def test_take_action(self, mock_load, mock_loads, mock_sleep):
mock_load.return_value = {
"cluster_name": "test_cluster",
"api_vip": "1.1.1.1",
"ingress_vip": "2.2.2.2",
"openshift_version": "1",
"base_dns_domain": "foo.bar",
"ssh_public_key": "ssh-public-key",
"external_network_name": "external_network",
"provisioning_network_name": "provisioning_network",
"private_network_name": "private_network",
"private_subnet_name": "private_subnet",
"nodes": ["node1", "node2", "node3"]
}
mock_loads.return_value = 'pull_secret_value'

arglist = ['config.json']
verifylist = []

parsed_args = self.check_parser(self.cmd, arglist, verifylist)

with patch("builtins.open"):
self.cmd.take_action(parsed_args)

self.app.client_manager.network.ports.assert_has_calls([
call(fixed_ips='ip_address=1.1.1.1'),
call(fixed_ips='ip_address=2.2.2.2')
])
self.app.client_manager.network.ips.assert_has_calls([
call(fixed_ip_address='1.1.1.1'),
call(fixed_ip_address='2.2.2.2')
])
self.app.client_manager.network.delete_ip.assert_has_calls([
call('fip_uuid_1'),
call('fip_uuid_2')
])
self.app.client_manager.network.delete_port.assert_has_calls([
call('api_port_uuid_1'),
call('apps_port_uuid_1'),
call('provisioning_port_uuid_1'),
call('private_port_uuid_1'),
call('provisioning_port_uuid_2'),
call('private_port_uuid_2'),
call('provisioning_port_uuid_3'),
call('private_port_uuid_3')
])
self.app.client_manager.baremetal.node.set_provision_state.\
assert_has_calls([
call('node1', 'deleted'),
call('node2', 'deleted'),
call('node3', 'deleted')
])
self.app.client_manager.network.find_port.assert_has_calls([
call('esi-node1-provisioning_network'),
call('esi-node1-private_network'),
call('esi-node2-provisioning_network'),
call('esi-node2-private_network'),
call('esi-node3-provisioning_network'),
call('esi-node3-private_network')
])
19 changes: 9 additions & 10 deletions esiclient/tests/unit/v1/test_trunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,9 @@ def mock_find_trunk(trunk_name):
self.app.client_manager.network.delete_port.\
return_value = None

def test_take_action(self):
@mock.patch('esiclient.utils.delete_trunk',
autospec=True)
def test_take_action(self, mock_delete_trunk):
arglist = ['trunk']
verifylist = []

Expand All @@ -270,16 +272,12 @@ def test_take_action(self):

self.app.client_manager.network.find_trunk.\
assert_called_once_with("trunk")
self.app.client_manager.network.delete_trunk.\
assert_called_once_with("trunk_uuid")
self.app.client_manager.network.delete_port.\
assert_has_calls([
mock.call("port_uuid_2"),
mock.call("port_uuid_3"),
mock.call("port_uuid_1"),
])
mock_delete_trunk.assert_called_once_with(
self.app.client_manager.network, self.trunk)

def test_take_action_no_trunk(self):
@mock.patch('esiclient.utils.delete_trunk',
autospec=True)
def test_take_action_no_trunk(self, mock_delete_trunk):
arglist = ['trunk2']
verifylist = []

Expand All @@ -289,6 +287,7 @@ def test_take_action_no_trunk(self):
exceptions.CommandError,
'ERROR: no trunk named trunk2',
self.cmd.take_action, parsed_args)
mock_delete_trunk.assert_not_called


class TestAddNetwork(base.TestCommand):
Expand Down
10 changes: 10 additions & 0 deletions esiclient/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,13 @@ def create_trunk(neutron_client, trunk_name, network, tagged_networks=[]):
sub_ports=sub_ports)

return trunk, trunk_port


def delete_trunk(neutron_client, trunk):
port_ids_to_delete = [sub_port['port_id']
for sub_port in trunk.sub_ports]
port_ids_to_delete.append(trunk.port_id)

neutron_client.delete_trunk(trunk.id)
for port_id in port_ids_to_delete:
neutron_client.delete_port(port_id)
Loading

0 comments on commit 0f45137

Please sign in to comment.