From 14f38eb961d557827b59fc83c4bfb293a24c9eb7 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 8 May 2024 00:16:51 +0200 Subject: [PATCH 1/8] Feat: Recursive mode types --- k8-operator/api/v1alpha1/infisicalsecret_types.go | 4 ++++ .../crd/bases/secrets.infisical.com_infisicalsecrets.yaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/k8-operator/api/v1alpha1/infisicalsecret_types.go b/k8-operator/api/v1alpha1/infisicalsecret_types.go index c29761b06..f6a7ef022 100644 --- a/k8-operator/api/v1alpha1/infisicalsecret_types.go +++ b/k8-operator/api/v1alpha1/infisicalsecret_types.go @@ -38,6 +38,8 @@ type SecretScopeInWorkspace struct { SecretsPath string `json:"secretsPath"` // +kubebuilder:validation:Required EnvSlug string `json:"envSlug"` + // +kubebuilder:validation:Optional + Recursive bool `json:"recursive"` } type MachineIdentityScopeInWorkspace struct { @@ -47,6 +49,8 @@ type MachineIdentityScopeInWorkspace struct { EnvSlug string `json:"envSlug"` // +kubebuilder:validation:Required ProjectSlug string `json:"projectSlug"` + // +kubebuilder:validation:Optional + Recursive bool `json:"recursive"` } type KubeSecretReference struct { diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml index 811eb9669..855bff7a9 100644 --- a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml +++ b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml @@ -67,6 +67,8 @@ spec: properties: envSlug: type: string + recursive: + type: boolean secretsPath: type: string required: @@ -111,6 +113,8 @@ spec: type: string projectSlug: type: string + recursive: + type: boolean secretsPath: type: string required: From 4a02520147a6dc629221bee81d771ab41ff18f04 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 8 May 2024 00:18:26 +0200 Subject: [PATCH 2/8] Update sample --- k8-operator/config/samples/sample.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/k8-operator/config/samples/sample.yaml b/k8-operator/config/samples/sample.yaml index 65347dec7..1c8a9a3f0 100644 --- a/k8-operator/config/samples/sample.yaml +++ b/k8-operator/config/samples/sample.yaml @@ -19,12 +19,14 @@ spec: secretsScope: envSlug: secretsPath: # Root is "/" + recursive: true # Wether or not to use recursive mode (Fetches all secrets in an environment from a given secret path, and all folders inside the path) / defaults to false universalAuth: secretsScope: projectSlug: envSlug: # "dev", "staging", "prod", etc.. secretsPath: "" # Root is "/" + recursive: true # Wether or not to use recursive mode (Fetches all secrets in an environment from a given secret path, and all folders inside the path) / defaults to false credentialsRef: secretName: universal-auth-credentials From 1f6abc7f27b840c2f9219c4b571600bb0b71a300 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 8 May 2024 00:18:40 +0200 Subject: [PATCH 3/8] Feat: Recursive mode and fix error formatting --- k8-operator/controllers/infisicalsecret_helper.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/k8-operator/controllers/infisicalsecret_helper.go b/k8-operator/controllers/infisicalsecret_helper.go index 4ef378fe2..c14f724eb 100644 --- a/k8-operator/controllers/infisicalsecret_helper.go +++ b/k8-operator/controllers/infisicalsecret_helper.go @@ -269,7 +269,7 @@ func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context } else if infisicalMachineIdentityCreds.ClientId != "" && infisicalMachineIdentityCreds.ClientSecret != "" { authStrategy = AuthStrategy.UNIVERSAL_MACHINE_IDENTITY } else { - return fmt.Errorf("no authentication method provided. You must provide either a valid service token or a service account details to fetch secrets") + return fmt.Errorf("no authentication method provided. You must provide either a valid service token or a service account details to fetch secrets\n") } r.SetInfisicalTokenLoadCondition(ctx, &infisicalSecret, err) @@ -312,8 +312,9 @@ func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context } else if authStrategy == AuthStrategy.SERVICE_TOKEN { // Service Tokens (deprecated) envSlug := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.EnvSlug secretsPath := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.SecretsPath + recursive := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.Recursive - plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaServiceToken(infisicalToken, secretVersionBasedOnETag, envSlug, secretsPath) + plainTextSecretsFromApi, updateDetails, err = util.GetPlainTextSecretsViaServiceToken(infisicalToken, secretVersionBasedOnETag, envSlug, secretsPath, recursive) if err != nil { return fmt.Errorf("\nfailed to get secrets because [err=%v]", err) } From 6b83326d0067cbfce28b463a52823ac07f60e401 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 8 May 2024 00:18:53 +0200 Subject: [PATCH 4/8] Feat: Recursive mode support --- k8-operator/packages/api/api.go | 16 ++++++++++++---- k8-operator/packages/api/models.go | 2 ++ k8-operator/packages/util/secrets.go | 6 ++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/k8-operator/packages/api/api.go b/k8-operator/packages/api/api.go index 05a58e8cb..233925dda 100644 --- a/k8-operator/packages/api/api.go +++ b/k8-operator/packages/api/api.go @@ -66,6 +66,10 @@ func CallGetSecretsV3(httpClient *resty.Client, request GetEncryptedSecretsV3Req httpRequest.SetQueryParam("secretPath", request.SecretPath) } + if request.Recursive { + httpRequest.SetQueryParam("recursive", "true") + } + response, err := httpRequest.Get(fmt.Sprintf("%v/v3/secrets", API_HOST_URL)) if err != nil { @@ -148,19 +152,23 @@ func CallUniversalMachineIdentityRefreshAccessToken(request MachineIdentityUnive func CallGetDecryptedSecretsV3(httpClient *resty.Client, request GetDecryptedSecretsV3Request) (GetDecryptedSecretsV3Response, error) { var decryptedSecretsResponse GetDecryptedSecretsV3Response - response, err := httpClient. + req := httpClient. R(). SetResult(&decryptedSecretsResponse). SetHeader("User-Agent", USER_AGENT_NAME). SetQueryParam("secretPath", request.SecretPath). SetQueryParam("workspaceSlug", request.ProjectSlug). - SetQueryParam("environment", request.Environment). - Get(fmt.Sprintf("%v/v3/secrets/raw", API_HOST_URL)) + SetQueryParam("environment", request.Environment) + + if request.Recursive { + req.SetQueryParam("recursive", "true") + } + + response, err := req.Get(fmt.Sprintf("%v/v3/secrets/raw", API_HOST_URL)) if err != nil { return GetDecryptedSecretsV3Response{}, fmt.Errorf("CallGetDecryptedSecretsV3: Unable to complete api request [err=%s]", err) } - if response.IsError() { return GetDecryptedSecretsV3Response{}, fmt.Errorf("CallGetDecryptedSecretsV3: Unsuccessful response: [response=%s]", response) } diff --git a/k8-operator/packages/api/models.go b/k8-operator/packages/api/models.go index ff4ea3e10..ccb8d0d00 100644 --- a/k8-operator/packages/api/models.go +++ b/k8-operator/packages/api/models.go @@ -31,6 +31,7 @@ type GetEncryptedWorkspaceKeyResponse struct { type GetEncryptedSecretsV3Request struct { Environment string `json:"environment"` WorkspaceId string `json:"workspaceId"` + Recursive bool `json:"recursive"` SecretPath string `json:"secretPath"` IncludeImport bool `json:"include_imports"` ETag string `json:"etag,omitempty"` @@ -100,6 +101,7 @@ type GetDecryptedSecretsV3Request struct { ProjectSlug string `json:"workspaceSlug"` Environment string `json:"environment"` SecretPath string `json:"secretPath"` + Recursive bool `json:"recursive"` ETag string `json:"etag,omitempty"` } diff --git a/k8-operator/packages/util/secrets.go b/k8-operator/packages/util/secrets.go index a8c4a4cc5..290e1340c 100644 --- a/k8-operator/packages/util/secrets.go +++ b/k8-operator/packages/util/secrets.go @@ -60,6 +60,7 @@ func GetPlainTextSecretsViaUniversalAuth(accessToken string, etag string, secret secretsResponse, err := api.CallGetDecryptedSecretsV3(httpClient, api.GetDecryptedSecretsV3Request{ ProjectSlug: secretScope.ProjectSlug, Environment: secretScope.EnvSlug, + Recursive: secretScope.Recursive, SecretPath: secretScope.SecretsPath, ETag: etag, }) @@ -85,7 +86,7 @@ func GetPlainTextSecretsViaUniversalAuth(accessToken string, etag string, secret }, nil } -func GetPlainTextSecretsViaServiceToken(fullServiceToken string, etag string, envSlug string, secretPath string) ([]model.SingleEnvironmentVariable, model.RequestUpdateUpdateDetails, error) { +func GetPlainTextSecretsViaServiceToken(fullServiceToken string, etag string, envSlug string, secretPath string, recursive bool) ([]model.SingleEnvironmentVariable, model.RequestUpdateUpdateDetails, error) { serviceTokenParts := strings.SplitN(fullServiceToken, ".", 4) if len(serviceTokenParts) < 4 { return nil, model.RequestUpdateUpdateDetails{}, fmt.Errorf("invalid service token entered. Please double check your service token and try again") @@ -106,6 +107,7 @@ func GetPlainTextSecretsViaServiceToken(fullServiceToken string, etag string, en encryptedSecretsResponse, err := api.CallGetSecretsV3(httpClient, api.GetEncryptedSecretsV3Request{ WorkspaceId: serviceTokenDetails.Workspace, Environment: envSlug, + Recursive: recursive, ETag: etag, SecretPath: secretPath, }) @@ -376,7 +378,7 @@ func ExpandSecrets(secrets []model.SingleEnvironmentVariable, infisicalToken str if crossRefSec, ok := crossEnvRefSecs[uniqKey]; !ok { // if not in cross reference cache, fetch it from server - refSecs, _, err := GetPlainTextSecretsViaServiceToken(infisicalToken, "", env, secPath) + refSecs, _, err := GetPlainTextSecretsViaServiceToken(infisicalToken, "", env, secPath, false) if err != nil { fmt.Printf("Could not fetch secrets in environment: %s secret-path: %s", env, secPath) // HandleError(err, fmt.Sprintf("Could not fetch secrets in environment: %s secret-path: %s", env, secPath), "If you are using a service token to fetch secrets, please ensure it is valid") From b0421ccad0fa6576b04198223bbe58a7f0f484cc Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 8 May 2024 00:21:08 +0200 Subject: [PATCH 5/8] Docs: Add recursive to example --- docs/integrations/platforms/kubernetes.mdx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/integrations/platforms/kubernetes.mdx b/docs/integrations/platforms/kubernetes.mdx index d1cff4e75..3d1b72331 100644 --- a/docs/integrations/platforms/kubernetes.mdx +++ b/docs/integrations/platforms/kubernetes.mdx @@ -77,6 +77,8 @@ spec: projectSlug: envSlug: # "dev", "staging", "prod", etc.. secretsPath: "" # Root is "/" + recursive: true # Fetch all secrets from the specified path and all sub-directories. Default is false. + credentialsRef: secretName: universal-auth-credentials secretNamespace: default @@ -89,6 +91,7 @@ spec: secretsScope: envSlug: secretsPath: # Root is "/" + recursive: true # Fetch all secrets from the specified path and all sub-directories. Default is false. managedSecretReference: secretName: managed-secret From 0b012c5dfbf3f58cd4c226c052a90ab47a603ab7 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 8 May 2024 00:23:50 +0200 Subject: [PATCH 6/8] Chore: Helm --- .../secrets-operator/templates/infisicalsecret-crd.yaml | 4 ++++ helm-charts/secrets-operator/values.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/helm-charts/secrets-operator/templates/infisicalsecret-crd.yaml b/helm-charts/secrets-operator/templates/infisicalsecret-crd.yaml index 61e7a6719..edc3eaaae 100644 --- a/helm-charts/secrets-operator/templates/infisicalsecret-crd.yaml +++ b/helm-charts/secrets-operator/templates/infisicalsecret-crd.yaml @@ -67,6 +67,8 @@ spec: properties: envSlug: type: string + recursive: + type: boolean secretsPath: type: string required: @@ -111,6 +113,8 @@ spec: type: string projectSlug: type: string + recursive: + type: boolean secretsPath: type: string required: diff --git a/helm-charts/secrets-operator/values.yaml b/helm-charts/secrets-operator/values.yaml index 26f7a1938..e7d27306b 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.0 # fixed to prevent accidental upgrade + tag: v0.5.1 # fixed to prevent accidental upgrade (manually bump when adding new versions) resources: limits: cpu: 500m From 829dbb9970a6bf58ad70aab7d3977d8f29387501 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 8 May 2024 00:41:53 +0200 Subject: [PATCH 7/8] Update values.yaml --- helm-charts/secrets-operator/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm-charts/secrets-operator/values.yaml b/helm-charts/secrets-operator/values.yaml index e7d27306b..8054b1b0c 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 (manually bump when adding new versions) + tag: v0.5.1 # fixed to prevent accidental upgrade resources: limits: cpu: 500m From be2fc4fec4915812e1ea08ff9cec484463bbc87a Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 8 May 2024 00:42:38 +0200 Subject: [PATCH 8/8] Update Chart.yaml --- helm-charts/secrets-operator/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm-charts/secrets-operator/Chart.yaml b/helm-charts/secrets-operator/Chart.yaml index b007891b0..9c4f83248 100644 --- a/helm-charts/secrets-operator/Chart.yaml +++ b/helm-charts/secrets-operator/Chart.yaml @@ -13,7 +13,7 @@ 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.0 +version: v0.5.1 # 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.