feat(k8s): pushsecret go templating

This commit is contained in:
Daniel Hougaard
2025-03-28 08:09:55 +04:00
parent c765c20539
commit 03b0334fa0
11 changed files with 282 additions and 67 deletions

View File

@@ -401,6 +401,82 @@ After applying the InfisicalPushSecret CRD, you should notice that the secrets y
</Accordion> </Accordion>
## Using templating to push secrets
Pushing secrets to Infisical from the operator may not always be enough.
Templating is a useful utility of the Infisical secrets operator that allows you to use Go Templating to template the secrets you want to push to Infisical.
Using Go templates, you can format, combine, and create new key-value pairs of secrets that you want to push to Infisical.
<Accordion title="push.secret.template"/>
<Accordion title="push.secret.template.includeAllSecrets">
This property controls what secrets are included in your push to Infisica.
When set to `true`, all secrets included in the `push.secret.secretName` Kubernetes secret will be pushed to Infisical.
**Use this option when you would like to push all secrets to Infisical from the secrets operator, but want to template a subset of them.**
When set to `false`, only secrets defined in the `push.secret.template.data` field of the template will be pushed to Infisical.
Use this option when you would like to push **only** a subset of secrets from the Kubernetes secret to Infisical.
</Accordion>
<Accordion title="push.secret.template.data">
Define secret keys and their corresponding templates.
Each data value uses a Golang template with access to all secrets defined in the `push.secret.secretName` Kubernetes secret.
Secrets are structured as follows:
```go
type TemplateSecret struct {
Value string `json:"value"`
SecretPath string `json:"secretPath"`
}
```
#### Example template configuration:
```yaml
# This example assumes that the `push-secret-demo` Kubernetes secret contains the following secrets:
# SITE_URL = "https://example.com"
# REGION = "us-east-1"
# OTHER_SECRET = "other-secret"
push:
secret:
secretName: push-secret-demo
secretNamespace: default
template:
includeAllSecrets: true # Includes all secrets from the `push-secret-demo` Kubernetes secret
data:
SITE_URL: "{{ .SITE_URL.Value }}"
API_URL: "https://api.{{.SITE_URL.Value}}.{{.REGION.Value}}.com" # Will create a new secret in Infisical with the key `API_URL` with the value of the `SITE_URL` and `REGION` secrets
```
To help transform your config map data further, the operator provides a set of built-in functions that you can use in your templates.
### Available templating functions
<Accordion title="encodeBase64">
**Function name**: encodeBase64
**Description**:
Given a string, this function will encode the string as a base64 encoded string.
This function is useful when you want to store a string as a base64 encoded value in Infisical.
**Returns**: The base64 encoded string.
**Example**:
The example below assumes that the `PLAIN_KEY` secret is stored in your source secret as a plaintext string.
```yaml
push:
secret:
secretName: push-secret-demo
secretNamespace: default
template:
includeAllSecrets: true
data:
PLAIN_KEY: "{{ encodeBase64 .PLAIN_KEY.Value }}" # Will be stored in Infisical as a base64 encoded string
```
</Accordion>
</Accordion>
## Applying the InfisicalPushSecret CRD to your cluster ## Applying the InfisicalPushSecret CRD to your cluster
Once you have configured the `InfisicalPushSecret` CRD with the required fields, you can apply it to your cluster. Once you have configured the `InfisicalPushSecret` CRD with the required fields, you can apply it to your cluster.

View File

