Skip to content

Commit

Permalink
fix: added update_cluster_status
Browse files Browse the repository at this point in the history
  • Loading branch information
mnaser committed Nov 7, 2022
1 parent a021300 commit faa153b
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 38 deletions.
59 changes: 51 additions & 8 deletions magnum_cluster_api/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def create_cluster(self, context, cluster, cluster_create_timeout):
resources.apply_cluster_from_magnum_cluster(context, self.k8s_api, cluster)

def update_cluster_status(self, context, cluster, use_admin_ctx=False):
# TODO: watch for topology change instead
osc = clients.get_openstack_api(context)

capi_cluster = resources.Cluster(context, self.k8s_api, cluster).get_object()
Expand All @@ -81,6 +82,11 @@ def update_cluster_status(self, context, cluster, use_admin_ctx=False):
f"https://{api_endpoint['host']}:{api_endpoint['port']}"
)

for node_group in cluster.nodegroups:
ng = self.update_nodegroup_status(context, cluster, node_group)
if not ng.status.endswith("_COMPLETE"):
return

cluster.coe_version = capi_cluster.obj["spec"]["topology"]["version"]

if cluster.status == "CREATE_IN_PROGRESS":
Expand Down Expand Up @@ -169,12 +175,9 @@ def upgrade_cluster(
"""
# TODO: nodegroup?

# TODO: intelligently determine the changing labels
# and only update those (use get_labels_diff)
cluster.labels = cluster_template.labels
cluster.cluster_template = cluster_template

resources.apply_cluster_from_magnum_cluster(context, self.k8s_api, cluster)
resources.apply_cluster_from_magnum_cluster(
context, self.k8s_api, cluster, cluster_template=cluster_template
)

def delete_cluster(self, context, cluster):
resources.Cluster(context, self.k8s_api, cluster).delete()
Expand All @@ -183,13 +186,53 @@ def create_nodegroup(self, context, cluster, nodegroup):
# TODO: update nodegroup tags
resources.apply_cluster_from_magnum_cluster(context, self.k8s_api, cluster)

def update_nodegroup_status(self, context, cluster, nodegroup):
action = nodegroup.status.split("_")[0]

if nodegroup.role == "master":
kcp = resources.get_kubeadm_control_plane(self.k8s_api, cluster)
if kcp is None:
return nodegroup

ready = kcp.obj["status"].get("ready", False)
failure_message = kcp.obj["status"].get("failureMessage")

if ready:
nodegroup.status = f"{action}_COMPLETE"
nodegroup.status_reason = failure_message
else:
md = resources.get_machine_deployment(self.k8s_api, cluster, nodegroup)
if md is None:
if action == "DELETE":
nodegroup.status = f"{action}_COMPLETE"
nodegroup.save()
return nodegroup
return nodegroup

phase = md.obj["status"]["phase"]

if phase in ("ScalingUp", "ScalingDown"):
nodegroup.status = f"{action}_IN_PROGRESS"
elif phase == "Running":
nodegroup.status = f"{action}_COMPLETE"
elif phase in ("Failed", "Unknown"):
nodegroup.status = f"{action}_FAILED"

nodegroup.save()

return nodegroup

def update_nodegroup(self, context, cluster, nodegroup):
# TODO
resources.apply_cluster_from_magnum_cluster(context, self.k8s_api, cluster)

def delete_nodegroup(self, context, cluster, nodegroup):
# TODO
resources.apply_cluster_from_magnum_cluster(context, self.k8s_api, cluster)
nodegroup.destroy()
resources.apply_cluster_from_magnum_cluster(
context,
self.k8s_api,
cluster,
)

def get_monitor(self, context, cluster):
return monitor.ClusterApiMonitor(context, cluster)
Expand Down
12 changes: 12 additions & 0 deletions magnum_cluster_api/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,24 @@ class KubeadmConfigTemplate(pykube.objects.NamespacedAPIObject):
kind = "KubeadmConfigTemplate"


class KubeadmControlPlane(pykube.objects.NamespacedAPIObject):
version = "controlplane.cluster.x-k8s.io/v1beta1"
endpoint = "kubeadmcontrolplanes"
kind = "KubeadmControlPlane"


class KubeadmControlPlaneTemplate(pykube.objects.NamespacedAPIObject):
version = "controlplane.cluster.x-k8s.io/v1beta1"
endpoint = "kubeadmcontrolplanetemplates"
kind = "KubeadmControlPlaneTemplate"


class MachineDeployment(pykube.objects.NamespacedAPIObject):
version = "cluster.x-k8s.io/v1beta1"
endpoint = "machinedeployments"
kind = "MachineDeployment"


class Machine(pykube.objects.NamespacedAPIObject):
version = "cluster.x-k8s.io/v1beta1"
endpoint = "machines"
Expand Down
81 changes: 76 additions & 5 deletions magnum_cluster_api/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,7 @@ def get_object(self) -> objects.ClusterClass:
)


def create_cluster_class_from_cluster_template(
def create_cluster_class(
api: pykube.HTTPClient,
) -> ClusterClass:
"""
Expand Down Expand Up @@ -1131,9 +1131,37 @@ def get_object(self) -> objects.Cluster:
"failureDomain": utils.get_cluster_label(
self.cluster, "availability_zone", ""
),
# bootVolume
# flavor
# imageUUID
"variables": {
"overrides": [
{
"name": "bootVolume",
"value": {
"size": utils.get_node_group_label_as_int(
self.context,
ng,
"boot_volume_size",
CONF.cinder.default_boot_volume_size,
),
"type": utils.get_node_group_label(
self.context,
ng,
"boot_volume_type",
cinder.get_default_boot_volume_type(
self.context
),
),
},
},
{
"name": "flavor",
"value": ng.flavor_id,
},
{
"name": "imageUUID",
"value": ng.image_id,
},
],
},
}
for ng in self.cluster.nodegroups
if ng.role != "master"
Expand Down Expand Up @@ -1245,11 +1273,21 @@ def apply_cluster_from_magnum_cluster(
context: context.RequestContext,
api: pykube.HTTPClient,
cluster: magnum_objects.Cluster,
cluster_template: magnum_objects.ClusterTemplate = None,
) -> objects.Cluster:
"""
Create a ClusterAPI cluster given a Magnum Cluster object.
"""
create_cluster_class_from_cluster_template(api)
create_cluster_class(api)

