diff --git a/helm-charts/secrets-operator/Chart.yaml b/helm-charts/secrets-operator/Chart.yaml index dcc1b1c70..8cbe57c44 100644 --- a/helm-charts/secrets-operator/Chart.yaml +++ b/helm-charts/secrets-operator/Chart.yaml @@ -13,9 +13,9 @@ 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.3.3 +version: v0.4.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: "0.3.0" +appVersion: "v0.4.0" diff --git a/helm-charts/secrets-operator/templates/deployment.yaml b/helm-charts/secrets-operator/templates/deployment.yaml index 448fb614a..2d27b4b5a 100644 --- a/helm-charts/secrets-operator/templates/deployment.yaml +++ b/helm-charts/secrets-operator/templates/deployment.yaml @@ -1,13 +1,3 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "secrets-operator.fullname" . }}-controller-manager - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/part-of: k8-operator - {{- include "secrets-operator.labels" . | nindent 4 }} ---- apiVersion: apps/v1 kind: Deployment metadata: @@ -49,36 +39,29 @@ spec: values: - linux containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 + - args: {{- toYaml .Values.controllerManager.kubeRbacProxy.args | nindent 8 }} env: - name: KUBERNETES_CLUSTER_DOMAIN - value: {{ .Values.kubernetesClusterDomain }} - image: {{ .Values.controllerManager.kubeRbacProxy.image.repository }}:{{ .Values.controllerManager.kubeRbacProxy.image.tag | default .Chart.AppVersion }} + value: {{ quote .Values.kubernetesClusterDomain }} + image: {{ .Values.controllerManager.kubeRbacProxy.image.repository }}:{{ .Values.controllerManager.kubeRbacProxy.image.tag + | default .Chart.AppVersion }} name: kube-rbac-proxy ports: - containerPort: 8443 name: https protocol: TCP - resources: {{- toYaml .Values.controllerManager.kubeRbacProxy.resources | nindent 10 }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - - --leader-elect + resources: {{- toYaml .Values.controllerManager.kubeRbacProxy.resources | nindent + 10 }} + securityContext: {{- toYaml .Values.controllerManager.kubeRbacProxy.containerSecurityContext + | nindent 10 }} + - args: {{- toYaml .Values.controllerManager.manager.args | nindent 8 }} command: - /manager env: - name: KUBERNETES_CLUSTER_DOMAIN - value: {{ .Values.kubernetesClusterDomain }} - image: {{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag | default .Chart.AppVersion }} + value: {{ quote .Values.kubernetesClusterDomain }} + image: {{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag + | default .Chart.AppVersion }} livenessProbe: httpGet: path: /healthz @@ -92,12 +75,10 @@ spec: port: 8081 initialDelaySeconds: 5 periodSeconds: 10 - resources: {{- toYaml .Values.controllerManager.manager.resources | nindent 10 }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL + resources: {{- toYaml .Values.controllerManager.manager.resources | nindent 10 + }} + securityContext: {{- toYaml .Values.controllerManager.manager.containerSecurityContext + | nindent 10 }} securityContext: runAsNonRoot: true serviceAccountName: {{ include "secrets-operator.fullname" . }}-controller-manager diff --git a/helm-charts/secrets-operator/templates/infisicalsecret-crd.yaml b/helm-charts/secrets-operator/templates/infisicalsecret-crd.yaml index cfee98f81..4ac32fca4 100644 --- a/helm-charts/secrets-operator/templates/infisicalsecret-crd.yaml +++ b/helm-charts/secrets-operator/templates/infisicalsecret-crd.yaml @@ -96,6 +96,14 @@ spec: type: string managedSecretReference: properties: + creationPolicy: + default: Orphan + description: 'The Kubernetes Secret creation policy. Enum with values: + ''Owner'', ''Orphan''. Owner creates the secret and sets .metadata.ownerReferences + of the InfisicalSecret CRD that created it. Orphan will not set + the secret owner. This will result in the secret being orphaned + and not deleted when the resource is deleted.' + type: string secretName: description: The name of the Kubernetes Secret type: string diff --git a/helm-charts/secrets-operator/templates/metrics-service.yaml b/helm-charts/secrets-operator/templates/metrics-service.yaml index ebf7ce549..983b8a861 100644 --- a/helm-charts/secrets-operator/templates/metrics-service.yaml +++ b/helm-charts/secrets-operator/templates/metrics-service.yaml @@ -14,4 +14,4 @@ spec: control-plane: controller-manager {{- include "secrets-operator.selectorLabels" . | nindent 4 }} ports: - {{- .Values.metricsService.ports | toYaml | nindent 2 -}} \ No newline at end of file + {{- .Values.metricsService.ports | toYaml | nindent 2 }} \ No newline at end of file diff --git a/helm-charts/secrets-operator/templates/serviceaccount.yaml b/helm-charts/secrets-operator/templates/serviceaccount.yaml new file mode 100644 index 000000000..3e014ced3 --- /dev/null +++ b/helm-charts/secrets-operator/templates/serviceaccount.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "secrets-operator.fullname" . }}-controller-manager + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: k8-operator + app.kubernetes.io/part-of: k8-operator + {{- include "secrets-operator.labels" . | nindent 4 }} + annotations: + {{- toYaml .Values.controllerManager.serviceAccount.annotations | nindent 4 }} \ No newline at end of file diff --git a/helm-charts/secrets-operator/values.yaml b/helm-charts/secrets-operator/values.yaml index bd5cb09c3..a5692b061 100644 --- a/helm-charts/secrets-operator/values.yaml +++ b/helm-charts/secrets-operator/values.yaml @@ -1,5 +1,15 @@ controllerManager: kubeRbacProxy: + args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL image: repository: gcr.io/kubebuilder/kube-rbac-proxy tag: v0.15.0 @@ -11,9 +21,18 @@ controllerManager: cpu: 5m memory: 64Mi manager: + args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL image: repository: infisical/kubernetes-operator - tag: latest + tag: v0.4.0 # fixed to prevent accidental upgrade resources: limits: cpu: 500m @@ -22,6 +41,8 @@ controllerManager: cpu: 10m memory: 64Mi replicas: 1 + serviceAccount: + annotations: {} kubernetesClusterDomain: cluster.local metricsService: ports: diff --git a/k8-operator/Makefile b/k8-operator/Makefile index c1b7a57d2..de1465871 100644 --- a/k8-operator/Makefile +++ b/k8-operator/Makefile @@ -37,9 +37,19 @@ help: ## Display this help. @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) -## Chart - NOTE: change helper file to have 15 length for full name method -helm-chart: - $(KUSTOMIZE) build config/default | helmify ../helm-charts/secrets-operator +# ## Chart - NOTE: change helper file to have 15 length for full name method +# helm-chart: +# $(KUSTOMIZE) build config/default | helmify ../helm-charts/secrets-operator + +HELMIFY ?= $(LOCALBIN)/helmify + +.PHONY: helmify +helmify: $(HELMIFY) ## Download helmify locally if necessary. +$(HELMIFY): $(LOCALBIN) + test -s $(LOCALBIN)/helmify || GOBIN=$(LOCALBIN) go install github.com/arttor/helmify/cmd/helmify@latest + +helm: manifests kustomize helmify + $(KUSTOMIZE) build config/default | $(HELMIFY) ../helm-charts/secrets-operator ## Yaml for Kubectl kubectl-install: manifests kustomize diff --git a/k8-operator/api/v1alpha1/infisicalsecret_types.go b/k8-operator/api/v1alpha1/infisicalsecret_types.go index 2acad987c..cae966fe0 100644 --- a/k8-operator/api/v1alpha1/infisicalsecret_types.go +++ b/k8-operator/api/v1alpha1/infisicalsecret_types.go @@ -56,6 +56,14 @@ type MangedKubeSecretConfig struct { // +kubebuilder:validation:Optional // +kubebuilder:default:=Opaque SecretType string `json:"secretType"` + + // The Kubernetes Secret creation policy. + // Enum with values: 'Owner', 'Orphan'. + // Owner creates the secret and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. + // Orphan will not set the secret owner. This will result in the secret being orphaned and not deleted when the resource is deleted. + // +kubebuilder:validation:Optional + // +kubebuilder:default:=Orphan + CreationPolicy string `json:"creationPolicy"` } // InfisicalSecretSpec defines the desired state of InfisicalSecret diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml index c5a6beaa1..7d4e88b14 100644 --- a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml +++ b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml @@ -96,6 +96,15 @@ spec: type: string managedSecretReference: properties: + creationPolicy: + default: Orphan + description: 'The Kubernetes Secret creation policy. Enum with + values: ''Owner'', ''Orphan''. Owner creates the secret and + sets .metadata.ownerReferences of the InfisicalSecret CRD that + created it. Orphan will not set the secret owner. This will + result in the secret being orphaned and not deleted when the + resource is deleted.' + type: string secretName: description: The name of the Kubernetes Secret type: string diff --git a/k8-operator/config/samples/sample.yaml b/k8-operator/config/samples/sample.yaml index 82addeb4e..ca0025a53 100644 --- a/k8-operator/config/samples/sample.yaml +++ b/k8-operator/config/samples/sample.yaml @@ -5,9 +5,9 @@ metadata: labels: label-to-be-passed-to-managed-secret: sample-value annotations: - example.com/annotation-to-be-passed-to-managed-secret: "sample-value" + reflector.v1.k8s.emberstack.com/reflection-allowed: 'true' spec: - hostAPI: https://app.infisical.com/api + hostAPI: http://localhost:8888/api resyncInterval: 10 authentication: serviceAccount: @@ -26,6 +26,7 @@ spec: managedSecretReference: secretName: managed-secret secretNamespace: default + creationPolicy: "Orphan" ## Owner | Orphan # secretType: kubernetes.io/dockerconfigjson # # To be depreciated soon diff --git a/k8-operator/controllers/infisicalsecret_helper.go b/k8-operator/controllers/infisicalsecret_helper.go index 5f7ff4798..4523b42bb 100644 --- a/k8-operator/controllers/infisicalsecret_helper.go +++ b/k8-operator/controllers/infisicalsecret_helper.go @@ -142,8 +142,18 @@ func (r *InfisicalSecretReconciler) CreateInfisicalManagedKubeSecret(ctx context } annotations := map[string]string{} + systemPrefixes := []string{"kubectl.kubernetes.io/", "kubernetes.io/", "k8s.io/", "helm.sh/"} for k, v := range infisicalSecret.Annotations { - annotations[k] = v + isSystem := false + for _, prefix := range systemPrefixes { + if strings.HasPrefix(k, prefix) { + isSystem = true + break + } + } + if !isSystem { + annotations[k] = v + } } annotations[SECRET_VERSION_ANNOTATION] = encryptedSecretsResponse.ETag @@ -160,13 +170,15 @@ func (r *InfisicalSecretReconciler) CreateInfisicalManagedKubeSecret(ctx context Data: plainProcessedSecrets, } - // Set InfisicalSecret instance as the owner and controller - err := ctrl.SetControllerReference(&infisicalSecret, newKubeSecretInstance, r.Scheme) - if err != nil { - return err + if infisicalSecret.Spec.ManagedSecretReference.CreationPolicy == "Owner" { + // Set InfisicalSecret instance as the owner and controller of the managed secret + err := ctrl.SetControllerReference(&infisicalSecret, newKubeSecretInstance, r.Scheme) + if err != nil { + return err + } } - err = r.Client.Create(ctx, newKubeSecretInstance) + err := r.Client.Create(ctx, newKubeSecretInstance) if err != nil { return fmt.Errorf("unable to create the managed Kubernetes secret : %w", err) } diff --git a/k8-operator/packages/api/api.go b/k8-operator/packages/api/api.go index 83feffdf5..15de04321 100644 --- a/k8-operator/packages/api/api.go +++ b/k8-operator/packages/api/api.go @@ -77,7 +77,7 @@ func CallGetSecretsV3(httpClient *resty.Client, request GetEncryptedSecretsV3Req return GetEncryptedSecretsV3Response{}, fmt.Errorf("CallGetSecretsV3: Unsuccessful response. Please make sure your secret path, workspace and environment name are all correct [response=%s]", response) } - if response.StatusCode() == 304 { + if response.Header().Get("etag") == request.ETag { secretsResponse.Modified = false } else { secretsResponse.Modified = true