Skip to content

Commit

Permalink
Initial iteration of openshift orchestrate command
Browse files Browse the repository at this point in the history
  • Loading branch information
tzumainn committed Nov 7, 2023
1 parent d591359 commit 8bac883
Show file tree
Hide file tree
Showing 8 changed files with 1,182 additions and 0 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,33 @@ openstack esi switch trunk remove vlan
- `switch`: Switch
- `switchport`: Switchport
- `vlan`: VLAN

## `openstack esi orchestrate <command>`

These commands orchestrate a bare metal cluster

### `openstack esi orchestrate openshift`

Orchestrate an OpenShift cluster.

```
openstack esi orchestrate openshift <config-file>
```

- `<config file>`: Configuration file; for example

```
{
"cluster_name": "my-cluster",
"openshift_version": "4.13.12",
"high_availability_mode": "Full",
"base_dns_domain": "my.domain",
"api_vip": "192.168.1.250",
"ingress_vip": "192.168.1.249",
"ssh_public_key": "my-public-key",
"external_network_name": "external",
"private_network_name": "my-private-network",
"private_subnet_name": "my-private-subnet",
"nodes": ["node1", "node2", "node3"]
}
```
209 changes: 209 additions & 0 deletions esiclient/tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,212 @@ def test_get_or_create_port_many_matches(self):
utils.get_or_create_port(self.port_name, self.network,
self.neutron_client)
self.neutron_client.create_port.assert_not_called()


class TestGetOrCreatePortByIP(TestCase):

def setUp(self):
super(TestGetOrCreatePortByIP, self).setUp()
self.ip = '1.1.1.1'
self.port_name = 'test_port'
self.network = test_utils.create_mock_object({
"id": "network_uuid",
"name": "test_network",
"provider_segmentation_id": "777"
})
self.subnet = test_utils.create_mock_object({
"id": "subnet_uuid",
"name": "test_subnet"
})
self.port = test_utils.create_mock_object({
"id": "port_uuid",
"name": self.port_name,
"status": "DOWN"
})

self.neutron_client = mock.Mock()
self.neutron_client.create_port.return_value = None

def test_get_or_create_port_by_ip_no_match(self):
self.neutron_client.ports.return_value = []

utils.get_or_create_port_by_ip(
self.ip, self.port_name, self.network,
self.subnet, self.neutron_client)

self.neutron_client.ports.\
assert_called_once_with(
fixed_ips="ip_address=%s" % self.ip)
self.neutron_client.create_port.\
assert_called_once_with(name=self.port_name,
network_id=self.network.id,
device_owner='baremetal:none',
fixed_ips=[{
"subnet_id": self.subnet.id,
"ip_address": self.ip
}])

def test_get_or_create_port_by_ip_match(self):
self.neutron_client.ports.return_value = [self.port]

utils.get_or_create_port_by_ip(
self.ip, self.port_name, self.network,
self.subnet, self.neutron_client)

self.neutron_client.ports.\
assert_called_once_with(
fixed_ips="ip_address=%s" % self.ip)
self.neutron_client.create_port.assert_not_called()


class TestGetOrAssignPortFloatingIP(TestCase):

def setUp(self):
super(TestGetOrAssignPortFloatingIP, self).setUp()
self.fixed_ip = '1.1.1.1'
self.port_uuid = 'port_uuid'
self.port = test_utils.create_mock_object({
"id": self.port_uuid,
"name": 'port_name',
"status": "DOWN",
"fixed_ips": [{
"ip_address": self.fixed_ip,
"subnet_id": "subnet_uuid"
}
]
})
self.fip_network = test_utils.create_mock_object({
"id": "network_uuid",
"name": "test_network",
"provider_segmentation_id": "777"
})
self.fip = test_utils.create_mock_object({
"id": "fip_uuid",
})

self.neutron_client = mock.Mock()
self.neutron_client.update_ip.return_value = None

@mock.patch('esiclient.utils.get_or_create_floating_ip',
autospec=True)
def test_get_or_assign_port_floating_ip_free_fip(self, mock_gocfi):
self.neutron_client.ips.return_value = [self.fip]

