http-add-on/operator/controllers/http/scaled_object.go

108 lines
2.8 KiB
Go

package http
import (
"context"
"github.com/go-logr/logr"
kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
httpv1alpha1 "github.com/kedacore/http-add-on/operator/apis/http/v1alpha1"
"github.com/kedacore/http-add-on/pkg/k8s"
)
// createOrUpdateScaledObject attempts to create a new ScaledObject
// according to the given parameters. If the create failed because the
// ScaledObject already exists, attempts to patch the scaledobject.
// otherwise, fails.
func (r *HTTPScaledObjectReconciler) createOrUpdateScaledObject(
ctx context.Context,
cl client.Client,
logger logr.Logger,
externalScalerHostName string,
httpso *httpv1alpha1.HTTPScaledObject,
) error {
logger.Info("Creating scaled objects", "external scaler host name", externalScalerHostName)
var minReplicaCount *int32
var maxReplicaCount *int32
if replicas := httpso.Spec.Replicas; replicas != nil {
minReplicaCount = replicas.Min
maxReplicaCount = replicas.Max
}
appScaledObject := k8s.NewScaledObject(
httpso.GetNamespace(),
httpso.GetName(), // HTTPScaledObject name is the same as the ScaledObject name
httpso.Labels,
httpso.Annotations,
httpso.Spec.ScaleTargetRef,
externalScalerHostName,
minReplicaCount,
maxReplicaCount,
httpso.Spec.CooldownPeriod,
httpso.Spec.InitialCooldownPeriod,
)
// Set HTTPScaledObject instance as the owner and controller
if err := controllerutil.SetControllerReference(httpso, appScaledObject, r.Scheme); err != nil {
return err
}
logger.Info("Creating App ScaledObject", "ScaledObject", *appScaledObject)
if err := cl.Create(ctx, appScaledObject); err != nil {
if errors.IsAlreadyExists(err) {
existingSOKey := client.ObjectKey{
Namespace: httpso.GetNamespace(),
Name: appScaledObject.GetName(),
}
var fetchedSO kedav1alpha1.ScaledObject
if err := cl.Get(ctx, existingSOKey, &fetchedSO); err != nil {
logger.Error(
err,
"failed to fetch existing ScaledObject for patching",
)
return err
}
if err := cl.Patch(ctx, appScaledObject, client.Merge); err != nil {
logger.Error(
err,
"failed to patch existing ScaledObject",
)
return err
}
} else {
AddOrUpdateCondition(
httpso,
*SetMessage(
CreateCondition(
httpv1alpha1.Ready,
v1.ConditionFalse,
httpv1alpha1.ErrorCreatingAppScaledObject,
),
err.Error(),
),
)
logger.Error(err, "Creating ScaledObject")
return err
}
}
AddOrUpdateCondition(
httpso,
*SetMessage(
CreateCondition(
httpv1alpha1.Ready,
v1.ConditionTrue,
httpv1alpha1.AppScaledObjectCreated,
),
"App ScaledObject created",
),
)
return nil
}