if cluster_template is None:
cluster_template = cluster.cluster_template

# TODO: intelligently determine the changing labels
# and only update those (use get_labels_diff)
cluster.labels = cluster_template.labels
cluster.cluster_template = cluster_template

Cluster(context, api, cluster).apply()

# TODO: refactor into Cluster topology
Expand All @@ -1259,5 +1297,38 @@ def apply_cluster_from_magnum_cluster(
MachineHealthCheck(api, cluster).delete()


def get_kubeadm_control_plane(
api: pykube.HTTPClient, cluster: magnum_objects.Cluster
) -> objects.KubeadmControlPlane:
kcps = objects.KubeadmControlPlane.objects(api, namespace="magnum-system").filter(
selector={
"cluster.x-k8s.io/cluster-name": utils.get_or_generate_cluster_api_name(
api, cluster
)
},
)
if len(kcps) == 1:
return list(kcps)[0]
return None


def get_machine_deployment(
api: pykube.HTTPClient,
cluster: magnum_objects.Cluster,
node_group: magnum_objects.NodeGroup,
) -> objects.KubeadmControlPlane:
mds = objects.MachineDeployment.objects(api, namespace="magnum-system").filter(
selector={
"cluster.x-k8s.io/cluster-name": utils.get_or_generate_cluster_api_name(
api, cluster
),
"topology.cluster.x-k8s.io/deployment-name": node_group.name,
},
)
if len(mds) == 1:
return list(mds)[0]
return None


def name_from_node_group(api: pykube.HTTPClient, cluster: any, node_group: any) -> str:
return f"{utils.get_or_generate_cluster_api_name(api, cluster)}-{node_group.name}"
56 changes: 31 additions & 25 deletions magnum_cluster_api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import shortuuid
import yaml
from magnum import objects as magnum_objects
from magnum.common import exception
from magnum.common import context, exception
from oslo_serialization import base64
from oslo_utils import strutils
from tenacity import retry, retry_if_exception_type
Expand Down Expand Up @@ -70,18 +70,14 @@ def generate_cloud_controller_manager_config(
)


def get_cluster_label_as_bool(
cluster: magnum_objects.Cluster, key: str, default: bool
) -> bool:
value = get_cluster_label(cluster, key, default)
return strutils.bool_from_string(value, strict=True)


def get_cluster_label_as_int(
cluster: magnum_objects.Cluster, key: str, default: int
) -> int:
value = get_cluster_label(cluster, key, default)
return strutils.validate_integer(value, key)
def get_node_group_label(
context: context.RequestContext,
node_group: magnum_objects.NodeGroup,
key: str,
default: str,
) -> str:
cluster = magnum_objects.Cluster.get_by_uuid(context, node_group.cluster_id)
return node_group.labels.get(key, get_cluster_label(cluster, key, default))


def get_cluster_label(cluster: magnum_objects.Cluster, key: str, default: str) -> str:
Expand All @@ -90,21 +86,31 @@ def get_cluster_label(cluster: magnum_objects.Cluster, key: str, default: str) -
)


def get_cluster_template_label_as_bool(
cluster_template: magnum_objects.ClusterTemplate, key: str, default: bool
) -> bool:
value = get_cluster_template_label(cluster_template, key, default)
return strutils.bool_from_string(value, strict=True)
def get_cluster_template_label(
cluster_template: magnum_objects.ClusterTemplate, key: str, default: str
) -> str:
return cluster_template.labels.get(key, default)


def get_cluster_template_label_as_int(
cluster_template: magnum_objects.ClusterTemplate, key: str, default: int
def get_node_group_label_as_int(
context: context.RequestContext,
node_group: magnum_objects.NodeGroup,
key: str,
default: int,
) -> int:
value = get_cluster_template_label(cluster_template, key, default)
value = get_node_group_label(context, node_group, key, default)
return strutils.validate_integer(value, key)


def get_cluster_template_label(
cluster_template: magnum_objects.ClusterTemplate, key: str, default: str
) -> str:
return cluster_template.labels.get(key, default)
def get_cluster_label_as_int(
cluster: magnum_objects.Cluster, key: str, default: int
) -> int:
value = get_cluster_label(cluster, key, default)
return strutils.validate_integer(value, key)


def get_cluster_label_as_bool(
cluster: magnum_objects.Cluster, key: str, default: bool
) -> bool:
value = get_cluster_label(cluster, key, default)
return strutils.bool_from_string(value, strict=True)

0 comments on commit faa153b

Please sign in to comment.