kubernetes-operator v0.2.0

This commit is contained in:
M Essam Hamed
2025-11-25 20:43:08 +02:00
parent 1b7ef66957
commit d4dbd90516
19 changed files with 479 additions and 155 deletions
+2 -2
View File
@@ -2,5 +2,5 @@ apiVersion: v2
name: kubernetes-operator
description: NetBird Kubernetes Operator
type: application
version: 0.1.15
appVersion: "0.1.5"
version: 0.2.0
appVersion: "0.2.0"
@@ -0,0 +1,17 @@
fullnameOverride: "netbird-api-gateway"
controller:
replicaCount: 1
allowSnippetAnnotations: true
nodeSelector:
kubernetes.io/os: null
service:
type: ClusterIP
admissionWebhooks:
enabled: false
ingressClassResource:
name: netbird-api-gateway
controllerValue: k8s.io/netbird-api-gateway
ingressClass: netbird-api-gateway
config:
ssl-redirect: "true"
@@ -40,6 +40,11 @@ helm.sh/chart: {{ include "kubernetes-operator.chart" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- if .Values.general.labels }}
{{- range $key, $val := .Values.general.labels }}
{{ $key }}: "{{ $val }}"
{{- end }}
{{- end }}
{{- end }}
{{/*
@@ -66,6 +66,13 @@ spec:
{{- if .Values.routingClientImage }}
- --netbird-client-image={{.Values.routingClientImage}}
{{- end }}
{{- if .Values.general.labels }}
{{- $list := list }}
{{- range $k, $v := .Values.general.labels }}
{{- $list = append $list (printf "%s=%s" $k $v) }}
{{- end }}
- --default-labels="{{ join ", " $list }}"
{{- end }}
ports:
- name: webhook-server
containerPort: {{ .Values.webhook.service.port }}
@@ -27,7 +27,7 @@ spec:
spec:
initContainers:
- name: wait-network-ready
image: {{ .Values.ingress.kubernetesAPI.customKubectlImage | default "registry.suse.com/suse/kubectl:latest"}}
image: "netbirdio/kubectl:latest"
command:
- bash
- -c
@@ -35,7 +35,7 @@ spec:
- kubectl wait --for 'jsonpath={.status.networkID}' -n {{ $routerNS }} nbroutingpeer router;
containers:
- name: apply-nbresource
image: {{ .Values.ingress.kubernetesAPI.customKubectlImage | default "registry.suse.com/suse/kubectl:latest"}}
image: "netbirdio/kubectl:latest"
env:
- name: NBRESOURCE_VALUE
value: |
@@ -8,6 +8,8 @@ metadata:
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" $ | nindent 4 }}
annotations:
helm.sh/resource-policy: keep
name: {{ $k }}
spec:
name: {{ $v.name }}
@@ -10,6 +10,8 @@ metadata:
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" $ | nindent 4 }}
annotations:
helm.sh/resource-policy: keep
name: router
namespace: {{ $k }}
{{ $spec := merge $defaults $v }}
@@ -51,6 +53,8 @@ metadata:
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" $ | nindent 4 }}
annotations:
helm.sh/resource-policy: keep
name: router
{{- if or (or (or .replicas .resources) (or .labels .annotations)) (or .nodeSelector .tolerations) }}
spec:
@@ -1,69 +1,41 @@
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "kubernetes-operator.fullname" . }}-delete-routers
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" . | nindent 4 }}
annotations:
helm.sh/hook: pre-delete
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
spec:
backoffLimit: 3
template:
metadata:
name: {{ include "kubernetes-operator.fullname" . }}
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" . | nindent 8 }}
{{- with .Values.operator.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
containers:
- name: pre-delete
image: {{ .Values.ingress.kubernetesAPI.customKubectlImage | default "registry.suse.com/suse/kubectl:latest"}}
args:
- delete
- --all
- -A
- --cascade=foreground
- --ignore-not-found
- NBRoutingPeer
serviceAccountName: {{ include "kubernetes-operator.serviceAccountName" . }}
restartPolicy: Never
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "kubernetes-operator.fullname" . }}-delete-policies
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" . | nindent 4 }}
annotations:
helm.sh/hook: pre-delete
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
spec:
backoffLimit: 3
template:
metadata:
name: {{ include "kubernetes-operator.fullname" . }}
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" . | nindent 8 }}
{{- with .Values.operator.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
containers:
- name: pre-delete
image: {{ .Values.ingress.kubernetesAPI.customKubectlImage | default "registry.suse.com/suse/kubectl:latest"}}
args:
- delete
- --all
- --cascade=foreground
- --ignore-not-found
- NBPolicy
serviceAccountName: {{ include "kubernetes-operator.serviceAccountName" . }}
restartPolicy: Never
---
{{/*apiVersion: batch/v1*/}}
{{/*kind: Job*/}}
{{/*metadata:*/}}
{{/* name: {{ include "kubernetes-operator.fullname" . }}-delete-router-deployments*/}}
{{/* labels:*/}}
{{/* app.kubernetes.io/component: operator*/}}
{{/* {{- include "kubernetes-operator.labels" . | nindent 4 }}*/}}
{{/* annotations:*/}}
{{/* helm.sh/hook: pre-delete*/}}
{{/* helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded*/}}
{{/*spec:*/}}
{{/* backoffLimit: 3*/}}
{{/* template:*/}}
{{/* metadata:*/}}
{{/* name: {{ include "kubernetes-operator.fullname" . }}*/}}
{{/* labels:*/}}
{{/* app.kubernetes.io/component: operator*/}}
{{/* {{- include "kubernetes-operator.labels" . | nindent 8 }}*/}}
{{/* {{- with .Values.operator.podLabels }}*/}}
{{/* {{- toYaml . | nindent 8 }}*/}}
{{/* {{- end }}*/}}
{{/* spec:*/}}
{{/* containers:*/}}
{{/* - name: pre-delete*/}}
{{/* image: "netbirdio/kubectl:latest"*/}}
{{/* imagePullPolicy: {{ .Values.operator.image.pullPolicy }}*/}}
{{/* command:*/}}
{{/* - sh*/}}
{{/* - -c*/}}
{{/* args:*/}}
{{/* - kubectl get NBRoutingPeer -A --no-headers -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name | while read "L"; do kubectl patch --type=json -p '[{"op":"replace","path":"/spec/disableDeployment","value":true}]' NBRoutingPeer -n $(echo "$L" | awk '{print $1}') $(echo "$L" | awk '{print $2}'); done*/}}
{{/* - name: delete-wait*/}}
{{/* image: "netbirdio/kubectl:latest"*/}}
{{/* imagePullPolicy: {{ .Values.operator.image.pullPolicy }}*/}}
{{/* command:*/}}
{{/* - sh*/}}
{{/* - -c*/}}
{{/* args:*/}}
{{/* - kubectl get NBRoutingPeer -A --no-headers -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name | while read "L"; do kubectl wait --for=delete deployment -n $(echo "$L" | awk '{print $1}') $(echo "$L" | awk '{print $2}'); done*/}}
{{/* serviceAccountName: {{ include "kubernetes-operator.serviceAccountName" . }}*/}}
{{/* restartPolicy: Never*/}}
@@ -96,84 +96,6 @@ webhooks:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
{{- if $.Values.webhook.enableCertManager }}
annotations:
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ template "kubernetes-operator.fullname" . }}-serving-cert
{{- end }}
name: {{ include "kubernetes-operator.fullname" . }}-vnbresource-webhook
labels:
{{- include "kubernetes-operator.labels" . | nindent 4 }}
webhooks:
- clientConfig:
{{- if not $.Values.webhook.enableCertManager }}
caBundle: {{ $tls.caCert }}
{{ end }}
service:
name: {{ template "kubernetes-operator.webhookService" . }}
namespace: {{ $.Release.Namespace }}
path: /validate-netbird-io-v1-nbresource
failurePolicy: {{ .Values.webhook.failurePolicy }}
name: vnbresource-v1.netbird.io
admissionReviewVersions:
- v1
{{- if .Values.webhook.namespaceSelectors }}
namespaceSelector:
matchExpressions:
{{ toYaml .Values.webhook.namespaceSelectors | nindent 4 }}
{{ end }}
rules:
- apiGroups:
- netbird.io
apiVersions:
- v1
operations:
- DELETE
resources:
- "nbresources"
sideEffects: None
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
{{- if $.Values.webhook.enableCertManager }}
annotations:
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ template "kubernetes-operator.fullname" . }}-serving-cert
{{- end }}
name: {{ include "kubernetes-operator.fullname" . }}-vnbroutingpeer-webhook
labels:
{{- include "kubernetes-operator.labels" . | nindent 4 }}
webhooks:
- clientConfig:
{{- if not $.Values.webhook.enableCertManager }}
caBundle: {{ $tls.caCert }}
{{ end }}
service:
name: {{ template "kubernetes-operator.webhookService" . }}
namespace: {{ $.Release.Namespace }}
path: /validate-netbird-io-v1-nbroutingpeer
failurePolicy: {{ .Values.webhook.failurePolicy }}
name: vnbroutingpeer-v1.netbird.io
admissionReviewVersions:
- v1
{{- if .Values.webhook.namespaceSelectors }}
namespaceSelector:
matchExpressions:
{{ toYaml .Values.webhook.namespaceSelectors | nindent 4 }}
{{ end }}
rules:
- apiGroups:
- netbird.io
apiVersions:
- v1
operations:
- DELETE
resources:
- "nbroutingpeers"
sideEffects: None
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
{{- if $.Values.webhook.enableCertManager }}
annotations:
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ template "kubernetes-operator.fullname" . }}-serving-cert
+9 -4
View File
@@ -140,15 +140,14 @@ ingress:
namespacedNetworks: false
# Allow creating policies through Service annotations
allowAutomaticPolicyCreation: false
kubernetesAPI:
kubernetesAPI: # DEPRECATED: Use netbirdio/netbird-operator-configs Chart instead
enabled: false
groups: []
# - group1
# - group2
policies: []
# - default
customKubectlImage: "registry.suse.com/suse/kubectl:latest"
router:
router: # DEPRECATED: Use netbirdio/netbird-operator-configs Chart instead
# Deploy routing peer(s)
enabled: false
# replicas: 3
@@ -179,7 +178,7 @@ ingress:
# nodeSelector: {}
# tolerations: []
# NetBird Policies for use with exposed services
policies: {}
policies: {} # DEPRECATED: Use netbirdio/netbird-operator-configs Chart instead
# default:
# name: Kubernetes Default Policy
# sourceGroups:
@@ -199,3 +198,9 @@ netbirdAPI: {}
# key: "NB_API_KEY"
#routingClientImage: "netbirdio/netbird:latest"
general:
# General labels, applied to all created K8s resources
labels: {}
# acme_com_managed_by: platform-engineering
# acme_com_owned_by: release-engineering
@@ -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/
@@ -0,0 +1,6 @@
apiVersion: v2
name: netbird-operator-config
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "0.0.0"
@@ -0,0 +1,62 @@
{{/*
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 "netbird-operator-config.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 }}
{{/*
Expand the name of the chart.
*/}}
{{- define "netbird-operator-config.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "netbird-operator-config.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "netbird-operator-config.labels" -}}
helm.sh/chart: {{ include "netbird-operator-config.chart" . }}
{{ include "netbird-operator-config.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "netbird-operator-config.selectorLabels" -}}
app.kubernetes.io/name: {{ include "netbird-operator-config.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "netbird-operator-config.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "netbird-operator-config.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
@@ -0,0 +1,71 @@
{{- if and .Values.ingress.enabled .Values.ingress.kubernetesAPI.enabled }}
{{- $routerNS := .Release.Namespace }}
{{- if .Values.ingress.namespacedNetworks }}
{{- $routerNS = "default" }}
{{- end }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "netbird-operator-config.fullname" . }}-kubernetes-service-expose
labels:
app.kubernetes.io/component: operator
{{- include "netbird-operator-config.labels" . | nindent 4 }}
annotations:
helm.sh/hook: post-upgrade,post-install
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
spec:
backoffLimit: 3
template:
metadata:
name: {{ include "netbird-operator-config.fullname" . }}
labels:
app.kubernetes.io/component: operator
{{- include "netbird-operator-config.labels" . | nindent 8 }}
{{- with .Values.operator.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
initContainers:
- name: wait-network-ready
image: "netbirdio/kubectl:latest"
command:
- bash
- -c
args:
- kubectl wait --for 'jsonpath={.status.networkID}' -n {{ $routerNS }} nbroutingpeer router;
containers:
- name: apply-nbresource
image: "netbirdio/kubectl:latest"
env:
- name: NBRESOURCE_VALUE
value: |
apiVersion: netbird.io/v1
kind: NBResource
metadata:
finalizers:
- netbird.io/cleanup
name: kubernetes
namespace: default
spec:
address: kubernetes.default.{{.Values.cluster.dns}}
groups:
{{- if .Values.kubernetesAPI.groups }}
{{ toYaml .Values.kubernetesAPI.groups }}
{{- else }}
- {{ .Values.cluster.name }}-default-api-access
{{- end }}
name: {{ .Values.kubernetesAPI.resourceName | default "default-kubernetes-api" }}
networkID: ${NETWORK_ID}
{{- if .Values.kubernetesAPI.policies }}
policyName: "{{ join "," .Values.kubernetesAPI.policies }}"
{{- end }}
tcpPorts:
- 443
command:
- bash
- -c
args:
- kubectl delete NBResource --ignore-not-found -n default kubernetes; export NETWORK_ID=$(kubectl get NBRoutingPeer -n {{ $routerNS }} router -o 'jsonpath={.status.networkID}'); echo "$NBRESOURCE_VALUE" | envsubst | kubectl apply -f -
serviceAccountName: {{ include "netbird-operator-config.serviceAccountName" . }}
restartPolicy: Never
{{- end }}
@@ -0,0 +1,30 @@
{{- range $k, $v := $.Values.policies }}
---
apiVersion: netbird.io/v1
kind: NBPolicy
metadata:
annotations:
helm.sh/resource-policy: keep
finalizers:
- netbird.io/cleanup
labels:
app.kubernetes.io/component: operator
{{- include "netbird-operator-config.labels" $ | nindent 4 }}
name: {{ $k }}
spec:
name: {{ $v.name }}
sourceGroups:
{{ toYaml $v.sourceGroups | nindent 4}}
{{- if $v.description }}
description: {{ $v.description }}
{{- end }}
{{- if $v.protocols }}
protocols: {{ $v.protocols }}
{{- end }}
{{- if $v.ports }}
ports: {{ $v.ports }}
{{- end }}
{{- if hasKey $v "bidirectional" }}
bidirectional: {{ $v.bidirectional }}
{{- end }}
{{- end }}
@@ -0,0 +1,83 @@
{{- if .Values.router.enabled }}
{{- if .Values.namespacedNetworks }}
{{ $defaults := .Values.router }}
{{ range $k, $v := .Values.router.namespaces }}
apiVersion: netbird.io/v1
kind: NBRoutingPeer
metadata:
finalizers:
- netbird.io/cleanup
labels:
app.kubernetes.io/component: operator
{{- include "netbird-operator-config.labels" $ | nindent 4 }}
name: router
namespace: {{ $k }}
{{ $spec := merge $defaults $v }}
{{- if or (or (or $spec.replicas $spec.resources) (or $spec.labels $spec.annotations)) (or $spec.nodeSelector $spec.tolerations) }}
spec:
{{- if $spec.replicas }}
replicas: {{ $spec.replicas }}
{{- end }}
{{- if $spec.resources }}
resources:
{{- toYaml $spec.resources | nindent 4 }}
{{- end }}
{{- if $spec.labels }}
labels:
{{- toYaml $spec.labels | nindent 4 }}
{{- end }}
{{- if $spec.annotations }}
annotations:
{{- toYaml $spec.annotations | nindent 4 }}
{{- end }}
{{- if $spec.nodeSelector }}
nodeSelector:
{{- toYaml $spec.nodeSelector | nindent 4 }}
{{- end }}
{{- if $spec.tolerations }}
tolerations:
{{- toYaml $spec.tolerations | nindent 4 }}
{{- end }}
{{- end }}
---
{{- end }}
{{- else }}
{{- with .Values.router }}
apiVersion: netbird.io/v1
kind: NBRoutingPeer
metadata:
finalizers:
- netbird.io/cleanup
labels:
app.kubernetes.io/component: operator
{{- include "netbird-operator-config.labels" $ | nindent 4 }}
name: router
{{- if or (or (or .replicas .resources) (or .labels .annotations)) (or .nodeSelector .tolerations) }}
spec:
{{- if .replicas }}
replicas: {{ .replicas }}
{{- end }}
{{- if .resources }}
resources:
{{- toYaml .resources | nindent 4 }}
{{- end }}
{{- if .labels }}
labels:
{{- toYaml .labels | nindent 4 }}
{{- end }}
{{- if .annotations }}
annotations:
{{- toYaml .annotations | nindent 4 }}
{{- end }}
{{- if .nodeSelector }}
nodeSelector:
{{- toYaml .nodeSelector | nindent 4 }}
{{- end }}
{{- if .tolerations }}
tolerations:
{{- toYaml .tolerations | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,45 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "netbird-operator-config.fullname" . }}
labels:
{{- include "netbird-operator-config.labels" . | nindent 4 }}
rules:
- apiGroups:
- netbird.io
resources:
- nbresources
verbs:
- patch
- update
- list
- watch
- create
- delete
- apiGroups:
- netbird.io
resources:
- nbroutingpeers
verbs:
- get
- apiGroups:
- netbird.io
resources:
- nbresources/finalizers
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "netbird-operator-config.fullname" . }}
labels:
{{- include "netbird-operator-config.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "netbird-operator-config.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ include "netbird-operator-config.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
@@ -0,0 +1,13 @@
{{- if and .Values.kubernetesAPI.enabled .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "netbird-operator-config.serviceAccountName" . }}
labels:
{{- include "netbird-operator-config.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: true
{{- end }}
@@ -0,0 +1,57 @@
cluster:
name: "kubernetes"
dns: "svc.cluster.local"
# Create router per namespace, useful for strict networking requirements
namespacedNetworks: false
router:
# Deploy routing peer(s)
enabled: false
# replicas: 3
# resources:
# requests:
# cpu: 100m
# memory: 100Mi
# limits:
# cpu: 100m
# memory: 100Mi
# labels: {}
# annotations: {}
# nodeSelector: {}
# tolerations: []
# Only needed if namespacedNetworks is set to true
namespaces: {}
# default:
# replicas: 3
# resources:
# requests:
# cpu: 100m
# memory: 100Mi
# limits:
# cpu: 100m
# memory: 100Mi
# labels: {}
# annotations: {}
# nodeSelector: {}
# tolerations: []
# NetBird Policies for use with exposed services
policies: {}
# default:
# name: Kubernetes Default Policy
# sourceGroups:
# - All
kubernetesAPI:
enabled: false
groups: []
# - group1
# - group2
policies: []
# - default
# resourceName: "my-cluster-kubernetes"
serviceAccount:
create: true
name: ""
annotations: {}