From 2b6fd5601e0016f3055963cad5e6803e66703ee9 Mon Sep 17 00:00:00 2001 From: Jirka Kremser <535866+jkremser@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:04:35 +0200 Subject: [PATCH] First shot of the agent helm chart (#51) * All our tweaks should go here If there is another thing to add to our fork, pls add it here. Example: ``` echo -e "#foo?\n\n bar?" > foo-bar.md # Pls keep adding the changes to standalone files that are not present in the upstream to mitigate the risk of conflict add foo-bar.md git commit -s --ammend yada yada ``` Signed-off-by: Jirka Kremser Signed-off-by: Jan Wozniak Signed-off-by: Jirka Kremser * ensure keda ns in smoketests before chart installation (#36) Signed-off-by: Jan Wozniak * smoke_tests: wait for deployments availability (#37) Signed-off-by: Jan Wozniak * fix keda chart deployment smoketest check missing ns (#38) Signed-off-by: Jan Wozniak * Don't skip the publish step (#39) Signed-off-by: Jirka Kremser * http-add-on: allow fetching certs from secrets (#40) Signed-off-by: Jan Wozniak * http-add-on: disable explicit tls secret mount Signed-off-by: Jan Wozniak * restricted scc (#41) Signed-off-by: Zbynek Roubalik * ci: refactor kedify chart release trigger (#42) Signed-off-by: Jan Wozniak * bump kube-rbax-proxy to v0.16.0 (#43) Signed-off-by: Zbynek Roubalik * ci: fix missing quote and pipe Signed-off-by: Jan Wozniak * http-add-on: attempt HTTP2 upgrade by default (#45) Signed-off-by: Jan Wozniak * http-add-on: allow configuring prometheus and otel collectors (#46) * http-add-on: allow configuring prometheus and otel collectors Signed-off-by: Jan Wozniak * helm-docs Signed-off-by: Jan Wozniak --------- Signed-off-by: Jan Wozniak * gh release chart: fix env var evaluation (#47) Signed-off-by: Jan Wozniak * http-add-on: metrics service (#48) Signed-off-by: Jan Wozniak * http-add-on: disable interceptor pdb (#49) Signed-off-by: Jan Wozniak * http-add-on: RBAC to emit events (#50) Signed-off-by: Jan Wozniak * First shot of the agent helm chart Signed-off-by: Jirka Kremser * more granular rbac Signed-off-by: Jirka Kremser * more granular rbac vol 2 Signed-off-by: Jirka Kremser * Install also CRD and CR if requested, this is done using pre install hook (for crd) and post install hook for CR Signed-off-by: Jirka Kremser * fixes for agent chart (#52) * fixes for agent chart Signed-off-by: Jan Wozniak * image tag proposal Signed-off-by: Jan Wozniak * add cluster name + option to disable kedifyconfig Signed-off-by: Jan Wozniak * simplify kedify cr template Signed-off-by: Jan Wozniak * narrow down autowiring rbac Signed-off-by: Jan Wozniak --------- Signed-off-by: Jan Wozniak --------- Signed-off-by: Jirka Kremser Signed-off-by: Jan Wozniak Signed-off-by: Zbynek Roubalik Co-authored-by: Jan Wozniak Co-authored-by: Zbynek Roubalik Co-authored-by: Jan Wozniak --- .github/workflows/gh-release-chart.yml | 69 ++- kedify-agent/.gitignore | 1 + kedify-agent/.helmignore | 23 + kedify-agent/Chart.lock | 9 + kedify-agent/Chart.yaml | 20 + kedify-agent/files/kedify-configuration.yaml | 304 ++++++++++++ kedify-agent/files/kedify-scalingpolicy.yaml | 312 ++++++++++++ kedify-agent/templates/NOTES.txt | 17 + kedify-agent/templates/_helpers.tpl | 79 +++ kedify-agent/templates/agent-deployment.yaml | 138 ++++++ kedify-agent/templates/agent-rbac.yaml | 458 ++++++++++++++++++ kedify-agent/templates/api-key-secret.yaml | 8 + .../templates/cr-install/cr-configmap.yaml | 41 ++ kedify-agent/templates/cr-install/cr-job.yaml | 74 +++ .../templates/cr-install/cr-rbac.yaml | 54 +++ .../templates/crd-install/crd-configmap.yaml | 27 ++ .../templates/crd-install/crd-job.yaml | 65 +++ .../templates/crd-install/crd-rbac.yaml | 66 +++ kedify-agent/templates/httpaddon-rbac.yaml | 244 ++++++++++ kedify-agent/templates/keda-rbac.yaml | 370 ++++++++++++++ kedify-agent/templates/serviceaccount.yaml | 12 + kedify-agent/values.schema.json | 34 ++ kedify-agent/values.yaml | 111 +++++ 23 files changed, 2534 insertions(+), 2 deletions(-) create mode 100644 kedify-agent/.gitignore create mode 100644 kedify-agent/.helmignore create mode 100644 kedify-agent/Chart.lock create mode 100644 kedify-agent/Chart.yaml create mode 100644 kedify-agent/files/kedify-configuration.yaml create mode 100644 kedify-agent/files/kedify-scalingpolicy.yaml create mode 100644 kedify-agent/templates/NOTES.txt create mode 100644 kedify-agent/templates/_helpers.tpl create mode 100644 kedify-agent/templates/agent-deployment.yaml create mode 100644 kedify-agent/templates/agent-rbac.yaml create mode 100644 kedify-agent/templates/api-key-secret.yaml create mode 100644 kedify-agent/templates/cr-install/cr-configmap.yaml create mode 100644 kedify-agent/templates/cr-install/cr-job.yaml create mode 100644 kedify-agent/templates/cr-install/cr-rbac.yaml create mode 100644 kedify-agent/templates/crd-install/crd-configmap.yaml create mode 100644 kedify-agent/templates/crd-install/crd-job.yaml create mode 100644 kedify-agent/templates/crd-install/crd-rbac.yaml create mode 100644 kedify-agent/templates/httpaddon-rbac.yaml create mode 100644 kedify-agent/templates/keda-rbac.yaml create mode 100644 kedify-agent/templates/serviceaccount.yaml create mode 100644 kedify-agent/values.schema.json create mode 100644 kedify-agent/values.yaml diff --git a/.github/workflows/gh-release-chart.yml b/.github/workflows/gh-release-chart.yml index 0e9528c8..4332626c 100644 --- a/.github/workflows/gh-release-chart.yml +++ b/.github/workflows/gh-release-chart.yml @@ -15,6 +15,7 @@ on: options: - keda - http-add-on + - kedify-agent permissions: contents: read @@ -72,6 +73,20 @@ jobs: kubectl wait --timeout=600s -nkeda --for=condition=ready pod -lapp.kubernetes.io/component=interceptor,app.kubernetes.io/part-of=keda-add-ons-http echo -e "\n\n\n pods:\n\n" kubectl get pods -A + - name: Smoke test helm rendering and deployability (kedify agent chart) + if: inputs.chart == 'kedify-agent' + run: | + set -o pipefail + kubectl create ns keda --dry-run=client -o yaml | kubectl apply -f - + helm dependency build kedify-agent + helm template ./kedify-agent -nkeda \ + --set agent.apiKey=kfy_facefaceface424242d0f7e1963c7d542aee9d62b66c4c705ec70108655b3c000 \ + --set agent.orgId=9151f21f-42ab-42ab-42ab-f4af67cddf54 | kubectl apply -f - + sleep 10 + kubectl rollout status --timeout=300s -nkeda deploy/kedify-agent + sleep 5 + echo -e "\n\n\n pods:\n\n" + kubectl get pods -A publish: runs-on: ubuntu-latest @@ -81,6 +96,7 @@ jobs: with: fetch-depth: 0 - name: Add the -N suffix to chart's version + id: version run: | set -xeuo pipefail version=${{ inputs.version }} @@ -94,12 +110,20 @@ jobs: sed 's/\.\([0-9]\+\)$/-\1/') version=$(echo "$last_version" | awk -F'-' '{print $1 "-" $2+1}') fi + echo "newVersion=${version}" >> ${GITHUB_OUTPUT} sed -i ${{ inputs.chart }}/Chart.yaml -e "s;^version:.*;version: ${version};" - name: Publish Helm chart uses: stefanprodan/helm-gh-pages@master with: token: ${{ secrets.PAT_TOKEN }} charts_dir: "." + - name: Push Tag + uses: mathieudutour/github-tag-action@v6.2 + with: + github_token: ${{ secrets.PAT_TOKEN }} + create_annotated_tag: true + tag_prefix: "" + custom_tag: ${{ inputs.chart }}-${{ steps.version.outputs.newVersion }} - name: Create k3s cluster if: inputs.chart == 'keda' uses: AbsaOSS/k3d-action@v2 @@ -126,7 +150,7 @@ jobs: --create-namespace \ --timeout 300s \ --wait \ - --version ${{ inputs.version }} \ + --version ${{ steps.version.outputs.newVersion }} \ --set customManagedBy=kedify && break set +x [ "$i" = "16" ] && exit 1 @@ -148,5 +172,46 @@ jobs: echo -e "\n\nthe following command is supposed to fail:\n\n" helm template keda kedify/keda \ - --version $${{ inputs.version }} \ + --version ${{ steps.version.outputs.newVersion }} \ --set crds.install=f4lse || true + + - name: Smoke test helm installation + if: inputs.chart == 'kedify-agent' + run: | + # exp-backoff - we wait for pages to become available here + for i in $(seq 16) + do + _sec=$(echo "1.5^$i" | bc) + echo "Waiting ${_sec} seconds.." + sleep ${_sec} + helm repo add kedify https://kedify.github.io/charts || continue + helm repo update + set -x + helm upgrade -i agent kedify/kedify-agent \ + -n keda \ + --create-namespace \ + --set agent.apiKey=kfy_facefaceface424242d0f7e1963c7d542aee9d62b66c4c705ec70108655b3c000 \ + --set agent.orgId=9151f21f-42ab-42ab-42ab-f4af67cddf54 \ + --timeout 300s \ + --wait \ + --version ${{ steps.version.outputs.newVersion }} && break + set +x + [ "$i" = "16" ] && exit 1 + done + kubectl rollout status --timeout=300s -nkeda deploy/kedify-agent + + echo -e "\n\n\n pods:\n\n" + kubectl get pods -A + + sleep 5 + echo "::group::logs" + kubectl logs -lcontrol-plane=kedify-agent --tail=-1 + echo "::endgroup::" + + echo "::group::values.yaml" + helm get values -n keda agent + echo "::endgroup::" + + echo "::group::resulting YAML manifests" + helm get manifest -n keda agent + echo "::endgroup::" diff --git a/kedify-agent/.gitignore b/kedify-agent/.gitignore new file mode 100644 index 00000000..948259a7 --- /dev/null +++ b/kedify-agent/.gitignore @@ -0,0 +1 @@ +charts/*.tgz diff --git a/kedify-agent/.helmignore b/kedify-agent/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/kedify-agent/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/kedify-agent/Chart.lock b/kedify-agent/Chart.lock new file mode 100644 index 00000000..3bf206a9 --- /dev/null +++ b/kedify-agent/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: keda + repository: https://kedify.github.io/charts + version: v2.15.1-0 +- name: keda-add-ons-http + repository: https://kedify.github.io/charts + version: v0.8.0-8 +digest: sha256:59b25a8b78de8619e36b9d35c08c601c2791b7d23c24243168076fc62cee6c93 +generated: "2024-10-18T09:56:29.18376111+02:00" diff --git a/kedify-agent/Chart.yaml b/kedify-agent/Chart.yaml new file mode 100644 index 00000000..eb4156b9 --- /dev/null +++ b/kedify-agent/Chart.yaml @@ -0,0 +1,20 @@ +apiVersion: v2 +name: kedify-agent +description: Kedify agent - Helm Chart +kubeVersion: ">=v1.23.0-0" +type: application +version: "v0.0.54" +appVersion: "v0.0.54" +dependencies: + - name: keda + repository: https://kedify.github.io/charts + version: v2.15.1-0 + condition: keda.enabled + - name: keda-add-ons-http + repository: https://kedify.github.io/charts + version: v0.8.0-8 + condition: kedaAddOnsHttp.enabled +home: https://github.com/kedify/charts +sources: + - https://github.com/kedify/agent + - https://github.com/kedify/charts diff --git a/kedify-agent/files/kedify-configuration.yaml b/kedify-agent/files/kedify-configuration.yaml new file mode 100644 index 00000000..ba55e512 --- /dev/null +++ b/kedify-agent/files/kedify-configuration.yaml @@ -0,0 +1,304 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: kedifyconfigurations.install.kedify.io +spec: + group: install.kedify.io + names: + kind: KedifyConfiguration + listKind: KedifyConfigurationList + plural: kedifyconfigurations + shortNames: + - kedify + - kedifyconfig + singular: kedifyconfiguration + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: KEDA version + jsonPath: .status.installations.keda.kedaVersion + name: Version + type: string + - description: Installation mode + jsonPath: .spec.kedaInstallations[].mode + name: Mode + type: string + - description: HTTTP Addon version + jsonPath: .status.installations.keda.httpAddonVersion + name: HTTP-Addon + priority: 20 + type: string + - description: Health of Kedify Agent + jsonPath: .status.agent.phase + name: Agent + type: string + - description: Health of KEDA Operator + jsonPath: .status.installations.keda.deployments.keda-operator.phase + name: KEDA + type: string + - description: Health of aggregated API Service (v1beta1.external.metrics.k8s.io) + jsonPath: .status.apiService.phase + name: API Service + type: string + - description: Health of KEDA's internal Metric Server + jsonPath: .status.installations.keda.deployments.keda-operator-metrics-apiserver.phase + name: Metric Server + priority: 20 + type: string + - description: Health of KEDA's Admission controller + jsonPath: .status.installations.keda.deployments.keda-admission-webhooks.phase + name: Admission + priority: 20 + type: string + - description: Health of KEDA's HTTP Addon interceptor + jsonPath: .status.installations.keda.deployments.keda-add-ons-http-interceptor.phase + name: Interceptor + priority: 20 + type: string + - description: When the resources was created + jsonPath: .metadata.creationTimestamp + name: Created + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: KedifyConfiguration is the Schema for the KedifyConfiguration + API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KedifyConfigurationSpec defines the desired state of KedifyConfiguration + properties: + clusterName: + description: ClusterName is the name of this k8s cluster in the Kedify + Dashboard + type: string + kedaInstallations: + description: KEDAInstallations defines the KEDA installations options + items: + description: KEDAInstallation defines the desired state of a KEDA + installation + properties: + agentAutoUpdate: + description: AutoUpdate controls whether the agent should be + auto updated to latest released version + type: boolean + httpAddonHelm: + description: HTTPAddonHelm defines the http-addon Helm values + and chart version for HTTP Addon installation + properties: + appVersion: + description: AppVersion defines the actual version of the + application that will be installed (KEDA or HttpAddon, + this should correspond with the container image tags) + type: string + autoUpdate: + description: AutoUpdate controls what strategy should be + used for updating the AppVersion when new releases are + available + enum: + - LatestReleased + - BuildsOnly + - PatchesOnly + - Disabled + type: string + chartVersion: + description: ChartVersion defines the Helm chart version + type: string + enabled: + description: Enabled determines whether the helm chart should + be installed or not (for KEDA helm chart ManagementMode + needs to also allow this) + type: boolean + values: + description: Values defines the Helm values + type: string + type: object + kedaHelm: + description: KedaHelm defines the Helm values and chart version + for KEDA installation + properties: + appVersion: + description: AppVersion defines the actual version of the + application that will be installed (KEDA or HttpAddon, + this should correspond with the container image tags) + type: string + autoUpdate: + description: AutoUpdate controls what strategy should be + used for updating the AppVersion when new releases are + available + enum: + - LatestReleased + - BuildsOnly + - PatchesOnly + - Disabled + type: string + chartVersion: + description: ChartVersion defines the Helm chart version + type: string + enabled: + description: Enabled determines whether the helm chart should + be installed or not (for KEDA helm chart ManagementMode + needs to also allow this) + type: boolean + values: + description: Values defines the Helm values + type: string + type: object + mode: + description: |- + Mode defines how Agent should manage the KEDA installation + Managed: Agent will manage KEDA throughout its lifecycle + InstallOnly: Agent will install KEDA but not manage it + Adopt: Agent will adopt an existing KEDA installation + enum: + - Managed + - InstallOnly + - Adopt + - Auto + - Disabled + type: string + name: + description: Name of the KEDA installation + type: string + namespace: + description: Namespace where KEDA should be installed + type: string + telemetry: + description: Telemetry defines the telemetry configuration + properties: + controlPlane: + description: ControlPlane defines the telemetry configuration + for the control plane + properties: + disabled: + description: Disabled defines if telemetry should be + disabled, enabled by default + type: boolean + interval: + description: Interval defines the interval for telemetry + in seconds, 30 by default + format: int32 + type: integer + type: object + kedaResources: + description: KedaResources defines the telemetry configuration + for the KEDA resources + properties: + disabled: + description: Disabled defines if telemetry should be + disabled, enabled by default + type: boolean + interval: + description: Interval defines the interval for telemetry + in seconds, 30 by default + format: int32 + type: integer + type: object + kubernetesResources: + description: KubernetesResources defines the telemetry configuration + for the Kubernetes resources + properties: + disabled: + description: Disabled defines if telemetry should be + disabled, enabled by default + type: boolean + interval: + description: Interval defines the interval for telemetry + in seconds, 30 by default + format: int32 + type: integer + type: object + type: object + required: + - agentAutoUpdate + - mode + type: object + type: array + type: object + status: + description: KedifyConfigurationStatus defines the observed state of KedifyConfiguration + properties: + agent: + description: KedifyConfigurationAgentStatus defines the observed state + of a KedifyConfiguration agent + properties: + phase: + type: string + reason: + type: string + uninstallationStartedAt: + format: date-time + type: string + version: + type: string + type: object + apiService: + description: KedifyConfigurationResourceStatus defines the observed + state of a KedifyConfiguration owned resources + properties: + phase: + type: string + reason: + type: string + type: object + configSHA256: + type: string + installations: + additionalProperties: + description: KedifyInstallationStatus defines the observed state + of a KedifyInstallation + properties: + adoptedAt: + format: date-time + type: string + controlPlaneMetrics: + type: string + deployments: + additionalProperties: + description: KedifyConfigurationResourceStatus defines the + observed state of a KedifyConfiguration owned resources + properties: + phase: + type: string + reason: + type: string + type: object + type: object + firstHealthyAt: + format: date-time + type: string + httpAddonVersion: + type: string + k8sResourcesMetrics: + type: string + kedaResourcesMetrics: + type: string + kedaVersion: + type: string + type: object + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/kedify-agent/files/kedify-scalingpolicy.yaml b/kedify-agent/files/kedify-scalingpolicy.yaml new file mode 100644 index 00000000..2738dccb --- /dev/null +++ b/kedify-agent/files/kedify-scalingpolicy.yaml @@ -0,0 +1,312 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: scalingpolicies.keda.kedify.io +spec: + group: keda.kedify.io + names: + kind: ScalingPolicy + listKind: ScalingPolicyList + plural: scalingpolicies + singular: scalingpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The readiness of the scaling policy + jsonPath: .status.conditions[?(.type=='Ready')].status + name: Ready + type: string + - description: Is the scaling policy active + jsonPath: .status.active + name: Active + type: boolean + name: v1alpha1 + schema: + openAPIV3Schema: + description: ScalingPolicy is the Schema for the scalingpolicies API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ScalingPolicySpec defines the desired state of ScalingPolicy + properties: + actions: + description: Action is the list of actions to be taken + items: + description: ScalingAction defines the action to be taken + properties: + adjustment: + description: ActionAdjustment defines the adjustment for the + action + properties: + idleReplicaCount: + format: int32 + type: integer + maxReplicaCount: + format: int32 + type: integer + minReplicaCount: + format: int32 + type: integer + pauseConfig: + description: PauseConfig defines the pause configuration + properties: + paused: + description: |- + Paused is the flag to pause the scaling policy + autoscaling.keda.sh/paused + type: boolean + replicas: + description: |- + Replicas is the number of replicas to be set when the scaling policy is paused + autoscaling.keda.sh/paused-replicas + format: int32 + type: integer + type: object + pollingInterval: + format: int32 + type: integer + type: object + name: + type: string + priority: + format: int32 + type: integer + trigger: + description: ActionTrigger defines the trigger for the action + properties: + schedule: + description: ActionTriggerSchedule defines the schedule + for the trigger + properties: + end: + type: string + start: + type: string + timezone: + type: string + required: + - end + - start + - timezone + type: object + required: + - schedule + type: object + required: + - adjustment + - name + type: object + type: array + targets: + description: Targets is the list target resources to be modified + items: + description: ScalingActionTarget defines the target resource to + be modified + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + type: array + required: + - actions + - targets + type: object + status: + description: ScalingPolicyStatus defines the observed state of ScalingPolicy + properties: + actions: + items: + description: ScalingPolicyStatusAction defines the status of the + action + properties: + active: + type: boolean + applied: + type: boolean + message: + type: string + name: + type: string + scheduleEnd: + format: date-time + type: string + scheduleStart: + format: date-time + type: string + type: object + type: array + active: + type: boolean + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + schedule: + description: ScheduleStatus defines the status of the schedule + properties: + lastEnd: + format: date-time + type: string + lastStart: + format: date-time + type: string + nextEnd: + format: date-time + type: string + nextSchedule: + format: date-time + type: string + nextStart: + format: date-time + type: string + type: object + targets: + additionalProperties: + description: ScalingPolicyStatusTarget defines the status of the + target + properties: + message: + type: string + name: + type: string + namespace: + type: string + originalConfig: + description: ActionAdjustment defines the adjustment for the + action + properties: + idleReplicaCount: + format: int32 + type: integer + maxReplicaCount: + format: int32 + type: integer + minReplicaCount: + format: int32 + type: integer + pauseConfig: + description: PauseConfig defines the pause configuration + properties: + paused: + description: |- + Paused is the flag to pause the scaling policy + autoscaling.keda.sh/paused + type: boolean + replicas: + description: |- + Replicas is the number of replicas to be set when the scaling policy is paused + autoscaling.keda.sh/paused-replicas + format: int32 + type: integer + type: object + pollingInterval: + format: int32 + type: integer + type: object + reason: + type: string + status: + type: string + required: + - status + type: object + type: object + validatedGeneration: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/kedify-agent/templates/NOTES.txt b/kedify-agent/templates/NOTES.txt new file mode 100644 index 00000000..97123964 --- /dev/null +++ b/kedify-agent/templates/NOTES.txt @@ -0,0 +1,17 @@ +{{ if not .Values.agent.noBanner }} +> _ _ _ ___ _ + | |_ ___ _| |_| _|_ _ |_|___ + | '_| -_| . | | _| | |_| | . | + |_,_|___|___|_|_| |_ |_|_|___| + |___| + +{{- end }} + +You have successfully installed the: + - agent +{{- if .Values.keda.enabled }} + - keda +{{- end}} +{{- if .Values.kedaAddOnsHttp.enabled }} + - keda-add-ons-http +{{- end}} diff --git a/kedify-agent/templates/_helpers.tpl b/kedify-agent/templates/_helpers.tpl new file mode 100644 index 00000000..b7ab85a1 --- /dev/null +++ b/kedify-agent/templates/_helpers.tpl @@ -0,0 +1,79 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "kedify-agent.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kedify-agent.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kedify-agent.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "kedify-agent.labels" -}} +helm.sh/chart: {{ include "kedify-agent.chart" . }} +{{ include "kedify-agent.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kedify-agent.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kedify-agent.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kedify-agent.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "kedify-agent.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +CRD installation labels +*/}} +{{- define "crdInstall" -}} +{{- printf "%s-%s" ( include "kedify-agent.name" . ) "crd-install" | replace "+" "_" | trimSuffix "-" -}} +{{- end -}} + +{{- define "crdInstallAnnotations" -}} +"helm.sh/hook": "pre-install,pre-upgrade" +"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded,hook-failed" +{{- end -}} + +{{/* Create a label which can be used to select any orphaned crd-install hook resources */}} +{{- define "crdInstallSelector" -}} +{{- printf "%s" "crd-install-hook" -}} +{{- end -}} diff --git a/kedify-agent/templates/agent-deployment.yaml b/kedify-agent/templates/agent-deployment.yaml new file mode 100644 index 00000000..fe73ee51 --- /dev/null +++ b/kedify-agent/templates/agent-deployment.yaml @@ -0,0 +1,138 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: manager + app.kubernetes.io/instance: kedify-agent + control-plane: kedify-agent + {{- include "kedify-agent.labels" . | nindent 4 }} + name: kedify-agent + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.agent.replicas }} + selector: + matchLabels: + control-plane: kedify-agent + template: + metadata: + {{- with .Values.agent.volumeMounts }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + control-plane: kedify-agent + {{- with .Values.agent.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + containers: + - args: + - --leader-elect + - --zap-log-level={{ .Values.agent.logLevel }} + command: + - /manager + env: + - name: KEDIFY_SERVER + value: {{ .Values.agent.kedifyServer }} + # - name: KEDIFY_AGENT_ID + # value: {{ .Values.agentId }} + - name: KEDIFY_ORGANIZATION_ID + value: {{ .Values.agent.orgId }} + - name: KEDIFY_API_KEY + valueFrom: + secretKeyRef: + name: kedify-agent + key: apikey + - name: HELM_REPOSITORY_CONFIG + value: /helm/repository/repositories.yaml + - name: HELM_REPOSITORY_CACHE + value: /helm/charts + {{- if .Values.agent.noColor }} + - name: NO_COLOR + value: {{ .Values.agent.noColor | quote }} + {{- end }} + {{- if .Values.agent.noBanner }} + - name: NO_BANNER + value: {{ .Values.agent.noBanner | quote }} + {{- end }} + - name: RBAC_READ_NODES + value: {{ .Values.agent.rbac.readNodes | quote }} + - name: RBAC_READ_PODS + value: {{ .Values.agent.rbac.readPods | quote }} + - name: RBAC_READ_DEPLOYMENTS_CLUSTERWIDE + value: {{ .Values.agent.rbac.readDeploymentsClusterwide | quote }} + - name: RBAC_READ_SERVICES + value: {{ .Values.agent.rbac.readServices | quote }} + - name: RBAC_READ_HPAS + value: {{ .Values.agent.rbac.readHpas | quote }} + - name: RBAC_READ_STATEFUL_SETS + value: {{ .Values.agent.rbac.readStatefulSets | quote }} + - name: RBAC_MANAGE_KUBE_RESOURCES + value: {{ .Values.agent.rbac.selfUpdates | quote }} + - name: RBAC_MANAGE_CUSTOM_RESOURCE_DEFINITIONS + value: {{ or .Values.agent.rbac.shouldBeAbleToInstallKeda .Values.agent.rbac.shouldBeAbleToInstallHttpAddon | quote }} + - name: RBAC_MANAGE_HELM + value: {{ or .Values.agent.rbac.shouldBeAbleToInstallKeda .Values.agent.rbac.shouldBeAbleToInstallHttpAddon | quote }} + - name: RBAC_MANAGE_INGRESS_AUTOWIRE + value: {{ .Values.agent.rbac.ingressAutoWire | quote }} + - name: RBAC_MANAGE_KEDIFY_CONFIG + value: {{ .Values.agent.rbac.kedifyConfig | quote }} + image: "{{ .Values.agent.image.repository }}:{{ .Values.agent.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.agent.pullPolicy }} + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + {{- with .Values.agent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.agent.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: /helm/charts + name: helm-charts + {{- with .Values.agent.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.agent.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.agent.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: kedify-agent + terminationGracePeriodSeconds: 10 + volumes: + - name: helm-charts + emptyDir: + sizeLimit: 50Mi + {{- with .Values.agent.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + + {{- with .Values.agent.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.agent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.agent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/kedify-agent/templates/agent-rbac.yaml b/kedify-agent/templates/agent-rbac.yaml new file mode 100644 index 00000000..347fc690 --- /dev/null +++ b/kedify-agent/templates/agent-rbac.yaml @@ -0,0 +1,458 @@ +{{- if .Values.agent.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: kedify-leader-election + namespace: {{ .Release.Namespace }} + labels: + control-plane: kedify-agent +rules: +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kedify-leader-election + namespace: {{ .Release.Namespace }} + labels: + control-plane: kedify-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: kedify-leader-election +subjects: +- kind: ServiceAccount + name: kedify-agent + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: kedify-manager-role + namespace: {{ .Release.Namespace }} +rules: + +{{- if .Values.agent.rbac.selfUpdates }} +# Kedify agent needs to be able to update its own container image +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch + - update + - patch +{{- end }} + +# Cruding own CRD that holds the helm chart values for Keda installation, but also enabling disabling telemetry +- apiGroups: + - install.kedify.io + resources: + - KedifyConfiguration + verbs: + - "*" + +{{- if or .Values.agent.rbac.shouldBeAbleToInstallKeda .Values.agent.rbac.shouldBeAbleToInstallHttpAddon }} +# Save/load state of each installed resource and its version +- apiGroups: + - "" + resources: + - configmaps + verbs: + - delete + - get + - patch + - update + resourceNames: + - kedify-state + - kedify-http-addon-state +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - list + - watch +{{- end }} + +{{- if .Values.agent.rbac.selfUpdates }} +# Kedify needs to be able to uninstall itself +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - update + resourceNames: + - keda +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + verbs: + - get + - delete + - update + resourceNames: + - kedify-leader-election +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - delete + - update + resourceNames: + - kedify-agent +{{- end }} + +# kedify-agent reads API key from here and stores agent_id from fleet install initialization +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - delete + - update + resourceNames: + - kedify-agent +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kedify-manager-rolebinding + namespace: {{ .Release.Namespace }} + labels: + control-plane: kedify-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: kedify-manager-role +subjects: +- kind: ServiceAccount + name: kedify-agent + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kedify-manager-role +rules: +# to get kube-system UUID for self-registration in fleet installation +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + resourceNames: + - kube-system +# for reporting status about KEDA installation to dashboard +- apiGroups: + - apiregistration.k8s.io + resources: + - apiservices + verbs: + - get + - list + - watch +{{- if .Values.agent.rbac.readNodes }} +# for metrics and metered billing +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +{{- end }} +{{- if .Values.agent.rbac.readPods }} +# for metrics +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch +{{- end }} +{{- if .Values.agent.rbac.readMetrics }} +- apiGroups: + - "" + resources: + - namespaces + verbs: + - list + - watch + - get +- apiGroups: + - metrics.k8s.io + resources: + - pods + verbs: + - get + - list +{{- end }} +{{- if .Values.agent.rbac.readDeploymentsClusterwide }} +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list +{{- end }} +{{- if .Values.agent.rbac.readHpas }} +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - get + - list + - watch +{{- end }} +{{- if .Values.agent.rbac.readStatefulSets }} +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - get + - list + - watch +{{- end }} +{{- if or .Values.agent.rbac.shouldBeAbleToInstallKeda .Values.agent.rbac.shouldBeAbleToInstallHttpAddon }} +# required by Kedify to be able to crud CR(D)s related to KEDA +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - create + - delete + - get + - patch + - update + resourceNames: + - kedifyconfigurations.install.kedify.io + - scalingpolicies.keda.kedify.io + - clustertriggerauthentications.keda.sh + - cloudeventsources.eventing.keda.sh + - clustercloudeventsources.eventing.keda.sh + - httpscaledobjects.http.keda.sh + - scaledjobs.keda.sh + - scaledobjects.keda.sh + - triggerauthentications.keda.sh +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - create +{{- end }} +- apiGroups: + - keda.sh + - http.keda.sh + - eventing.keda.sh + - install.kedify.io + - keda.kedify.io + resources: + - "*" + verbs: + - "*" + +{{- if .Values.agent.rbac.ingressAutoWire }} +# Kedify needs to configure envoy proxy also in other namespaces & deploy it +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - list + - watch + - create +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - delete + - update + resourceNames: + - kedify-proxy +{{- end }} + +{{- if .Values.agent.rbac.uninstall }} +# Kedify needs to be able to uninstall itself +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - list + - watch + - delete +{{- end }} + +{{- if .Values.agent.rbac.ingressAutoWire }} +# required by Kedify agent to be able to do the auto-wiring of communication from {VirtualService, Service, HttpRoute, Ingress, Route}'s original workload to Interceptor +# Interceptor then forwards the traffic to the original workload (used for activation phase when there is no replicas) +- apiGroups: + - networking.istio.io + resources: + - virtualservices + verbs: + - get + - list + - patch + - update + - watch +{{- if .Values.agent.rbac.readServices }} +- apiGroups: + - "" + resources: + - services + verbs: + - list + - create + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - patch + - update + resourceNames: + - kedify-proxy + - keda-add-ons-http-interceptor-proxy +{{- end }} +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - referencegrants + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - get + - list + - patch + - update + - watch +{{- end }} + +{{- if or .Values.agent.rbac.shouldBeAbleToInstallKeda .Values.agent.rbac.shouldBeAbleToInstallHttpAddon }} +# Kedify needs to be able to uninstall itself +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + - clusterroles + - clusterrolebindings + verbs: + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - get + - delete + - update + resourceNames: + - kedify-manager-role +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - get + - delete + - update + resourceNames: + - kedify-manager-rolebinding +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kedify-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kedify-manager-role +subjects: +- kind: ServiceAccount + name: kedify-agent + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/kedify-agent/templates/api-key-secret.yaml b/kedify-agent/templates/api-key-secret.yaml new file mode 100644 index 00000000..13048e4f --- /dev/null +++ b/kedify-agent/templates/api-key-secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: kedify-agent + namespace: {{ .Release.Namespace }} +data: + apikey: {{ b64enc .Values.agent.apiKey }} diff --git a/kedify-agent/templates/cr-install/cr-configmap.yaml b/kedify-agent/templates/cr-install/cr-configmap.yaml new file mode 100644 index 00000000..843508d3 --- /dev/null +++ b/kedify-agent/templates/cr-install/cr-configmap.yaml @@ -0,0 +1,41 @@ +{{- if .Values.agent.createKedifyConfiguration }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: default-kedifyconfig + namespace: {{ .Release.Namespace }} + annotations: + helm.sh/hook: "post-install,post-upgrade" + helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded" + helm.sh/hook-weight: "-2" +data: + content: | + apiVersion: install.kedify.io/v1alpha1 + kind: KedifyConfiguration + metadata: + name: kedify + namespace: {{ .Release.Namespace }} + spec: + clusterName: {{ .Values.clusterName }} + kedaInstallations: + - agentAutoUpdate: false + httpAddonHelm: + enabled: true + values: |- + --- + kedaHelm: + enabled: true + values: |- + --- + mode: Disabled + name: keda + namespace: {{ .Release.Namespace }} + telemetry: + controlPlane: + interval: 30 + kedaResources: + interval: 30 + kubernetesResources: + interval: 30 +--- +{{- end }} diff --git a/kedify-agent/templates/cr-install/cr-job.yaml b/kedify-agent/templates/cr-install/cr-job.yaml new file mode 100644 index 00000000..4db73c6a --- /dev/null +++ b/kedify-agent/templates/cr-install/cr-job.yaml @@ -0,0 +1,74 @@ +{{- if .Values.agent.createKedifyConfiguration }} +apiVersion: batch/v1 +kind: Job +metadata: + name: create-default-kedifyconfig + namespace: {{ .Release.Namespace }} + labels: + app: create-default-kedifyconfig + annotations: + helm.sh/hook: post-install,post-upgrade + helm.sh/hook-weight: "-1" + helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded" +spec: + ttlSecondsAfterFinished: 43200 # 12h + backoffLimit: 4 + template: + metadata: + labels: + app: create-default-kedifyconfig + spec: + restartPolicy: Never + serviceAccountName: install-crs + securityContext: + runAsUser: 1000 + runAsGroup: 2000 + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + volumes: + - name: default-kedifyconfig + configMap: + name: default-kedifyconfig + items: + - key: content + path: default-kedifyconfig.yaml + initContainers: + - name: wait-crds + image: "quay.io/giantswarm/docker-kubectl:1.29.2" + imagePullPolicy: IfNotPresent + command: + - sh + args: + - -c + - | + while ! kubectl get crd kedifyconfigurations.install.kedify.io + do + echo "Waiting for CRD kedifyconfigurations.install.kedify.io to exist" + sleep 5 + done + containers: + - name: create-default-kedifyconfig + image: "quay.io/giantswarm/docker-kubectl:1.29.2" + imagePullPolicy: IfNotPresent + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - name: default-kedifyconfig + mountPath: /data/default-kedifyconfig.yaml + subPath: default-kedifyconfig.yaml + command: + - sh + args: + - -c + - | + set -o nounset + for i in $(seq 20) + do + kubectl apply -f /data/ 2>&1 && exit 0 + _sec=$(echo "1.5^$i" | bc) + echo "Waiting ${_sec} seconds.." + sleep ${_sec} + done + exit 1 +{{- end }} diff --git a/kedify-agent/templates/cr-install/cr-rbac.yaml b/kedify-agent/templates/cr-install/cr-rbac.yaml new file mode 100644 index 00000000..3be55aa2 --- /dev/null +++ b/kedify-agent/templates/cr-install/cr-rbac.yaml @@ -0,0 +1,54 @@ +{{- if .Values.agent.createKedifyConfiguration }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: install-crs + namespace: {{ .Release.Namespace }} + annotations: + helm.sh/hook: "post-install,post-upgrade" + helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded" + helm.sh/hook-weight: "-2" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: install-crs + annotations: + helm.sh/hook: "post-install,post-upgrade" + helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded" + helm.sh/hook-weight: "-2" +rules: +- apiGroups: + - install.kedify.io + resources: + - kedifyconfigurations + verbs: + - patch + - create + - get +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + resourceNames: + - kedifyconfigurations.install.kedify.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: install-crs + annotations: + helm.sh/hook: "post-install,post-upgrade" + helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded" + helm.sh/hook-weight: "-2" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: install-crs +subjects: +- kind: ServiceAccount + name: install-crs + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/kedify-agent/templates/crd-install/crd-configmap.yaml b/kedify-agent/templates/crd-install/crd-configmap.yaml new file mode 100644 index 00000000..825bc472 --- /dev/null +++ b/kedify-agent/templates/crd-install/crd-configmap.yaml @@ -0,0 +1,27 @@ +{{- if .Values.agent.createCrds }} +{{/* +We have to create individual configmaps for each CRD - they might exceed the total +allowed length for a configmap if they are combined. +*/}} +{{ $currentScope := . }} + {{- range $path, $_ := .Files.Glob "files/**" }} + {{- with $currentScope }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "crdInstall" . }}-{{ $path | base | trimSuffix ".yaml" }} + namespace: {{ .Release.Namespace | quote }} + annotations: + # create hook dependencies in the right order + "helm.sh/hook-weight": "-5" + {{- include "crdInstallAnnotations" . | nindent 4 }} + labels: + app.kubernetes.io/component: {{ include "crdInstall" . | quote }} + role: {{ include "crdInstallSelector" . | quote }} +data: + content: | +{{ tpl ($.Files.Get $path) . | indent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/kedify-agent/templates/crd-install/crd-job.yaml b/kedify-agent/templates/crd-install/crd-job.yaml new file mode 100644 index 00000000..0114174d --- /dev/null +++ b/kedify-agent/templates/crd-install/crd-job.yaml @@ -0,0 +1,65 @@ +{{- if .Values.agent.createCrds }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "crdInstall" . }} + namespace: {{ .Release.Namespace | quote }} + annotations: + # create hook dependencies in the right order + "helm.sh/hook-weight": "-1" + {{- include "crdInstallAnnotations" . | nindent 4 }} + labels: + app.kubernetes.io/component: {{ include "crdInstall" . | quote }} + role: {{ include "crdInstallSelector" . | quote }} +spec: + ttlSecondsAfterFinished: 43200 # 12h + template: + metadata: + labels: + app.kubernetes.io/component: {{ include "crdInstall" . | quote }} + spec: + serviceAccountName: {{ include "crdInstall" . }} + securityContext: + runAsUser: 1000 + runAsGroup: 2000 + containers: + - name: kubectl + image: "quay.io/giantswarm/docker-kubectl:1.29.2" + command: + - sh + - -c + - | + set -o errexit ; set -o xtrace ; set -o nounset + # piping stderr to stdout means kubectl's errors are surfaced + # in the pod's logs. + kubectl apply -f /data/ 2>&1 + securityContext: + readOnlyRootFilesystem: true + volumeMounts: +{{- range $path, $_ := .Files.Glob "files/**" }} + - name: {{ $path | base | trimSuffix ".yaml" }} + mountPath: /data/{{ $path | base }} + subPath: {{ $path | base }} +{{- end }} + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 100m + memory: 64Mi + volumes: +{{ $currentScope := . }} +{{- range $path, $_ := .Files.Glob "files/**" }} + {{- with $currentScope }} + - name: {{ $path | base | trimSuffix ".yaml" }} + configMap: + name: {{ include "crdInstall" . }}-{{ $path | base | trimSuffix ".yaml" }} + items: + - key: content + path: {{ $path | base }} +{{- end }} +{{- end }} + restartPolicy: Never + backoffLimit: 4 +{{- end }} diff --git a/kedify-agent/templates/crd-install/crd-rbac.yaml b/kedify-agent/templates/crd-install/crd-rbac.yaml new file mode 100644 index 00000000..f7fda9e6 --- /dev/null +++ b/kedify-agent/templates/crd-install/crd-rbac.yaml @@ -0,0 +1,66 @@ +{{- if .Values.agent.createCrds }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "crdInstall" . }} + namespace: {{ .Release.Namespace }} + annotations: + # create hook dependencies in the right order + "helm.sh/hook-weight": "-4" + {{- include "crdInstallAnnotations" . | nindent 4 }} + labels: + app.kubernetes.io/component: {{ include "crdInstall" . | quote }} + role: {{ include "crdInstallSelector" . | quote }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "crdInstall" . }} + namespace: {{ .Release.Namespace }} + annotations: + # create hook dependencies in the right order + "helm.sh/hook-weight": "-3" + {{- include "crdInstallAnnotations" . | nindent 4 }} + labels: + app.kubernetes.io/component: {{ include "crdInstall" . | quote }} + role: {{ include "crdInstallSelector" . | quote }} +rules: +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - delete + - get + - patch + resourceNames: + - kedifyconfigurations.install.kedify.io + - scalingpolicies.keda.kedify.io +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "crdInstall" . }} + namespace: {{ .Release.Namespace }} + annotations: + # create hook dependencies in the right order + "helm.sh/hook-weight": "-2" + {{- include "crdInstallAnnotations" . | nindent 4 }} + labels: + app.kubernetes.io/component: {{ include "crdInstall" . | quote }} + role: {{ include "crdInstallSelector" . | quote }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "crdInstall" . }} +subjects: + - kind: ServiceAccount + name: {{ include "crdInstall" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/kedify-agent/templates/httpaddon-rbac.yaml b/kedify-agent/templates/httpaddon-rbac.yaml new file mode 100644 index 00000000..4de8c20b --- /dev/null +++ b/kedify-agent/templates/httpaddon-rbac.yaml @@ -0,0 +1,244 @@ +{{- if .Values.agent.rbac.create }} +{{- if .Values.agent.rbac.shouldBeAbleToInstallHttpAddon }} +# Following rbac is needed for kedify agent to be able to install also the HTTP addon + +# these rules are namespaced for resources present in the installation namespace (keda) +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: http-addon-installer + {{ .Release.Namespace }} + labels: + control-plane: kedify-agent +rules: + +# When installing http addon create its rbac +# serviceaccounts +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - '*' + resourceNames: + - keda-add-ons-http-interceptor + - keda-add-ons-http + - keda-add-ons-http-external-scaler +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + +# roles +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-add-ons-http-role +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + +# rolebindings +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-add-ons-http-role-rolebinding +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + +# When installing http addon create certain Services and Deployments +- apiGroups: + - "" + resources: + - services + verbs: + - '*' + resourceNames: + - keda-add-ons-http-interceptor-admin + - keda-add-ons-http-interceptor-proxy + - keda-add-ons-http-controller-manager-metrics-service + - keda-add-ons-http-external-scaler +- apiGroups: + - "" + resources: + - services + verbs: + - create +- apiGroups: + - "apps" + resources: + - deployments + verbs: + - '*' + resourceNames: + - keda-add-ons-http-interceptor + - keda-add-ons-http-controller-manager + - keda-add-ons-http-external-scaler +- apiGroups: + - "apps" + resources: + - deployments + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: http-addon-installer + {{ .Release.Namespace }} + labels: + control-plane: kedify-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: http-addon-installer +subjects: +- kind: ServiceAccount + name: kedify-agent + {{ .Release.Namespace }} + + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: http-addon-installer +rules: + +# we need to have the same rules to prevent privilege escalation issue - https://kubernetes.io/docs/reference/access-authn-authz/rbac/#restrictions-on-role-binding-creation-or-update +# additional content of keda-add-ons-http-interceptor cluster role +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list + - watch + +# additional content of keda-add-ons-http-proxy-role cluster role +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] + +# clusterroles +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-add-ons-http-interceptor + - keda-add-ons-http-role + - keda-add-ons-http-external-scaler + - keda-add-ons-http-proxy-role + - keda-add-ons-http-metrics-reader +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - create + +# clusterrolebindings +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-add-ons-http-interceptor + - keda-add-ons-http-rolebinding + - keda-add-ons-http-proxy-rolebinding + - keda-add-ons-http-external-scaler +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - create + +# events for the interceptor +- apiGroups: + - "" + resources: + - events + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: http-addon-installer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: http-addon-installer +subjects: +- kind: ServiceAccount + name: kedify-agent + {{ .Release.Namespace }} + + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: http-addon-metrics-reader-installer +rules: +# content of keda-add-ons-http-metrics-reader cluster role +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: http-addon-metrics-reader-installer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: http-addon-metrics-reader-installer +subjects: +- kind: ServiceAccount + name: kedify-agent + {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/kedify-agent/templates/keda-rbac.yaml b/kedify-agent/templates/keda-rbac.yaml new file mode 100644 index 00000000..9432e73c --- /dev/null +++ b/kedify-agent/templates/keda-rbac.yaml @@ -0,0 +1,370 @@ +{{- if .Values.agent.rbac.create }} +{{- if .Values.agent.rbac.shouldBeAbleToInstallKeda }} +# Following rbac is needed for kedify agent to be able to install also the KEDA +# most of these rules are not used by kedify agent itself, but its service account still needs them assigned +# to be able to create install the KEDA and its RBAC (privilege escalation feature of k8s rbac). + +# If you find these rbac rules too permissive, consider installing KEDA on your own and use Kedify in Adopt mode +# this way keda-installer role will not be required by Kedify. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: keda-installer + {{ .Release.Namespace }} + labels: + control-plane: kedify-agent +rules: + +# When installing keda create its rbac +# serviceaccounts +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - '*' + resourceNames: + - keda-operator + - keda-metrics-server + - keda-webhook +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + +# roles +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-operator-certs +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + +# rolebindings +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-operator-certs +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + +# When installing keda create certain Services and Deployments +- apiGroups: + - "" + resources: + - services + verbs: + - '*' + resourceNames: + - keda-operator + - keda-operator-metrics-apiserver + - keda-admission-webhooks +- apiGroups: + - "" + resources: + - services + verbs: + - create +- apiGroups: + - "apps" + resources: + - deployments + verbs: + - '*' + resourceNames: + - keda-operator + - keda-operator-metrics-apiserver + - keda-admission-webhooks +- apiGroups: + - "apps" + resources: + - deployments + verbs: + - create + +# keda-operator-certs +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - '*' +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + resourceNames: + - "kedaorg-certs" +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: keda-installer + {{ .Release.Namespace }} + labels: + control-plane: kedify-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: keda-installer +subjects: + - kind: ServiceAccount + name: kedify-agent + {{ .Release.Namespace }} + + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: keda-installer +rules: + +# we need to have the same rules to prevent privilege escalation issue - https://kubernetes.io/docs/reference/access-authn-authz/rbac/#restrictions-on-role-binding-creation-or-update + +# rolebindings (crud keda-operator rolebinding cluster-wide, used when keda's watchNamespace property is not empty) +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-operator + - keda-operator-auth-reader +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + + # clusterroles +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-operator-minimal-cluster-role + - keda-operator + - keda-operator-external-metrics-reader + - keda-operator-webhook + - kedify-keda-operator-http-admin + +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - create + + # clusterrolebindings +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - delete + - get + - patch + - update + resourceNames: + - keda-operator-minimal + - keda-operator + - keda-operator-webhook + - keda-operator-system-auth-delegator + - keda-operator-hpa-controller-external-metrics + - kedify-keda-operator-http-admin +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - create + +# additional content of keda-operator-minimal cluster role +- apiGroups: + - apiregistration.k8s.io + resources: + - apiservices + verbs: + - get + - list + - patch + - update + - watch + +# additional content of keda-operator-external-metrics-reader cluster role +- apiGroups: + - external.metrics.k8s.io + resources: + - '*' + verbs: + - '*' + +# additional content of keda-operator cluster role +- apiGroups: + - "" + resources: + - configmaps + - configmaps/status + - limitranges + - pods + - services + - serviceaccounts + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - '*' +- apiGroups: + - "" + resources: + - secrets + verbs: + - list + - watch +- apiGroups: + - "*" + resources: + - "*/scale" + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - "*" + resources: + - "*" + verbs: + - get +- apiGroups: + - apps + resources: + - deployments/scale + - statefulsets/scale + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments + - statefulsets + verbs: + - get + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - '*' +- apiGroups: + - batch + resources: + - jobs + verbs: + - '*' +- apiGroups: + - eventing.keda.sh + resources: + - cloudeventsources + - cloudeventsources/status + verbs: + - '*' +- apiGroups: + - keda.sh + resources: + - scaledjobs + - scaledjobs/finalizers + - scaledjobs/status + - scaledobjects + - scaledobjects/finalizers + - scaledobjects/status + - triggerauthentications + - triggerauthentications/status + verbs: + - '*' + +# for registering the keda's validating webhook called 'keda-admission' +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: keda-installer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: keda-installer +subjects: + - kind: ServiceAccount + name: kedify-agent + {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/kedify-agent/templates/serviceaccount.yaml b/kedify-agent/templates/serviceaccount.yaml new file mode 100644 index 00000000..1a9030b3 --- /dev/null +++ b/kedify-agent/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kedify-agent + namespace: {{ .Release.Namespace }} + labels: + {{- include "kedify-agent.labels" . | nindent 4 }} + {{- with .Values.agent.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.agent.serviceAccount.automount }} diff --git a/kedify-agent/values.schema.json b/kedify-agent/values.schema.json new file mode 100644 index 00000000..fc8b50f7 --- /dev/null +++ b/kedify-agent/values.schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "schema for values.yaml for kedify agent helm chart", + "$ref": "#/defs/Top-lvl", + "defs": { + "Top-lvl": { + "properties": { + "agent": { + "$ref": "#/defs/Agent" + } + }, + "required": [ + "agent" + ] + }, + "Agent": { + "properties": { + "apiKey": { + "type": "string", + "minLength": 10, + "pattern": "^kfy_[a-z0-9]*$" + }, + "orgId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "apiKey", + "orgId" + ] + } + } +} diff --git a/kedify-agent/values.yaml b/kedify-agent/values.yaml new file mode 100644 index 00000000..0c49be9b --- /dev/null +++ b/kedify-agent/values.yaml @@ -0,0 +1,111 @@ +clusterName: "cluster-1" + +agent: + replicas: 1 + + # you should already have this + orgId: "" + # you should already have this + apiKey: "" +# agentId: abcd1234-ab34-.. + kedifyServer: service.kedify.io:443 + + # Can be one of 'debug', 'info', 'error', or any integer value > 0 + # which corresponds to custom debug levels of increasing verbosity + logLevel: info + + # should the KedifyConfiguration and ScalingPolicy CRDs be also part of the release + createCrds: true + createKedifyConfiguration: true + + image: + tag: "v0.1.0" + repository: ghcr.io/kedify/agent + pullPolicy: IfNotPresent + imagePullSecrets: [] + + # if anything else than 'false', the log will not print the ascii logo + noBanner: false + # if anything else than 'false', the log will not contain colors + noColor: false + nameOverride: "" + fullnameOverride: "" + + rbac: + # create the necessary RBAC for kedify agent + create: true + # set this to true if the agent should be able to install the KEDA + shouldBeAbleToInstallKeda: false + # set this to true if the agent should be able to install the KEDA http addon + shouldBeAbleToInstallHttpAddon: false + # if true, rbac necessary for self-updates is added + selfUpdates: false + # if true, rbac necessary for metrics collection is added + readMetrics: true + # if true, rbac necessary for reading stateful sets is added + readStatefulSets: false + # if true, rbac necessary for reading HPAs (horizontal pod autoscalers) is added + readHpas: false + # if true, rbac necessary for reading Nodes is added + readNodes: false + # if true, rbac necessary for reading Pods is added + readPods: true + # if true, rbac necessary for reading Deployments is added + readDeploymentsClusterwide: true + # if true, rbac necessary for reading Services is added + readServices: true + # if true, ingress auto-wire capability with fallback is enabled + ingressAutoWire: true + # if true, enables sync of KedifyConfiguration between cluster and the dashboard + kedifyConfig: false + + serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + + podAnnotations: + kubectl.kubernetes.io/default-container: manager + podLabels: {} + + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 200Mi + + # Additional volumes on the output agent's Deployment definition. + volumes: [] + # - name: foo + # secret: + # secretName: mysecret + # optional: false + + volumeMounts: [] + # - name: foo + # mountPath: "/etc/foo" + # readOnly: true + + podSecurityContext: {} + securityContext: + capabilities: + drop: + - ALL + + nodeSelector: {} + tolerations: [] + affinity: {} + +# dependent helm charts +keda: + # for all available values, check: https://github.com/kedify/charts/blob/main/keda/values.yaml + enabled: false + +kedaAddOnsHttp: + # for all available values, check: https://github.com/kedify/charts/blob/main/http-add-on/values.yaml + enabled: false