@@ -105,7 +105,7 @@ type ManagedKubeSecretConfig struct {
// The template to transform the secret data // The template to transform the secret data
// +kubebuilder:validation:Optional // +kubebuilder:validation:Optional
Template *InfisicalSecretTemplate `json:"template,omitempty"` Template *SecretTemplate `json:"template,omitempty"`
} }
type ManagedKubeConfigMapConfig struct { type ManagedKubeConfigMapConfig struct {
@@ -127,5 +127,15 @@ type ManagedKubeConfigMapConfig struct {
// The template to transform the secret data // The template to transform the secret data
// +kubebuilder:validation:Optional // +kubebuilder:validation:Optional
Template *InfisicalSecretTemplate `json:"template,omitempty"` Template *SecretTemplate `json:"template,omitempty"`
}
type SecretTemplate struct {
// This injects all retrieved secrets into the top level of your template.
// Secrets defined in the template will take precedence over the injected ones.
// +kubebuilder:validation:Optional
IncludeAllSecrets bool `json:"includeAllSecrets"`
// The template key values
// +kubebuilder:validation:Optional
Data map[string]string `json:"data,omitempty"`
} }

View File

@@ -16,9 +16,22 @@ type InfisicalPushSecretDestination struct {
ProjectID string `json:"projectId"` ProjectID string `json:"projectId"`
} }
type InfisicalPushSecretSecretSource struct {
// The name of the Kubernetes Secret
// +kubebuilder:validation:Required
SecretName string `json:"secretName"`
// The name space where the Kubernetes Secret is located
// +kubebuilder:validation:Required
SecretNamespace string `json:"secretNamespace"`
// +kubebuilder:validation:Optional
Template *SecretTemplate `json:"template,omitempty"`
}
type SecretPush struct { type SecretPush struct {
// +kubebuilder:validation:Required // +kubebuilder:validation:Required
Secret KubeSecretReference `json:"secret"` Secret InfisicalPushSecretSecretSource `json:"secret"`
} }
// InfisicalPushSecretSpec defines the desired state of InfisicalPushSecret // InfisicalPushSecretSpec defines the desired state of InfisicalPushSecret

View File

