diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 2db3f8d80..203f7a3fc 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -1186,15 +1186,161 @@ jobs: run: | kubectl -n default apply -f config/testdata/crds-upgrade/create-replace kubectl -n default wait helmreleases/crds-upgrade-test --for=condition=ready --timeout=2m + - name: Run upgrade with chart name changed and default ChartNameChangeStrategy + run: | + test_name=upgrade-chart-name-change + kubectl -n helm-system apply -f config/testdata/$test_name/install.yaml + echo -n ">>> Waiting for expected conditions" + count=0 + until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .Ready=="True"' )" ]; do + echo -n '.' + sleep 5 + count=$((count + 1)) + if [[ ${count} -eq 24 ]]; then + echo ' No more retries left!' + exit 1 + fi + done + echo ' done' + + # Validate release was installed. + HISTORY=$(helm -n helm-system history -o json $test_name) + REVISION_COUNT=$(echo "$HISTORY" | jq 'length') + if [ "$REVISION_COUNT" != 1 ]; then + echo -e "Unexpected revision count: $REVISION_COUNT" + exit 1 + fi + LAST_REVISION_STATUS=$(echo "$HISTORY" | jq -r 'last | .status') + if [ "$LAST_REVISION_STATUS" != "deployed" ]; then + echo -e "Unexpected last revision status: $LAST_REVISION_STATUS" + exit 1 + fi + + kubectl -n helm-system apply -f config/testdata/$test_name/upgrade.yaml + + kubectl -n helm-system wait helmreleases/$test_name --for=condition=ready --timeout=4m + + # Validate release was uninstalled/reinstalled. + HISTORY=$(helm -n helm-system history -o json $test_name) + REVISION_COUNT=$(echo "$HISTORY" | jq 'length') + if [ "$REVISION_COUNT" != 1 ]; then + echo -e "Unexpected revision count: $REVISION_COUNT" + exit 1 + fi + LAST_REVISION_STATUS=$(echo "$HISTORY" | jq -r 'last | .status') + if [ "$LAST_REVISION_STATUS" != "deployed" ]; then + echo -e "Unexpected last revision status: $LAST_REVISION_STATUS" + exit 1 + fi + + kubectl delete -n helm-system -f config/testdata/$test_name/install.yaml + - name: Run upgrade with chart name changed and reinstall ChartNameChangeStrategy + run: | + test_name=upgrade-chart-name-change + kubectl -n helm-system apply -f config/testdata/$test_name/install.yaml + echo -n ">>> Waiting for expected conditions" + count=0 + until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .Ready=="True"' )" ]; do + echo -n '.' + sleep 5 + count=$((count + 1)) + if [[ ${count} -eq 24 ]]; then + echo ' No more retries left!' + exit 1 + fi + done + echo ' done' + + # Validate release was installed. + HISTORY=$(helm -n helm-system history -o json $test_name) + REVISION_COUNT=$(echo "$HISTORY" | jq 'length') + if [ "$REVISION_COUNT" != 1 ]; then + echo -e "Unexpected revision count: $REVISION_COUNT" + exit 1 + fi + LAST_REVISION_STATUS=$(echo "$HISTORY" | jq -r 'last | .status') + if [ "$LAST_REVISION_STATUS" != "deployed" ]; then + echo -e "Unexpected last revision status: $LAST_REVISION_STATUS" + exit 1 + fi + + kubectl -n helm-system apply -f config/testdata/$test_name/upgrade-reinstall.yaml + kubectl -n helm-system wait helmreleases/$test_name --for=condition=ready --timeout=4m + + # Validate release was uninstalled/reinstalled. + HISTORY=$(helm -n helm-system history -o json $test_name) + REVISION_COUNT=$(echo "$HISTORY" | jq 'length') + if [ "$REVISION_COUNT" != 1 ]; then + echo -e "Unexpected revision count: $REVISION_COUNT" + exit 1 + fi + LAST_REVISION_STATUS=$(echo "$HISTORY" | jq -r 'last | .status') + if [ "$LAST_REVISION_STATUS" != "deployed" ]; then + echo -e "Unexpected last revision status: $LAST_REVISION_STATUS" + exit 1 + fi + + kubectl delete -n helm-system -f config/testdata/$test_name/install.yaml + - name: Run upgrade with chart name changed and InPlaceUpdate ChartNameChangeStrategy + run: | + test_name=upgrade-chart-name-change + kubectl -n helm-system apply -f config/testdata/$test_name/install.yaml + echo -n ">>> Waiting for expected conditions" + count=0 + until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .Ready=="True"' )" ]; do + echo -n '.' + sleep 5 + count=$((count + 1)) + if [[ ${count} -eq 24 ]]; then + echo ' No more retries left!' + exit 1 + fi + done + echo ' done' + + # Validate release was installed. + HISTORY=$(helm -n helm-system history -o json $test_name) + REVISION_COUNT=$(echo "$HISTORY" | jq 'length') + if [ "$REVISION_COUNT" != 1 ]; then + echo -e "Unexpected revision count: $REVISION_COUNT" + exit 1 + fi + LAST_REVISION_STATUS=$(echo "$HISTORY" | jq -r 'last | .status') + if [ "$LAST_REVISION_STATUS" != "deployed" ]; then + echo -e "Unexpected last revision status: $LAST_REVISION_STATUS" + exit 1 + fi + + kubectl -n helm-system apply -f config/testdata/$test_name/upgrade-inplace.yaml + + # Wait for the upgrade to complete (revision count should be 2). + echo -n ">>> Waiting for upgrade" + count=0 + until [ '2' == "$(helm -n helm-system history -o json $test_name 2>/dev/null | jq 'length')" ]; do + echo -n '.' + sleep 5 + count=$((count + 1)) + if [[ ${count} -eq 24 ]]; then + echo ' No more retries left!' + exit 1 + fi + done + echo ' done' + + kubectl -n helm-system wait helmreleases/$test_name --for=condition=ready --timeout=4m + + kubectl delete -n helm-system -f config/testdata/$test_name/install.yaml - name: Logs if: always() continue-on-error: true run: | kubectl -n helm-system logs deploy/source-controller kubectl -n helm-system logs deploy/helm-controller + kubectl -n helm-system describe Deployment/helm-system/upgrade-chart-name-change-pod2info - name: Debug failure if: failure() run: | + helm list --all-namespaces kubectl -n helm-system get helmrepositories -oyaml || true kubectl -n helm-system get helmcharts -oyaml || true kubectl -n helm-system get helmreleases -oyaml || true diff --git a/config/testdata/charts/pod2info/.helmignore b/config/testdata/charts/pod2info/.helmignore new file mode 100644 index 000000000..f0c131944 --- /dev/null +++ b/config/testdata/charts/pod2info/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/config/testdata/charts/pod2info/Chart.yaml b/config/testdata/charts/pod2info/Chart.yaml new file mode 100644 index 000000000..a0664decc --- /dev/null +++ b/config/testdata/charts/pod2info/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +version: 6.11.3 +appVersion: 6.11.3 +name: pod2info +engine: gotpl +description: Podinfo Helm chart for Kubernetes +home: https://github.com/MichaelMorrisEst/podinfo +maintainers: +- email: stefanprodan@users.noreply.github.com + name: stefanprodan +sources: +- https://github.com/MichaelMorrisEst/podinfo +kubeVersion: ">=1.23.0-0" diff --git a/config/testdata/charts/pod2info/LICENSE b/config/testdata/charts/pod2info/LICENSE new file mode 100644 index 000000000..1b92ec15f --- /dev/null +++ b/config/testdata/charts/pod2info/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018 Stefan Prodan. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/config/testdata/charts/pod2info/README.md b/config/testdata/charts/pod2info/README.md new file mode 100644 index 000000000..c20686c9f --- /dev/null +++ b/config/testdata/charts/pod2info/README.md @@ -0,0 +1,145 @@ +# Podinfo + +Podinfo is a tiny web application made with Go +that showcases best practices of running microservices in Kubernetes. + +Podinfo is used by CNCF projects like [Flux](https://github.com/fluxcd/flux2) +and [Flagger](https://github.com/fluxcd/flagger) +for end-to-end testing and workshops. + +## Installing the Chart + +The Podinfo charts are published to +[GitHub Container Registry](https://github.com/stefanprodan/podinfo/pkgs/container/charts%2Fpodinfo) +and signed with [Cosign](https://github.com/sigstore/cosign) & GitHub Actions OIDC. + +To install the chart with the release name `podinfo` from GHCR: + +```console +$ helm upgrade -i podinfo oci://ghcr.io/stefanprodan/charts/podinfo +``` + +To verify a chart version with Cosign: + +```console +$ cosign verify ghcr.io/stefanprodan/charts/podinfo: \ + --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ + --certificate-identity-regexp=^https://github\\.com/stefanprodan/podinfo/.*$ +``` + +Alternatively, you can install the chart from GitHub pages: + +```console +$ helm repo add stefanprodan https://stefanprodan.github.io/podinfo + +$ helm upgrade -i podinfo stefanprodan/podinfo +``` + +The command deploys podinfo on the Kubernetes cluster in the default namespace. +The [configuration](#configuration) section lists the parameters that can be configured during installation. + +## Uninstalling the Chart + +To uninstall the `podinfo` release: + +```console +$ helm uninstall podinfo +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following tables lists the configurable parameters of the podinfo chart and their default values. + +| Parameter | Default | Description | +|-----------------------------------|--------------------------------|------------------------------------------------------------------------------------------------------------------------| +| `replicaCount` | `1` | Desired number of pods | +| `logLevel` | `info` | Log level: `debug`, `info`, `warn`, `error` | +| `backend` | `None` | Echo backend URL | +| `backends` | `[]` | Array of echo backend URLs | +| `cache` | `None` | Redis address in the format `tcp://:` | +| `redis.enabled` | `false` | Create Redis deployment for caching purposes | +| `redis.repository` | `docker.io/redis` | Redis image repository | +| `redis.tag` | `` | Redis image tag | +| `redis.imagePullSecrets` | `[]` | Redis image pull secrets | +| `ui.color` | `#34577c` | UI color | +| `ui.message` | `None` | UI greetings message | +| `ui.logo` | `None` | UI logo | +| `faults.delay` | `false` | Random HTTP response delays between 0 and 5 seconds | +| `faults.error` | `false` | 1/3 chances of a random HTTP response error | +| `faults.unhealthy` | `false` | When set, the healthy state is never reached | +| `faults.unready` | `false` | When set, the ready state is never reached | +| `faults.testFail` | `false` | When set, a helm test is included which always fails | +| `faults.testTimeout` | `false` | When set, a helm test is included which always times out | +| `image.repository` | `ghcr.io/stefanprodan/podinfo` | Image repository | +| `image.tag` | `` | Image tag | +| `image.pullPolicy` | `IfNotPresent` | Image pull policy | +| `image.pullSecrets` | `[]` | Image pull secrets | +| `service.enabled` | `true` | Create a Kubernetes Service, should be disabled when using [Flagger](https://flagger.app) | +| `service.type` | `ClusterIP` | Type of the Kubernetes Service | +| `service.metricsPort` | `9797` | Prometheus metrics endpoint port | +| `service.httpPort` | `9898` | Container HTTP port | +| `service.externalPort` | `9898` | ClusterIP HTTP port | +| `service.grpcPort` | `9999` | ClusterIP gPRC port | +| `service.grpcService` | `podinfo` | gPRC service name | +| `service.nodePort` | `31198` | NodePort for the HTTP endpoint | +| `h2c.enabled` | `false` | Allow upgrading to h2c (non-TLS version of HTTP/2) | +| `extraArgs` | `[]` | Additional command line arguments to pass to podinfo container | +| `extraEnvs` | `[]` | Extra environment variables for the podinfo container | +| `config.path` | `""` | config file path | +| `config.name` | `""` | config file name | +| `hpa.enabled` | `false` | Enables the Kubernetes HPA | +| `hpa.maxReplicas` | `10` | Maximum amount of pods | +| `hpa.cpu` | `None` | Target CPU usage per pod | +| `hpa.memory` | `None` | Target memory usage per pod | +| `hpa.requests` | `None` | Target HTTP requests per second per pod | +| `serviceAccount.enabled` | `false` | Whether a service account should be created | +| `serviceAccount.name` | `None` | The name of the service account to use, if not set and create is true, a name is generated using the fullname template | +| `serviceAccount.imagePullSecrets` | `[]` | List of image pull secrets if pulling from private registries. | +| `securityContext` | `{}` | The security context to be set on the podinfo container | +| `podSecurityContext` | `{}` | The security context to be set on the pod | +| `podAnnotations` | `{}` | Pod annotations | +| `serviceMonitor.enabled` | `false` | Whether a Prometheus Operator service monitor should be created | +| `serviceMonitor.interval` | `15s` | Prometheus scraping interval | +| `serviceMonitor.additionalLabels` | `{}` | Add additional labels to the service monitor | +| `ingress.enabled` | `false` | Enables Ingress | +| `ingress.className` | `""` | Use ingressClassName | +| `ingress.additionalLabels` | `{}` | Add additional labels to the ingress | +| `ingress.annotations` | `{}` | Ingress annotations | +| `ingress.hosts` | `[]` | Ingress accepted hosts | +| `ingress.tls` | `[]` | Ingress TLS configuration | +| `httpRoute.enabled` | `false` | Enables Gateway API HTTPRoute | +| `httpRoute.additionalLabels` | `{}` | Add additional labels to the HTTPRoute | +| `httpRoute.annotations` | `{}` | HTTPRoute annotations | +| `httpRoute.parentRefs` | `[]` | Gateways that this route is attached to | +| `httpRoute.hostnames` | `["podinfo.local"]` | Hostnames matching HTTP header | +| `httpRoute.rules` | `[]` | List of rules and filters applied | +| `linkerd.profile.enabled` | `false` | Create Linkerd service profile | +| `resources.requests.cpu` | `1m` | Pod CPU request | +| `resources.requests.memory` | `16Mi` | Pod memory request | +| `resources.limits.cpu` | `None` | Pod CPU limit | +| `resources.limits.memory` | `None` | Pod memory limit | +| `nodeSelector` | `{}` | Node labels for pod assignment | +| `tolerations` | `[]` | List of node taints to tolerate | +| `affinity` | `None` | Node/pod affinities | + +Specify each parameter using the `--set key=value[,key=value]` argument: + +```console +$ helm upgrade -i podinfo oci://ghcr.io/stefanprodan/charts/podinfo \ + --set=serviceMonitor.enabled=true,serviceMonitor.interval=5s +``` + +To add custom annotations you need to escape the annotation key string: + +```console +$ helm upgrade -i podinfo oci://ghcr.io/stefanprodan/charts/podinfo \ +--set podAnnotations."toolkit\.fluxcd\.io\/tenant"=dev-team +``` + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart: + +```console +$ helm upgrade -i my-release oci://ghcr.io/stefanprodan/charts/podinfo -f values.yaml +``` diff --git a/config/testdata/charts/pod2info/templates/NOTES.txt b/config/testdata/charts/pod2info/templates/NOTES.txt new file mode 100644 index 000000000..2772e80f8 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/NOTES.txt @@ -0,0 +1,20 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ include "podinfo.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "podinfo.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ include "podinfo.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ template "podinfo.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ include "podinfo.namespace" . }} {{ template "podinfo.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.externalPort }} +{{- else if contains "ClusterIP" .Values.service.type }} + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl -n {{ include "podinfo.namespace" . }} port-forward deploy/{{ template "podinfo.fullname" . }} 8080:{{ .Values.service.externalPort }} +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/_helpers.tpl b/config/testdata/charts/pod2info/templates/_helpers.tpl new file mode 100644 index 000000000..9dce2d06c --- /dev/null +++ b/config/testdata/charts/pod2info/templates/_helpers.tpl @@ -0,0 +1,76 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "podinfo.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 "podinfo.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 }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "podinfo.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "podinfo.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "podinfo.labels" -}} +helm.sh/chart: {{ include "podinfo.chart" . }} +{{ include "podinfo.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "podinfo.selectorLabels" -}} +app.kubernetes.io/name: {{ include "podinfo.fullname" . }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "podinfo.serviceAccountName" -}} +{{- if .Values.serviceAccount.enabled }} +{{- default (include "podinfo.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the tls secret for secure port +*/}} +{{- define "podinfo.tlsSecretName" -}} +{{- $fullname := include "podinfo.fullname" . -}} +{{- default (printf "%s-tls" $fullname) .Values.tls.secretName }} +{{- end }} \ No newline at end of file diff --git a/config/testdata/charts/pod2info/templates/certificate.yaml b/config/testdata/charts/pod2info/templates/certificate.yaml new file mode 100644 index 000000000..9393c7323 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/certificate.yaml @@ -0,0 +1,17 @@ +{{- if .Values.certificate.create -}} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "podinfo.fullname" . }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} +spec: + dnsNames: + {{- range .Values.certificate.dnsNames }} + - {{ . | quote }} + {{- end }} + secretName: {{ template "podinfo.tlsSecretName" . }} + issuerRef: + {{- .Values.certificate.issuerRef | toYaml | trimSuffix "\n" | nindent 4 }} +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/deployment.yaml b/config/testdata/charts/pod2info/templates/deployment.yaml new file mode 100644 index 000000000..177b0573c --- /dev/null +++ b/config/testdata/charts/pod2info/templates/deployment.yaml @@ -0,0 +1,229 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "podinfo.fullname" . }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} +spec: + {{- if not .Values.hpa.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + selector: + matchLabels: + {{- include "podinfo.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "podinfo.selectorLabels" . | nindent 8 }} + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.service.httpPort }}" + {{- range $key, $value := .Values.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + terminationGracePeriodSeconds: 30 + {{- if .Values.serviceAccount.enabled }} + serviceAccountName: {{ template "podinfo.serviceAccountName" . }} + {{- end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: {{ toYaml .Values.image.pullSecrets | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.securityContext }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + {{- else if (or .Values.service.hostPort .Values.tls.hostPort) }} + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE + {{- end }} + command: + - ./podinfo + - --port={{ .Values.service.httpPort | default 9898 }} + {{- if .Values.host }} + - --host={{ .Values.host }} + {{- end }} + {{- if .Values.tls.enabled }} + - --secure-port={{ .Values.tls.port }} + {{- end }} + {{- if .Values.tls.certPath }} + - --cert-path={{ .Values.tls.certPath }} + {{- end }} + {{- if .Values.service.metricsPort }} + - --port-metrics={{ .Values.service.metricsPort }} + {{- end }} + {{- if .Values.service.grpcPort }} + - --grpc-port={{ .Values.service.grpcPort }} + {{- end }} + {{- if .Values.service.grpcService }} + - --grpc-service-name={{ .Values.service.grpcService }} + {{- end }} + {{- range .Values.backends }} + - --backend-url={{ . }} + {{- end }} + {{- if .Values.cache }} + - --cache-server={{ .Values.cache }} + {{- else if .Values.redis.enabled }} + - --cache-server=tcp://{{ template "podinfo.fullname" . }}-redis:6379 + {{- end }} + - --level={{ .Values.logLevel }} + - --random-delay={{ .Values.faults.delay }} + - --random-error={{ .Values.faults.error }} + {{- if .Values.faults.unhealthy }} + - --unhealthy + {{- end }} + {{- if .Values.faults.unready }} + - --unready + {{- end }} + {{- if .Values.h2c.enabled }} + - --h2c + {{- end }} + {{- with .Values.config.path }} + - --config-path={{ . }} + {{- end }} + {{- with .Values.config.name }} + - --config={{ . }} + {{- end }} + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + env: + {{- if .Values.ui.message }} + - name: PODINFO_UI_MESSAGE + value: {{ quote .Values.ui.message }} + {{- end }} + {{- if .Values.ui.logo }} + - name: PODINFO_UI_LOGO + value: {{ .Values.ui.logo }} + {{- end }} + {{- if .Values.ui.color }} + - name: PODINFO_UI_COLOR + value: {{ quote .Values.ui.color }} + {{- end }} + {{- if .Values.backend }} + - name: PODINFO_BACKEND_URL + value: {{ .Values.backend }} + {{- end }} + {{- if .Values.extraEnvs }} +{{ toYaml .Values.extraEnvs | indent 10 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.service.httpPort | default 9898 }} + protocol: TCP + {{- if .Values.service.hostPort }} + hostPort: {{ .Values.service.hostPort }} + {{- end }} + {{- if .Values.tls.enabled }} + - name: https + containerPort: {{ .Values.tls.port | default 9899 }} + protocol: TCP + {{- if .Values.tls.hostPort }} + hostPort: {{ .Values.tls.hostPort }} + {{- end }} + {{- end }} + {{- if .Values.service.metricsPort }} + - name: http-metrics + containerPort: {{ .Values.service.metricsPort }} + protocol: TCP + {{- end }} + {{- if .Values.service.grpcPort }} + - name: grpc + containerPort: {{ .Values.service.grpcPort }} + protocol: TCP + {{- end }} + {{- if .Values.probes.startup.enable }} + startupProbe: + exec: + command: + - podcli + - check + - http + - localhost:{{ .Values.service.httpPort | default 9898 }}/healthz + {{- with .Values.probes.startup }} + initialDelaySeconds: {{ .initialDelaySeconds | default 1 }} + timeoutSeconds: {{ .timeoutSeconds | default 5 }} + failureThreshold: {{ .failureThreshold | default 3 }} + successThreshold: {{ .successThreshold | default 1 }} + periodSeconds: {{ .periodSeconds | default 10 }} + {{- end }} + {{- end }} + livenessProbe: + exec: + command: + - podcli + - check + - http + - localhost:{{ .Values.service.httpPort | default 9898 }}/healthz + {{- with .Values.probes.liveness }} + initialDelaySeconds: {{ .initialDelaySeconds | default 1 }} + timeoutSeconds: {{ .timeoutSeconds | default 5 }} + failureThreshold: {{ .failureThreshold | default 3 }} + successThreshold: {{ .successThreshold | default 1 }} + periodSeconds: {{ .periodSeconds | default 10 }} + {{- end }} + readinessProbe: + exec: + command: + - podcli + - check + - http + - localhost:{{ .Values.service.httpPort | default 9898 }}/readyz + {{- with .Values.probes.readiness }} + initialDelaySeconds: {{ .initialDelaySeconds | default 1 }} + timeoutSeconds: {{ .timeoutSeconds | default 5 }} + failureThreshold: {{ .failureThreshold | default 3 }} + successThreshold: {{ .successThreshold | default 1 }} + periodSeconds: {{ .periodSeconds | default 10 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /data + {{- if .Values.tls.enabled }} + - name: tls + mountPath: {{ .Values.tls.certPath | default "/data/cert" }} + readOnly: true + {{- end }} + resources: +{{ toYaml .Values.resources | indent 12 }} + {{- with .Values.podSecurityContext }} + securityContext: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + volumes: + - name: data + emptyDir: {} + {{- if .Values.tls.enabled }} + - name: tls + secret: + secretName: {{ template "podinfo.tlsSecretName" . }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: +{{- toYaml . | nindent 8 }} + {{- end }} diff --git a/config/testdata/charts/pod2info/templates/hpa.yaml b/config/testdata/charts/pod2info/templates/hpa.yaml new file mode 100644 index 000000000..f33cf463d --- /dev/null +++ b/config/testdata/charts/pod2info/templates/hpa.yaml @@ -0,0 +1,42 @@ +{{- if .Values.hpa.enabled -}} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ template "podinfo.fullname" . }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "podinfo.fullname" . }} + minReplicas: {{ .Values.replicaCount }} + maxReplicas: {{ .Values.hpa.maxReplicas }} + metrics: + {{- if .Values.hpa.cpu }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.hpa.cpu }} + {{- end }} + {{- if .Values.hpa.memory }} + - type: Resource + resource: + name: memory + target: + type: AverageValue + averageValue: {{ .Values.hpa.memory }} + {{- end }} + {{- if .Values.hpa.requests }} + - type: Pods + pods: + metric: + name: http_requests + target: + type: AverageValue + averageValue: {{ .Values.hpa.requests }} + {{- end }} +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/httproute.yaml b/config/testdata/charts/pod2info/templates/httproute.yaml new file mode 100644 index 000000000..b10394cfb --- /dev/null +++ b/config/testdata/charts/pod2info/templates/httproute.yaml @@ -0,0 +1,41 @@ +{{- if .Values.httpRoute.enabled -}} +{{- $fullName := include "podinfo.fullname" . -}} +{{- $svcPort := .Values.service.externalPort -}} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ $fullName }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + {{- with .Values.httpRoute.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.httpRoute.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + parentRefs: + {{- with .Values.httpRoute.parentRefs }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.httpRoute.hostnames }} + hostnames: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + {{- range .Values.httpRoute.rules }} + {{- with .matches }} + - matches: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .filters }} + filters: + {{- toYaml . | nindent 8 }} + {{- end }} + backendRefs: + - name: {{ $fullName }} + port: {{ $svcPort }} + weight: 1 + {{- end }} +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/ingress.yaml b/config/testdata/charts/pod2info/templates/ingress.yaml new file mode 100644 index 000000000..826942209 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/ingress.yaml @@ -0,0 +1,45 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "podinfo.fullname" . -}} +{{- $svcPort := .Values.service.externalPort -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + {{- with .Values.ingress.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ingressClassName: {{ .Values.ingress.className }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- end }} + {{- end }} +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/linkerd.yaml b/config/testdata/charts/pod2info/templates/linkerd.yaml new file mode 100644 index 000000000..15ae969c4 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/linkerd.yaml @@ -0,0 +1,99 @@ +{{- if .Values.linkerd.profile.enabled -}} +apiVersion: linkerd.io/v1alpha2 +kind: ServiceProfile +metadata: + name: {{ template "podinfo.fullname" . }}.{{ include "podinfo.namespace" . }}.svc.cluster.local + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} +spec: + routes: + - condition: + method: GET + pathRegex: / + name: GET / + - condition: + method: POST + pathRegex: /api/echo + name: POST /api/echo + - condition: + method: GET + pathRegex: /api/info + name: GET /api/info + - condition: + method: GET + pathRegex: /chunked/[^/]* + name: GET /chunked/{seconds} + - condition: + method: GET + pathRegex: /delay/[^/]* + name: GET /delay/{seconds} + - condition: + method: GET + pathRegex: /env + name: GET /env + - condition: + method: GET + pathRegex: /headers + name: GET /headers + - condition: + method: GET + pathRegex: /healthz + name: GET /healthz + - condition: + method: GET + pathRegex: /metrics + name: GET /metrics + - condition: + method: GET + pathRegex: /panic + name: GET /panic + - condition: + method: GET + pathRegex: /readyz + name: GET /readyz + - condition: + method: POST + pathRegex: /readyz/disable + name: POST /readyz/disable + - condition: + method: POST + pathRegex: /readyz/enable + name: POST /readyz/enable + - condition: + method: GET + pathRegex: /status/[^/]* + name: GET /status/{code} + - condition: + method: POST + pathRegex: /cache + name: POST /cache + - condition: + method: GET + pathRegex: /cache/[^/]* + name: GET /cache/{hash} + - condition: + method: POST + pathRegex: /store + name: POST /store + - condition: + method: GET + pathRegex: /store/[^/]* + name: GET /store/{hash} + - condition: + method: POST + pathRegex: /token + name: POST /token + - condition: + method: POST + pathRegex: /token/validate + name: POST /token/validate + - condition: + method: GET + pathRegex: /version + name: GET /version + - condition: + method: POST + pathRegex: /ws/echo + name: POST /ws/echo +{{- end }} \ No newline at end of file diff --git a/config/testdata/charts/pod2info/templates/pdb.yaml b/config/testdata/charts/pod2info/templates/pdb.yaml new file mode 100644 index 000000000..97002e657 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/pdb.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.podDisruptionBudget (gt (int .Values.replicaCount) 1) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "podinfo.fullname" . }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "podinfo.selectorLabels" . | nindent 6 }} + {{- toYaml .Values.podDisruptionBudget | nindent 2 }} +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/redis/config.yaml b/config/testdata/charts/pod2info/templates/redis/config.yaml new file mode 100644 index 000000000..cd63785c8 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/redis/config.yaml @@ -0,0 +1,12 @@ +{{- if .Values.redis.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "podinfo.fullname" . }}-redis +data: + redis.conf: | + maxmemory 64mb + maxmemory-policy allkeys-lru + save "" + appendonly no +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/redis/deployment.yaml b/config/testdata/charts/pod2info/templates/redis/deployment.yaml new file mode 100644 index 000000000..829562eb5 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/redis/deployment.yaml @@ -0,0 +1,71 @@ +{{- if .Values.redis.enabled -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "podinfo.fullname" . }}-redis + labels: + app: {{ template "podinfo.fullname" . }}-redis +spec: + strategy: + type: Recreate + selector: + matchLabels: + app: {{ template "podinfo.fullname" . }}-redis + template: + metadata: + labels: + app: {{ template "podinfo.fullname" . }}-redis + annotations: + checksum/config: {{ include (print $.Template.BasePath "/redis/config.yaml") . | sha256sum | quote }} + spec: + {{- if .Values.serviceAccount.enabled }} + serviceAccountName: {{ template "podinfo.serviceAccountName" . }} + {{- end }} + {{- if .Values.redis.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.redis.imagePullSecrets | nindent 8 }} + {{- end }} + containers: + - name: redis + image: "{{ .Values.redis.repository }}:{{ .Values.redis.tag }}" + imagePullPolicy: IfNotPresent + command: + - redis-server + - "/redis-master/redis.conf" + ports: + - name: redis + containerPort: 6379 + protocol: TCP + livenessProbe: + tcpSocket: + port: redis + initialDelaySeconds: 5 + timeoutSeconds: 5 + readinessProbe: + exec: + command: + - redis-cli + - ping + initialDelaySeconds: 5 + timeoutSeconds: 5 + resources: + limits: + cpu: 1000m + memory: 128Mi + requests: + cpu: 100m + memory: 32Mi + volumeMounts: + - mountPath: /var/lib/redis + name: data + - mountPath: /redis-master + name: config + volumes: + - name: data + emptyDir: {} + - name: config + configMap: + name: {{ template "podinfo.fullname" . }}-redis + items: + - key: redis.conf + path: redis.conf +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/redis/service.yaml b/config/testdata/charts/pod2info/templates/redis/service.yaml new file mode 100644 index 000000000..820320506 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/redis/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.redis.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "podinfo.fullname" . }}-redis + labels: + app: {{ template "podinfo.fullname" . }}-redis +spec: + type: ClusterIP + selector: + app: {{ template "podinfo.fullname" . }}-redis + ports: + - name: redis + port: 6379 + protocol: TCP + targetPort: redis + appProtocol: redis +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/service.yaml b/config/testdata/charts/pod2info/templates/service.yaml new file mode 100644 index 000000000..040769a0a --- /dev/null +++ b/config/testdata/charts/pod2info/templates/service.yaml @@ -0,0 +1,37 @@ +{{- if .Values.service.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "podinfo.fullname" . }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} +{{- with .Values.service.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.externalPort }} + targetPort: http + protocol: TCP + name: http + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + {{- if .Values.tls.enabled }} + - port: {{ .Values.tls.port | default 9899 }} + targetPort: https + protocol: TCP + name: https + {{- end }} + {{- if .Values.service.grpcPort }} + - port: {{ .Values.service.grpcPort }} + targetPort: grpc + protocol: TCP + name: grpc + {{- end }} + selector: + {{- include "podinfo.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/serviceaccount.yaml b/config/testdata/charts/pod2info/templates/serviceaccount.yaml new file mode 100644 index 000000000..72ff524d2 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.enabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "podinfo.serviceAccountName" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} +{{- with .Values.serviceAccount.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/config/testdata/charts/pod2info/templates/servicemonitor.yaml b/config/testdata/charts/pod2info/templates/servicemonitor.yaml new file mode 100644 index 000000000..f868d8585 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/servicemonitor.yaml @@ -0,0 +1,23 @@ +{{- if .Values.serviceMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "podinfo.fullname" . }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + {{- with .Values.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - path: /metrics + port: http + interval: {{ .Values.serviceMonitor.interval }} + namespaceSelector: + matchNames: + - {{ include "podinfo.namespace" . }} + selector: + matchLabels: + {{- include "podinfo.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/tests/cache.yaml b/config/testdata/charts/pod2info/templates/tests/cache.yaml new file mode 100644 index 000000000..98e335795 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/tests/cache.yaml @@ -0,0 +1,30 @@ +{{- if .Values.cache }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "podinfo.fullname" . }}-cache-test-{{ randAlphaNum 5 | lower }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + sidecar.istio.io/inject: "false" + linkerd.io/inject: disabled + appmesh.k8s.aws/sidecarInjectorWebhook: disabled +spec: + containers: + - name: curl + image: curlimages/curl:7.69.0 + command: + - sh + - -c + - | + curl -sd 'data' ${PODINFO_SVC}/cache/test && + curl -s ${PODINFO_SVC}/cache/test | grep data && + curl -s -XDELETE ${PODINFO_SVC}/cache/test + env: + - name: PODINFO_SVC + value: "{{ template "podinfo.fullname" . }}.{{ include "podinfo.namespace" . }}:{{ .Values.service.externalPort }}" + restartPolicy: Never +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/tests/fail.yaml b/config/testdata/charts/pod2info/templates/tests/fail.yaml new file mode 100644 index 000000000..44b279753 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/tests/fail.yaml @@ -0,0 +1,22 @@ +{{- if .Values.faults.testFail }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "podinfo.fullname" . }}-fault-test-{{ randAlphaNum 5 | lower }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + sidecar.istio.io/inject: "false" + linkerd.io/inject: disabled + appmesh.k8s.aws/sidecarInjectorWebhook: disabled +spec: + containers: + - name: fault + image: alpine:3.11 + command: ['/bin/sh'] + args: ['-c', 'exit 1'] + restartPolicy: Never +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/tests/grpc.yaml b/config/testdata/charts/pod2info/templates/tests/grpc.yaml new file mode 100644 index 000000000..5720f4856 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/tests/grpc.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "podinfo.fullname" . }}-grpc-test-{{ randAlphaNum 5 | lower }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + sidecar.istio.io/inject: "false" + linkerd.io/inject: disabled + appmesh.k8s.aws/sidecarInjectorWebhook: disabled +spec: + containers: + - name: grpc-health-probe + image: stefanprodan/grpc_health_probe:v0.3.0 + command: ['grpc_health_probe'] + args: ['-addr={{ template "podinfo.fullname" . }}.{{ include "podinfo.namespace" . }}:{{ .Values.service.grpcPort }}'] + restartPolicy: Never diff --git a/config/testdata/charts/pod2info/templates/tests/jwt.yaml b/config/testdata/charts/pod2info/templates/tests/jwt.yaml new file mode 100644 index 000000000..5eb2edcda --- /dev/null +++ b/config/testdata/charts/pod2info/templates/tests/jwt.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "podinfo.fullname" . }}-jwt-test-{{ randAlphaNum 5 | lower }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + sidecar.istio.io/inject: "false" + linkerd.io/inject: disabled + appmesh.k8s.aws/sidecarInjectorWebhook: disabled +spec: + containers: + - name: tools + image: giantswarm/tiny-tools + command: + - sh + - -c + - | + TOKEN=$(curl -sd 'test' ${PODINFO_SVC}/token | jq -r .token) && + curl -sH "Authorization: Bearer ${TOKEN}" ${PODINFO_SVC}/token/validate | grep test + env: + - name: PODINFO_SVC + value: "{{ template "podinfo.fullname" . }}.{{ include "podinfo.namespace" . }}:{{ .Values.service.externalPort }}" + restartPolicy: Never diff --git a/config/testdata/charts/pod2info/templates/tests/service.yaml b/config/testdata/charts/pod2info/templates/tests/service.yaml new file mode 100644 index 000000000..74b8bc797 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/tests/service.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "podinfo.fullname" . }}-service-test-{{ randAlphaNum 5 | lower }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + sidecar.istio.io/inject: "false" + linkerd.io/inject: disabled + appmesh.k8s.aws/sidecarInjectorWebhook: disabled +spec: + containers: + - name: curl + image: curlimages/curl:7.69.0 + command: + - sh + - -c + - | + curl -s ${PODINFO_SVC}/api/info | grep version + env: + - name: PODINFO_SVC + value: "{{ template "podinfo.fullname" . }}.{{ include "podinfo.namespace" . }}:{{ .Values.service.externalPort }}" + restartPolicy: Never diff --git a/config/testdata/charts/pod2info/templates/tests/timeout.yaml b/config/testdata/charts/pod2info/templates/tests/timeout.yaml new file mode 100644 index 000000000..884769a05 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/tests/timeout.yaml @@ -0,0 +1,22 @@ +{{- if .Values.faults.testTimeout }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "podinfo.fullname" . }}-fault-test-{{ randAlphaNum 5 | lower }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + sidecar.istio.io/inject: "false" + linkerd.io/inject: disabled + appmesh.k8s.aws/sidecarInjectorWebhook: disabled +spec: + containers: + - name: fault + image: alpine:3.11 + command: ['/bin/sh'] + args: ['-c', 'while sleep 3600; do :; done'] + restartPolicy: Never +{{- end }} diff --git a/config/testdata/charts/pod2info/templates/tests/tls.yaml b/config/testdata/charts/pod2info/templates/tests/tls.yaml new file mode 100644 index 000000000..0cc659a66 --- /dev/null +++ b/config/testdata/charts/pod2info/templates/tests/tls.yaml @@ -0,0 +1,28 @@ +{{- if .Values.tls.enabled -}} +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "podinfo.fullname" . }}-tls-test-{{ randAlphaNum 5 | lower }} + namespace: {{ include "podinfo.namespace" . }} + labels: + {{- include "podinfo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + sidecar.istio.io/inject: "false" + linkerd.io/inject: disabled + appmesh.k8s.aws/sidecarInjectorWebhook: disabled +spec: + containers: + - name: curl + image: curlimages/curl:7.69.0 + command: + - sh + - -c + - | + curl -sk ${PODINFO_SVC}/api/info | grep version + env: + - name: PODINFO_SVC + value: "https://{{ template "podinfo.fullname" . }}.{{ include "podinfo.namespace" . }}:{{ .Values.tls.port }}" + restartPolicy: Never +{{- end }} \ No newline at end of file diff --git a/config/testdata/charts/pod2info/values-prod.yaml b/config/testdata/charts/pod2info/values-prod.yaml new file mode 100644 index 000000000..2d6b1b142 --- /dev/null +++ b/config/testdata/charts/pod2info/values-prod.yaml @@ -0,0 +1,211 @@ +# Production values for podinfo. +# Includes Redis deployment and memory limits. + +replicaCount: 1 +logLevel: info +backend: #http://backend-podinfo:9898/echo +backends: [] + +image: + repository: ghcr.io/stefanprodan/podinfo + tag: 6.9.3 + pullPolicy: IfNotPresent + +ui: + color: "#34577c" + message: "" + logo: "" + +# failure conditions +faults: + delay: false + error: false + unhealthy: false + unready: false + testFail: false + testTimeout: false + +# Kubernetes Service settings +service: + enabled: true + annotations: {} + type: ClusterIP + metricsPort: 9797 + httpPort: 9898 + externalPort: 9898 + grpcPort: 9999 + grpcService: podinfo + nodePort: 31198 + +# enable h2c protocol (non-TLS version of HTTP/2) +h2c: + enabled: false + +# config file settings +config: + # config file path + path: "" + # config file name + name: "" + +# Additional command line arguments to pass to podinfo container +extraArgs: [] + +# enable tls on the podinfo service +tls: + enabled: false + # the name of the secret used to mount the certificate key pair + secretName: + # the path where the certificate key pair will be mounted + certPath: /data/cert + # the port used to host the tls endpoint on the service + port: 9899 + # the port used to bind the tls port to the host + # NOTE: requires privileged container with NET_BIND_SERVICE capability -- this is useful for testing + # in local clusters such as kind without port forwarding + hostPort: + +# create a certificate manager certificate (cert-manager required) +certificate: + create: false + # the issuer used to issue the certificate + issuerRef: + kind: ClusterIssuer + name: self-signed + # the hostname / subject alternative names for the certificate + dnsNames: + - podinfo + +# metrics-server add-on required +hpa: + enabled: true + maxReplicas: 5 + # average total CPU usage per pod (1-100) + cpu: 99 + # average memory usage per pod (100Mi-1Gi) + memory: + # average http requests per second per pod (k8s-prometheus-adapter) + requests: + +# Redis address in the format tcp://: +cache: "" +# Redis deployment +redis: + enabled: true + repository: redis + tag: 8.4.0 + +serviceAccount: + # Specifies whether a service account should be created + enabled: false + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: + # List of image pull secrets if pulling from private registries + imagePullSecrets: [] + +# set container security context +securityContext: {} + +# set pod security context +podSecurityContext: {} + +# -- Expose the service via Kubernetes Ingress +# Requires an Ingress controller +# Docs https://kubernetes.io/docs/concepts/services-networking/ingress/ +ingress: + enabled: false + className: "" + additionalLabels: {} + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: podinfo.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +# -- Expose the service via Gateway HTTPRoute +# Requires a Gateway controller +# Docs https://gateway-api.sigs.k8s.io/guides/ +httpRoute: + # HTTPRoute enabled. + enabled: false + # Add additional labels to the HTTPRoute. + additionalLabels: {} + # HTTPRoute annotations. + annotations: {} + # Which Gateways this Route is attached to. + parentRefs: + - name: gateway + sectionName: http + # namespace: default + # Hostnames matching HTTP header. + hostnames: + - podinfo.local + # List of rules and filters applied. + rules: + - matches: + - path: + type: PathPrefix + value: / + +linkerd: + profile: + enabled: false + +# create Prometheus Operator monitor +serviceMonitor: + enabled: false + interval: 15s + additionalLabels: {} + +resources: + limits: + memory: 256Mi + requests: + cpu: 100m + memory: 64Mi + +# Extra environment variables for the podinfo container +extraEnvs: [] +# Example on how to configure extraEnvs +# - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT +# value: "http://otel:4317" +# - name: MULTIPLE_VALUES +# value: TEST + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +podAnnotations: {} + +# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes +probes: + readiness: + initialDelaySeconds: 1 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + periodSeconds: 10 + liveness: + initialDelaySeconds: 1 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + periodSeconds: 10 + startup: + enable: false + initialDelaySeconds: 10 + timeoutSeconds: 5 + failureThreshold: 20 + successThreshold: 1 + periodSeconds: 10 diff --git a/config/testdata/charts/pod2info/values.schema.json b/config/testdata/charts/pod2info/values.schema.json new file mode 100644 index 000000000..01a232238 --- /dev/null +++ b/config/testdata/charts/pod2info/values.schema.json @@ -0,0 +1,501 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "replicaCount": { + "type": "integer" + }, + "logLevel": { + "type": "string" + }, + "host": { + "type": "null" + }, + "backend": { + "type": "null" + }, + "backends": { + "type": "array", + "items": {} + }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "pullSecrets": { + "type": "array", + "items": {} + } + } + }, + "ui": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "message": { + "type": "string" + }, + "logo": { + "type": "string" + } + } + }, + "faults": { + "type": "object", + "properties": { + "delay": { + "type": "boolean" + }, + "error": { + "type": "boolean" + }, + "unhealthy": { + "type": "boolean" + }, + "unready": { + "type": "boolean" + }, + "testFail": { + "type": "boolean" + }, + "testTimeout": { + "type": "boolean" + } + } + }, + "service": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "annotations": { + "type": "object" + }, + "type": { + "type": "string" + }, + "metricsPort": { + "type": "integer" + }, + "httpPort": { + "type": "integer" + }, + "externalPort": { + "type": "integer" + }, + "grpcPort": { + "type": "integer" + }, + "grpcService": { + "type": "string" + }, + "nodePort": { + "type": "integer" + }, + "hostPort": { + "type": "null" + } + } + }, + "h2c": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "config": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "extraArgs": { + "type": "array", + "items": {} + }, + "extraEnvs": { + "type": "array", + "items": {} + }, + "tls": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "secretName": { + "type": "null" + }, + "certPath": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "hostPort": { + "type": "null" + } + } + }, + "certificate": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "issuerRef": { + "type": "object", + "properties": { + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "dnsNames": { + "type": "array", + "items": [ + { + "type": "string" + } + ] + } + } + }, + "hpa": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxReplicas": { + "type": "integer" + }, + "cpu": { + "type": "null" + }, + "memory": { + "type": "null" + }, + "requests": { + "type": "null" + } + } + }, + "cache": { + "type": "string" + }, + "redis": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + }, + "imagePullSecrets": { + "type": "array", + "items": {} + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "null" + }, + "imagePullSecrets": { + "type": "array", + "items": {} + } + } + }, + "securityContext": { + "type": "object" + }, + "podSecurityContext": { + "type": "object" + }, + "ingress": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "className": { + "type": "string" + }, + "additionalLabels": { + "type": "object" + }, + "annotations": { + "type": "object" + }, + "hosts": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "paths": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "pathType": { + "type": "string" + } + } + } + ] + } + } + } + ] + }, + "tls": { + "type": "array", + "items": {} + } + } + }, + "httpRoute": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "additionalLabels": { + "type": "object" + }, + "annotations": { + "type": "object" + }, + "parentRefs": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "sectionName": { + "type": "string" + } + } + } + ] + }, + "hostnames": { + "type": "array", + "items": [ + { + "type": "string" + } + ] + }, + "rules": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "matches": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "path": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "value": { + "type": "string" + } + } + } + } + } + ] + } + } + } + ] + } + } + }, + "linkerd": { + "type": "object", + "properties": { + "profile": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + } + } + }, + "serviceMonitor": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "interval": { + "type": "string" + }, + "additionalLabels": { + "type": "object" + } + } + }, + "resources": { + "type": "object", + "properties": { + "limits": { + "type": "null" + }, + "requests": { + "type": "object", + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + } + } + } + }, + "nodeSelector": { + "type": "object" + }, + "tolerations": { + "type": "array", + "items": {} + }, + "affinity": { + "type": "object" + }, + "podAnnotations": { + "type": "object" + }, + "topologySpreadConstraints": { + "type": "array", + "items": {} + }, + "podDisruptionBudget": { + "type": "object" + }, + "probes": { + "type": "object", + "properties": { + "readiness": { + "type": "object", + "properties": { + "initialDelaySeconds": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + }, + "failureThreshold": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + } + } + }, + "liveness": { + "type": "object", + "properties": { + "initialDelaySeconds": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + }, + "failureThreshold": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + } + } + }, + "startup": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + }, + "failureThreshold": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + } + } + } + } + } + } +} diff --git a/config/testdata/charts/pod2info/values.yaml b/config/testdata/charts/pod2info/values.yaml new file mode 100644 index 000000000..706209e96 --- /dev/null +++ b/config/testdata/charts/pod2info/values.yaml @@ -0,0 +1,224 @@ +# Default values for podinfo. + +replicaCount: 1 +logLevel: info +host: #0.0.0.0 +backend: #http://backend-podinfo:9898/echo +backends: [] +# somethingelse: blah + +image: + repository: ghcr.io/stefanprodan/podinfo + tag: 6.9.3 + pullPolicy: IfNotPresent + pullSecrets: [] + +ui: + color: "#34577c" + message: "" + logo: "" + +# failure conditions +faults: + delay: false + error: false + unhealthy: false + unready: false + testFail: false + testTimeout: false + +# Kubernetes Service settings +service: + enabled: true + annotations: {} + type: ClusterIP + metricsPort: 9797 + httpPort: 9898 + externalPort: 9898 + grpcPort: 9999 + grpcService: podinfo + nodePort: 31198 + # the port used to bind the http port to the host + # NOTE: requires privileged container with NET_BIND_SERVICE capability -- this is useful for testing + # in local clusters such as kind without port forwarding + hostPort: + +# enable h2c protocol (non-TLS version of HTTP/2) +h2c: + enabled: false + +# config file settings +config: + # config file path + path: "" + # config file name + name: "" + +# Additional command line arguments to pass to podinfo container +extraArgs: [] + +# Extra environment variables for the podinfo container +extraEnvs: [] +# Example on how to configure extraEnvs +# - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT +# value: "http://otel:4317" +# - name: MULTIPLE_VALUES +# value: TEST + +# enable tls on the podinfo service +tls: + enabled: false + # the name of the secret used to mount the certificate key pair + secretName: + # the path where the certificate key pair will be mounted + certPath: /data/cert + # the port used to host the tls endpoint on the service + port: 9899 + # the port used to bind the tls port to the host + # NOTE: requires privileged container with NET_BIND_SERVICE capability -- this is useful for testing + # in local clusters such as kind without port forwarding + hostPort: + +# create a certificate manager certificate (cert-manager required) +certificate: + create: false + # the issuer used to issue the certificate + issuerRef: + kind: ClusterIssuer + name: self-signed + # the hostname / subject alternative names for the certificate + dnsNames: + - podinfo + +# metrics-server add-on required +hpa: + enabled: false + maxReplicas: 10 + # average total CPU usage per pod (1-100) + cpu: + # average memory usage per pod (100Mi-1Gi) + memory: + # average http requests per second per pod (k8s-prometheus-adapter) + requests: + +# Redis address in the format tcp://: +cache: "" +# Redis deployment +redis: + enabled: false + repository: docker.io/redis + tag: 8.4.0 + imagePullSecrets: [] + +serviceAccount: + # Specifies whether a service account should be created + enabled: false + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: + # List of image pull secrets if pulling from private registries + imagePullSecrets: [] + +# set container security context +securityContext: {} + +# set pod security context +podSecurityContext: {} + +# -- Expose the service via Kubernetes Ingress +# Requires an Ingress controller +# Docs https://kubernetes.io/docs/concepts/services-networking/ingress/ +ingress: + enabled: false + className: "" + additionalLabels: {} + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: podinfo.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +# -- Expose the service via Gateway HTTPRoute +# Requires a Gateway controller +# Docs https://gateway-api.sigs.k8s.io/guides/ +httpRoute: + # HTTPRoute enabled. + enabled: false + # Add additional labels to the HTTPRoute. + additionalLabels: {} + # HTTPRoute annotations. + annotations: {} + # Which Gateways this Route is attached to. + parentRefs: + - name: gateway + sectionName: http + # namespace: default + # Hostnames matching HTTP header. + hostnames: + - podinfo.local + # List of rules and filters applied. + rules: + - matches: + - path: + type: PathPrefix + value: / + +linkerd: + profile: + enabled: false + +# create Prometheus Operator monitor +serviceMonitor: + enabled: false + interval: 15s + additionalLabels: {} + +resources: + limits: + requests: + cpu: 1m + memory: 16Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +podAnnotations: {} + +# https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +topologySpreadConstraints: [] + +# Disruption budget will be configured only when the replicaCount is greater than 1 +podDisruptionBudget: {} +# maxUnavailable: 1 + +# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes +probes: + readiness: + initialDelaySeconds: 1 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + periodSeconds: 10 + liveness: + initialDelaySeconds: 1 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + periodSeconds: 10 + startup: + enable: false + initialDelaySeconds: 10 + timeoutSeconds: 5 + failureThreshold: 20 + successThreshold: 1 + periodSeconds: 10 diff --git a/config/testdata/upgrade-chart-name-change/install.yaml b/config/testdata/upgrade-chart-name-change/install.yaml new file mode 100644 index 000000000..f34cdf2b1 --- /dev/null +++ b/config/testdata/upgrade-chart-name-change/install.yaml @@ -0,0 +1,19 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: upgrade-chart-name-change +spec: + interval: 30s + chart: + spec: + chart: podinfo + version: '>=6.0.0 <7.0.0' + sourceRef: + kind: HelmRepository + name: podinfo + interval: 10m + values: + resources: + requests: + cpu: 100m + memory: 64Mi diff --git a/config/testdata/upgrade-chart-name-change/upgrade-inplace.yaml b/config/testdata/upgrade-chart-name-change/upgrade-inplace.yaml new file mode 100644 index 000000000..07190f6da --- /dev/null +++ b/config/testdata/upgrade-chart-name-change/upgrade-inplace.yaml @@ -0,0 +1,22 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: upgrade-chart-name-change +spec: + interval: 30s + chart: + spec: + chart: config/testdata/charts/pod2info + version: '>=6.0.0 <7.0.0' + sourceRef: + kind: GitRepository + name: this + namespace: default + interval: 10m + upgrade: + chartNameChangeStrategy: InPlaceUpdate + values: + resources: + requests: + cpu: 100m + memory: 64Mi diff --git a/config/testdata/upgrade-chart-name-change/upgrade-reinstall.yaml b/config/testdata/upgrade-chart-name-change/upgrade-reinstall.yaml new file mode 100644 index 000000000..fe498186d --- /dev/null +++ b/config/testdata/upgrade-chart-name-change/upgrade-reinstall.yaml @@ -0,0 +1,22 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: upgrade-chart-name-change +spec: + interval: 30s + chart: + spec: + chart: config/testdata/charts/pod2info + version: '>=6.0.0 <7.0.0' + sourceRef: + kind: GitRepository + name: this + namespace: default + interval: 10m + upgrade: + chartNameChangeStrategy: Reinstall + values: + resources: + requests: + cpu: 100m + memory: 64Mi diff --git a/config/testdata/upgrade-chart-name-change/upgrade.yaml b/config/testdata/upgrade-chart-name-change/upgrade.yaml new file mode 100644 index 000000000..006f7636d --- /dev/null +++ b/config/testdata/upgrade-chart-name-change/upgrade.yaml @@ -0,0 +1,20 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: upgrade-chart-name-change +spec: + interval: 30s + chart: + spec: + chart: config/testdata/charts/pod2info + version: '>=6.0.0 <7.0.0' + sourceRef: + kind: GitRepository + name: this + namespace: default + interval: 10m + values: + resources: + requests: + cpu: 100m + memory: 64Mi