Browse Source

allow references expansion when searching secret by key infinsical (#4486)

* allow references expansion when searching secret by key

Signed-off-by: Christophe Jauffret <reg-github@geo6.net>

* add updated helm test for the crd

Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>

---------

Signed-off-by: Christophe Jauffret <reg-github@geo6.net>
Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
Co-authored-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
Christophe Jauffret 1 year ago
parent
commit
49926e2a35

+ 10 - 0
apis/externalsecrets/v1beta1/secretsstore_infisical_types.go

@@ -31,16 +31,24 @@ type InfisicalAuth struct {
 }
 
 type MachineIdentityScopeInWorkspace struct {
+	// SecretsPath specifies the path to the secrets within the workspace. Defaults to "/" if not provided.
 	// +kubebuilder:default="/"
 	// +optional
 	SecretsPath string `json:"secretsPath,omitempty"`
+	// Recursive indicates whether the secrets should be fetched recursively. Defaults to false if not provided.
 	// +kubebuilder:default=false
 	// +optional
 	Recursive bool `json:"recursive,omitempty"`
+	// EnvironmentSlug is the required slug identifier for the environment.
 	// +kubebuilder:validation:Required
 	EnvironmentSlug string `json:"environmentSlug"`
+	// ProjectSlug is the required slug identifier for the project.
 	// +kubebuilder:validation:Required
 	ProjectSlug string `json:"projectSlug"`
+	// ExpandSecretReferences indicates whether secret references should be expanded. Defaults to true if not provided.
+	// +kubebuilder:default=true
+	// +optional
+	ExpandSecretReferences bool `json:"expandSecretReferences,omitempty"`
 }
 
 // InfisicalProvider configures a store to sync secrets using the Infisical provider.
@@ -48,8 +56,10 @@ type InfisicalProvider struct {
 	// Auth configures how the Operator authenticates with the Infisical API
 	// +kubebuilder:validation:Required
 	Auth InfisicalAuth `json:"auth"`
+	// SecretsScope defines the scope of the secrets within the workspace
 	// +kubebuilder:validation:Required
 	SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"`
+	// HostAPI specifies the base URL of the Infisical API. If not provided, it defaults to "https://app.infisical.com/api".
 	// +kubebuilder:default="https://app.infisical.com/api"
 	// +optional
 	HostAPI string `json:"hostAPI,omitempty"`

+ 18 - 0
config/crds/bases/external-secrets.io_clustersecretstores.yaml

@@ -4037,18 +4037,36 @@ spec:
                         type: object
                       hostAPI:
                         default: https://app.infisical.com/api
+                        description: HostAPI specifies the base URL of the Infisical
+                          API. If not provided, it defaults to "https://app.infisical.com/api".
                         type: string
                       secretsScope:
+                        description: SecretsScope defines the scope of the secrets
+                          within the workspace
                         properties:
                           environmentSlug:
+                            description: EnvironmentSlug is the required slug identifier
+                              for the environment.
                             type: string
+                          expandSecretReferences:
+                            default: true
+                            description: ExpandSecretReferences indicates whether
+                              secret references should be expanded. Defaults to true
+                              if not provided.
+                            type: boolean
                           projectSlug:
+                            description: ProjectSlug is the required slug identifier
+                              for the project.
                             type: string
                           recursive:
                             default: false
+                            description: Recursive indicates whether the secrets should
+                              be fetched recursively. Defaults to false if not provided.
                             type: boolean
                           secretsPath:
                             default: /
+                            description: SecretsPath specifies the path to the secrets
+                              within the workspace. Defaults to "/" if not provided.
                             type: string
                         required:
                         - environmentSlug

+ 18 - 0
config/crds/bases/external-secrets.io_secretstores.yaml

@@ -4037,18 +4037,36 @@ spec:
                         type: object
                       hostAPI:
                         default: https://app.infisical.com/api
+                        description: HostAPI specifies the base URL of the Infisical
+                          API. If not provided, it defaults to "https://app.infisical.com/api".
                         type: string
                       secretsScope:
+                        description: SecretsScope defines the scope of the secrets
+                          within the workspace
                         properties:
                           environmentSlug:
+                            description: EnvironmentSlug is the required slug identifier
+                              for the environment.
                             type: string
+                          expandSecretReferences:
+                            default: true
+                            description: ExpandSecretReferences indicates whether
+                              secret references should be expanded. Defaults to true
+                              if not provided.
+                            type: boolean
                           projectSlug:
+                            description: ProjectSlug is the required slug identifier
+                              for the project.
                             type: string
                           recursive:
                             default: false
+                            description: Recursive indicates whether the secrets should
+                              be fetched recursively. Defaults to false if not provided.
                             type: boolean
                           secretsPath:
                             default: /
+                            description: SecretsPath specifies the path to the secrets
+                              within the workspace. Defaults to "/" if not provided.
                             type: string
                         required:
                         - environmentSlug

+ 10 - 0
deploy/charts/external-secrets/tests/__snapshot__/crds_test.yaml.snap

@@ -3797,18 +3797,28 @@ should match snapshot of default values:
                               type: object
                             hostAPI:
                               default: https://app.infisical.com/api
+                              description: HostAPI specifies the base URL of the Infisical API. If not provided, it defaults to "https://app.infisical.com/api".
                               type: string
                             secretsScope:
+                              description: SecretsScope defines the scope of the secrets within the workspace
                               properties:
                                 environmentSlug:
+                                  description: EnvironmentSlug is the required slug identifier for the environment.
                                   type: string
+                                expandSecretReferences:
+                                  default: true
+                                  description: ExpandSecretReferences indicates whether secret references should be expanded. Defaults to true if not provided.
+                                  type: boolean
                                 projectSlug:
+                                  description: ProjectSlug is the required slug identifier for the project.
                                   type: string
                                 recursive:
                                   default: false
+                                  description: Recursive indicates whether the secrets should be fetched recursively. Defaults to false if not provided.
                                   type: boolean
                                 secretsPath:
                                   default: /
+                                  description: SecretsPath specifies the path to the secrets within the workspace. Defaults to "/" if not provided.
                                   type: string
                               required:
                                 - environmentSlug

+ 20 - 0
deploy/crds/bundle.yaml

@@ -4521,18 +4521,28 @@ spec:
                           type: object
                         hostAPI:
                           default: https://app.infisical.com/api
+                          description: HostAPI specifies the base URL of the Infisical API. If not provided, it defaults to "https://app.infisical.com/api".
                           type: string
                         secretsScope:
+                          description: SecretsScope defines the scope of the secrets within the workspace
                           properties:
                             environmentSlug:
+                              description: EnvironmentSlug is the required slug identifier for the environment.
                               type: string
+                            expandSecretReferences:
+                              default: true
+                              description: ExpandSecretReferences indicates whether secret references should be expanded. Defaults to true if not provided.
+                              type: boolean
                             projectSlug:
+                              description: ProjectSlug is the required slug identifier for the project.
                               type: string
                             recursive:
                               default: false
+                              description: Recursive indicates whether the secrets should be fetched recursively. Defaults to false if not provided.
                               type: boolean
                             secretsPath:
                               default: /
+                              description: SecretsPath specifies the path to the secrets within the workspace. Defaults to "/" if not provided.
                               type: string
                           required:
                             - environmentSlug
@@ -11722,18 +11732,28 @@ spec:
                           type: object
                         hostAPI:
                           default: https://app.infisical.com/api
+                          description: HostAPI specifies the base URL of the Infisical API. If not provided, it defaults to "https://app.infisical.com/api".
                           type: string
                         secretsScope:
+                          description: SecretsScope defines the scope of the secrets within the workspace
                           properties:
                             environmentSlug:
+                              description: EnvironmentSlug is the required slug identifier for the environment.
                               type: string
+                            expandSecretReferences:
+                              default: true
+                              description: ExpandSecretReferences indicates whether secret references should be expanded. Defaults to true if not provided.
+                              type: boolean
                             projectSlug:
+                              description: ProjectSlug is the required slug identifier for the project.
                               type: string
                             recursive:
                               default: false
+                              description: Recursive indicates whether the secrets should be fetched recursively. Defaults to false if not provided.
                               type: boolean
                             secretsPath:
                               default: /
+                              description: SecretsPath specifies the path to the secrets within the workspace. Defaults to "/" if not provided.
                               type: string
                           required:
                             - environmentSlug

+ 18 - 0
docs/api/spec.md

@@ -5149,6 +5149,7 @@ MachineIdentityScopeInWorkspace
 </em>
 </td>
 <td>
+<p>SecretsScope defines the scope of the secrets within the workspace</p>
 </td>
 </tr>
 <tr>
@@ -5160,6 +5161,7 @@ string
 </td>
 <td>
 <em>(Optional)</em>
+<p>HostAPI specifies the base URL of the Infisical API. If not provided, it defaults to &ldquo;<a href="https://app.infisical.com/api&quot;">https://app.infisical.com/api&rdquo;</a>.</p>
 </td>
 </tr>
 </tbody>
@@ -5419,6 +5421,7 @@ string
 </td>
 <td>
 <em>(Optional)</em>
+<p>SecretsPath specifies the path to the secrets within the workspace. Defaults to &ldquo;/&rdquo; if not provided.</p>
 </td>
 </tr>
 <tr>
@@ -5430,6 +5433,7 @@ bool
 </td>
 <td>
 <em>(Optional)</em>
+<p>Recursive indicates whether the secrets should be fetched recursively. Defaults to false if not provided.</p>
 </td>
 </tr>
 <tr>
@@ -5440,6 +5444,7 @@ string
 </em>
 </td>
 <td>
+<p>EnvironmentSlug is the required slug identifier for the environment.</p>
 </td>
 </tr>
 <tr>
@@ -5450,6 +5455,19 @@ string
 </em>
 </td>
 <td>
+<p>ProjectSlug is the required slug identifier for the project.</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>expandSecretReferences</code></br>
+<em>
+bool
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>ExpandSecretReferences indicates whether secret references should be expanded. Defaults to true if not provided.</p>
 </td>
 </tr>
 </tbody>

+ 2 - 0
docs/snippets/infisical-generic-secret-store.yaml

@@ -23,5 +23,7 @@ spec:
         secretsPath: / # Root is "/"
         # optional
         recursive: true # Default is false
+        # optional
+        expandSecretReferences: false # Default is true
       # optional
       hostAPI: https://app.infisical.com

+ 6 - 5
pkg/provider/infisical/api/api.go

@@ -235,7 +235,7 @@ func (a *InfisicalClient) GetSecretsV3(data GetSecretsV3Request) (map[string]str
 		"environment":            data.EnvironmentSlug,
 		"secretPath":             data.SecretPath,
 		"include_imports":        "true",
-		"expandSecretReferences": "true",
+		"expandSecretReferences": strconv.FormatBool(data.ExpandSecretReferences),
 		"recursive":              strconv.FormatBool(data.Recursive),
 	}
 
@@ -267,10 +267,11 @@ func (a *InfisicalClient) GetSecretsV3(data GetSecretsV3Request) (map[string]str
 
 func (a *InfisicalClient) GetSecretByKeyV3(data GetSecretByKeyV3Request) (string, error) {
 	params := map[string]string{
-		"workspaceSlug":   data.ProjectSlug,
-		"environment":     data.EnvironmentSlug,
-		"secretPath":      data.SecretPath,
-		"include_imports": "true",
+		"workspaceSlug":          data.ProjectSlug,
+		"environment":            data.EnvironmentSlug,
+		"secretPath":             data.SecretPath,
+		"include_imports":        "true",
+		"expandSecretReferences": strconv.FormatBool(data.ExpandSecretReferences),
 	}
 
 	endpointURL := fmt.Sprintf("api/v3/secrets/raw/%s", data.SecretKey)

+ 10 - 8
pkg/provider/infisical/api/api_models.go

@@ -39,10 +39,11 @@ type RevokeMachineIdentityAccessTokenResponse struct {
 }
 
 type GetSecretByKeyV3Request struct {
-	EnvironmentSlug string `json:"environment"`
-	ProjectSlug     string `json:"workspaceSlug"`
-	SecretPath      string `json:"secretPath"`
-	SecretKey       string `json:"secretKey"`
+	EnvironmentSlug        string `json:"environment"`
+	ProjectSlug            string `json:"workspaceSlug"`
+	SecretPath             string `json:"secretPath"`
+	SecretKey              string `json:"secretKey"`
+	ExpandSecretReferences bool   `json:"expandSecretReferences"`
 }
 
 type GetSecretByKeyV3Response struct {
@@ -50,10 +51,11 @@ type GetSecretByKeyV3Response struct {
 }
 
 type GetSecretsV3Request struct {
-	EnvironmentSlug string `json:"environment"`
-	ProjectSlug     string `json:"workspaceSlug"`
-	Recursive       bool   `json:"recursive"`
-	SecretPath      string `json:"secretPath"`
+	EnvironmentSlug        string `json:"environment"`
+	ProjectSlug            string `json:"workspaceSlug"`
+	Recursive              bool   `json:"recursive"`
+	SecretPath             string `json:"secretPath"`
+	ExpandSecretReferences bool   `json:"expandSecretReferences"`
 }
 
 type GetSecretsV3Response struct {

+ 15 - 12
pkg/provider/infisical/client.go

@@ -47,10 +47,11 @@ func getPropertyValue(jsonData, propertyName, keyName string) ([]byte, error) {
 // then the secret entry will be deleted depending on the deletionPolicy.
 func (p *Provider) GetSecret(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
 	secret, err := p.apiClient.GetSecretByKeyV3(api.GetSecretByKeyV3Request{
-		EnvironmentSlug: p.apiScope.EnvironmentSlug,
-		ProjectSlug:     p.apiScope.ProjectSlug,
-		SecretKey:       ref.Key,
-		SecretPath:      p.apiScope.SecretPath,
+		EnvironmentSlug:        p.apiScope.EnvironmentSlug,
+		ProjectSlug:            p.apiScope.ProjectSlug,
+		SecretKey:              ref.Key,
+		SecretPath:             p.apiScope.SecretPath,
+		ExpandSecretReferences: p.apiScope.ExpandSecretReferences,
 	})
 
 	if err != nil {
@@ -101,10 +102,11 @@ func (p *Provider) GetAllSecrets(ctx context.Context, ref esv1beta1.ExternalSecr
 	}
 
 	secrets, err := p.apiClient.GetSecretsV3(api.GetSecretsV3Request{
-		EnvironmentSlug: p.apiScope.EnvironmentSlug,
-		ProjectSlug:     p.apiScope.ProjectSlug,
-		SecretPath:      p.apiScope.SecretPath,
-		Recursive:       p.apiScope.Recursive,
+		EnvironmentSlug:        p.apiScope.EnvironmentSlug,
+		ProjectSlug:            p.apiScope.ProjectSlug,
+		SecretPath:             p.apiScope.SecretPath,
+		Recursive:              p.apiScope.Recursive,
+		ExpandSecretReferences: p.apiScope.ExpandSecretReferences,
 	})
 	if err != nil {
 		return nil, err
@@ -143,10 +145,11 @@ func (p *Provider) GetAllSecrets(ctx context.Context, ref esv1beta1.ExternalSecr
 func (p *Provider) Validate() (esv1beta1.ValidationResult, error) {
 	// try to fetch the secrets to ensure provided credentials has access to read secrets
 	_, err := p.apiClient.GetSecretsV3(api.GetSecretsV3Request{
-		EnvironmentSlug: p.apiScope.EnvironmentSlug,
-		ProjectSlug:     p.apiScope.ProjectSlug,
-		Recursive:       p.apiScope.Recursive,
-		SecretPath:      p.apiScope.SecretPath,
+		EnvironmentSlug:        p.apiScope.EnvironmentSlug,
+		ProjectSlug:            p.apiScope.ProjectSlug,
+		Recursive:              p.apiScope.Recursive,
+		SecretPath:             p.apiScope.SecretPath,
+		ExpandSecretReferences: p.apiScope.ExpandSecretReferences,
 	})
 
 	if err != nil {

+ 10 - 8
pkg/provider/infisical/provider.go

@@ -43,10 +43,11 @@ type Provider struct {
 }
 
 type InfisicalClientScope struct {
-	EnvironmentSlug string
-	ProjectSlug     string
-	Recursive       bool
-	SecretPath      string
+	EnvironmentSlug        string
+	ProjectSlug            string
+	Recursive              bool
+	SecretPath             string
+	ExpandSecretReferences bool
 }
 
 // https://github.com/external-secrets/external-secrets/issues/644
@@ -98,10 +99,11 @@ func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore,
 		return &Provider{
 			apiClient: apiClient,
 			apiScope: &InfisicalClientScope{
-				EnvironmentSlug: infisicalSpec.SecretsScope.EnvironmentSlug,
-				ProjectSlug:     infisicalSpec.SecretsScope.ProjectSlug,
-				Recursive:       infisicalSpec.SecretsScope.Recursive,
-				SecretPath:      infisicalSpec.SecretsScope.SecretsPath,
+				EnvironmentSlug:        infisicalSpec.SecretsScope.EnvironmentSlug,
+				ProjectSlug:            infisicalSpec.SecretsScope.ProjectSlug,
+				Recursive:              infisicalSpec.SecretsScope.Recursive,
+				SecretPath:             infisicalSpec.SecretsScope.SecretsPath,
+				ExpandSecretReferences: infisicalSpec.SecretsScope.ExpandSecretReferences,
 			},
 		}, nil
 	}