func()

in pkg/controllers/mysqld_statefulset_controller.go [56:135]


func (mssc *mysqldStatefulSetController) HandleScaleDown(ctx context.Context, sc *SyncContext) syncResult {

	nc := sc.ndb
	mysqldSfset := sc.mysqldSfset

	if mysqldSfset == nil {
		// Nothing to scale down
		return continueProcessing()
	}
	NdbGeneration := sc.configSummary.NdbClusterGeneration
	// StatefulSet exists
	if !sc.isStatefulsetUpdated(sc.mysqldSfset, NdbGeneration, Complete) {
		// Previous StatefulSet update is not complete yet.
		// Finish processing. Reconciliation will
		// continue once the StatefulSet update has been
		// rolled out.
		return finishProcessing()
	}

	// Handle any scale down
	mysqldNodeCount := sc.configSummary.NumOfMySQLServers
	if mysqldSfset.Status.Replicas <= mysqldNodeCount {
		// No scale down requested or, it has been processed already
		// Continue processing rest of sync loop
		return continueProcessing()
	}

	// scale down requested
	if mysqldNodeCount == 0 {
		// The StatefulSet has to be deleted
		// Delete the root user first.
		rootHost := mysqldSfset.GetAnnotations()[rootHost]
		secretClient := NewMySQLUserPasswordSecretInterface(mssc.client)

		// Extract ndb operator mysql user password.
		operatorSecretName := resources.GetMySQLNDBOperatorPasswordSecretName(nc)
		operatorPassword, err := secretClient.ExtractPassword(ctx, mysqldSfset.Namespace, operatorSecretName)
		if err != nil {
			klog.Errorf("Failed to extract ndb operator password from the secret")
			return errorWhileProcessing(err)
		}

		if err := mysqlclient.DeleteRootUserIfExists(mysqldSfset, rootHost, operatorPassword); err != nil {
			klog.Errorf("Failed to delete root user")
			return errorWhileProcessing(err)
		}

		// Delete the secret.
		annotations := mysqldSfset.GetAnnotations()
		secretName := annotations[statefulset.RootPasswordSecret]

		if secretClient.IsControlledBy(ctx, secretName, nc) {
			// The given NdbCluster is set as the Owner of the secret,
			// which implies that this was created by the operator.
			err := secretClient.Delete(ctx, mysqldSfset.Namespace, secretName)
			if err != nil && !errors.IsNotFound(err) {
				// Delete failed with an error.
				// Ignore NotFound error as this delete might be a redundant
				// step, caused by an outdated cache read.
				klog.Errorf("Failed to delete MySQL Root pass secret %q : %s", secretName, err)
				return errorWhileProcessing(err)
			}
		}

		// scale down to 0 servers, i.e., delete the statefulset
		if err := mssc.deleteStatefulSet(ctx, mysqldSfset, sc); err != nil {
			return errorWhileProcessing(err)
		}

		// reconciliation will continue once the statefulset has been deleted
		return finishProcessing()
	}

	// create a new statefulset with updated replica to patch the original statefulset
	// Note : the annotation 'last-applied-config-generation' will be updated only
	//        during ReconcileStatefulset
	updatedSfset := mysqldSfset.DeepCopy()
	updatedSfset.Spec.Replicas = &mysqldNodeCount
	return mssc.patchStatefulSet(ctx, mysqldSfset, updatedSfset)
}