From 68bb9c95d8ca8e3db7f3e7454b2572d5cfa73e24 Mon Sep 17 00:00:00 2001 From: Hans Knecht Date: Wed, 11 Feb 2026 14:58:07 +0000 Subject: [PATCH 1/5] feat(chart): provision a helm chart that matches currently generated kustomize objects --- chart/node-readiness-controller/.helmignore | 23 ++ chart/node-readiness-controller/Chart.yaml | 24 ++ chart/node-readiness-controller/README.md | 41 ++ .../node-readiness-controller/crds/crds.yaml | 382 ++++++++++++++++++ .../templates/NOTES.txt | 35 ++ .../templates/_helpers.tpl | 81 ++++ .../templates/deployment.yaml | 90 +++++ .../templates/rbac.yaml | 251 ++++++++++++ .../templates/serviceaccount.yaml | 13 + .../values.schema.json | 175 ++++++++ chart/node-readiness-controller/values.yaml | 127 ++++++ 11 files changed, 1242 insertions(+) create mode 100644 chart/node-readiness-controller/.helmignore create mode 100644 chart/node-readiness-controller/Chart.yaml create mode 100644 chart/node-readiness-controller/README.md create mode 100644 chart/node-readiness-controller/crds/crds.yaml create mode 100644 chart/node-readiness-controller/templates/NOTES.txt create mode 100644 chart/node-readiness-controller/templates/_helpers.tpl create mode 100644 chart/node-readiness-controller/templates/deployment.yaml create mode 100644 chart/node-readiness-controller/templates/rbac.yaml create mode 100644 chart/node-readiness-controller/templates/serviceaccount.yaml create mode 100644 chart/node-readiness-controller/values.schema.json create mode 100644 chart/node-readiness-controller/values.yaml diff --git a/chart/node-readiness-controller/.helmignore b/chart/node-readiness-controller/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/chart/node-readiness-controller/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/chart/node-readiness-controller/Chart.yaml b/chart/node-readiness-controller/Chart.yaml new file mode 100644 index 0000000..e68fa38 --- /dev/null +++ b/chart/node-readiness-controller/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: node-readiness-controller +description: A Helm chart for Kubernetes + +# 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 + +# 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 + +# 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" diff --git a/chart/node-readiness-controller/README.md b/chart/node-readiness-controller/README.md new file mode 100644 index 0000000..39d29d2 --- /dev/null +++ b/chart/node-readiness-controller/README.md @@ -0,0 +1,41 @@ +# node-readiness-controller + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.16.0](https://img.shields.io/badge/AppVersion-1.16.0-informational?style=flat-square) + +A Helm chart for Kubernetes + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | This is for setting the affinity for the controller. More information can be found here: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity | +| enableWebhook | bool | `false` | Enables the validating webhook for the controller. More information can be found here: https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/ | +| extraArgs | list | `[]` | This is for setting extra arguments to the controller | +| fullnameOverride | string | `""` | This is to override the full name of the resources created by this chart. More information can be found here: https://helm.sh/docs/chart_template_guide/naming_conventions/#full-name-override | +| healthCheckPort | int | `8081` | This is for setting the health check port for the controller. More information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ | +| image | object | `{"pullPolicy":"IfNotPresent","repository":"controller","tag":""}` | This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ | +| image.pullPolicy | string | `"IfNotPresent"` | This sets the pull policy for images. | +| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | +| imagePullSecrets | list | `[]` | This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | +| livenessProbe | object | `{"httpGet":{"initialDelaySeconds":15,"path":"/healthz","periodSeconds":20,"port":"http"}}` | This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ | +| nameOverride | string | `""` | This is to override the chart name. | +| nodeSelector | object | `{}` | This is for setting the node selector for the controller. More information can be found here: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector | +| podAnnotations | object | `{}` | This is for setting Kubernetes Annotations to a Pod. For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ | +| podLabels | object | `{}` | This is for setting Kubernetes Labels to a Pod. For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ | +| podSecurityContext | object | `{"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | This is for setting the security context for the pod. Set to a reasonable default. More information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ | +| priorityClassName | string | `"system-cluster-critical"` | This is for setting the priority class name for the controller. More information can be found here: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ | +| rbac | object | `{"create":true}` | Configures Roles, ClusterRoles, RoleBindings and ClusterRoleBindings required for node-readiness-controller to operate. | +| rbac.create | bool | `true` | Specifies whether RBAC resources should be created. | +| readinessProbe | object | `{"httpGet":{"initialDelaySeconds":5,"path":"/healthz","periodSeconds":10,"port":"http"}}` | This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ | +| replicaCount | int | `1` | This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ | +| resources | object | `{}` | This is for setting the resource requests and limits for the container. A reeasonable default is commented out for guidance. More information can be found here: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | +| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true}` | This is for setting the security context for the container. Set to a reasonable default. More information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ | +| serviceAccount | object | `{"annotations":{},"automount":true,"create":true,"name":""}` | This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account. | +| serviceAccount.automount | bool | `true` | Automatically mount a ServiceAccount's API credentials? | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created. | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. | +| tolerations | list | `[]` | This is for setting the tolerations for the controller. More information can be found here: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#concepts | +| volumeMounts | list | `[]` | Additional volumeMounts on the output Deployment definition. | +| volumes | list | `[]` | Additional volumes on the output Deployment definition. | + diff --git a/chart/node-readiness-controller/crds/crds.yaml b/chart/node-readiness-controller/crds/crds.yaml new file mode 100644 index 0000000..0ccf52a --- /dev/null +++ b/chart/node-readiness-controller/crds/crds.yaml @@ -0,0 +1,382 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: nodereadinessrules.readiness.node.x-k8s.io +spec: + group: readiness.node.x-k8s.io + names: + kind: NodeReadinessRule + listKind: NodeReadinessRuleList + plural: nodereadinessrules + shortNames: + - nrr + singular: nodereadinessrule + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Continuous, Bootstrap or Dryrun - shows if the rule is in enforcement + or dryrun mode. + jsonPath: .spec.enforcementMode + name: Mode + type: string + - description: The readiness taint applied by this rule. + jsonPath: .spec.taint.key + name: Taint + type: string + - description: The age of this resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeReadinessRule is the Schema for the NodeReadinessRules API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of NodeReadinessRule + properties: + conditions: + description: |- + conditions contains a list of the Node conditions that defines the specific + criteria that must be met for taints to be managed on the target Node. + The presence or status of these conditions directly triggers the application or removal of Node taints. + items: + description: |- + ConditionRequirement defines a specific Node condition and the status value + required to trigger the controller's action. + properties: + requiredStatus: + description: requiredStatus is status of the condition, one + of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of Node condition + + Following kubebuilder validation is referred from https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Condition + maxLength: 316 + minLength: 1 + type: string + required: + - requiredStatus + - type + type: object + maxItems: 32 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + dryRun: + description: |- + dryRun when set to true, The controller will evaluate Node conditions and log intended taint modifications + without persisting changes to the cluster. Proposed actions are reflected in the resource status. + type: boolean + enforcementMode: + description: |- + enforcementMode specifies how the controller maintains the desired state. + enforcementMode is one of bootstrap-only, continuous. + "bootstrap-only" applies the configuration once during initial setup. + "continuous" ensures the state is monitored and corrected throughout the resource lifecycle. + enum: + - bootstrap-only + - continuous + type: string + nodeSelector: + description: nodeSelector limits the scope of this rule to a specific + subset of Nodes. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + taint: + description: |- + taint defines the specific Taint (Key, Value, and Effect) to be managed + on Nodes that meet the defined condition criteria. + properties: + effect: + description: |- + Required. The effect of the taint on pods + that do not tolerate the taint. + Valid effects are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Required. The taint key to be applied to a node. + type: string + timeAdded: + description: TimeAdded represents the time at which the taint + was added. + format: date-time + type: string + value: + description: The taint value corresponding to the taint key. + type: string + required: + - effect + - key + type: object + required: + - conditions + - enforcementMode + - nodeSelector + - taint + type: object + status: + description: status defines the observed state of NodeReadinessRule + minProperties: 1 + properties: + appliedNodes: + description: |- + appliedNodes lists the names of Nodes where the taint has been successfully managed. + This provides a quick reference to the scope of impact for this rule. + items: + maxLength: 253 + type: string + maxItems: 5000 + type: array + x-kubernetes-list-type: set + dryRunResults: + description: |- + dryRunResults captures the outcome of the rule evaluation when DryRun is enabled. + This field provides visibility into the actions the controller would have taken, + allowing users to preview taint changes before they are committed. + minProperties: 1 + properties: + affectedNodes: + description: affectedNodes is the total count of Nodes that match + the rule's criteria. + format: int32 + minimum: 0 + type: integer + riskyOperations: + description: |- + riskyOperations represents the count of Nodes where required conditions + are missing entirely, potentially indicating an ambiguous node state. + format: int32 + minimum: 0 + type: integer + summary: + description: |- + summary provides a human-readable overview of the dry run evaluation, + highlighting key findings or warnings. + maxLength: 4096 + minLength: 1 + type: string + taintsToAdd: + description: taintsToAdd is the number of Nodes that currently + lack the specified taint and would have it applied. + format: int32 + minimum: 0 + type: integer + taintsToRemove: + description: |- + taintsToRemove is the number of Nodes that currently possess the + taint but no longer meet the criteria, leading to its removal. + format: int32 + minimum: 0 + type: integer + required: + - summary + type: object + failedNodes: + description: |- + failedNodes lists the Nodes where the rule evaluation encountered an error. + This is used for troubleshooting configuration issues, such as invalid selectors during node lookup. + items: + description: NodeFailure provides diagnostic details for Nodes that + could not be successfully evaluated by the rule. + properties: + lastEvaluationTime: + description: lastEvaluationTime is the timestamp of the last + rule check failed for this Node. + format: date-time + type: string + message: + description: message is a human-readable message indicating + details about the evaluation. + maxLength: 10240 + minLength: 1 + type: string + nodeName: + description: |- + nodeName is the name of the failed Node. + + Following kubebuilder validation is referred from + https://github.com/kubernetes/apimachinery/blob/84d740c9e27f3ccc94c8bc4d13f1b17f60f7080b/pkg/util/validation/validation.go#L198 + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + reason: + description: reason provides a brief explanation of the evaluation + result. + maxLength: 256 + minLength: 1 + type: string + required: + - lastEvaluationTime + - nodeName + type: object + maxItems: 5000 + type: array + x-kubernetes-list-map-keys: + - nodeName + x-kubernetes-list-type: map + nodeEvaluations: + description: |- + nodeEvaluations provides detailed insight into the rule's assessment for individual Nodes. + This is primarily used for auditing and debugging why specific Nodes were or + were not targeted by the rule. + items: + description: NodeEvaluation provides a detailed audit of a single + Node's compliance with the rule. + properties: + conditionResults: + description: |- + conditionResults provides a detailed breakdown of each condition evaluation + for this Node. This allows for granular auditing of which specific + criteria passed or failed during the rule assessment. + items: + description: |- + ConditionEvaluationResult provides a detailed report of the comparison between + the Node's observed condition and the rule's requirement. + properties: + currentStatus: + description: currentStatus is the actual status value + observed on the Node, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + requiredStatus: + description: requiredStatus is the status value defined + in the rule that must be matched, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type corresponds to the Node condition type + being evaluated. + maxLength: 316 + minLength: 1 + type: string + required: + - currentStatus + - requiredStatus + - type + type: object + maxItems: 5000 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + lastEvaluationTime: + description: lastEvaluationTime is the timestamp when the controller + last assessed this Node. + format: date-time + type: string + nodeName: + description: nodeName is the name of the evaluated Node. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + taintStatus: + description: taintStatus represents the taint status on the + Node, one of Present, Absent. + enum: + - Present + - Absent + type: string + required: + - conditionResults + - lastEvaluationTime + - nodeName + - taintStatus + type: object + maxItems: 5000 + type: array + x-kubernetes-list-map-keys: + - nodeName + x-kubernetes-list-type: map + observedGeneration: + description: observedGeneration reflects the generation of the most + recently observed NodeReadinessRule by the controller. + format: int64 + minimum: 1 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/chart/node-readiness-controller/templates/NOTES.txt b/chart/node-readiness-controller/templates/NOTES.txt new file mode 100644 index 0000000..32d7742 --- /dev/null +++ b/chart/node-readiness-controller/templates/NOTES.txt @@ -0,0 +1,35 @@ +1. Get the application URL by running these commands: +{{- if .Values.httpRoute.enabled }} +{{- if .Values.httpRoute.hostnames }} + export APP_HOSTNAME={{ .Values.httpRoute.hostnames | first }} +{{- else }} + export APP_HOSTNAME=$(kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o jsonpath="{.spec.listeners[0].hostname}") + {{- end }} +{{- if and .Values.httpRoute.rules (first .Values.httpRoute.rules).matches (first (first .Values.httpRoute.rules).matches).path.value }} + echo "Visit http://$APP_HOSTNAME{{ (first (first .Values.httpRoute.rules).matches).path.value }} to use your application" + + NOTE: Your HTTPRoute depends on the listener configuration of your gateway and your HTTPRoute rules. + The rules can be set for path, method, header and query parameters. + You can check the gateway configuration with 'kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o yaml' +{{- end }} +{{- else if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "node-readiness-controller.fullname" . }}) + 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" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "node-readiness-controller.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "node-readiness-controller.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "node-readiness-controller.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 }} diff --git a/chart/node-readiness-controller/templates/_helpers.tpl b/chart/node-readiness-controller/templates/_helpers.tpl new file mode 100644 index 0000000..8ca8a0d --- /dev/null +++ b/chart/node-readiness-controller/templates/_helpers.tpl @@ -0,0 +1,81 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "node-readiness-controller.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "node-readiness-controller.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create a default short name for the application. +We truncate at 32 chars because some Kubernetes name fields are limited to this 63 characters (by the DNS naming spec) +and we add 29 characters maximum via a suffix for rbac +If release name contains chart name it will be used as a full name. +*/}} +{{- define "node-readiness-controller.shortname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 32 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 32 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 32 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "node-readiness-controller.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "node-readiness-controller.labels" -}} +helm.sh/chart: {{ include "node-readiness-controller.chart" . }} +{{ include "node-readiness-controller.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "node-readiness-controller.selectorLabels" -}} +app.kubernetes.io/name: {{ include "node-readiness-controller.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "node-readiness-controller.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "node-readiness-controller.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/chart/node-readiness-controller/templates/deployment.yaml b/chart/node-readiness-controller/templates/deployment.yaml new file mode 100644 index 0000000..e2dc3f3 --- /dev/null +++ b/chart/node-readiness-controller/templates/deployment.yaml @@ -0,0 +1,90 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "node-readiness-controller.fullname" . }} + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "node-readiness-controller.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "node-readiness-controller.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "node-readiness-controller.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: manager + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - --leader-elect + - --health-probe-bind-address=:{{ .Values.healthCheckPort }} + - --enable-webhook={{ .Values.enableWebhook }} + {{- with .Values.extraArgs }} + {{- range . }} + - {{ . }} + {{- end }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.controller.healthCheckPort }} + protocol: TCP + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/chart/node-readiness-controller/templates/rbac.yaml b/chart/node-readiness-controller/templates/rbac.yaml new file mode 100644 index 0000000..e2713d2 --- /dev/null +++ b/chart/node-readiness-controller/templates/rbac.yaml @@ -0,0 +1,251 @@ +{{- if .Values.rbac.create -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-leader-election-role + namespace: {{ .Release.Namespace }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +... +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-manager-role +rules: +- apiGroups: + - "" + resources: + - nodes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - nodes/finalizers + verbs: + - update +- apiGroups: + - "" + resources: + - nodes/status + verbs: + - get + - patch + - update +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules/finalizers + verbs: + - update +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules/status + verbs: + - get + - patch + - update +... +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-metrics-auth-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +... +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-nodereadinessrule-admin-role +rules: +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules + verbs: + - '*' +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-nodereadinessrule-editor-role +rules: +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-nodereadinessrule-viewer-role +rules: +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules + verbs: + - get + - list + - watch +- apiGroups: + - readiness.node.x-k8s.io + resources: + - nodereadinessrules/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-leader-election-rolebinding + namespace: {{ include "node-readiness-controller.shortname" . }}-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "node-readiness-controller.shortname" . }}-leader-election-role +subjects: +- kind: ServiceAccount + name: {{ include "node-readiness-controller.shortname" . }}-controller-manager + namespace: {{ include "node-readiness-controller.shortname" . }}-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "node-readiness-controller.shortname" . }}-manager-role +subjects: +- kind: ServiceAccount + name: {{ include "node-readiness-controller.shortname" . }}-controller-manager + namespace: {{ include "node-readiness-controller.shortname" . }}-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + name: {{ include "node-readiness-controller.shortname" . }}-metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "node-readiness-controller.shortname" . }}-metrics-auth-role +subjects: +- kind: ServiceAccount + name: {{ include "node-readiness-controller.shortname" . }}-controller-manager + namespace: {{ include "node-readiness-controller.shortname" . }}-system +{{- end }} \ No newline at end of file diff --git a/chart/node-readiness-controller/templates/serviceaccount.yaml b/chart/node-readiness-controller/templates/serviceaccount.yaml new file mode 100644 index 0000000..b64682d --- /dev/null +++ b/chart/node-readiness-controller/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "node-readiness-controller.serviceAccountName" . }} + labels: + {{- include "node-readiness-controller.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/chart/node-readiness-controller/values.schema.json b/chart/node-readiness-controller/values.schema.json new file mode 100644 index 0000000..35836df --- /dev/null +++ b/chart/node-readiness-controller/values.schema.json @@ -0,0 +1,175 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "affinity": { + "type": "object" + }, + "enableWebhook": { + "type": "boolean" + }, + "extraArgs": { + "type": "array" + }, + "fullnameOverride": { + "type": "string" + }, + "healthCheckPort": { + "type": "integer" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "imagePullSecrets": { + "type": "array" + }, + "livenessProbe": { + "type": "object", + "properties": { + "httpGet": { + "type": "object", + "properties": { + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "string" + } + } + } + } + }, + "nameOverride": { + "type": "string" + }, + "nodeSelector": { + "type": "object" + }, + "podAnnotations": { + "type": "object" + }, + "podLabels": { + "type": "object" + }, + "podSecurityContext": { + "type": "object", + "properties": { + "runAsNonRoot": { + "type": "boolean" + }, + "seccompProfile": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + } + } + } + }, + "priorityClassName": { + "type": "string" + }, + "rbac": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "httpGet": { + "type": "object", + "properties": { + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "string" + } + } + } + } + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "securityContext": { + "type": "object", + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "readOnlyRootFilesystem": { + "type": "boolean" + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "automount": { + "type": "boolean" + }, + "create": { + "type": "boolean" + }, + "name": { + "type": "string" + } + } + }, + "tolerations": { + "type": "array" + }, + "volumeMounts": { + "type": "array" + }, + "volumes": { + "type": "array" + } + } +} diff --git a/chart/node-readiness-controller/values.yaml b/chart/node-readiness-controller/values.yaml new file mode 100644 index 0000000..8f977c4 --- /dev/null +++ b/chart/node-readiness-controller/values.yaml @@ -0,0 +1,127 @@ +# Default values for node-readiness-controller. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# replicaCount -- This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# image -- This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + # image.repository + repository: controller + # image.pullPolicy -- This sets the pull policy for images. + pullPolicy: IfNotPresent + # image.tag -- Overrides the image tag whose default is the chart appVersion. + tag: "" + +# imagePullSecrets -- This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] + +# nameOverride -- This is to override the chart name. +nameOverride: "" + +# fullnameOverride -- This is to override the full name of the resources created by this chart. More information can be found here: https://helm.sh/docs/chart_template_guide/naming_conventions/#full-name-override +fullnameOverride: "" + +# enableWebhook -- Enables the validating webhook for the controller. More information can be found here: https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/ +enableWebhook: false + +# healthCheckPort -- This is for setting the health check port for the controller. More information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +healthCheckPort: 8081 + +# extraArgs -- This is for setting extra arguments to the controller +extraArgs: [] + +# priorityClassName -- This is for setting the priority class name for the controller. More information can be found here: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ +priorityClassName: system-cluster-critical + +# serviceAccount -- This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # serviceAccount.create -- Specifies whether a service account should be created. + create: true + # serviceAccount.automount -- Automatically mount a ServiceAccount's API credentials? + automount: true + # serviceAccount.annotations -- Annotations to add to the service account. + annotations: {} + # serviceAccount.name -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" + +# rbac -- Configures Roles, ClusterRoles, RoleBindings and ClusterRoleBindings required for node-readiness-controller to operate. +rbac: + # rbac.create -- Specifies whether RBAC resources should be created. + create: true + +# podAnnotations -- This is for setting Kubernetes Annotations to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} + +# podLabels -- This is for setting Kubernetes Labels to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +# podSecurityContext -- This is for setting the security context for the pod. Set to a reasonable default. More information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + +# securityContext -- This is for setting the security context for the container. Set to a reasonable default. More information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + + +# resources -- This is for setting the resource requests and limits for the container. A reeasonable default is commented out for guidance. More information can be found here: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +resources: {} + # limits: + # cpu: 500m + # memory: 128Mi + # requests: + # cpu: 10m + # memory: 64Mi + +# livenessProbe -- This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +livenessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 15 + periodSeconds: 20 + +# readinessProbe -- This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +readinessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + + +# volumes -- Additional volumes on the output Deployment definition. +volumes: [] + # - name: foo + # secret: + # secretName: mysecret + # optional: false + +# volumeMounts -- Additional volumeMounts on the output Deployment definition. +volumeMounts: [] + # - name: foo + # mountPath: "/etc/foo" + # readOnly: true + +# nodeSelector -- This is for setting the node selector for the controller. More information can be found here: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector +nodeSelector: {} + # node-role.kubernetes.io/control-plane: "" + +# tolerations -- This is for setting the tolerations for the controller. More information can be found here: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#concepts +tolerations: [] + # - key: node-role.kubernetes.io/control-plane + # operator: Exists + +# affinity -- This is for setting the affinity for the controller. More information can be found here: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity +affinity: {} From 67be682f3ce2be3017b748c2a2e3e7ba231bc4b8 Mon Sep 17 00:00:00 2001 From: Hans Knecht Date: Wed, 11 Feb 2026 14:58:45 +0000 Subject: [PATCH 2/5] feat(gha): add a helm docs workflow to prompt for readme generation feat(gha): add a helm schema gen workflow to prompt for values generation --- .github/workflows/helm-docs.yaml | 24 ++++++++++++++++++++++++ .github/workflows/helm-schema-gen.yaml | 21 +++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 .github/workflows/helm-docs.yaml create mode 100644 .github/workflows/helm-schema-gen.yaml diff --git a/.github/workflows/helm-docs.yaml b/.github/workflows/helm-docs.yaml new file mode 100644 index 0000000..9ac416c --- /dev/null +++ b/.github/workflows/helm-docs.yaml @@ -0,0 +1,24 @@ +name: Generate Helm documentation +on: + pull_request: + paths: + - 'chart/**' +jobs: + generate: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.event.pull_request.head.ref }} + token: ${{ secrets.GITHUB_TOKEN }} + - name: Run helm-docs + uses: losisin/helm-docs-github-action@v1 + with: + fail-on-diff: true + version: v1.14.2 + # git-push-user-name: "github-actions[bot]" + # git-push-user-email: "github-actions[bot]@users.noreply.github.com" diff --git a/.github/workflows/helm-schema-gen.yaml b/.github/workflows/helm-schema-gen.yaml new file mode 100644 index 0000000..23b7b4e --- /dev/null +++ b/.github/workflows/helm-schema-gen.yaml @@ -0,0 +1,21 @@ +name: Generate values schema json +on: + pull_request: + paths: + - 'chart/**' +jobs: + generate: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.ref }} + - name: Generate values schema json + uses: losisin/helm-values-schema-json-action@v2 + with: + values: chart/node-readiness-controller/values.yaml + output: chart/node-readiness-controller/values.schema.json + fail-on-diff: true From c0e7c1803dfd93d242a7f60bcf204800b9690125 Mon Sep 17 00:00:00 2001 From: Hans Knecht Date: Wed, 11 Feb 2026 15:17:29 +0000 Subject: [PATCH 3/5] fix: tempalting --- .../templates/NOTES.txt | 35 ------------------- .../templates/deployment.yaml | 4 +-- 2 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 chart/node-readiness-controller/templates/NOTES.txt diff --git a/chart/node-readiness-controller/templates/NOTES.txt b/chart/node-readiness-controller/templates/NOTES.txt deleted file mode 100644 index 32d7742..0000000 --- a/chart/node-readiness-controller/templates/NOTES.txt +++ /dev/null @@ -1,35 +0,0 @@ -1. Get the application URL by running these commands: -{{- if .Values.httpRoute.enabled }} -{{- if .Values.httpRoute.hostnames }} - export APP_HOSTNAME={{ .Values.httpRoute.hostnames | first }} -{{- else }} - export APP_HOSTNAME=$(kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o jsonpath="{.spec.listeners[0].hostname}") - {{- end }} -{{- if and .Values.httpRoute.rules (first .Values.httpRoute.rules).matches (first (first .Values.httpRoute.rules).matches).path.value }} - echo "Visit http://$APP_HOSTNAME{{ (first (first .Values.httpRoute.rules).matches).path.value }} to use your application" - - NOTE: Your HTTPRoute depends on the listener configuration of your gateway and your HTTPRoute rules. - The rules can be set for path, method, header and query parameters. - You can check the gateway configuration with 'kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o yaml' -{{- end }} -{{- else if .Values.ingress.enabled }} -{{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "node-readiness-controller.fullname" . }}) - 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" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "node-readiness-controller.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "node-readiness-controller.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "node-readiness-controller.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 }} diff --git a/chart/node-readiness-controller/templates/deployment.yaml b/chart/node-readiness-controller/templates/deployment.yaml index e2dc3f3..3de6736 100644 --- a/chart/node-readiness-controller/templates/deployment.yaml +++ b/chart/node-readiness-controller/templates/deployment.yaml @@ -5,9 +5,7 @@ metadata: labels: {{- include "node-readiness-controller.labels" . | nindent 4 }} spec: - {{- if not .Values.autoscaling.enabled }} replicas: {{ .Values.replicaCount }} - {{- end }} selector: matchLabels: {{- include "node-readiness-controller.selectorLabels" . | nindent 6 }} @@ -51,7 +49,7 @@ spec: {{- end }} ports: - name: http - containerPort: {{ .Values.controller.healthCheckPort }} + containerPort: {{ .Values.healthCheckPort }} protocol: TCP {{- with .Values.livenessProbe }} livenessProbe: From bf6b98a6ed364ae5f5cd46097832e73b622a0828 Mon Sep 17 00:00:00 2001 From: Hans Knecht Date: Wed, 11 Feb 2026 15:36:06 +0000 Subject: [PATCH 4/5] fix: indenting --- chart/node-readiness-controller/README.md | 4 ++-- .../templates/rbac.yaml | 8 +++---- .../values.schema.json | 24 +++++++++---------- chart/node-readiness-controller/values.yaml | 8 +++---- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/chart/node-readiness-controller/README.md b/chart/node-readiness-controller/README.md index 39d29d2..1a30dfd 100644 --- a/chart/node-readiness-controller/README.md +++ b/chart/node-readiness-controller/README.md @@ -17,7 +17,7 @@ A Helm chart for Kubernetes | image.pullPolicy | string | `"IfNotPresent"` | This sets the pull policy for images. | | image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | | imagePullSecrets | list | `[]` | This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | -| livenessProbe | object | `{"httpGet":{"initialDelaySeconds":15,"path":"/healthz","periodSeconds":20,"port":"http"}}` | This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ | +| livenessProbe | object | `{"httpGet":{"path":"/healthz","port":"http"},"initialDelaySeconds":15,"periodSeconds":20}` | This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ | | nameOverride | string | `""` | This is to override the chart name. | | nodeSelector | object | `{}` | This is for setting the node selector for the controller. More information can be found here: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector | | podAnnotations | object | `{}` | This is for setting Kubernetes Annotations to a Pod. For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ | @@ -26,7 +26,7 @@ A Helm chart for Kubernetes | priorityClassName | string | `"system-cluster-critical"` | This is for setting the priority class name for the controller. More information can be found here: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ | | rbac | object | `{"create":true}` | Configures Roles, ClusterRoles, RoleBindings and ClusterRoleBindings required for node-readiness-controller to operate. | | rbac.create | bool | `true` | Specifies whether RBAC resources should be created. | -| readinessProbe | object | `{"httpGet":{"initialDelaySeconds":5,"path":"/healthz","periodSeconds":10,"port":"http"}}` | This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ | +| readinessProbe | object | `{"httpGet":{"path":"/healthz","port":"http"},"initialDelaySeconds":5,"periodSeconds":10}` | This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ | | replicaCount | int | `1` | This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ | | resources | object | `{}` | This is for setting the resource requests and limits for the container. A reeasonable default is commented out for guidance. More information can be found here: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true}` | This is for setting the security context for the container. Set to a reasonable default. More information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ | diff --git a/chart/node-readiness-controller/templates/rbac.yaml b/chart/node-readiness-controller/templates/rbac.yaml index e2713d2..860dffa 100644 --- a/chart/node-readiness-controller/templates/rbac.yaml +++ b/chart/node-readiness-controller/templates/rbac.yaml @@ -209,7 +209,7 @@ metadata: labels: {{- include "node-readiness-controller.labels" . | nindent 4 }} name: {{ include "node-readiness-controller.shortname" . }}-leader-election-rolebinding - namespace: {{ include "node-readiness-controller.shortname" . }}-system + namespace: {{ .Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role @@ -217,7 +217,7 @@ roleRef: subjects: - kind: ServiceAccount name: {{ include "node-readiness-controller.shortname" . }}-controller-manager - namespace: {{ include "node-readiness-controller.shortname" . }}-system + namespace: {{ .Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -232,7 +232,7 @@ roleRef: subjects: - kind: ServiceAccount name: {{ include "node-readiness-controller.shortname" . }}-controller-manager - namespace: {{ include "node-readiness-controller.shortname" . }}-system + namespace: {{ .Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -247,5 +247,5 @@ roleRef: subjects: - kind: ServiceAccount name: {{ include "node-readiness-controller.shortname" . }}-controller-manager - namespace: {{ include "node-readiness-controller.shortname" . }}-system + namespace: {{ .Release.Namespace }} {{- end }} \ No newline at end of file diff --git a/chart/node-readiness-controller/values.schema.json b/chart/node-readiness-controller/values.schema.json index 35836df..90a83f1 100644 --- a/chart/node-readiness-controller/values.schema.json +++ b/chart/node-readiness-controller/values.schema.json @@ -40,19 +40,19 @@ "httpGet": { "type": "object", "properties": { - "initialDelaySeconds": { - "type": "integer" - }, "path": { "type": "string" }, - "periodSeconds": { - "type": "integer" - }, "port": { "type": "string" } } + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" } } }, @@ -101,19 +101,19 @@ "httpGet": { "type": "object", "properties": { - "initialDelaySeconds": { - "type": "integer" - }, "path": { "type": "string" }, - "periodSeconds": { - "type": "integer" - }, "port": { "type": "string" } } + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" } } }, diff --git a/chart/node-readiness-controller/values.yaml b/chart/node-readiness-controller/values.yaml index 8f977c4..c63f4fe 100644 --- a/chart/node-readiness-controller/values.yaml +++ b/chart/node-readiness-controller/values.yaml @@ -89,16 +89,16 @@ livenessProbe: httpGet: path: /healthz port: http - initialDelaySeconds: 15 - periodSeconds: 20 + initialDelaySeconds: 15 + periodSeconds: 20 # readinessProbe -- This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ readinessProbe: httpGet: path: /healthz port: http - initialDelaySeconds: 5 - periodSeconds: 10 + initialDelaySeconds: 5 + periodSeconds: 10 # volumes -- Additional volumes on the output Deployment definition. From 1106dd8e288ff41e54c65938a2a2ddc0a7b0df41 Mon Sep 17 00:00:00 2001 From: Hans Knecht Date: Wed, 11 Feb 2026 15:49:49 +0000 Subject: [PATCH 5/5] fix: correct service account --- chart/node-readiness-controller/templates/rbac.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chart/node-readiness-controller/templates/rbac.yaml b/chart/node-readiness-controller/templates/rbac.yaml index 860dffa..95b4be1 100644 --- a/chart/node-readiness-controller/templates/rbac.yaml +++ b/chart/node-readiness-controller/templates/rbac.yaml @@ -216,7 +216,7 @@ roleRef: name: {{ include "node-readiness-controller.shortname" . }}-leader-election-role subjects: - kind: ServiceAccount - name: {{ include "node-readiness-controller.shortname" . }}-controller-manager + name: {{ include "node-readiness-controller.serviceAccountName" . }} namespace: {{ .Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 @@ -231,7 +231,7 @@ roleRef: name: {{ include "node-readiness-controller.shortname" . }}-manager-role subjects: - kind: ServiceAccount - name: {{ include "node-readiness-controller.shortname" . }}-controller-manager + name: {{ include "node-readiness-controller.serviceAccountName" . }} namespace: {{ .Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 @@ -246,6 +246,6 @@ roleRef: name: {{ include "node-readiness-controller.shortname" . }}-metrics-auth-role subjects: - kind: ServiceAccount - name: {{ include "node-readiness-controller.shortname" . }}-controller-manager + name: {{ include "node-readiness-controller.serviceAccountName" . }} namespace: {{ .Release.Namespace }} {{- end }} \ No newline at end of file