mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
WIP: implementing separate deployments
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
This commit is contained in:
parent
ab03bcdcc7
commit
e776f6d843
21 changed files with 760 additions and 88 deletions
8
Makefile
8
Makefile
|
@ -103,6 +103,14 @@ build-%: generate ## Build binary for the specified arch
|
|||
@CGO_ENABLED=0 GOOS=linux GOARCH=$* \
|
||||
go build -o '$(OUTPUT_DIR)/external-secrets-linux-$*' main.go
|
||||
@$(OK) go build $*
|
||||
@$(INFO) go build $*
|
||||
@CGO_ENABLED=0 GOOS=linux GOARCH=$* \
|
||||
go build -o 'webhook/$(OUTPUT_DIR)/external-secrets-webhook-linux-$*' webhook/main.go
|
||||
@$(OK) go build $*
|
||||
@$(INFO) go build $*
|
||||
@CGO_ENABLED=0 GOOS=linux GOARCH=$* \
|
||||
go build -o 'webhook/certcontroller$(OUTPUT_DIR)/external-secrets-cert-controller-linux-$*' webhook/certcontroller/main.go
|
||||
@$(OK) go build $*
|
||||
|
||||
lint.check: ## Check install of golanci-lint
|
||||
@if ! golangci-lint --version > /dev/null 2>&1; then \
|
||||
|
|
|
@ -42,6 +42,24 @@ app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
|||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "external-secrets-webhook.labels" -}}
|
||||
helm.sh/chart: {{ include "external-secrets.chart" . }}
|
||||
{{ include "external-secrets-webhook.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "external-secrets-cert-controller.labels" -}}
|
||||
helm.sh/chart: {{ include "external-secrets.chart" . }}
|
||||
{{ include "external-secrets-cert-controller.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
|
@ -49,7 +67,14 @@ Selector labels
|
|||
app.kubernetes.io/name: {{ include "external-secrets.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "external-secrets-webhook.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "external-secrets.name" . }}-webhook
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
{{- define "external-secrets-cert-controller.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "external-secrets.name" . }}-cert-controller
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
|
@ -60,3 +85,26 @@ Create the name of the service account to use
|
|||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "external-secrets-webhook.serviceAccountName" -}}
|
||||
{{- if .Values.webhook.serviceAccount.create }}
|
||||
{{- default "external-secrets-webhook" .Values.webhook.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.webhook.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "external-secrets-cert-controller.serviceAccountName" -}}
|
||||
{{- if .Values.certController.serviceAccount.create }}
|
||||
{{- default "external-secrets-cert-controller" .Values.certController.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.certController.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "external-secrets.fullname" . }}-cert-controller
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "external-secrets-cert-controller.labels" . | nindent 4 }}
|
||||
{{- with .Values.certController.deploymentAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.certController.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "external-secrets-cert-controller.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.certController.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "external-secrets-cert-controller.selectorLabels" . | nindent 8 }}
|
||||
{{- with .Values.certController.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.certController.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "external-secrets-cert-controller.serviceAccountName" . }}
|
||||
{{- with .Values.certController.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: cert-controller
|
||||
{{- with .Values.certController.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.certController.image.repository }}:{{ .Values.certController.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.certController.image.pullPolicy }}
|
||||
{{- range $key, $value := .Values.certController.extraArgs }}
|
||||
{{- if $value }}
|
||||
- --{{ $key }}={{ $value }}
|
||||
{{- else }}
|
||||
- --{{ $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.certController.prometheus.service.port }}
|
||||
protocol: TCP
|
||||
name: metrics
|
||||
{{- with .Values.certController.extraEnv }}
|
||||
env:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.certController.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhook.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhook.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhook.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.webhook.priorityClassName }}
|
||||
priorityClassName: {{ .Values.webhook.priorityClassName }}
|
||||
{{- end }}
|
|
@ -0,0 +1,52 @@
|
|||
{{- if .Values.certController.rbac.create -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "external-secrets.fullname" . }}-cert-controller
|
||||
labels:
|
||||
{{- include "external-secrets-cert-controller.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "apiextensions.k8s.io"
|
||||
resources:
|
||||
- "customresourcedefinitions"
|
||||
verbs:
|
||||
- "get"
|
||||
- "list"
|
||||
- "watch"
|
||||
- "update"
|
||||
- "patch"
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "services"
|
||||
verbs:
|
||||
- "get"
|
||||
- "list"
|
||||
- "watch"
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "secrets"
|
||||
verbs:
|
||||
- "get"
|
||||
- "list"
|
||||
- "watch"
|
||||
- "update"
|
||||
- "patch"
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "external-secrets.fullname" . }}-cert-controller
|
||||
labels:
|
||||
{{- include "external-secrets-cert-controller.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "external-secrets.fullname" . }}-cert-controller
|
||||
subjects:
|
||||
- name: {{ include "external-secrets-cert-controller.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
kind: ServiceAccount
|
||||
{{- end }}
|
|
@ -0,0 +1,20 @@
|
|||
{{- if .Values.certController.prometheus.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "external-secrets.fullname" . }}-cert-controller-metrics
|
||||
labels:
|
||||
{{- include "external-secrets.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
prometheus.io/path: "/metrics"
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: {{ .Values.certController.prometheus.service.port | quote }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: {{ .Values.certController.prometheus.service.port }}
|
||||
protocol: TCP
|
||||
name: metrics
|
||||
selector:
|
||||
{{- include "external-secrets-cert-controller.selectorLabels" . | nindent 4 }}
|
||||
{{- end }}
|
|
@ -0,0 +1,13 @@
|
|||
{{- if .Values.certController.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "external-secrets-cert-controller.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "external-secrets-cert-controller.labels" . | nindent 4 }}
|
||||
{{- with .Values.certController.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,94 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "external-secrets.fullname" . }}-webhook
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "external-secrets-webhook.labels" . | nindent 4 }}
|
||||
{{- with .Values.webhook.deploymentAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.webhook.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "external-secrets-webhook.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.webhook.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "external-secrets-webhook.selectorLabels" . | nindent 8 }}
|
||||
{{- with .Values.webhook.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.webhook.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "external-secrets-webhook.serviceAccountName" . }}
|
||||
{{- with .Values.webhook.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: webhook
|
||||
{{- with .Values.webhook.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.webhook.image.repository }}:{{ .Values.webhook.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.webhook.image.pullPolicy }}
|
||||
{{- range $key, $value := .Values.webhook.extraArgs }}
|
||||
{{- if $value }}
|
||||
- --{{ $key }}={{ $value }}
|
||||
{{- else }}
|
||||
- --{{ $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.webhook.prometheus.service.port }}
|
||||
protocol: TCP
|
||||
name: metrics
|
||||
- containerPort: 9443
|
||||
protocol: TCP
|
||||
name: webhook
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: 9443
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
{{- with .Values.webhook.extraEnv }}
|
||||
env:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhook.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: certs
|
||||
mountPath: {{ .Values.webhook.certDir }}
|
||||
volumes:
|
||||
- name: certs
|
||||
secret:
|
||||
secretName: {{ include "external-secrets.fullname" . }}-webhook
|
||||
{{- with .Values.webhook.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhook.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhook.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.webhook.priorityClassName }}
|
||||
priorityClassName: {{ .Values.webhook.priorityClassName }}
|
||||
{{- end }}
|
|
@ -4,6 +4,6 @@ kind: Secret
|
|||
metadata:
|
||||
name: {{ include "external-secrets.fullname" . }}-webhook
|
||||
labels:
|
||||
{{- include "external-secrets.labels" . | nindent 4 }}
|
||||
{{- include "external-secrets-webhook.labels" . | nindent 4 }}
|
||||
external-secrets.io/component : webhook
|
||||
{{- end }}
|
||||
|
|
|
@ -4,7 +4,7 @@ kind: Service
|
|||
metadata:
|
||||
name: {{ include "external-secrets.fullname" . }}-webhook
|
||||
labels:
|
||||
{{- include "external-secrets.labels" . | nindent 4 }}
|
||||
{{- include "external-secrets-webhook.labels" . | nindent 4 }}
|
||||
external-secrets.io/component : webhook
|
||||
spec:
|
||||
type: ClusterIP
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
{{- if .Values.webhook.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "external-secrets-webhook.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "external-secrets-webhook.labels" . | nindent 4 }}
|
||||
{{- with .Values.webhook.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -78,9 +78,6 @@ prometheus:
|
|||
service:
|
||||
port: 8080
|
||||
|
||||
webhook:
|
||||
enabled: true
|
||||
certDir: /tmp/k8s-webhook-server/serving-certs
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
@ -89,3 +86,128 @@ affinity: {}
|
|||
|
||||
# -- Pod priority class name.
|
||||
priorityClassName: ""
|
||||
|
||||
webhook:
|
||||
certDir: /tmp/k8s-webhook-server/serving-certs
|
||||
image:
|
||||
repository: ghcr.io/external-secrets/external-secrets-webhook
|
||||
pullPolicy: IfNotPresent
|
||||
# -- The image tag to use. The default is the chart appVersion.
|
||||
tag: ""
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
rbac:
|
||||
# -- Specifies whether role and rolebinding resources should be created.
|
||||
create: true
|
||||
serviceAccount:
|
||||
# -- Specifies whether a service account should be created.
|
||||
create: true
|
||||
# -- Annotations to add to the service account.
|
||||
annotations: {}
|
||||
# -- The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template.
|
||||
name: ""
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
# -- Pod priority class name.
|
||||
priorityClassName: ""
|
||||
prometheus:
|
||||
# -- Specifies whether to expose Service resource for collecting Prometheus metrics
|
||||
enabled: false
|
||||
service:
|
||||
port: 8080
|
||||
## -- Extra environment variables to add to container.
|
||||
extraEnv: []
|
||||
|
||||
## -- Map of extra arguments to pass to container.
|
||||
extraArgs: {}
|
||||
|
||||
# -- Annotations to add to Deployment
|
||||
deploymentAnnotations: {}
|
||||
|
||||
# -- Annotations to add to Pod
|
||||
podAnnotations: {}
|
||||
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
resources: {}
|
||||
# requests:
|
||||
# cpu: 10m
|
||||
# memory: 32Mi
|
||||
|
||||
certController:
|
||||
image:
|
||||
repository: ghcr.io/external-secrets/external-secrets-cert-controller
|
||||
pullPolicy: IfNotPresent
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
rbac:
|
||||
# -- Specifies whether role and rolebinding resources should be created.
|
||||
create: true
|
||||
serviceAccount:
|
||||
# -- Specifies whether a service account should be created.
|
||||
create: true
|
||||
# -- Annotations to add to the service account.
|
||||
annotations: {}
|
||||
# -- The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template.
|
||||
name: ""
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
# -- Pod priority class name.
|
||||
priorityClassName: ""
|
||||
prometheus:
|
||||
# -- Specifies whether to expose Service resource for collecting Prometheus metrics
|
||||
enabled: false
|
||||
service:
|
||||
port: 8080
|
||||
## -- Extra environment variables to add to container.
|
||||
extraEnv: []
|
||||
|
||||
## -- Map of extra arguments to pass to container.
|
||||
extraArgs: {}
|
||||
|
||||
# -- Annotations to add to Deployment
|
||||
deploymentAnnotations: {}
|
||||
|
||||
# -- Annotations to add to Pod
|
||||
podAnnotations: {}
|
||||
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
resources: {}
|
||||
# requests:
|
||||
# cpu: 10m
|
||||
# memory: 32Mi
|
112
main.go
112
main.go
|
@ -29,7 +29,6 @@ import (
|
|||
|
||||
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
|
||||
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
|
||||
"github.com/external-secrets/external-secrets/pkg/controllers/crds"
|
||||
"github.com/external-secrets/external-secrets/pkg/controllers/externalsecret"
|
||||
"github.com/external-secrets/external-secrets/pkg/controllers/secretstore"
|
||||
)
|
||||
|
@ -57,14 +56,12 @@ func main() {
|
|||
var concurrent int
|
||||
var loglevel string
|
||||
var namespace string
|
||||
var webhook bool
|
||||
var storeRequeueInterval time.Duration
|
||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||
flag.StringVar(&controllerClass, "controller-class", "default", "the controller is instantiated with a specific controller name and filters ES based on this property")
|
||||
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
|
||||
"Enable leader election for controller manager. "+
|
||||
"Enabling this will ensure there is only one active controller manager.")
|
||||
flag.BoolVar(&webhook, "webhook", false, "Run as webhook") // Properly separate
|
||||
flag.IntVar(&concurrent, "concurrent", 1, "The number of concurrent ExternalSecret reconciles.")
|
||||
flag.StringVar(&loglevel, "loglevel", "info", "loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal")
|
||||
flag.StringVar(&namespace, "namespace", "", "watch external secrets scoped in the provided namespace only. ClusterSecretStore can be used but only work if it doesn't reference resources from other namespaces")
|
||||
|
@ -92,84 +89,37 @@ func main() {
|
|||
setupLog.Error(err, "unable to start manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
if webhook {
|
||||
crds := &crds.Reconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("CustomResourceDefinition"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
SvcLabels: map[string]string{"external-secrets.io/component": "webhook"},
|
||||
SecretLabels: map[string]string{"external-secrets.io/component": "webhook"},
|
||||
CrdResources: []string{"externalsecrets.external-secrets.io", "clustersecretstores.external-secrets.io", "secretstores.external-secrets.io"},
|
||||
CertDir: "/tmp/k8s-webhook-server/serving-certs",
|
||||
CAName: "external-secrets",
|
||||
CAOrganization: "external-secrets",
|
||||
RestartOnSecretRefresh: true,
|
||||
}
|
||||
if err := crds.SetupWithManager(mgr, controller.Options{
|
||||
MaxConcurrentReconciles: concurrent,
|
||||
}); err != nil {
|
||||
setupLog.Error(err, errCreateController, "controller", "CustomResourceDefinition")
|
||||
os.Exit(1)
|
||||
}
|
||||
if crtsReady := crds.EnsureCertsMounted(); crtsReady {
|
||||
if err = (&esv1beta1.ExternalSecret{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "ExternalSecret-v1beta1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1beta1.SecretStore{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "SecretStore-v1beta1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1beta1.ClusterSecretStore{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "ClusterSecretStore-v1beta1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1alpha1.ExternalSecret{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "ExternalSecret-v1alpha1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1alpha1.SecretStore{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "SecretStore-v1alpha1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1alpha1.ClusterSecretStore{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "ClusterSecretStore-v1alpha1")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err = (&secretstore.StoreReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("contllers").WithName("SecretStore"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
ControllerClass: controllerClass,
|
||||
RequeueInterval: storeRequeueInterval,
|
||||
}).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateController, "controller", "SecretStore")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&secretstore.ClusterStoreReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("ClusterSecretStore"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
ControllerClass: controllerClass,
|
||||
RequeueInterval: storeRequeueInterval,
|
||||
}).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateController, "controller", "ClusterSecretStore")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&externalsecret.Reconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("ExternalSecret"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
ControllerClass: controllerClass,
|
||||
RequeueInterval: time.Hour,
|
||||
}).SetupWithManager(mgr, controller.Options{
|
||||
MaxConcurrentReconciles: concurrent,
|
||||
}); err != nil {
|
||||
setupLog.Error(err, errCreateController, "controller", "ExternalSecret")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&secretstore.StoreReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("contllers").WithName("SecretStore"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
ControllerClass: controllerClass,
|
||||
RequeueInterval: storeRequeueInterval,
|
||||
}).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateController, "controller", "SecretStore")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&secretstore.ClusterStoreReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("ClusterSecretStore"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
ControllerClass: controllerClass,
|
||||
RequeueInterval: storeRequeueInterval,
|
||||
}).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateController, "controller", "ClusterSecretStore")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&externalsecret.Reconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("ExternalSecret"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
ControllerClass: controllerClass,
|
||||
RequeueInterval: time.Hour,
|
||||
}).SetupWithManager(mgr, controller.Options{
|
||||
MaxConcurrentReconciles: concurrent,
|
||||
}); err != nil {
|
||||
setupLog.Error(err, errCreateController, "controller", "ExternalSecret")
|
||||
os.Exit(1)
|
||||
}
|
||||
setupLog.Info("starting manager")
|
||||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
|
||||
|
|
|
@ -55,7 +55,7 @@ var _ = BeforeSuite(func() {
|
|||
|
||||
By("bootstrapping test environment")
|
||||
testEnv = &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds", "bases")},
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "deploy", "crds")},
|
||||
}
|
||||
|
||||
var ctx context.Context
|
||||
|
|
9
webhook/Dockerfile
Normal file
9
webhook/Dockerfile
Normal file
|
@ -0,0 +1,9 @@
|
|||
FROM gcr.io/distroless/static
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
COPY bin/external-secrets-webhook-${TARGETOS}-${TARGETARCH} /bin/external-secrets-webhook
|
||||
|
||||
# Run as UID for nobody
|
||||
USER 65534
|
||||
|
||||
ENTRYPOINT ["/bin/external-secrets-webhook"]
|
BIN
webhook/bin/external-secrets-webhook-linux-amd64
Executable file
BIN
webhook/bin/external-secrets-webhook-linux-amd64
Executable file
Binary file not shown.
BIN
webhook/bin/external-secrets-webhook-linux-arm64
Executable file
BIN
webhook/bin/external-secrets-webhook-linux-arm64
Executable file
Binary file not shown.
9
webhook/certcontroller/Dockerfile
Normal file
9
webhook/certcontroller/Dockerfile
Normal file
|
@ -0,0 +1,9 @@
|
|||
FROM gcr.io/distroless/static
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
COPY bin/external-secrets-cert-controller-${TARGETOS}-${TARGETARCH} /bin/external-secrets-cert-controller
|
||||
|
||||
# Run as UID for nobody
|
||||
USER 65534
|
||||
|
||||
ENTRYPOINT ["/bin/external-secrets-cert-controller"]
|
107
webhook/certcontroller/main.go
Normal file
107
webhook/certcontroller/main.go
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
|
||||
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
|
||||
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
|
||||
"github.com/external-secrets/external-secrets/pkg/controllers/crds"
|
||||
)
|
||||
|
||||
var (
|
||||
scheme = runtime.NewScheme()
|
||||
setupLog = ctrl.Log.WithName("setup")
|
||||
)
|
||||
|
||||
const (
|
||||
errCreateController = "unable to create controller"
|
||||
errCreateWebhook = "unable to create webhook"
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
_ = esv1beta1.AddToScheme(scheme)
|
||||
_ = esv1alpha1.AddToScheme(scheme)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var metricsAddr string
|
||||
var enableLeaderElection bool
|
||||
var concurrent int
|
||||
var loglevel string
|
||||
var namespace string
|
||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
|
||||
"Enable leader election for controller manager. "+
|
||||
"Enabling this will ensure there is only one active controller manager.")
|
||||
flag.StringVar(&loglevel, "loglevel", "info", "loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal")
|
||||
flag.Parse()
|
||||
|
||||
var lvl zapcore.Level
|
||||
err := lvl.UnmarshalText([]byte(loglevel))
|
||||
if err != nil {
|
||||
setupLog.Error(err, "error unmarshalling loglevel")
|
||||
os.Exit(1)
|
||||
}
|
||||
logger := zap.New(zap.Level(lvl))
|
||||
ctrl.SetLogger(logger)
|
||||
|
||||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
||||
Scheme: scheme,
|
||||
MetricsBindAddress: metricsAddr,
|
||||
Port: 9443,
|
||||
LeaderElection: enableLeaderElection,
|
||||
LeaderElectionID: "crd-certs-controller",
|
||||
Namespace: namespace,
|
||||
})
|
||||
if err != nil {
|
||||
setupLog.Error(err, "unable to start manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
crds := &crds.Reconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("webhook-certs-updater"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
SvcLabels: map[string]string{"external-secrets.io/component": "webhook"},
|
||||
SecretLabels: map[string]string{"external-secrets.io/component": "webhook"},
|
||||
CrdResources: []string{"externalsecrets.external-secrets.io", "clustersecretstores.external-secrets.io", "secretstores.external-secrets.io"},
|
||||
CertDir: "/tmp/k8s-webhook-server/serving-certs",
|
||||
CAName: "external-secrets",
|
||||
CAOrganization: "external-secrets",
|
||||
RestartOnSecretRefresh: false,
|
||||
}
|
||||
if err := crds.SetupWithManager(mgr, controller.Options{
|
||||
MaxConcurrentReconciles: concurrent,
|
||||
}); err != nil {
|
||||
setupLog.Error(err, errCreateController, "controller", "CustomResourceDefinition")
|
||||
os.Exit(1)
|
||||
}
|
||||
setupLog.Info("starting manager")
|
||||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
|
||||
setupLog.Error(err, "problem running manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
BIN
webhook/certcontrollerbin/external-secrets-cert-controller-linux-amd64
Executable file
BIN
webhook/certcontrollerbin/external-secrets-cert-controller-linux-amd64
Executable file
Binary file not shown.
BIN
webhook/certcontrollerbin/external-secrets-cert-controller-linux-arm64
Executable file
BIN
webhook/certcontrollerbin/external-secrets-cert-controller-linux-arm64
Executable file
Binary file not shown.
148
webhook/main.go
Normal file
148
webhook/main.go
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
|
||||
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
|
||||
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
|
||||
"github.com/external-secrets/external-secrets/pkg/controllers/crds"
|
||||
)
|
||||
|
||||
var (
|
||||
scheme = runtime.NewScheme()
|
||||
setupLog = ctrl.Log.WithName("setup")
|
||||
)
|
||||
|
||||
const (
|
||||
errCreateController = "unable to create controller"
|
||||
errCreateWebhook = "unable to create webhook"
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
_ = esv1beta1.AddToScheme(scheme)
|
||||
_ = esv1alpha1.AddToScheme(scheme)
|
||||
}
|
||||
|
||||
func checkCerts(certDir, dnsName string) {
|
||||
for {
|
||||
setupLog.Info("Checking certs")
|
||||
certFile := certDir + "/tls.crt"
|
||||
_, err := os.Stat(certFile)
|
||||
if err != nil {
|
||||
setupLog.Error(err, "certs not found")
|
||||
os.Exit(1)
|
||||
}
|
||||
ca, err := os.ReadFile(certDir + "/ca.crt")
|
||||
if err != nil {
|
||||
setupLog.Error(err, "error loading ca cert")
|
||||
os.Exit(1)
|
||||
}
|
||||
cert, err := os.ReadFile(certDir + "/tls.crt")
|
||||
if err != nil {
|
||||
setupLog.Error(err, "error loading server cert")
|
||||
os.Exit(1)
|
||||
}
|
||||
key, err := os.ReadFile(certDir + "/tls.key")
|
||||
if err != nil {
|
||||
setupLog.Error(err, "error loading server key")
|
||||
os.Exit(1)
|
||||
}
|
||||
ok, err := crds.ValidCert(ca, cert, key, dnsName, time.Now())
|
||||
if err != nil || !ok {
|
||||
setupLog.Error(err, "certificates are not valid!")
|
||||
os.Exit(1)
|
||||
}
|
||||
setupLog.Info("Certs valid")
|
||||
time.Sleep(time.Hour * 24)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var metricsAddr string
|
||||
var enableLeaderElection bool
|
||||
var loglevel string
|
||||
var namespace string
|
||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||
flag.StringVar(&loglevel, "loglevel", "info", "loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal")
|
||||
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
|
||||
"Enable leader election for controller manager. "+
|
||||
"Enabling this will ensure there is only one active controller manager.")
|
||||
flag.StringVar(&namespace, "namespace", "", "watch external secrets scoped in the provided namespace only. ClusterSecretStore can be used but only work if it doesn't reference resources from other namespaces")
|
||||
flag.Parse()
|
||||
|
||||
var lvl zapcore.Level
|
||||
err := lvl.UnmarshalText([]byte(loglevel))
|
||||
if err != nil {
|
||||
setupLog.Error(err, "error unmarshalling loglevel")
|
||||
os.Exit(1)
|
||||
}
|
||||
go checkCerts("/tmp/k8s-webhook-server/serving-certs", "host.minikube.internal")
|
||||
logger := zap.New(zap.Level(lvl))
|
||||
ctrl.SetLogger(logger)
|
||||
|
||||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
||||
Scheme: scheme,
|
||||
MetricsBindAddress: metricsAddr,
|
||||
Port: 9443,
|
||||
LeaderElection: enableLeaderElection,
|
||||
LeaderElectionID: "webhook-controller",
|
||||
Namespace: namespace,
|
||||
})
|
||||
if err != nil {
|
||||
setupLog.Error(err, "unable to start manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1beta1.ExternalSecret{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "ExternalSecret-v1beta1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1beta1.SecretStore{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "SecretStore-v1beta1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1beta1.ClusterSecretStore{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "ClusterSecretStore-v1beta1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1alpha1.ExternalSecret{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "ExternalSecret-v1alpha1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1alpha1.SecretStore{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "SecretStore-v1alpha1")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = (&esv1alpha1.ClusterSecretStore{}).SetupWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, errCreateWebhook, "webhook", "ClusterSecretStore-v1alpha1")
|
||||
os.Exit(1)
|
||||
}
|
||||
setupLog.Info("starting manager")
|
||||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
|
||||
setupLog.Error(err, "problem running manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue