From b7ff69650715c3332aca3beee121ca5d8ac443bb Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 27 Feb 2024 14:26:16 -0500 Subject: [PATCH 01/22] feat: add initial support for injecting keda addons --- plugins/app-json/appjson.go | 77 +++++++++++++++++++ plugins/app-json/go.mod | 1 + plugins/app-json/go.sum | 5 +- plugins/cron/go.mod | 1 + plugins/cron/go.sum | 5 +- plugins/scheduler-docker-local/go.mod | 1 + plugins/scheduler-docker-local/go.sum | 5 +- plugins/scheduler-k3s/functions.go | 42 ++++++++++ plugins/scheduler-k3s/template.go | 38 +++++++++ .../templates/chart/scaled-object.yaml | 43 +++++++++++ plugins/scheduler-k3s/triggers.go | 9 ++- 11 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 plugins/scheduler-k3s/templates/chart/scaled-object.yaml diff --git a/plugins/app-json/appjson.go b/plugins/app-json/appjson.go index cba952105..85ac95694 100644 --- a/plugins/app-json/appjson.go +++ b/plugins/app-json/appjson.go @@ -3,10 +3,12 @@ package appjson import ( "encoding/json" "fmt" + "math" "os" "strings" "github.com/dokku/dokku/plugins/common" + "k8s.io/utils/ptr" ) var ( @@ -59,6 +61,9 @@ type CronCommand struct { // Formation is a struct that represents the scale for a process from an app.json file type Formation struct { + // Autoscaling is whether or not to enable autoscaling + Autoscaling *FormationAutoscaling `json:"autoscaling"` + // Quantity is the number of processes to run Quantity *int `json:"quantity"` @@ -66,6 +71,36 @@ type Formation struct { MaxParallel *int `json:"max_parallel"` } +// FormationAutoscaling is a struct that represents the autoscaling configuration for a process from an app.json file +type FormationAutoscaling struct { + // CoolDownSeconds is the number of seconds to wait before scaling again + CooldownPeriodSeconds *int `json:"cooldown_period_seconds,omitempty"` + + // MaxQuantity is the maximum number of processes to run + MaxQuantity *int `json:"max_quantity,omitempty"` + + // MinQuantity is the minimum number of processes to run + MinQuantity *int `json:"min_quantity,omitempty"` + + // PollingIntervalSeconds is the number of seconds to wait between autoscaling checks + PollingIntervalSeconds *int `json:"polling_interval_seconds,omitempty"` + + // Triggers is a list of triggers to use for autoscaling + Triggers []FormationAutoscalingTrigger `json:"triggers,omitempty"` +} + +// FormationAutoscalingTrigger is a struct that represents a single autoscaling trigger from an app.json file +type FormationAutoscalingTrigger struct { + // Name is the name of the trigger + Name string `json:"name,omitempty"` + + // Type is the type of the trigger + Type string `json:"type,omitempty"` + + // Metadata is a map of metadata to use for the trigger + Metadata map[string]interface{} `json:"metadata,omitempty"` +} + // Healthcheck is a struct that represents a single healthcheck from an app.json file type Healthcheck struct { // Attempts is the number of attempts to make before considering a healthcheck failed @@ -181,3 +216,45 @@ func GetAppJSON(appName string) (AppJSON, error) { return appJSON, nil } + +func GetAutoscalingConfig(appName string, processType string, replicas int) (FormationAutoscaling, bool, error) { + appJSON, err := GetAppJSON(appName) + if err != nil { + return FormationAutoscaling{}, false, err + } + + common.LogWarn(fmt.Sprintf("appJSON: %v", appJSON)) + + formation, ok := appJSON.Formation[processType] + if !ok { + return FormationAutoscaling{}, false, nil + } + + if formation.Autoscaling == nil { + return FormationAutoscaling{}, false, nil + } + + autoscaling := *formation.Autoscaling + if autoscaling.CooldownPeriodSeconds == nil { + autoscaling.CooldownPeriodSeconds = ptr.To(300) + } + + if autoscaling.MinQuantity == nil { + autoscaling.MinQuantity = ptr.To(replicas) + } + + if autoscaling.MaxQuantity == nil { + defaultValue := math.Max(float64(replicas), float64(*autoscaling.MinQuantity)) + autoscaling.MaxQuantity = ptr.To(int(defaultValue)) + } + + if autoscaling.PollingIntervalSeconds == nil { + autoscaling.PollingIntervalSeconds = ptr.To(30) + } + + if len(autoscaling.Triggers) == 0 { + return FormationAutoscaling{}, false, nil + } + + return autoscaling, true, nil +} diff --git a/plugins/app-json/go.mod b/plugins/app-json/go.mod index 3b37ad66b..8ffa9aa50 100644 --- a/plugins/app-json/go.mod +++ b/plugins/app-json/go.mod @@ -7,6 +7,7 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/spf13/pflag v1.0.5 golang.org/x/sync v0.6.0 + k8s.io/utils v0.0.0-20240102154912-e7106e64919e ) require ( diff --git a/plugins/app-json/go.sum b/plugins/app-json/go.sum index ecf8b6528..6131c1424 100644 --- a/plugins/app-json/go.sum +++ b/plugins/app-json/go.sum @@ -4,8 +4,9 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+Bu github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -95,3 +96,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= diff --git a/plugins/cron/go.mod b/plugins/cron/go.mod index b37f672ad..7fab44cd3 100644 --- a/plugins/cron/go.mod +++ b/plugins/cron/go.mod @@ -30,6 +30,7 @@ require ( golang.org/x/crypto v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect + k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect ) replace github.com/dokku/dokku/plugins/app-json => ../app-json diff --git a/plugins/cron/go.sum b/plugins/cron/go.sum index d84c69cbd..3dad92380 100644 --- a/plugins/cron/go.sum +++ b/plugins/cron/go.sum @@ -4,8 +4,9 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+Bu github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -107,5 +108,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= mvdan.cc/sh/v3 v3.8.0 h1:ZxuJipLZwr/HLbASonmXtcvvC9HXY9d2lXZHnKGjFc8= mvdan.cc/sh/v3 v3.8.0/go.mod h1:w04623xkgBVo7/IUK89E0g8hBykgEpN0vgOj3RJr6MY= diff --git a/plugins/scheduler-docker-local/go.mod b/plugins/scheduler-docker-local/go.mod index 1e950c939..db86c77b1 100644 --- a/plugins/scheduler-docker-local/go.mod +++ b/plugins/scheduler-docker-local/go.mod @@ -29,6 +29,7 @@ require ( github.com/ryanuber/columnize v2.1.2+incompatible // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/sys v0.18.0 // indirect + k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect mvdan.cc/sh/v3 v3.8.0 // indirect ) diff --git a/plugins/scheduler-docker-local/go.sum b/plugins/scheduler-docker-local/go.sum index 18f4d85be..c231b0109 100644 --- a/plugins/scheduler-docker-local/go.sum +++ b/plugins/scheduler-docker-local/go.sum @@ -4,8 +4,9 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+Bu github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -105,5 +106,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= mvdan.cc/sh/v3 v3.8.0 h1:ZxuJipLZwr/HLbASonmXtcvvC9HXY9d2lXZHnKGjFc8= mvdan.cc/sh/v3 v3.8.0/go.mod h1:w04623xkgBVo7/IUK89E0g8hBykgEpN0vgOj3RJr6MY= diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index 3b18c0540..e04d76768 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -27,6 +27,7 @@ import ( "k8s.io/client-go/tools/remotecommand" "k8s.io/kubectl/pkg/util/term" "k8s.io/kubernetes/pkg/client/conditions" + "k8s.io/utils/ptr" "mvdan.cc/sh/v3/shell" ) @@ -395,6 +396,12 @@ func getAnnotations(appName string, processType string) (ProcessAnnotations, err } annotations.JobAnnotations = jobAnnotations + kedaScalingObjectAnnotations, err := getAnnotation(appName, processType, "keda_scaled_object") + if err != nil { + return annotations, err + } + annotations.KedaScalingObjectAnnotations = kedaScalingObjectAnnotations + podAnnotations, err := getAnnotation(appName, processType, "pod") if err != nil { return annotations, err @@ -434,6 +441,41 @@ func getAnnotations(appName string, processType string) (ProcessAnnotations, err return annotations, nil } +// getAutoscaling retrieves autoscaling config for a given app and process type +func getAutoscaling(appName string, processName string, replicas int) (ProcessAutoscaling, error) { + config, ok, err := appjson.GetAutoscalingConfig(appName, processName, replicas) + if err != nil { + common.LogWarn(fmt.Sprintf("Error getting autoscaling config for %s: %v", appName, err)) + return ProcessAutoscaling{}, err + } + + if !ok { + common.LogWarn(fmt.Sprintf("No autoscaling config found for %s", appName)) + return ProcessAutoscaling{}, nil + } + + triggers := []ProcessAutoscalingTrigger{} + for _, trigger := range config.Triggers { + triggers = append(triggers, ProcessAutoscalingTrigger{ + Name: trigger.Name, + Type: trigger.Type, + Metadata: trigger.Metadata, + }) + } + + autoscaling := ProcessAutoscaling{ + CooldownPeriodSeconds: ptr.Deref(config.CooldownPeriodSeconds, 300), + Enabled: len(triggers) > 0, + MaxReplicas: ptr.Deref(config.MaxQuantity, 0), + MinReplicas: ptr.Deref(config.MinQuantity, 0), + PollingIntervalSeconds: ptr.Deref(config.PollingIntervalSeconds, 30), + Triggers: triggers, + Type: "keda", + } + + return autoscaling, nil +} + // getGlobalAnnotations retrieves global annotations for a given app func getGlobalAnnotations(appName string) (ProcessAnnotations, error) { return getAnnotations(appName, GlobalProcessType) diff --git a/plugins/scheduler-k3s/template.go b/plugins/scheduler-k3s/template.go index 1af9c8445..7b0f4fdbd 100644 --- a/plugins/scheduler-k3s/template.go +++ b/plugins/scheduler-k3s/template.go @@ -59,6 +59,7 @@ type GlobalNetwork struct { type ProcessValues struct { Annotations ProcessAnnotations `yaml:"annotations,omitempty"` Args []string `yaml:"args,omitempty"` + Autoscaling ProcessAutoscaling `yaml:"autoscaling,omitempty"` Cron ProcessCron `yaml:"cron,omitempty"` Healthchecks ProcessHealthchecks `yaml:"healthchecks,omitempty"` Labels ProcessLabels `yaml:"labels,omitempty"` @@ -74,6 +75,7 @@ type ProcessAnnotations struct { DeploymentAnnotations map[string]string `yaml:"deployment,omitempty"` IngressAnnotations map[string]string `yaml:"ingress,omitempty"` JobAnnotations map[string]string `yaml:"job,omitempty"` + KedaScalingObjectAnnotations map[string]string `yaml:"keda_scaled_object,omitempty"` PodAnnotations map[string]string `yaml:"pod,omitempty"` SecretAnnotations map[string]string `yaml:"secret,omitempty"` ServiceAccountAnnotations map[string]string `yaml:"serviceaccount,omitempty"` @@ -82,6 +84,42 @@ type ProcessAnnotations struct { TraefikMiddlewareAnnotations map[string]string `yaml:"traefik_middleware,omitempty"` } +// ProcessAutoscaling contains the autoscaling configuration for a process +type ProcessAutoscaling struct { + // CooldownPeriodSeconds is the number of seconds after a scaling event before another can be triggered + CooldownPeriodSeconds int `yaml:"cooldown_period_seconds,omitempty"` + + // Enabled is a flag to enable autoscaling + Enabled bool `yaml:"enabled"` + + // MaxReplicas is the maximum number of replicas to scale to + MaxReplicas int `yaml:"max_replicas,omitempty"` + + // MinReplicas is the minimum number of replicas to scale to + MinReplicas int `yaml:"min_replicas,omitempty"` + + // PollingIntervalSeconds is the number of seconds between polling for new metrics + PollingIntervalSeconds int `yaml:"polling_interval_seconds,omitempty"` + + // Triggers is a list of triggers to use for autoscaling + Triggers []ProcessAutoscalingTrigger `yaml:"triggers,omitempty"` + + // Type is the type of autoscaling to use + Type string `yaml:"type"` +} + +// ProcessAutoscalingTrigger is a trigger to use for autoscaling +type ProcessAutoscalingTrigger struct { + // Name is the name of the trigger + Name string `yaml:"name"` + + // Type is the type of trigger to use + Type string `yaml:"type"` + + // Metadata is a map of key-value pairs that can be used to store arbitrary trigger data + Metadata map[string]interface{} `yaml:"metadata,omitempty"` +} + type ProcessHealthchecks struct { Liveness ProcessHealthcheck `yaml:"liveness,omitempty"` Readiness ProcessHealthcheck `yaml:"readiness,omitempty"` diff --git a/plugins/scheduler-k3s/templates/chart/scaled-object.yaml b/plugins/scheduler-k3s/templates/chart/scaled-object.yaml new file mode 100644 index 000000000..806392c71 --- /dev/null +++ b/plugins/scheduler-k3s/templates/chart/scaled-object.yaml @@ -0,0 +1,43 @@ +{{- $processName := "PROCESS_NAME" }} +{{- $config := index .Values.processes "PROCESS_NAME" }} +{{- if and $config.autoscaling (and $config.autoscaling.enabled (eq $config.autoscaling.type "keda")) }} +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + annotations: + app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} + dokku.com/builder-type: {{ $.Values.global.image.type }} + dokku.com/managed: "true" + kubectl.kubernetes.io/default-container: {{ $.Values.global.app_name }}-{{ $processName }} + {{- if and $.Values.global.annotations $.Values.global.annotations.keda_scaled_object }} + {{- range $k, $v := $.Values.global.annotations.keda_scaled_object }} + {{ $k }}: {{ $v | quote }} + {{- end }} + {{- end }} + {{- if and $config.annotations $config.annotations.keda_scaled_object }} + {{- range $k, $v := $config.annotations.keda_scaled_object }} + {{ $k }}: {{ $v | quote }} + {{- end }} + {{- end }} + labels: + app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $processName }}-scaled-object + app.kubernetes.io/name: {{ $processName }} + app.kubernetes.io/part-of: {{ $.Values.global.app_name }} + name: {{ $.Values.global.app_name}}-{{ $processName }} + namespace: {{ $.Values.global.namespace }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ $.Values.global.app_name }}-{{ $processName }} + envSourceContainerName: {{ $.Values.global.app_name }}-{{ $processName }} + cooldownPeriod: {{ $config.autoscaling.cooldown_period_seconds }} + pollingInterval: {{ $config.autoscaling.polling_interval_seconds }} + minReplicaCount: {{ $config.autoscaling.min_replicas }} + maxReplicaCount: {{ $config.autoscaling.max_replicas }} + fallback: + failureThreshold: 3 + replicas: {{ $config.replicas }} + triggers: + {{- toYaml $config.autoscaling.triggers | nindent 4 }} +{{- end }} \ No newline at end of file diff --git a/plugins/scheduler-k3s/triggers.go b/plugins/scheduler-k3s/triggers.go index 24be9066e..6ec08aa6d 100644 --- a/plugins/scheduler-k3s/triggers.go +++ b/plugins/scheduler-k3s/triggers.go @@ -327,8 +327,14 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e return fmt.Errorf("Error getting process labels: %w", err) } + autoscaling, err := getAutoscaling(appName, processType, int(processCount)) + if err != nil { + return fmt.Errorf("Error getting autoscaling: %w", err) + } + processValues := ProcessValues{ Annotations: annotations, + Autoscaling: autoscaling, Args: args, Healthchecks: processHealthchecks, Labels: labels, @@ -336,6 +342,7 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e Replicas: int32(processCount), Resources: processResources, } + if processType == "web" { processValues.Web = ProcessWeb{ Domains: domains, @@ -392,7 +399,7 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e values.Processes[processType] = processValues - templateFiles := []string{"deployment"} + templateFiles := []string{"deployment", "scaled-object"} if processType == "web" { templateFiles = append(templateFiles, "service", "certificate", "ingress", "ingress-route", "https-redirect-middleware") } From 46f11cb239ba0fb1ba1d516ffc2e50d59bd63356 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 27 Feb 2024 16:09:10 -0500 Subject: [PATCH 02/22] feat: implement replacements --- plugins/app-json/appjson.go | 2 +- plugins/scheduler-k3s/functions.go | 28 +++++++++++++++++++++++++--- plugins/scheduler-k3s/template.go | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/plugins/app-json/appjson.go b/plugins/app-json/appjson.go index 85ac95694..90fbfc3fd 100644 --- a/plugins/app-json/appjson.go +++ b/plugins/app-json/appjson.go @@ -98,7 +98,7 @@ type FormationAutoscalingTrigger struct { Type string `json:"type,omitempty"` // Metadata is a map of metadata to use for the trigger - Metadata map[string]interface{} `json:"metadata,omitempty"` + Metadata map[string]string `json:"metadata,omitempty"` } // Healthcheck is a struct that represents a single healthcheck from an app.json file diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index e04d76768..dbacf8a53 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -1,6 +1,7 @@ package scheduler_k3s import ( + "bytes" "context" "errors" "fmt" @@ -10,6 +11,7 @@ import ( "sort" "strconv" "strings" + "text/template" "time" appjson "github.com/dokku/dokku/plugins/app-json" @@ -442,8 +444,8 @@ func getAnnotations(appName string, processType string) (ProcessAnnotations, err } // getAutoscaling retrieves autoscaling config for a given app and process type -func getAutoscaling(appName string, processName string, replicas int) (ProcessAutoscaling, error) { - config, ok, err := appjson.GetAutoscalingConfig(appName, processName, replicas) +func getAutoscaling(appName string, processType string, replicas int) (ProcessAutoscaling, error) { + config, ok, err := appjson.GetAutoscalingConfig(appName, processType, replicas) if err != nil { common.LogWarn(fmt.Sprintf("Error getting autoscaling config for %s: %v", appName, err)) return ProcessAutoscaling{}, err @@ -454,12 +456,32 @@ func getAutoscaling(appName string, processName string, replicas int) (ProcessAu return ProcessAutoscaling{}, nil } + replacements := map[string]string{ + "APP_NAME": appName, + "PROCESS_TYPE": processType, + "DEPLOYMENT_NAME": fmt.Sprintf("%s-%s", appName, processType), + } + triggers := []ProcessAutoscalingTrigger{} for _, trigger := range config.Triggers { + metadata := map[string]string{} + for key, value := range trigger.Metadata { + tmpl, err := template.New("").Delims("[[", "]]").Parse(value) + if err != nil { + return ProcessAutoscaling{}, fmt.Errorf("Error parsing autoscaling trigger metadata: %w", err) + } + + var output bytes.Buffer + if err := tmpl.Execute(&output, replacements); err != nil { + return ProcessAutoscaling{}, fmt.Errorf("Error executing autoscaling trigger metadata template: %w", err) + } + metadata[key] = output.String() + } + triggers = append(triggers, ProcessAutoscalingTrigger{ Name: trigger.Name, Type: trigger.Type, - Metadata: trigger.Metadata, + Metadata: metadata, }) } diff --git a/plugins/scheduler-k3s/template.go b/plugins/scheduler-k3s/template.go index 7b0f4fdbd..6db52c32f 100644 --- a/plugins/scheduler-k3s/template.go +++ b/plugins/scheduler-k3s/template.go @@ -117,7 +117,7 @@ type ProcessAutoscalingTrigger struct { Type string `yaml:"type"` // Metadata is a map of key-value pairs that can be used to store arbitrary trigger data - Metadata map[string]interface{} `yaml:"metadata,omitempty"` + Metadata map[string]string `yaml:"metadata,omitempty"` } type ProcessHealthchecks struct { From 8add9b4b134c3e92c746caf244bdfbdeff63fc1a Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 27 Feb 2024 16:48:08 -0500 Subject: [PATCH 03/22] fix: ensure the ScaledObject resource is not created if the capability does not exist --- plugins/scheduler-k3s/templates/chart/scaled-object.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/scheduler-k3s/templates/chart/scaled-object.yaml b/plugins/scheduler-k3s/templates/chart/scaled-object.yaml index 806392c71..af66f19ab 100644 --- a/plugins/scheduler-k3s/templates/chart/scaled-object.yaml +++ b/plugins/scheduler-k3s/templates/chart/scaled-object.yaml @@ -1,6 +1,7 @@ {{- $processName := "PROCESS_NAME" }} {{- $config := index .Values.processes "PROCESS_NAME" }} {{- if and $config.autoscaling (and $config.autoscaling.enabled (eq $config.autoscaling.type "keda")) }} +{{- if .Capabilities.APIVersions.Has "keda.sh/v1alpha1" -}} apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: @@ -40,4 +41,5 @@ spec: replicas: {{ $config.replicas }} triggers: {{- toYaml $config.autoscaling.triggers | nindent 4 }} -{{- end }} \ No newline at end of file +{{- end }} +{{- end }} From 4ddd3411849a01abe871145d01861146b2093f57 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 27 Feb 2024 18:23:28 -0500 Subject: [PATCH 04/22] feat: add initial support for keda authentication --- plugins/scheduler-k3s/functions.go | 12 +++++++ plugins/scheduler-k3s/template.go | 26 +++++++------- ...ed-object.yaml => keda-scaled-object.yaml} | 8 ++--- .../templates/chart/keda-secret.yaml | 32 +++++++++++++++++ .../chart/keda-trigger-authentication.yaml | 34 +++++++++++++++++++ plugins/scheduler-k3s/triggers.go | 2 +- 6 files changed, 97 insertions(+), 17 deletions(-) rename plugins/scheduler-k3s/templates/chart/{scaled-object.yaml => keda-scaled-object.yaml} (87%) create mode 100644 plugins/scheduler-k3s/templates/chart/keda-secret.yaml create mode 100644 plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index dbacf8a53..5efa8947e 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -404,6 +404,18 @@ func getAnnotations(appName string, processType string) (ProcessAnnotations, err } annotations.KedaScalingObjectAnnotations = kedaScalingObjectAnnotations + kedaSecretAnnotations, err := getAnnotation(appName, processType, "keda_secret") + if err != nil { + return annotations, err + } + annotations.KedaSecretAnnotations = kedaSecretAnnotations + + kedaTriggerAuthenticationAnnotations, err := getAnnotation(appName, processType, "keda_trigger_authentication") + if err != nil { + return annotations, err + } + annotations.KedaTriggerAuthenticationAnnotations = kedaTriggerAuthenticationAnnotations + podAnnotations, err := getAnnotation(appName, processType, "pod") if err != nil { return annotations, err diff --git a/plugins/scheduler-k3s/template.go b/plugins/scheduler-k3s/template.go index 6db52c32f..b3aea7001 100644 --- a/plugins/scheduler-k3s/template.go +++ b/plugins/scheduler-k3s/template.go @@ -70,18 +70,20 @@ type ProcessValues struct { } type ProcessAnnotations struct { - CertificateAnnotations map[string]string `yaml:"certificate,omitempty"` - CronJobAnnotations map[string]string `yaml:"cronjob,omitempty"` - DeploymentAnnotations map[string]string `yaml:"deployment,omitempty"` - IngressAnnotations map[string]string `yaml:"ingress,omitempty"` - JobAnnotations map[string]string `yaml:"job,omitempty"` - KedaScalingObjectAnnotations map[string]string `yaml:"keda_scaled_object,omitempty"` - PodAnnotations map[string]string `yaml:"pod,omitempty"` - SecretAnnotations map[string]string `yaml:"secret,omitempty"` - ServiceAccountAnnotations map[string]string `yaml:"serviceaccount,omitempty"` - ServiceAnnotations map[string]string `yaml:"service,omitempty"` - TraefikIngressRouteAnnotations map[string]string `yaml:"traefik_ingressroute,omitempty"` - TraefikMiddlewareAnnotations map[string]string `yaml:"traefik_middleware,omitempty"` + CertificateAnnotations map[string]string `yaml:"certificate,omitempty"` + CronJobAnnotations map[string]string `yaml:"cronjob,omitempty"` + DeploymentAnnotations map[string]string `yaml:"deployment,omitempty"` + IngressAnnotations map[string]string `yaml:"ingress,omitempty"` + JobAnnotations map[string]string `yaml:"job,omitempty"` + KedaScalingObjectAnnotations map[string]string `yaml:"keda_scaled_object,omitempty"` + KedaSecretAnnotations map[string]string `yaml:"keda_secret,omitempty"` + KedaTriggerAuthenticationAnnotations map[string]string `yaml:"keda_trigger_authentication,omitempty"` + PodAnnotations map[string]string `yaml:"pod,omitempty"` + SecretAnnotations map[string]string `yaml:"secret,omitempty"` + ServiceAccountAnnotations map[string]string `yaml:"serviceaccount,omitempty"` + ServiceAnnotations map[string]string `yaml:"service,omitempty"` + TraefikIngressRouteAnnotations map[string]string `yaml:"traefik_ingressroute,omitempty"` + TraefikMiddlewareAnnotations map[string]string `yaml:"traefik_middleware,omitempty"` } // ProcessAutoscaling contains the autoscaling configuration for a process diff --git a/plugins/scheduler-k3s/templates/chart/scaled-object.yaml b/plugins/scheduler-k3s/templates/chart/keda-scaled-object.yaml similarity index 87% rename from plugins/scheduler-k3s/templates/chart/scaled-object.yaml rename to plugins/scheduler-k3s/templates/chart/keda-scaled-object.yaml index af66f19ab..7df2f250d 100644 --- a/plugins/scheduler-k3s/templates/chart/scaled-object.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-scaled-object.yaml @@ -7,9 +7,7 @@ kind: ScaledObject metadata: annotations: app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} - dokku.com/builder-type: {{ $.Values.global.image.type }} dokku.com/managed: "true" - kubectl.kubernetes.io/default-container: {{ $.Values.global.app_name }}-{{ $processName }} {{- if and $.Values.global.annotations $.Values.global.annotations.keda_scaled_object }} {{- range $k, $v := $.Values.global.annotations.keda_scaled_object }} {{ $k }}: {{ $v | quote }} @@ -21,7 +19,7 @@ metadata: {{- end }} {{- end }} labels: - app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $processName }}-scaled-object + app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $processName }} app.kubernetes.io/name: {{ $processName }} app.kubernetes.io/part-of: {{ $.Values.global.app_name }} name: {{ $.Values.global.app_name}}-{{ $processName }} @@ -40,6 +38,8 @@ spec: failureThreshold: 3 replicas: {{ $config.replicas }} triggers: - {{- toYaml $config.autoscaling.triggers | nindent 4 }} + {{- with $config.autoscaling.triggers }} + {{- toYaml . | nindent 4 }} + {{- end }} {{- end }} {{- end }} diff --git a/plugins/scheduler-k3s/templates/chart/keda-secret.yaml b/plugins/scheduler-k3s/templates/chart/keda-secret.yaml new file mode 100644 index 000000000..3809df019 --- /dev/null +++ b/plugins/scheduler-k3s/templates/chart/keda-secret.yaml @@ -0,0 +1,32 @@ +{{- if .Capabilities.APIVersions.Has "keda.sh/v1alpha1" -}} +{{- range $type, $config := .Values.global.keda.auth }} +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} + dokku.com/managed: "true" + {{- if and $.Values.global.annotations $.Values.global.annotations.keda_secret }} + {{- range $k, $v := $.Values.global.annotations.keda_secret }} + {{ $k }}: {{ $v | quote }} + {{- end }} + {{- end }} + {{- if and $config.annotations $config.annotations.keda_secret }} + {{- range $k, $v := $config.annotations.keda_secret }} + {{ $k }}: {{ $v | quote }} + {{- end }} + {{- end }} + labels: + app.kubernetes.io/instance: {{ $.Values.global.app_name }}-trigger-auth-secret + app.kubernetes.io/name: {{ $type }} + app.kubernetes.io/part-of: {{ $.Values.global.app_name }} + name: app-auth-{{ $type }} + namespace: {{ $.Values.global.namespace }} +data: +{{- with $config.secrets }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml b/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml new file mode 100644 index 000000000..73807a9a8 --- /dev/null +++ b/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml @@ -0,0 +1,34 @@ +{{- if .Capabilities.APIVersions.Has "keda.sh/v1alpha1" -}} +{{- range $type, $config := .Values.global.keda.auth }} +--- +apiVersion: keda.sh/v1alpha1 +kind: TriggerAuthentication +metadata: + annotations: + app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} + dokku.com/managed: "true" + {{- if and $.Values.global.annotations $.Values.global.annotations.keda_trigger_authentication }} + {{- range $k, $v := $.Values.global.annotations.keda_trigger_authentication }} + {{ $k }}: {{ $v | quote }} + {{- end }} + {{- end }} + {{- if and $config.annotations $config.annotations.keda_trigger_authentication }} + {{- range $k, $v := $config.annotations.keda_trigger_authentication }} + {{ $k }}: {{ $v | quote }} + {{- end }} + {{- end }} + labels: + app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $type }} + app.kubernetes.io/name: {{ $type }} + app.kubernetes.io/part-of: {{ $.Values.global.app_name }} + name: {{ $.Values.global.app_name }}-{{ $type }} + namespace: {{ $.Values.global.namespace }} +spec: + secretTargetRef: + {{- range $key := $config.secrets }} + - parameter: {{ $key }} + name: app-auth-{{ $type }} + key: {{ $key }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/plugins/scheduler-k3s/triggers.go b/plugins/scheduler-k3s/triggers.go index 6ec08aa6d..4818639ef 100644 --- a/plugins/scheduler-k3s/triggers.go +++ b/plugins/scheduler-k3s/triggers.go @@ -399,7 +399,7 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e values.Processes[processType] = processValues - templateFiles := []string{"deployment", "scaled-object"} + templateFiles := []string{"deployment", "keda-scaled-object"} if processType == "web" { templateFiles = append(templateFiles, "service", "certificate", "ingress", "ingress-route", "https-redirect-middleware") } From 042495bcd61ca9d15a0775db5a847c5e0d6ed0a9 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 27 Feb 2024 22:37:06 -0500 Subject: [PATCH 05/22] fix: ensure keda auth secrets are written out --- plugins/common/properties.go | 34 ++++++++++++++++++ plugins/scheduler-k3s/functions.go | 36 +++++++++++++++++++ plugins/scheduler-k3s/template.go | 25 +++++++++++++ .../templates/chart/keda-secret.yaml | 14 +++----- .../chart/keda-trigger-authentication.yaml | 22 +++++------- plugins/scheduler-k3s/triggers.go | 28 ++++++++++++++- 6 files changed, 134 insertions(+), 25 deletions(-) diff --git a/plugins/common/properties.go b/plugins/common/properties.go index 3b131b4f3..f0f1c23d2 100644 --- a/plugins/common/properties.go +++ b/plugins/common/properties.go @@ -138,6 +138,40 @@ func PropertyGetAll(pluginName string, appName string) (map[string]string, error return properties, nil } +// PropertyGetAllByPrefix returns a map of all properties for a given app with a specified prefix +func PropertyGetAllByPrefix(pluginName string, appName string, prefix string) (map[string]string, error) { + properties := make(map[string]string) + pluginAppConfigRoot := getPluginAppPropertyPath(pluginName, appName) + + fi, err := os.Stat(pluginAppConfigRoot) + if err != nil { + return properties, nil + } + + if !fi.IsDir() { + return properties, errors.New("Specified property path is not a directory") + } + + files, err := os.ReadDir(pluginAppConfigRoot) + if err != nil { + return properties, err + } + + for _, file := range files { + if file.IsDir() { + continue + } + property := file.Name() + if !strings.HasPrefix(property, prefix) { + continue + } + + properties[property] = PropertyGet(pluginName, appName, property) + } + + return properties, nil +} + // PropertyGetDefault returns the value for a given property with a specified default value func PropertyGetDefault(pluginName, appName, property, defaultValue string) (val string) { if !PropertyExists(pluginName, appName, property) { diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index 5efa8947e..eba23b449 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -3,6 +3,7 @@ package scheduler_k3s import ( "bytes" "context" + "encoding/base64" "errors" "fmt" "net" @@ -510,6 +511,41 @@ func getAutoscaling(appName string, processType string, replicas int) (ProcessAu return autoscaling, nil } +// getKedaValues retrieves keda values for a given app and process type +func getKedaValues(appName string) (GlobalKedaValues, error) { + properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, "trigger-auth-") + if err != nil { + return GlobalKedaValues{}, fmt.Errorf("Error getting trigger-auth properties: %w", err) + } + + auths := map[string]KedaAuthentication{} + for key, value := range properties { + parts := strings.SplitN(strings.TrimPrefix(key, "trigger-auth-"), ":", 2) + if len(parts) != 2 { + return GlobalKedaValues{}, fmt.Errorf("Invalid trigger-auth property format: %s", key) + } + + authType := parts[0] + secretKey := parts[1] + if len(secretKey) == 0 { + return GlobalKedaValues{}, fmt.Errorf("Invalid trigger-auth property format: %s", key) + } + + if _, ok := auths[authType]; !ok { + auths[authType] = KedaAuthentication{ + Type: authType, + Secrets: make(map[string]string), + } + } + + auths[authType].Secrets[secretKey] = base64.StdEncoding.EncodeToString([]byte(value)) + } + + return GlobalKedaValues{ + Authentications: auths, + }, nil +} + // getGlobalAnnotations retrieves global annotations for a given app func getGlobalAnnotations(appName string) (ProcessAnnotations, error) { return getAnnotations(appName, GlobalProcessType) diff --git a/plugins/scheduler-k3s/template.go b/plugins/scheduler-k3s/template.go index b3aea7001..3711f631f 100644 --- a/plugins/scheduler-k3s/template.go +++ b/plugins/scheduler-k3s/template.go @@ -38,6 +38,7 @@ type GlobalValues struct { DeploymentID string `yaml:"deploment_id"` Image GlobalImage `yaml:"image"` Labels ProcessLabels `yaml:"labels,omitempty"` + Keda GlobalKedaValues `yaml:"keda"` Namespace string `yaml:"namespace"` Network GlobalNetwork `yaml:"network"` Secrets map[string]string `yaml:"secrets,omitempty"` @@ -56,6 +57,21 @@ type GlobalNetwork struct { PrimaryPort int32 `yaml:"primary_port"` } +// GlobalKedaValues contains the global keda configuration +type GlobalKedaValues struct { + // Authentications is a map of authentication objects to use for keda + Authentications map[string]KedaAuthentication `yaml:"authentications"` +} + +// KedaAuthentication contains the authentication configuration for keda +type KedaAuthentication struct { + // Type is the type of authentication to use + Type string `yaml:"type"` + + // Secrets is a map of secrets to use for authentication + Secrets map[string]string `yaml:"secrets"` +} + type ProcessValues struct { Annotations ProcessAnnotations `yaml:"annotations,omitempty"` Args []string `yaml:"args,omitempty"` @@ -120,6 +136,15 @@ type ProcessAutoscalingTrigger struct { // Metadata is a map of key-value pairs that can be used to store arbitrary trigger data Metadata map[string]string `yaml:"metadata,omitempty"` + + // AuthenticationRef is a reference to an authentication object + AuthenticationRef *ProcessAutoscalingTriggerAuthenticationRef `yaml:"authenticationRef,omitempty"` +} + +// ProcessAutoscalingTriggerAuthenticationRef is a reference to an authentication object +type ProcessAutoscalingTriggerAuthenticationRef struct { + // Name is the name of the authentication object + Name string `yaml:"name"` } type ProcessHealthchecks struct { diff --git a/plugins/scheduler-k3s/templates/chart/keda-secret.yaml b/plugins/scheduler-k3s/templates/chart/keda-secret.yaml index 3809df019..29531b479 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-secret.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-secret.yaml @@ -1,5 +1,5 @@ {{- if .Capabilities.APIVersions.Has "keda.sh/v1alpha1" -}} -{{- range $type, $config := .Values.global.keda.auth }} +{{- $config := index .Values.global.keda.authentications "AUTH_NAME" }} --- apiVersion: v1 kind: Secret @@ -12,16 +12,11 @@ metadata: {{ $k }}: {{ $v | quote }} {{- end }} {{- end }} - {{- if and $config.annotations $config.annotations.keda_secret }} - {{- range $k, $v := $config.annotations.keda_secret }} - {{ $k }}: {{ $v | quote }} - {{- end }} - {{- end }} labels: - app.kubernetes.io/instance: {{ $.Values.global.app_name }}-trigger-auth-secret - app.kubernetes.io/name: {{ $type }} + app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $config.type }} + app.kubernetes.io/name: {{ $config.type }} app.kubernetes.io/part-of: {{ $.Values.global.app_name }} - name: app-auth-{{ $type }} + name: keda-app-auth-{{ $.Values.global.app_name }}-{{ $config.type }} namespace: {{ $.Values.global.namespace }} data: {{- with $config.secrets }} @@ -29,4 +24,3 @@ data: {{- toYaml . | nindent 2 }} {{- end }} {{- end }} -{{- end }} \ No newline at end of file diff --git a/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml b/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml index 73807a9a8..a78cdabc2 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml @@ -1,5 +1,5 @@ {{- if .Capabilities.APIVersions.Has "keda.sh/v1alpha1" -}} -{{- range $type, $config := .Values.global.keda.auth }} +{{- $config := index .Values.global.keda.authentications "AUTH_NAME" }} --- apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication @@ -12,23 +12,17 @@ metadata: {{ $k }}: {{ $v | quote }} {{- end }} {{- end }} - {{- if and $config.annotations $config.annotations.keda_trigger_authentication }} - {{- range $k, $v := $config.annotations.keda_trigger_authentication }} - {{ $k }}: {{ $v | quote }} - {{- end }} - {{- end }} labels: - app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $type }} - app.kubernetes.io/name: {{ $type }} + app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $config.type }} + app.kubernetes.io/name: {{ $config.type }} app.kubernetes.io/part-of: {{ $.Values.global.app_name }} - name: {{ $.Values.global.app_name }}-{{ $type }} + name: {{ $.Values.global.app_name }}-{{ $config.type }} namespace: {{ $.Values.global.namespace }} spec: secretTargetRef: - {{- range $key := $config.secrets }} - - parameter: {{ $key }} - name: app-auth-{{ $type }} - key: {{ $key }} + {{- range $k, $v := $config.secrets }} + - key: {{ $k }} + name: app-auth-{{ $config.type }} + parameter: {{ $k }} {{- end }} {{- end }} -{{- end }} \ No newline at end of file diff --git a/plugins/scheduler-k3s/triggers.go b/plugins/scheduler-k3s/triggers.go index 4818639ef..764300714 100644 --- a/plugins/scheduler-k3s/triggers.go +++ b/plugins/scheduler-k3s/triggers.go @@ -266,11 +266,17 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e return fmt.Errorf("Error getting global labels: %w", err) } + kedaValues, err := getKedaValues(appName) + if err != nil { + return fmt.Errorf("Error getting keda values: %w", err) + } + values := &AppValues{ Global: GlobalValues{ Annotations: globalAnnotations, AppName: appName, DeploymentID: fmt.Sprint(deploymentId), + Keda: kedaValues, Image: GlobalImage{ ImagePullSecrets: imagePullSecrets, PullSecretBase64: pullSecretBase64, @@ -289,6 +295,27 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e Processes: map[string]ProcessValues{}, } + for authName := range kedaValues.Authentications { + templateFiles := []string{"keda-secret", "keda-trigger-authentication"} + for _, templateName := range templateFiles { + b, err := templates.ReadFile(fmt.Sprintf("templates/chart/%s.yaml", templateName)) + if err != nil { + return fmt.Errorf("Error reading %s template: %w", templateName, err) + } + + filename := filepath.Join(chartDir, "templates", fmt.Sprintf("%s-%s.yaml", templateName, authName)) + contents := strings.ReplaceAll(string(b), "AUTH_NAME", authName) + err = os.WriteFile(filename, []byte(contents), os.FileMode(0644)) + if err != nil { + return fmt.Errorf("Error writing %s template: %w", templateName, err) + } + + if os.Getenv("DOKKU_TRACE") == "1" { + common.CatFile(filename) + } + } + } + for processType, processCount := range processes { // todo: implement deployment annotations // todo: implement pod annotations @@ -420,7 +447,6 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e common.CatFile(filename) } } - } clientset, err := NewKubernetesClient() From b3b3a93789bc50692bf8f8ede3bbc0c649445520 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 27 Feb 2024 23:09:18 -0500 Subject: [PATCH 06/22] fix: correct associated name --- .../templates/chart/keda-trigger-authentication.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml b/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml index a78cdabc2..73be1b089 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml @@ -22,7 +22,7 @@ spec: secretTargetRef: {{- range $k, $v := $config.secrets }} - key: {{ $k }} - name: app-auth-{{ $config.type }} + name: keda-app-auth-{{ $config.type }} parameter: {{ $k }} {{- end }} {{- end }} From f23cdffe4952da023ed02d33d013fefb46edd0ae Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 27 Feb 2024 23:09:39 -0500 Subject: [PATCH 07/22] feat: associate matching authentication info to a given autoscaler --- plugins/scheduler-k3s/functions.go | 41 +++++++++++++++++++++++------- plugins/scheduler-k3s/triggers.go | 7 ++++- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index eba23b449..ad9d45c16 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -456,23 +456,38 @@ func getAnnotations(appName string, processType string) (ProcessAnnotations, err return annotations, nil } +// GetAutoscalingInput contains all the information needed to get autoscaling config +type GetAutoscalingInput struct { + // AppName is the name of the app + AppName string + + // ProcessType is the process type + ProcessType string + + // Replicas is the number of replicas + Replicas int + + // KedaValues is the keda values + KedaValues GlobalKedaValues +} + // getAutoscaling retrieves autoscaling config for a given app and process type -func getAutoscaling(appName string, processType string, replicas int) (ProcessAutoscaling, error) { - config, ok, err := appjson.GetAutoscalingConfig(appName, processType, replicas) +func getAutoscaling(input GetAutoscalingInput) (ProcessAutoscaling, error) { + config, ok, err := appjson.GetAutoscalingConfig(input.AppName, input.ProcessType, input.Replicas) if err != nil { - common.LogWarn(fmt.Sprintf("Error getting autoscaling config for %s: %v", appName, err)) + common.LogWarn(fmt.Sprintf("Error getting autoscaling config for %s: %v", input.AppName, err)) return ProcessAutoscaling{}, err } if !ok { - common.LogWarn(fmt.Sprintf("No autoscaling config found for %s", appName)) + common.LogWarn(fmt.Sprintf("No autoscaling config found for %s", input.AppName)) return ProcessAutoscaling{}, nil } replacements := map[string]string{ - "APP_NAME": appName, - "PROCESS_TYPE": processType, - "DEPLOYMENT_NAME": fmt.Sprintf("%s-%s", appName, processType), + "APP_NAME": input.AppName, + "PROCESS_TYPE": input.ProcessType, + "DEPLOYMENT_NAME": fmt.Sprintf("%s-%s", input.AppName, input.ProcessType), } triggers := []ProcessAutoscalingTrigger{} @@ -491,11 +506,19 @@ func getAutoscaling(appName string, processType string, replicas int) (ProcessAu metadata[key] = output.String() } - triggers = append(triggers, ProcessAutoscalingTrigger{ + trigger := ProcessAutoscalingTrigger{ Name: trigger.Name, Type: trigger.Type, Metadata: metadata, - }) + } + + if _, ok := input.KedaValues.Authentications[trigger.Type]; ok { + trigger.AuthenticationRef = &ProcessAutoscalingTriggerAuthenticationRef{ + Name: fmt.Sprintf("%s-%s", input.AppName, trigger.Type), + } + } + + triggers = append(triggers, trigger) } autoscaling := ProcessAutoscaling{ diff --git a/plugins/scheduler-k3s/triggers.go b/plugins/scheduler-k3s/triggers.go index 764300714..952a79a57 100644 --- a/plugins/scheduler-k3s/triggers.go +++ b/plugins/scheduler-k3s/triggers.go @@ -354,7 +354,12 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e return fmt.Errorf("Error getting process labels: %w", err) } - autoscaling, err := getAutoscaling(appName, processType, int(processCount)) + autoscaling, err := getAutoscaling(GetAutoscalingInput{ + AppName: appName, + ProcessType: processType, + Replicas: int(processCount), + KedaValues: kedaValues, + }) if err != nil { return fmt.Errorf("Error getting autoscaling: %w", err) } From 0cb47f1c549abb2aae4e56d665df06cc2b2486e2 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 27 Feb 2024 23:22:42 -0500 Subject: [PATCH 08/22] fix: include app name and use shorter prefix --- plugins/scheduler-k3s/templates/chart/keda-secret.yaml | 2 +- .../templates/chart/keda-trigger-authentication.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/scheduler-k3s/templates/chart/keda-secret.yaml b/plugins/scheduler-k3s/templates/chart/keda-secret.yaml index 29531b479..c906bdde4 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-secret.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-secret.yaml @@ -16,7 +16,7 @@ metadata: app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $config.type }} app.kubernetes.io/name: {{ $config.type }} app.kubernetes.io/part-of: {{ $.Values.global.app_name }} - name: keda-app-auth-{{ $.Values.global.app_name }}-{{ $config.type }} + name: kta-{{ $.Values.global.app_name }}-{{ $config.type }} namespace: {{ $.Values.global.namespace }} data: {{- with $config.secrets }} diff --git a/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml b/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml index 73be1b089..2748a675c 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-trigger-authentication.yaml @@ -22,7 +22,7 @@ spec: secretTargetRef: {{- range $k, $v := $config.secrets }} - key: {{ $k }} - name: keda-app-auth-{{ $config.type }} + name: kta-{{ $.Values.global.app_name }}-{{ $config.type }} parameter: {{ $k }} {{- end }} {{- end }} From 3bd61d8c7f27574a611e682a6288cf10a343d603 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 28 Feb 2024 00:22:34 -0500 Subject: [PATCH 09/22] feat: add command to add or remove auth configurations --- plugins/scheduler-k3s/Makefile | 2 +- .../scheduler-k3s/src/commands/commands.go | 1 + .../src/subcommands/subcommands.go | 8 ++++++ plugins/scheduler-k3s/subcommands.go | 28 +++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/plugins/scheduler-k3s/Makefile b/plugins/scheduler-k3s/Makefile index c150d6aa1..0fcac0b5a 100644 --- a/plugins/scheduler-k3s/Makefile +++ b/plugins/scheduler-k3s/Makefile @@ -1,4 +1,4 @@ -SUBCOMMANDS = subcommands/annotations:set subcommands/cluster-add subcommands/cluster-list subcommands/cluster-remove subcommands/initialize subcommands/labels:set subcommands/report subcommands/set subcommands/show-kubeconfig subcommands/uninstall +SUBCOMMANDS = subcommands/annotations:set subcommands/autoscaling-auth:set subcommands/cluster-add subcommands/cluster-list subcommands/cluster-remove subcommands/initialize subcommands/labels:set subcommands/report subcommands/set subcommands/show-kubeconfig subcommands/uninstall TRIGGERS = triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report triggers/scheduler-deploy triggers/scheduler-enter triggers/scheduler-logs triggers/scheduler-post-delete triggers/scheduler-run triggers/scheduler-run-list triggers/scheduler-stop BUILD = commands subcommands triggers PLUGIN_NAME = scheduler-k3s diff --git a/plugins/scheduler-k3s/src/commands/commands.go b/plugins/scheduler-k3s/src/commands/commands.go index 6eb64640a..0339c43ea 100644 --- a/plugins/scheduler-k3s/src/commands/commands.go +++ b/plugins/scheduler-k3s/src/commands/commands.go @@ -17,6 +17,7 @@ Manage scheduler-k3s settings for an app Additional commands:` helpContent = ` + scheduler-k3s:autoscaling-auth:set [<--metadata key=value>...], Set or clear a scheduler-k3s autoscaling keda trigger authentication object for an app scheduler-k3s:annotations:set () [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear an annotation for a given app/process-type/resource-type combination scheduler-k3s:cluster-add [--insecure-allow-unknown-hosts] [--server-ip SERVER_IP] [--taint-scheduling] , Adds a server node to a Dokku-managed cluster scheduler-k3s:cluster-list [--format json|stdout], Lists all nodes in a Dokku-managed cluster diff --git a/plugins/scheduler-k3s/src/subcommands/subcommands.go b/plugins/scheduler-k3s/src/subcommands/subcommands.go index 4685d0834..138d68c2f 100644 --- a/plugins/scheduler-k3s/src/subcommands/subcommands.go +++ b/plugins/scheduler-k3s/src/subcommands/subcommands.go @@ -34,6 +34,14 @@ func main() { } err = scheduler_k3s.CommandAnnotationsSet(appName, *processType, *resourceType, property, value) + case "autoscaling-auth:set": + args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:set", flag.ExitOnError) + global := args.Bool("global", false, "--global: set a global property") + metadata := args.StringToString("metadata", map[string]string{}, "--metadata: a key=value map of parameter metadata") + args.Parse(os.Args[2:]) + appName := args.Arg(0) + trigger := args.Arg(1) + err = scheduler_k3s.CommandAutoscalingAuthSet(appName, trigger, *metadata, *global) case "cluster-add": args := flag.NewFlagSet("scheduler-k3s:cluster-add", flag.ExitOnError) allowUknownHosts := args.Bool("insecure-allow-unknown-hosts", false, "insecure-allow-unknown-hosts: allow unknown hosts") diff --git a/plugins/scheduler-k3s/subcommands.go b/plugins/scheduler-k3s/subcommands.go index 681e426ae..a4e445d96 100644 --- a/plugins/scheduler-k3s/subcommands.go +++ b/plugins/scheduler-k3s/subcommands.go @@ -58,6 +58,34 @@ func CommandAnnotationsSet(appName string, processType string, resourceType stri return nil } +// CommandAutoscalingAuthSet set or clear a scheduler-k3s autoscaling keda trigger authentication object for an app +func CommandAutoscalingAuthSet(appName string, trigger string, metadata map[string]string, global bool) error { + if global { + appName = "--global" + } + + if len(metadata) == 0 { + properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, fmt.Sprintf("trigger-auth.%s.", trigger)) + if err != nil { + return fmt.Errorf("Unable to get property list: %w", err) + } + + for key := range properties { + if err := common.PropertyDelete("scheduler-k3s", appName, key); err != nil { + return fmt.Errorf("Unable to delete property: %w", err) + } + } + return nil + } + + for key, value := range metadata { + if err := common.PropertyWrite("scheduler-k3s", appName, fmt.Sprintf("trigger-auth.%s.%s", trigger, key), value); err != nil { + return fmt.Errorf("Unable to set property: %w", err) + } + } + return nil +} + // CommandInitialize initializes a k3s cluster on the local server func CommandInitialize(ingressClass string, serverIP string, taintScheduling bool) error { if ingressClass != "nginx" && ingressClass != "traefik" { From 14f0e2fb7231584d723c51e5667573310221eb18 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 28 Feb 2024 11:44:02 -0500 Subject: [PATCH 10/22] refactor: use const for prefix --- plugins/scheduler-k3s/functions.go | 4 ++-- plugins/scheduler-k3s/scheduler_k3s.go | 1 + plugins/scheduler-k3s/subcommands.go | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index ad9d45c16..0ee22af7b 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -536,14 +536,14 @@ func getAutoscaling(input GetAutoscalingInput) (ProcessAutoscaling, error) { // getKedaValues retrieves keda values for a given app and process type func getKedaValues(appName string) (GlobalKedaValues, error) { - properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, "trigger-auth-") + properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, TriggerAuthPropertyPrefix) if err != nil { return GlobalKedaValues{}, fmt.Errorf("Error getting trigger-auth properties: %w", err) } auths := map[string]KedaAuthentication{} for key, value := range properties { - parts := strings.SplitN(strings.TrimPrefix(key, "trigger-auth-"), ":", 2) + parts := strings.SplitN(strings.TrimPrefix(key, TriggerAuthPropertyPrefix), ".", 2) if len(parts) != 2 { return GlobalKedaValues{}, fmt.Errorf("Invalid trigger-auth property format: %s", key) } diff --git a/plugins/scheduler-k3s/scheduler_k3s.go b/plugins/scheduler-k3s/scheduler_k3s.go index 39ce66f11..7a0ea7ab8 100644 --- a/plugins/scheduler-k3s/scheduler_k3s.go +++ b/plugins/scheduler-k3s/scheduler_k3s.go @@ -45,6 +45,7 @@ const DefaultIngressClass = "traefik" const GlobalProcessType = "--global" const KubeConfigPath = "/etc/rancher/k3s/k3s.yaml" const DefaultKubeContext = "" +const TriggerAuthPropertyPrefix = "trigger-auth." var ( runtimeScheme = runtime.NewScheme() diff --git a/plugins/scheduler-k3s/subcommands.go b/plugins/scheduler-k3s/subcommands.go index a4e445d96..315c70bc9 100644 --- a/plugins/scheduler-k3s/subcommands.go +++ b/plugins/scheduler-k3s/subcommands.go @@ -65,7 +65,7 @@ func CommandAutoscalingAuthSet(appName string, trigger string, metadata map[stri } if len(metadata) == 0 { - properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, fmt.Sprintf("trigger-auth.%s.", trigger)) + properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, fmt.Sprintf("%s%s.", TriggerAuthPropertyPrefix, trigger)) if err != nil { return fmt.Errorf("Unable to get property list: %w", err) } @@ -79,7 +79,7 @@ func CommandAutoscalingAuthSet(appName string, trigger string, metadata map[stri } for key, value := range metadata { - if err := common.PropertyWrite("scheduler-k3s", appName, fmt.Sprintf("trigger-auth.%s.%s", trigger, key), value); err != nil { + if err := common.PropertyWrite("scheduler-k3s", appName, fmt.Sprintf("%s%s.%s", TriggerAuthPropertyPrefix, trigger, key), value); err != nil { return fmt.Errorf("Unable to set property: %w", err) } } From 8c9db010062abcbe9c3c7c33ab7d7c6b42732f13 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 28 Feb 2024 16:15:20 -0500 Subject: [PATCH 11/22] chore: add keda dependency We need this in order to list keda objects that might exist in the api. --- plugins/scheduler-k3s/go.mod | 80 ++++---- plugins/scheduler-k3s/go.sum | 246 +++++++++++-------------- plugins/scheduler-k3s/scheduler_k3s.go | 2 + 3 files changed, 152 insertions(+), 176 deletions(-) diff --git a/plugins/scheduler-k3s/go.mod b/plugins/scheduler-k3s/go.mod index 31c182908..b4c31ab3e 100644 --- a/plugins/scheduler-k3s/go.mod +++ b/plugins/scheduler-k3s/go.mod @@ -10,10 +10,11 @@ require ( github.com/dokku/dokku/plugins/cron v0.0.0-00010101000000-000000000000 github.com/dokku/dokku/plugins/nginx-vhosts v0.0.0-00010101000000-000000000000 github.com/fatih/color v1.16.0 - github.com/go-openapi/jsonpointer v0.19.6 + github.com/go-openapi/jsonpointer v0.20.2 github.com/go-resty/resty/v2 v2.11.0 github.com/gofrs/flock v0.8.1 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 + github.com/kedacore/keda/v2 v2.13.0 github.com/ryanuber/columnize v2.1.2+incompatible github.com/spf13/pflag v1.0.5 github.com/traefik/traefik/v2 v2.10.7 @@ -40,7 +41,7 @@ require ( github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect - github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -58,41 +59,45 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch v5.7.0+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.11.2 // indirect + github.com/evanphx/json-patch v5.8.1+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.8.1 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/expr-lang/expr v1.15.8 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-acme/lego/v4 v4.14.0 // indirect - github.com/go-errors/errors v1.4.2 // indirect + github.com/go-errors/errors v1.5.1 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.1 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/swag v0.22.7 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.5.0 // indirect github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect - github.com/imdario/mergo v0.3.13 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect - github.com/joho/godotenv v1.2.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.1 // indirect + github.com/klauspost/compress v1.17.4 // indirect github.com/kr/fs v0.1.0 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect @@ -101,8 +106,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/melbahja/goph v1.4.0 // indirect github.com/miekg/dns v1.1.55 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -125,40 +129,44 @@ require ( github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/sftp v1.13.5 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rubenv/sql-migrate v1.5.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/traefik/paerser v0.2.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 // indirect - go.opentelemetry.io/otel v1.20.0 // indirect - go.opentelemetry.io/otel/metric v1.20.0 // indirect - go.opentelemetry.io/otel/trace v1.20.0 // indirect - go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect + go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect + go.starlark.net v0.0.0-20231121155337-90ade8b19d09 // indirect golang.org/x/crypto v0.21.0 // indirect + golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.21.0 // indirect - golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect + google.golang.org/grpc v1.60.1 // indirect + google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/evanphx/json-patch.v5 v5.8.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.29.0 // indirect @@ -166,14 +174,16 @@ require ( k8s.io/cli-runtime v0.29.0 // indirect k8s.io/component-base v0.29.0 // indirect k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 // indirect + knative.dev/pkg v0.0.0-20240116073220-b488e7be5902 // indirect oras.land/oras-go v1.2.4 // indirect + sigs.k8s.io/controller-runtime v0.16.3 // indirect sigs.k8s.io/gateway-api v0.8.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/api v0.16.0 // indirect + sigs.k8s.io/kustomize/kyaml v0.16.0 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) replace github.com/dokku/dokku/plugins/app-json => ../app-json diff --git a/plugins/scheduler-k3s/go.sum b/plugins/scheduler-k3s/go.sum index 763f9129f..b289bda23 100644 --- a/plugins/scheduler-k3s/go.sum +++ b/plugins/scheduler-k3s/go.sum @@ -1,9 +1,7 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= @@ -31,8 +29,8 @@ github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhs github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= -github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -47,17 +45,12 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXe github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cert-manager/cert-manager v1.13.3 h1:3R4G0RI7K0OkTZhWlVOC5SGZMYa2NwqmQJoyKydrz/M= github.com/cert-manager/cert-manager v1.13.3/go.mod h1:BM2+Pt/NmSv1Zr25/MHv6BgIEF9IUxA1xAjp80qkxgc= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA= @@ -71,7 +64,6 @@ github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= @@ -100,14 +92,16 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/emicklei/go-restful/v3 v3.11.2 h1:1onLa9DcsMYO9P+CXaL0dStDqQ2EHHXLiz+BtnqkLAU= +github.com/emicklei/go-restful/v3 v3.11.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v5.8.1+incompatible h1:2toJaoe7/rNa1zpeQx0UnVEjqk6z2ecyA20V/zg8vTU= +github.com/evanphx/json-patch v5.8.1+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.8.1 h1:iPEdwg0XayoS+E7Mth9JxwUtOgyVxnDTXHtKhZPlZxA= +github.com/evanphx/json-patch/v5 v5.8.1/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/expr-lang/expr v1.15.8 h1:FL8+d3rSSP4tmK9o+vKfSMqqpGL8n15pEPiHcnBpxoI= +github.com/expr-lang/expr v1.15.8/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -116,10 +110,12 @@ github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6 github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-acme/lego/v4 v4.14.0 h1:/skZoRHgVh0d2RK7l1g3Ch8HqeqP9LB8ZEjLdGEpcDE= github.com/go-acme/lego/v4 v4.14.0/go.mod h1:zjmvNCDLGz7GrC1OqdVpVmZFKSRabEDtWbdzmcpBsGo= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= @@ -128,20 +124,24 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= +github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -158,20 +158,13 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= @@ -180,12 +173,8 @@ github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -193,20 +182,20 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= @@ -222,14 +211,14 @@ github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= -github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc= -github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -241,19 +230,18 @@ github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwS github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kedacore/keda/v2 v2.13.0 h1:vUjLnEUQGrPBavyEFbPK7KxG10w+HfOnWk3eg8NPnnY= +github.com/kedacore/keda/v2 v2.13.0/go.mod h1:AZTRgxWpK5/6pq+DqJ15y3Bl/C8sl9C7tUVF4phzGDQ= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.1 h1:NE3C767s2ak2bweCZo3+rdP4U/HoyVXLv/X9f2gPS5g= -github.com/klauspost/compress v1.17.1/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= @@ -278,14 +266,12 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs= github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= @@ -324,8 +310,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -355,22 +341,24 @@ github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjz github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= @@ -390,16 +378,14 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -407,9 +393,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/traefik/paerser v0.2.0 h1:zqCLGSXoNlcBd+mzqSCLjon/I6phqIjeJL2xFB2ysgQ= @@ -436,16 +419,22 @@ github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1 github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 h1:1eHu3/pUSWaOgltNK3WJFaywKsTIr/PwvHyDmi0lQA0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0/go.mod h1:HyABWq60Uy1kjJSa2BVOxUVao8Cdick5AWSKPutqy6U= -go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc= -go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs= -go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA= -go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM= -go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ= -go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= +go.starlark.net v0.0.0-20231121155337-90ade8b19d09 h1:hzy3LFnSN8kuQK8h9tHl4ndF6UruMj47OqwqsS+/Ai4= +go.starlark.net v0.0.0-20231121155337-90ade8b19d09/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -458,23 +447,16 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -488,10 +470,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -501,7 +481,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -526,7 +505,6 @@ golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= @@ -534,23 +512,20 @@ golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -562,36 +537,24 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 h1:o4LtQxebKIJ4vkzyhtD2rfUNZ20Zf0ik5YVP5E7G7VE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v5 v5.8.1 h1:BVxXj2YS+4i9fttNkVvDKi4Pg1pVMpVE8tdEwaKeQY0= +gopkg.in/evanphx/json-patch.v5 v5.8.1/go.mod h1:/kvTRh1TVm5wuM6OkHxqXtE/1nUZZpihg29RtuIyfvk= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -601,15 +564,12 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= helm.sh/helm/v3 v3.14.2 h1:V71fv+NGZv0icBlr+in1MJXuUIHCiPG1hW9gEBISTIA= helm.sh/helm/v3 v3.14.2/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= @@ -626,27 +586,31 @@ k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 h1:avRdiaB03v88Mfvum2S3BBwkNuTlmuar4LlfO9Hajko= +k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022/go.mod h1:sIV51WBTkZrlGOJMCDZDA1IaPBUDTulPpD4y7oe038k= k8s.io/kubectl v0.29.0 h1:Oqi48gXjikDhrBF67AYuZRTcJV4lg2l42GmvsP7FmYI= k8s.io/kubectl v0.29.0/go.mod h1:0jMjGWIcMIQzmUaMgAzhSELv5WtHo2a8pq67DtviAJs= k8s.io/kubernetes v1.29.1 h1:fxJFVb8uqbYZDYHpwIsAndBQs360cQGb0xa1gYFh3fo= k8s.io/kubernetes v1.29.1/go.mod h1:xZPKU0yO0CBbLTnbd+XGyRmmtmaVuJykDb8gNCkeeUE= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +knative.dev/pkg v0.0.0-20240116073220-b488e7be5902 h1:H6+JJN23fhwYWCHY1339sY6uhIyoUwDy1a8dN233fdk= +knative.dev/pkg v0.0.0-20240116073220-b488e7be5902/go.mod h1:NYk8mMYoLkO7CQWnNkti4YGGnvLxN6MIDbUvtgeo0C0= mvdan.cc/sh/v3 v3.8.0 h1:ZxuJipLZwr/HLbASonmXtcvvC9HXY9d2lXZHnKGjFc8= mvdan.cc/sh/v3 v3.8.0/go.mod h1:w04623xkgBVo7/IUK89E0g8hBykgEpN0vgOj3RJr6MY= oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY= oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324= +sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= +sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/gateway-api v0.8.0 h1:isQQ3Jx2qFP7vaA3ls0846F0Amp9Eq14P08xbSwVbQg= sigs.k8s.io/gateway-api v0.8.0/go.mod h1:okOnjPNBFbIS/Rw9kAhuIUaIkLhTKEu+ARIuXk2dgaM= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +sigs.k8s.io/kustomize/api v0.16.0 h1:/zAR4FOQDCkgSDmVzV2uiFbuy9bhu3jEzthrHCuvm1g= +sigs.k8s.io/kustomize/api v0.16.0/go.mod h1:MnFZ7IP2YqVyVwMWoRxPtgl/5hpA+eCCrQR/866cm5c= +sigs.k8s.io/kustomize/kyaml v0.16.0 h1:6J33uKSoATlKZH16unr2XOhDI+otoe2sR3M8PDzW3K0= +sigs.k8s.io/kustomize/kyaml v0.16.0/go.mod h1:xOK/7i+vmE14N2FdFyugIshB8eF6ALpy7jI87Q2nRh4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/plugins/scheduler-k3s/scheduler_k3s.go b/plugins/scheduler-k3s/scheduler_k3s.go index 7a0ea7ab8..70dec17f5 100644 --- a/plugins/scheduler-k3s/scheduler_k3s.go +++ b/plugins/scheduler-k3s/scheduler_k3s.go @@ -5,6 +5,7 @@ import ( "sync" certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" + kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1" traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" @@ -161,5 +162,6 @@ func init() { _ = certmanagerv1.AddToScheme(runtimeScheme) _ = corev1.AddToScheme(runtimeScheme) _ = traefikv1alpha1.AddToScheme(runtimeScheme) + _ = kedav1alpha1.AddToScheme(runtimeScheme) }) } From 94125ce787247b533e49b5a5bc2ad532a9893a7a Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 28 Feb 2024 16:51:55 -0500 Subject: [PATCH 12/22] chore: make secrets optional --- plugins/scheduler-k3s/template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scheduler-k3s/template.go b/plugins/scheduler-k3s/template.go index 3711f631f..435d414ce 100644 --- a/plugins/scheduler-k3s/template.go +++ b/plugins/scheduler-k3s/template.go @@ -69,7 +69,7 @@ type KedaAuthentication struct { Type string `yaml:"type"` // Secrets is a map of secrets to use for authentication - Secrets map[string]string `yaml:"secrets"` + Secrets map[string]string `yaml:"secrets,omitempty"` } type ProcessValues struct { From c0f01c58d694fba75fdffe857083d1c4c2061539 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 28 Feb 2024 17:05:08 -0500 Subject: [PATCH 13/22] feat: add initial support for interacting with ClusterTriggerAuthentication objects These will be provisioned to the keda namespace and referenced by Triggers if they exist (as a fallback to app-specific values). --- plugins/scheduler-k3s/functions.go | 33 ++++++- plugins/scheduler-k3s/k8s.go | 87 +++++++++++++++++++ plugins/scheduler-k3s/template.go | 9 ++ .../templates/chart/keda-cluster-secret.yaml | 25 ++++++ .../keda-cluster-trigger-authentication.yaml | 26 ++++++ plugins/scheduler-k3s/triggers.go | 20 ++--- 6 files changed, 186 insertions(+), 14 deletions(-) create mode 100644 plugins/scheduler-k3s/templates/chart/keda-cluster-secret.yaml create mode 100644 plugins/scheduler-k3s/templates/chart/keda-cluster-trigger-authentication.yaml diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index 0ee22af7b..6ae1cf38b 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -512,9 +512,14 @@ func getAutoscaling(input GetAutoscalingInput) (ProcessAutoscaling, error) { Metadata: metadata, } - if _, ok := input.KedaValues.Authentications[trigger.Type]; ok { + if auth, ok := input.KedaValues.Authentications[trigger.Type]; ok { trigger.AuthenticationRef = &ProcessAutoscalingTriggerAuthenticationRef{ - Name: fmt.Sprintf("%s-%s", input.AppName, trigger.Type), + Name: auth.Name, + } + } else if auth, ok := input.KedaValues.GlobalAuthentications[trigger.Type]; ok { + trigger.AuthenticationRef = &ProcessAutoscalingTriggerAuthenticationRef{ + Name: auth.Name, + Kind: "ClusterTriggerAuthentication", } } @@ -535,7 +540,7 @@ func getAutoscaling(input GetAutoscalingInput) (ProcessAutoscaling, error) { } // getKedaValues retrieves keda values for a given app and process type -func getKedaValues(appName string) (GlobalKedaValues, error) { +func getKedaValues(ctx context.Context, clientset KubernetesClient, appName string) (GlobalKedaValues, error) { properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, TriggerAuthPropertyPrefix) if err != nil { return GlobalKedaValues{}, fmt.Errorf("Error getting trigger-auth properties: %w", err) @@ -556,6 +561,7 @@ func getKedaValues(appName string) (GlobalKedaValues, error) { if _, ok := auths[authType]; !ok { auths[authType] = KedaAuthentication{ + Name: fmt.Sprintf("%s-%s", appName, authType), Type: authType, Secrets: make(map[string]string), } @@ -564,8 +570,27 @@ func getKedaValues(appName string) (GlobalKedaValues, error) { auths[authType].Secrets[secretKey] = base64.StdEncoding.EncodeToString([]byte(value)) } + items, err := clientset.ListClusterTriggerAuthentications(ctx, ListClusterTriggerAuthenticationsInput{}) + if err != nil { + return GlobalKedaValues{}, fmt.Errorf("Error listing cluster trigger authentications: %w", err) + } + + globalAuths := map[string]KedaAuthentication{} + for _, item := range items { + if !strings.HasPrefix(item.Name, "global-auth-") { + continue + } + + authType := strings.TrimPrefix(item.Name, "global-auth-") + globalAuths[authType] = KedaAuthentication{ + Name: item.Name, + Type: authType, + } + } + return GlobalKedaValues{ - Authentications: auths, + Authentications: auths, + GlobalAuthentications: globalAuths, }, nil } diff --git a/plugins/scheduler-k3s/k8s.go b/plugins/scheduler-k3s/k8s.go index 556d8d4ab..f7f13245e 100644 --- a/plugins/scheduler-k3s/k8s.go +++ b/plugins/scheduler-k3s/k8s.go @@ -7,6 +7,7 @@ import ( "github.com/dokku/dokku/plugins/common" "github.com/go-openapi/jsonpointer" + kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1" appsv1 "k8s.io/api/apps/v1" autoscalingv1 "k8s.io/api/autoscaling/v1" batchv1 "k8s.io/api/batch/v1" @@ -15,6 +16,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -35,6 +37,9 @@ type KubernetesClient struct { // Client is the Kubernetes client Client kubernetes.Clientset + // DynamicClient is the Kubernetes dynamic client + DynamicClient dynamic.Interface + // KubeConfigPath is the path to the Kubernetes config KubeConfigPath string @@ -72,8 +77,14 @@ func NewKubernetesClient() (KubernetesClient, error) { return KubernetesClient{}, err } + dynamicClient, err := dynamic.NewForConfig(restConf) + if err != nil { + return KubernetesClient{}, err + } + return KubernetesClient{ Client: *client, + DynamicClient: dynamicClient, KubeConfigPath: kubeconfigPath, RestConfig: *restConf, RestClient: restClient, @@ -337,6 +348,44 @@ func (k KubernetesClient) LabelNode(ctx context.Context, input LabelNodeInput) e return nil } +// ListClusterTriggerAuthenticationsInput contains all the information needed to list Kubernetes trigger authentications +type ListClusterTriggerAuthenticationsInput struct { + // Namespace is the Kubernetes namespace + Namespace string + + // LabelSelector is the Kubernetes label selector + LabelSelector string +} + +// ListClusterTriggerAuthentications lists Kubernetes trigger authentications +func (k KubernetesClient) ListClusterTriggerAuthentications(ctx context.Context, input ListClusterTriggerAuthenticationsInput) ([]kedav1alpha1.ClusterTriggerAuthentication, error) { + listOptions := metav1.ListOptions{LabelSelector: input.LabelSelector} + + gvr := schema.GroupVersionResource{ + Group: "keda.sh", + Version: "v1alpha1", + Resource: "clustertriggerauthentications", + } + + response, err := k.DynamicClient.Resource(gvr).Namespace(input.Namespace).List(ctx, listOptions) + if err != nil { + return []kedav1alpha1.ClusterTriggerAuthentication{}, err + } + + triggerAuthentications := []kedav1alpha1.ClusterTriggerAuthentication{} + for _, triggerAuthentication := range response.Items { + var ta kedav1alpha1.ClusterTriggerAuthentication + err := runtime.DefaultUnstructuredConverter.FromUnstructured(triggerAuthentication.Object, &ta) + if err != nil { + return []kedav1alpha1.ClusterTriggerAuthentication{}, err + } + + triggerAuthentications = append(triggerAuthentications, ta) + } + + return triggerAuthentications, nil +} + // ListCronJobsInput contains all the information needed to list Kubernetes cron jobs type ListCronJobsInput struct { // LabelSelector is the Kubernetes label selector @@ -451,6 +500,44 @@ func (k KubernetesClient) ListPods(ctx context.Context, input ListPodsInput) ([] return podList.Items, err } +// ListTriggerAuthenticationsInput contains all the information needed to list Kubernetes trigger authentications +type ListTriggerAuthenticationsInput struct { + // Namespace is the Kubernetes namespace + Namespace string + + // LabelSelector is the Kubernetes label selector + LabelSelector string +} + +// ListTriggerAuthentications lists Kubernetes trigger authentications +func (k KubernetesClient) ListTriggerAuthentications(ctx context.Context, input ListTriggerAuthenticationsInput) ([]kedav1alpha1.TriggerAuthentication, error) { + listOptions := metav1.ListOptions{LabelSelector: input.LabelSelector} + + gvr := schema.GroupVersionResource{ + Group: "keda.sh", + Version: "v1alpha1", + Resource: "triggerauthentications", + } + + response, err := k.DynamicClient.Resource(gvr).Namespace(input.Namespace).List(ctx, listOptions) + if err != nil { + return []kedav1alpha1.TriggerAuthentication{}, err + } + + triggerAuthentications := []kedav1alpha1.TriggerAuthentication{} + for _, triggerAuthentication := range response.Items { + var ta kedav1alpha1.TriggerAuthentication + err := runtime.DefaultUnstructuredConverter.FromUnstructured(triggerAuthentication.Object, &ta) + if err != nil { + return []kedav1alpha1.TriggerAuthentication{}, err + } + + triggerAuthentications = append(triggerAuthentications, ta) + } + + return triggerAuthentications, nil +} + // ScaleDeploymentInput contains all the information needed to scale a Kubernetes deployment type ScaleDeploymentInput struct { // Name is the Kubernetes deployment name diff --git a/plugins/scheduler-k3s/template.go b/plugins/scheduler-k3s/template.go index 435d414ce..3bf76fdfd 100644 --- a/plugins/scheduler-k3s/template.go +++ b/plugins/scheduler-k3s/template.go @@ -61,10 +61,16 @@ type GlobalNetwork struct { type GlobalKedaValues struct { // Authentications is a map of authentication objects to use for keda Authentications map[string]KedaAuthentication `yaml:"authentications"` + + // GlobalAuthentications is a map of global authentication objects to use for keda + GlobalAuthentications map[string]KedaAuthentication `yaml:"global_authentications"` } // KedaAuthentication contains the authentication configuration for keda type KedaAuthentication struct { + // Name is the name of the authentication object + Name string `yaml:"name"` + // Type is the type of authentication to use Type string `yaml:"type"` @@ -145,6 +151,9 @@ type ProcessAutoscalingTrigger struct { type ProcessAutoscalingTriggerAuthenticationRef struct { // Name is the name of the authentication object Name string `yaml:"name"` + + // Kind is the kind of authentication object + Kind string `yaml:"kind,omitempty"` } type ProcessHealthchecks struct { diff --git a/plugins/scheduler-k3s/templates/chart/keda-cluster-secret.yaml b/plugins/scheduler-k3s/templates/chart/keda-cluster-secret.yaml new file mode 100644 index 000000000..cd9d997eb --- /dev/null +++ b/plugins/scheduler-k3s/templates/chart/keda-cluster-secret.yaml @@ -0,0 +1,25 @@ +{{- if .Capabilities.APIVersions.Has "keda.sh/v1alpha1" -}} +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} + dokku.com/managed: "true" + {{- if and $.Values.global.annotations $.Values.global.annotations.keda_secret }} + {{- range $k, $v := $.Values.global.annotations.keda_secret }} + {{ $k }}: {{ $v | quote }} + {{- end }} + {{- end }} + labels: + app.kubernetes.io/instance: {{ $.Values.type }} + app.kubernetes.io/name: {{ $.Values.type }} + app.kubernetes.io/part-of: cluster + name: ckta-{{ $.Values.type }} + namespace: keda +data: +{{- with $.Values.secrets }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/plugins/scheduler-k3s/templates/chart/keda-cluster-trigger-authentication.yaml b/plugins/scheduler-k3s/templates/chart/keda-cluster-trigger-authentication.yaml new file mode 100644 index 000000000..b74b9d30b --- /dev/null +++ b/plugins/scheduler-k3s/templates/chart/keda-cluster-trigger-authentication.yaml @@ -0,0 +1,26 @@ +{{- if .Capabilities.APIVersions.Has "keda.sh/v1alpha1" -}} +--- +apiVersion: keda.sh/v1alpha1 +kind: ClusterTriggerAuthentication +metadata: + annotations: + app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} + dokku.com/managed: "true" + {{- if and $.Values.global.annotations $.Values.global.annotations.keda_trigger_authentication }} + {{- range $k, $v := $.Values.global.annotations.keda_trigger_authentication }} + {{ $k }}: {{ $v | quote }} + {{- end }} + {{- end }} + labels: + app.kubernetes.io/instance: {{ $.Values.type }} + app.kubernetes.io/name: {{ $.Values.type }} + app.kubernetes.io/part-of: cluster + name: {{ $.Values.type }} +spec: + secretTargetRef: + {{- range $k, $v := $.Values.secrets }} + - key: {{ $k }} + name: ckta-{{ $.Values.type }} + parameter: {{ $k }} + {{- end }} +{{- end }} diff --git a/plugins/scheduler-k3s/triggers.go b/plugins/scheduler-k3s/triggers.go index 952a79a57..a3195c3ce 100644 --- a/plugins/scheduler-k3s/triggers.go +++ b/plugins/scheduler-k3s/triggers.go @@ -266,7 +266,16 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e return fmt.Errorf("Error getting global labels: %w", err) } - kedaValues, err := getKedaValues(appName) + clientset, err := NewKubernetesClient() + if err != nil { + return fmt.Errorf("Error creating kubernetes client: %w", err) + } + + if err := clientset.Ping(); err != nil { + return fmt.Errorf("kubernetes api not available: %w", err) + } + + kedaValues, err := getKedaValues(ctx, clientset, appName) if err != nil { return fmt.Errorf("Error getting keda values: %w", err) } @@ -454,15 +463,6 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e } } - clientset, err := NewKubernetesClient() - if err != nil { - return fmt.Errorf("Error creating kubernetes client: %w", err) - } - - if err := clientset.Ping(); err != nil { - return fmt.Errorf("kubernetes api not available: %w", err) - } - cronJobs, err := clientset.ListCronJobs(ctx, ListCronJobsInput{ LabelSelector: fmt.Sprintf("app.kubernetes.io/part-of=%s", appName), Namespace: namespace, From 75eeb99a424e8a50cd2ba0aa8821a96207a2531b Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 4 Mar 2024 19:16:22 -0500 Subject: [PATCH 14/22] fix: pin to older version of godotenv The newer version is pulled by something in k3s and somehow is - probably through workspace magic - pulled into the config plugin tests. We pin to the older version since parsing changed at some point, which will cause issues for users. A future update should move this to the latest version and cause a BC break, but for now lets pin as expected. --- plugins/scheduler-k3s/go.mod | 2 ++ plugins/scheduler-k3s/go.sum | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/scheduler-k3s/go.mod b/plugins/scheduler-k3s/go.mod index b4c31ab3e..3d7e4d9bf 100644 --- a/plugins/scheduler-k3s/go.mod +++ b/plugins/scheduler-k3s/go.mod @@ -195,3 +195,5 @@ replace github.com/dokku/dokku/plugins/config => ../config replace github.com/dokku/dokku/plugins/cron => ../cron replace github.com/dokku/dokku/plugins/nginx-vhosts => ../nginx-vhosts + +replace github.com/joho/godotenv => github.com/joho/godotenv v1.2.0 diff --git a/plugins/scheduler-k3s/go.sum b/plugins/scheduler-k3s/go.sum index b289bda23..6486f8292 100644 --- a/plugins/scheduler-k3s/go.sum +++ b/plugins/scheduler-k3s/go.sum @@ -217,8 +217,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc= +github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= From 25ad302ed231983a6236ce2c7c1351852997322f Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 5 Mar 2024 23:27:20 -0500 Subject: [PATCH 15/22] refactor: use enum to represent authentication type --- plugins/scheduler-k3s/functions.go | 5 ++++- plugins/scheduler-k3s/template.go | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index 6ae1cf38b..4d37ac2ec 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -515,11 +515,12 @@ func getAutoscaling(input GetAutoscalingInput) (ProcessAutoscaling, error) { if auth, ok := input.KedaValues.Authentications[trigger.Type]; ok { trigger.AuthenticationRef = &ProcessAutoscalingTriggerAuthenticationRef{ Name: auth.Name, + Kind: string(auth.Kind), } } else if auth, ok := input.KedaValues.GlobalAuthentications[trigger.Type]; ok { trigger.AuthenticationRef = &ProcessAutoscalingTriggerAuthenticationRef{ Name: auth.Name, - Kind: "ClusterTriggerAuthentication", + Kind: string(auth.Kind), } } @@ -563,6 +564,7 @@ func getKedaValues(ctx context.Context, clientset KubernetesClient, appName stri auths[authType] = KedaAuthentication{ Name: fmt.Sprintf("%s-%s", appName, authType), Type: authType, + Kind: KedaAuthenticationKind_TriggerAuthentication, Secrets: make(map[string]string), } } @@ -584,6 +586,7 @@ func getKedaValues(ctx context.Context, clientset KubernetesClient, appName stri authType := strings.TrimPrefix(item.Name, "global-auth-") globalAuths[authType] = KedaAuthentication{ Name: item.Name, + Kind: KedaAuthenticationKind_ClusterTriggerAuthentication, Type: authType, } } diff --git a/plugins/scheduler-k3s/template.go b/plugins/scheduler-k3s/template.go index 3bf76fdfd..9aebcc2f1 100644 --- a/plugins/scheduler-k3s/template.go +++ b/plugins/scheduler-k3s/template.go @@ -71,6 +71,9 @@ type KedaAuthentication struct { // Name is the name of the authentication object Name string `yaml:"name"` + // Kind is the kind of authentication object + Kind KedaAuthenticationKind `yaml:"kind,omitempty"` + // Type is the type of authentication to use Type string `yaml:"type"` @@ -78,6 +81,13 @@ type KedaAuthentication struct { Secrets map[string]string `yaml:"secrets,omitempty"` } +type KedaAuthenticationKind string + +const ( + KedaAuthenticationKind_ClusterTriggerAuthentication KedaAuthenticationKind = "ClusterTriggerAuthentication" + KedaAuthenticationKind_TriggerAuthentication KedaAuthenticationKind = "TriggerAuthentication" +) + type ProcessValues struct { Annotations ProcessAnnotations `yaml:"annotations,omitempty"` Args []string `yaml:"args,omitempty"` From 9bba7843c1128ba8e56ec492676f53bcc53507ee Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 5 Mar 2024 23:40:16 -0500 Subject: [PATCH 16/22] fix: add labels subcommand to scheduler-k3s documentation --- plugins/scheduler-k3s/src/commands/commands.go | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/scheduler-k3s/src/commands/commands.go b/plugins/scheduler-k3s/src/commands/commands.go index 0339c43ea..ee39cc634 100644 --- a/plugins/scheduler-k3s/src/commands/commands.go +++ b/plugins/scheduler-k3s/src/commands/commands.go @@ -23,6 +23,7 @@ Additional commands:` scheduler-k3s:cluster-list [--format json|stdout], Lists all nodes in a Dokku-managed cluster scheduler-k3s:cluster-remove [node-id], Removes client node to a Dokku-managed cluster scheduler-k3s:initialize [--server-ip SERVER_IP] [--taint-scheduling], Initializes a cluster + scheduler-k3s:labels:set () [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear a label for a given app/process-type/resource-type combination scheduler-k3s:report [] [], Displays a scheduler-k3s report for one or more apps scheduler-k3s:set (), Set or clear a scheduler-k3s property for an app scheduler-k3s:show-kubeconfig, Displays the kubeconfig for remote usage From ba7a4d85b65bdc9f6c737ad6e908bc0cc81e4691 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 5 Mar 2024 23:42:25 -0500 Subject: [PATCH 17/22] chore: document k3s autoscaling --- docs/deployment/schedulers/k3s.md | 119 +++++++++++++++++- .../scheduler-k3s/src/commands/commands.go | 2 +- 2 files changed, 118 insertions(+), 3 deletions(-) diff --git a/docs/deployment/schedulers/k3s.md b/docs/deployment/schedulers/k3s.md index d3ff4f6a0..6e0d33519 100644 --- a/docs/deployment/schedulers/k3s.md +++ b/docs/deployment/schedulers/k3s.md @@ -5,10 +5,12 @@ ``` scheduler-k3s:annotations:set () [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear an annotation for a given app/process-type/resource-type combination +scheduler-k3s:autoscaling-auth:set [<--metadata key=value>...], Set or clear a scheduler-k3s autoscaling keda trigger authentication resource for an app scheduler-k3s:cluster-add [ssh://user@host:port] # Adds a server node to a Dokku-managed cluster scheduler-k3s:cluster-list # Lists all nodes in a Dokku-managed cluster scheduler-k3s:cluster-remove [node-id] # Removes client node to a Dokku-managed cluster scheduler-k3s:initialize # Initializes a cluster +scheduler-k3s:labels:set () [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear a label for a given app/process-type/resource-type combination scheduler-k3s:report [] [] # Displays a scheduler-k3s report for one or more apps scheduler-k3s:set [|--global] () # Set or clear a scheduler-k3s property for an app or the scheduler scheduler-k3s:show-kubeconfig # Displays the kubeconfig for remote usage @@ -231,7 +233,9 @@ The default value may be set by passing an empty value for the option. dokku scheduler-k3s:set --global image-pull-secrets ``` -### Enabling letsencrypt integration +### SSL Certificates + +#### Enabling letsencrypt integration By default, letsencrypt is disabled and https port mappings are ignored. To enable, set the `letsencrypt-email-prod` or `letsencrypt-email-stag` property with the `--global` flag: @@ -245,7 +249,7 @@ dokku scheduler-k3s:set --global letsencrypt-email-stag automated@dokku.sh After enabling and rebuilding, all apps with an `http:80` port mapping will have a corresponding `https:443` added and ssl will be automatically enabled. All http requests will then be redirected to https. -### Customizing the letsencrypt server +#### Customizing the letsencrypt server The letsencrypt integration is set to the production letsencrypt server by default. This can be changed on an app-level by setting the `letsencrypt-server` property with the `scheduler-k3s:set` command @@ -350,6 +354,117 @@ dokku scheduler-k3s:annotations:set node-js-app label.key --resource-type deploy dokku scheduler-k3s:labels:set node-js-app label.key --resource-type deployment --process-type web ``` +### Autoscaling + +#### Workload Autoscaling + +> [!IMPORTANT] +> New as of 0.33.8 +> Users with older installations will need to manually install Keda. + +Autoscaling in k3s is managed by [Keda](https://keda.sh/), which integrates with a variety of external metric providers to allow for autoscaling application workloads. + +To enable autoscaling, use the `app.json` `formations.$PROCESS_TYPE.autoscaling` key to manage rules. In addition to the existing configuration used for process management, each process type in the `formations.$PROCESS_TYPE.autoscaling` key can have the following keys: + +- `min_quantity`: The minimum number of instances the application can run. If not specified, the `quantity` specified for the app is used. +- `max_quantity`: The maximum number of instances the application can run. If not specified, the higher value of `quantity` and the `min_quantity` is used. +- `polling_interval_seconds`: (default: 30) The interval to wait for polling each of the configured triggers +- `cooldown_seconds`: (default: 300) The number of seconds to wait in between each scaling event +- `triggers`: A list of autoscaling triggers. + +Autoscaling triggers are passed as is to Keda, and should match the configuration keda uses for a given [scaler](https://keda.sh/docs/2.13/scalers/). Below is an example for [datadog](https://keda.sh/docs/2.13/scalers/datadog/#example-2---driving-scale-directly): + +```json +{ + "formations": { + "web": { + "autoscaling": { + "min_quantity": 1, + "max_quantity": 10, + "triggers": [ + { + "name": "name-for-trigger", + "type": "datadog", + "metadata": { + "query": "per_second(sum:http.requests{service:myservice1}).rollup(max, 300))/180,per_second(sum:http.backlog{service:myservice1}).rollup(max, 300)/30", + "queryValue": "1", + "queryAggregator": "max" + } + } + ] + } + } + } +} +``` + +Each value in the `metadata` stanza can use the following interpolated strings: + +- `DOKKU_DEPLOYMENT_NAME`: The name of the deployment being scaled +- `DOKKU_PROCESS_TYPE`: The name of the process being scaled +- `DOKKU_APP_NAME`: The name of the app being scaled + +#### Workload Autoscaling Authentication + +Most Keda triggers require some form of authentication to query for data. In the Kubernetes API, they are represented by `TriggerAuthentication` and `ClusterTriggerAuthentication` resources. Dokku can manage these via the `scheduler-k3s:autoscaling-auth` commands, and includes generated resources with each helm release generated by a deploy. + +If no app-specific authentication is provided for a given trigger type, Dokku will fallback to any globally defined `ClusterTriggerAuthentication` resources. Autoscaling triggers within an app all share the same `TriggerAuthentication` resources, while `ClusterTriggerAuthentication` resources can be shared across all apps deployed by Dokku within a given cluster. + +##### Creating Authentication Resources + +Users can specify custom authentication resources directly via the Kubernetes api _or_ use the `scheduler-k3s:autoscaling-auth:set` command to create the resources in the Kubernetes cluster. + +```shell +dokku scheduler-k3s:autoscaling-auth:set $APP $TRIGGER --metadata apiKey=some-api-key --metadata appKey=some-app-key +``` + +For example, the following will configure the authentication for all datadog triggers on the specified app: + +```shell +dokku scheduler-k3s:autoscaling-auth:set node-js-app datadog --metadata apiKey=1234567890 --metadata appKey=asdfghjkl --metadata datadogSite=us5.datadoghq.com +``` + +After execution, Dokku will include the following resources for each specified trigger with the helm release generated on subsequent app deploys: + +- `Secret`: an Opaque `Secret` resource storing the authentication credentials +- `TriggerAuthentication`: A `TriggerAuthentication` resource that references the secret for use by triggers + +If the `--global` flag is specified instead of an app name, a custom helm chart is created on the fly with the above resources. + +##### Removing Authentication Resources + +To remove a configured authenticatin resource, run the `scheduler-k3s:autoscaling-auth:set` command with no parameters specified. Subsequent deploys will not include these resources. + +```shell +dokku scheduler-k3s:autoscaling-auth:set $APP $TRIGGER_TYPE +``` + +##### Displaying an Authentication Resource report + +To see a list of authentication resources managed by Dokku, run the `scheduler-k3s:autoscaling-auth:report` command. + +```shell +dokku scheduler-k3s:autoscaling-auth:report $APP +``` + +``` +====> $APP autoscaling-auth report + datadog: configured +``` + +By default, the report will not display configured parameters - making it safe to include in Dokku report output. To include parameters, add the `--include-parameters` flag: + +```shell +dokku scheduler-k3s:autoscaling-auth:report $APP --include-parameters +``` + +``` +====> $APP autoscaling-auth report + datadog: configured + datadog-apiKey: some-api-key + datadog-appKey: some-app-key +``` + ### Using kubectl remotely > [!WARNING] diff --git a/plugins/scheduler-k3s/src/commands/commands.go b/plugins/scheduler-k3s/src/commands/commands.go index ee39cc634..702c3ba96 100644 --- a/plugins/scheduler-k3s/src/commands/commands.go +++ b/plugins/scheduler-k3s/src/commands/commands.go @@ -17,7 +17,7 @@ Manage scheduler-k3s settings for an app Additional commands:` helpContent = ` - scheduler-k3s:autoscaling-auth:set [<--metadata key=value>...], Set or clear a scheduler-k3s autoscaling keda trigger authentication object for an app + scheduler-k3s:autoscaling-auth:set [<--metadata key=value>...], Set or clear a scheduler-k3s autoscaling keda trigger authentication resource for an app scheduler-k3s:annotations:set () [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear an annotation for a given app/process-type/resource-type combination scheduler-k3s:cluster-add [--insecure-allow-unknown-hosts] [--server-ip SERVER_IP] [--taint-scheduling] , Adds a server node to a Dokku-managed cluster scheduler-k3s:cluster-list [--format json|stdout], Lists all nodes in a Dokku-managed cluster From 5b0bc0b132a65f7abbed188d333d6aaedd5ed350 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 6 Mar 2024 00:33:07 -0500 Subject: [PATCH 18/22] fix: ensure the trigger type is properly set when handling global autoscaling auth objects --- plugins/scheduler-k3s/src/subcommands/subcommands.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/scheduler-k3s/src/subcommands/subcommands.go b/plugins/scheduler-k3s/src/subcommands/subcommands.go index 138d68c2f..5aaa8b0c6 100644 --- a/plugins/scheduler-k3s/src/subcommands/subcommands.go +++ b/plugins/scheduler-k3s/src/subcommands/subcommands.go @@ -41,6 +41,10 @@ func main() { args.Parse(os.Args[2:]) appName := args.Arg(0) trigger := args.Arg(1) + if *global { + appName = "--global" + trigger = args.Arg(0) + } err = scheduler_k3s.CommandAutoscalingAuthSet(appName, trigger, *metadata, *global) case "cluster-add": args := flag.NewFlagSet("scheduler-k3s:cluster-add", flag.ExitOnError) From 6b74cd1d6b3bacce64d2908a50f8ad1438d62210 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 6 Mar 2024 00:33:45 -0500 Subject: [PATCH 19/22] feat: implement autoscaling-auth:report --- docs/deployment/schedulers/k3s.md | 18 +++++----- plugins/scheduler-k3s/Makefile | 2 +- plugins/scheduler-k3s/report.go | 34 +++++++++++++++++++ .../src/subcommands/subcommands.go | 8 +++++ plugins/scheduler-k3s/subcommands.go | 23 +++++++++++++ 5 files changed, 76 insertions(+), 9 deletions(-) diff --git a/docs/deployment/schedulers/k3s.md b/docs/deployment/schedulers/k3s.md index 6e0d33519..62b694dbc 100644 --- a/docs/deployment/schedulers/k3s.md +++ b/docs/deployment/schedulers/k3s.md @@ -6,6 +6,7 @@ ``` scheduler-k3s:annotations:set () [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear an annotation for a given app/process-type/resource-type combination scheduler-k3s:autoscaling-auth:set [<--metadata key=value>...], Set or clear a scheduler-k3s autoscaling keda trigger authentication resource for an app +scheduler-k3s:autoscaling-auth:report [--format stdout|json] [--include-metadata] # Displays a scheduler-k3s autoscaling auth report for an app scheduler-k3s:cluster-add [ssh://user@host:port] # Adds a server node to a Dokku-managed cluster scheduler-k3s:cluster-list # Lists all nodes in a Dokku-managed cluster scheduler-k3s:cluster-remove [node-id] # Removes client node to a Dokku-managed cluster @@ -433,7 +434,7 @@ If the `--global` flag is specified instead of an app name, a custom helm chart ##### Removing Authentication Resources -To remove a configured authenticatin resource, run the `scheduler-k3s:autoscaling-auth:set` command with no parameters specified. Subsequent deploys will not include these resources. +To remove a configured authenticatin resource, run the `scheduler-k3s:autoscaling-auth:set` command with no metadata specified. Subsequent deploys will not include these resources. ```shell dokku scheduler-k3s:autoscaling-auth:set $APP $TRIGGER_TYPE @@ -444,7 +445,7 @@ dokku scheduler-k3s:autoscaling-auth:set $APP $TRIGGER_TYPE To see a list of authentication resources managed by Dokku, run the `scheduler-k3s:autoscaling-auth:report` command. ```shell -dokku scheduler-k3s:autoscaling-auth:report $APP +dokku scheduler-k3s:autoscaling-auth:report node-js-app ``` ``` @@ -452,17 +453,18 @@ dokku scheduler-k3s:autoscaling-auth:report $APP datadog: configured ``` -By default, the report will not display configured parameters - making it safe to include in Dokku report output. To include parameters, add the `--include-parameters` flag: +By default, the report will not display configured metadata - making it safe to include in Dokku report output. To include metadata and their values, add the `--include-metadata` flag: ```shell -dokku scheduler-k3s:autoscaling-auth:report $APP --include-parameters +dokku scheduler-k3s:autoscaling-auth:report node-js-app --include-metadata ``` ``` -====> $APP autoscaling-auth report - datadog: configured - datadog-apiKey: some-api-key - datadog-appKey: some-app-key +====> node-js-app autoscaling-auth report + Datadog: configured + Datadog apiKey: 1234567890 + Datadog appKey: asdfghjkl + Datadog datadogSite: us5.datadoghq.com ``` ### Using kubectl remotely diff --git a/plugins/scheduler-k3s/Makefile b/plugins/scheduler-k3s/Makefile index 0fcac0b5a..0efc49c33 100644 --- a/plugins/scheduler-k3s/Makefile +++ b/plugins/scheduler-k3s/Makefile @@ -1,4 +1,4 @@ -SUBCOMMANDS = subcommands/annotations:set subcommands/autoscaling-auth:set subcommands/cluster-add subcommands/cluster-list subcommands/cluster-remove subcommands/initialize subcommands/labels:set subcommands/report subcommands/set subcommands/show-kubeconfig subcommands/uninstall +SUBCOMMANDS = subcommands/annotations:set subcommands/autoscaling-auth:set subcommands/autoscaling-auth:report subcommands/cluster-add subcommands/cluster-list subcommands/cluster-remove subcommands/initialize subcommands/labels:set subcommands/report subcommands/set subcommands/show-kubeconfig subcommands/uninstall TRIGGERS = triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report triggers/scheduler-deploy triggers/scheduler-enter triggers/scheduler-logs triggers/scheduler-post-delete triggers/scheduler-run triggers/scheduler-run-list triggers/scheduler-stop BUILD = commands subcommands triggers PLUGIN_NAME = scheduler-k3s diff --git a/plugins/scheduler-k3s/report.go b/plugins/scheduler-k3s/report.go index 2e25445df..fd388c067 100644 --- a/plugins/scheduler-k3s/report.go +++ b/plugins/scheduler-k3s/report.go @@ -1,6 +1,9 @@ package scheduler_k3s import ( + "fmt" + "strings" + "github.com/dokku/dokku/plugins/common" ) @@ -45,6 +48,37 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { return common.ReportSingleApp("scheduler-k3s", appName, infoFlag, infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter) } +// ReportAutoscalingAuthSingleApp is an internal function that displays the scheduler-k3s autoscaling-auth report for one app +func ReportAutoscalingAuthSingleApp(appName string, format string, includeMetadata bool) error { + properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, TriggerAuthPropertyPrefix) + if err != nil { + return fmt.Errorf("Unable to get property list: %w", err) + } + + infoFlags := map[string]string{} + for key, value := range properties { + metadataKey := strings.TrimPrefix(key, TriggerAuthPropertyPrefix) + authType := strings.SplitN(metadataKey, ".", 2)[0] + if authType == "" { + continue + } + + infoFlags[authType] = "configured" + if includeMetadata { + infoFlags[strings.ReplaceAll(metadataKey, ".", "-")] = value + } + } + + flagKeys := []string{} + for flagKey := range infoFlags { + flagKeys = append(flagKeys, flagKey) + } + + trimPrefix := false + uppercaseFirstCharacter := true + return common.ReportSingleApp("scheduler-k3s", appName, "", infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter) +} + func reportComputedDeployTimeout(appName string) string { return getComputedDeployTimeout(appName) } diff --git a/plugins/scheduler-k3s/src/subcommands/subcommands.go b/plugins/scheduler-k3s/src/subcommands/subcommands.go index 5aaa8b0c6..883dc4a56 100644 --- a/plugins/scheduler-k3s/src/subcommands/subcommands.go +++ b/plugins/scheduler-k3s/src/subcommands/subcommands.go @@ -46,6 +46,14 @@ func main() { trigger = args.Arg(0) } err = scheduler_k3s.CommandAutoscalingAuthSet(appName, trigger, *metadata, *global) + case "autoscaling-auth:report": + args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:report", flag.ExitOnError) + global := args.Bool("global", false, "--global: show a global report") + includeMetadata := args.Bool("include-metadata", false, "--include-metadata: include metadata in the report") + format := args.String("format", "stdout", "format: [ stdout | json ]") + args.Parse(os.Args[2:]) + appName := args.Arg(0) + err = scheduler_k3s.CommandAutoscalingAuthReport(appName, *format, *global, *includeMetadata) case "cluster-add": args := flag.NewFlagSet("scheduler-k3s:cluster-add", flag.ExitOnError) allowUknownHosts := args.Bool("insecure-allow-unknown-hosts", false, "insecure-allow-unknown-hosts: allow unknown hosts") diff --git a/plugins/scheduler-k3s/subcommands.go b/plugins/scheduler-k3s/subcommands.go index 315c70bc9..2fbd83624 100644 --- a/plugins/scheduler-k3s/subcommands.go +++ b/plugins/scheduler-k3s/subcommands.go @@ -86,6 +86,29 @@ func CommandAutoscalingAuthSet(appName string, trigger string, metadata map[stri return nil } +// CommandAutoscalingAuthReport displays a scheduler-k3s autoscaling keda trigger authentication report for one or more apps +func CommandAutoscalingAuthReport(appName string, format string, global bool, includeMetadata bool) error { + if len(appName) == 0 && !global { + return fmt.Errorf("Missing required app name or --global flag") + } + + if len(appName) > 0 && global { + return fmt.Errorf("Cannot specify both app name and --global flag") + } + + if !global { + if err := common.VerifyAppName(appName); err != nil { + return err + } + } + + if len(appName) > 0 { + return ReportAutoscalingAuthSingleApp(appName, format, includeMetadata) + } + + return ReportAutoscalingAuthSingleApp("--global", format, includeMetadata) +} + // CommandInitialize initializes a k3s cluster on the local server func CommandInitialize(ingressClass string, serverIP string, taintScheduling bool) error { if ingressClass != "nginx" && ingressClass != "traefik" { From 7c58bbf79238872c6debfb658221de8a394b8971 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 6 Mar 2024 01:11:40 -0500 Subject: [PATCH 20/22] feat: setup cluster trigger authentication objects --- plugins/scheduler-k3s/functions.go | 112 ++++++++++++++++++ plugins/scheduler-k3s/subcommands.go | 21 ++++ plugins/scheduler-k3s/template.go | 8 ++ .../templates/chart/keda-cluster-secret.yaml | 8 +- .../keda-cluster-trigger-authentication.yaml | 8 +- .../templates/chart/keda-scaled-object.yaml | 14 +-- .../templates/chart/keda-secret.yaml | 7 +- 7 files changed, 151 insertions(+), 27 deletions(-) diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index 4d37ac2ec..df3decc37 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -122,6 +122,118 @@ type WaitForPodToExistInput struct { LabelSelector string } +// applyKedaClusterTriggerAuthentications applies keda cluster trigger authentications chart to the cluster +func applyKedaClusterTriggerAuthentications(ctx context.Context, triggerType string, metadata map[string]string) error { + chartDir, err := os.MkdirTemp("", "keda-cluster-trigger-authentications-chart-") + if err != nil { + return fmt.Errorf("Error creating keda-cluster-trigger-authentications chart directory: %w", err) + } + defer os.RemoveAll(chartDir) + + // create the chart.yaml + chart := &Chart{ + ApiVersion: "v2", + AppVersion: "1.0.0", + Icon: "https://dokku.com/assets/dokku-logo.svg", + Name: fmt.Sprintf("keda-cluster-trigger-authentications-%s", triggerType), + Version: "0.0.1", + } + + err = writeYaml(WriteYamlInput{ + Object: chart, + Path: filepath.Join(chartDir, "Chart.yaml"), + }) + if err != nil { + return fmt.Errorf("Error writing keda-cluster-trigger-authentications chart: %w", err) + } + + // create the values.yaml + values := ClusterKedaValues{ + Secrets: map[string]string{}, + Type: triggerType, + } + + for key, value := range metadata { + values.Secrets[key] = base64.StdEncoding.EncodeToString([]byte(value)) + } + + if err := os.MkdirAll(filepath.Join(chartDir, "templates"), os.FileMode(0755)); err != nil { + return fmt.Errorf("Error creating keda-cluster-trigger-authentications chart templates directory: %w", err) + } + + err = writeYaml(WriteYamlInput{ + Object: values, + Path: filepath.Join(chartDir, "values.yaml"), + }) + if err != nil { + return fmt.Errorf("Error writing chart: %w", err) + } + + templateFiles := []string{"keda-cluster-trigger-authentication", "keda-cluster-secret"} + for _, template := range templateFiles { + b, err := templates.ReadFile(fmt.Sprintf("templates/chart/%s.yaml", template)) + if err != nil { + return fmt.Errorf("Error reading %s template: %w", template, err) + } + + filename := filepath.Join(chartDir, "templates", fmt.Sprintf("%s.yaml", template)) + err = os.WriteFile(filename, b, os.FileMode(0644)) + if err != nil { + return fmt.Errorf("Error writing %s template: %w", template, err) + } + + if os.Getenv("DOKKU_TRACE") == "1" { + common.CatFile(filename) + } + } + + b, err := templates.ReadFile("templates/chart/_helpers.tpl") + if err != nil { + return fmt.Errorf("Error reading _helpers template: %w", err) + } + + helpersFile := filepath.Join(chartDir, "templates", "_helpers.tpl") + err = os.WriteFile(helpersFile, b, os.FileMode(0644)) + if err != nil { + return fmt.Errorf("Error writing _helpers template: %w", err) + } + + if os.Getenv("DOKKU_TRACE") == "1" { + common.CatFile(helpersFile) + } + + // install the chart + helmAgent, err := NewHelmAgent("keda", DeployLogPrinter) + if err != nil { + return fmt.Errorf("Error creating helm agent: %w", err) + } + + chartPath, err := filepath.Abs(chartDir) + if err != nil { + return fmt.Errorf("Error getting chart path: %w", err) + } + + timeoutDuration, err := time.ParseDuration("300s") + if err != nil { + return fmt.Errorf("Error parsing deploy timeout duration: %w", err) + } + + err = helmAgent.InstallOrUpgradeChart(ctx, ChartInput{ + ChartPath: chartPath, + Namespace: "keda", + ReleaseName: fmt.Sprintf("keda-cluster-trigger-authentications-%s", triggerType), + RollbackOnFailure: true, + Timeout: timeoutDuration, + }) + if err != nil { + return fmt.Errorf("Error installing keda-cluster-trigger-authentications-%s chart: %w", triggerType, err) + } + + common.LogInfo1Quiet(fmt.Sprintf("Applied keda-cluster-trigger-authentications-%s chart", triggerType)) + + return nil +} + func applyClusterIssuers(ctx context.Context) error { chartDir, err := os.MkdirTemp("", "cluster-issuer-chart-") if err != nil { diff --git a/plugins/scheduler-k3s/subcommands.go b/plugins/scheduler-k3s/subcommands.go index 2fbd83624..abe02da91 100644 --- a/plugins/scheduler-k3s/subcommands.go +++ b/plugins/scheduler-k3s/subcommands.go @@ -75,6 +75,19 @@ func CommandAutoscalingAuthSet(appName string, trigger string, metadata map[stri return fmt.Errorf("Unable to delete property: %w", err) } } + + if appName == "--global" { + helmAgent, err := NewHelmAgent("keda", DeployLogPrinter) + if err != nil { + return fmt.Errorf("Unable to create helm agent: %w", err) + } + + releaseName := fmt.Sprintf("keda-cluster-trigger-authentications-%s", trigger) + if err := helmAgent.UninstallChart(releaseName); err != nil { + return fmt.Errorf("Unable to uninstall chart: %w", err) + } + } + return nil } @@ -83,6 +96,14 @@ func CommandAutoscalingAuthSet(appName string, trigger string, metadata map[stri return fmt.Errorf("Unable to set property: %w", err) } } + + if appName == "--global" { + err := applyKedaClusterTriggerAuthentications(context.Background(), trigger, metadata) + if err != nil { + return fmt.Errorf("Unable to install chart: %w", err) + } + } + return nil } diff --git a/plugins/scheduler-k3s/template.go b/plugins/scheduler-k3s/template.go index 9aebcc2f1..d5fb94ba3 100644 --- a/plugins/scheduler-k3s/template.go +++ b/plugins/scheduler-k3s/template.go @@ -27,6 +27,14 @@ type ClusterIssuerValues struct { ClusterIssuers map[string]ClusterIssuer `yaml:"cluster_issuers"` } +type ClusterKedaValues struct { + Global struct { + Annotations ProcessAnnotations `yaml:"annotations,omitempty"` + } `yaml:"global"` + Secrets map[string]string `yaml:"secrets"` + Type string `yaml:"type"` +} + type AppValues struct { Global GlobalValues `yaml:"global"` Processes map[string]ProcessValues `yaml:"processes"` diff --git a/plugins/scheduler-k3s/templates/chart/keda-cluster-secret.yaml b/plugins/scheduler-k3s/templates/chart/keda-cluster-secret.yaml index cd9d997eb..b60c4424d 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-cluster-secret.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-cluster-secret.yaml @@ -4,17 +4,13 @@ apiVersion: v1 kind: Secret metadata: annotations: - app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} dokku.com/managed: "true" - {{- if and $.Values.global.annotations $.Values.global.annotations.keda_secret }} - {{- range $k, $v := $.Values.global.annotations.keda_secret }} - {{ $k }}: {{ $v | quote }} - {{- end }} - {{- end }} + {{ include "print.annotations" (dict "config" $.Values.global "key" "keda_secret") | indent 4 }} labels: app.kubernetes.io/instance: {{ $.Values.type }} app.kubernetes.io/name: {{ $.Values.type }} app.kubernetes.io/part-of: cluster + {{ include "print.labels" (dict "config" $.Values.global "key" "keda_secret") | indent 4 }} name: ckta-{{ $.Values.type }} namespace: keda data: diff --git a/plugins/scheduler-k3s/templates/chart/keda-cluster-trigger-authentication.yaml b/plugins/scheduler-k3s/templates/chart/keda-cluster-trigger-authentication.yaml index b74b9d30b..581698fa9 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-cluster-trigger-authentication.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-cluster-trigger-authentication.yaml @@ -4,17 +4,13 @@ apiVersion: keda.sh/v1alpha1 kind: ClusterTriggerAuthentication metadata: annotations: - app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} dokku.com/managed: "true" - {{- if and $.Values.global.annotations $.Values.global.annotations.keda_trigger_authentication }} - {{- range $k, $v := $.Values.global.annotations.keda_trigger_authentication }} - {{ $k }}: {{ $v | quote }} - {{- end }} - {{- end }} + {{ include "print.annotations" (dict "config" $.Values.global "key" "keda_trigger_authentication") | indent 4 }} labels: app.kubernetes.io/instance: {{ $.Values.type }} app.kubernetes.io/name: {{ $.Values.type }} app.kubernetes.io/part-of: cluster + {{ include "print.labels" (dict "config" $.Values.global "key" "keda_trigger_authentication") | indent 4 }} name: {{ $.Values.type }} spec: secretTargetRef: diff --git a/plugins/scheduler-k3s/templates/chart/keda-scaled-object.yaml b/plugins/scheduler-k3s/templates/chart/keda-scaled-object.yaml index 7df2f250d..13e766797 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-scaled-object.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-scaled-object.yaml @@ -8,20 +8,14 @@ metadata: annotations: app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} dokku.com/managed: "true" - {{- if and $.Values.global.annotations $.Values.global.annotations.keda_scaled_object }} - {{- range $k, $v := $.Values.global.annotations.keda_scaled_object }} - {{ $k }}: {{ $v | quote }} - {{- end }} - {{- end }} - {{- if and $config.annotations $config.annotations.keda_scaled_object }} - {{- range $k, $v := $config.annotations.keda_scaled_object }} - {{ $k }}: {{ $v | quote }} - {{- end }} - {{- end }} + {{ include "print.annotations" (dict "config" $.Values.global "key" "keda_scaled_object") | indent 4 }} + {{ include "print.annotations" (dict "config" $config "key" "keda_scaled_object") | indent 4 }} labels: app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $processName }} app.kubernetes.io/name: {{ $processName }} app.kubernetes.io/part-of: {{ $.Values.global.app_name }} + {{ include "print.labels" (dict "config" $.Values.global "key" "keda_scaled_object") | indent 4 }} + {{ include "print.labels" (dict "config" $config "key" "keda_scaled_object") | indent 4 }} name: {{ $.Values.global.app_name}}-{{ $processName }} namespace: {{ $.Values.global.namespace }} spec: diff --git a/plugins/scheduler-k3s/templates/chart/keda-secret.yaml b/plugins/scheduler-k3s/templates/chart/keda-secret.yaml index c906bdde4..d57815ffa 100644 --- a/plugins/scheduler-k3s/templates/chart/keda-secret.yaml +++ b/plugins/scheduler-k3s/templates/chart/keda-secret.yaml @@ -7,15 +7,12 @@ metadata: annotations: app.kubernetes.io/version: {{ $.Values.global.deploment_id | quote }} dokku.com/managed: "true" - {{- if and $.Values.global.annotations $.Values.global.annotations.keda_secret }} - {{- range $k, $v := $.Values.global.annotations.keda_secret }} - {{ $k }}: {{ $v | quote }} - {{- end }} - {{- end }} + {{ include "print.annotations" (dict "config" $.Values.global "key" "keda_secret") | indent 4 }} labels: app.kubernetes.io/instance: {{ $.Values.global.app_name }}-{{ $config.type }} app.kubernetes.io/name: {{ $config.type }} app.kubernetes.io/part-of: {{ $.Values.global.app_name }} + {{ include "print.labels" (dict "config" $.Values.global "key" "keda_secret") | indent 4 }} name: kta-{{ $.Values.global.app_name }}-{{ $config.type }} namespace: {{ $.Values.global.namespace }} data: From 3fa1cdc93858b37fcc265140274d6e24e1d0d5df Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 6 Mar 2024 01:50:02 -0500 Subject: [PATCH 21/22] tests: add test for keda triggers --- tests/unit/scheduler-k3s.bats | 44 ++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tests/unit/scheduler-k3s.bats b/tests/unit/scheduler-k3s.bats index 530d29bda..993aa66a0 100644 --- a/tests/unit/scheduler-k3s.bats +++ b/tests/unit/scheduler-k3s.bats @@ -86,7 +86,7 @@ uninstall_k3s() { INGRESS_CLASS=nginx TAINT_SCHEDULING=true install_k3s } -@test "(scheduler-k3s) deploy traefik [resource]" { +@test "(scheduler-k3s) deploy traefik [resource] [autoscaling]" { if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN" fi @@ -103,6 +103,11 @@ uninstall_k3s() { echo "status: $status" assert_success + run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set node-js-app memory --metadata some-key=1234567890 --metadata some-value=asdfghjkl" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku git:sync --build $TEST_APP https://github.com/dokku/smoke-test-app.git" echo "output: $output" echo "status: $status" @@ -115,6 +120,43 @@ uninstall_k3s() { assert_http_localhost_response "http" "$TEST_APP.dokku.me" "80" "" "python/http.server" + # include autoscaling tests + run /bin/bash -c "kubectl get scaledobjects.keda.sh $TEST_APP-web -o=jsonpath='{.spec.triggers[0].authenticationRef.name}'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "$TEST_APP-memory" + + run /bin/bash -c "kubectl get triggerauthentications.keda.sh $TEST_APP-memory -o=jsonpath='{.spec.secretTargetRef[0].key}'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "some-key" + + run /bin/bash -c "kubectl get triggerauthentications.keda.sh $TEST_APP-memory -o=jsonpath='{.spec.secretTargetRef[0].name}'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "kta-test-memory" + + run /bin/bash -c "kubectl get triggerauthentications.keda.sh $TEST_APP-memory -o=jsonpath='{.spec.secretTargetRef[0].parameter}'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "some-key" + + run /bin/bash -c "kubectl get secret kta-$TEST_APP-memory -o=jsonpath='{.data.some-key}' | base64 --decode" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "1234567890" + + run /bin/bash -c "kubectl get secret kta-$TEST_APP-memory -o=jsonpath='{.data.some-value}' | base64 --decode" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "asdfghjkl" + # include resource tests run /bin/bash -c "kubectl get pods -o=jsonpath='{.items[*]..resources.requests.cpu}'" echo "output: $output" From 22ba40a2d4bc19cc9f23e1d5eaf3399e6e9ee42c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 6 Mar 2024 02:45:15 -0500 Subject: [PATCH 22/22] tests: correct issues in referencing the app name within tests --- tests/unit/scheduler-k3s.bats | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/scheduler-k3s.bats b/tests/unit/scheduler-k3s.bats index 993aa66a0..c2a4ffc41 100644 --- a/tests/unit/scheduler-k3s.bats +++ b/tests/unit/scheduler-k3s.bats @@ -103,7 +103,7 @@ uninstall_k3s() { echo "status: $status" assert_success - run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set node-js-app memory --metadata some-key=1234567890 --metadata some-value=asdfghjkl" + run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP memory --metadata some-key=1234567890 --metadata some-value=asdfghjkl" echo "output: $output" echo "status: $status" assert_success @@ -137,7 +137,7 @@ uninstall_k3s() { echo "output: $output" echo "status: $status" assert_success - assert_output "kta-test-memory" + assert_output "kta-$TEST_APP-memory" run /bin/bash -c "kubectl get triggerauthentications.keda.sh $TEST_APP-memory -o=jsonpath='{.spec.secretTargetRef[0].parameter}'" echo "output: $output"