Skip to content

Commit

Permalink
Add support for Flatcar OS
Browse files Browse the repository at this point in the history
Fetch os_distro metadata and pass to helm chart.

Depends on Helm chart flatcar support:
https://github.com/stackhpc/capi-helm-charts/pull/53
  • Loading branch information
dalees committed Nov 2, 2023
1 parent 6726c7c commit 8634f00
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 20 deletions.
23 changes: 21 additions & 2 deletions magnum_capi_helm/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ def provides(self):
"os": "capi-kubeadm-cloudinit",
"coe": "kubernetes",
},
{
"server_type": "vm",
"os": "flatcar",
"coe": "kubernetes",
},
]

def _update_control_plane_nodegroup_status(self, cluster, nodegroup):
Expand Down Expand Up @@ -499,12 +504,25 @@ def _get_kube_version(self, image):
# TODO(johngarbutt) more validation required?
return re.sub(r"[^0-9\.]+", "", raw)

def _get_os_distro(self, image):
os_distro = image.get("os_distro")
if not os_distro:
raise exception.MagnumException(
message=f"Image {image.id} does not "
"have an os_distro property."
)
return re.sub(r"[^a-zA-Z0-9\.\-\/ ]+", "", os_distro)

def _get_image_details(self, context, image_identifier):
osc = clients.OpenStackClients(context)
image = api_utils.get_openstack_resource(
osc.glance().images, image_identifier, "images"
)
return image.id, self._get_kube_version(image)
return (
image.id,
self._get_kube_version(image),
self._get_os_distro(image),
)

def _get_app_cred_name(self, cluster):
return self._sanitized_name(
Expand Down Expand Up @@ -544,7 +562,7 @@ def _update_helm_release(self, context, cluster, nodegroups=None):
if nodegroups is None:
nodegroups = cluster.nodegroups

image_id, kube_version = self._get_image_details(
image_id, kube_version, os_distro = self._get_image_details(
context, cluster.cluster_template.image_id
)

Expand Down Expand Up @@ -578,6 +596,7 @@ def _update_helm_release(self, context, cluster, nodegroups=None):
),
},
},
"osDistro": os_distro,
"controlPlane": {
"machineFlavor": cluster.master_flavor_id,
"machineCount": cluster.master_count,
Expand Down
92 changes: 75 additions & 17 deletions magnum_capi_helm/tests/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ def test_provides(self):
"server_type": "vm",
"os": "capi-kubeadm-cloudinit",
"coe": "kubernetes",
}
},
{
"server_type": "vm",
"os": "flatcar",
"coe": "kubernetes",
},
],
self.driver.provides,
)
Expand Down Expand Up @@ -1017,24 +1022,61 @@ def test_get_kube_version_works(self):
self.assertEqual("1.27.9", result)
mock_image.get.assert_called_once_with("kube_version")

@mock.patch("magnum.common.clients.OpenStackClients")
@mock.patch("magnum.api.utils.get_openstack_resource")
def test_get_image_details(self, mock_get, mock_osc):
@mock.patch("magnum.common.clients.OpenStackClients", autospec=True)
@mock.patch("magnum.api.utils.get_openstack_resource", autospec=True)
def test_get_image_details_ubuntu(self, mock_get, mock_osc):
mock_image = mock.Mock()
mock_image.get.return_value = "v1.27.9"
image_metadata = {
"os_distro": "ubuntu",
"kube_version": "1.27.9",
}

def image_side_effect(arg):
return image_metadata[arg]

mock_image.get.side_effect = image_side_effect
mock_image.id = "myid"
mock_get.return_value = mock_image