utils.get_or_assign_port_floating_ip(
self.port, self.fip_network, self.neutron_client)

self.neutron_client.ips.\
assert_called_once_with(fixed_ip_address=self.fixed_ip)
mock_gocfi.assert_not_called
self.neutron_client.update_ip.assert_not_called

@mock.patch('esiclient.utils.get_or_create_floating_ip',
autospec=True)
def test_get_or_assign_port_floating_ip_no_free_fip(self, mock_gocfi):
self.neutron_client.ips.return_value = []
mock_gocfi.return_value = self.fip

utils.get_or_assign_port_floating_ip(
self.port, self.fip_network, self.neutron_client)

self.neutron_client.ips.\
assert_called_once_with(fixed_ip_address=self.fixed_ip)
mock_gocfi.assert_called_once_with(self.fip_network,
self.neutron_client)
self.neutron_client.update_ip.assert_called_once_with(
self.fip, port_id=self.port_uuid
)


class TestGetOrCreateFloatingIP(TestCase):

def setUp(self):
super(TestGetOrCreateFloatingIP, self).setUp()
self.fip_network = test_utils.create_mock_object({
"id": "network_uuid",
"name": "test_network",
"provider_segmentation_id": "777"
})
self.fip = test_utils.create_mock_object({
"id": "fip_uuid",
})
self.neutron_client = mock.Mock()
self.neutron_client.create_ip.return_value = None

def test_get_or_create_floating_ip_exists(self):
self.neutron_client.ips.return_value = [self.fip]

utils.get_or_create_floating_ip(
self.fip_network, self.neutron_client)

self.neutron_client.ips.\
assert_called_once_with(
network=self.fip_network.id, fixed_ip_address='')
self.neutron_client.create_ip.assert_not_called

def test_get_or_create_floating_ip_not_exists(self):
self.neutron_client.ips.return_value = []

utils.get_or_create_floating_ip(
self.fip_network, self.neutron_client)

self.neutron_client.ips.\
assert_called_once_with(
network=self.fip_network.id, fixed_ip_address='')
self.neutron_client.create_ip.\
assert_called_once_with(
floating_network_id=self.fip_network.id)


class TestBootNodeFromURL(TestCase):

def setUp(self):
super(TestBootNodeFromURL, self).setUp()
self.node = "node_uuid"
self.url = 'http://test.test/test'
self.network = test_utils.create_mock_object({
"id": "network_uuid",
"name": "test_network",
})
self.port_name = 'test_port'
self.port = {
"id": "port_uuid",
"name": self.port_name,
"status": "DOWN"
}

self.neutron_client = mock.Mock()
self.ironic_client = mock.Mock()
self.ironic_client.node.update.return_value = None
self.ironic_client.node.vif_attach.return_value = None
self.ironic_client.node.set_provision_state.return_value = None

@mock.patch('esiclient.utils.get_port_name', autospec=True)
@mock.patch('esiclient.utils.get_or_create_port', autospec=True)
def test_boot_node_from_url(self, mock_gocp, mock_gpn):
mock_gpn.return_value = self.port_name
mock_gocp.return_value = self.port
node_update = [{'path': '/instance_info/deploy_interface',
'value': 'ramdisk',
'op': 'add'},
{'path': '/instance_info/boot_iso',
'value': self.url,
'op': 'add'}]

utils.boot_node_from_url(
self.node, self.url, self.network,
self.ironic_client, self.neutron_client)

mock_gpn.assert_called_once_with(
self.network.name, prefix=self.node)
mock_gocp.assert_called_once_with(
self.port_name, self.network, self.neutron_client)
self.ironic_client.node.update.assert_called_once_with(
self.node, node_update
)
self.ironic_client.node.vif_attach.assert_called_once_with(
self.node, self.port['id']
)
self.ironic_client.node.set_provision_state.assert_called_once_with(
self.node, 'active'
)
Empty file.
Loading

0 comments on commit 8bac883

Please sign in to comment.