diff --git a/magnum_cluster_api/driver.py b/magnum_cluster_api/driver.py index 798ed39a..a0d29252 100644 --- a/magnum_cluster_api/driver.py +++ b/magnum_cluster_api/driver.py @@ -31,6 +31,8 @@ def create_cluster(self, context, cluster, cluster_create_timeout): cluster.stack_id = utils.generate_cluster_api_name(self.k8s_api) cluster.save() + utils.validate_cluster(cluster) + osc = clients.get_openstack_api(context) resources.Namespace(self.k8s_api).apply() @@ -180,6 +182,8 @@ def resize_cluster( nodes_to_remove, nodegroup=None, ): + utils.validate_cluster(cluster) + if nodegroup is None: nodegroup = cluster.default_ng_worker @@ -252,6 +256,8 @@ def wait_capi_cluster_reconciliation_start( raise exceptions.ClusterAPIReconcileTimeout() def delete_cluster(self, context, cluster): + if cluster.stack_id is None: + return # NOTE(mnaser): This should be removed when this is fixed: # # https://github.com/kubernetes-sigs/cluster-api-provider-openstack/issues/842 @@ -320,7 +326,15 @@ def update_nodegroup_status(self, context, cluster, nodegroup): def update_nodegroup(self, context, cluster, nodegroup): # TODO + # NOTE(okozachenko1203): First we save the nodegroup status because update_cluster_status() + # could be finished before update_nodegroup(). + nodegroup.save() resources.apply_cluster_from_magnum_cluster(context, self.k8s_api, cluster) + # NOTE(okozachenko1203): We set the cluster status as UPDATE_IN_PROGRESS again at the end because + # update_cluster_status() could be finished and cluster status has been set as + # UPDATE_COMPLETE before nodegroup_conductor.Handler.nodegroup_update finished. + cluster.status = "UPDATE_IN_PROGRESS" + cluster.save() def delete_nodegroup(self, context, cluster, nodegroup): nodegroup.status = "DELETE_IN_PROGRESS" diff --git a/magnum_cluster_api/exceptions.py b/magnum_cluster_api/exceptions.py index cc0c4341..ae214086 100644 --- a/magnum_cluster_api/exceptions.py +++ b/magnum_cluster_api/exceptions.py @@ -47,3 +47,7 @@ class OpenStackClusterSubnetNotReady(OpenStackClusterNotReady): class ClusterAPIReconcileTimeout(Exception): pass + + +class ClusterMasterCountEven(Exception): + pass diff --git a/magnum_cluster_api/resources.py b/magnum_cluster_api/resources.py index cc452cb9..117a603a 100644 --- a/magnum_cluster_api/resources.py +++ b/magnum_cluster_api/resources.py @@ -383,9 +383,23 @@ def get_object(self) -> objects.ClusterResourceSet: class CertificateAuthoritySecret(ClusterBase): + def delete(self) -> None: + resource = self.get_or_none() + if resource: + resource.delete() + + def get_or_none(self) -> pykube.Secret: + return pykube.Secret.objects(self.api, namespace="magnum-system").get_or_none( + name=f"{self.cluster.stack_id}-{self.CERT}" + ) + def get_object(self) -> pykube.Secret: + cert_ref = getattr(self.cluster, self.REF) + if cert_ref is None: + raise Exception("Certificate for %s doesn't exist." % self.REF) + ca_cert = cert_manager.get_backend().CertManager.get_cert( - getattr(self.cluster, self.REF), + cert_ref, resource_ref=self.cluster.uuid, ) diff --git a/magnum_cluster_api/utils.py b/magnum_cluster_api/utils.py index 844b86ed..716a1724 100644 --- a/magnum_cluster_api/utils.py +++ b/magnum_cluster_api/utils.py @@ -27,7 +27,9 @@ from oslo_utils import strutils from tenacity import retry, retry_if_exception_type -from magnum_cluster_api import clients, image_utils, images, objects +from magnum_cluster_api import clients +from magnum_cluster_api import exceptions as mcapi_exceptions +from magnum_cluster_api import image_utils, images, objects LOG = logging.getLogger(__name__) @@ -316,3 +318,9 @@ def format_event_message(event: pykube.Event): event.obj["reason"], event.obj["message"], ) + + +def validate_cluster(cluster: magnum_objects.Cluster): + # Check master count + if (cluster.master_count % 2) == 0: + raise mcapi_exceptions.ClusterMasterCountEven