diff --git a/Chart.yaml b/Chart.yaml index c94797f..2b4da0a 100755 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,24 +1,24 @@ apiVersion: v2 -name: helm-template -description: A Helm chart for Kubernetes +name: helm-generic +description: Generic helm chart for all kind of applications -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. type: application +version: 0.1.1 -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: "0.1.0" +keywords: + - java + - node + - dotnet + - kubernetes + - stakater + - application -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: "1.16.0" +home: https://github.com/stakater/application +maintainers: + - name: Ahmad Ali Bagheri + email: ahmad@devopshobbies.com + + - name: Mehdi Rahimi + email: mediraworkm@gmail.com + +icon: https://github.com/stakater/ForecastleIcons/blob/master/stakater.png diff --git a/README.md b/README.md index b71fd20..1fb3a71 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This chart is created to be used inside devopshobbies & kaiser-io devops operati ## How it works: -The use-case is pretty simple and you can start using this by fetching the chart. Also, there is one `values`.example.yaml` defined for you which you can check and have a look at to find out how to set the variables. +The use-case is pretty simple and you can start using this by fetching the chart. Also, there is one `values.example.yaml` defined for you which you can check and have a look at to find out how to set the variables. ## How release and versioning work: diff --git a/templates/NOTES.txt b/templates/NOTES.txt deleted file mode 100755 index 676e7a0..0000000 --- a/templates/NOTES.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 }} -{{- range $containers := .Values.containers }} -{{- range $service := $containers.ports }} -{{- if $service.service_enable }} -{{- else if contains "NodePort" $service.service_type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm-template.name" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" $service.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 --namespace {{ .Release.Namespace }} svc -w {{ include "helm-template.name" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm-template.name" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ $service.service_port }} -{{- else if contains "ClusterIP" $service.service_type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm-template.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} -{{- end }}{{- end }}{{- end }} \ No newline at end of file diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl old mode 100755 new mode 100644 index d8da814..48f8166 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -1,188 +1,62 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "helm-template.name" -}} -{{- default .Chart.Name .Values.name | 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 "helm-template.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.name }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - - -{{- define "helm-template.namespace" -}} -{{- default .Values.namespace | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "helm-template.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} +{{/* vim: set filetype=mustache: */}} {{/* -Common labels +Define the name of the chart/application. */}} -{{- define "helm-template.labels" -}} -helm.sh/chart: {{ include "helm-template.chart" . }} -{{ include "helm-template.selectorLabels" . }} -{{- $labellist := list -}} -{{- range $key := .Values.Affinity }} -{{- range $value := $key.values }} -{{- $label := cat $key.key ":" $value -}} -{{- if not (has $label $labellist) }} -{{ $key.key }}: {{ $value }} -{{- end }} -{{- $labellist = append $labellist $label -}} -{{- end }} -{{- end }} - -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} +{{- define "application.name" -}} +{{- default .Chart.Name .Values.applicationName | trunc 63 | trimSuffix "-" -}} +{{- end -}} {{/* -Selector labels +Define the name of the chart/application. */}} - -{{- define "helm-template.selectorLabels" -}} -app: {{ include "helm-template.name" . }} -{{- end }} +{{- define "application.version" -}} + {{- $version := default "" .Values.deployment.image.tag -}} + {{- regexReplaceAll "[^a-zA-Z0-9_\\.\\-]" $version "-" | trunc 63 | trimSuffix "-" -}} +{{- end -}} {{/* -Pars Affinity +Renders a value that contains template. +Usage: +{{ include "application.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} */}} -{{- define "helm-template.affinity" -}} -{{- range $typelist := (list "nodeAffinity" "nodeAntiAffinity" "podAntiAffinity" "podAffinity") -}} -{{- $afflag := list 1 -}} -{{- range $rulelist := (list "required" "preferred") -}} -{{- range $Affinities := $.Values.Affinity -}} -{{- if eq $typelist $Affinities.type -}} -{{- if not (has $typelist $afflag ) -}} -{{- $typelist | nindent 0 -}}: -{{- $afflag = append $afflag $Affinities.type -}} -{{- end -}} -{{- if eq $rulelist $Affinities.rule -}} -{{- if and (not (has $Affinities.rule $afflag)) (eq $Affinities.rule "required") }} - requiredDuringSchedulingIgnoredDuringExecution: - {{- if contains "node" $Affinities.type }} - nodeSelectorTerms: - - matchExpressions: - {{- else if contains "pod" $Affinities.type }} - - labelSelector: - matchExpressions: - {{- end }} - {{- $afflag = append $afflag $Affinities.rule -}} - {{- end }} - {{- if eq $Affinities.rule "required" }} - - key: {{ $Affinities.key }} - operator: {{ $Affinities.operator }} - values: - {{- toYaml $Affinities.values | nindent 10 }} -{{- end }} -{{- if and (not (has $Affinities.rule $afflag)) (eq $Affinities.rule "preferred") }} - preferredDuringSchedulingIgnoredDuringExecution: -{{- $afflag = append $afflag $Affinities.rule -}} -{{- end }} -{{- if eq $Affinities.rule "preferred" }} -{{- if contains "node" $Affinities.type }} - - weight: {{ $Affinities.weight | default "100" }} - preference: - matchExpressions: - - key: {{ $Affinities.key }} - operator: {{ $Affinities.operator }} - values: - {{- toYaml $Affinities.values | nindent 8 }} -{{- else if contains "pod" $Affinities.type }} - - weight: {{ $Affinities.weight | default "100" }} - podAffinityTerm: - labelSelector: - matchExpressions: - - key: {{ $Affinities.key }} - operator: {{ $Affinities.operator }} - values: - {{- toYaml $Affinities.values | nindent 12 }} -{{- end }} -{{- end }} - {{- if and (contains "pod" $Affinities.type) (eq $Affinities.rule "preferred") }} - topologyKey: "kubernetes.io/hostname" - {{- $afflag = append $afflag "topology" -}} +{{- define "application.tplvalues.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} {{- end }} {{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} - {{/* -ENV Secret +Create chart name and version as used by the chart label. */}} - -{{- define "helm-template.envsecrets" -}} -{{- range $key, $val := .Values.secretdata }} -- name: {{ $key | replace "." "_" | upper }} - valueFrom: - configMapKeyRef: - key: {{ $key }} - name: {{ include "helm-template.name" $ }}-secrets -{{- end }} +{{- define "application.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} {{/* -Secret Data +Common labels */}} -{{- define "helm-template.secretdata" -}} -{{- range $key, $val := .Values.secretdata }} -{{ $key | indent 2}}: {{ $val | quote }} +{{- define "application.labels" -}} +helm.sh/chart: {{ include "application.chart" . }} +{{- with include "application.version" . }} +app.kubernetes.io/version: {{ quote . }} {{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/part-of: {{ include "application.name" . }} {{- end }} {{/* -Volume Mounts +Selector labels */}} - -{{- define "helm-template.volumemount" -}} -{{- if .Values.volumes }} -volumeMounts: -{{- end }} -{{- range $vol := .Values.volumes }} -- mountPath: /opt/{{ $vol.name }} - name: {{ $vol.name }} -{{- end }} +{{- define "application.selectorLabels" -}} +app.kubernetes.io/name: {{ include "application.name" . }} {{- end }} {{/* -Create the name of the service account to use +Allow the release namespace to be overridden */}} -{{- define "helm-template.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "helm-template.name" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} - - -{{ define "render-value" }} - {{- if kindIs "string" .value }} - {{- tpl .value .context }} - {{- else }} - {{- tpl (.value | toYaml) .context }} - {{- end }} -{{- end }} \ No newline at end of file +{{- define "application.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride -}} +{{- end -}} diff --git a/templates/alertmanagerconfig.yaml b/templates/alertmanagerconfig.yaml new file mode 100644 index 0000000..766373a --- /dev/null +++ b/templates/alertmanagerconfig.yaml @@ -0,0 +1,22 @@ +{{- if and (.Values.alertmanagerConfig).enabled (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1alpha1") -}} +apiVersion: monitoring.coreos.com/v1alpha1 +kind: AlertmanagerConfig +metadata: + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{ toYaml .Values.alertmanagerConfig.selectionLabels | indent 4 }} +spec: +{{- if .Values.alertmanagerConfig.spec.route }} + route: +{{ toYaml .Values.alertmanagerConfig.spec.route | indent 6 }} +{{- end -}} +{{- if .Values.alertmanagerConfig.spec.receivers }} + receivers: +{{ toYaml .Values.alertmanagerConfig.spec.receivers | indent 6 }} +{{- end -}} +{{- if .Values.alertmanagerConfig.spec.inhibitRules }} + inhibitRules: {{ toYaml .Values.alertmanagerConfig.spec.inhibitRules | nindent 6 }} +{{- end -}} +{{- end -}} diff --git a/templates/certificate.yaml b/templates/certificate.yaml new file mode 100644 index 0000000..bffce90 --- /dev/null +++ b/templates/certificate.yaml @@ -0,0 +1,79 @@ +{{- if and (.Values.certificate).enabled (.Capabilities.APIVersions.Has "cert-manager.io/v1") }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "application.name" . }}-certificate + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.certificate.additionalLabels }} +{{ toYaml .Values.certificate.additionalLabels | indent 4 }} +{{- end }} +{{- if or .Values.certificate.annotations .Values.forecastle.enabled }} + annotations: +{{- end }} +{{- if .Values.certificate.annotations }} +{{ toYaml .Values.certificate.annotations | indent 4 }} +{{- end }} +spec: + secretName: {{ include "application.tplvalues.render" ( dict "value" .Values.certificate.secretName "context" $ ) }} + duration: {{ .Values.certificate.duration }} + renewBefore: {{ .Values.certificate.renewBefore }} + subject: +{{ include "application.tplvalues.render" ( dict "value" .Values.certificate.subject "context" $ ) | indent 4 }} + commonName: {{ include "application.tplvalues.render" ( dict "value" .Values.certificate.commonName "context" $ ) }} + {{- if .Values.certificate.isCA }} + isCA: {{ .Values.certificate.isCA }} +{{- end }} + usages: +{{ toYaml .Values.certificate.usages | indent 4 }} + # At least one of a DNS Name, URI, or IP address is required. + dnsNames: +{{ include "application.tplvalues.render" ( dict "value" .Values.certificate.dnsNames "context" $ ) | indent 4 }} +{{- if .Values.certificate.ipAddresses }} + ipAddresses: +{{ toYaml .Values.certificate.ipAddresses | indent 4 }} +{{- end }} +{{- if .Values.certificate.uriSANs }} + uris: +{{ toYaml .Values.certificate.uriSANs | indent 4 }} +{{- end }} +{{- if .Values.certificate.emailSANs }} + emailAddresses: +{{ toYaml .Values.certificate.emailSANs | indent 4 }} +{{- end }} +{{- if .Values.certificate.privateKey.enabled }} + privateKey: + algorithm: {{ .Values.certificate.keyAlgorithm }} + encoding: {{ .Values.certificate.keyEncoding }} + size: {{ .Values.certificate.keySize }} + rotationPolicy: {{ .Values.certificate.privateKey.rotationPolicy }} +{{- end }} + issuerRef: + name: {{ .Values.certificate.issuerRef.name }} + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: {{ .Values.certificate.issuerRef.kind }} +{{- if .Values.certificate.issuerRef.group }} + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: {{ .Values.certificate.issuerRef.group }} +{{- end }} +{{- if .Values.certificate.keystores.enabled }} + keystores: +{{- if .Values.certificate.keystores.jks.create }} + jks: + create: {{ .Values.certificate.keystores.jks.create }} + passwordSecretRef: + key: {{ .Values.certificate.keystores.jks.key }} + name: {{ .Values.certificate.keystores.jks.name }} +{{- end }} +{{- if .Values.certificate.keystores.pkcs12.create }} + pkcs12: + create: {{ .Values.certificate.keystores.pkcs12.create }} + passwordSecretRef: + key: {{ .Values.certificate.keystores.pkcs12.key }} + name: {{ include "application.tplvalues.render" ( dict "value" .Values.certificate.keystores.pkcs12.name "context" $ ) }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/configmap.yaml b/templates/configmap.yaml new file mode 100644 index 0000000..ff1cb3e --- /dev/null +++ b/templates/configmap.yaml @@ -0,0 +1,21 @@ +{{- if (.Values.configMap).enabled }} +{{- range $nameSuffix, $data := .Values.configMap.files }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "application.name" $ }}-{{ $nameSuffix }} + namespace: {{ template "application.namespace" $ }} + labels: + {{- include "application.labels" $ | nindent 4 }} +{{- if $.Values.configMap.additionalLabels }} +{{ toYaml $.Values.configMap.additionalLabels | indent 4 }} +{{- end }} +{{- if $.Values.configMap.annotations }} + annotations: +{{ toYaml $.Values.configMap.annotations | indent 4 }} +{{- end }} +data: +{{ include "application.tplvalues.render" ( dict "value" $data "context" $ ) | indent 2 }} +--- +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/cronjob.yaml b/templates/cronjob.yaml new file mode 100644 index 0000000..a2352a8 --- /dev/null +++ b/templates/cronjob.yaml @@ -0,0 +1,107 @@ +{{- if (.Values.cronJob).enabled }} +{{- range $name, $job := .Values.cronJob.jobs }} +{{ if $.Capabilities.APIVersions.Has "batch/v1/CronJob" -}} +apiVersion: batch/v1 +{{- else -}} +apiVersion: batch/v1beta1 +{{- end }} +kind: CronJob +metadata: + labels: + {{- include "application.labels" $ | nindent 4 }} +{{- if $job.additionalLabels }} +{{ $job.additionalLabels | indent 4 }} +{{- end }} +{{- if $job.annotations }} + annotations: +{{ $job.annotations | indent 4 }} +{{- end }} + name: {{ $name }} + namespace: {{ template "application.namespace" $ }} +spec: + schedule: {{ $job.schedule | quote }} +{{- if $job.successfulJobsHistoryLimit }} + successfulJobsHistoryLimit: {{ $job.successfulJobsHistoryLimit }} +{{ end }} +{{- if $job.concurrencyPolicy }} + concurrencyPolicy: {{ $job.concurrencyPolicy }} +{{ end }} +{{- if $job.failedJobsHistoryLimit }} + failedJobsHistoryLimit: {{ $job.failedJobsHistoryLimit }} +{{ end }} + jobTemplate: + spec: + template: + metadata: + labels: + {{- include "application.labels" $ | nindent 12 }} + spec: + {{- if $.Values.rbac.serviceAccount.name }} + serviceAccountName: {{ $.Values.rbac.serviceAccount.name }} + {{- else }} + serviceAccountName: {{ template "application.name" $ }} + {{- end }} + containers: + - name: {{ $name }} + + {{- $image := required (print "Undefined image repo for container '" $name "'") $job.image.repository }} + {{- with $job.image.tag }} {{- $image = print $image ":" . }} {{- end }} + {{- with $job.image.digest }} {{- $image = print $image "@" . }} {{- end }} + image: {{ $image }} + + {{- if $job.image.imagePullPolicy }} + imagePullPolicy: {{ $job.image.imagePullPolicy }} + {{ end }} + {{- with $job.env }} + env: + {{- range $key, $value := $job.env }} + - name: {{ include "application.tplvalues.render" ( dict "value" $key "context" $ ) }} +{{ include "application.tplvalues.render" ( dict "value" $value "context" $ ) | indent 14 }} + {{- end }} + {{- end }} + {{- with $job.envFrom }} + envFrom: +{{ toYaml . | indent 12 }} + {{- end }} + {{- if $job.command }} + command: {{ $job.command }} + {{- end }} + {{- with $job.args }} + args: +{{ toYaml . | indent 12 }} + {{- end }} + {{- with $job.resources }} + resources: +{{ toYaml . | indent 14 }} + {{- end }} + {{- with $job.volumeMounts }} + volumeMounts: +{{ toYaml . | indent 12 }} + {{- end }} + {{- with $job.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 12 }} + {{- end }} + {{- with $job.affinity }} + affinity: +{{ toYaml . | indent 12 }} + {{- end }} + {{- with $job.tolerations }} + tolerations: +{{ toYaml . | indent 12 }} + {{- end }} + {{- if $job.restartPolicy}} + restartPolicy: {{ $job.restartPolicy }} + {{ else }} + restartPolicy: OnFailure + {{ end }} + {{- with $job.imagePullSecrets}} + imagePullSecrets: +{{ toYaml . | indent 12 }} + {{ end }} + {{- with $job.volumes }} + volumes: +{{ toYaml . | indent 12 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/templates/deployment.yaml b/templates/deployment.yaml old mode 100755 new mode 100644 index a8027ba..8e03b7d --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -1,128 +1,301 @@ +{{- if .Values.deployment.enabled }} apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "helm-template.name" . }} - namespace: {{ include "helm-template.namespace" $ }} - + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.deployment.additionalLabels }} +{{ toYaml .Values.deployment.additionalLabels | indent 4 }} +{{- end }} +{{- if or .Values.deployment.annotations .Values.deployment.reloadOnChange }} + annotations: +{{- end }} +{{- if .Values.deployment.annotations }} +{{ toYaml .Values.deployment.annotations | indent 4 }} +{{- end }} +{{- if .Values.deployment.reloadOnChange }} + reloader.stakater.com/auto: "true" +{{- end }} + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} spec: - {{- if not .Values.autoscaling.enabled }} - replicas: {{ .Values.replicaCount }} - {{- end }} - selector: +{{- if .Values.deployment.replicas }} + replicas: {{ .Values.deployment.replicas }} +{{- end }} + selector: matchLabels: - {{- include "helm-template.selectorLabels" . | nindent 6 }} - - strategy: - rollingUpdate: - maxSurge: 1 - maxUnavailable: 0 - type: RollingUpdate +{{ include "application.selectorLabels" . | indent 6 }} + {{- if .Values.deployment.strategy }} + strategy: +{{ toYaml .Values.deployment.strategy | indent 4 }} + {{- end }} + {{- if not (kindIs "invalid" .Values.deployment.revisionHistoryLimit) }} + revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }} + {{- end }} template: metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} labels: - {{- include "helm-template.labels" . | nindent 8 }} +{{ include "application.selectorLabels" . | indent 8 }} +{{- if .Values.deployment.podLabels }} +{{ toYaml .Values.deployment.podLabels | indent 8 }} +{{- end }} +{{- if or .Values.deployment.additionalPodAnnotations .Values.deployment.fluentdConfigAnnotations }} + annotations: +{{- end }} +{{- with .Values.deployment.additionalPodAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- if .Values.deployment.fluentdConfigAnnotations }} + fluentdConfiguration: > + [ + { + "containers": + [ + { + "expressionFirstLine": "{{ .Values.deployment.fluentdConfigAnnotations.regexFirstLine }}", + "expression": "{{ .Values.deployment.fluentdConfigAnnotations.regex }}", + "timeFormat": "{{ .Values.deployment.fluentdConfigAnnotations.timeFormat }}", + "containerName": "{{ template "application.name" . }}" + } + ]{{- with .Values.deployment.fluentdConfigAnnotations.notifications }}, + "notifications": { + {{- with .slack }} + "slack": { + "webhookURL": "{{ .webhookURL }}", + "channelName": "{{ .channelName }}" + }, + {{- end }} + "key": "{{ .key }}", + "pattern": "{{ .pattern }}" + } + {{- end }} + } + ] +{{- end }} spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} + {{- if .Values.deployment.hostAliases }} + hostAliases: +{{ toYaml .Values.deployment.hostAliases | indent 6 }} {{- end }} - restartPolicy: "{{- toYaml .Values.restartPolicy }}" - {{- if .Values.Affinity }} - affinity: - {{- include "helm-template.affinity" . | nindent 8 -}} + {{- if .Values.deployment.initContainers }} + initContainers: + {{- range $key, $value := .Values.deployment.initContainers }} + - name: {{ $key }} +{{ include "application.tplvalues.render" ( dict "value" $value "context" $ ) | indent 8 }} {{- end }} - serviceAccountName: {{ include "helm-template.serviceAccountName" . }} - {{- if .Values.podSecurityContext }} - securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} {{- end }} -{{- range $container := .Values.containers }} - containers: - - name: {{ $container.image }} - {{- if $container.securityContext -}} - securityContext: - {{- toYaml $container.securityContext | nindent 10 }} + {{- if .Values.deployment.nodeSelector }} + nodeSelector: +{{ toYaml .Values.deployment.nodeSelector | indent 8 }} {{- end }} - image: "{{ $container.repository }}/{{ $container.image }}:{{ $container.tag | default "latest" }}" - {{- with $container.args }} - args: - {{- toYaml . |nindent 8 }} + {{- if .Values.deployment.tolerations }} + tolerations: +{{ toYaml .Values.deployment.tolerations | indent 8 -}} {{- end }} - - command: - {{- dig "command" "- /bin/sh" $container | toYaml | nindent 8 }} - workingDir: {{ $container.workingDir | default "/opt" }} - imagePullPolicy: {{ $container.pullPolicy | default "IfNotPresent" }} + {{- if .Values.deployment.affinity }} + affinity: +{{ toYaml .Values.deployment.affinity | indent 8 -}} + {{- end }} + {{- with .Values.deployment.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.deployment.imagePullSecrets }} + imagePullSecrets: + - name: {{ .Values.deployment.imagePullSecrets }} + {{- end }} + containers: + {{- if .Values.deployment.openshiftOAuthProxy.enabled }} + - args: + {{- if .Values.deployment.openshiftOAuthProxy.disableTLSArg }} + - --http-address=:8081 + {{- else }} + - --https-address=:8443 + {{- end }} + - --provider=openshift + - --upstream=http://localhost:{{ .Values.deployment.openshiftOAuthProxy.port }} + - --openshift-service-account={{ template "application.name" . }} + - --tls-cert=/etc/tls/private/tls.crt + - --tls-key=/etc/tls/private/tls.key + - --cookie-secret=SECRET + image: {{ .Values.deployment.openshiftOAuthProxy.image | default "openshift/oauth-proxy:latest" }} + imagePullPolicy: IfNotPresent + name: oauth-proxy ports: - {{- range $port := $container.ports }} - - name: {{ toYaml $port.name | default "http" }} - containerPort: {{ toYaml $port.port | default "8080" }} - protocol: TCP + {{- if .Values.deployment.openshiftOAuthProxy.disableTLSArg }} + - containerPort: 8081 + {{- else }} + - containerPort: 8443 {{- end }} - {{- if $container.healthcheck -}} - {{- toYaml $container.healthcheck | nindent 8 }} + name: proxy + volumeMounts: + - mountPath: /etc/tls/private + name: proxy-tls {{- end }} - resources: - limits: - memory: {{ dig "resources" "limits" "memory" "100Mi" $container | quote }} - cpu: {{ dig "resources" "limits" "cpu" "1" $container | quote }} - requests: - cpu: {{ dig "resources" "requests" "cpu" "1" $container | quote }} - memory: {{ dig "resources" "requests" "memory" "200Mi" $container | quote }} - {{- if $container.envFrom }} - envFrom: + - name: {{ template "application.name" . }} + + {{- $image := required "Undefined image for application container" .Values.deployment.image.repository }} + {{- with .Values.deployment.image.tag }} {{- $image = print $image ":" . }} {{- end }} + {{- with .Values.deployment.image.digest }} {{- $image = print $image "@" . }} {{- end }} + image: {{ $image }} + + imagePullPolicy: {{ .Values.deployment.image.pullPolicy }} + {{- if .Values.deployment.command }} + command: {{- include "application.tplvalues.render" (dict "value" .Values.deployment.command "context" $) | nindent 12 }} {{- end }} - {{- range $envFrom := $container.envFrom }} + {{- if .Values.deployment.args }} + args: {{- include "application.tplvalues.render" (dict "value" .Values.deployment.args "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.deployment.ports }} + ports: +{{ toYaml .Values.deployment.ports | indent 10 }} + {{- end }} + {{- if .Values.deployment.envFrom }} + envFrom: + {{- range $value := .Values.deployment.envFrom }} + {{- if (eq .type "configmap") }} - configMapRef: - name: {{ toYaml $envFrom.ConfigMapName }} + {{- if .name }} + name: {{ include "application.tplvalues.render" ( dict "value" $value.name "context" $ ) }} + {{- else if .nameSuffix }} + name: {{ template "application.name" $ }}-{{ include "application.tplvalues.render" ( dict "value" $value.nameSuffix "context" $ ) }} + {{- else }} + name: {{ template "application.name" $ }} + {{- end }} + {{- end }} + {{- if (eq .type "secret") }} + - secretRef: + {{- if .name }} + name: {{ include "application.tplvalues.render" ( dict "value" $value.name "context" $ ) }} + {{- else if .nameSuffix }} + name: {{ template "application.name" $ }}-{{ include "application.tplvalues.render" ( dict "value" $value.nameSuffix "context" $ ) }} + {{- else }} + name: {{ template "application.name" $ }} + {{- end }} + {{- end }} {{- end }} + {{- end }} + {{- if .Values.deployment.env }} env: - {{- range $configkey := $container.env.configMapKeyRef }} - - name: {{ toYaml $configkey.key | replace "." "_" | upper }} - valueFrom: - configMapKeyRef: - key: {{ toYaml $configkey.key }} - name: {{ toYaml $configkey.ConfigMapName }} - {{- end }} - {{- include "helm-template.envsecrets" $ | nindent 8 }} - - name: MY_POD_NAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.name - - name: MY_POD_IP - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: status.podIP - {{- range $key, $val := $container.env }} - {{- if ne $key "configMapKeyRef" }} - - name: {{ toYaml $key }} - value: {{ toYaml $val }} - {{- end }} - {{- end }} - {{- if $.Values.volumes }} + {{- range $key, $value := .Values.deployment.env }} + - name: {{ include "application.tplvalues.render" ( dict "value" $key "context" $ ) }} +{{ include "application.tplvalues.render" ( dict "value" $value "context" $ ) | indent 10 }} + {{- end }} + {{- end }} + {{- if .Values.deployment.startupProbe.enabled }} + startupProbe: + failureThreshold: {{ .Values.deployment.startupProbe.failureThreshold }} + periodSeconds: {{ .Values.deployment.startupProbe.periodSeconds }} + successThreshold: {{ .Values.deployment.startupProbe.successThreshold }} + timeoutSeconds: {{ .Values.deployment.startupProbe.timeoutSeconds }} + initialDelaySeconds: {{ .Values.deployment.startupProbe.initialDelaySeconds }} + {{- if .Values.deployment.startupProbe.exec }} + exec: + {{- toYaml .Values.deployment.startupProbe.exec | nindent 12 }} + {{- else if .Values.deployment.startupProbe.httpGet }} + httpGet: + {{- toYaml .Values.deployment.startupProbe.httpGet | nindent 12 }} + {{- else if .Values.deployment.startupProbe.tcpSocket }} + tcpSocket: + {{- toYaml .Values.deployment.startupProbe.tcpSocket | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.deployment.livenessProbe.enabled }} + livenessProbe: + failureThreshold: {{ .Values.deployment.livenessProbe.failureThreshold }} + periodSeconds: {{ .Values.deployment.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.deployment.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.deployment.livenessProbe.timeoutSeconds }} + initialDelaySeconds: {{ .Values.deployment.livenessProbe.initialDelaySeconds }} + {{- if .Values.deployment.livenessProbe.exec }} + exec: + {{- toYaml .Values.deployment.livenessProbe.exec | nindent 12 }} + {{- else if .Values.deployment.livenessProbe.httpGet }} + httpGet: + {{- toYaml .Values.deployment.livenessProbe.httpGet | nindent 12 }} + {{- else if .Values.deployment.livenessProbe.tcpSocket }} + tcpSocket: + {{- toYaml .Values.deployment.livenessProbe.tcpSocket | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.deployment.readinessProbe.enabled }} + readinessProbe: + failureThreshold: {{ .Values.deployment.readinessProbe.failureThreshold }} + periodSeconds: {{ .Values.deployment.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.deployment.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.deployment.readinessProbe.timeoutSeconds }} + initialDelaySeconds: {{ .Values.deployment.readinessProbe.initialDelaySeconds }} + {{- if .Values.deployment.readinessProbe.exec }} + exec: + {{- toYaml .Values.deployment.readinessProbe.exec | nindent 12 }} + {{- else if .Values.deployment.readinessProbe.httpGet }} + httpGet: + {{- toYaml .Values.deployment.readinessProbe.httpGet | nindent 12 }} + {{- else if .Values.deployment.readinessProbe.tcpSocket }} + tcpSocket: + {{- toYaml .Values.deployment.readinessProbe.tcpSocket | nindent 12 }} + {{- end }} + {{- end }} + {{- if or (.Values.deployment.volumeMounts) (and (eq .Values.persistence.enabled true) (eq .Values.persistence.mountPVC true) )}} volumeMounts: + {{- if (eq .Values.persistence.mountPVC true) }} + - mountPath: {{ .Values.persistence.mountPath }} + name: {{ template "application.name" . }}-data {{- end }} - {{- range $vol := $.Values.volumes }} - - mountPath: {{ $container.workingDir | default "/opt" | trimSuffix "/" }}/{{ $vol.name }} - name: {{ $vol.name }} + {{- if .Values.deployment.volumeMounts }} + {{- range $key, $value := .Values.deployment.volumeMounts }} + - name: {{ $key }} +{{ include "application.tplvalues.render" ( dict "value" $value "context" $ ) | indent 10 }} {{- end }} -{{- end }} - {{- with .Values.volumes }} + {{- end }} + {{- end }} + {{- with .Values.deployment.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if .Values.deployment.containerSecurityContext }} + securityContext: +{{ toYaml .Values.deployment.containerSecurityContext | indent 10 }} + {{- end }} + {{- if .Values.deployment.additionalContainers }} +{{ toYaml .Values.deployment.additionalContainers | indent 6 }} + {{- end }} + {{- if .Values.deployment.securityContext }} + securityContext: +{{ toYaml .Values.deployment.securityContext | indent 8 }} + {{- end }} + {{- if .Values.deployment.dnsConfig }} + dnsConfig: +{{ toYaml .Values.deployment.dnsConfig | indent 8 }} + {{- end }} + {{- if or (.Values.deployment.openshiftOAuthProxy.enabled) (.Values.deployment.volumes) (and (eq .Values.persistence.enabled true) (eq .Values.persistence.mountPVC true) )}} volumes: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} + {{- if .Values.deployment.openshiftOAuthProxy.enabled }} + - name: proxy-tls + secret: + secretName: {{ .Values.deployment.openshiftOAuthProxy.secretName }} + {{- end }} + {{- if (eq .Values.persistence.mountPVC true) }} + - name: {{ template "application.name" . }}-data + persistentVolumeClaim: + {{- if .Values.persistence.name }} + claimName: {{ .Values.persistence.name }} + {{- else }} + claimName: {{ template "application.name" . }}-data + {{- end }} + {{- end }} + {{- if .Values.deployment.volumes }} + {{- range $key, $value := .Values.deployment.volumes }} + - name: {{ $key }} +{{ include "application.tplvalues.render" ( dict "value" $value "context" $ ) | indent 8 }} + {{- end }} + {{- end }} {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} + {{- if .Values.rbac.serviceAccount.enabled }} + {{- if .Values.rbac.serviceAccount.name }} + serviceAccountName: {{ .Values.rbac.serviceAccount.name }} + {{- else }} + serviceAccountName: {{ template "application.name" $ }} {{- end }} - + {{- end }} +{{- end }} diff --git a/templates/endpointmonitor.yaml b/templates/endpointmonitor.yaml new file mode 100644 index 0000000..1e7c92f --- /dev/null +++ b/templates/endpointmonitor.yaml @@ -0,0 +1,30 @@ +{{- if and (.Values.endpointMonitor).enabled (.Capabilities.APIVersions.Has "endpointmonitor.stakater.com/v1alpha1") (or (and .Values.route .Values.route.enabled) (and .Values.ingress .Values.ingress.enabled))}} +apiVersion: endpointmonitor.stakater.com/v1alpha1 +kind: EndpointMonitor +metadata: + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.endpointMonitor.additionalLabels }} +{{ toYaml .Values.endpointMonitor.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.endpointMonitor.annotations }} + annotations: +{{ toYaml .Values.endpointMonitor.annotations | indent 4 }} +{{- end }} +spec: + forceHttps: true + urlFrom: +{{- if and .Values.route .Values.route.enabled }} + routeRef: + name: {{ template "application.name" . }} +{{- end }} +{{- if and .Values.ingress .Values.ingress.enabled }} + ingressRef: + name: {{ template "application.name" . }} +{{- end }} +{{- if .Values.endpointMonitor.additionalConfig }} +{{ toYaml .Values.endpointMonitor.additionalConfig | indent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/externalsecrets.yaml b/templates/externalsecrets.yaml new file mode 100644 index 0000000..d6c369e --- /dev/null +++ b/templates/externalsecrets.yaml @@ -0,0 +1,53 @@ +{{- if and (.Values.externalSecret).enabled (.Capabilities.APIVersions.Has "external-secrets.io/v1beta1") }} +{{- range $nameSuffix, $data := .Values.externalSecret.files }} +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: {{ template "application.name" $ }}-{{ $nameSuffix }} + namespace: {{ include "application.namespace" $ }} + labels: + {{- include "application.labels" $ | nindent 4 }} +spec: + refreshInterval: {{ $.Values.externalSecret.refreshInterval }} +{{- if and (not $data.data) (not $data.dataFrom) }} +{{- fail "Data or datafrom not specified for secret {{ template 'application.name' $ }}-{{ $nameSuffix }} " }} +{{- end }} +{{- if $data.data }} + data: +{{- range $secretKey, $remoteRef := $data.data}} + - secretKey: {{ $secretKey }} +{{ toYaml $remoteRef | indent 6}} +{{- end }} +{{- end }} +{{- if $data.dataFrom }} + dataFrom: + - extract: +{{ toYaml $data.dataFrom | indent 6 }} +{{- end }} + {{- if $data.secretStore }} + secretStoreRef: + name: {{ $data.secretStore.name }} + kind: {{ $data.secretStore.kind | default "SecretStore" }} + {{- else }} + secretStoreRef: + name: {{ $.Values.externalSecret.secretStore.name }} + kind: {{ $.Values.externalSecret.secretStore.kind | default "SecretStore" }} + {{- end}} + target: + name: {{ template "application.name" $ }}-{{ $nameSuffix }} + template: + type: {{ $data.type | default "Opaque" }} +{{- if or $data.annotations $data.labels}} + metadata: +{{- if $data.annotations }} + annotations: +{{ toYaml $data.annotations | indent 10 }} +{{- end }} +{{- if $data.labels }} + labels: +{{ toYaml $data.labels | indent 10 }} +{{- end }} +{{- end }} +--- +{{- end}} +{{- end}} \ No newline at end of file diff --git a/templates/forecastle.yaml b/templates/forecastle.yaml new file mode 100644 index 0000000..3ac748d --- /dev/null +++ b/templates/forecastle.yaml @@ -0,0 +1,29 @@ +{{- if and (.Values.forecastle).enabled (.Capabilities.APIVersions.Has "forecastle.stakater.com/v1alpha1") (or .Values.ingress.enabled .Values.route.enabled) }} +apiVersion: forecastle.stakater.com/v1alpha1 +kind: ForecastleApp +metadata: + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.forecastle.additionalLabels }} +{{ toYaml .Values.forecastle.additionalLabels | indent 4 }} +{{- end }} +spec: + name: {{ .Values.forecastle.displayName }} + group: {{ default .Release.Namespace .Values.forecastle.group }} + icon: {{ .Values.forecastle.icon }} + urlFrom: + {{- if .Values.ingress.enabled }} + ingressRef: + name: {{ template "application.name" . }} + {{- else }} + routeRef: + name: {{ template "application.name" . }} + {{- end }} + networkRestricted: {{ .Values.forecastle.networkRestricted }} + {{- if .Values.forecastle.properties }} + properties: +{{ toYaml .Values.forecastle.properties | indent 4 }} + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/templates/grafanadashboard.yaml b/templates/grafanadashboard.yaml new file mode 100644 index 0000000..eec15dc --- /dev/null +++ b/templates/grafanadashboard.yaml @@ -0,0 +1,29 @@ +{{- if and (.Values.grafanaDashboard).enabled (.Capabilities.APIVersions.Has "integreatly.org/v1alpha1") -}} +{{- range $name, $content := .Values.grafanaDashboard.contents }} +apiVersion: integreatly.org/v1alpha1 +kind: GrafanaDashboard +metadata: + name: {{ $name }} + namespace: {{ template "application.namespace" $ }} + labels: + # this label is used as dashboard selector by grafana operator + grafanaDashboard: grafana-operator + {{- include "application.labels" $ | nindent 4 }} +{{- if $.Values.grafanaDashboard.additionalLabels }} +{{ toYaml $.Values.grafanaDashboard.additionalLabels | indent 4 }} +{{- end }} +{{- if $.Values.grafanaDashboard.annotations }} + annotations: +{{ toYaml $.Values.grafanaDashboard.annotations | indent 4 }} +{{- end }} +spec: + {{- if $content.json }} + json: + {{ $content.json | toJson }} + {{- end }} + {{- if $content.url }} + url: {{ $content.url }} + {{- end }} +--- +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/hpa.yaml b/templates/hpa.yaml old mode 100755 new mode 100644 index ae24d86..7e4c946 --- a/templates/hpa.yaml +++ b/templates/hpa.yaml @@ -1,28 +1,31 @@ -{{- if .Values.autoscaling.enabled }} -apiVersion: autoscaling/v2beta1 +{{- if and .Values.autoscaling.enabled .Values.deployment.enabled }} + +{{- if .Capabilities.APIVersions.Has "autoscaling/v2/HorizontalPodAutoscaler" }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta2 +{{- end }} + kind: HorizontalPodAutoscaler metadata: - name: {{ include "helm-template.name" . }} + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} labels: - {{- include "helm-template.labels" . | nindent 4 }} + {{- include "application.labels" . | nindent 4 }} + {{- with .Values.autoscaling.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.autoscaling.annotations }} + annotations: + {{- toYaml .Values.autoscaling.annotations | nindent 4 }} + {{- end }} spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment - name: {{ include "helm-template.name" . }} + name: {{ template "application.name" . }} minReplicas: {{ .Values.autoscaling.minReplicas }} maxReplicas: {{ .Values.autoscaling.maxReplicas }} metrics: - {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} - - type: Resource - resource: - name: cpu - targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} - {{- end }} - {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} - {{- end }} + {{- toYaml .Values.autoscaling.metrics | nindent 4 }} {{- end }} diff --git a/templates/ingress.yaml b/templates/ingress.yaml old mode 100755 new mode 100644 index 90a4b33..760439f --- a/templates/ingress.yaml +++ b/templates/ingress.yaml @@ -1,61 +1,46 @@ -{{- if .Values.ingress.enabled -}} -{{- $fullName := include "helm-template.fullname" . -}} -{{- $svcPort := .Values.service.port -}} -{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} - {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} - {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} - {{- end }} -{{- end }} -{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +{{- if (.Values.ingress).enabled -}} +{{- $servicePort := .Values.ingress.servicePort -}} +{{- $pathType := .Values.ingress.pathType -}} +{{- $applicationNameTpl := include "application.name" . -}} apiVersion: networking.k8s.io/v1 -{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1beta1 -{{- else -}} -apiVersion: extensions/v1beta1 -{{- end }} kind: Ingress metadata: - name: {{ $fullName }} + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} labels: - {{- include "helm-template.labels" . | nindent 4 }} - {{- with .Values.ingress.annotations }} + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.ingress.additionalLabels }} +{{ toYaml .Values.ingress.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.ingress.annotations }} annotations: - {{- toYaml . | nindent 4 }} - {{- end }} +{{ toYaml .Values.ingress.annotations | indent 4 }} +{{- end }} spec: - {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} - ingressClassName: {{ .Values.ingress.className }} - {{- end }} - {{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} - {{- end }} +{{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} +{{- end}} rules: {{- range .Values.ingress.hosts }} - - host: {{ .host | quote }} + - host: {{ tpl .host $ }} http: paths: - {{- range .paths }} - - path: {{ .path }} - {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} - pathType: {{ .pathType }} - {{- end }} - backend: - {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} - service: - name: {{ $fullName }} - port: - number: {{ $svcPort }} - {{- else }} - serviceName: {{ $fullName }} - servicePort: {{ $svcPort }} - {{- end }} - {{- end }} - {{- end }} -{{- end }} + {{- if .paths }} + {{- range .paths }} + - path: {{ .path }} + pathType: {{ default "ImplementationSpecific" (.pathType) }} + backend: + service: + name: {{ default $applicationNameTpl (.serviceName) }} + port: + name: {{ default "http" (.servicePort) }} + {{- end }} + {{- else }} + {{ fail "Specify paths for ingress host, check values.yaml" }} + {{- end }} + {{- end -}} + {{- if .Values.ingress.tls }} + tls: +{{ include "application.tplvalues.render" (dict "value" .Values.ingress.tls "context" $) | indent 3 }} + {{- end -}} +{{- end -}} diff --git a/templates/networkpolicy.yaml b/templates/networkpolicy.yaml new file mode 100644 index 0000000..bb3f537 --- /dev/null +++ b/templates/networkpolicy.yaml @@ -0,0 +1,40 @@ +{{- if (.Values.networkPolicy).enabled }} +apiVersion: "networking.k8s.io/v1" +kind: NetworkPolicy +metadata: + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.networkPolicy.additionalLabels }} +{{ toYaml .Values.networkPolicy.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.networkPolicy.annotations }} + annotations: +{{ toYaml .Values.networkPolicy.annotations | indent 4 }} +{{- end }} +spec: + podSelector: + matchLabels: +{{ include "application.selectorLabels" . | indent 6 }} +{{- if .Values.deployment.podLabels }} +{{ toYaml .Values.deployment.podLabels | indent 6 }} +{{- end }} +{{- if or .Values.networkPolicy.ingress .Values.networkPolicy.egress }} + policyTypes: +{{- if .Values.networkPolicy.ingress }} + - Ingress +{{- end }} +{{- if .Values.networkPolicy.egress }} + - Egress +{{- end }} +{{- end }} +{{- if .Values.networkPolicy.egress }} + egress: +{{ toYaml .Values.networkPolicy.egress | indent 4 }} +{{- end }} +{{- if .Values.networkPolicy.ingress }} + ingress: +{{ toYaml .Values.networkPolicy.ingress | indent 4 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/pdb.yaml b/templates/pdb.yaml new file mode 100644 index 0000000..50a4d24 --- /dev/null +++ b/templates/pdb.yaml @@ -0,0 +1,24 @@ +{{- if or .Values.pdb.minAvailable .Values.pdb.maxUnavailable | and .Values.pdb.enabled }} + +{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} + +kind: PodDisruptionBudget +metadata: + labels: + {{- include "application.labels" . | nindent 4 }} + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} +spec: + {{- if .Values.pdb.minAvailable }} + minAvailable: {{ .Values.pdb.minAvailable }} + {{- else }} + maxUnavailable: {{ .Values.pdb.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "application.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/templates/prometheusrule.yaml b/templates/prometheusrule.yaml new file mode 100644 index 0000000..9d25782 --- /dev/null +++ b/templates/prometheusrule.yaml @@ -0,0 +1,15 @@ +{{- if and (.Values.prometheusRule).enabled (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") -}} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.prometheusRule.additionalLabels }} +{{ toYaml .Values.prometheusRule.additionalLabels | indent 4 }} +{{- end }} +spec: + groups: +{{ toYaml .Values.prometheusRule.groups | indent 4 }} +{{- end -}} \ No newline at end of file diff --git a/templates/pvc.yaml b/templates/pvc.yaml new file mode 100644 index 0000000..2db1ebf --- /dev/null +++ b/templates/pvc.yaml @@ -0,0 +1,39 @@ +{{- if and (.Values.persistence).enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: +{{- if .Values.persistence.name }} + name: "{{ .Values.persistence.name }}" +{{- else }} + name: {{ template "application.name" . }}-data +{{- end }} + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.persistence.additionalLabels }} +{{ toYaml .Values.persistence.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.persistence.annotations }} + annotations: +{{ toYaml .Values.persistence.annotations | indent 4 }} +{{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.storageSize | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- if .Values.persistence.volumeMode }} + volumeMode: "{{ .Values.persistence.volumeMode }}" +{{- end }} +{{- if .Values.persistence.volumeName }} + volumeName: "{{ .Values.persistence.volumeName }}" +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/role.yaml b/templates/role.yaml new file mode 100644 index 0000000..f531e38 --- /dev/null +++ b/templates/role.yaml @@ -0,0 +1,21 @@ +{{- if and (.Values.rbac).enabled .Values.rbac.roles }} +{{- range .Values.rbac.roles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "application.name" $ }}-role-{{ .name }} + namespace: {{ template "application.namespace" $ }} + labels: + {{- include "application.labels" $ | nindent 4 }} +{{- if $.Values.rbac.additionalLabels }} +{{ toYaml $.Values.rbac.additionalLabels | indent 4 }} +{{- end }} +{{- if $.Values.rbac.annotations }} + annotations: +{{ toYaml $.Values.rbac.annotations | indent 4 }} +{{- end }} +rules: +{{ toYaml .rules | indent 2 }} +--- +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/rolebinding.yaml b/templates/rolebinding.yaml new file mode 100644 index 0000000..e247d51 --- /dev/null +++ b/templates/rolebinding.yaml @@ -0,0 +1,31 @@ +{{- if and (.Values.rbac).enabled .Values.rbac.roles }} +{{- range .Values.rbac.roles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "application.name" $ }}-rolebinding-{{ .name }} + namespace: {{ template "application.namespace" $ }} + labels: + {{- include "application.labels" $ | nindent 4 }} +{{- if $.Values.rbac.additionalLabels }} +{{ toYaml $.Values.rbac.additionalLabels | indent 4 }} +{{- end }} +{{- if $.Values.rbac.annotations }} + annotations: +{{ toYaml $.Values.rbac.annotations | indent 4 }} +{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "application.name" $ }}-role-{{ .name }} +subjects: + - kind: ServiceAccount + {{- if $.Values.rbac.serviceAccount.name }} + name: {{ $.Values.rbac.serviceAccount.name }} + {{- else }} + name: {{ template "application.name" $ }} + {{- end }} + namespace: {{ $.Release.Namespace }} +--- +{{- end }} +{{- end }} diff --git a/templates/route.yaml b/templates/route.yaml new file mode 100644 index 0000000..123efd8 --- /dev/null +++ b/templates/route.yaml @@ -0,0 +1,47 @@ +{{- if and (.Values.route).enabled (.Capabilities.APIVersions.Has "route.openshift.io/v1") -}} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.route.additionalLabels }} +{{ toYaml .Values.route.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.route.annotations }} + annotations: +{{ toYaml .Values.route.annotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.route.host }} + host: {{ .Values.route.host }} +{{- end }} +{{- if .Values.route.path }} + path: {{ .Values.route.path }} +{{- end }} + port: + {{- if .Values.deployment.openshiftOAuthProxy.enabled }} + targetPort: proxy + {{- else }} +{{ toYaml .Values.route.port | indent 4 }} + {{- end }} + to: + kind: Service + name: {{ template "application.name" . }} + {{- if .Values.route.to }} + weight: {{ .Values.route.to.weight }} + {{- else }} + weight: 100 + {{- end }} + wildcardPolicy: {{ .Values.route.wildcardPolicy }} + tls: + termination: {{ .Values.route.tls.termination }} + insecureEdgeTerminationPolicy: {{ .Values.route.tls.insecureEdgeTerminationPolicy }} + {{- if .Values.route.alternateBackends }} + alternateBackends: + - kind: {{ .Values.route.alternateBackends.kind }} + name: {{ .Values.route.alternateBackends.name }} + weight: {{ .Values.route.alternateBackends.weight }} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/templates/sealedsecrets.yaml b/templates/sealedsecrets.yaml new file mode 100644 index 0000000..002d1cb --- /dev/null +++ b/templates/sealedsecrets.yaml @@ -0,0 +1,61 @@ +{{- if and (.Values.sealedSecret) (.Capabilities.APIVersions.Has "bitnami.com/v1alpha1") }} +{{- range $nameSuffix, $config := .Values.sealedSecret.files }} +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + name: {{ template "application.name" $ }}-{{ $nameSuffix }} + namespace: {{ template "application.namespace" $ }} + labels: + {{- include "application.labels" $ | nindent 4 }} +{{- if $.Values.sealedSecret.additionalLabels }} +{{ toYaml $.Values.sealedSecret.additionalLabels | indent 4 }} +{{- end }} +{{- if $config.labels }} +{{ toYaml $config.labels | indent 4 }} +{{- end }} +{{- if or ($.Values.sealedSecret.annotations) ($config.annotations) ($config.clusterWide) }} + annotations: +{{- if $config.annotations }} +{{ toYaml $config.annotations | indent 4 }} +{{- end }} +{{- if $.Values.sealedSecret.annotations }} +{{ toYaml $.Values.sealedSecret.annotations | indent 4 }} +{{- end }} +{{- if $config.clusterWide}} + sealedsecrets.bitnami.com/cluster-wide: "true" +{{- end}} +{{- end }} +spec: + encryptedData: +{{- range $key, $value := $config.encryptedData }} + {{ $key }}: {{ $value }} + {{- end }} + template: + type: {{ $config.type | default "Opaque" }} + metadata: + name: {{ template "application.name" $ }}-{{ $nameSuffix }} + namespace: {{ template "application.namespace" $ }} + {{- if or ($.Values.sealedSecret.annotations) ($config.annotations) ($config.clusterWide) }} + annotations: + {{- if $config.annotations }} + {{ toYaml $config.annotations | indent 2 }} + {{- end }} + {{- if $.Values.sealedSecret.annotations }} + {{ toYaml $.Values.sealedSecret.annotations | indent 2 }} + {{- end }} + {{- if $config.clusterWide}} + sealedsecrets.bitnami.com/cluster-wide: "true" + {{- end}} + {{- end }} + {{- if or ($config.labels) ($.Values.sealedSecret.additionalLabels) }} + labels: + {{- if $config.labels }} + {{ toYaml $config.labels | indent 2 }} + {{- end }} + {{- if $.Values.sealedSecret.additionalLabels }} + {{ toYaml $.Values.sealedSecret.additionalLabels | indent 2 }} + {{- end }} + {{- end }} +--- +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/secret.yaml b/templates/secret.yaml new file mode 100644 index 0000000..5e5d279 --- /dev/null +++ b/templates/secret.yaml @@ -0,0 +1,23 @@ +{{- if (.Values.secret).enabled }} +{{- range $nameSuffix, $data := .Values.secret.files }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "application.name" $ }}-{{ $nameSuffix }} + namespace: {{ template "application.namespace" $ }} + labels: + {{- include "application.labels" $ | nindent 4 }} +{{- if $.Values.secret.additionalLabels }} +{{ toYaml $.Values.secret.additionalLabels | indent 4 }} +{{- end }} +{{- if $.Values.secret.annotations }} + annotations: +{{ toYaml $.Values.secret.annotations | indent 4 }} +{{- end }} +data: +{{- range $key, $value := .data }} + {{ $key }}: {{ $value | b64enc }} +{{- end }} +--- +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/secretproviderclass.yaml b/templates/secretproviderclass.yaml new file mode 100644 index 0000000..0a3a06e --- /dev/null +++ b/templates/secretproviderclass.yaml @@ -0,0 +1,28 @@ +{{- if and (.Values.secretProviderClass).enabled (.Capabilities.APIVersions.Has "secrets-store.csi.x-k8s.io/v1alpha1") }} +apiVersion: secrets-store.csi.x-k8s.io/v1alpha1 +kind: SecretProviderClass +metadata: + name: {{ .Values.secretProviderClass.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "application.labels" $ | nindent 4 }} +spec: + provider: {{ .Values.secretProviderClass.provider }} + parameters: + {{- if .Values.secretProviderClass.vaultAddress }} + vaultAddress: {{ .Values.secretProviderClass.vaultAddress }} + {{- end }} + roleName: {{ include "application.tplvalues.render" (dict "value" .Values.secretProviderClass.roleName "context" $) }} + {{- if .Values.secretProviderClass.objects }} + objects: + {{ toYaml .Values.secretProviderClass.objects | indent 4 }} + {{- end }} + {{- if .Values.secretProviderClass.secretObjects }} + secretObjects: + {{- range $value := .Values.secretProviderClass.secretObjects }} + - data: {{- toYaml $value.data | nindent 8 }} + secretName: {{ $value.secretName }} + type: {{ $value.type }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/secrets.yaml b/templates/secrets.yaml deleted file mode 100755 index c8a2512..0000000 --- a/templates/secrets.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -data: -{{- include "helm-template.secretdata" . | indent 2 }} -{{/* include "render-value" ( dict "value" .Values.secretdata "context" .) | indent 2 */}} -kind: Secret - -metadata: - name: {{ include "helm-template.name" . }}-secrets - namespace: {{ include "helm-template.namespace" . }} -type: Opaque \ No newline at end of file diff --git a/templates/service.yaml b/templates/service.yaml old mode 100755 new mode 100644 index eb0957f..5a7c17d --- a/templates/service.yaml +++ b/templates/service.yaml @@ -1,22 +1,41 @@ -{{- range $containers := .Values.containers }} -{{- range $service := $containers.ports }} -{{- if $service.service_enable }} ---- +{{- if (.Values.service).enabled }} apiVersion: v1 kind: Service metadata: - name: {{ include "helm-template.name" $ }}-{{ $service.name }} - namespace: {{ include "helm-template.namespace" $ }} + name: {{ template "application.name" . }} + namespace: {{ template "application.namespace" $ }} labels: - {{- include "helm-template.selectorLabels" $ | nindent 4 }} + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.service.additionalLabels }} +{{ toYaml .Values.service.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.service.annotations }} + annotations: +{{ include "application.tplvalues.render" ( dict "value" .Values.service.annotations "context" $ ) | indent 4 }} +{{- end }} spec: - type: {{ $service.service_type | default "ClusterIP" }} - ports: - - port: {{ $service.service_port | default "8080" }} - targetPort: {{ $service.port | default "8080" }} - protocol: TCP +{{- if .Values.service.type }} + type: "{{ .Values.service.type }}" +{{- end }} +{{- with .Values.service.clusterIP }} + clusterIP: {{ . }} +{{- end }} selector: - {{- include "helm-template.selectorLabels" $ | nindent 4 }} +{{ include "application.selectorLabels" . | indent 4 }} +{{- if .Values.deployment.podLabels }} +{{ toYaml .Values.deployment.podLabels | indent 4 }} {{- end }} + ports: + {{- if .Values.deployment.openshiftOAuthProxy.enabled }} + - name: proxy + port: 443 + protocol: TCP + {{- if .Values.deployment.openshiftOAuthProxy.disableTLSArg }} + targetPort: 8081 + {{- else }} + targetPort: 8443 + {{- end }} + {{- else }} +{{ toYaml .Values.service.ports | indent 4 }} + {{- end }} {{- end }} -{{- end }} \ No newline at end of file diff --git a/templates/serviceaccount.yaml b/templates/serviceaccount.yaml new file mode 100644 index 0000000..ed8430b --- /dev/null +++ b/templates/serviceaccount.yaml @@ -0,0 +1,31 @@ +{{- define "application.sa.oauth-redirectreference" }} +apiVersion: v1 +kind: OAuthRedirectReference +reference: + kind: Route + name: {{ include "application.name" . }} +{{- end }} + +{{- if and .Values.rbac.enabled .Values.rbac.serviceAccount.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ default (include "application.name" .) .Values.rbac.serviceAccount.name }} + namespace: {{ template "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} + {{- with .Values.rbac.serviceAccount.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + + annotations: + {{- with .Values.rbac.serviceAccount.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + + {{- if .Values.deployment.openshiftOAuthProxy.enabled }} + serviceaccounts.openshift.io/oauth-redirectreference.primary: + {{- $reference := include "application.sa.oauth-redirectreference" . | fromYaml }} + {{- toRawJson $reference | quote | nindent 6 }} + {{- end }} +{{- end }} diff --git a/templates/servicemonitor.yaml b/templates/servicemonitor.yaml new file mode 100644 index 0000000..d7972ed --- /dev/null +++ b/templates/servicemonitor.yaml @@ -0,0 +1,27 @@ +{{- if and (.Values.serviceMonitor).enabled (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") }} +apiVersion: "monitoring.coreos.com/v1" +kind: ServiceMonitor +metadata: + name: {{ template "application.name" . }}-svc-monitor + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} +{{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} +{{- end }} +{{- if or .Values.serviceMonitor.annotations .Values.forecastle.enabled }} + annotations: +{{- end }} +{{- if or .Values.serviceMonitor.annotations }} +{{ toYaml .Values.serviceMonitor.annotations | indent 4 }} +{{- end }} +spec: + selector: + matchLabels: + app: {{ template "application.name" . }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + endpoints: +{{ toYaml .Values.serviceMonitor.endpoints | indent 4 }} +{{- end }} \ No newline at end of file diff --git a/templates/vpa.yaml b/templates/vpa.yaml new file mode 100644 index 0000000..36fc32f --- /dev/null +++ b/templates/vpa.yaml @@ -0,0 +1,27 @@ +{{- if .Values.vpa.enabled -}} +{{- if not (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1/VerticalPodAutoscaler") }} + {{- fail "There is no VerticalPodAutoscaler resource definition in the target cluster!" }} +{{- end }} +apiVersion: "autoscaling.k8s.io/v1" +kind: VerticalPodAutoscaler +metadata: + name: {{ template "application.name" . }} + namespace: {{ include "application.namespace" . }} + labels: + {{- include "application.labels" . | nindent 4 }} + {{- with .Values.vpa.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.vpa.annotations }} + annotations: + {{- toYaml .Values.vpa.annotations | nindent 4 }} + {{- end }} +spec: + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "application.name" . }} + resourcePolicy: + containerPolicies: + {{- toYaml .Values.vpa.containerPolicies | nindent 6 }} +{{- end }} diff --git a/tests/cronjob_test.yaml b/tests/cronjob_test.yaml new file mode 100644 index 0000000..2cbb6ce --- /dev/null +++ b/tests/cronjob_test.yaml @@ -0,0 +1,79 @@ +suite: CronJob + +templates: + - cronjob.yaml + +tests: + - it: does not fail rendering when job image tag and digest are absent + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + tag: "" + digest: "" + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].image + value: example-image + + - it: fails rendering when job image repository is not given + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: "" + tag: doesnt + digest: matter + asserts: + - failedTemplate: + errorMessage: "Undefined image repo for container 'example'" + + - it: uses tag when defined + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + tag: example-tag + digest: "" + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].image + value: example-image:example-tag + + - it: uses digest when defined + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + tag: "" + digest: sha256:example-digest + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].image + value: example-image@sha256:example-digest + + - it: uses both tag and digest when given both + set: + cronJob: + enabled: true + jobs: + example: + image: + repository: example-image + tag: example-tag + digest: sha256:example-digest + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].image + value: example-image:example-tag@sha256:example-digest diff --git a/tests/deployment_test.yaml b/tests/deployment_test.yaml new file mode 100644 index 0000000..07a2228 --- /dev/null +++ b/tests/deployment_test.yaml @@ -0,0 +1,103 @@ +suite: Deployment + +templates: + - deployment.yaml + +tests: + - it: does not include OAuth proxy container if disabled + set: + deployment.openshiftOAuthProxy.enabled: false + asserts: + - notContains: + path: spec.template.spec.containers + content: + image: openshift/oauth-proxy:latest + any: true + + - it: includes OAuth proxy container when enabled + set: + deployment.openshiftOAuthProxy.enabled: true + asserts: + - contains: + path: spec.template.spec.containers + content: + image: openshift/oauth-proxy:latest + any: true + + - it: does not fail to render when image tag and digest are not given + set: + deployment.image.repository: example-image + deployment.image.tag: "" + deployment.image.digest: "" + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: example-image + + - it: fails to render when image repository is not present + set: + deployment.image.repository: "" + asserts: + - failedTemplate: + errorMessage: "Undefined image for application container" + + - it: uses image tag when given + set: + deployment.image.repository: example-image + deployment.image.tag: example-tag + deployment.image.digest: "" + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: example-image:example-tag + - equal: + path: metadata.labels["app.kubernetes.io/version"] + value: example-tag + + - it: uses image digest when given + set: + deployment.image.repository: example-image + deployment.image.tag: "" + deployment.image.digest: sha256:example-digest + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: example-image@sha256:example-digest + - isNull: + path: metadata.labels["app.kubernetes.io/version"] + + - it: uses both image digest and tag when given both + set: + deployment.image.repository: example-image + deployment.image.tag: example-tag + deployment.image.digest: sha256:example-digest + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: example-image:example-tag@sha256:example-digest + + - it: yields empty service account name when disabled + set: + rbac.serviceAccount.enabled: false + asserts: + - notExists: + path: spec.template.spec.serviceAccountName + + - it: uses service account name override when present + set: + rbac.serviceAccount.enabled: true + rbac.serviceAccount.name: example-sa + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: example-sa + + - it: uses a generated service account name when not given + set: + applicationName: example-app + rbac.serviceAccount.enabled: true + rbac.serviceAccount.name: "" + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: example-app diff --git a/tests/hpa_test.yaml b/tests/hpa_test.yaml new file mode 100644 index 0000000..a6da0cd --- /dev/null +++ b/tests/hpa_test.yaml @@ -0,0 +1,82 @@ +suite: HorizontalPodAutoscaler + +templates: + - hpa.yaml + +tests: + - it: does not yield HPA resource if autoscaling.enabled is false + set: + autoscaling.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: does not yield HPA resource if deployment is disabled + set: + autoscaling.enabled: true + deployment.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: yields HPA resource if autoscaling and deployment are both enabled + set: + autoscaling.enabled: true + deployment.enabled: true + asserts: + - hasDocuments: + count: 1 + - isKind: + of: HorizontalPodAutoscaler + + - it: renders additional labels passed through values + set: + autoscaling: + enabled: true + additionalLabels: + foo: bar + test: ing + asserts: + - equal: + path: metadata.labels.foo + value: bar + - equal: + path: metadata.labels.test + value: ing + + - it: renders annotations passed through values + set: + autoscaling: + enabled: true + annotations: + foo: bar + test: ing + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + test: ing + + - it: uses API version autoscaling/v2 when available + set: + autoscaling.enabled: true + deployment.enabled: true + capabilities: + apiVersions: + - apps/v1 + - autoscaling/v2/HorizontalPodAutoscaler + asserts: + - isAPIVersion: + of: autoscaling/v2 + + - it: uses API version autoscaling/v2beta2 when v2 is unavailable + set: + autoscaling.enabled: true + deployment.enabled: true + capabilities: + apiVersions: + - apps/v1 + asserts: + - isAPIVersion: + of: autoscaling/v2beta2 diff --git a/tests/pdb_test.yaml b/tests/pdb_test.yaml new file mode 100644 index 0000000..f939a50 --- /dev/null +++ b/tests/pdb_test.yaml @@ -0,0 +1,96 @@ +suite: PodDisruptionBudget + +templates: + - pdb.yaml + +tests: + - it: does not yield PDB if disabled + set: + pdb.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: does not yield PDB if minAvailable and maxUnavailable are inexistent + set: + pdb: + enabled: true + minAvailable: null + maxUnavailable: null + asserts: + - hasDocuments: + count: 0 + + - it: yields PDB if enabled and minAvailable is set + set: + pdb: + enabled: true + minAvailable: 1 + maxUnavailable: null + asserts: + - isKind: + of: PodDisruptionBudget + - hasDocuments: + count: 1 + + - it: yields PDB if enabled and maxUnavailable is set + set: + pdb: + enabled: true + minAvailable: null + maxUnavailable: 1 + asserts: + - isKind: + of: PodDisruptionBudget + - hasDocuments: + count: 1 + + - it: uses API version policy/v1 if cluster advertises capability + set: + pdb: + enabled: true + minAvailable: 1 + capabilities: + apiVersions: + - policy/v1/PodDisruptionBudget + asserts: + - isAPIVersion: + of: policy/v1 + + - it: uses API version policy/v1beta1 if cluster does not advertise capability + set: + pdb: + enabled: true + minAvailable: 1 + capabilities: + apiVersions: + - apps/v1 + asserts: + - isAPIVersion: + of: policy/v1beta1 + + - it: uses minAvailable when both minAvailable and maxUnavailable are set + set: + pdb: + enabled: true + minAvailable: 1 + maxUnavailable: 1 + asserts: + - equal: + path: spec.minAvailable + value: 1 + - isNull: + path: spec.maxUnavailable + + - it: uses maxUnavailable when it is set and minAvailable is not + set: + pdb: + enabled: true + minAvailable: null + maxUnavailable: 1 + asserts: + - equal: + path: spec.maxUnavailable + value: 1 + - isNull: + path: spec.minAvailable diff --git a/tests/pvc_test.yaml b/tests/pvc_test.yaml new file mode 100644 index 0000000..3b8220a --- /dev/null +++ b/tests/pvc_test.yaml @@ -0,0 +1,128 @@ +suite: PersistentVolumeClaim + +templates: + - pvc.yaml + +tests: + - it: does not yield PVC if persistence is disabled + set: + persistence.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: does not yield PVC if there's an existing claim + set: + persistence: + enabled: true + existingClaim: true + asserts: + - hasDocuments: + count: 0 + + - it: yields a PVC when persistence is enabled and there's no existing claim + set: + persistence: + enabled: true + existingClaim: false + asserts: + - hasDocuments: + count: 1 + - isKind: + of: PersistentVolumeClaim + + - it: includes additional labels when defined in values + set: + persistence: + enabled: true + existingClaim: false + additionalLabels: + foo: bar + test: ing + asserts: + - equal: + path: metadata.labels.foo + value: bar + - equal: + path: metadata.labels.test + value: ing + + - it: includes annotations when defined in values + set: + persistence: + enabled: true + existingClaim: false + annotations: + foo: bar + test: ing + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + test: ing + + - it: uses name override when it is defined in values + set: + persistence: + enabled: true + existingClaim: false + name: example-name-that-should-be-used + asserts: + - equal: + path: metadata.name + value: example-name-that-should-be-used + + - it: storage class name is unset if not in values + set: + persistence: + enabled: true + existingClaim: false + storageClass: null + asserts: + - isNull: + path: spec.storageClassName + + - it: storage class name is an empty string if set to '-' + set: + persistence: + enabled: true + existingClaim: false + storageClass: "-" + asserts: + - equal: + path: spec.storageClassName + value: "" + + - it: storage class name is used if present and not '-' + set: + persistence: + enabled: true + existingClaim: false + storageClass: example-class-that-should-be-used + asserts: + - equal: + path: spec.storageClassName + value: example-class-that-should-be-used + + - it: volume mode is used if present + set: + persistence: + enabled: true + existingClaim: false + volumeMode: ExampleVolumeMode + asserts: + - equal: + path: spec.volumeMode + value: ExampleVolumeMode + + - it: volume name is used if present + set: + persistence: + enabled: true + existingClaim: false + volumeName: ExampleVolumeName + asserts: + - equal: + path: spec.volumeName + value: ExampleVolumeName diff --git a/tests/serviceaccount_test.yaml b/tests/serviceaccount_test.yaml new file mode 100644 index 0000000..14e838c --- /dev/null +++ b/tests/serviceaccount_test.yaml @@ -0,0 +1,95 @@ +suite: ServiceAccount + +templates: + - serviceaccount.yaml + +tests: + - it: does not yield resource if RBAC is disabled + set: + rbac: + enabled: false + serviceAccount: + enabled: true + asserts: + - hasDocuments: + count: 0 + + - it: does not yield resource if ServiceAccount is disabled + set: + rbac: + enabled: true + serviceAccount: + enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: yields a ServiceAccount if RBAC & SA creation are enabled + set: + rbac: + enabled: true + serviceAccount: + enabled: true + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ServiceAccount + + - it: includes additional labels when defined in values + set: + rbac: + enabled: true + serviceAccount: + enabled: true + additionalLabels: + foo: bar + test: ing + asserts: + - equal: + path: metadata.labels.foo + value: bar + - equal: + path: metadata.labels.test + value: ing + + - it: renders annotations when defined in values + set: + deployment.openshiftOAuthProxy.enabled: false + rbac: + enabled: true + serviceAccount: + enabled: true + annotations: + foo: bar + test: ing + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + test: ing + + - it: sets OpenShift annotation when OAuth Proxy is enabled + set: + deployment.openshiftOAuthProxy.enabled: true + rbac: + enabled: true + serviceAccount: + enabled: true + asserts: + - matchRegex: + path: metadata.annotations["serviceaccounts.openshift.io/oauth-redirectreference.primary"] + pattern: "^{.*}$" + + - it: uses service account name override when present + set: + rbac: + enabled: true + serviceAccount: + enabled: true + name: example-name-that-should-be-used + asserts: + - equal: + path: metadata.name + value: example-name-that-should-be-used diff --git a/values.example.yaml b/values.example.yaml new file mode 100644 index 0000000..52bda72 --- /dev/null +++ b/values.example.yaml @@ -0,0 +1,1275 @@ +# Name of the application. +applicationName: "application" + +namespaceOverride: "" + +# These labels will be added on all resources, and you can add additional labels from below on individual resource +labels: + group: com.stakater.platform + team: stakater +deployment: + dnsConfig: + options: + - name: ndots + value: "1" + # By default deploymentStrategy is set to rollingUpdate with maxSurge of 25% and maxUnavailable of 25% + # You can change type to `Recreate` or can uncomment `rollingUpdate` specification and adjust them to your usage. + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + + # Reload deployment if configMap/secret updates + reloadOnChange: true + + # Select nodes to deploy which matches the following labels + nodeSelector: + # cloud.google.com/gke-nodepool: default-pool + + # Init containers which runs before the app container + hostAliases: + - ip: "127.0.0.1" + hostnames: + - "foo.local" + - "bar.local" + - ip: "10.1.2.3" + hostnames: + - "foo.remote" + - "bar.remote" + + # Init containers which runs before the app container + initContainers: + init-contaner: + image: busybox + imagePullPolicy: IfNotPresent + command: ["/bin/sh"] + + # Additional labels for Deployment + additionalLabels: + key: value + + # Additional label added on pod which is used in Service's Label Selector + podLabels: + env: prod + + # Annotations on deployments + annotations: + + # Additional Pod Annotations added on pod created by this Deployment + additionalPodAnnotations: + key: value + + # Annotations for fluentd Configurations + fluentdConfigAnnotations: + fluentd: + regex: hello + timeFormat: world + + # Replicas to be created + replicas: 2 + + # Secrets used to pull image + imagePullSecrets: "" + + # If want to mount Envs from configmap or secret + envFrom: + production-cm: + type: configmap + nameSuffix: my-configmap + logging-config: + type: configmap + name: your-configmap + postgres-config: + type: secret + nameSuffix: postgres + + # Environment variables to be passed to the app container + env: + ENVIRONMENT: + value: "dev" + + # Volumes to be added to the pod + volumes: + config-volume: + configMap: + name: configmap-name + configmap-volume: + configMap: + name: '{{ template "application.name" . }}-configmap-nameSuffix' + secret-volume: + secret: + secretName: secret-name + volume-name: + emptyDir: {} + persistent-volume-name: + persistentVolumeClaim: + claimName: claim-name + + # Mount path for Volumes + volumeMounts: + volume-name: + mountPath: /path1 + + # Taint tolerations for nodes + tolerations: + - key: "dedicated" + operator: "Equal" + value: "app" + effect: "NoSchedule" + + # Pod affinity and pod anti-affinity allow you to specify rules about how pods should be placed relative to other pods. + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: disktype + operator: In + values: + - ssd + + # Image of the app container + image: + repository: repository/image-name + tag: v1.0.0 + pullPolicy: IfNotPresent + + # Startup, Readiness and Liveness probes + startupProbe: + enabled: true + failureThreshold: 30 + periodSeconds: 10 + httpGet: + path: "/path" + port: 8080 + exec: {} + + readinessProbe: + enabled: true + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + initialDelaySeconds: 10 + exec: + command: + - cat + - tmp/healthy + + livenessProbe: + enabled: true + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + initialDelaySeconds: 10 + httpGet: + path: /path + port: 8080 + + # Resources to be defined for pod + resources: + limits: + memory: 256Mi + cpu: 0.5 + requests: + memory: 128Mi + cpu: 0.1 + + # Security Context at Container Level + containerSecurityContext: + readOnlyRootFilesystem: true + runAsNonRoot: true + + openshiftOAuthProxy: + enabled: true + port: 8080 + secretName: "openshift-oauth-proxy-tls" + + # Add additional containers besides init and app containers + additionalContainers: + - name: sidecar-contaner + image: busybox + imagePullPolicy: IfNotPresent + command: ["/bin/sh"] + + # Security Context for the pod + securityContext: + # fsGroup: 2000 + + # Command for primary container + command: [] + + # Args for primary contaner + args: [] + + # List of ports for the primary container + ports: + - containerPort: 8080 + name: http + protocol: TCP + - containerPort: 8778 + name: jolokia + protocol: TCP + - containerPort: 8443 + name: https + protocol: TCP + +# Add Storage volumes to the pods +persistence: + enabled: true + mountPVC: false + mountPath: "/" + name: "" + accessMode: ReadWriteOnce + ## If defined, storageClass: + ## If set to "-", storageClass: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClass spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "-" + additionalLabels: + key: "value" + + annotations: + # "helm.sh/resource-policy": keep + storageSize: 8Gi + volumeMode: "Filesystem" + volumeName: "" + +# Service object for servicing pods +service: + additionalLabels: + key: value + expose: "true" + annotations: + config.xposer.stakater.com/Domain: stakater.com + config.xposer.stakater.com/IngressNameTemplate: '{{ "{{.Service}}-{{.Namespace}}" }}' + config.xposer.stakater.com/IngressURLPath: / + config.xposer.stakater.com/IngressURLTemplate: '{{ "{{.Service}}.{{.Namespace}}.{{.Domain}}" }}' + service.alpha.openshift.io/serving-cert-secret-name: | + '{{ template "application.name" . }}-tls' + xposer.stakater.com/annotations: |- + kubernetes.io/ingress.class: external-ingress + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/force-ssl-redirect: "true" + + ports: + - port: 8080 + name: http + protocol: TCP + targetPort: 8080 + type: ClusterIP + +# Ingress object for exposing services +ingress: + enabled: true + + # Name of the ingress class + ingressClassName: nginx + + # Port of the service that serves pods + servicePort: http + + #Set pathType: default is ImplementationSpecific; Options: Exact, Prefix + pathType: ImplementationSpecific + + # List of host addresses to be exposed by this Ingress + + hosts: + - host: chart-example.local + paths: + - path: / + # pathType: '' + # serviceName: '' + # servicePort: '' + - path: /subpath + # pathType: '' + # serviceName: '' + # servicePort: '' + - host: "{{ .Release.Name }}.stakater.com" + paths: + - path: / + + # Additional labels for this Ingress + additionalLabels: + key: value + + # Add annotations to this Ingress + annotations: + kubernetes.io/ingress.class: external-ingress + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/force-ssl-redirect: "true" + + # TLS details for this Ingress + tls: + # Secrets must be manually created in the namespace. + - secretName: chart-example-tls + hosts: + - chart-example.local + - "{{ .Release.Name }}.stakater.com" + +# Route object for exposing services (OpenShift only) +route: + enabled: true + + # Add annotations to this Route + annotations: + kubernetes.io/ingress.class: external-ingress + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/force-ssl-redirect: "true" + + # Additional labels for this Route + additionalLabels: + key: value + + # If no host is added then openshift inserts the default hostname. To Add host explicitly, use host attribute + host: + + path: /document + + # Port of the service that serves pods + port: + targetPort: http + + to: + weight: 80 + + wildcardPolicy: None + + tls: + # TLS Termination strategy + termination: edge + insecureEdgeTerminationPolicy: Redirect + + alternateBackends: + kind: Service + name: alternate-application + weight: 20 + +secretProviderClass: + enabled: true + name: mongo-host + provider: vault + vaultAddress: "http://vault:8200" + roleName: "{{ .Release.Name }}" + objects: | + - objectName: "MONGO_HOST" + secretPath: "testing/data/mongoDb" + secretKey: "MONGO_HOST" + secretObjects: + - data: + - key: MONGO_HOST + objectName: host + secretName: secret-mongo-host + type: Opaque + +# Expose Application on Forecastle Dashboard +forecastle: + enabled: true + + # Add additional labels on Forecastle Custom Resource + additionalLabels: + key: value + + # URL of the icon for the custom app + icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/stakater-big.png + + # Name of the application to be displayed on the Forecastle Dashboard + displayName: "application" + + # Group for the custom app (default: .Release.Namespace) + group: "" + + # Add properties to Custom Resource + properties: + + # Whether app is network restricted or not + networkRestricted: false + +# Role Based Access Control +rbac: + enabled: true + + # Service Account to use by pods + serviceAccount: + enabled: true + name: "application" + + # Additional Labels on service account + additionalLabels: + key: value + + # Annotations on service account + annotations: + # key: value + + # Create Roles (Namespaced) + roles: + - name: configmaps + rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - name: secrets + rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + +# Additional ConfigMaps +configMap: + enabled: true + additionalLabels: + key: value + annotations: + # key: value + files: + code-config: + key1: value1 + key2: value2 + dev-config: + key1: value1 + key2: value2 + +sealedSecret: + enabled: true + additionalLabels: + # key: value + annotations: + # key: value + files: + # nameSuffix of sealedSecret + example: + encryptedData: + name: AgBghrdepGMKmp/rdtJrkBv/CWpJbtmoMsbKQ7QiZZ2kUoLeeTbrDnhmJY03kWKkNW4kN/sQRf6r1vvBEaR4nkHt5f/ayAeaH3NveI3bdb0xv/svvWjyjehwqwr/kNEAVWxRoUij0Y7MyIEAr4hnV2UnrhgvcjPJLNA8bK6spA+kuT328Vpyceyvnm6yArNn1aYlEckaFHrnculHWRpG73iRYxS5GWAY7EdkLXx7OLLWoopHtLcupklYyPfraJzPvBNZ5/PsyjlUBvoQbGV3cZlrdEj1WHj2S1RQ13ddf2WGtMHmY83t9B3LFZAZuA7BBt4rjludbwQm3/tJ5Kas1dDsSIRIIF7MTeum9YfRB8XUz8IxVKQ/JDskeynrWe3VzN/3HFVnv9GGFy+BCVXZKVU/roIRancz+nXkyoOHS722ZpBi53dfLItoS5dG+0EzArMTQzK/KXHz3b1rxp5oWWDNt3WggTiSg2zwy5ZR8VV2ToTDof6UrFmbCZv/kKriyxbVSxIo3KFnvuRiUZ5MwC0TNut4mW3LKyJfHqkUuLa1mYV6tKF58qBnoj/+JaibAIBEudT9hms5U52p7/jKmgHuop7XPEsz4OVwER//Vbv7X6ctoXtyPu6mZyOfOyJHM8Qj/H7/gwMBYhZHQ96DWrVmZOsWSRpZGJni4Xm7rgt2cFj6UtWv6lvl8aOi/HSZVC3TwWZ9mQrk + annotations: + key: value + labels: + key: value + type: Opaque + clusterWide: true + +# Additional Secrets +secret: + enabled: true + additionalLabels: + key: value + annotations: + # key: value + files: +# nameSuffix of Secret +# credentials: +# data: +# secretKey1: secretValue1 +# secretKey2: secretValue2 +# password: +# data: +# secretKey1: secretValue1 +# secretKey2: secretValue2 + +# Service Monitor to collect Prometheus metrices +serviceMonitor: + enabled: true + + # Additional labels + additionalLabels: + key: value + + # Additional annotations + annotations: + # key: value + + # List of the endpoints of service from which prometheus will scrape data + endpoints: + - interval: 5s + path: /actuator/prometheus + port: http + +# autoscaling is used for horizonal pod autoscaling +autoscaling: + # enabled is a boolean flag for enabling or disabling autoscaling + enabled: true + # additionalLabels defines additional labels + additionalLabels: + key: value + # annotations defines annotations in key value pair + annotations: + # key: value + # minReplicas sets the minimum number of replicas + minReplicas: 1 + # maxReplicas sets the maximum number of replicas + maxReplicas: 10 + # metrics is the list of metrics used for hpa + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 60 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 60 + +# autoscaling is used for vertical pod autoscaling +vpa: + # enabled is a boolean flag for enabling or disabling vpa + enabled: true + # additionalLabels defines additional labels + additionalLabels: + # key: value + # annotations defines annotations in key value pair + annotations: + # key: value + # container policies for individual containers. + # There can be at most one entry for every named container and optionally a single wildcard entry with `containerName = '*'`, which handles all containers that do not have individual policies. + containerPolicies: + - containerName: "*" + minAllowed: + cpu: 0.5 + memory: 1Gi + maxAllowed: + cpu: 1 + memory: 5Gi + +# EndpointMonitor for IMC (https://github.com/stakater/IngressMonitorController) +endpointMonitor: + enabled: true + + # Additional labels + additionalLabels: + key: value + + # Additional annotations + annotations: + # key: value + +# Certficate CRD to generate the certificate +certificate: + enabled: false + + # Additional labels + additionalLabels: + key: value + + # Additional annotations + annotations: + # key: value + + secretName: tls-cert + duration: 8760h0m0s # 1 year + renewBefore: 720h0m0s # 30d + subject: + # organizations: + # - stakater + # countries: + # - SE + # organizationalUnits: + # - '{{ template "application.namespace" . }}' + # localities: + # - Stockholm + # provinces: + # - Stockholm + commonName: admin-app + keyAlgorithm: rsa + keyEncoding: pkcs1 + keySize: 2048 + isCA: false + usages: + # - digital signature + # - client auth + dnsNames: + # - admin-app + ipAddresses: + # - 192.168.0.5 + uriSANs: + # - spiffe://cluster.local/ns/sandbox/sa/example + emailSANs: + # - emailSubjectAltNames + privateKey: + enabled: true + rotationPolicy: Always + issuerRef: + name: ca-issuer + # We can reference ClusterIssuers by changing the kind here. + kind: ClusterIssuer + group: #cert-manager.io + keystores: + enabled: true + pkcs12: + create: true + key: test_key + name: test-creds + jks: + create: false + key: test_key + name: test-creds + +# AlertmanagerConfig object for defining application specific alertmanager configurations +alertmanagerConfig: + enabled: true + + # AlertmanagerConfig selectionLabels to specify label to be picked up by Alertmanager to add it to base config. Read more about it at [https://docs.openshift.com/container-platform/4.7/rest_api/monitoring_apis/alertmanager-monitoring-coreos-com-v1.html] under .spec.alertmanagerConfigSelector + selectionLabels: + alertmanagerConfig: "workload" + + # AlertmanagerConfig spec, read details here [https://docs.openshift.com/container-platform/4.7/rest_api/monitoring_apis/alertmanagerconfig-monitoring-coreos-com-v1alpha1.html] + spec: + route: + receiver: "null" + groupBy: + - job + routes: + - receiver: "null" + groupBy: + - alertname + - severity + continue: true + groupWait: 30s + groupInterval: 5m + repeatInterval: 12h + receivers: + - name: "null" + inhibitRules: + - sourceMatch: + - name: severity + value: "critical" + targetMatch: + - name: severity + value: "warning" + equal: ["cluster", "service"] + +# PrometheusRule object for defining application alerting rules +prometheusRule: + enabled: true + + # PrometheusRule labels + additionalLabels: + prometheus: stakater-workload-monitoring + role: alert-rules + + # Groups with alerting rules. Read more here [https://docs.openshift.com/container-platform/4.7/rest_api/monitoring_apis/prometheusrule-monitoring-coreos-com-v1.html] + + groups: + - name: example-app-uptime + rules: + - alert: ExampleAppDown + annotations: + message: >- + The Example App is Down (Test Alert) + expr: up{namespace="test-app"} == 0 + for: 1m + labels: + severity: critical + +# ExternalSecrets +externalSecret: + enabled: true + + #SecretStore defines which SecretStore to use when fetching the secret data + secretStore: + name: example-secret-store + #kind: SecretStore # or ClusterSecretStore + + # RefreshInterval is the amount of time before the values reading again from the SecretStore provider + refreshInterval: "1m" + files: + secret-1-name: + #Data defines the connection between the Kubernetes Secret keys and the Provider data + data: + example-secret-key: + remoteRef: + key: example-provider-key + property: example-provider-key-property + + secret-2-name: + #Used to fetch all properties from the Provider key + dataFrom: + key: example-provider-key + type: Opaque + annotations: + key: value + labels: + key: value + +########################################################## +# Network Policy +########################################################## +networkPolicy: + enabled: false + # Additional labels + additionalLabels: + key: value + + # Additional annotations + annotations: + # key: value + + # Ingress rules + ingress: + - from: + - ipBlock: + cidr: 172.17.0.0/16 + except: + - 172.17.1.0/24 + - namespaceSelector: + matchLabels: + project: myproject + - podSelector: + matchLabels: + role: frontend + ports: + - protocol: TCP + port: 6379 + + # Egress rules + egress: + - to: + - ipBlock: + cidr: 10.0.0.0/24 + ports: + - protocol: TCP + port: 5978 + +########################################################## +# Pod disruption budget - PDB +########################################################## +pdb: + enabled: true + minAvailable: 1 + maxUnavailable: 2 + +# Grafana Dashboard +grafanaDashboard: + enabled: true + additionalLabels: + test-label: chart + annotations: + test-annoation: chart + contents: + dashboard-test-name-1: + json: |- + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 9, + "iteration": 1592326712687, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "prometheus", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(haproxy_server_http_responses_total{code=\"5xx\", route=~\"$route\", namespace=~\"$namespace\", pod=~\"$router\"}[$rate])) by (namespace, code, route)", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "Route: {{route}}, Namespace: {{namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Failure Requests Rate (5xx)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "none", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "prometheus", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(haproxy_server_http_responses_total{code=\"2xx\", route=~\"$route\", namespace=~\"$namespace\", pod=~\"$router\"}[$rate])) by (namespace, code, route)", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "Route: {{route}}, Namespace: {{namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Successful Requests Rate (2xx)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "none", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "prometheus", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(haproxy_server_http_responses_total{namespace=~\"$namespace\", route=~\"$route\", code=~\"$code\", pod=~\"$router\"}) by (namespace, route, code)", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "Code: {{code}}, Route: {{route}}, Namespace: {{namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of requests by HTTP codes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "none", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 20, + "style": "dark", + "tags": [ + "haproxy" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "tags": [], + "text": "All", + "value": "$__all" + }, + "datasource": "prometheus", + "definition": "label_values(haproxy_server_http_responses_total, namespace)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "namespace", + "options": [], + "query": "label_values(haproxy_server_http_responses_total, namespace)", + "refresh": 1, + "regex": ".*", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "All", + "value": "$__all" + }, + "datasource": "prometheus", + "definition": "label_values(haproxy_server_http_responses_total{namespace=~\"$namespace\"}, route)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "route", + "options": [], + "query": "label_values(haproxy_server_http_responses_total{namespace=~\"$namespace\"}, route)", + "refresh": 1, + "regex": ".*", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "tags": [], + "text": "All", + "value": "$__all" + }, + "datasource": "prometheus", + "definition": "label_values(haproxy_server_http_responses_total, code)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "code", + "options": [], + "query": "label_values(haproxy_server_http_responses_total, code)", + "refresh": 1, + "regex": ".*", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "tags": [], + "text": "5m", + "value": "5m" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "rate", + "options": [ + { + "selected": false, + "text": "1m", + "value": "1m" + }, + { + "selected": true, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "30m", + "value": "30m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + } + ], + "query": "1m,5m,30m,1h", + "skipUrlSync": false, + "type": "custom" + }, + { + "allValue": null, + "current": { + "text": "All", + "value": "$__all" + }, + "datasource": "prometheus", + "definition": "label_values(haproxy_server_http_responses_total, pod)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "router", + "options": [], + "query": "label_values(haproxy_server_http_responses_total, pod)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "HAProxy Dashboard Example from chart", + "uid": "OmHEcaFZz", + "version": 3 + } + +cronJob: + enabled: true + jobs: + db-migration: + schedule: "* * * 8 *" + imagePullSecrets: + - name: nexus-secret + image: + repository: docker.io/nginx + tag: v1.0.0 + env: + KEY: + value: VALUE + command: ["/bin/bash"] + args: ["-c", "sleep 5000"] + resources: + requests: + memory: 5Gi + cpu: 1 diff --git a/values.yaml b/values.yaml old mode 100755 new mode 100644 index 4b92fa1..7881a4c --- a/values.yaml +++ b/values.yaml @@ -1,167 +1,871 @@ -# Secret Data Variables for -secretdata: - amq.datasource.username: XXXXXX - amq.datasource.password: YYYYYY - minio.access.key: ZZZZZZ - minio.secret.key: AAAAAA - redis.datasource.password: BBBBBBBB - -name: "MyApp" -namespace: "MyNS" -replicaCount: 1 - -imagePullSecrets: -- name: regcred - -restartPolicy: Always - - -affinitylable: - pan: xk - -Affinity: - - type: nodeAntiAffinity - rule: required - key: app - operator: In - values: - - general - - nn - - - type: podAntiAffinity - rule: preferred - key: pan - operator: In - values: - - man - weight: 100 - - type: nodeAffinity - rule: required - key: app - operator: NotIn - values: - - ali - - type: podAntiAffinity - rule: preferred - key: pan - operator: NotIn - values: - - we - weight: 100 - - type: podAffinity - rule: required - key: pan - operator: In - values: - - we - weight: 100 +# -- Same as nameOverride but for the namespace. +namespaceOverride: "" +# -- Same as nameOverride but for the component. +componentOverride: "" -podAnnotations: {} +# -- Same as nameOverride but for the partOf. +partOfOverride: "" -podSecurityContext: - # fsGroup: 2000 +########################################################## +# Name of the application. +########################################################## +applicationName: "application" +########################################################## +# Global labels +# These labels will be added on all resources, +# and you can add additional labels from below +# on individual resource +########################################################## -containers: - - image: nginx - repository: hub.my.org - pullPolicy: IfNotPresent - # Overrides the image tag whose default is the chart appVersion. +cronJob: + enabled: false + jobs: + # db-migration: + # schedule: "* * * 8 *" + # env: + # KEY: + # value: VALUE + # image: + # repository: docker.io/nginx + # tag: v1.0.0 + # digest: '' # if set to a non empty value, digest takes precedence on the tag + # imagePullPolicy: IfNotPresent + # command: ["/bin/bash"] + # args: ["-c","sleep 5000"] + # resources: + # requests: + # memory: 5Gi + # cpu: 1 + +########################################################## +# Deployment +########################################################## +deployment: + enabled: true + # By default deploymentStrategy is set to rollingUpdate with maxSurge of 25% and maxUnavailable of 25% + # You can change type to `Recreate` or can uncomment `rollingUpdate` specification and adjust them to your usage. + strategy: + type: RollingUpdate + # rollingUpdate: + # maxSurge: 25% + # maxUnavailable: 25% + + # Reload deployment if configMap/secret updates + reloadOnChange: true + + # Select nodes to deploy which matches the following labels + nodeSelector: + # cloud.google.com/gke-nodepool: default-pool + + # Init containers which runs before the app container + hostAliases: + # - ip: "127.0.0.1" + # hostnames: + # - "foo.local" + # - "bar.local" + # - ip: "10.1.2.3" + # hostnames: + # - "foo.remote" + # - "bar.remote" + + # Init containers which runs before the app container + initContainers: + # init-contaner: + # image: busybox + # imagePullPolicy: IfNotPresent + # command: ['/bin/sh'] + + # Additional labels for Deployment + additionalLabels: + # key: value + + # Additional label added on pod which is used in Service's Label Selector + podLabels: + # env: prod + + # Annotations on deployments + annotations: + + # Additional Pod Annotations added on pod created by this Deployment + additionalPodAnnotations: + # key: value + + # Annotations for fluentd Configurations + fluentdConfigAnnotations: + # fluentd: + # regex: hello + # timeFormat: world + + # Replicas to be created + replicas: + + # Secrets used to pull image + imagePullSecrets: "" + + # If want to mount Envs from configmap or secret + envFrom: + # production-cm: + # type: configmap + # nameSuffix: my-configmap + # logging-config: + # type: configmap + # nameSuffix: your-configmap + # postgres-config: + # type: secret + # nameSuffix: postgres + + # Environment variables to be passed to the app container + env: + # ENVIRONMENT: + # value: "dev" + # FREQUENCY: + # valueFrom: + # configMapKeyRef: + # name: config + # key: frequency + + # Volumes to be added to the pod + volumes: + # configmap-volume: + # configMap: + # name: '{{ template "application.name" . }}-configmap-nameSuffix' + # secret-volume: + # secret: + # secretName: secret-name + # persistent-volume-name: + # persistentVolumeClaim: + # claimName: claim-name + + # Mount path for Volumes + volumeMounts: + # volume-name: + # mountPath: path + # subPath: szy + + # volume-name-2: + # mountPath: path-2 + + # Taint tolerations for nodes + tolerations: + # - key: "dedicated" + # operator: "Equal" + # value: "app" + # effect: "NoSchedule" + + # Pod affinity and pod anti-affinity allow you to specify rules about how pods should be placed relative to other pods. + affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: disktype + # operator: In + # values: + # - ssd + + # Topology spread constraints + topologySpreadConstraints: + # - maxSkew: 1 + # topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: ScheduleAnyway + # labelSelector: + # matchExpressions: + # - key: disktype + # operator: In + # values: + # - ssd + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: ScheduleAnyway + # labelSelector: + # matchExpressions: + # - key: disktype + # operator: In + # values: + # - ssd + + # Number of ReplicaSet versions to retain + revisionHistoryLimit: 2 + + # Image of the app container + image: + repository: repository/image-name tag: "" - args: - - -c - - java $JAVA_OPTS -Duser.timezone='Asia/Tehran' -Dlog4j2.formatMsgNoLookups=true -jar app.jar - command: - - /bin/bash - workingDir: /opt/ - ports: - - name: http - port: 8080 - service_enable: true - service_type: - service_port: - env: - configMapKeyRef: - - key: network.version - ConfigMapName: hooman-config - - key: network.deployment - ConfigMapName: hooman-config - JAVA_OPTS: -Drouting.local-ip=127.0.0.1 -Drouting.version=$(VERSION) - envFrom: - - ConfigMapName: configmapname - healthcheck: - livenessProbe: - failureThreshold: 10 - httpGet: - path: /monitor/health - port: 8080 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 30 - timeoutSeconds: 7 - readinessProbe: - failureThreshold: 3 - httpGet: - path: /monitor/health - port: 8080 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 7 - resources: {} - # limits: - # memory: 4Gi - # cpu: "4" - # requests: - # cpu: "2" - # memory: 2Gi - - - securityContext: {} - # capabilities: - # drop: - # - ALL - # readOnlyRootFilesystem: true - # runAsNonRoot: true - # runAsUser: 1000 -volumes: - - name: vol1 - emptyDir: {} - - name: vol2 - emptyDir: - medium: Memory + digest: "" # if set to a non empty value, digest takes precedence on the tag + pullPolicy: IfNotPresent + dnsConfig: + # options: + # - name: ndots + # value: '1' + # Startup, Readiness and Liveness probes + startupProbe: + enabled: false + failureThreshold: 30 + periodSeconds: 10 + # Must specify either one of the following field when enabled + httpGet: {} + exec: {} + tcpSocket: {} + readinessProbe: + enabled: false + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + initialDelaySeconds: 10 + # Must specify either one of the following field when enabled + httpGet: {} + exec: {} + tcpSocket: {} -autoscaling: + livenessProbe: + enabled: false + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + initialDelaySeconds: 10 + # Must specify either one of the following field when enabled + httpGet: {} + exec: {} + tcpSocket: {} + + # Resources to be defined for pod + resources: + limits: + memory: 256Mi + cpu: 0.5 + requests: + memory: 128Mi + cpu: 0.1 + + # Security Context at Container Level + containerSecurityContext: + readOnlyRootFilesystem: true + runAsNonRoot: true + + openshiftOAuthProxy: + enabled: false + port: 8080 # Port on which application is running inside container + secretName: "openshift-oauth-proxy-tls" + image: openshift/oauth-proxy:latest # If you have a custom container for oauth-proxy that can be updated here + disableTLSArg: false # If disabled --http-address=:8081 will be used instead of --https-address=:8443 , to be used when an ingress is used for application + # Add additional containers besides init and app containers + additionalContainers: + # - name: sidecar-contaner + # image: busybox + # imagePullPolicy: IfNotPresent + # command: ['/bin/sh'] + + # Security Context for the pod + + securityContext: + # fsGroup: 2000 + + # Command for primary container + command: [] + + # Args for primary contaner + args: [] + + # List of ports for the primary container + ports: + #- containerPort: 8080 + # name: http + # protocol: TCP + #- containerPort: 8778 + # name: jolokia + # protocol: TCP + #- containerPort: 8443 + # name: https + # protocol: TCP + +########################################################## +# Add Storage volumes to the pods +########################################################## +persistence: + enabled: false + mountPVC: false + mountPath: "/" + name: "" + accessMode: ReadWriteOnce + ## If defined, storageClass: + ## If set to "-", storageClass: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClass spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "-" + additionalLabels: + # key: "value" + annotations: + # "helm.sh/resource-policy": keep + storageSize: 8Gi + volumeMode: "" + volumeName: "" + +########################################################## +# Service object for servicing pods +########################################################## +service: enabled: true - minReplicas: 1 - maxReplicas: 100 - targetCPUUtilizationPercentage: 80 - # targetMemoryUtilizationPercentage: 80 + additionalLabels: + # expose: "true" -nodeSelector: {} + annotations: + # config.xposer.stakater.com/Domain: stakater.com + # config.xposer.stakater.com/IngressNameTemplate: '{{ "{{.Service}}-{{.Namespace}}" }}' + # config.xposer.stakater.com/IngressURLPath: / + # config.xposer.stakater.com/IngressURLTemplate: '{{ "{{.Service}}.{{.Namespace}}.{{.Domain}}" }}' + # service.alpha.openshift.io/serving-cert-secret-name: | + # '{{ template "application.name" . }}-tls' + # xposer.stakater.com/annotations: |- + # kubernetes.io/ingress.class: external-ingress + # ingress.kubernetes.io/rewrite-target: / + # ingress.kubernetes.io/force-ssl-redirect: true -tolerations: [] + ports: + - port: 8080 + name: http + protocol: TCP + targetPort: 8080 + type: ClusterIP -serviceAccount: - # Specifies whether a service account should be created - create: false - # Annotations to add to the service account - annotations: {} - # The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template - name: "MyApp" + # Set to 'None' will make this service headless + clusterIP: +########################################################## +# Ingress object for exposing services +########################################################## ingress: enabled: false - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" + + # Name of the ingress class + ingressClassName: "" + + # Port of the service that serves pods + servicePort: http + + #Set pathType: default is ImplementationSpecific; Options: Exact, Prefix + pathType: ImplementationSpecific + + # List of host addresses to be exposed by this Ingress hosts: - host: chart-example.local paths: - - path: / - backend: - serviceName: chart-example.local - servicePort: 80 \ No newline at end of file + - path: / + # pathType: '' + # serviceName: '' + # servicePort: '' + # Additional labels for this Ingress + additionalLabels: + + # Add annotations to this Ingress + annotations: + # kubernetes.io/ingress.class: external-ingress + # ingress.kubernetes.io/rewrite-target: / + # ingress.kubernetes.io/force-ssl-redirect: true + + # TLS details for this Ingress + tls: + # Secrets must be manually created in the namespace. + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +########################################################## +# Route object for exposing services (OpenShift) +########################################################## +route: + enabled: false + + # Add annotations to this Route + annotations: + # kubernetes.io/ingress.class: external-ingress + # ingress.kubernetes.io/rewrite-target: / + # ingress.kubernetes.io/force-ssl-redirect: true + + # Additional labels for this Route + additionalLabels: + + # If no host is added then openshift inserts the default hostname. To Add host explicitly, use host attribute + host: + + path: + # Port of the service that serves pods + port: + targetPort: http + + to: + weight: 100 + + wildcardPolicy: None + + tls: + # TLS Termination strategy + termination: edge + insecureEdgeTerminationPolicy: Redirect + + alternateBackends: + # kind: Service + # name: alternate-application + # weight: 20 + +########################################################## +# SecretProviderClass +########################################################## +secretProviderClass: + enabled: false + name: "" + # name: example + provider: "" + # provider: vault + vaultAddress: "" + # vaultAddress: http://vault:8200 + roleName: "" + # roleName: example-role + objects: + #- objectName: MONGO_HOST + # secretPath: testing/data/mongoDb + # secretKey: MONGO_HOST + secretObjects: + #- data: + # - key: MONGO_HOST + # objectName: host + # secretName: secret-mongo-host + # type: Opaque + +########################################################## +# Expose Application on Forecastle Dashboard +# https://github.com/stakater/Forecastle +########################################################## +forecastle: + enabled: false + + # Add additional labels on Forecastle Custom Resource + additionalLabels: + + # URL of the icon for the custom app + icon: https://raw.githubusercontent.com/stakater/ForecastleIcons/master/stakater-big.png + + # Name of the application to be displayed on the Forecastle Dashboard + displayName: "application" + + # Group for the custom app (default: .Release.Namespace) + group: "" + + # Add properties to Custom Resource + properties: + + # Whether app is network restricted or not + networkRestricted: false + +########################################################## +# Role Based Access Control (RBAC) +########################################################## +rbac: + enabled: true + + # Service Account to use by pods + serviceAccount: + enabled: false + name: "" + + # Additional Labels on service account + additionalLabels: + # key: value + + # Annotations on service account + annotations: + # key: value + + # Create Roles (Namespaced) + roles: + # - name: configmaps + # rules: + # - apiGroups: + # - "" + # resources: + # - configmaps + # verbs: + # - get + # - name: secrets + # rules: + # - apiGroups: + # - "" + # resources: + # - secrets + # verbs: + # - get + +########################################################## +# Additional ConfigMaps +########################################################## +configMap: + enabled: false + additionalLabels: + # key: value + annotations: + # key: value + files: + # nameSuffix of configMap +# code-config: +# key1: value1 +# key2: value2 +# dev-config: +# key1: value1 +# key2: value2 + +########################################################## +# SealedSecrets +########################################################## +sealedSecret: + enabled: false + additionalLabels: + #key: value + annotations: + #key: value + files: +# #nameSuffix of sealedSecret +# example: +# encryptedData: +# name: AgBghrdepGMKmp/rdtJrkBv/CWpJbtmoMsbKQ7QiZZ2kUoLeeTbrDnhmJY03kWKkNW4kN/sQRf6r1vvBEaR4nkHt5f/ayAeaH3NveI3bdb0xv/svvWjyjehwqwr/kNEAVWxRoUij0Y7MyIEAr4hnV2UnrhgvcjPJLNA8bK6spA+kuT328Vpyceyvnm6yArNn1aYlEckaFHrnculHWRpG73iRYxS5GWAY7EdkLXx7OLLWoopHtLcupklYyPfraJzPvBNZ5/PsyjlUBvoQbGV3cZlrdEj1WHj2S1RQ13ddf2WGtMHmY83t9B3LFZAZuA7BBt4rjludbwQm3/tJ5Kas1dDsSIRIIF7MTeum9YfRB8XUz8IxVKQ/JDskeynrWe3VzN/3HFVnv9GGFy+BCVXZKVU/roIRancz+nXkyoOHS722ZpBi53dfLItoS5dG+0EzArMTQzK/KXHz3b1rxp5oWWDNt3WggTiSg2zwy5ZR8VV2ToTDof6UrFmbCZv/kKriyxbVSxIo3KFnvuRiUZ5MwC0TNut4mW3LKyJfHqkUuLa1mYV6tKF58qBnoj/+JaibAIBEudT9hms5U52p7/jKmgHuop7XPEsz4OVwER//Vbv7X6ctoXtyPu6mZyOfOyJHM8Qj/H7/gwMBYhZHQ96DWrVmZOsWSRpZGJni4Xm7rgt2cFj6UtWv6lvl8aOi/HSZVC3TwWZ9mQrk +# annotations: +# key: value +# labels: +# key: value +# clusterWide: true +# example2: +# encryptedData: +# name: AgBghrdepGMKmp/rdtJrkBv/CWpJbtmoMsbKQ7QiZZ2kUoLeeTbrDnhmJY03kWKkNW4kN/sQRf6r1vvBEaR4nkHt5f/ayAeaH3NveI3bdb0xv/svvWjyjehwqwr/kNEAVWxRoUij0Y7MyIEAr4hnV2UnrhgvcjPJLNA8bK6spA+kuT328Vpyceyvnm6yArNn1aYlEckaFHrnculHWRpG73iRYxS5GWAY7EdkLXx7OLLWoopHtLcupklYyPfraJzPvBNZ5/PsyjlUBvoQbGV3cZlrdEj1WHj2S1RQ13ddf2WGtMHmY83t9B3LFZAZuA7BBt4rjludbwQm3/tJ5Kas1dDsSIRIIF7MTeum9YfRB8XUz8IxVKQ/JDskeynrWe3VzN/3HFVnv9GGFy+BCVXZKVU/roIRancz+nXkyoOHS722ZpBi53dfLItoS5dG+0EzArMTQzK/KXHz3b1rxp5oWWDNt3WggTiSg2zwy5ZR8VV2ToTDof6UrFmbCZv/kKriyxbVSxIo3KFnvuRiUZ5MwC0TNut4mW3LKyJfHqkUuLa1mYV6tKF58qBnoj/+JaibAIBEudT9hms5U52p7/jKmgHuop7XPEsz4OVwER//Vbv7X6ctoXtyPu6mZyOfOyJHM8Qj/H7/gwMBYhZHQ96DWrVmZOsWSRpZGJni4Xm7rgt2cFj6UtWv6lvl8aOi/HSZVC3TwWZ9mQrk + +########################################################## +# Additional Secrets +########################################################## +secret: + enabled: false + additionalLabels: + # key: value + annotations: + # key: value + files: +# nameSuffix of Secret +# credentials: +# data: +# secretKey1: secretValue1 +# secretKey2: secretValue2 +# password: +# data: +# secretKey1: secretValue1 +# secretKey2: secretValue2 + +########################################################## +# Service Monitor to collect Prometheus metrices +########################################################## +serviceMonitor: + enabled: false + + # Additional labels + additionalLabels: + # key: value + + # Additional annotations + annotations: + # key: value + + # List of the endpoints of service from which prometheus will scrape data + endpoints: + - interval: 5s + path: /actuator/prometheus + port: http + +########################################################## +# HPA - Horizontal Pod Autoscaling +########################################################## +autoscaling: + # enabled is a boolean flag for enabling or disabling autoscaling + enabled: false + # additionalLabels defines additional labels + additionalLabels: + # key: value + # annotations defines annotations in key value pair + annotations: + # key: value + # minReplicas sets the minimum number of replicas + minReplicas: 1 + # maxReplicas sets the maximum number of replicas + maxReplicas: 10 + # metrics is the list of metrics used for hpa + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 60 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 60 + +########################################################## +# VPA - Vertical Pod Autoscaling +########################################################## +vpa: + # enabled is a boolean flag for enabling or disabling vpa + enabled: false + # additionalLabels defines additional labels + additionalLabels: + # key: value + # annotations defines annotations in key value pair + annotations: + # key: value + # container policies for individual containers. + containerPolicies: [] + +########################################################## +# EndpointMonitor for IMC +# https://github.com/stakater/IngressMonitorController +########################################################## +endpointMonitor: + enabled: false + + # Additional labels + additionalLabels: + # key: value + + # Additional annotations + annotations: + # key: value + +########################################################## +# Certficate CRD to generate the certificate +########################################################## +certificate: + enabled: false + + # Additional labels + additionalLabels: + # key: value + + # Additional annotations + annotations: + # key: value + + secretName: tls-cert + duration: 8760h0m0s # 1 year + renewBefore: 720h0m0s # 30d + subject: + # organizations: + # - stakater + # countries: + # - SE + # organizationalUnits: + # - '{{ template "application.namespace" . }}' + # localities: + # - Stockholm + # provinces: + # - Stockholm + commonName: admin-app + keyAlgorithm: rsa + keyEncoding: pkcs1 + keySize: 2048 + isCA: false + usages: + # - digital signature + # - client auth + dnsNames: + # - admin-app + ipAddresses: + # - 192.168.0.5 + uriSANs: + # - spiffe://cluster.local/ns/sandbox/sa/example + emailSANs: + # - emailSubjectAltNames + privateKey: + enabled: false + rotationPolicy: Always + issuerRef: + name: ca-issuer + # We can reference ClusterIssuers by changing the kind here. + kind: ClusterIssuer + group: #cert-manager.io + keystores: + enabled: false + pkcs12: + create: true + key: test_key + name: test-creds + jks: + create: false + key: test_key + name: test-creds + +########################################################## +# AlertmanagerConfig object for defining application +# specific alertmanager configurations +########################################################## +alertmanagerConfig: + enabled: false + + # AlertmanagerConfig selectionLabels to specify label to be picked up by Alertmanager to add it to base config. Read more about it at [https://docs.openshift.com/container-platform/4.7/rest_api/monitoring_apis/alertmanager-monitoring-coreos-com-v1.html] under .spec.alertmanagerConfigSelector + selectionLabels: + alertmanagerConfig: "workload" + + # AlertmanagerConfig spec, read details here [https://docs.openshift.com/container-platform/4.7/rest_api/monitoring_apis/alertmanagerconfig-monitoring-coreos-com-v1alpha1.html] + spec: + route: + # receiver: "null" + # groupBy: + # - job + # routes: + # - receiver: "null" + # groupBy: + # - alertname + # - severity + # continue: true + # groupWait: 30s + # groupInterval: 5m + # repeatInterval: 12h + receivers: [] + # - name: "null" + inhibitRules: [] + # - sourceMatch: + # severity: 'critical' + # targetMatch: + # severity: 'warning' + # equal: ['cluster', 'service'] + +########################################################## +# PrometheusRule object for defining application +# alerting rules +########################################################## +prometheusRule: + enabled: false + + # PrometheusRule labels + additionalLabels: + # prometheus: stakater-workload-monitoring + # role: alert-rules + + # Groups with alerting rules. Read more here [https://docs.openshift.com/container-platform/4.7/rest_api/monitoring_apis/prometheusrule-monitoring-coreos-com-v1.html] + + groups: + [] + # - name: example-app-uptime + # rules: + # - alert: ExampleAppDown + # annotations: + # message: >- + # The Example App is Down (Test Alert) + # expr: up{namespace="test-app"} == 0 + # for: 1m + # labels: + # severity: critical +########################################################## +# External Secrets +########################################################## +externalSecret: + enabled: false + + # Default SecretStore for all externalsecrets defines which SecretStore to use when fetching the secret data + secretStore: + name: tenant-vault-secret-store + #kind: ClusterSecretStore # Defaults to SecretStore if not specified + + # RefreshInterval is the amount of time before the values reading again from the SecretStore provider + refreshInterval: "1m" + files: + # mongodb: + # # Data defines the connection between the Kubernetes Secret keys and the Provider data + # data: + # mongo-password: + # remoteRef: + # key: monodb + # property: passowrd + # secretStore: + # name: secret-store-name-2 # specify if value is other than default secretstore + # labels: + # stakater.com/app: mongodb + # # + # postgres: + ## Used to fetch all properties from the Provider key + # dataFrom: + # key: postgres + +########################################################## +# Network Policy +########################################################## +networkPolicy: + enabled: false + additionalLabels: + # key: value + annotations: + # key: value + ingress: + # - from: + # - ipBlock: + # cidr: 172.17.0.0/16 + # except: + # - 172.17.1.0/24 + # - namespaceSelector: + # matchLabels: + # project: myproject + # - podSelector: + # matchLabels: + # role: frontend + # ports: + # - protocol: TCP + # port: 6379 + egress: + # - to: + # - ipBlock: + # cidr: 10.0.0.0/24 + # ports: + # - protocol: TCP + # port: 5978 + +########################################################## +# Pod disruption budget - PDB +########################################################## +pdb: + enabled: false + minAvailable: 1 +# maxUnavailable: 1 + +########################################################## +# grafanaDashboard object for defining application +# Grafana Dashboard +########################################################## +grafanaDashboard: + enabled: false + + # GrafanaDashboard additonal labels + additionalLabels: + # grafanaDashboard: grafana-operator + + # GrafanaDashboard annotations + annotations: + # key: value + + # GrafanaDashboard contents + # this includes pairs of dashboard name and associated json content + # Accoroding to GrafanaDashboard behavior, if both url and json are specified then the GrafanaDashboard content will be updated with fetched content from url + contents: + # dashboard-name-1: + # json: |- + # { + # "data" + # } + # url: http://hostname/path/to/file.json + # dashboard-name-2: + # json: |- + # { + # "data" + # } + # url: http://hostname/path/to/file.json