mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 06:28:11 +00:00
Merge pull request #2987 from Infisical/daniel/k8s-multi-managed-secrets
feat(k8-operator/infisicalsecret-crd): multiple secret references
This commit is contained in:
@@ -26,15 +26,15 @@ spec:
|
|||||||
name: <service-account-name>
|
name: <service-account-name>
|
||||||
namespace: <service-account-namespace>
|
namespace: <service-account-namespace>
|
||||||
|
|
||||||
managedSecretReference:
|
managedKubeSecretReferences:
|
||||||
secretName: managed-secret
|
- secretName: managed-secret
|
||||||
secretNamespace: default
|
secretNamespace: default
|
||||||
creationPolicy: "Orphan"
|
creationPolicy: "Orphan"
|
||||||
template:
|
template:
|
||||||
includeAllSecrets: true
|
includeAllSecrets: true
|
||||||
data:
|
data:
|
||||||
NEW_KEY_NAME: "{{ .KEY.SecretPath }} {{ .KEY.Value }}"
|
NEW_KEY_NAME: "{{ .KEY.SecretPath }} {{ .KEY.Value }}"
|
||||||
KEY_WITH_BINARY_VALUE: "{{ .KEY.SecretPath }} {{ .KEY.Value }}"
|
KEY_WITH_BINARY_VALUE: "{{ .KEY.SecretPath }} {{ .KEY.Value }}"
|
||||||
```
|
```
|
||||||
|
|
||||||
## CRD properties
|
## CRD properties
|
||||||
@@ -541,18 +541,32 @@ The managed secret properties specify where to store the secrets retrieved from
|
|||||||
This includes defining the name and namespace of the Kubernetes secret that will hold these secrets.
|
This includes defining the name and namespace of the Kubernetes secret that will hold these secrets.
|
||||||
The Infisical operator will automatically create the Kubernetes secret in the specified name/namespace and ensure it stays up-to-date.
|
The Infisical operator will automatically create the Kubernetes secret in the specified name/namespace and ensure it stays up-to-date.
|
||||||
|
|
||||||
<Accordion title="managedSecretReference">
|
<Note>
|
||||||
|
|
||||||
|
The `managedSecretReference` field is deprecated and will be removed in a future release.
|
||||||
|
Replace it with `managedKubeSecretReferences`, which now accepts an array of references to support multiple managed secrets in a single InfisicalSecret CRD.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
managedKubeSecretReferences:
|
||||||
|
- secretName: managed-secret
|
||||||
|
secretNamespace: default
|
||||||
|
creationPolicy: "Orphan"
|
||||||
|
```
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
<Accordion title="managedKubeSecretReferences">
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<Accordion title="managedSecretReference.secretName">
|
<Accordion title="managedKubeSecretReferences[].secretName">
|
||||||
The name of the managed Kubernetes secret to be created
|
The name of the managed Kubernetes secret to be created
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<Accordion title="managedSecretReference.secretNamespace">
|
<Accordion title="managedKubeSecretReferences[].secretNamespace">
|
||||||
The namespace of the managed Kubernetes secret to be created.
|
The namespace of the managed Kubernetes secret to be created.
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<Accordion title="managedSecretReference.secretType">
|
<Accordion title="managedKubeSecretReferences[].secretType">
|
||||||
Override the default Opaque type for managed secrets with this field. Useful for creating kubernetes.io/dockerconfigjson secrets.
|
Override the default Opaque type for managed secrets with this field. Useful for creating kubernetes.io/dockerconfigjson secrets.
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<Accordion title="managedSecretReference.creationPolicy">
|
<Accordion title="managedKubeSecretReferences[].creationPolicy">
|
||||||
Creation polices allow you to control whether or not owner references should be added to the managed Kubernetes secret that is generated by the Infisical operator.
|
Creation polices allow you to control whether or not owner references should be added to the managed Kubernetes secret that is generated by the Infisical operator.
|
||||||
This is useful for tools such as ArgoCD, where every resource requires an owner reference; otherwise, it will be pruned automatically.
|
This is useful for tools such as ArgoCD, where every resource requires an owner reference; otherwise, it will be pruned automatically.
|
||||||
|
|
||||||
@@ -573,18 +587,18 @@ This is useful for tools such as ArgoCD, where every resource requires an owner
|
|||||||
Fetching secrets from Infisical as is via the operator may not be enough. This is where templating functionality may be helpful.
|
Fetching secrets from Infisical as is via the operator may not be enough. This is where templating functionality may be helpful.
|
||||||
Using Go templates, you can format, combine, and create new key-value pairs from secrets fetched from Infisical before storing them as Kubernetes Secrets.
|
Using Go templates, you can format, combine, and create new key-value pairs from secrets fetched from Infisical before storing them as Kubernetes Secrets.
|
||||||
|
|
||||||
<Accordion title="managedSecretReference.template">
|
<Accordion title="managedKubeSecretReferences[].template">
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<Accordion title="managedSecretReference.template.includeAllSecrets">
|
<Accordion title="managedKubeSecretReferences[].template.includeAllSecrets">
|
||||||
This property controls what secrets are included in your managed secret when using templates.
|
This property controls what secrets are included in your managed secret when using templates.
|
||||||
When set to `true`, all secrets fetched from your Infisical project will be added into your managed Kubernetes secret resource.
|
When set to `true`, all secrets fetched from your Infisical project will be added into your managed Kubernetes secret resource.
|
||||||
**Use this option when you would like to sync all secrets from Infisical to Kubernetes but want to template a subset of them.**
|
**Use this option when you would like to sync all secrets from Infisical to Kubernetes but want to template a subset of them.**
|
||||||
|
|
||||||
When set to `false`, only secrets defined in the `managedSecretReference.template.data` field of the template will be included in the managed secret.
|
When set to `false`, only secrets defined in the `managedKubeSecretReferences[].template.data` field of the template will be included in the managed secret.
|
||||||
Use this option when you would like to sync **only** a subset of secrets from Infisical to Kubernetes.
|
Use this option when you would like to sync **only** a subset of secrets from Infisical to Kubernetes.
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<Accordion title="managedSecretReference.template.data">
|
<Accordion title="managedKubeSecretReferences[].template.data">
|
||||||
Define secret keys and their corresponding templates.
|
Define secret keys and their corresponding templates.
|
||||||
Each data value uses a Golang template with access to all secrets retrieved from the specified scope.
|
Each data value uses a Golang template with access to all secrets retrieved from the specified scope.
|
||||||
|
|
||||||
@@ -600,16 +614,16 @@ type TemplateSecret struct {
|
|||||||
#### Example template configuration:
|
#### Example template configuration:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
managedSecretReference:
|
managedKubeSecretReferences:
|
||||||
secretName: managed-secret
|
- secretName: managed-secret
|
||||||
secretNamespace: default
|
secretNamespace: default
|
||||||
template:
|
template:
|
||||||
includeAllSecrets: true
|
includeAllSecrets: true
|
||||||
data:
|
data:
|
||||||
# Create new secret key that doesn't exist in your Infisical project using values of other secrets
|
# Create new secret key that doesn't exist in your Infisical project using values of other secrets
|
||||||
NEW_KEY: "{{ .DB_PASSWORD.Value }}"
|
NEW_KEY: "{{ .DB_PASSWORD.Value }}"
|
||||||
# Override an existing secret key in Infisical project with a new value using values of other secrets
|
# Override an existing secret key in Infisical project with a new value using values of other secrets
|
||||||
API_URL: "https://api.{{.COMPANY_NAME.Value}}.{{.REGION.Value}}.com"
|
API_URL: "https://api.{{.COMPANY_NAME.Value}}.{{.REGION.Value}}.com"
|
||||||
```
|
```
|
||||||
|
|
||||||
For this example, let's assume the following secrets exist in your Infisical project:
|
For this example, let's assume the following secrets exist in your Infisical project:
|
||||||
@@ -652,13 +666,13 @@ The example below assumes that the `BINARY_KEY_BASE64` secret is stored as a bas
|
|||||||
The resulting managed secret will contain the decoded value of `BINARY_KEY_BASE64`.
|
The resulting managed secret will contain the decoded value of `BINARY_KEY_BASE64`.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
managedSecretReference:
|
managedKubeSecretReferences:
|
||||||
secretName: managed-secret
|
secretName: managed-secret
|
||||||
secretNamespace: default
|
secretNamespace: default
|
||||||
template:
|
template:
|
||||||
includeAllSecrets: true
|
includeAllSecrets: true
|
||||||
data:
|
data:
|
||||||
BINARY_KEY: "{{ decodeBase64ToBytes .BINARY_KEY_BASE64.Value }}"
|
BINARY_KEY: "{{ decodeBase64ToBytes .BINARY_KEY_BASE64.Value }}"
|
||||||
```
|
```
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
@@ -913,7 +927,7 @@ spec:
|
|||||||
..
|
..
|
||||||
authentication:
|
authentication:
|
||||||
...
|
...
|
||||||
managedSecretReference:
|
managedKubeSecretReferences:
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -934,4 +948,4 @@ metadata:
|
|||||||
type: Opaque
|
type: Opaque
|
||||||
```
|
```
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
@@ -5462,4 +5462,4 @@ export const routeTree = rootRoute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ROUTE_MANIFEST_END */
|
ROUTE_MANIFEST_END */
|
||||||
@@ -13,9 +13,9 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# 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.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: v0.8.5
|
version: v0.8.6
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# 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
|
# 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.
|
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||||
# It is recommended to use it with quotes.
|
# It is recommended to use it with quotes.
|
||||||
appVersion: "v0.8.5"
|
appVersion: "v0.8.6"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{{- if .Values.installCRDs }}
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
@@ -262,6 +261,48 @@ spec:
|
|||||||
hostAPI:
|
hostAPI:
|
||||||
description: Infisical host to pull secrets from
|
description: Infisical host to pull secrets from
|
||||||
type: string
|
type: string
|
||||||
|
managedKubeSecretReferences:
|
||||||
|
items:
|
||||||
|
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
|
||||||
|
secretNamespace:
|
||||||
|
description: The name space where the Kubernetes Secret is located
|
||||||
|
type: string
|
||||||
|
secretType:
|
||||||
|
default: Opaque
|
||||||
|
description: 'The Kubernetes Secret type (experimental feature).
|
||||||
|
More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types'
|
||||||
|
type: string
|
||||||
|
template:
|
||||||
|
description: The template to transform the secret data
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: The template key values
|
||||||
|
type: object
|
||||||
|
includeAllSecrets:
|
||||||
|
description: This injects all retrieved secrets into the top
|
||||||
|
level of your template. Secrets defined in the template
|
||||||
|
will take precedence over the injected ones.
|
||||||
|
type: boolean
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
- secretNamespace
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
managedSecretReference:
|
managedSecretReference:
|
||||||
properties:
|
properties:
|
||||||
creationPolicy:
|
creationPolicy:
|
||||||
@@ -338,7 +379,6 @@ spec:
|
|||||||
- secretNamespace
|
- secretNamespace
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- managedSecretReference
|
|
||||||
- resyncInterval
|
- resyncInterval
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
@@ -425,5 +465,4 @@ status:
|
|||||||
kind: ""
|
kind: ""
|
||||||
plural: ""
|
plural: ""
|
||||||
conditions: []
|
conditions: []
|
||||||
storedVersions: []
|
storedVersions: []
|
||||||
{{- end }}
|
|
||||||
@@ -32,7 +32,7 @@ controllerManager:
|
|||||||
- ALL
|
- ALL
|
||||||
image:
|
image:
|
||||||
repository: infisical/kubernetes-operator
|
repository: infisical/kubernetes-operator
|
||||||
tag: v0.8.5
|
tag: v0.8.6
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 500m
|
cpu: 500m
|
||||||
|
|||||||
@@ -134,9 +134,12 @@ type InfisicalSecretSpec struct {
|
|||||||
// +kubebuilder:validation:Optional
|
// +kubebuilder:validation:Optional
|
||||||
Authentication Authentication `json:"authentication"`
|
Authentication Authentication `json:"authentication"`
|
||||||
|
|
||||||
// +kubebuilder:validation:Required
|
// +kubebuilder:validation:Optional
|
||||||
ManagedSecretReference ManagedKubeSecretConfig `json:"managedSecretReference"`
|
ManagedSecretReference ManagedKubeSecretConfig `json:"managedSecretReference"`
|
||||||
|
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
ManagedKubeSecretReferences []ManagedKubeSecretConfig `json:"managedKubeSecretReferences"`
|
||||||
|
|
||||||
// +kubebuilder:default:=60
|
// +kubebuilder:default:=60
|
||||||
ResyncInterval int `json:"resyncInterval"`
|
ResyncInterval int `json:"resyncInterval"`
|
||||||
|
|
||||||
|
|||||||
@@ -565,6 +565,13 @@ func (in *InfisicalSecretSpec) DeepCopyInto(out *InfisicalSecretSpec) {
|
|||||||
out.TokenSecretReference = in.TokenSecretReference
|
out.TokenSecretReference = in.TokenSecretReference
|
||||||
out.Authentication = in.Authentication
|
out.Authentication = in.Authentication
|
||||||
in.ManagedSecretReference.DeepCopyInto(&out.ManagedSecretReference)
|
in.ManagedSecretReference.DeepCopyInto(&out.ManagedSecretReference)
|
||||||
|
if in.ManagedKubeSecretReferences != nil {
|
||||||
|
in, out := &in.ManagedKubeSecretReferences, &out.ManagedKubeSecretReferences
|
||||||
|
*out = make([]ManagedKubeSecretConfig, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
out.TLS = in.TLS
|
out.TLS = in.TLS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,48 @@ spec:
|
|||||||
hostAPI:
|
hostAPI:
|
||||||
description: Infisical host to pull secrets from
|
description: Infisical host to pull secrets from
|
||||||
type: string
|
type: string
|
||||||
|
managedKubeSecretReferences:
|
||||||
|
items:
|
||||||
|
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
|
||||||
|
secretNamespace:
|
||||||
|
description: The name space where the Kubernetes Secret is located
|
||||||
|
type: string
|
||||||
|
secretType:
|
||||||
|
default: Opaque
|
||||||
|
description: 'The Kubernetes Secret type (experimental feature).
|
||||||
|
More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types'
|
||||||
|
type: string
|
||||||
|
template:
|
||||||
|
description: The template to transform the secret data
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: The template key values
|
||||||
|
type: object
|
||||||
|
includeAllSecrets:
|
||||||
|
description: This injects all retrieved secrets into the
|
||||||
|
top level of your template. Secrets defined in the template
|
||||||
|
will take precedence over the injected ones.
|
||||||
|
type: boolean
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
- secretNamespace
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
managedSecretReference:
|
managedSecretReference:
|
||||||
properties:
|
properties:
|
||||||
creationPolicy:
|
creationPolicy:
|
||||||
@@ -339,7 +381,6 @@ spec:
|
|||||||
- secretNamespace
|
- secretNamespace
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- managedSecretReference
|
|
||||||
- resyncInterval
|
- resyncInterval
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
|
|||||||
@@ -97,11 +97,11 @@ spec:
|
|||||||
secretsPath: "/path"
|
secretsPath: "/path"
|
||||||
recursive: true
|
recursive: true
|
||||||
|
|
||||||
managedSecretReference:
|
managedSecretReferences:
|
||||||
secretName: managed-secret
|
- secretName: managed-secret
|
||||||
secretNamespace: default
|
secretNamespace: default
|
||||||
creationPolicy: "Orphan" ## Owner | Orphan
|
creationPolicy: "Orphan" ## Owner | Orphan
|
||||||
# secretType: kubernetes.io/dockerconfigjson
|
# secretType: kubernetes.io/dockerconfigjson
|
||||||
|
|
||||||
# # To be depreciated soon
|
# # To be depreciated soon
|
||||||
# tokenSecretReference:
|
# tokenSecretReference:
|
||||||
|
|||||||
@@ -1,108 +0,0 @@
|
|||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/Infisical/infisical/k8-operator/api/v1alpha1"
|
|
||||||
"github.com/Infisical/infisical/k8-operator/packages/constants"
|
|
||||||
"github.com/go-logr/logr"
|
|
||||||
v1 "k8s.io/api/apps/v1"
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
const DEPLOYMENT_SECRET_NAME_ANNOTATION_PREFIX = "secrets.infisical.com/managed-secret"
|
|
||||||
const AUTO_RELOAD_DEPLOYMENT_ANNOTATION = "secrets.infisical.com/auto-reload" // needs to be set to true for a deployment to start auto redeploying
|
|
||||||
|
|
||||||
func (r *InfisicalSecretReconciler) ReconcileDeploymentsWithManagedSecrets(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret) (int, error) {
|
|
||||||
listOfDeployments := &v1.DeploymentList{}
|
|
||||||
err := r.Client.List(ctx, listOfDeployments, &client.ListOptions{Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace})
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("unable to get deployments in the [namespace=%v] [err=%v]", infisicalSecret.Spec.ManagedSecretReference.SecretNamespace, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
managedKubeSecretNameAndNamespace := types.NamespacedName{
|
|
||||||
Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace,
|
|
||||||
Name: infisicalSecret.Spec.ManagedSecretReference.SecretName,
|
|
||||||
}
|
|
||||||
|
|
||||||
managedKubeSecret := &corev1.Secret{}
|
|
||||||
err = r.Client.Get(ctx, managedKubeSecretNameAndNamespace, managedKubeSecret)
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("unable to fetch Kubernetes secret to update deployment: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
// Iterate over the deployments and check if they use the managed secret
|
|
||||||
for _, deployment := range listOfDeployments.Items {
|
|
||||||
deployment := deployment
|
|
||||||
if deployment.Annotations[AUTO_RELOAD_DEPLOYMENT_ANNOTATION] == "true" && r.IsDeploymentUsingManagedSecret(deployment, infisicalSecret) {
|
|
||||||
// Start a goroutine to reconcile the deployment
|
|
||||||
wg.Add(1)
|
|
||||||
go func(d v1.Deployment, s corev1.Secret) {
|
|
||||||
defer wg.Done()
|
|
||||||
if err := r.ReconcileDeployment(ctx, logger, d, s); err != nil {
|
|
||||||
logger.Error(err, fmt.Sprintf("unable to reconcile deployment with [name=%v]. Will try next requeue", deployment.ObjectMeta.Name))
|
|
||||||
}
|
|
||||||
}(deployment, *managedKubeSecret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the deployment uses managed secrets
|
|
||||||
func (r *InfisicalSecretReconciler) IsDeploymentUsingManagedSecret(deployment v1.Deployment, infisicalSecret v1alpha1.InfisicalSecret) bool {
|
|
||||||
managedSecretName := infisicalSecret.Spec.ManagedSecretReference.SecretName
|
|
||||||
for _, container := range deployment.Spec.Template.Spec.Containers {
|
|
||||||
for _, envFrom := range container.EnvFrom {
|
|
||||||
if envFrom.SecretRef != nil && envFrom.SecretRef.LocalObjectReference.Name == managedSecretName {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, env := range container.Env {
|
|
||||||
if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.LocalObjectReference.Name == managedSecretName {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, volume := range deployment.Spec.Template.Spec.Volumes {
|
|
||||||
if volume.Secret != nil && volume.Secret.SecretName == managedSecretName {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function ensures that a deployment is in sync with a Kubernetes secret by comparing their versions.
|
|
||||||
// If the version of the secret is different from the version annotation on the deployment, the annotation is updated to trigger a restart of the deployment.
|
|
||||||
func (r *InfisicalSecretReconciler) ReconcileDeployment(ctx context.Context, logger logr.Logger, deployment v1.Deployment, secret corev1.Secret) error {
|
|
||||||
annotationKey := fmt.Sprintf("%s.%s", DEPLOYMENT_SECRET_NAME_ANNOTATION_PREFIX, secret.Name)
|
|
||||||
annotationValue := secret.Annotations[constants.SECRET_VERSION_ANNOTATION]
|
|
||||||
|
|
||||||
if deployment.Annotations[annotationKey] == annotationValue &&
|
|
||||||
deployment.Spec.Template.Annotations[annotationKey] == annotationValue {
|
|
||||||
logger.Info(fmt.Sprintf("The [deploymentName=%v] is already using the most up to date managed secrets. No action required.", deployment.ObjectMeta.Name))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("Deployment is using outdated managed secret. Starting re-deployment [deploymentName=%v]", deployment.ObjectMeta.Name))
|
|
||||||
|
|
||||||
if deployment.Spec.Template.Annotations == nil {
|
|
||||||
deployment.Spec.Template.Annotations = make(map[string]string)
|
|
||||||
}
|
|
||||||
|
|
||||||
deployment.Annotations[annotationKey] = annotationValue
|
|
||||||
deployment.Spec.Template.Annotations[annotationKey] = annotationValue
|
|
||||||
|
|
||||||
if err := r.Client.Update(ctx, &deployment); err != nil {
|
|
||||||
return fmt.Errorf("failed to update deployment annotation: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -13,6 +13,8 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
|
|
||||||
|
defaultErrors "errors"
|
||||||
|
|
||||||
secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1"
|
secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1"
|
||||||
"github.com/Infisical/infisical/k8-operator/packages/api"
|
"github.com/Infisical/infisical/k8-operator/packages/api"
|
||||||
controllerhelpers "github.com/Infisical/infisical/k8-operator/packages/controllerhelpers"
|
controllerhelpers "github.com/Infisical/infisical/k8-operator/packages/controllerhelpers"
|
||||||
@@ -35,8 +37,6 @@ func (r *InfisicalSecretReconciler) GetLogger(req ctrl.Request) logr.Logger {
|
|||||||
return r.BaseLogger.WithValues("infisicalsecret", req.NamespacedName)
|
return r.BaseLogger.WithValues("infisicalsecret", req.NamespacedName)
|
||||||
}
|
}
|
||||||
|
|
||||||
var resourceVariablesMap map[string]util.ResourceVariables = make(map[string]util.ResourceVariables)
|
|
||||||
|
|
||||||
//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets,verbs=get;list;watch;create;update;patch;delete
|
//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets,verbs=get;list;watch;create;update;patch;delete
|
||||||
//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets/status,verbs=get;update;patch
|
//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets/status,verbs=get;update;patch
|
||||||
//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets/finalizers,verbs=update
|
//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets/finalizers,verbs=update
|
||||||
@@ -71,6 +71,30 @@ func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It's important we don't directly modify the CRD object, so we create a copy of it and move existing data into it.
|
||||||
|
managedKubeSecretReferences := infisicalSecretCRD.Spec.ManagedKubeSecretReferences
|
||||||
|
|
||||||
|
if infisicalSecretCRD.Spec.ManagedSecretReference.SecretName != "" && managedKubeSecretReferences != nil && len(managedKubeSecretReferences) > 0 {
|
||||||
|
errMessage := "InfisicalSecret CRD cannot have both managedSecretReference and managedKubeSecretReferences"
|
||||||
|
logger.Error(defaultErrors.New(errMessage), errMessage)
|
||||||
|
return ctrl.Result{}, defaultErrors.New(errMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
if infisicalSecretCRD.Spec.ManagedSecretReference.SecretName != "" {
|
||||||
|
logger.Info("\n\n\nThe field `managedSecretReference` will be deprecated in the near future, please use `managedKubeSecretReferences` instead.\n\nRefer to the documentation for more information: https://infisical.com/docs/integrations/platforms/kubernetes/infisical-secret-crd\n\n\n")
|
||||||
|
|
||||||
|
if managedKubeSecretReferences == nil {
|
||||||
|
managedKubeSecretReferences = []secretsv1alpha1.ManagedKubeSecretConfig{}
|
||||||
|
}
|
||||||
|
managedKubeSecretReferences = append(managedKubeSecretReferences, infisicalSecretCRD.Spec.ManagedSecretReference)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(managedKubeSecretReferences) == 0 {
|
||||||
|
errMessage := "InfisicalSecret CRD must have at least one managed secret reference set in the `managedKubeSecretReferences` field"
|
||||||
|
logger.Error(defaultErrors.New(errMessage), errMessage)
|
||||||
|
return ctrl.Result{}, defaultErrors.New(errMessage)
|
||||||
|
}
|
||||||
|
|
||||||
// Remove finalizers if they exist. This is to support previous InfisicalSecret CRD's that have finalizers on them.
|
// Remove finalizers if they exist. This is to support previous InfisicalSecret CRD's that have finalizers on them.
|
||||||
// In order to delete secrets with finalizers, we first remove the finalizers so we can use the simplified and improved deletion process
|
// In order to delete secrets with finalizers, we first remove the finalizers so we can use the simplified and improved deletion process
|
||||||
if !infisicalSecretCRD.ObjectMeta.DeletionTimestamp.IsZero() && len(infisicalSecretCRD.ObjectMeta.Finalizers) > 0 {
|
if !infisicalSecretCRD.ObjectMeta.DeletionTimestamp.IsZero() && len(infisicalSecretCRD.ObjectMeta.Finalizers) > 0 {
|
||||||
@@ -127,7 +151,7 @@ func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
api.API_CA_CERTIFICATE = ""
|
api.API_CA_CERTIFICATE = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.ReconcileInfisicalSecret(ctx, logger, infisicalSecretCRD)
|
err = r.ReconcileInfisicalSecret(ctx, logger, infisicalSecretCRD, managedKubeSecretReferences)
|
||||||
r.SetReadyToSyncSecretsConditions(ctx, &infisicalSecretCRD, err)
|
r.SetReadyToSyncSecretsConditions(ctx, &infisicalSecretCRD, err)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -138,7 +162,7 @@ func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
numDeployments, err := controllerhelpers.ReconcileDeploymentsWithManagedSecrets(ctx, r.Client, logger, infisicalSecretCRD.Spec.ManagedSecretReference)
|
numDeployments, err := controllerhelpers.ReconcileDeploymentsWithMultipleManagedSecrets(ctx, r.Client, logger, managedKubeSecretReferences)
|
||||||
r.SetInfisicalAutoRedeploymentReady(ctx, logger, &infisicalSecretCRD, numDeployments, err)
|
r.SetInfisicalAutoRedeploymentReady(ctx, logger, &infisicalSecretCRD, numDeployments, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, fmt.Sprintf("unable to reconcile auto redeployment. Will requeue after [requeueTime=%v]", requeueTime))
|
logger.Error(err, fmt.Sprintf("unable to reconcile auto redeployment. Will requeue after [requeueTime=%v]", requeueTime))
|
||||||
|
|||||||
@@ -165,10 +165,10 @@ var infisicalSecretTemplateFunctions = template.FuncMap{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *InfisicalSecretReconciler) createInfisicalManagedKubeSecret(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret, secretsFromAPI []model.SingleEnvironmentVariable, ETag string) error {
|
func (r *InfisicalSecretReconciler) createInfisicalManagedKubeSecret(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret, managedSecretReference v1alpha1.ManagedKubeSecretConfig, secretsFromAPI []model.SingleEnvironmentVariable, ETag string) error {
|
||||||
plainProcessedSecrets := make(map[string][]byte)
|
plainProcessedSecrets := make(map[string][]byte)
|
||||||
secretType := infisicalSecret.Spec.ManagedSecretReference.SecretType
|
secretType := managedSecretReference.SecretType
|
||||||
managedTemplateData := infisicalSecret.Spec.ManagedSecretReference.Template
|
managedTemplateData := managedSecretReference.Template
|
||||||
|
|
||||||
if managedTemplateData == nil || managedTemplateData.IncludeAllSecrets {
|
if managedTemplateData == nil || managedTemplateData.IncludeAllSecrets {
|
||||||
for _, secret := range secretsFromAPI {
|
for _, secret := range secretsFromAPI {
|
||||||
@@ -226,8 +226,8 @@ func (r *InfisicalSecretReconciler) createInfisicalManagedKubeSecret(ctx context
|
|||||||
// create a new secret as specified by the managed secret spec of CRD
|
// create a new secret as specified by the managed secret spec of CRD
|
||||||
newKubeSecretInstance := &corev1.Secret{
|
newKubeSecretInstance := &corev1.Secret{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: infisicalSecret.Spec.ManagedSecretReference.SecretName,
|
Name: managedSecretReference.SecretName,
|
||||||
Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace,
|
Namespace: managedSecretReference.SecretNamespace,
|
||||||
Annotations: annotations,
|
Annotations: annotations,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
},
|
},
|
||||||
@@ -235,7 +235,7 @@ func (r *InfisicalSecretReconciler) createInfisicalManagedKubeSecret(ctx context
|
|||||||
Data: plainProcessedSecrets,
|
Data: plainProcessedSecrets,
|
||||||
}
|
}
|
||||||
|
|
||||||
if infisicalSecret.Spec.ManagedSecretReference.CreationPolicy == "Owner" {
|
if managedSecretReference.CreationPolicy == "Owner" {
|
||||||
// Set InfisicalSecret instance as the owner and controller of the managed secret
|
// Set InfisicalSecret instance as the owner and controller of the managed secret
|
||||||
err := ctrl.SetControllerReference(&infisicalSecret, newKubeSecretInstance, r.Scheme)
|
err := ctrl.SetControllerReference(&infisicalSecret, newKubeSecretInstance, r.Scheme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -252,8 +252,8 @@ func (r *InfisicalSecretReconciler) createInfisicalManagedKubeSecret(ctx context
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *InfisicalSecretReconciler) updateInfisicalManagedKubeSecret(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret, managedKubeSecret corev1.Secret, secretsFromAPI []model.SingleEnvironmentVariable, ETag string) error {
|
func (r *InfisicalSecretReconciler) updateInfisicalManagedKubeSecret(ctx context.Context, logger logr.Logger, managedSecretReference v1alpha1.ManagedKubeSecretConfig, managedKubeSecret corev1.Secret, secretsFromAPI []model.SingleEnvironmentVariable, ETag string) error {
|
||||||
managedTemplateData := infisicalSecret.Spec.ManagedSecretReference.Template
|
managedTemplateData := managedSecretReference.Template
|
||||||
|
|
||||||
plainProcessedSecrets := make(map[string][]byte)
|
plainProcessedSecrets := make(map[string][]byte)
|
||||||
if managedTemplateData == nil || managedTemplateData.IncludeAllSecrets {
|
if managedTemplateData == nil || managedTemplateData.IncludeAllSecrets {
|
||||||
@@ -337,7 +337,7 @@ func (r *InfisicalSecretReconciler) updateResourceVariables(infisicalSecret v1al
|
|||||||
infisicalSecretResourceVariablesMap[string(infisicalSecret.UID)] = resourceVariables
|
infisicalSecretResourceVariablesMap[string(infisicalSecret.UID)] = resourceVariables
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret) error {
|
func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret, managedKubeSecretReferences []v1alpha1.ManagedKubeSecretConfig) error {
|
||||||
|
|
||||||
resourceVariables := r.getResourceVariables(infisicalSecret)
|
resourceVariables := r.getResourceVariables(infisicalSecret)
|
||||||
infisicalClient := resourceVariables.InfisicalClient
|
infisicalClient := resourceVariables.InfisicalClient
|
||||||
@@ -361,72 +361,84 @@ func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for managed secret by name and namespace
|
for _, managedSecretReference := range managedKubeSecretReferences {
|
||||||
managedKubeSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{
|
// Look for managed secret by name and namespace
|
||||||
Name: infisicalSecret.Spec.ManagedSecretReference.SecretName,
|
managedKubeSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{
|
||||||
Namespace: infisicalSecret.Spec.ManagedSecretReference.SecretNamespace,
|
Name: managedSecretReference.SecretName,
|
||||||
})
|
Namespace: managedSecretReference.SecretNamespace,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil && !k8Errors.IsNotFound(err) {
|
if err != nil && !k8Errors.IsNotFound(err) {
|
||||||
return fmt.Errorf("something went wrong when fetching the managed Kubernetes secret [%w]", err)
|
return fmt.Errorf("something went wrong when fetching the managed Kubernetes secret [%w]", err)
|
||||||
}
|
|
||||||
|
|
||||||
// Get exiting Etag if exists
|
|
||||||
secretVersionBasedOnETag := ""
|
|
||||||
if managedKubeSecret != nil {
|
|
||||||
secretVersionBasedOnETag = managedKubeSecret.Annotations[constants.SECRET_VERSION_ANNOTATION]
|
|
||||||
}
|
|
||||||
|
|
||||||
var plainTextSecretsFromApi []model.SingleEnvironmentVariable
|
|
||||||
var updateDetails model.RequestUpdateUpdateDetails
|
|
||||||
|
|
||||||
if authDetails.AuthStrategy == util.AuthStrategy.SERVICE_ACCOUNT { // Service Account // ! Legacy auth method
|
|
||||||
serviceAccountCreds, err := r.getInfisicalServiceAccountCredentialsFromKubeSecret(ctx, infisicalSecret)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("ReconcileInfisicalSecret: unable to get service account creds from kube secret [err=%s]", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaServiceAccount(infisicalClient, serviceAccountCreds, infisicalSecret.Spec.Authentication.ServiceAccount.ProjectId, infisicalSecret.Spec.Authentication.ServiceAccount.EnvironmentName, secretVersionBasedOnETag)
|
// Get exiting Etag if exists
|
||||||
if err != nil {
|
secretVersionBasedOnETag := ""
|
||||||
return fmt.Errorf("\nfailed to get secrets because [err=%v]", err)
|
if managedKubeSecret != nil {
|
||||||
|
secretVersionBasedOnETag = managedKubeSecret.Annotations[constants.SECRET_VERSION_ANNOTATION]
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("ReconcileInfisicalSecret: Fetched secrets via service account")
|
var plainTextSecretsFromApi []model.SingleEnvironmentVariable
|
||||||
|
var updateDetails model.RequestUpdateUpdateDetails
|
||||||
|
|
||||||
} else if authDetails.AuthStrategy == util.AuthStrategy.SERVICE_TOKEN { // Service Tokens // ! Legacy / Deprecated auth method
|
if authDetails.AuthStrategy == util.AuthStrategy.SERVICE_ACCOUNT { // Service Account // ! Legacy auth method
|
||||||
infisicalToken, err := r.getInfisicalTokenFromKubeSecret(ctx, infisicalSecret)
|
serviceAccountCreds, err := r.getInfisicalServiceAccountCredentialsFromKubeSecret(ctx, infisicalSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ReconcileInfisicalSecret: unable to get service token from kube secret [err=%s]", err)
|
return fmt.Errorf("ReconcileInfisicalSecret: unable to get service account creds from kube secret [err=%s]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
envSlug := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.EnvSlug
|
plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaServiceAccount(infisicalClient, serviceAccountCreds, infisicalSecret.Spec.Authentication.ServiceAccount.ProjectId, infisicalSecret.Spec.Authentication.ServiceAccount.EnvironmentName, secretVersionBasedOnETag)
|
||||||
secretsPath := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.SecretsPath
|
if err != nil {
|
||||||
recursive := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.Recursive
|
return fmt.Errorf("\nfailed to get secrets because [err=%v]", err)
|
||||||
|
}
|
||||||
|
|
||||||
plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaServiceToken(infisicalClient, infisicalToken, secretVersionBasedOnETag, envSlug, secretsPath, recursive)
|
logger.Info("ReconcileInfisicalSecret: Fetched secrets via service account")
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("\nfailed to get secrets because [err=%v]", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Info("ReconcileInfisicalSecret: Fetched secrets via [type=SERVICE_TOKEN]")
|
} else if authDetails.AuthStrategy == util.AuthStrategy.SERVICE_TOKEN { // Service Tokens // ! Legacy / Deprecated auth method
|
||||||
|
infisicalToken, err := r.getInfisicalTokenFromKubeSecret(ctx, infisicalSecret)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ReconcileInfisicalSecret: unable to get service token from kube secret [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
} else if authDetails.IsMachineIdentityAuth { // * Machine Identity authentication, the SDK will be authenticated at this point
|
envSlug := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.EnvSlug
|
||||||
plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaMachineIdentity(infisicalClient, secretVersionBasedOnETag, authDetails.MachineIdentityScope)
|
secretsPath := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.SecretsPath
|
||||||
|
recursive := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.Recursive
|
||||||
|
|
||||||
if err != nil {
|
plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaServiceToken(infisicalClient, infisicalToken, secretVersionBasedOnETag, envSlug, secretsPath, recursive)
|
||||||
return fmt.Errorf("\nfailed to get secrets because [err=%v]", err)
|
if err != nil {
|
||||||
}
|
return fmt.Errorf("\nfailed to get secrets because [err=%v]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("ReconcileInfisicalSecret: Fetched secrets via [type=SERVICE_TOKEN]")
|
||||||
|
|
||||||
|
} else if authDetails.IsMachineIdentityAuth { // * Machine Identity authentication, the SDK will be authenticated at this point
|
||||||
|
plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaMachineIdentity(infisicalClient, secretVersionBasedOnETag, authDetails.MachineIdentityScope)
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("ReconcileInfisicalSecret: Fetched secrets via machine identity [type=%v]", authDetails.AuthStrategy))
|
if err != nil {
|
||||||
|
return fmt.Errorf("\nfailed to get secrets because [err=%v]", err)
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
logger.Info(fmt.Sprintf("ReconcileInfisicalSecret: Fetched secrets via machine identity [type=%v]", authDetails.AuthStrategy))
|
||||||
return errors.New("no authentication method provided yet. Please configure a authentication method then try again")
|
|
||||||
}
|
|
||||||
|
|
||||||
if managedKubeSecret == nil {
|
} else {
|
||||||
return r.createInfisicalManagedKubeSecret(ctx, logger, infisicalSecret, plainTextSecretsFromApi, updateDetails.ETag)
|
return errors.New("no authentication method provided. Please configure a authentication method then try again")
|
||||||
} else {
|
}
|
||||||
return r.updateInfisicalManagedKubeSecret(ctx, logger, infisicalSecret, *managedKubeSecret, plainTextSecretsFromApi, updateDetails.ETag)
|
|
||||||
|
if !updateDetails.Modified {
|
||||||
|
logger.Info("ReconcileInfisicalSecret: No secrets modified so reconcile not needed")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if managedKubeSecret == nil {
|
||||||
|
if err := r.createInfisicalManagedKubeSecret(ctx, logger, infisicalSecret, managedSecretReference, plainTextSecretsFromApi, updateDetails.ETag); err != nil {
|
||||||
|
return fmt.Errorf("failed to create managed secret [err=%s]", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := r.updateInfisicalManagedKubeSecret(ctx, logger, managedSecretReference, *managedKubeSecret, plainTextSecretsFromApi, updateDetails.ETag); err != nil {
|
||||||
|
return fmt.Errorf("failed to update managed secret [err=%s]", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,17 @@ func ReconcileDeploymentsWithManagedSecrets(ctx context.Context, client controll
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReconcileDeploymentsWithMultipleManagedSecrets(ctx context.Context, client controllerClient.Client, logger logr.Logger, managedSecrets []v1alpha1.ManagedKubeSecretConfig) (int, error) {
|
||||||
|
for _, managedSecret := range managedSecrets {
|
||||||
|
_, err := ReconcileDeploymentsWithManagedSecrets(ctx, client, logger, managedSecret)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err, fmt.Sprintf("unable to reconcile deployments with managed secret [name=%v]", managedSecret.SecretName))
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the deployment uses managed secrets
|
// Check if the deployment uses managed secrets
|
||||||
func IsDeploymentUsingManagedSecret(deployment v1.Deployment, managedSecret v1alpha1.ManagedKubeSecretConfig) bool {
|
func IsDeploymentUsingManagedSecret(deployment v1.Deployment, managedSecret v1alpha1.ManagedKubeSecretConfig) bool {
|
||||||
managedSecretName := managedSecret.SecretName
|
managedSecretName := managedSecret.SecretName
|
||||||
|
|||||||
Reference in New Issue
Block a user