@@ -116,16 +116,6 @@ type MachineIdentityScopeInWorkspace struct {
Recursive bool `json:"recursive"` Recursive bool `json:"recursive"`
} }
type InfisicalSecretTemplate struct {
// This injects all retrieved secrets into the top level of your template.
// Secrets defined in the template will take precedence over the injected ones.
// +kubebuilder:validation:Optional
IncludeAllSecrets bool `json:"includeAllSecrets"`
// The template key values
// +kubebuilder:validation:Optional
Data map[string]string `json:"data,omitempty"`
}
// InfisicalSecretSpec defines the desired state of InfisicalSecret // InfisicalSecretSpec defines the desired state of InfisicalSecret
type InfisicalSecretSpec struct { type InfisicalSecretSpec struct {
// +kubebuilder:validation:Optional // +kubebuilder:validation:Optional

View File

@@ -383,7 +383,7 @@ func (in *InfisicalPushSecret) DeepCopyInto(out *InfisicalPushSecret) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status) in.Status.DeepCopyInto(&out.Status)
} }
@@ -452,12 +452,32 @@ func (in *InfisicalPushSecretList) DeepCopyObject() runtime.Object {
return nil return nil
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfisicalPushSecretSecretSource) DeepCopyInto(out *InfisicalPushSecretSecretSource) {
*out = *in
if in.Template != nil {
in, out := &in.Template, &out.Template
*out = new(SecretTemplate)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalPushSecretSecretSource.
func (in *InfisicalPushSecretSecretSource) DeepCopy() *InfisicalPushSecretSecretSource {
if in == nil {
return nil
}
out := new(InfisicalPushSecretSecretSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfisicalPushSecretSpec) DeepCopyInto(out *InfisicalPushSecretSpec) { func (in *InfisicalPushSecretSpec) DeepCopyInto(out *InfisicalPushSecretSpec) {
*out = *in *out = *in
out.Destination = in.Destination out.Destination = in.Destination
out.Authentication = in.Authentication out.Authentication = in.Authentication
out.Push = in.Push in.Push.DeepCopyInto(&out.Push)
out.TLS = in.TLS out.TLS = in.TLS
} }
@@ -614,28 +634,6 @@ func (in *InfisicalSecretStatus) DeepCopy() *InfisicalSecretStatus {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfisicalSecretTemplate) DeepCopyInto(out *InfisicalSecretTemplate) {
*out = *in
if in.Data != nil {
in, out := &in.Data, &out.Data
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalSecretTemplate.
func (in *InfisicalSecretTemplate) DeepCopy() *InfisicalSecretTemplate {
if in == nil {
return nil
}
out := new(InfisicalSecretTemplate)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeSecretReference) DeepCopyInto(out *KubeSecretReference) { func (in *KubeSecretReference) DeepCopyInto(out *KubeSecretReference) {
*out = *in *out = *in
@@ -703,7 +701,7 @@ func (in *ManagedKubeConfigMapConfig) DeepCopyInto(out *ManagedKubeConfigMapConf
*out = *in *out = *in
if in.Template != nil { if in.Template != nil {
in, out := &in.Template, &out.Template in, out := &in.Template, &out.Template
*out = new(InfisicalSecretTemplate) *out = new(SecretTemplate)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
} }
@@ -723,7 +721,7 @@ func (in *ManagedKubeSecretConfig) DeepCopyInto(out *ManagedKubeSecretConfig) {
*out = *in *out = *in
if in.Template != nil { if in.Template != nil {
in, out := &in.Template, &out.Template in, out := &in.Template, &out.Template
*out = new(InfisicalSecretTemplate) *out = new(SecretTemplate)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
} }
@@ -741,7 +739,7 @@ func (in *ManagedKubeSecretConfig) DeepCopy() *ManagedKubeSecretConfig {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretPush) DeepCopyInto(out *SecretPush) { func (in *SecretPush) DeepCopyInto(out *SecretPush) {
*out = *in *out = *in
out.Secret = in.Secret in.Secret.DeepCopyInto(&out.Secret)
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretPush. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretPush.
@@ -769,6 +767,28 @@ func (in *SecretScopeInWorkspace) DeepCopy() *SecretScopeInWorkspace {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretTemplate) DeepCopyInto(out *SecretTemplate) {
*out = *in
if in.Data != nil {
in, out := &in.Data, &out.Data
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretTemplate.
func (in *SecretTemplate) DeepCopy() *SecretTemplate {
if in == nil {
return nil
}
out := new(SecretTemplate)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceAccountDetails) DeepCopyInto(out *ServiceAccountDetails) { func (in *ServiceAccountDetails) DeepCopyInto(out *ServiceAccountDetails) {
*out = *in *out = *in

View File

@@ -137,6 +137,19 @@ spec:
description: The name space where the Kubernetes Secret is description: The name space where the Kubernetes Secret is
located located
type: string type: string
template:
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: required:
- secretName - secretName
- secretNamespace - secretNamespace

View File

@@ -0,0 +1,39 @@
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalPushSecret
metadata:
name: infisical-api-secret-sample-push
spec:
resyncInterval: 1m
hostAPI: http://localhost:8080/api
# Optional, defaults to replacement.
updatePolicy: Replace # If set to replace, existing secrets inside Infisical will be replaced by the value of the PushSecret on sync.
# Optional, defaults to no deletion.
deletionPolicy: Delete # If set to delete, the secret(s) inside Infisical managed by the operator, will be deleted if the InfisicalPushSecret CRD is deleted.
destination:
projectId: <project-id>
environmentSlug: <env-slug>
secretsPath: <secret-path>
push:
secret:
secretName: push-secret-demo # Secret CRD
secretNamespace: default
template:
includeAllSecrets: false
data:
# Encodes the data so it's stored as base64 in Infisical.
API_KEY: "{{ .API_KEY.Value }}"
DATABASE_URL: "{{ .DATABASE_URL.Value }}"
ENCRYPTION_KEY: "{{ .ENCRYPTION_KEY.Value }}"
OTHER_VALUE: "{{ encodeBase64 .API_KEY.Value }} {{ encodeBase64 .DATABASE_URL.Value }} {{ encodeBase64 .ENCRYPTION_KEY.Value }}"
# Only have one authentication method defined or you are likely to run into authentication issues.
# Remove all except one authentication method.
authentication:
universalAuth:
credentialsRef:
secretName: universal-auth-credentials
secretNamespace: default

View File

@@ -1,16 +1,20 @@
package controllers package controllers
import ( import (
"bytes"
"context" "context"
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
"text/template"
"github.com/Infisical/infisical/k8-operator/api/v1alpha1" "github.com/Infisical/infisical/k8-operator/api/v1alpha1"
"github.com/Infisical/infisical/k8-operator/packages/api" "github.com/Infisical/infisical/k8-operator/packages/api"
"github.com/Infisical/infisical/k8-operator/packages/constants" "github.com/Infisical/infisical/k8-operator/packages/constants"
"github.com/Infisical/infisical/k8-operator/packages/model"
"github.com/Infisical/infisical/k8-operator/packages/util" "github.com/Infisical/infisical/k8-operator/packages/util"
"github.com/go-logr/logr" "github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
@@ -101,6 +105,48 @@ func (r *InfisicalPushSecretReconciler) updateResourceVariables(infisicalPushSec
infisicalPushSecretResourceVariablesMap[string(infisicalPushSecret.UID)] = resourceVariables infisicalPushSecretResourceVariablesMap[string(infisicalPushSecret.UID)] = resourceVariables
} }
func (r *InfisicalPushSecretReconciler) processTemplatedSecrets(infisicalPushSecret v1alpha1.InfisicalPushSecret, kubePushSecret *corev1.Secret, destination v1alpha1.InfisicalPushSecretDestination) (map[string]string, error) {
processedSecrets := make(map[string]string)
sourceSecrets := make(map[string]model.SecretTemplateOptions)
for key, value := range kubePushSecret.Data {
sourceSecrets[key] = model.SecretTemplateOptions{
Value: string(value),
SecretPath: destination.SecretsPath,
}
}
if infisicalPushSecret.Spec.Push.Secret.Template == nil || (infisicalPushSecret.Spec.Push.Secret.Template != nil && infisicalPushSecret.Spec.Push.Secret.Template.IncludeAllSecrets) {
for key, value := range kubePushSecret.Data {
processedSecrets[key] = string(value)
}
}
if infisicalPushSecret.Spec.Push.Secret.Template != nil &&
len(infisicalPushSecret.Spec.Push.Secret.Template.Data) > 0 {
for templateKey, userTemplate := range infisicalPushSecret.Spec.Push.Secret.Template.Data {
tmpl, err := template.New("push-secret-templates").Funcs(util.InfisicalSecretTemplateFunctions).Parse(userTemplate)
if err != nil {
return nil, fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err)
}
buf := bytes.NewBuffer(nil)
err = tmpl.Execute(buf, sourceSecrets)
if err != nil {
return nil, fmt.Errorf("unable to execute template: %s [err=%v]", templateKey, err)
}
processedSecrets[templateKey] = buf.String()
}
}
return processedSecrets, nil
}
func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context.Context, logger logr.Logger, infisicalPushSecret v1alpha1.InfisicalPushSecret) error { func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context.Context, logger logr.Logger, infisicalPushSecret v1alpha1.InfisicalPushSecret) error {
resourceVariables := r.getResourceVariables(infisicalPushSecret) resourceVariables := r.getResourceVariables(infisicalPushSecret)
@@ -134,10 +180,9 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
return fmt.Errorf("unable to fetch kube secret [err=%s]", err) return fmt.Errorf("unable to fetch kube secret [err=%s]", err)
} }
var kubeSecrets = make(map[string]string) processedSecrets, err := r.processTemplatedSecrets(infisicalPushSecret, kubePushSecret, infisicalPushSecret.Spec.Destination)
if err != nil {
for key, value := range kubePushSecret.Data { return fmt.Errorf("unable to process templated secrets [err=%s]", err)
kubeSecrets[key] = string(value)
} }
destination := infisicalPushSecret.Spec.Destination destination := infisicalPushSecret.Spec.Destination
@@ -191,7 +236,7 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
infisicalPushSecret.Status.ManagedSecrets = make(map[string]string) // (string[id], string[key] ) infisicalPushSecret.Status.ManagedSecrets = make(map[string]string) // (string[id], string[key] )
for secretKey, secretValue := range kubeSecrets { for secretKey, secretValue := range processedSecrets {
if exists := getExistingSecretByKey(secretKey); exists != nil { if exists := getExistingSecretByKey(secretKey); exists != nil {
if updatePolicy == string(constants.PUSH_SECRET_REPLACE_POLICY_ENABLED) { if updatePolicy == string(constants.PUSH_SECRET_REPLACE_POLICY_ENABLED) {
@@ -280,7 +325,7 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
// We need to check if any of the secrets have been removed in the new kube secret // We need to check if any of the secrets have been removed in the new kube secret
for _, managedSecretKey := range infisicalPushSecret.Status.ManagedSecrets { for _, managedSecretKey := range infisicalPushSecret.Status.ManagedSecrets {
if _, ok := kubeSecrets[managedSecretKey]; !ok { if _, ok := processedSecrets[managedSecretKey]; !ok {
// Secret has been removed, verify that the secret is managed by the operator // Secret has been removed, verify that the secret is managed by the operator
if getExistingSecretByKey(managedSecretKey) != nil { if getExistingSecretByKey(managedSecretKey) != nil {
@@ -305,7 +350,7 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
} }
// We need to check if any new secrets have been added in the kube secret // We need to check if any new secrets have been added in the kube secret
for currentSecretKey := range kubeSecrets { for currentSecretKey := range processedSecrets {
if exists := getExistingSecretByKey(currentSecretKey); exists == nil { if exists := getExistingSecretByKey(currentSecretKey); exists == nil {
@@ -317,7 +362,7 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
createdSecret, err := infisicalClient.Secrets().Create(infisicalSdk.CreateSecretOptions{ createdSecret, err := infisicalClient.Secrets().Create(infisicalSdk.CreateSecretOptions{
SecretKey: currentSecretKey, SecretKey: currentSecretKey,
SecretValue: kubeSecrets[currentSecretKey], SecretValue: processedSecrets[currentSecretKey],
ProjectID: destination.ProjectID, ProjectID: destination.ProjectID,
Environment: destination.EnvironmentSlug, Environment: destination.EnvironmentSlug,
SecretPath: destination.SecretsPath, SecretPath: destination.SecretsPath,
@@ -336,12 +381,12 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
existingSecret := getExistingSecretByKey(currentSecretKey) existingSecret := getExistingSecretByKey(currentSecretKey)
if existingSecret != nil && existingSecret.SecretValue != kubeSecrets[currentSecretKey] { if existingSecret != nil && existingSecret.SecretValue != processedSecrets[currentSecretKey] {
logger.Info(fmt.Sprintf("Secret with key [key=%s] has changed value. Updating secret in Infisical", currentSecretKey)) logger.Info(fmt.Sprintf("Secret with key [key=%s] has changed value. Updating secret in Infisical", currentSecretKey))
updatedSecret, err := infisicalClient.Secrets().Update(infisicalSdk.UpdateSecretOptions{ updatedSecret, err := infisicalClient.Secrets().Update(infisicalSdk.UpdateSecretOptions{
SecretKey: currentSecretKey, SecretKey: currentSecretKey,
NewSecretValue: kubeSecrets[currentSecretKey], NewSecretValue: processedSecrets[currentSecretKey],
ProjectID: destination.ProjectID, ProjectID: destination.ProjectID,
Environment: destination.EnvironmentSlug, Environment: destination.EnvironmentSlug,
SecretPath: destination.SecretsPath, SecretPath: destination.SecretsPath,
@@ -353,7 +398,7 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
continue continue
} }
updateExistingSecretByKey(currentSecretKey, kubeSecrets[currentSecretKey]) updateExistingSecretByKey(currentSecretKey, processedSecrets[currentSecretKey])
infisicalPushSecret.Status.ManagedSecrets[updatedSecret.ID] = currentSecretKey infisicalPushSecret.Status.ManagedSecrets[updatedSecret.ID] = currentSecretKey
} }
} }
@@ -361,7 +406,7 @@ func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context
} }
// Check if any of the existing secrets values have changed // Check if any of the existing secrets values have changed
for secretKey, secretValue := range kubeSecrets { for secretKey, secretValue := range processedSecrets {
existingSecret := getExistingSecretByKey(secretKey) existingSecret := getExistingSecretByKey(secretKey)

View File

@@ -3,7 +3,6 @@ package controllers
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/base64"
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
@@ -156,16 +155,6 @@ func (r *InfisicalSecretReconciler) getInfisicalServiceAccountCredentialsFromKub
return model.ServiceAccountDetails{AccessKey: string(accessKeyFromSecret), PrivateKey: string(privateKeyFromSecret), PublicKey: string(publicKeyFromSecret)}, nil return model.ServiceAccountDetails{AccessKey: string(accessKeyFromSecret), PrivateKey: string(privateKeyFromSecret), PublicKey: string(publicKeyFromSecret)}, nil
} }
var infisicalSecretTemplateFunctions = template.FuncMap{
"decodeBase64ToBytes": func(encodedString string) string {
decoded, err := base64.StdEncoding.DecodeString(encodedString)
if err != nil {
panic(fmt.Sprintf("Error: %v", err))
}
return string(decoded)
},
}
func convertBinaryToStringMap(binaryMap map[string][]byte) map[string]string { func convertBinaryToStringMap(binaryMap map[string][]byte) map[string]string {
stringMap := make(map[string]string) stringMap := make(map[string]string)
for k, v := range binaryMap { for k, v := range binaryMap {
@@ -177,7 +166,7 @@ func convertBinaryToStringMap(binaryMap map[string][]byte) map[string]string {
func (r *InfisicalSecretReconciler) createInfisicalManagedKubeResource(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret, managedSecretReferenceInterface interface{}, secretsFromAPI []model.SingleEnvironmentVariable, ETag string, resourceType constants.ManagedKubeResourceType) error { func (r *InfisicalSecretReconciler) createInfisicalManagedKubeResource(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret, managedSecretReferenceInterface interface{}, secretsFromAPI []model.SingleEnvironmentVariable, ETag string, resourceType constants.ManagedKubeResourceType) error {
plainProcessedSecrets := make(map[string][]byte) plainProcessedSecrets := make(map[string][]byte)
var managedTemplateData *v1alpha1.InfisicalSecretTemplate var managedTemplateData *v1alpha1.SecretTemplate
if resourceType == constants.MANAGED_KUBE_RESOURCE_TYPE_SECRET { if resourceType == constants.MANAGED_KUBE_RESOURCE_TYPE_SECRET {
managedTemplateData = managedSecretReferenceInterface.(v1alpha1.ManagedKubeSecretConfig).Template managedTemplateData = managedSecretReferenceInterface.(v1alpha1.ManagedKubeSecretConfig).Template
@@ -201,7 +190,7 @@ func (r *InfisicalSecretReconciler) createInfisicalManagedKubeResource(ctx conte
} }
for templateKey, userTemplate := range managedTemplateData.Data { for templateKey, userTemplate := range managedTemplateData.Data {
tmpl, err := template.New("secret-templates").Funcs(infisicalSecretTemplateFunctions).Parse(userTemplate) tmpl, err := template.New("secret-templates").Funcs(util.InfisicalSecretTemplateFunctions).Parse(userTemplate)
if err != nil { if err != nil {
return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err) return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err)
} }
@@ -322,7 +311,7 @@ func (r *InfisicalSecretReconciler) updateInfisicalManagedKubeSecret(ctx context
} }
for templateKey, userTemplate := range managedTemplateData.Data { for templateKey, userTemplate := range managedTemplateData.Data {
tmpl, err := template.New("secret-templates").Funcs(infisicalSecretTemplateFunctions).Parse(userTemplate) tmpl, err := template.New("secret-templates").Funcs(util.InfisicalSecretTemplateFunctions).Parse(userTemplate)
if err != nil { if err != nil {
return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err) return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err)
} }
@@ -373,7 +362,7 @@ func (r *InfisicalSecretReconciler) updateInfisicalManagedConfigMap(ctx context.
} }
for templateKey, userTemplate := range managedTemplateData.Data { for templateKey, userTemplate := range managedTemplateData.Data {
tmpl, err := template.New("secret-templates").Funcs(infisicalSecretTemplateFunctions).Parse(userTemplate) tmpl, err := template.New("secret-templates").Funcs(util.InfisicalSecretTemplateFunctions).Parse(userTemplate)
if err != nil { if err != nil {
return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err) return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err)
} }

View File

@@ -0,0 +1,20 @@
package util
import (
"encoding/base64"
"fmt"
"text/template"
)
var InfisicalSecretTemplateFunctions = template.FuncMap{
"decodeBase64ToBytes": func(encodedString string) string {
decoded, err := base64.StdEncoding.DecodeString(encodedString)
if err != nil {
panic(fmt.Sprintf("Error: %v", err))
}
return string(decoded)
},
"encodeBase64": func(plainString string) string {
return base64.StdEncoding.EncodeToString([]byte(plainString))
},
}