bjw-s / helm-charts Goto Github PK
View Code? Open in Web Editor NEWA collection of Helm charts
Home Page: https://bjw-s.github.io/helm-charts/
License: Apache License 2.0
A collection of Helm charts
Home Page: https://bjw-s.github.io/helm-charts/
License: Apache License 2.0
This is primarily a question to know ensure that the functionality is intentional and hear the reasoning, not necessarily a bug.
There's a new label and selector ( app.kubernetes.io/component
) added in the new version 2.0.1 of the chart.
The value of this is set to main
. Even if I change the name of the main container in the pod to something other than main
.
Is it intentional, that it works like this, and what is the reason?
What did you expect to happen:
I expected the value of the label / selector to be the same as the name of the main pod, but I'm no charting expert, so there is probably a reason for the functionality, that I am not aware of.
Anything else you would like to add:
No.
Additional Information:
No.
Is it possible to support for argo rollouts controller?
Argo Rollouts is a Kubernetes controller and set of CRDs which provide advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and progressive delivery features to Kubernetes.
Describe the solution you'd like:
Example:
controller:
type: rollout
rollout:
strategy:
canary:
# Reference to a Service which the controller will update to point to the canary ReplicaSet
canaryService: rollouts-demo-canary
# Reference to a Service which the controller will update to point to the stable ReplicaSet
stableService: rollouts-demo-stable
trafficRouting:
nginx:
# Reference to an Ingress which has a rule pointing to the stable service (e.g. rollouts-demo-stable)
# This ingress will be cloned with a new name, in order to achieve NGINX traffic splitting.
stableIngress: rollouts-demo-stable
Anything else you would like to add:
Additional Information:
What steps did you take and what happened:
use the app-template with the env vars:
env:
# -- Config dir
DATA_FOLDER: "config"
A_FOLDER: "sometest"
This will lead to a e.g. deployment with:
env:
- name: A_FOLDER
value: sometest
- name: DATA_FOLDER
value: config
Env var sorting breaks dependent environment variables of kubernetes.
What did you expect to happen:
Don't change the order of env vars.
Anything else you would like to add:
Additional Information:
Describe the solution you'd like:
With the Kubernetes version 1.24 you can add the service config like below:
spec.allocateLoadBalancerNodePorts: false/true
This allows the LB service to not create NodePort when the LB service is created.
The feature is now stable.
Anything else you would like to add:
Would it be possible to enable this option to be enabled when creating a LoadBalancer service Type.
https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-nodeport-allocation
Since additionalContainers
has been renamed to sidecars
support for the old key should be removed in an upcoming major version
For example i use blocky dns which gathers it configuration from data/config.yaml
I can write new configmap from chart, but i can't mount it as some path
My app has multiple independent deployments. They have separate readiness, scheduling, etc; but need to be deployed with the same image.
It'd be great to have an example of how to use the new common chart and do extra "custom" deployments sharing the base templates and configurations. In my case the deployments are all the same except the command and args.
Ideally each deployment would also have a headless service to target with a ServiceMonitor.
Is this possible to do with the new common chart, or would I be better off making separate charts and having a meta chart with the others as a dependency?
What steps did you take and what happened:
Inject a x509 certificate as stringData for a secret. I tried multiple yaml formatters but failed (|
or |-
)
secrets:
secret:
enabled: true
stringData: |-
aldfaldflaf
adfadfadf
What did you expect to happen:
That the secret just has a literal block with
stringData: |-
aldfaldflaf
adfadfadf
but instead it is rendered as
stringData:
|-
aldfaldflaf
adfadfadf
Anything else you would like to add:
Additional Information:
Describe the solution you'd like:
It might be nice to cover some usage examples using various methods of installing a app. There's only 3 methods of installation I can think of:
What steps did you take and what happened:
Tried to upgrade 1.5.1 -> 2.x, followed the values.yaml changes as best i could. Ran through argoCD to update, it fails to deploy because of an immutable field
exact error:
Deployment.apps "sonarr" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/component":"main", "app.kubernetes.io/instance":"sonarr", "app.kubernetes.io/name":"sonarr"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
1.5.1 format:
image:
repository: ghcr.io/onedr0p/sonarr-develop
pullPolicy: IfNotPresent
tag: 4.0.0.688
strategy:
type: Recreate
podSecurityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: "OnRootMismatch"
env:
TZ: America/Los_Angeles
SONARR__API_KEY:
valueFrom:
secretKeyRef:
name: sonarr-api-key
key: sonarr_api_key
service:
main:
ports:
http:
port: 8989
ingress:
main:
enabled: true
ingressClassName: traefik
hosts:
- host: server.domain.tld
paths:
- path: /
pathType: Prefix
service:
port: 8989
persistence:
config:
enabled: true
type: pvc
accessMode: ReadWriteOnce
size: 15Gi
mountPath: "/config"
media:
enabled: true
type: nfs
server: server.domain.tld
path: /mnt/sirius/media
mountPath: "/media-nfs"
backups:
enabled: true
type: nfs
server: server.domain.tld
path: /mnt/sirius/dockerdata/backups/sonarr
mountPath: "/config/Backups"
dockerdata:
enabled: true
type: nfs
server: server.domain.tld
path: /mnt/sirius/dockerdata/
mountPath: "/mnt/dockerdata"
probes:
liveness:
enabled: true
custom: true
spec:
httpGet:
path: /
port: http
resources:
requests:
cpu: 300m
memory: 768Mi
limits:
memory: 3Gi
2.x format:
defaultPodOptions:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: "OnRootMismatch"
controllers:
main:
containers:
main:
strategy:
type: Recreate
image:
repository: ghcr.io/onedr0p/sonarr-develop
pullPolicy: IfNotPresent
tag: 4.0.0.688
probes:
liveness:
enabled: true
custom: true
spec:
httpGet:
path: /
port: http
env:
TZ: America/Los_Angeles
SONARR__API_KEY:
valueFrom:
secretKeyRef:
name: sonarr-api-key
key: sonarr_api_key
resources:
requests:
cpu: 300m
memory: 768Mi
limits:
memory: 3Gi
service:
main:
ports:
http:
port: 8989
ingress:
main:
enabled: true
className: traefik
hosts:
- host: server.domain.tld
paths:
- path: /
pathType: Prefix
service:
name: main
port: 8989
persistence:
config:
enabled: true
type: persistentVolumeClaim
accessMode: ReadWriteOnce
size: 15Gi
globalMounts:
- path: "/config"
media:
enabled: true
type: nfs
server: server.domain.tld
path: /mnt/sirius/media
globalMounts:
- path: "/media-nfs"
backups:
enabled: true
type: nfs
server: server.domain.tld
path: /mnt/sirius/dockerdata/backups/sonarr
globalMounts:
- path: "/config/Backups"
dockerdata:
enabled: true
type: nfs
server: server.domain.tld
path: /mnt/sirius/dockerdata/
globalMounts:
- path: "/mnt/dockerdata"
am I missing something here? the values seem to lint fine to ArgoCD. thanks! FWIW, this is what ArgoCD shows as the deltas:
Please provide support for RBAC creation.
What steps did you take and what happened:
I was migrating to the latest version 2.0.0-beta.1 and have seen that imagePullSecrets are currently not able to be set.
i was using the following syntax
defaultPodOptions:
imagePullSecrets:
- name: my-pull-secret
but this causes the following error:
Helm upgrade failed: template: app-template/templates/common.yaml:14:3: executing "app-template/templates/common.yaml" at <include "bjw-s.common.loader.generate" .>: error calling include: template: app-template/charts/common/templates/loader/_generate.tpl:8:6: executing "bjw-s.common.loader.generate" at <include "bjw-s.common.render.controllers" .>: error calling include: template: app-template/charts/common/templates/render/_controllers.tpl:25:12: executing "bjw-s.common.render.controllers" at <include "bjw-s.common.class.deployment" (dict "rootContext" $ "object" $deploymentObject)>: error calling include: template: app-template/charts/common/templates/classes/_deployment.tpl:59:13: executing "bjw-s.common.class.deployment" at <include "bjw-s.common.lib.pod.spec" (dict "rootContext" $rootContext "controllerObject" $deploymentObject)>: error calling include: template: app-template/charts/common/templates/lib/pod/_spec.tpl:38:25: executing "bjw-s.common.lib.pod.spec" at <trim>: wrong type for value; expected string; got []interface {}
What did you expect to happen:
The image pull secret is applied to all pods
Anything else you would like to add:
Additional Information:
First off, thank you for the template, it works brilliantly.
I have written a number of values files successfully for services that are a single microservice (no external database).
In the examples, I did not see anything that uses more than one image, nor did I see a way to use multiple in the provided values file.
How would I create something like a web service with a postgresql database?
What steps did you take and what happened:
It looks like initContainers
ordering is not preserved when the values are templated out.
This gets templated out like
initContainers:
- args:
- -c
- |
/opt/guacamole/bin/initdb.sh --postgres > /migrations/init.sql
command:
- /bin/sh
envFrom:
- secretRef:
name: guacamole-secret
image: docker.io/guacamole/guacamole:1.5.0
imagePullPolicy: IfNotPresent
name: create-schema
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /migrations
name: migrations
- envFrom:
- secretRef:
name: guacamole-secret
image: ghcr.io/onedr0p/postgres-initdb:14.6
imagePullPolicy: IfNotPresent
name: init-db
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
- args:
- -c
- |
export PGPASSWORD=$(POSTGRES_PASSWORD)
psql -h $(POSTGRES_HOSTNAME) -d $(POSTGRES_DATABASE) -U $(POSTGRES_USER) -a -w -f /migrations/init.sql || true
command:
- /bin/bash
envFrom:
- secretRef:
name: guacamole-secret
image: ghcr.io/onedr0p/postgres-initdb:14.6
imagePullPolicy: IfNotPresent
name: run-migrations
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /migrations
name: migrations
It is my understanding that initContainers run in the order specified.
What steps did you take and what happened:
Deploying an app with .Values.secret
sets sets an envFrom
field in the bjw-s.common.lib.controller.mainContainer
with the release name as the secret name, but does not create a Secret
object.
Given that .Values.secret
does not appear in the main values.yaml
file, it seems like this is a holdover from k8s-at-home/common
chart. It looks like .Values.secrets
is supposed to replace this functionality.
What did you expect to happen:
Either a Secret
object is created when .Values.secret
is populated, or the envFrom:
field is removed entirely.
Anything else you would like to add:
N/A
Additional Information:
N/A
What steps did you take and what happened:
When both persistence.advancedMounts
and controllers.*.initContainers
are specified in values.yaml
, installing or
upgrading the chart (app-template) will fail with "error calling dig: interface conversion: interface {} is nil, not
string".
helm upgrade -i release-name bjw-s/app-template --version 2.0.0 -f values.yaml
controllers:
main:
containers:
main:
image:
repository: ghcr.io/mendhak/http-https-echo
tag: 30
initContainers:
a-container:
image:
repository: ghcr.io/mendhak/http-https-echo
tag: 30
service:
main:
enabled: false
persistence:
config:
enabled: true
advancedMounts:
main:
main:
- path: /data/config.yaml
readOnly: false
subPath: config.yaml
helm upgrade -i release-name bjw-s/app-template --version 2.0.0 -f values.yaml
controllers:
main:
containers:
main:
image:
repository: ghcr.io/mendhak/http-https-echo
tag: 30
# initContainers:
a-container:
image:
repository: ghcr.io/mendhak/http-https-echo
tag: 30
service:
main:
enabled: false
persistence:
config:
enabled: true
advancedMounts:
main:
main:
- path: /data/config.yaml
readOnly: false
subPath: config.yaml
Error: UPGRADE FAILED: template: app-template/templates/common.yaml:14:3: executing "app-template/templates/common.yaml" at <include "bjw-s.common.loader.generate" .>:
error calling include: template: app-template/charts/common/templates/loader/_generate.tpl:8:6: executing "bjw-s.common.loader.generate" at <include "bjw-s.common.render.controllers" .>:
error calling include: template: app-template/charts/common/templates/render/_controllers.tpl:25:12: executing "bjw-s.common.render.controllers" at <include "bjw-s.common.class.deployment" (dict "rootContext" $ "object" $deploymentObject)>:
error calling include: template: app-template/charts/common/templates/classes/_deployment.tpl:59:13: executing "bjw-s.common.class.deployment" at <include "bjw-s.common.lib.pod.spec" (dict "rootContext" $rootContext "controllerObject" $deploymentObject)>:
error calling include: template: app-template/charts/common/templates/lib/pod/_spec.tpl:58:12: executing "bjw-s.common.lib.pod.spec" at <include "bjw-s.common.lib.pod.field.initContainers" (dict "ctx" $ctx)>:
error calling include: template: app-template/charts/common/templates/lib/pod/fields/_initContainers.tpl:28:32: executing "bjw-s.common.lib.pod.field.initContainers" at <include "bjw-s.common.lib.container.spec" (dict "rootContext" $rootContext "containerObject" $containerObject)>:
error calling include: template: app-template/charts/common/templates/lib/container/_spec.tpl:48:12: executing "bjw-s.common.lib.container.spec" at <include "bjw-s.common.lib.container.field.volumeMounts" (dict "ctx" $ctx)>:
error calling include: template: app-template/charts/common/templates/lib/container/fields/_volumeMounts.tpl:38:33: executing "bjw-s.common.lib.container.field.volumeMounts" at <dig $controllerObject.identifier $containerObject.identifier list .advancedMounts>:
error calling dig: interface conversion: interface {} is nil, not string
(Examples are a reduced version of advanced-values.yaml)
What did you expect to happen:
The chart should install successfully, with the volumeMounts rendered as expected for both main and init containers (or
ignored completely, if advancedMounts
was not designed to include init containers).
Anything else you would like to add:
Additional Information:
I noticed that controllers.*.initContainers.*.volumeMounts
is no longer applied (as in v1.5.1), and that
persistence.globalMounts
applies to init containers. Does this imply that persistence.advancedMounts
was intended to
also apply to init containers?
What steps did you take and what happened:
I've tried to use your template to deploy a factorio server - which doesn't have any http endpoints (or a service called 'http' for that matter')
I've found that when service.main.ports.http
is not set, the template will render it in the service as an empty ports, and thus failing the validation done by kubernetes.
Helm debugging showed the service being rendered as this:
# Source: app-template/templates/common.yaml
apiVersion: v1
kind: Service
metadata:
name: factorio
labels:
app.kubernetes.io/service: factorio
app.kubernetes.io/instance: factorio
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: factorio
helm.sh/chart: app-template-1.3.2
annotations:
spec:
type: ClusterIP
ports:
- port: 34197
targetPort: 34197
protocol: UDP
name: game
- port:
targetPort: http
protocol: TCP
name: http
- port: 27015
targetPort: 27015
protocol: TCP
name: steam
selector:
app.kubernetes.io/instance: factorio
app.kubernetes.io/name: factorio
---
When setting service.main.ports.http.enabled
explicitly to false
the problem disappears.
However, when someone isn't aware of this mechanic kubernetes will only throw the
spec.ports[1].port: Invalid value: 0: must be between 1 and 65535, inclusive
making it very ambiguous to debug.
This issue happens because the template's init file makes a deepcopy reference to values.yaml which contains the defined http
service with a non-defined port.
I could dive deeper into this, haven't really done much with writing helm templates before.
Basically my first guess would be to check whether the user has defined addtional services other then the default 'http' service and to omit the 'default' service if that's the case.
I hope this helps!
Kind regards,
Sem
Describe the solution you'd like:
This seems to be the way forward
Currently there is support for both list-based and map-based entries for sidecars
and initContainers
. Merging lists is a pain, so I want to remove support for list-based entries in an upcoming major version.
Describe the solution you'd like:
I have recently started migrating some less used deployments to Knative, which can scale to 0 until an ingress request occurs.
To deploy these "serverless" containers, Knative uses its own Service CRD which is basically a combination of a standard Deployment, Service, and Ingress. They have a good example and comparison at Converting a Kubernetes Deployment to a Knative Service.
I would like to implement a new controller type for for this, but want to check first to see if there's any sort of desire for this and if a PR would be accepted. Knative obviously doesn't ship with Kubernetes so I don't want to confuse users of the common library.
Anything else you would like to add:
It would be nice if the common library could create a Knative service with a new controller type called something like knative-service
.
This may be complicated to implement since it would affect how services and ingresses are created, but it has been frustrating to completely scrap Helm when I migrate a site.
Additional Information:
I really enjoy using the common library chart. Thank you for everything that you do!
What steps did you take and what happened:
I tried to deploy the example app based on the template provided (which specifies the ingress's backend service port
as the strings http
and websockets
, rather than a number).
But I get the error:
cannot unmarshal string into Go struct field ServiceBackendPort.spec.rules.http.paths.backend.service.port.number of type int32
What did you expect to happen:
I expected the example template to work out of the box. Additionally, the examples themselves made me think I would be able to specify the ingress' backend service ports via their service port name, rather than just a numbered port.
Anything else you would like to add:
The Ingress resources' ServiceBackenPort allows for either a number
or name
property. So, it could be possible to support this usage if we wanted
Side question: I am noticing that there is little-to-no reference/examples in the main Kubernetes documentation to using the service port name
as reference... is it's usage really uncommon and/or discouraged for some reason I am unaware of?
Additional Information:
I'd be happy to help with a PR, but would first look for guidance on your preferred solution. Example:
name
references (ex: using kindIs or an explicit portName
property)Is there anyway we can specify matchLabels for deployments/statefulsets/daemonsets?
I think the only thing i saw that might make this possible for ds
(in my case) is to set topology constraints?
Cheers,
I tried to use the new common library-chart to continue using the uptime-kuma chart from k8s-at-home, but apparently the new common library-chart evolved and is no longer a drop-in replacement.
Is there any documentation on how to convert an existing chart from the old k8s-at-home library-chart to the new one?
Using the following config on Kubernetes 1.25 does not adhere to the changes made to ServiceAccounts in 1.25
values:
serviceAccount:
create: true
name: *app
In 1.25 we need to define the Secret and link it to the SA:
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault-auth
secrets:
- name: vault-auth
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: vault-auth
annotations:
kubernetes.io/service-account.name: vault-auth
I would like the common chart to be able to support prometheusRule
, which goes nicely with the existing serviceMonitor
.
Example:
# -- Enable and configure Prometheus Rules for the chart under this key.
prometheusRule:
enabled: true
labels: {}
# -- Configure additionial rules for the chart under this key.
rules:
- alert: SonarrDown
annotations:
description: Sonarr service is down.
summary: Sonarr is down.
expr: |
sonarr_system_status == 0
for: 5m
labels:
severity: critical
Anything else you would like to add:
Additional Information:
I've looked all over but can't find a release notes file for the 2.0 release, is it somewhere I'm missing?
Describe the solution you'd like:
A proper CI needs to be put in place to automatically (re)build the custom Typescript actions
Anything else you would like to add:
Additional Information:
Describe the solution you'd like:
An additional field that would allow you to add Finalizers to resources.
Anything else you would like to add:
Sorry if you can already do this and I have missed it!
I am happy to make a PR to try and do it but would be good to know where you think it would be best to go.
Required to put quotes around the tag since it wasn't in the form a.b.c
What did you expect to happen:
I would expect a tag to work without quotes. Is it a semver comparison issue?
Hi there. I have adopted some of the k8s-at-home charts so I can continue to maintain them, in k8s-at-home/charts#1762
It was suggested to me to clone this repo and benefit from the CI on my own repo of charts. I've got most of it working but some of the steps seem to need a GitHub application. I haven't used one of these before, do you have any notes about how you set this up? What permissions etc.
It would be super useful to me, and probably to anyone else who wants to rehome a kah chart. Thanks
Currently there's a property nameOverride:
under ingress:
, where you can override the suffix used for an Ingress' name, see: https://github.com/bjw-s/helm-charts/blob/main/charts/library/common/values.yaml
We would like to be able to add a prefix instead, unless there's a specific reason, this is a bad idea?
Our case is that we have the same service in multiple namespaces in our test environment, and we would like the ingress names to be prefixed with the namespace name.
Anything else you would like to add:
No.
Additional Information:
No.
Describe the solution you'd like:
We currently have to set this option to override app-template
from being in the labels.
global:
nameOverride: *app
Maybe we can default this to {{.Release.Name}}
somehow so it doesn't need to be set on all HelmRelease
?
Describe the solution you'd like:
Vector would be much nicer to have over promtail since it supports a lot more options and sinks
Describe the solution you'd like:
Some applications from k8s-at-home
like radarr
had additional resources beyond what the common chart provided. It would be useful to be able to specify extra resources like this directly in the values for app-templates.
The bedag/raw chart provides a good model for doing this. The values .Values.resources
and .Values.templates
are provided as arrays of kubernetes resource objects that are rendered into the helm chart, with templates rendered with the tpl
function.
Because resources
is already a reserved value in the top level of app-template
, I propose .Values.extraManifests
and .Values.extraManifestTemplates
(though if anyone wants to propose something better, go for it).
Additional Information:
Links:
https://github.com/bedag/helm-charts/tree/master/charts/raw
https://artifacthub.io/packages/helm/main/raw
The bedag/raw
template is licensed under Apache-2.0
Saw that the app-template can create a cron-job resource, so I gave it a try and it didn't get a few things.
values.yaml
controller:
type: cronjob
cronjob:
schedule: "@daily"
ttlSecondsAfterFinished: 43200
restartPolicy: OnFailure
image:
repository: docker.io/prodrigestivill/postgres-backup-local
tag: 15@sha256:93f597a7ad95d5a9d988e57c32442e6f78d6e88d809ca96bb0a3270e45c85650
pullPolicy: IfNotPresent
command: ["/backup.sh"]
env:
- name: POSTGRES_HOST
value: postgres-ro.dbms.svc.cluster.local
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-superuser
key: POSTGRES_SUPER_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-superuser
key: POSTGRES_SUPER_PASS
- name: POSTGRES_DB
value: "outline,shlink,teslamate"
- name: BACKUP_KEEP_DAYS
value: "7"
- name: BACKUP_KEEP_WEEKS
value: "4"
- name: BACKUP_KEEP_MONTHS
value: "6"
- name: BACKUP_KEEP_MINS
value: "1440"
- name: POSTGRES_EXTRA_OPTS
value: "-b -C -Z6"
enableServiceLinks: false
service:
main:
enabled: false
persistence:
backups:
enabled: true
existingClaim: postgres-backups
mountPath: /backups
podSecurityContext:
runAsUser: 568
runAsGroup: 568
fsGroup: 568
fsGroupChangePolicy: "OnRootMismatch"
output.yaml
---
# Source: app-template/templates/common.yaml
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: postgres-backup
labels:
app.kubernetes.io/instance: postgres-backup
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: postgres-backup
helm.sh/chart: app-template-1.2.1
spec:
concurrencyPolicy: "Forbid"
startingDeadlineSeconds: 30
schedule: "@daily"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
ttlSecondsAfterFinished: 43200
template:
metadata:
labels:
app.kubernetes.io/name: postgres-backup
app.kubernetes.io/instance: postgres-backup
spec:
serviceAccountName: default
automountServiceAccountToken: true
securityContext:
fsGroup: 568
fsGroupChangePolicy: OnRootMismatch
runAsGroup: 568
runAsUser: 568
dnsPolicy: ClusterFirst
enableServiceLinks: false
containers:
- name: postgres-backup
image: "docker.io/prodrigestivill/postgres-backup-local:15@sha256:93f597a7ad95d5a9d988e57c32442e6f78d6e88d809ca96bb0a3270e45c85650"
imagePullPolicy: IfNotPresent
command:
- /backup.sh
env:
- name: POSTGRES_HOST
value: postgres-ro.dbms.svc.cluster.local
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
key: POSTGRES_SUPER_USER
name: postgres-superuser
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: POSTGRES_SUPER_PASS
name: postgres-superuser
- name: POSTGRES_DB
value: outline,shlink,teslamate
- name: BACKUP_KEEP_DAYS
value: "7"
- name: BACKUP_KEEP_WEEKS
value: "4"
- name: BACKUP_KEEP_MONTHS
value: "6"
- name: BACKUP_KEEP_MINS
value: "1440"
- name: POSTGRES_EXTRA_OPTS
value: -b -C -Z6
ports:
volumeMounts:
- name: backups
mountPath: /backups
livenessProbe:
readinessProbe:
startupProbe:
volumes:
- name: backups
persistentVolumeClaim:
claimName: postgres-backups
restartPolicy: Never
command:
helm template postgres-backup -n dbms bjw-s/app-template -f values.yaml > output.yaml
What did you expect to happen:
The ports:
entry shouldn't be present because there aren't any ports.
As well, the livenessProbe, readinessProbe, and startupProbe are specified but don't have any defaults. (or shouldn't be there)
Anything else you would like to add:
Not sure if this is a desired use of the template at all, but it did work for recyclarr (from Devin of course)
Additional Information:
This is primarily a question to know ensure that the change below was intentional and hear the reasoning, not necessarily a bug.
I upgraded my Helm chart from using version 1.5.1 to 2.0.1 and compared the rendered result.
Previously I automatically got a ports
property under the main container in the rendered result, like this:
spec:
...
containers:
- name: ...
...
ports:
- name: http
containerPort: 8080
protocol: TCP
... in the new version I have to add it myself manually in my values-file, like this:
controllers:
main:
containers:
main:
...
ports:
- containerPort: 8080
name: http
protocol: TCP
... otherwise it is not rendered. Was this change on purpose, and what is the reason?
What did you expect to happen:
I expected the new version to render the same as the old version for ports
, but I'm no charting expert, so there is probably a reason for the change, that I am not aware of.
Anything else you would like to add:
No.
Additional Information:
No.
Describe the solution you'd like:
An option to enable a pre-upgrade
helm hook that is able to snapshot the config PVC via a Kubernetes Job with the external-snapshotter.
For example this job would get ran before helm upgrade:
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}"
labels:
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "1"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
template:
metadata:
name: "{{ .Release.Name }}"
labels:
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
spec:
restartPolicy: Never
containers:
- name: snapshot-volume
image: "bjw-s/snapshotter:1.0.0"
command: ["run","snapshot"]
Maybe it could be enabled via a new option with an array of volumes for the Job to be ran for:
values:
snapshotHooks:
- volume: config
- volume: test
Or, included in persistence and volumeClaimTemplates blocks:
values:
persistence:
config:
enabled: true
existingClaim: config
snapshotBeforeUpgrade: true
values:
volumeClaimTemplates:
- name: config
mountPath: /config
accessMode: ReadWriteOnce
size: 10Gi
storageClass: ceph-block
snapshotBeforeUpgrade: true
labels:
snapshot.home.arpa/enabled: "true"
Having something like this would make reverting back to a previous version of an application with the matching data volume given you change your PVC to the snapshot taken via dataSource
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc-1
spec:
# ...
dataSource:
name: snapshot-name
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
Few areas of concern I have are:
Capabilities
via helmLine 17 in bfc48a7
This repo contains Helm charts that I have developed to run applications in my home Kubernetes cluster.
Isn't this only containing the library chart? Or are there other charts that I just failed to find? :-)
Describe the solution you'd like:
I could not find a way to add fully fledged networkpolicies (ingress/egress) to my workload.
Anything else you would like to add:
I found a way to deploy egress network policies by "hacking" them into the vpn addon, unfortunately it is only possible to add egress policies.
addons:
vpn:
enabled: true
type: ""
networkPolicy:
enabled: true
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
This config allowed me to get egress network policies, but unfortunately no ingress
Additional Information:
I would be interested in implementing this feature. Thank you for this great helm chart ๐ฅณ๐
I think this might be a small QoL improvement. Since this is already under the ingress key, we don't need to prefix this field with ingress
I am not sure if this is covered anywhere, but is there a way to have the ingress
block create an IngressRouteUDP/IngressRouteTCP for traefik?
receiving an error expected map[string]interface {}; got bool in library/common/templates/lib/container/_ports.tpl. Upon closer inspection of the code, it appears that {{- $serviceEnabled = $service.enabled -}} on line 9 is missing :=
Another thing I noticed is that $serviceEnabled is being set to true on line 7, so that would make that cast as a bool twice.
I don't use helm very often, especially on such detailed library so I could be mistaken here.
What steps did you take and what happened:
I am using the xbvr helm chart which relies on this library as a submodule.
I am passing in the following in to .values in terraform
` set {
name = "service.enabled"
value = "true"
}
set {
name = "service.type"
value = "loadBalancer"
}
set {
name = "service.loadBalancerIP"
value = "${var.loadBalancerIP}"
}
`
What did you expect to happen:
I expected the flags set to configure to metallb with a fixed ip address and enable the service
Anything else you would like to add:
Here is the full error that I have received:
โ Error: template: xbvr/templates/common.yaml:1:4: executing "xbvr/templates/common.yaml" at <include "bjw-s.common.loader.all" .>: error calling include: template: xbvr/charts/common/templates/loader/_all.tpl:9:6: executing "bjw-s.common.loader.all" at <include "bjw-s.common.loader.generate" .>: error calling include: template: xbvr/charts/common/templates/loader/_generate.tpl:23:6: executing "bjw-s.common.loader.generate" at <include "bjw-s.common.render.controller" .>: error calling include: template: xbvr/charts/common/templates/render/_controller.tpl:7:10: executing "bjw-s.common.render.controller" at <include "bjw-s.common.class.deployment" .>: error calling include: template: xbvr/charts/common/templates/classes/_deployment.tpl:54:10: executing "bjw-s.common.class.deployment" at <include "bjw-s.common.lib.controller.pod" .>: error calling include: template: xbvr/charts/common/templates/lib/controller/_pod.tpl:70:6: executing "bjw-s.common.lib.controller.pod" at <include "bjw-s.common.lib.controller.mainContainer" .>: error calling include: template: xbvr/charts/common/templates/lib/controller/_mainContainer.tpl:45:12: executing "bjw-s.common.lib.controller.mainContainer" at <include "bjw-s.common.lib.container.ports" .>: error calling include: template: xbvr/charts/common/templates/lib/container/_ports.tpl:8:18: executing "bjw-s.common.lib.container.ports" at <$service>: wrong type for value; expected map[string]interface {}; got bool
When using the code server add-on in app-template, the defaultMode is specified as 256 and perhaps should actually be 100 (hex vs decimal?)
addons:
codeserver:
enabled: true
image:
repository: codercom/code-server
tag: 4.7.0
workingDir: "/config"
git:
deployKeySecret: home-assistant-code-server
root@home-assistant-7647895d87-j8jvn:~/.ssh# ls -l
total 4
-r--r----- 1 root coder 3434 Sep 12 01:04 id_rsa
What steps did you take and what happened:
What did you expect to happen:
Permissions should just be u+r
Anything else you would like to add:
Additional Information:
Describe the solution you'd like:
Hi! It would be very handy to not only mount pvc, emptyDir, hostPath and nfs
within the persistence
section but also ceph
.
As of the docs it does not need a lot of configuration expect the monitors
on which the ceph-storage is running.
At the end, it would be nice to configure it in the values.yaml
as the following:
persistence:
cephfs-config:
enabled: true
type: cephfs
monitors:
- mon.rook.svc.cluster.local:6790
- mon.rook.svc.cluster.local:6789
path: /registryFS
secretRef:
name: rook-rbd-user
Anything else you would like to add:
If there is no intention to add this, I can create a PR and try to implement it. I am relatively new to k8s, helm and everything but would put in the effort to create the PR properly.
Thanks in advance!
Describe the solution you'd like:
IMO this is a much nicer name, but would be a breaking change.
Describe the solution you'd like:
I frequently would like to add an additionalContainer (webserver, etc) to a deployment, but it's not clear to me how the additionalContainer objects map. If I wanted to define an additional container image/tag, environmental variables, attach secrets/configmaps, and include a service, how can I define all that in the additionalContainers object? Do some things (i.e., services(?) get defined with the main image?
An example would go a long way to helping sort this out.
Anything else you would like to add:
Chart is incredibly useful -- thank you!
Describe the solution you'd like:
Using the library chart with applications that export metrics requires the user to write a separate serviceMonitor
manifests.
Add basic support for embedding a serviceMonitor
in the library chart
For example:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: &app cloudflare-exporter
namespace: monitoring
spec:
interval: 15m
chart:
spec:
chart: kah-common-chart
version: 1.2.2
sourceRef:
kind: HelmRepository
name: k8s-at-home-charts
namespace: flux-system
interval: 15m
install:
createNamespace: true
remediation:
retries: 5
upgrade:
remediation:
retries: 5
values:
global:
nameOverride: *app
controller:
strategy: RollingUpdate
image:
repository: ghcr.io/lablabs/cloudflare_exporter
tag: 0.0.13
env:
FREE_TIER: "true"
envFrom:
- secretRef:
name: *app
service:
main:
ports:
http:
port: 8080
# Full Options for Service Monitor
serviceMonitor:
enabled: true
endpoints:
- port: http
path: /metrics
interval: 1m
scrapeTimeout: 10s
Open to any thoughts on this, maybe we pass the full spec
thru to the serviceMonitor
omitting the spec.selector
which can be auto populated?
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: &app cloudflare-exporter
namespace: monitoring
labels: &labels
app.kubernetes.io/instance: *app
app.kubernetes.io/name: *app
spec:
selector:
matchLabels:
<<: *labels
endpoints:
- port: http
scheme: http
path: /metrics
interval: 1m
scrapeTimeout: 10s
Request that the VPN addon (That was there in v1.5.5) be added in v2 as well
Anything else you would like to add:
The add-ons were a great functionality that was included in v1.5.1
Would really appreciate it if it could be made available in the latest version as well.
Since Helm version 3 you can use JSON schema files to validate Helm values as stated on the docs: https://helm.sh/docs/topics/charts/#schema-files
This values.schema.json
can be used by different helm
commands to validate the values.yml
, also could be used by the yaml language server of your editor to validate the changes as you make them.
I've tried to create a schema usin https://codebeautify.org using a simple HelmRelease
file and pasting the contents of values.yaml inside the values
field, wich generates the following JSON schema:
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$ref": "#/definitions/Welcome9",
"definitions": {
"Welcome9": {
"type": "object",
"additionalProperties": false,
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"$ref": "#/definitions/Metadata"
},
"spec": {
"$ref": "#/definitions/Welcome9Spec"
}
},
"required": [
"apiVersion",
"kind",
"metadata",
"spec"
],
"title": "Welcome9"
},
"Metadata": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"namespace": {
"type": "string"
}
},
"required": [
"name",
"namespace"
],
"title": "Metadata"
},
"Welcome9Spec": {
"type": "object",
"additionalProperties": false,
"properties": {
"interval": {
"type": "string"
},
"chart": {
"$ref": "#/definitions/Chart"
},
"install": {
"$ref": "#/definitions/Install"
},
"upgrade": {
"$ref": "#/definitions/Upgrade"
},
"values": {
"$ref": "#/definitions/Values"
}
},
"required": [
"chart",
"install",
"interval",
"upgrade",
"values"
],
"title": "Welcome9Spec"
},
"Chart": {
"type": "object",
"additionalProperties": false,
"properties": {
"spec": {
"$ref": "#/definitions/ChartSpec"
}
},
"required": [
"spec"
],
"title": "Chart"
},
"ChartSpec": {
"type": "object",
"additionalProperties": false,
"properties": {
"chart": {
"type": "string"
},
"version": {
"type": "string"
},
"sourceRef": {
"$ref": "#/definitions/SourceRef"
},
"interval": {
"type": "string"
}
},
"required": [
"chart",
"interval",
"sourceRef",
"version"
],
"title": "ChartSpec"
},
"SourceRef": {
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"type": "string"
},
"name": {
"type": "string"
},
"namespace": {
"type": "string"
}
},
"required": [
"kind",
"name",
"namespace"
],
"title": "SourceRef"
},
"Install": {
"type": "object",
"additionalProperties": false,
"properties": {
"createNamespace": {
"type": "boolean"
},
"remediation": {
"$ref": "#/definitions/Remediation"
}
},
"required": [
"createNamespace",
"remediation"
],
"title": "Install"
},
"Remediation": {
"type": "object",
"additionalProperties": false,
"properties": {
"retries": {
"type": "integer"
}
},
"required": [
"retries"
],
"title": "Remediation"
},
"Upgrade": {
"type": "object",
"additionalProperties": false,
"properties": {
"remediation": {
"$ref": "#/definitions/Remediation"
}
},
"required": [
"remediation"
],
"title": "Upgrade"
},
"Values": {
"type": "object",
"additionalProperties": false,
"properties": {
"global": {
"$ref": "#/definitions/Global"
},
"controller": {
"$ref": "#/definitions/Controller"
},
"image": {
"$ref": "#/definitions/Image"
},
"imagePullSecrets": {
"type": "array",
"items": {}
},
"command": {
"type": "array",
"items": {}
},
"args": {
"type": "array",
"items": {}
},
"podAnnotations": {
"$ref": "#/definitions/Affinity"
},
"podLabels": {
"$ref": "#/definitions/Affinity"
},
"serviceAccount": {
"$ref": "#/definitions/ServiceAccount"
},
"automountServiceAccountToken": {
"type": "boolean"
},
"secrets": {
"$ref": "#/definitions/Secrets"
},
"configMaps": {
"$ref": "#/definitions/ConfigMaps"
},
"env": {
"type": "null"
},
"envFrom": {
"type": "array",
"items": {}
},
"priorityClassName": {
"type": "null"
},
"runtimeClassName": {
"type": "null"
},
"schedulerName": {
"type": "null"
},
"hostname": {
"type": "null"
},
"hostNetwork": {
"type": "boolean"
},
"dnsPolicy": {
"type": "null"
},
"dnsConfig": {
"$ref": "#/definitions/Affinity"
},
"enableServiceLinks": {
"type": "boolean"
},
"podSecurityContext": {
"$ref": "#/definitions/Affinity"
},
"securityContext": {
"$ref": "#/definitions/Affinity"
},
"lifecycle": {
"$ref": "#/definitions/Affinity"
},
"initContainers": {
"$ref": "#/definitions/Affinity"
},
"sidecars": {
"$ref": "#/definitions/Affinity"
},
"probes": {
"$ref": "#/definitions/Probes"
},
"termination": {
"$ref": "#/definitions/Termination"
},
"service": {
"$ref": "#/definitions/ValuesService"
},
"serviceMonitor": {
"$ref": "#/definitions/ServiceMonitor"
},
"ingress": {
"$ref": "#/definitions/ValuesIngress"
},
"route": {
"$ref": "#/definitions/Route"
},
"persistence": {
"$ref": "#/definitions/Persistence"
},
"volumeClaimTemplates": {
"type": "array",
"items": {}
},
"nodeSelector": {
"$ref": "#/definitions/Affinity"
},
"affinity": {
"$ref": "#/definitions/Affinity"
},
"topologySpreadConstraints": {
"type": "array",
"items": {}
},
"tolerations": {
"type": "array",
"items": {}
},
"hostAliases": {
"type": "array",
"items": {}
},
"resources": {
"$ref": "#/definitions/Affinity"
},
"addons": {
"$ref": "#/definitions/Addons"
}
},
"required": [
"addons",
"affinity",
"args",
"automountServiceAccountToken",
"command",
"configMaps",
"controller",
"dnsConfig",
"dnsPolicy",
"enableServiceLinks",
"env",
"envFrom",
"global",
"hostAliases",
"hostNetwork",
"hostname",
"image",
"imagePullSecrets",
"ingress",
"initContainers",
"lifecycle",
"nodeSelector",
"persistence",
"podAnnotations",
"podLabels",
"podSecurityContext",
"priorityClassName",
"probes",
"resources",
"route",
"runtimeClassName",
"schedulerName",
"secrets",
"securityContext",
"service",
"serviceAccount",
"serviceMonitor",
"sidecars",
"termination",
"tolerations",
"topologySpreadConstraints",
"volumeClaimTemplates"
],
"title": "Values"
},
"Addons": {
"type": "object",
"additionalProperties": false,
"properties": {
"vpn": {
"$ref": "#/definitions/VPN"
},
"codeserver": {
"$ref": "#/definitions/AddonsCodeserver"
},
"netshoot": {
"$ref": "#/definitions/Netshoot"
}
},
"required": [
"codeserver",
"netshoot",
"vpn"
],
"title": "Addons"
},
"AddonsCodeserver": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"image": {
"$ref": "#/definitions/Image"
},
"env": {
"$ref": "#/definitions/Affinity"
},
"args": {
"type": "array",
"items": {
"type": "string"
}
},
"volumeMounts": {
"type": "array",
"items": {}
},
"workingDir": {
"type": "string"
},
"git": {
"$ref": "#/definitions/Git"
},
"service": {
"$ref": "#/definitions/CodeserverService"
},
"ingress": {
"$ref": "#/definitions/CodeserverIngress"
},
"securityContext": {
"$ref": "#/definitions/CodeserverSecurityContext"
}
},
"required": [
"args",
"enabled",
"env",
"git",
"image",
"ingress",
"securityContext",
"service",
"volumeMounts",
"workingDir"
],
"title": "AddonsCodeserver"
},
"Affinity": {
"type": "object",
"additionalProperties": false,
"title": "Affinity"
},
"Git": {
"type": "object",
"additionalProperties": false,
"properties": {
"deployKey": {
"type": "string"
},
"deployKeyBase64": {
"type": "string"
},
"deployKeySecret": {
"type": "string"
}
},
"required": [
"deployKey",
"deployKeyBase64",
"deployKeySecret"
],
"title": "Git"
},
"Image": {
"type": "object",
"additionalProperties": false,
"properties": {
"repository": {
"anyOf": [
{
"type": "null"
},
{
"type": "string"
}
]
},
"tag": {
"anyOf": [
{
"type": "null"
},
{
"type": "string"
}
]
},
"pullPolicy": {
"anyOf": [
{
"type": "null"
},
{
"type": "string"
}
]
}
},
"required": [
"pullPolicy",
"repository",
"tag"
],
"title": "Image"
},
"CodeserverIngress": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"ingressClassName": {
"type": "null"
},
"hosts": {
"type": "array",
"items": {
"$ref": "#/definitions/IngressHost"
}
},
"tls": {
"type": "array",
"items": {}
}
},
"required": [
"annotations",
"enabled",
"hosts",
"ingressClassName",
"labels",
"tls"
],
"title": "CodeserverIngress"
},
"IngressHost": {
"type": "object",
"additionalProperties": false,
"properties": {
"host": {
"type": "string"
},
"paths": {
"type": "array",
"items": {
"$ref": "#/definitions/PurplePath"
}
}
},
"required": [
"host",
"paths"
],
"title": "IngressHost"
},
"PurplePath": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"pathType": {
"type": "string"
}
},
"required": [
"path",
"pathType"
],
"title": "PurplePath"
},
"CodeserverSecurityContext": {
"type": "object",
"additionalProperties": false,
"properties": {
"runAsUser": {
"type": "integer"
}
},
"required": [
"runAsUser"
],
"title": "CodeserverSecurityContext"
},
"CodeserverService": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"type": {
"type": "string"
},
"ports": {
"$ref": "#/definitions/ServicePorts"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"labels": {
"$ref": "#/definitions/Affinity"
}
},
"required": [
"annotations",
"enabled",
"labels",
"ports",
"type"
],
"title": "CodeserverService"
},
"ServicePorts": {
"type": "object",
"additionalProperties": false,
"properties": {
"codeserver": {
"$ref": "#/definitions/PortsCodeserver"
}
},
"required": [
"codeserver"
],
"title": "ServicePorts"
},
"PortsCodeserver": {
"type": "object",
"additionalProperties": false,
"properties": {
"port": {
"type": "integer"
},
"enabled": {
"type": "boolean"
},
"protocol": {
"type": "string"
},
"targetPort": {
"type": "integer"
}
},
"required": [
"enabled",
"port",
"protocol",
"targetPort"
],
"title": "PortsCodeserver"
},
"Netshoot": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"image": {
"$ref": "#/definitions/Image"
},
"env": {
"$ref": "#/definitions/Affinity"
},
"securityContext": {
"$ref": "#/definitions/NetshootSecurityContext"
}
},
"required": [
"enabled",
"env",
"image",
"securityContext"
],
"title": "Netshoot"
},
"NetshootSecurityContext": {
"type": "object",
"additionalProperties": false,
"properties": {
"capabilities": {
"$ref": "#/definitions/Capabilities"
}
},
"required": [
"capabilities"
],
"title": "NetshootSecurityContext"
},
"Capabilities": {
"type": "object",
"additionalProperties": false,
"properties": {
"add": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"add"
],
"title": "Capabilities"
},
"VPN": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"type": {
"type": "string"
},
"gluetun": {
"$ref": "#/definitions/Gluetun"
},
"securityContext": {
"$ref": "#/definitions/NetshootSecurityContext"
},
"env": {
"$ref": "#/definitions/Affinity"
},
"args": {
"type": "array",
"items": {}
},
"configFile": {
"type": "null"
},
"configFileSecret": {
"type": "null"
},
"scripts": {
"$ref": "#/definitions/Scripts"
},
"additionalVolumeMounts": {
"type": "array",
"items": {}
},
"livenessProbe": {
"$ref": "#/definitions/Affinity"
},
"networkPolicy": {
"$ref": "#/definitions/NetworkPolicy"
}
},
"required": [
"additionalVolumeMounts",
"args",
"configFile",
"configFileSecret",
"enabled",
"env",
"gluetun",
"livenessProbe",
"networkPolicy",
"scripts",
"securityContext",
"type"
],
"title": "VPN"
},
"Gluetun": {
"type": "object",
"additionalProperties": false,
"properties": {
"image": {
"$ref": "#/definitions/Image"
}
},
"required": [
"image"
],
"title": "Gluetun"
},
"NetworkPolicy": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"podSelectorLabels": {
"$ref": "#/definitions/Affinity"
},
"egress": {
"type": "null"
}
},
"required": [
"annotations",
"egress",
"enabled",
"labels",
"podSelectorLabels"
],
"title": "NetworkPolicy"
},
"Scripts": {
"type": "object",
"additionalProperties": false,
"properties": {
"up": {
"type": "null"
},
"down": {
"type": "null"
}
},
"required": [
"down",
"up"
],
"title": "Scripts"
},
"ConfigMaps": {
"type": "object",
"additionalProperties": false,
"properties": {
"config": {
"$ref": "#/definitions/SecretClass"
}
},
"required": [
"config"
],
"title": "ConfigMaps"
},
"SecretClass": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"data": {
"$ref": "#/definitions/Affinity"
},
"stringData": {
"$ref": "#/definitions/Affinity"
}
},
"required": [
"annotations",
"enabled",
"labels"
],
"title": "SecretClass"
},
"Controller": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"type": {
"type": "string"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"replicas": {
"type": "integer"
},
"strategy": {
"type": "null"
},
"rollingUpdate": {
"$ref": "#/definitions/RollingUpdate"
},
"revisionHistoryLimit": {
"type": "integer"
},
"podManagementPolicy": {
"type": "null"
},
"restartPolicy": {
"type": "null"
},
"cronjob": {
"$ref": "#/definitions/Cronjob"
}
},
"required": [
"annotations",
"cronjob",
"enabled",
"labels",
"podManagementPolicy",
"replicas",
"restartPolicy",
"revisionHistoryLimit",
"rollingUpdate",
"strategy",
"type"
],
"title": "Controller"
},
"Cronjob": {
"type": "object",
"additionalProperties": false,
"properties": {
"concurrencyPolicy": {
"type": "string"
},
"schedule": {
"type": "string"
},
"startingDeadlineSeconds": {
"type": "integer"
},
"successfulJobsHistory": {
"type": "integer"
},
"failedJobsHistory": {
"type": "integer"
},
"ttlSecondsAfterFinished": {
"type": "null"
}
},
"required": [
"concurrencyPolicy",
"failedJobsHistory",
"schedule",
"startingDeadlineSeconds",
"successfulJobsHistory",
"ttlSecondsAfterFinished"
],
"title": "Cronjob"
},
"RollingUpdate": {
"type": "object",
"additionalProperties": false,
"properties": {
"unavailable": {
"type": "null"
},
"surge": {
"type": "null"
},
"partition": {
"type": "null"
}
},
"required": [
"partition",
"surge",
"unavailable"
],
"title": "RollingUpdate"
},
"Global": {
"type": "object",
"additionalProperties": false,
"properties": {
"nameOverride": {
"type": "null"
},
"fullnameOverride": {
"type": "null"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"annotations": {
"$ref": "#/definitions/Affinity"
}
},
"required": [
"annotations",
"fullnameOverride",
"labels",
"nameOverride"
],
"title": "Global"
},
"ValuesIngress": {
"type": "object",
"additionalProperties": false,
"properties": {
"main": {
"$ref": "#/definitions/IngressMain"
}
},
"required": [
"main"
],
"title": "ValuesIngress"
},
"IngressMain": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"primary": {
"type": "boolean"
},
"nameOverride": {
"type": "null"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"ingressClassName": {
"type": "null"
},
"hosts": {
"type": "array",
"items": {
"$ref": "#/definitions/MainHost"
}
},
"tls": {
"type": "array",
"items": {}
}
},
"required": [
"annotations",
"enabled",
"hosts",
"ingressClassName",
"labels",
"nameOverride",
"primary",
"tls"
],
"title": "IngressMain"
},
"MainHost": {
"type": "object",
"additionalProperties": false,
"properties": {
"host": {
"type": "string"
},
"paths": {
"type": "array",
"items": {
"$ref": "#/definitions/FluffyPath"
}
}
},
"required": [
"host",
"paths"
],
"title": "MainHost"
},
"FluffyPath": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
},
"pathType": {
"type": "string"
},
"service": {
"$ref": "#/definitions/PathService"
}
},
"required": [
"path",
"pathType",
"service"
],
"title": "FluffyPath"
},
"PathService": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "null"
},
"port": {
"type": "null"
}
},
"required": [
"name",
"port"
],
"title": "PathService"
},
"Persistence": {
"type": "object",
"additionalProperties": false,
"properties": {
"config": {
"$ref": "#/definitions/PersistenceConfig"
},
"shared": {
"$ref": "#/definitions/Shared"
}
},
"required": [
"config",
"shared"
],
"title": "Persistence"
},
"PersistenceConfig": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"type": {
"type": "string"
},
"mountPath": {
"type": "null"
},
"readOnly": {
"type": "boolean"
},
"nameOverride": {
"type": "null"
},
"storageClass": {
"type": "null"
},
"existingClaim": {
"type": "null"
},
"subPath": {
"type": "null"
},
"accessMode": {
"type": "string"
},
"size": {
"type": "string"
},
"retain": {
"type": "boolean"
}
},
"required": [
"accessMode",
"enabled",
"existingClaim",
"mountPath",
"nameOverride",
"readOnly",
"retain",
"size",
"storageClass",
"subPath",
"type"
],
"title": "PersistenceConfig"
},
"Shared": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"type": {
"type": "string"
},
"mountPath": {
"type": "string"
},
"medium": {
"type": "null"
},
"sizeLimit": {
"type": "null"
}
},
"required": [
"enabled",
"medium",
"mountPath",
"sizeLimit",
"type"
],
"title": "Shared"
},
"Probes": {
"type": "object",
"additionalProperties": false,
"properties": {
"liveness": {
"$ref": "#/definitions/Liveness"
},
"readiness": {
"$ref": "#/definitions/Liveness"
},
"startup": {
"$ref": "#/definitions/Liveness"
}
},
"required": [
"liveness",
"readiness",
"startup"
],
"title": "Probes"
},
"Liveness": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"custom": {
"type": "boolean"
},
"type": {
"type": "string"
},
"spec": {
"$ref": "#/definitions/LivenessSpec"
}
},
"required": [
"custom",
"enabled",
"spec",
"type"
],
"title": "Liveness"
},
"LivenessSpec": {
"type": "object",
"additionalProperties": false,
"properties": {
"initialDelaySeconds": {
"type": "integer"
},
"periodSeconds": {
"type": "integer"
},
"timeoutSeconds": {
"type": "integer"
},
"failureThreshold": {
"type": "integer"
}
},
"required": [
"failureThreshold",
"initialDelaySeconds",
"periodSeconds",
"timeoutSeconds"
],
"title": "LivenessSpec"
},
"Route": {
"type": "object",
"additionalProperties": false,
"properties": {
"main": {
"$ref": "#/definitions/RouteMain"
}
},
"required": [
"main"
],
"title": "Route"
},
"RouteMain": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"kind": {
"type": "string"
},
"nameOverride": {
"type": "null"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"parentRefs": {
"type": "array",
"items": {
"$ref": "#/definitions/ParentRef"
}
},
"hostnames": {
"type": "array",
"items": {}
},
"rules": {
"type": "array",
"items": {
"$ref": "#/definitions/Rule"
}
}
},
"required": [
"annotations",
"enabled",
"hostnames",
"kind",
"labels",
"nameOverride",
"parentRefs",
"rules"
],
"title": "RouteMain"
},
"ParentRef": {
"type": "object",
"additionalProperties": false,
"properties": {
"group": {
"type": "string"
},
"kind": {
"type": "string"
},
"name": {
"type": "null"
},
"namespace": {
"type": "null"
},
"sectionName": {
"type": "null"
}
},
"required": [
"group",
"kind",
"name",
"namespace",
"sectionName"
],
"title": "ParentRef"
},
"Rule": {
"type": "object",
"additionalProperties": false,
"properties": {
"backendRefs": {
"type": "array",
"items": {
"$ref": "#/definitions/BackendRef"
}
},
"matches": {
"type": "array",
"items": {
"$ref": "#/definitions/Match"
}
}
},
"required": [
"backendRefs",
"matches"
],
"title": "Rule"
},
"BackendRef": {
"type": "object",
"additionalProperties": false,
"properties": {
"group": {
"type": "string"
},
"kind": {
"type": "string"
},
"name": {
"type": "null"
},
"namespace": {
"type": "null"
},
"port": {
"type": "null"
},
"weight": {
"type": "integer"
}
},
"required": [
"group",
"kind",
"name",
"namespace",
"port",
"weight"
],
"title": "BackendRef"
},
"Match": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"$ref": "#/definitions/MatchPath"
}
},
"required": [
"path"
],
"title": "Match"
},
"MatchPath": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"type",
"value"
],
"title": "MatchPath"
},
"Secrets": {
"type": "object",
"additionalProperties": false,
"properties": {
"secret": {
"$ref": "#/definitions/SecretClass"
}
},
"required": [
"secret"
],
"title": "Secrets"
},
"ValuesService": {
"type": "object",
"additionalProperties": false,
"properties": {
"main": {
"$ref": "#/definitions/ServiceMain"
}
},
"required": [
"main"
],
"title": "ValuesService"
},
"ServiceMain": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"primary": {
"type": "boolean"
},
"nameOverride": {
"type": "null"
},
"type": {
"type": "string"
},
"externalTrafficPolicy": {
"type": "null"
},
"ipFamilyPolicy": {
"type": "null"
},
"ipFamilies": {
"type": "array",
"items": {}
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"ports": {
"$ref": "#/definitions/MainPorts"
}
},
"required": [
"annotations",
"enabled",
"externalTrafficPolicy",
"ipFamilies",
"ipFamilyPolicy",
"labels",
"nameOverride",
"ports",
"primary",
"type"
],
"title": "ServiceMain"
},
"MainPorts": {
"type": "object",
"additionalProperties": false,
"properties": {
"http": {
"$ref": "#/definitions/HTTP"
}
},
"required": [
"http"
],
"title": "MainPorts"
},
"HTTP": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"primary": {
"type": "boolean"
},
"port": {
"type": "null"
},
"protocol": {
"type": "string"
},
"targetPort": {
"type": "null"
},
"nodePort": {
"type": "null"
},
"extraSelectorLabels": {
"$ref": "#/definitions/Affinity"
}
},
"required": [
"enabled",
"extraSelectorLabels",
"nodePort",
"port",
"primary",
"protocol",
"targetPort"
],
"title": "HTTP"
},
"ServiceAccount": {
"type": "object",
"additionalProperties": false,
"properties": {
"create": {
"type": "boolean"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"name": {
"type": "string"
}
},
"required": [
"annotations",
"create",
"name"
],
"title": "ServiceAccount"
},
"ServiceMonitor": {
"type": "object",
"additionalProperties": false,
"properties": {
"main": {
"$ref": "#/definitions/ServiceMonitorMain"
}
},
"required": [
"main"
],
"title": "ServiceMonitor"
},
"ServiceMonitorMain": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"nameOverride": {
"type": "null"
},
"annotations": {
"$ref": "#/definitions/Affinity"
},
"labels": {
"$ref": "#/definitions/Affinity"
},
"selector": {
"$ref": "#/definitions/Affinity"
},
"serviceName": {
"type": "string"
},
"endpoints": {
"type": "array",
"items": {
"$ref": "#/definitions/Endpoint"
}
}
},
"required": [
"annotations",
"enabled",
"endpoints",
"labels",
"nameOverride",
"selector",
"serviceName"
],
"title": "ServiceMonitorMain"
},
"Endpoint": {
"type": "object",
"additionalProperties": false,
"properties": {
"port": {
"type": "string"
},
"scheme": {
"type": "string"
},
"path": {
"type": "string"
},
"interval": {
"type": "string"
},
"scrapeTimeout": {
"type": "string"
}
},
"required": [
"interval",
"path",
"port",
"scheme",
"scrapeTimeout"
],
"title": "Endpoint"
},
"Termination": {
"type": "object",
"additionalProperties": false,
"properties": {
"messagePath": {
"type": "null"
},
"messagePolicy": {
"type": "null"
},
"gracePeriodSeconds": {
"type": "null"
}
},
"required": [
"gracePeriodSeconds",
"messagePath",
"messagePolicy"
],
"title": "Termination"
}
}
}
This is not perfect as the values of each property aren't specified but is better than nothing as seen in the screenshot:
I think that having this schema generated as part of the chart will make upgrades easier
Describe the solution you'd like:
I was wondering if it would make sense to support additionalLabels similarly to see this: https://github.com/stefanprodan/podinfo/blob/fdd0a0b7dad56fbc6bb71e7e8badee5a3a3c663f/charts/podinfo/templates/servicemonitor.yaml#L8
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.