diff --git a/helm-charts/secrets-operator/Chart.yaml b/helm-charts/secrets-operator/Chart.yaml index 9c4f83248..91632c97d 100644 --- a/helm-charts/secrets-operator/Chart.yaml +++ b/helm-charts/secrets-operator/Chart.yaml @@ -13,9 +13,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: v0.5.1 +version: v0.5.2 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "v0.5.0" +appVersion: "v0.5.2" diff --git a/helm-charts/secrets-operator/values.yaml b/helm-charts/secrets-operator/values.yaml index 8054b1b0c..8564e79f5 100644 --- a/helm-charts/secrets-operator/values.yaml +++ b/helm-charts/secrets-operator/values.yaml @@ -32,7 +32,7 @@ controllerManager: - ALL image: repository: infisical/kubernetes-operator - tag: v0.5.1 # fixed to prevent accidental upgrade + tag: v0.5.2 # fixed to prevent accidental upgrade resources: limits: cpu: 500m diff --git a/k8-operator/packages/api/api.go b/k8-operator/packages/api/api.go index 233925dda..5ca3bdba3 100644 --- a/k8-operator/packages/api/api.go +++ b/k8-operator/packages/api/api.go @@ -156,6 +156,7 @@ func CallGetDecryptedSecretsV3(httpClient *resty.Client, request GetDecryptedSec R(). SetResult(&decryptedSecretsResponse). SetHeader("User-Agent", USER_AGENT_NAME). + SetQueryParam("include_imports", "true"). SetQueryParam("secretPath", request.SecretPath). SetQueryParam("workspaceSlug", request.ProjectSlug). SetQueryParam("environment", request.Environment) @@ -163,6 +164,9 @@ func CallGetDecryptedSecretsV3(httpClient *resty.Client, request GetDecryptedSec if request.Recursive { req.SetQueryParam("recursive", "true") } + if request.ExpandSecretReferences { + req.SetQueryParam("expandSecretReferences", "true") + } response, err := req.Get(fmt.Sprintf("%v/v3/secrets/raw", API_HOST_URL)) diff --git a/k8-operator/packages/api/models.go b/k8-operator/packages/api/models.go index ccb8d0d00..8439e4918 100644 --- a/k8-operator/packages/api/models.go +++ b/k8-operator/packages/api/models.go @@ -84,6 +84,13 @@ type ImportedSecretV3 struct { Secrets []EncryptedSecretV3 `json:"secrets"` } +type ImportedRawSecretV3 struct { + Environment string `json:"environment"` + FolderId string `json:"folderId"` + SecretPath string `json:"secretPath"` + Secrets []DecryptedSecretV3 `json:"secrets"` +} + type GetEncryptedSecretsV3Response struct { Secrets []EncryptedSecretV3 `json:"secrets"` ImportedSecrets []ImportedSecretV3 `json:"imports,omitempty"` @@ -92,17 +99,19 @@ type GetEncryptedSecretsV3Response struct { } type GetDecryptedSecretsV3Response struct { - Secrets []DecryptedSecretV3 `json:"secrets"` - ETag string `json:"ETag,omitempty"` - Modified bool `json:"modified,omitempty"` + Secrets []DecryptedSecretV3 `json:"secrets"` + ETag string `json:"ETag,omitempty"` + Modified bool `json:"modified,omitempty"` + Imports []ImportedRawSecretV3 `json:"imports,omitempty"` } type GetDecryptedSecretsV3Request struct { - ProjectSlug string `json:"workspaceSlug"` - Environment string `json:"environment"` - SecretPath string `json:"secretPath"` - Recursive bool `json:"recursive"` - ETag string `json:"etag,omitempty"` + ProjectSlug string `json:"workspaceSlug"` + Environment string `json:"environment"` + SecretPath string `json:"secretPath"` + Recursive bool `json:"recursive"` + ExpandSecretReferences bool `json:"expandSecretReferences"` + ETag string `json:"etag,omitempty"` } type GetServiceTokenDetailsResponse struct { diff --git a/k8-operator/packages/util/secrets.go b/k8-operator/packages/util/secrets.go index 290e1340c..ee0666ea8 100644 --- a/k8-operator/packages/util/secrets.go +++ b/k8-operator/packages/util/secrets.go @@ -58,11 +58,12 @@ func GetPlainTextSecretsViaUniversalAuth(accessToken string, etag string, secret httpClient.SetAuthToken(accessToken) secretsResponse, err := api.CallGetDecryptedSecretsV3(httpClient, api.GetDecryptedSecretsV3Request{ - ProjectSlug: secretScope.ProjectSlug, - Environment: secretScope.EnvSlug, - Recursive: secretScope.Recursive, - SecretPath: secretScope.SecretsPath, - ETag: etag, + ProjectSlug: secretScope.ProjectSlug, + Environment: secretScope.EnvSlug, + Recursive: secretScope.Recursive, + SecretPath: secretScope.SecretsPath, + ExpandSecretReferences: true, + ETag: etag, }) if err != nil { @@ -80,7 +81,13 @@ func GetPlainTextSecretsViaUniversalAuth(accessToken string, etag string, secret }) } - return secrets, model.RequestUpdateUpdateDetails{ + // No need to do expansion for Machine Identity auth as this is handled on server-side. + mergedSecrets := MergeRawImportedSecrets(secrets, secretsResponse.Imports) + if err != nil { + return nil, model.RequestUpdateUpdateDetails{}, err + } + + return mergedSecrets, model.RequestUpdateUpdateDetails{ Modified: secretsResponse.Modified, ETag: secretsResponse.ETag, }, nil @@ -435,3 +442,32 @@ func InjectImportedSecret(plainTextWorkspaceKey []byte, secrets []model.SingleEn return secrets, nil } + +func MergeRawImportedSecrets(secrets []model.SingleEnvironmentVariable, importedSecrets []api.ImportedRawSecretV3) []model.SingleEnvironmentVariable { + if importedSecrets == nil { + return secrets + } + + hasOverriden := make(map[string]bool) + for _, sec := range secrets { + hasOverriden[sec.Key] = true + } + + for i := len(importedSecrets) - 1; i >= 0; i-- { + importSec := importedSecrets[i] + + for _, sec := range importSec.Secrets { + if _, ok := hasOverriden[sec.SecretKey]; !ok { + secrets = append(secrets, model.SingleEnvironmentVariable{ + Key: sec.SecretKey, + Value: sec.SecretValue, + Type: sec.Type, + ID: sec.ID, + }) + hasOverriden[sec.SecretKey] = true + } + } + } + + return secrets +}