id, version = self.driver._get_image_details(
id, version, distro = self.driver._get_image_details(
self.context, "myimagename"
)

self.assertEqual("1.27.9", version)
self.assertEqual("myid", id)
mock_image.get.assert_called_once_with("kube_version")
self.assertEqual("ubuntu", distro)
mock_image.get.assert_any_call("kube_version")
mock_image.get.assert_any_call("os_distro")
mock_get.assert_called_once_with(mock.ANY, "myimagename", "images")

def test_get_chart_release_name_lenght(self):
@mock.patch("magnum.common.clients.OpenStackClients", autospec=True)
@mock.patch("magnum.api.utils.get_openstack_resource", autospec=True)
def test_get_image_details_flatcar(self, mock_get, mock_osc):
mock_image = mock.Mock()
image_metadata = {
"os_distro": "flatcar",
"kube_version": "1.28.2",
}

def image_side_effect(arg):
return image_metadata[arg]

mock_image.get.side_effect = image_side_effect
mock_image.id = "myid-flatcar"
mock_get.return_value = mock_image

id, version, distro = self.driver._get_image_details(
self.context, "myimagename"
)

self.assertEqual("1.28.2", version)
self.assertEqual("myid-flatcar", id)
self.assertEqual("flatcar", distro)
mock_image.get.assert_any_call("kube_version")
mock_image.get.assert_any_call("os_distro")
mock_get.assert_called_once_with(mock.ANY, "myimagename", "images")

def test_get_chart_release_name_length(self):
self.cluster_obj.stack_id = "foo"

result = self.driver._get_chart_release_name(self.cluster_obj)
Expand Down Expand Up @@ -1109,14 +1151,18 @@ def test_create_cluster(
mock_certs,
mock_get_net,
):
mock_image.return_value = ("imageid1", "1.27.4")
mock_image.return_value = (
"imageid1",
"1.27.4",
"capi-kubeadm-cloudinit",
)
mock_client = mock.MagicMock(spec=kubernetes.Client)
mock_load.return_value = mock_client
mock_get_net.side_effect = (
lambda c, net, source, target, external: f"{net}-{external}"
)

self.cluster_obj.keypair = "kp1"
expected_keypair = "kp1"
self.cluster_obj.keypair = expected_keypair

self.driver.create_cluster(self.context, self.cluster_obj, 10)

Expand All @@ -1142,6 +1188,7 @@ def test_create_cluster(
"enableLoadBalancer": True,
"loadBalancerProvider": "amphora",
},
"osDistro": "capi-kubeadm-cloudinit",
"controlPlane": {
"machineFlavor": "flavor_small",
"machineCount": 3,
Expand All @@ -1156,9 +1203,9 @@ def test_create_cluster(
"name": "test-worker",
"machineFlavor": "flavor_medium",
"machineCount": 3,
}
},
],
"machineSSHKeyName": "kp1",
"machineSSHKeyName": expected_keypair,
},
repo=CONF.capi_helm.helm_chart_repo,
version=CONF.capi_helm.default_helm_chart_version,
Expand All @@ -1184,11 +1231,16 @@ def test_create_cluster_no_dns(
mock_appcred,
mock_certs,
):
mock_image.return_value = ("imageid1", "1.27.4")
mock_image.return_value = (
"imageid1",
"1.27.4",
"capi-kubeadm-cloudinit",
)
mock_client = mock.MagicMock(spec=kubernetes.Client)
mock_load.return_value = mock_client
self.cluster_obj.cluster_template.dns_nameserver = ""
self.cluster_obj.keypair = "kp1"
expected_keypair = "kp1"
self.cluster_obj.keypair = expected_keypair
self.cluster_obj.cluster_template.labels["extra_network_name"] = "foo"

self.driver.create_cluster(self.context, self.cluster_obj, 10)
Expand All @@ -1215,6 +1267,7 @@ def test_create_cluster_no_dns(
"enableLoadBalancer": True,
"loadBalancerProvider": "amphora",
},
"osDistro": "capi-kubeadm-cloudinit",
"controlPlane": {
"machineFlavor": "flavor_small",
"machineCount": 3,
Expand Down Expand Up @@ -1242,7 +1295,7 @@ def test_create_cluster_no_dns(
],
},
},
"machineSSHKeyName": "kp1",
"machineSSHKeyName": expected_keypair,
},
repo=CONF.capi_helm.helm_chart_repo,
version=CONF.capi_helm.default_helm_chart_version,
Expand All @@ -1267,7 +1320,11 @@ def test_create_cluster_no_keypair(
mock_appcred,
mock_certs,
):
mock_image.return_value = ("imageid1", "1.27.4")
mock_image.return_value = (
"imageid1",
"1.27.4",
"capi-kubeadm-cloudinit",
)
mock_client = mock.MagicMock(spec=kubernetes.Client)
mock_load.return_value = mock_client
self.cluster_obj.keypair = ""
Expand Down Expand Up @@ -1296,6 +1353,7 @@ def test_create_cluster_no_keypair(
"enableLoadBalancer": True,
"loadBalancerProvider": "amphora",
},
"osDistro": "capi-kubeadm-cloudinit",
"controlPlane": {
"machineFlavor": "flavor_small",
"machineCount": 3,
Expand Down
8 changes: 7 additions & 1 deletion magnum_capi_helm/tests/test_magnum_capi_helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@


class TestMagnumDriverLoads(base.TestCase):
def test_get_driver(self):
def test_get_ubuntu_driver(self):
cluster_driver = common.Driver.get_driver(
"vm", "capi-kubeadm-cloudinit", "kubernetes"
)
self.assertIsInstance(cluster_driver, driver.Driver)

def test_get_flatcar_driver(self):
cluster_driver = common.Driver.get_driver(
"vm", "flatcar", "kubernetes"
)
self.assertIsInstance(cluster_driver, driver.Driver)

0 comments on commit 8634f00

Please sign in to comment.