mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-10 14:28:35 +00:00
574 lines
20 KiB
Go
574 lines
20 KiB
Go
package infisicalpushsecret
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
tpl "text/template"
|
|
|
|
"github.com/Infisical/infisical/k8-operator/api/v1alpha1"
|
|
"github.com/Infisical/infisical/k8-operator/internal/api"
|
|
"github.com/Infisical/infisical/k8-operator/internal/constants"
|
|
"github.com/Infisical/infisical/k8-operator/internal/model"
|
|
"github.com/Infisical/infisical/k8-operator/internal/template"
|
|
"github.com/Infisical/infisical/k8-operator/internal/util"
|
|
"github.com/go-logr/logr"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
generatorUtil "github.com/Infisical/infisical/k8-operator/internal/generator"
|
|
infisicalSdk "github.com/infisical/go-sdk"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
)
|
|
|
|
type InfisicalPushSecretReconciler struct {
|
|
client.Client
|
|
Scheme *runtime.Scheme
|
|
IsNamespaceScoped bool
|
|
}
|
|
|
|
func (r *InfisicalPushSecretReconciler) getResourceVariables(infisicalPushSecret v1alpha1.InfisicalPushSecret, resourceVariablesMap map[string]util.ResourceVariables) util.ResourceVariables {
|
|
|
|
var resourceVariables util.ResourceVariables
|
|
|
|
if _, ok := resourceVariablesMap[string(infisicalPushSecret.UID)]; !ok {
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
client := infisicalSdk.NewInfisicalClient(ctx, infisicalSdk.Config{
|
|
SiteUrl: api.API_HOST_URL,
|
|
CaCertificate: api.API_CA_CERTIFICATE,
|
|
UserAgent: api.USER_AGENT_NAME,
|
|
})
|
|
|
|
resourceVariablesMap[string(infisicalPushSecret.UID)] = util.ResourceVariables{
|
|
InfisicalClient: client,
|
|
CancelCtx: cancel,
|
|
AuthDetails: util.AuthenticationDetails{},
|
|
}
|
|
|
|
resourceVariables = resourceVariablesMap[string(infisicalPushSecret.UID)]
|
|
|
|
} else {
|
|
resourceVariables = resourceVariablesMap[string(infisicalPushSecret.UID)]
|
|
}
|
|
|
|
return resourceVariables
|
|
|
|
}
|
|
|
|
func (r *InfisicalPushSecretReconciler) updateResourceVariables(infisicalPushSecret v1alpha1.InfisicalPushSecret, resourceVariables util.ResourceVariables, resourceVariablesMap map[string]util.ResourceVariables) {
|
|
resourceVariablesMap[string(infisicalPushSecret.UID)] = resourceVariables
|
|
}
|
|
|
|
func (r *InfisicalPushSecretReconciler) processGenerators(ctx context.Context, infisicalPushSecret v1alpha1.InfisicalPushSecret) (map[string]string, error) {
|
|
|
|
processedSecrets := make(map[string]string)
|
|
|
|
if len(infisicalPushSecret.Spec.Push.Generators) == 0 {
|
|
return processedSecrets, nil
|
|
}
|
|
|
|
for _, generator := range infisicalPushSecret.Spec.Push.Generators {
|
|
generatorRef := generator.GeneratorRef
|
|
|
|
clusterGenerator := &v1alpha1.ClusterGenerator{}
|
|
err := r.Client.Get(ctx, types.NamespacedName{Name: generatorRef.Name}, clusterGenerator)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to get ClusterGenerator resource [err=%s]", err)
|
|
}
|
|
if generatorRef.Kind == v1alpha1.GeneratorKindPassword {
|
|
// get the custom ClusterGenerator resource from the cluster
|
|
|
|
if clusterGenerator.Spec.Generator.PasswordSpec == nil {
|
|
return nil, fmt.Errorf("password spec is not defined in the ClusterGenerator resource")
|
|
}
|
|
|
|
password, err := generatorUtil.GeneratorPassword(*clusterGenerator.Spec.Generator.PasswordSpec)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to generate password [err=%s]", err)
|
|
}
|
|
|
|
processedSecrets[generator.DestinationSecretName] = password
|
|
}
|
|
|
|
if generatorRef.Kind == v1alpha1.GeneratorKindUUID {
|
|
|
|
uuid, err := generatorUtil.GeneratorUUID()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to generate UUID [err=%s]", err)
|
|
}
|
|
|
|
processedSecrets[generator.DestinationSecretName] = uuid
|
|
}
|
|
}
|
|
|
|
return processedSecrets, nil
|
|
|
|
}
|
|
|
|
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 := tpl.New("push-secret-templates").Funcs(template.GetTemplateFunctions()).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, resourceVariablesMap map[string]util.ResourceVariables) error {
|
|
|
|
resourceVariables := r.getResourceVariables(*infisicalPushSecret, resourceVariablesMap)
|
|
infisicalClient := resourceVariables.InfisicalClient
|
|
cancelCtx := resourceVariables.CancelCtx
|
|
authDetails := resourceVariables.AuthDetails
|
|
var err error
|
|
|
|
if authDetails.AuthStrategy == "" {
|
|
logger.Info("No authentication strategy found. Attempting to authenticate")
|
|
authDetails, err = util.HandleAuthentication(ctx, util.SecretAuthInput{
|
|
Secret: *infisicalPushSecret,
|
|
Type: util.SecretCrd.INFISICAL_PUSH_SECRET,
|
|
}, r.Client, infisicalClient, r.IsNamespaceScoped)
|
|
r.SetAuthenticatedStatusCondition(ctx, infisicalPushSecret, err)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("unable to authenticate [err=%s]", err)
|
|
}
|
|
|
|
r.updateResourceVariables(*infisicalPushSecret, util.ResourceVariables{
|
|
InfisicalClient: infisicalClient,
|
|
CancelCtx: cancelCtx,
|
|
AuthDetails: authDetails,
|
|
}, resourceVariablesMap)
|
|
}
|
|
|
|
processedSecrets := make(map[string]string)
|
|
|
|
if infisicalPushSecret.Spec.Push.Secret != nil {
|
|
kubePushSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{
|
|
Namespace: infisicalPushSecret.Spec.Push.Secret.SecretNamespace,
|
|
Name: infisicalPushSecret.Spec.Push.Secret.SecretName,
|
|
})
|
|
|
|
if err != nil {
|
|
if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) {
|
|
return fmt.Errorf("unable to fetch Kubernetes destination secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the destination secret is in the same namespace as the operator. [err=%v]", err)
|
|
}
|
|
|
|
return fmt.Errorf("unable to fetch kube secret [err=%s]", err)
|
|
}
|
|
|
|
processedSecrets, err = r.processTemplatedSecrets(*infisicalPushSecret, kubePushSecret, infisicalPushSecret.Spec.Destination)
|
|
if err != nil {
|
|
return fmt.Errorf("unable to process templated secrets [err=%s]", err)
|
|
}
|
|
}
|
|
|
|
generatorSecrets, err := r.processGenerators(ctx, *infisicalPushSecret)
|
|
if err != nil {
|
|
return fmt.Errorf("unable to process generators [err=%s]", err)
|
|
}
|
|
|
|
for key, value := range generatorSecrets {
|
|
processedSecrets[key] = value
|
|
}
|
|
|
|
destination := infisicalPushSecret.Spec.Destination
|
|
existingSecrets, err := infisicalClient.Secrets().List(infisicalSdk.ListSecretsOptions{
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
IncludeImports: false,
|
|
})
|
|
|
|
getExistingSecretByKey := func(key string) *infisicalSdk.Secret {
|
|
for _, secret := range existingSecrets {
|
|
if secret.SecretKey == key {
|
|
return &secret
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
getExistingSecretById := func(id string) *infisicalSdk.Secret {
|
|
for _, secret := range existingSecrets {
|
|
if secret.ID == id {
|
|
return &secret
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
updateExistingSecretByKey := func(key string, newSecretValue string) {
|
|
for i := range existingSecrets {
|
|
if existingSecrets[i].SecretKey == key {
|
|
existingSecrets[i].SecretValue = newSecretValue
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("unable to list secrets [err=%s]", err)
|
|
}
|
|
|
|
updatePolicy := infisicalPushSecret.Spec.UpdatePolicy
|
|
|
|
var secretsFailedToCreate []string
|
|
var secretsFailedToUpdate []string
|
|
var secretsFailedToDelete []string
|
|
var secretsFailedToReplaceById []string
|
|
|
|
// If the ManagedSecrets are nil, we know this is the first time the InfisicalPushSecret is being reconciled.
|
|
if infisicalPushSecret.Status.ManagedSecrets == nil {
|
|
|
|
infisicalPushSecret.Status.ManagedSecrets = make(map[string]string) // (string[id], string[key] )
|
|
|
|
for secretKey, secretValue := range processedSecrets {
|
|
if exists := getExistingSecretByKey(secretKey); exists != nil {
|
|
|
|
if updatePolicy == string(constants.PUSH_SECRET_REPLACE_POLICY_ENABLED) {
|
|
updatedSecret, err := infisicalClient.Secrets().Update(infisicalSdk.UpdateSecretOptions{
|
|
SecretKey: secretKey,
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
NewSecretValue: secretValue,
|
|
})
|
|
|
|
if err != nil {
|
|
secretsFailedToUpdate = append(secretsFailedToUpdate, secretKey)
|
|
logger.Info(fmt.Sprintf("unable to update secret [key=%s] [err=%s]", secretKey, err))
|
|
continue
|
|
}
|
|
|
|
infisicalPushSecret.Status.ManagedSecrets[updatedSecret.ID] = secretKey
|
|
}
|
|
} else {
|
|
createdSecret, err := infisicalClient.Secrets().Create(infisicalSdk.CreateSecretOptions{
|
|
SecretKey: secretKey,
|
|
SecretValue: secretValue,
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
})
|
|
|
|
if err != nil {
|
|
secretsFailedToCreate = append(secretsFailedToCreate, secretKey)
|
|
logger.Info(fmt.Sprintf("unable to create secret [key=%s] [err=%s]", secretKey, err))
|
|
continue
|
|
}
|
|
|
|
infisicalPushSecret.Status.ManagedSecrets[createdSecret.ID] = secretKey
|
|
}
|
|
}
|
|
} else {
|
|
|
|
// Loop over all the managed secrets, and find the corresponding existingSecret that has the same ID. If the key doesn't match, delete the secret, and re-create it with the correct key/value
|
|
for managedSecretId, managedSecretKey := range infisicalPushSecret.Status.ManagedSecrets {
|
|
|
|
existingSecret := getExistingSecretById(managedSecretId)
|
|
|
|
if existingSecret != nil {
|
|
|
|
if existingSecret.SecretKey != managedSecretKey {
|
|
// Secret key has changed, lets delete the secret and re-create it with the correct key
|
|
|
|
logger.Info(fmt.Sprintf("Secret with ID [id=%s] has changed key from [%s] to [%s]. Deleting and re-creating secret", managedSecretId, managedSecretKey, existingSecret.SecretKey))
|
|
|
|
deletedSecret, err := infisicalClient.Secrets().Delete(infisicalSdk.DeleteSecretOptions{
|
|
SecretKey: existingSecret.SecretKey,
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
})
|
|
|
|
if err != nil {
|
|
secretsFailedToReplaceById = append(secretsFailedToReplaceById, managedSecretKey)
|
|
logger.Info(fmt.Sprintf("unable to delete secret [key=%s] [err=%s]", managedSecretKey, err))
|
|
continue
|
|
}
|
|
|
|
createdSecret, err := infisicalClient.Secrets().Create(infisicalSdk.CreateSecretOptions{
|
|
SecretKey: managedSecretKey,
|
|
SecretValue: existingSecret.SecretValue,
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
})
|
|
|
|
if err != nil {
|
|
secretsFailedToReplaceById = append(secretsFailedToReplaceById, managedSecretKey)
|
|
logger.Info(fmt.Sprintf("unable to create secret [key=%s] [err=%s]", managedSecretKey, err))
|
|
continue
|
|
}
|
|
|
|
delete(infisicalPushSecret.Status.ManagedSecrets, deletedSecret.ID)
|
|
infisicalPushSecret.Status.ManagedSecrets[createdSecret.ID] = managedSecretKey
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// We need to check if any of the secrets have been removed in the new kube secret
|
|
for _, managedSecretKey := range infisicalPushSecret.Status.ManagedSecrets {
|
|
|
|
if _, ok := processedSecrets[managedSecretKey]; !ok {
|
|
|
|
// Secret has been removed, verify that the secret is managed by the operator
|
|
if getExistingSecretByKey(managedSecretKey) != nil {
|
|
logger.Info(fmt.Sprintf("Secret with key [key=%s] has been removed from the kube secret. Deleting secret from Infisical", managedSecretKey))
|
|
|
|
deletedSecret, err := infisicalClient.Secrets().Delete(infisicalSdk.DeleteSecretOptions{
|
|
SecretKey: managedSecretKey,
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
})
|
|
|
|
if err != nil {
|
|
secretsFailedToDelete = append(secretsFailedToDelete, managedSecretKey)
|
|
logger.Info(fmt.Sprintf("unable to delete secret [key=%s] [err=%s]", managedSecretKey, err))
|
|
continue
|
|
}
|
|
|
|
delete(infisicalPushSecret.Status.ManagedSecrets, deletedSecret.ID)
|
|
}
|
|
}
|
|
}
|
|
|
|
// We need to check if any new secrets have been added in the kube secret
|
|
for currentSecretKey := range processedSecrets {
|
|
|
|
if exists := getExistingSecretByKey(currentSecretKey); exists == nil {
|
|
|
|
// Some secrets has been added, verify that the secret that has been added is not already managed by the operator
|
|
if _, ok := infisicalPushSecret.Status.ManagedSecrets[currentSecretKey]; !ok {
|
|
|
|
// Secret was not managed by the operator, lets add it
|
|
logger.Info(fmt.Sprintf("Secret with key [key=%s] has been added to the kube secret. Creating secret in Infisical", currentSecretKey))
|
|
|
|
createdSecret, err := infisicalClient.Secrets().Create(infisicalSdk.CreateSecretOptions{
|
|
SecretKey: currentSecretKey,
|
|
SecretValue: processedSecrets[currentSecretKey],
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
})
|
|
|
|
if err != nil {
|
|
secretsFailedToCreate = append(secretsFailedToCreate, currentSecretKey)
|
|
logger.Info(fmt.Sprintf("unable to create secret [key=%s] [err=%s]", currentSecretKey, err))
|
|
continue
|
|
}
|
|
|
|
infisicalPushSecret.Status.ManagedSecrets[createdSecret.ID] = currentSecretKey
|
|
}
|
|
} else {
|
|
if updatePolicy == string(constants.PUSH_SECRET_REPLACE_POLICY_ENABLED) {
|
|
|
|
existingSecret := getExistingSecretByKey(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))
|
|
|
|
updatedSecret, err := infisicalClient.Secrets().Update(infisicalSdk.UpdateSecretOptions{
|
|
SecretKey: currentSecretKey,
|
|
NewSecretValue: processedSecrets[currentSecretKey],
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
})
|
|
|
|
if err != nil {
|
|
secretsFailedToUpdate = append(secretsFailedToUpdate, currentSecretKey)
|
|
logger.Info(fmt.Sprintf("unable to update secret [key=%s] [err=%s]", currentSecretKey, err))
|
|
continue
|
|
}
|
|
|
|
updateExistingSecretByKey(currentSecretKey, processedSecrets[currentSecretKey])
|
|
infisicalPushSecret.Status.ManagedSecrets[updatedSecret.ID] = currentSecretKey
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if any of the existing secrets values have changed
|
|
for secretKey, secretValue := range processedSecrets {
|
|
|
|
existingSecret := getExistingSecretByKey(secretKey)
|
|
|
|
if existingSecret != nil {
|
|
|
|
_, managedByOperator := infisicalPushSecret.Status.ManagedSecrets[existingSecret.ID]
|
|
|
|
if secretValue != existingSecret.SecretValue {
|
|
|
|
if managedByOperator || updatePolicy == string(constants.PUSH_SECRET_REPLACE_POLICY_ENABLED) {
|
|
logger.Info(fmt.Sprintf("Secret with key [key=%s] has changed value. Updating secret in Infisical", secretKey))
|
|
|
|
updatedSecret, err := infisicalClient.Secrets().Update(infisicalSdk.UpdateSecretOptions{
|
|
SecretKey: secretKey,
|
|
NewSecretValue: secretValue,
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
})
|
|
|
|
if err != nil {
|
|
secretsFailedToUpdate = append(secretsFailedToUpdate, secretKey)
|
|
logger.Info(fmt.Sprintf("unable to update secret [key=%s] [err=%s]", secretKey, err))
|
|
continue
|
|
}
|
|
|
|
infisicalPushSecret.Status.ManagedSecrets[updatedSecret.ID] = secretKey
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var errorMessage string
|
|
if len(secretsFailedToCreate) > 0 {
|
|
errorMessage = fmt.Sprintf("Failed to create secrets: [%s]", strings.Join(secretsFailedToCreate, ", "))
|
|
} else {
|
|
errorMessage = ""
|
|
}
|
|
r.SetFailedToCreateSecretsStatusCondition(ctx, infisicalPushSecret, fmt.Sprintf("Failed to create secrets: [%s]", errorMessage))
|
|
|
|
if len(secretsFailedToUpdate) > 0 {
|
|
errorMessage = fmt.Sprintf("Failed to update secrets: [%s]", strings.Join(secretsFailedToUpdate, ", "))
|
|
} else {
|
|
errorMessage = ""
|
|
}
|
|
r.SetFailedToUpdateSecretsStatusCondition(ctx, infisicalPushSecret, fmt.Sprintf("Failed to update secrets: [%s]", errorMessage))
|
|
|
|
if len(secretsFailedToDelete) > 0 {
|
|
errorMessage = fmt.Sprintf("Failed to delete secrets: [%s]", strings.Join(secretsFailedToDelete, ", "))
|
|
} else {
|
|
errorMessage = ""
|
|
}
|
|
r.SetFailedToDeleteSecretsStatusCondition(ctx, infisicalPushSecret, errorMessage)
|
|
|
|
if len(secretsFailedToReplaceById) > 0 {
|
|
errorMessage = fmt.Sprintf("Failed to replace secrets: [%s]", strings.Join(secretsFailedToReplaceById, ", "))
|
|
} else {
|
|
errorMessage = ""
|
|
}
|
|
r.SetFailedToReplaceSecretsStatusCondition(ctx, infisicalPushSecret, errorMessage)
|
|
|
|
// Update the status of the InfisicalPushSecret
|
|
if err := r.Client.Status().Update(ctx, infisicalPushSecret); err != nil {
|
|
return fmt.Errorf("unable to update status of InfisicalPushSecret [err=%s]", err)
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func (r *InfisicalPushSecretReconciler) DeleteManagedSecrets(ctx context.Context, logger logr.Logger, infisicalPushSecret *v1alpha1.InfisicalPushSecret, resourceVariablesMap map[string]util.ResourceVariables) error {
|
|
if infisicalPushSecret.Spec.DeletionPolicy != string(constants.PUSH_SECRET_DELETE_POLICY_ENABLED) {
|
|
return nil
|
|
}
|
|
|
|
resourceVariables := r.getResourceVariables(*infisicalPushSecret, resourceVariablesMap)
|
|
infisicalClient := resourceVariables.InfisicalClient
|
|
cancelCtx := resourceVariables.CancelCtx
|
|
authDetails := resourceVariables.AuthDetails
|
|
var err error
|
|
|
|
if authDetails.AuthStrategy == "" {
|
|
logger.Info("No authentication strategy found. Attempting to authenticate")
|
|
authDetails, err = util.HandleAuthentication(ctx, util.SecretAuthInput{
|
|
Secret: *infisicalPushSecret,
|
|
Type: util.SecretCrd.INFISICAL_PUSH_SECRET,
|
|
}, r.Client, infisicalClient, r.IsNamespaceScoped)
|
|
r.SetAuthenticatedStatusCondition(ctx, infisicalPushSecret, err)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("unable to authenticate [err=%s]", err)
|
|
}
|
|
|
|
r.updateResourceVariables(*infisicalPushSecret, util.ResourceVariables{
|
|
InfisicalClient: infisicalClient,
|
|
CancelCtx: cancelCtx,
|
|
AuthDetails: authDetails,
|
|
}, resourceVariablesMap)
|
|
}
|
|
|
|
destination := infisicalPushSecret.Spec.Destination
|
|
existingSecrets, err := resourceVariables.InfisicalClient.Secrets().List(infisicalSdk.ListSecretsOptions{
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
IncludeImports: false,
|
|
})
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("unable to list secrets [err=%s]", err)
|
|
}
|
|
|
|
existingSecretsMappedById := make(map[string]infisicalSdk.Secret)
|
|
for _, secret := range existingSecrets {
|
|
existingSecretsMappedById[secret.ID] = secret
|
|
}
|
|
|
|
for managedSecretId, managedSecretKey := range infisicalPushSecret.Status.ManagedSecrets {
|
|
|
|
if _, ok := existingSecretsMappedById[managedSecretId]; ok {
|
|
logger.Info(fmt.Sprintf("Deleting secret with key [key=%s]", managedSecretKey))
|
|
|
|
_, err := infisicalClient.Secrets().Delete(infisicalSdk.DeleteSecretOptions{
|
|
SecretKey: managedSecretKey,
|
|
ProjectID: destination.ProjectID,
|
|
Environment: destination.EnvironmentSlug,
|
|
SecretPath: destination.SecretsPath,
|
|
})
|
|
|
|
if err != nil {
|
|
logger.Info(fmt.Sprintf("unable to delete secret [key=%s] [err=%s]", managedSecretKey, err))
|
|
continue
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|