Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show full triggers and authentications in status #6232

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Here is an overview of all new **experimental** features:
### Improvements

- **General**: Prevent multiple ScaledObjects managing one HPA ([#6130](https://github.com/kedacore/keda/issues/6130))
- **General**: Show full triggers'types and authentications'types in status ([#6187](https://github.com/kedacore/keda/issues/6187))
- **AWS CloudWatch Scaler**: Add support for ignoreNullValues ([#5352](https://github.com/kedacore/keda/issues/5352))
- **Elasticsearch Scaler**: Support Query at the Elasticsearch scaler ([#6216](https://github.com/kedacore/keda/issues/6216))
- **Etcd Scaler**: Add username and password support for etcd ([#6199](https://github.com/kedacore/keda/pull/6199))
Expand Down
8 changes: 6 additions & 2 deletions apis/keda/v1alpha1/scaledjob_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ const (
// +kubebuilder:resource:path=scaledjobs,scope=Namespaced,shortName=sj
// +kubebuilder:printcolumn:name="Min",type="integer",JSONPath=".spec.minReplicaCount"
// +kubebuilder:printcolumn:name="Max",type="integer",JSONPath=".spec.maxReplicaCount"
// +kubebuilder:printcolumn:name="Triggers",type="string",JSONPath=".spec.triggers[*].type"
// +kubebuilder:printcolumn:name="Authentication",type="string",JSONPath=".spec.triggers[*].authenticationRef.name"
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status"
// +kubebuilder:printcolumn:name="Active",type="string",JSONPath=".status.conditions[?(@.type==\"Active\")].status"
// +kubebuilder:printcolumn:name="Paused",type="string",JSONPath=".status.conditions[?(@.type==\"Paused\")].status"
// +kubebuilder:printcolumn:name="Triggers",type="string",JSONPath=".status.triggersTypes"
// +kubebuilder:printcolumn:name="Authentications",type="string",JSONPath=".status.authenticationsTypes"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"

// ScaledJob is the Schema for the scaledjobs API
Expand Down Expand Up @@ -81,6 +81,10 @@ type ScaledJobStatus struct {
Conditions Conditions `json:"conditions,omitempty"`
// +optional
Paused string `json:"Paused,omitempty"`
// +optional
TriggersTypes *string `json:"triggersTypes,omitempty"`
// +optional
AuthenticationsTypes *string `json:"authenticationsTypes,omitempty"`
}

// ScaledJobList contains a list of ScaledJob
Expand Down
8 changes: 6 additions & 2 deletions apis/keda/v1alpha1/scaledobject_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ import (
// +kubebuilder:printcolumn:name="ScaleTargetName",type="string",JSONPath=".spec.scaleTargetRef.name"
// +kubebuilder:printcolumn:name="Min",type="integer",JSONPath=".spec.minReplicaCount"
// +kubebuilder:printcolumn:name="Max",type="integer",JSONPath=".spec.maxReplicaCount"
// +kubebuilder:printcolumn:name="Triggers",type="string",JSONPath=".spec.triggers[*].type"
// +kubebuilder:printcolumn:name="Authentication",type="string",JSONPath=".spec.triggers[*].authenticationRef.name"
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status"
// +kubebuilder:printcolumn:name="Active",type="string",JSONPath=".status.conditions[?(@.type==\"Active\")].status"
// +kubebuilder:printcolumn:name="Fallback",type="string",JSONPath=".status.conditions[?(@.type==\"Fallback\")].status"
// +kubebuilder:printcolumn:name="Paused",type="string",JSONPath=".status.conditions[?(@.type==\"Paused\")].status"
// +kubebuilder:printcolumn:name="Triggers",type="string",JSONPath=".status.triggersTypes"
// +kubebuilder:printcolumn:name="Authentications",type="string",JSONPath=".status.authenticationsTypes"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"

// ScaledObject is a specification for a ScaledObject resource
Expand Down Expand Up @@ -177,6 +177,10 @@ type ScaledObjectStatus struct {
PausedReplicaCount *int32 `json:"pausedReplicaCount,omitempty"`
// +optional
HpaName string `json:"hpaName,omitempty"`
// +optional
TriggersTypes *string `json:"triggersTypes,omitempty"`
// +optional
AuthenticationsTypes *string `json:"authenticationsTypes,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
17 changes: 17 additions & 0 deletions apis/keda/v1alpha1/scaletriggers_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package v1alpha1

import (
"fmt"
"slices"
"strings"

autoscalingv2 "k8s.io/api/autoscaling/v2"
)
Expand Down Expand Up @@ -80,3 +82,18 @@ func ValidateTriggers(triggers []ScaleTriggers) error {

return nil
}

// CombinedTriggersAndAuthenticationsTypes returns a comma separated string of all trigger types and authentication types
func CombinedTriggersAndAuthenticationsTypes(triggers []ScaleTriggers) (string, string) {
var triggersTypes []string
var authTypes []string
for _, trigger := range triggers {
if !slices.Contains(triggersTypes, trigger.Type) {
triggersTypes = append(triggersTypes, trigger.Type)
}
if trigger.AuthenticationRef != nil && !slices.Contains(authTypes, trigger.AuthenticationRef.Name) {
authTypes = append(authTypes, trigger.AuthenticationRef.Name)
}
}
return strings.Join(triggersTypes, ","), strings.Join(authTypes, ",")
}
20 changes: 20 additions & 0 deletions apis/keda/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions config/crd/bases/keda.sh_scaledjobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ spec:
- jsonPath: .spec.maxReplicaCount
name: Max
type: integer
- jsonPath: .spec.triggers[*].type
name: Triggers
type: string
- jsonPath: .spec.triggers[*].authenticationRef.name
name: Authentication
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
Expand All @@ -38,6 +32,12 @@ spec:
- jsonPath: .status.conditions[?(@.type=="Paused")].status
name: Paused
type: string
- jsonPath: .status.triggersTypes
name: Triggers
type: string
- jsonPath: .status.authenticationsTypes
name: Authentications
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
Expand Down Expand Up @@ -8028,6 +8028,8 @@ spec:
properties:
Paused:
type: string
authenticationsTypes:
type: string
conditions:
description: Conditions an array representation to store multiple
Conditions
Expand Down Expand Up @@ -8055,6 +8057,8 @@ spec:
lastActiveTime:
format: date-time
type: string
triggersTypes:
type: string
type: object
type: object
served: true
Expand Down
16 changes: 10 additions & 6 deletions config/crd/bases/keda.sh_scaledobjects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ spec:
- jsonPath: .spec.maxReplicaCount
name: Max
type: integer
- jsonPath: .spec.triggers[*].type
name: Triggers
type: string
- jsonPath: .spec.triggers[*].authenticationRef.name
name: Authentication
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
Expand All @@ -47,6 +41,12 @@ spec:
- jsonPath: .status.conditions[?(@.type=="Paused")].status
name: Paused
type: string
- jsonPath: .status.triggersTypes
name: Triggers
type: string
- jsonPath: .status.authenticationsTypes
name: Authentications
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
Expand Down Expand Up @@ -309,6 +309,8 @@ spec:
status:
description: ScaledObjectStatus is the status for a ScaledObject resource
properties:
authenticationsTypes:
type: string
compositeScalerName:
type: string
conditions:
Expand Down Expand Up @@ -387,6 +389,8 @@ spec:
type: object
scaleTargetKind:
type: string
triggersTypes:
type: string
type: object
required:
- spec
Expand Down
16 changes: 16 additions & 0 deletions controllers/keda/scaledjob_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ func (r *ScaledJobReconciler) reconcileScaledJob(ctx context.Context, logger log
return "ScaledJob doesn't have correct triggers specification", err
}

err = r.updateStatusWithTriggersAndAuthsTypes(ctx, logger, scaledJob)
if err != nil {
return "Cannot update ScaledJob status with triggers'names and authentications'names", err
}

// nosemgrep: trailofbits.go.invalid-usage-of-modified-variable.invalid-usage-of-modified-variable
msg, err := r.deletePreviousVersionScaleJobs(ctx, logger, scaledJob)
if err != nil {
Expand Down Expand Up @@ -404,3 +409,14 @@ func (r *ScaledJobReconciler) updateTriggerAuthenticationStatusOnDelete(ctx cont
return triggerAuthenticationStatus
})
}

func (r *ScaledJobReconciler) updateStatusWithTriggersAndAuthsTypes(ctx context.Context, logger logr.Logger, scaledJob *kedav1alpha1.ScaledJob) error {
triggersTypes, authsTypes := kedav1alpha1.CombinedTriggersAndAuthenticationsTypes(scaledJob.Spec.Triggers)
status := scaledJob.Status.DeepCopy()
status.TriggersTypes = &triggersTypes
status.AuthenticationsTypes = &authsTypes

logger.V(1).Info("Updating ScaledJob status with triggers and authentications types", "triggersTypes", triggersTypes, "authenticationsTypes", authsTypes)

return kedastatus.UpdateScaledJobStatus(ctx, r.Client, logger, scaledJob, status)
}
16 changes: 16 additions & 0 deletions controllers/keda/scaledobject_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ func (r *ScaledObjectReconciler) reconcileScaledObject(ctx context.Context, logg
return "ScaledObject doesn't have correct triggers specification", err
}

err = r.updateStatusWithTriggersAndAuthsTypes(ctx, logger, scaledObject)
if err != nil {
return "Cannot update ScaledObject status with triggers'types and authentications'types", err
}

// Create a new HPA or update existing one according to ScaledObject
newHPACreated, err := r.ensureHPAForScaledObjectExists(ctx, logger, scaledObject, &gvkr)
if err != nil {
Expand Down Expand Up @@ -621,3 +626,14 @@ func (r *ScaledObjectReconciler) updateTriggerAuthenticationStatusOnDelete(ctx c
return triggerAuthenticationStatus
})
}

func (r *ScaledObjectReconciler) updateStatusWithTriggersAndAuthsTypes(ctx context.Context, logger logr.Logger, scaledObject *kedav1alpha1.ScaledObject) error {
triggersTypes, authsTypes := kedav1alpha1.CombinedTriggersAndAuthenticationsTypes(scaledObject.Spec.Triggers)
status := scaledObject.Status.DeepCopy()
status.TriggersTypes = &triggersTypes
status.AuthenticationsTypes = &authsTypes

logger.V(1).Info("Updating ScaledObject status with triggers and authentications types", "triggersTypes", triggersTypes, "authenticationsTypes", authsTypes)

return kedastatus.UpdateScaledObjectStatus(ctx, r.Client, logger, scaledObject, status)
}
26 changes: 21 additions & 5 deletions pkg/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,35 @@ func SetStatusConditions(ctx context.Context, client runtimeclient.StatusClient,

// UpdateScaledObjectStatus patches the given ScaledObject with the updated status passed to it or returns an error.
func UpdateScaledObjectStatus(ctx context.Context, client runtimeclient.StatusClient, logger logr.Logger, scaledObject *kedav1alpha1.ScaledObject, status *kedav1alpha1.ScaledObjectStatus) error {
return updateObjectStatus(ctx, client, logger, scaledObject, status)
}

// UpdateScaledJobStatus patches the given ScaledObject with the updated status passed to it or returns an error.
func UpdateScaledJobStatus(ctx context.Context, client runtimeclient.StatusClient, logger logr.Logger, scaledJob *kedav1alpha1.ScaledJob, status *kedav1alpha1.ScaledJobStatus) error {
return updateObjectStatus(ctx, client, logger, scaledJob, status)
}

// updateObjectStatus patches the given ScaledObject with the updated status passed to it or returns an error.
func updateObjectStatus(ctx context.Context, client runtimeclient.StatusClient, logger logr.Logger, object interface{}, status interface{}) error {
transform := func(runtimeObj runtimeclient.Object, target interface{}) error {
status, ok := target.(*kedav1alpha1.ScaledObjectStatus)
if !ok {
return fmt.Errorf("transform target is not kedav1alpha1.ScaledObjectStatus type %v", target)
}
switch obj := runtimeObj.(type) {
case *kedav1alpha1.ScaledObject:
status, ok := target.(*kedav1alpha1.ScaledObjectStatus)
if !ok {
return fmt.Errorf("transform target is not kedav1alpha1.ScaledObjectStatus type %v", target)
}
obj.Status = *status
case *kedav1alpha1.ScaledJob:
status, ok := target.(*kedav1alpha1.ScaledJobStatus)
if !ok {
return fmt.Errorf("transform target is not kedav1alpha1.ScaledJobStatus type %v", target)
}
obj.Status = *status
default:
}
return nil
}
return TransformObject(ctx, client, logger, scaledObject, status, transform)
return TransformObject(ctx, client, logger, object, status, transform)
}

// getTriggerAuth returns TriggerAuthentication/ClusterTriggerAuthentication object and its status from AuthenticationRef or returns an error.
Expand Down
Loading
Loading