Browse Source

fix: a lot of sonar issue fixes (#5771)

Gergely Bräutigam 3 months ago
parent
commit
0e31d72d7a

+ 0 - 3
.github/workflows/ci.yml

@@ -14,9 +14,6 @@ env:
   # Sonar
   # Sonar
   SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
   SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
 
 
-permissions:
-  contents: read
-
 jobs:
 jobs:
   detect-noop:
   detect-noop:
     permissions:
     permissions:

+ 2 - 3
.github/workflows/helm.yml

@@ -7,12 +7,11 @@ on:
   pull_request:
   pull_request:
   workflow_dispatch: {}
   workflow_dispatch: {}
 
 
-permissions:
-  contents: read
-
 jobs:
 jobs:
   lint-and-test:
   lint-and-test:
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:
     steps:
       - uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
       - uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
         with:
         with:

+ 0 - 4
.github/workflows/pull-request-label.yml

@@ -8,10 +8,6 @@ on:
       - synchronize
       - synchronize
       - reopened
       - reopened
 
 
-permissions:
-  pull-requests: write
-  issues: write
-
 jobs:
 jobs:
   conventional-commit-labeler:
   conventional-commit-labeler:
     name: Label PR based on Conventional Commit Specification
     name: Label PR based on Conventional Commit Specification

+ 42 - 2
.github/workflows/release.yml

@@ -34,7 +34,27 @@ jobs:
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
         with:
           fetch-depth: 0
           fetch-depth: 0
-          ref: ${{ github.event.inputs.source_ref }}
+
+      - name: Resolve and validate ref
+        id: resolve_ref
+        run: |
+          set -e
+          # Try to fetch the ref from remote
+          if git fetch origin "${{ github.event.inputs.source_ref }}"; then
+            # Remote ref exists, use it
+            RESOLVED_SHA=$(git rev-parse "origin/${{ github.event.inputs.source_ref }}")
+          elif git rev-parse --verify "${{ github.event.inputs.source_ref }}" >/dev/null 2>&1; then
+            # Local ref exists (e.g., a tag)
+            RESOLVED_SHA=$(git rev-parse "${{ github.event.inputs.source_ref }}")
+          else
+            echo "Error: ref '${{ github.event.inputs.source_ref }}' not found"
+            exit 1
+          fi
+          echo "Resolved to SHA: $RESOLVED_SHA"
+          echo "sha=$RESOLVED_SHA" >> $GITHUB_OUTPUT
+
+      - name: Checkout validated ref
+        run: git checkout ${{ steps.resolve_ref.outputs.sha }}
       - name: check-docs
       - name: check-docs
         env:
         env:
           DOCS_VERSION: ${{ github.event.inputs.version }}
           DOCS_VERSION: ${{ github.event.inputs.version }}
@@ -55,7 +75,27 @@ jobs:
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
         with:
           fetch-depth: 0
           fetch-depth: 0
-          ref: ${{ github.event.inputs.source_ref }}
+
+      - name: Resolve and validate ref
+        id: resolve_ref
+        run: |
+          set -e
+          # Try to fetch the ref from remote
+          if git fetch origin "${{ github.event.inputs.source_ref }}"; then
+            # Remote ref exists, use it
+            RESOLVED_SHA=$(git rev-parse "origin/${{ github.event.inputs.source_ref }}")
+          elif git rev-parse --verify "${{ github.event.inputs.source_ref }}" >/dev/null 2>&1; then
+            # Local ref exists (e.g., a tag)
+            RESOLVED_SHA=$(git rev-parse "${{ github.event.inputs.source_ref }}")
+          else
+            echo "Error: ref '${{ github.event.inputs.source_ref }}' not found"
+            exit 1
+          fi
+          echo "Resolved to SHA: $RESOLVED_SHA"
+          echo "sha=$RESOLVED_SHA" >> $GITHUB_OUTPUT
+
+      - name: Checkout validated ref
+        run: git checkout ${{ steps.resolve_ref.outputs.sha }}
 
 
       - name: Create Release
       - name: Create Release
         uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
         uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0

+ 21 - 1
.github/workflows/release_esoctl.yml

@@ -31,7 +31,27 @@ jobs:
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
         with:
           fetch-depth: 0
           fetch-depth: 0
-          ref: ${{ github.event.inputs.source_ref }}
+
+      - name: Resolve and validate ref
+        id: resolve_ref
+        run: |
+          set -e
+          # Try to fetch the ref from remote
+          if git fetch origin "${{ github.event.inputs.source_ref }}"; then
+            # Remote ref exists, use it
+            RESOLVED_SHA=$(git rev-parse "origin/${{ github.event.inputs.source_ref }}")
+          elif git rev-parse --verify "${{ github.event.inputs.source_ref }}" >/dev/null 2>&1; then
+            # Local ref exists (e.g., a tag)
+            RESOLVED_SHA=$(git rev-parse "${{ github.event.inputs.source_ref }}")
+          else
+            echo "Error: ref '${{ github.event.inputs.source_ref }}' not found"
+            exit 1
+          fi
+          echo "Resolved to SHA: $RESOLVED_SHA"
+          echo "sha=$RESOLVED_SHA" >> $GITHUB_OUTPUT
+
+      - name: Checkout validated ref
+        run: git checkout ${{ steps.resolve_ref.outputs.sha }}
 
 
       - name: Setup Go
       - name: Setup Go
         uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
         uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0

+ 0 - 2
.github/workflows/scorecard.yml

@@ -6,8 +6,6 @@ on:
   push:
   push:
     branches: [ "main" ]
     branches: [ "main" ]
 
 
-permissions: read-all
-
 jobs:
 jobs:
   analysis:
   analysis:
     name: Scorecard analysis
     name: Scorecard analysis

+ 2 - 4
.github/workflows/update-deps.yml

@@ -7,14 +7,12 @@ on:
   workflow_dispatch:
   workflow_dispatch:
     inputs: {}
     inputs: {}
 
 
-
-permissions:
-  contents: read
-
 jobs:
 jobs:
   branches:
   branches:
     name: get branch data
     name: get branch data
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     outputs:
     outputs:
       branches: ${{ steps.branches.outputs.branches }}
       branches: ${{ steps.branches.outputs.branches }}
 
 

+ 10 - 7
cmd/esoctl/generator/bootstrap.go

@@ -29,6 +29,8 @@ import (
 //go:embed templates/*.tmpl
 //go:embed templates/*.tmpl
 var templates embed.FS
 var templates embed.FS
 
 
+const generatorImportPath = "github.com/external-secrets/external-secrets/generators/v1/"
+
 // Config holds the configuration for bootstrapping a generator.
 // Config holds the configuration for bootstrapping a generator.
 type Config struct {
 type Config struct {
 	GeneratorName string
 	GeneratorName string
@@ -184,8 +186,8 @@ func updateRegisterFile(rootDir string, cfg Config) error {
 	}
 	}
 
 
 	// Add import
 	// Add import
-	importLine := fmt.Sprintf("\t%s \"github.com/external-secrets/external-secrets/generators/v1/%s\"",
-		cfg.PackageName, cfg.PackageName)
+	importLine := fmt.Sprintf("\t%s \"%s%s\"",
+		cfg.PackageName, generatorImportPath, cfg.PackageName)
 
 
 	// Find the last import before the closing parenthesis
 	// Find the last import before the closing parenthesis
 	lines := strings.Split(content, "\n")
 	lines := strings.Split(content, "\n")
@@ -197,7 +199,7 @@ func updateRegisterFile(rootDir string, cfg Config) error {
 		newLines = append(newLines, line)
 		newLines = append(newLines, line)
 
 
 		// Add import after the last generator import
 		// Add import after the last generator import
-		if !importAdded && strings.Contains(line, "\"github.com/external-secrets/external-secrets/generators/v1/") {
+		if !importAdded && strings.Contains(line, "\""+generatorImportPath) {
 			// Look ahead to see if next line is still an import or closing paren
 			// Look ahead to see if next line is still an import or closing paren
 			if i+1 < len(lines) && strings.TrimSpace(lines[i+1]) == ")" {
 			if i+1 < len(lines) && strings.TrimSpace(lines[i+1]) == ")" {
 				newLines = append(newLines, importLine)
 				newLines = append(newLines, importLine)
@@ -323,7 +325,8 @@ func updateMainGoMod(rootDir string, cfg Config) error {
 	}
 	}
 
 
 	content := string(data)
 	content := string(data)
-	replaceLine := fmt.Sprintf("\tgithub.com/external-secrets/external-secrets/generators/v1/%s => ./generators/v1/%s",
+	replaceLine := fmt.Sprintf("\t%s%s => ./generators/v1/%s",
+		generatorImportPath,
 		cfg.PackageName, cfg.PackageName)
 		cfg.PackageName, cfg.PackageName)
 
 
 	// Check if already exists
 	// Check if already exists
@@ -339,7 +342,7 @@ func updateMainGoMod(rootDir string, cfg Config) error {
 
 
 	// First pass: find where to insert
 	// First pass: find where to insert
 	for i, line := range lines {
 	for i, line := range lines {
-		if strings.Contains(line, "github.com/external-secrets/external-secrets/generators/v1/") {
+		if strings.Contains(line, generatorImportPath) {
 			lastGeneratorIdx = i
 			lastGeneratorIdx = i
 			// Extract the package name from the current line
 			// Extract the package name from the current line
 			currentPkg := extractGeneratorPackage(line)
 			currentPkg := extractGeneratorPackage(line)
@@ -355,7 +358,7 @@ func updateMainGoMod(rootDir string, cfg Config) error {
 		// If this was the last generator and we haven't added yet, add after it
 		// If this was the last generator and we haven't added yet, add after it
 		if i == lastGeneratorIdx && !added && lastGeneratorIdx != -1 {
 		if i == lastGeneratorIdx && !added && lastGeneratorIdx != -1 {
 			// Check if next line is NOT a generator (meaning this is the last one)
 			// Check if next line is NOT a generator (meaning this is the last one)
-			if i+1 >= len(lines) || !strings.Contains(lines[i+1], "github.com/external-secrets/external-secrets/generators/v1/") {
+			if i+1 >= len(lines) || !strings.Contains(lines[i+1], generatorImportPath) {
 				newLines = append(newLines, replaceLine)
 				newLines = append(newLines, replaceLine)
 				added = true
 				added = true
 			}
 			}
@@ -376,7 +379,7 @@ func updateMainGoMod(rootDir string, cfg Config) error {
 }
 }
 
 
 func extractGeneratorPackage(line string) string {
 func extractGeneratorPackage(line string) string {
-	if !strings.Contains(line, "github.com/external-secrets/external-secrets/generators/v1/") {
+	if !strings.Contains(line, generatorImportPath) {
 		return ""
 		return ""
 	}
 	}
 	// Extract package name from line like:
 	// Extract package name from line like:

+ 59 - 24
generators/v1/password/password.go

@@ -78,60 +78,95 @@ func (g *Generator) generate(jsonSpec *apiextensions.JSON, passGen generateFunc)
 	if err != nil {
 	if err != nil {
 		return nil, nil, fmt.Errorf(errParseSpec, err)
 		return nil, nil, fmt.Errorf(errParseSpec, err)
 	}
 	}
-	symbolCharacters := defaultSymbolChars
+
+	config := extractPasswordConfig(res)
+	keys, err := validateSecretKeys(res.Spec.SecretKeys)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	passwords, err := generatePasswords(keys, config, passGen)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return passwords, nil, nil
+}
+
+type passwordConfig struct {
+	length           int
+	digits           int
+	symbols          int
+	symbolCharacters string
+	encoding         string
+	noUpper          bool
+	allowRepeat      bool
+}
+
+func extractPasswordConfig(res *genv1alpha1.Password) passwordConfig {
+	config := passwordConfig{
+		symbolCharacters: defaultSymbolChars,
+		length:           defaultLength,
+		encoding:         "raw",
+	}
+
 	if res.Spec.SymbolCharacters != nil {
 	if res.Spec.SymbolCharacters != nil {
-		symbolCharacters = *res.Spec.SymbolCharacters
+		config.symbolCharacters = *res.Spec.SymbolCharacters
 	}
 	}
-	passLen := defaultLength
 	if res.Spec.Length > 0 {
 	if res.Spec.Length > 0 {
-		passLen = res.Spec.Length
+		config.length = res.Spec.Length
 	}
 	}
-	digits := int(float32(passLen) * digitFactor)
+	config.digits = int(float32(config.length) * digitFactor)
 	if res.Spec.Digits != nil {
 	if res.Spec.Digits != nil {
-		digits = *res.Spec.Digits
+		config.digits = *res.Spec.Digits
 	}
 	}
-	symbols := int(float32(passLen) * symbolFactor)
+	config.symbols = int(float32(config.length) * symbolFactor)
 	if res.Spec.Symbols != nil {
 	if res.Spec.Symbols != nil {
-		symbols = *res.Spec.Symbols
+		config.symbols = *res.Spec.Symbols
 	}
 	}
-
-	encoding := "raw"
 	if res.Spec.Encoding != nil {
 	if res.Spec.Encoding != nil {
-		encoding = *res.Spec.Encoding
+		config.encoding = *res.Spec.Encoding
 	}
 	}
+	config.noUpper = res.Spec.NoUpper
+	config.allowRepeat = res.Spec.AllowRepeat
 
 
-	keys := res.Spec.SecretKeys
+	return config
+}
+
+func validateSecretKeys(keys []string) ([]string, error) {
 	if len(keys) == 0 {
 	if len(keys) == 0 {
 		keys = []string{"password"}
 		keys = []string{"password"}
 	}
 	}
 	seen := make(map[string]struct{}, len(keys))
 	seen := make(map[string]struct{}, len(keys))
 	for _, key := range keys {
 	for _, key := range keys {
 		if key == "" {
 		if key == "" {
-			return nil, nil, errors.New(errSecretKey)
+			return nil, errors.New(errSecretKey)
 		}
 		}
 		if _, ok := seen[key]; ok {
 		if _, ok := seen[key]; ok {
-			return nil, nil, errors.New(errSecretKey)
+			return nil, errors.New(errSecretKey)
 		}
 		}
 		seen[key] = struct{}{}
 		seen[key] = struct{}{}
 	}
 	}
+	return keys, nil
+}
 
 
+func generatePasswords(keys []string, config passwordConfig, passGen generateFunc) (map[string][]byte, error) {
 	passwords := make(map[string][]byte, len(keys))
 	passwords := make(map[string][]byte, len(keys))
 	for _, key := range keys {
 	for _, key := range keys {
 		pass, err := passGen(
 		pass, err := passGen(
-			passLen,
-			symbols,
-			symbolCharacters,
-			digits,
-			res.Spec.NoUpper,
-			res.Spec.AllowRepeat,
+			config.length,
+			config.symbols,
+			config.symbolCharacters,
+			config.digits,
+			config.noUpper,
+			config.allowRepeat,
 		)
 		)
 		if err != nil {
 		if err != nil {
-			return nil, nil, err
+			return nil, err
 		}
 		}
-		passwords[key] = encodePassword([]byte(pass), encoding)
+		passwords[key] = encodePassword([]byte(pass), config.encoding)
 	}
 	}
-
-	return passwords, nil, nil
+	return passwords, nil
 }
 }
 
 
 func generateSafePassword(
 func generateSafePassword(

+ 5 - 3
providers/v1/cloudru/secretmanager/adapter/csm_client.go

@@ -35,6 +35,8 @@ import (
 	esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
 	esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
 )
 )
 
 
+const errUnauthorized = "unauthorized: %w"
+
 // CredentialsResolver returns the actual client credentials.
 // CredentialsResolver returns the actual client credentials.
 type CredentialsResolver interface {
 type CredentialsResolver interface {
 	Resolve(ctx context.Context) (*Credentials, error)
 	Resolve(ctx context.Context) (*Credentials, error)
@@ -101,7 +103,7 @@ func (c *APIClient) ListSecrets(ctx context.Context, req *ListSecretsRequest) ([
 	var err error
 	var err error
 	ctx, err = c.authCtx(ctx)
 	ctx, err = c.authCtx(ctx)
 	if err != nil {
 	if err != nil {
-		return nil, fmt.Errorf("unauthorized: %w", err)
+		return nil, fmt.Errorf(errUnauthorized, err)
 	}
 	}
 
 
 	resp, err := c.smsClient.V2.SecretService.Search(ctx, searchReq)
 	resp, err := c.smsClient.V2.SecretService.Search(ctx, searchReq)
@@ -117,7 +119,7 @@ func (c *APIClient) AccessSecretVersionByPath(ctx context.Context, projectID, pa
 	var err error
 	var err error
 	ctx, err = c.authCtx(ctx)
 	ctx, err = c.authCtx(ctx)
 	if err != nil {
 	if err != nil {
-		return nil, fmt.Errorf("unauthorized: %w", err)
+		return nil, fmt.Errorf(errUnauthorized, err)
 	}
 	}
 
 
 	req := &smsV2.AccessSecretRequest{
 	req := &smsV2.AccessSecretRequest{
@@ -143,7 +145,7 @@ func (c *APIClient) AccessSecretVersion(ctx context.Context, id, version string)
 	var err error
 	var err error
 	ctx, err = c.authCtx(ctx)
 	ctx, err = c.authCtx(ctx)
 	if err != nil {
 	if err != nil {
-		return nil, fmt.Errorf("unauthorized: %w", err)
+		return nil, fmt.Errorf(errUnauthorized, err)
 	}
 	}
 
 
 	if version == "" {
 	if version == "" {

+ 31 - 27
providers/v1/fake/fake.go

@@ -140,36 +140,40 @@ func (p *Provider) PushSecret(_ context.Context, secret *corev1.Secret, data esv
 // GetAllSecrets returns multiple secrets from the given ExternalSecretFind
 // GetAllSecrets returns multiple secrets from the given ExternalSecretFind
 // Currently, only the Name operator is supported.
 // Currently, only the Name operator is supported.
 func (p *Provider) GetAllSecrets(_ context.Context, ref esv1.ExternalSecretFind) (map[string][]byte, error) {
 func (p *Provider) GetAllSecrets(_ context.Context, ref esv1.ExternalSecretFind) (map[string][]byte, error) {
-	if ref.Name != nil {
-		matcher, err := find.New(*ref.Name)
-		if err != nil {
-			return nil, err
-		}
+	if ref.Name == nil {
+		return nil, fmt.Errorf("unsupported find operator: %#v", ref)
+	}
 
 
-		latestVersionMap := make(map[string]string)
-		dataMap := make(map[string][]byte)
-		for key, data := range p.config {
-			// Reconstruct the original key without the version suffix
-			// See the mapKey function to know how the provider generates keys
-			originalKey := strings.TrimSuffix(key, data.Version)
-			if !matcher.MatchName(originalKey) {
-				continue
-			}
-
-			if version, ok := latestVersionMap[originalKey]; ok {
-				// Need to get only the latest version
-				if version < data.Version {
-					latestVersionMap[originalKey] = data.Version
-					dataMap[originalKey] = []byte(data.Value)
-				}
-			} else {
-				latestVersionMap[originalKey] = data.Version
-				dataMap[originalKey] = []byte(data.Value)
-			}
+	matcher, err := find.New(*ref.Name)
+	if err != nil {
+		return nil, err
+	}
+
+	dataMap := p.collectMatchingSecrets(matcher)
+	return esutils.ConvertKeys(ref.ConversionStrategy, dataMap)
+}
+
+func (p *Provider) collectMatchingSecrets(matcher *find.Matcher) map[string][]byte {
+	latestVersionMap := make(map[string]string)
+	dataMap := make(map[string][]byte)
+
+	for key, data := range p.config {
+		originalKey := strings.TrimSuffix(key, data.Version)
+		if !matcher.MatchName(originalKey) {
+			continue
 		}
 		}
-		return esutils.ConvertKeys(ref.ConversionStrategy, dataMap)
+
+		p.updateLatestVersion(originalKey, data, latestVersionMap, dataMap)
+	}
+	return dataMap
+}
+
+func (p *Provider) updateLatestVersion(originalKey string, data *Data, latestVersionMap map[string]string, dataMap map[string][]byte) {
+	version, exists := latestVersionMap[originalKey]
+	if !exists || version < data.Version {
+		latestVersionMap[originalKey] = data.Version
+		dataMap[originalKey] = []byte(data.Value)
 	}
 	}
-	return nil, fmt.Errorf("unsupported find operator: %#v", ref)
 }
 }
 
 
 // GetSecret returns a single secret from the provider.
 // GetSecret returns a single secret from the provider.

+ 5 - 3
providers/v1/github/client.go

@@ -32,6 +32,8 @@ import (
 	esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
 	esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
 )
 )
 
 
+const errWriteOnlyProvider = "not implemented - this provider supports write-only operations"
+
 // https://github.com/external-secrets/external-secrets/issues/644
 // https://github.com/external-secrets/external-secrets/issues/644
 var _ esv1.SecretsClient = &Client{}
 var _ esv1.SecretsClient = &Client{}
 
 
@@ -144,17 +146,17 @@ func (g *Client) PushSecret(ctx context.Context, secret *corev1.Secret, remoteRe
 
 
 // GetAllSecrets is not implemented as this provider is write-only.
 // GetAllSecrets is not implemented as this provider is write-only.
 func (g *Client) GetAllSecrets(_ context.Context, _ esv1.ExternalSecretFind) (map[string][]byte, error) {
 func (g *Client) GetAllSecrets(_ context.Context, _ esv1.ExternalSecretFind) (map[string][]byte, error) {
-	return nil, fmt.Errorf("not implemented - this provider supports write-only operations")
+	return nil, fmt.Errorf(errWriteOnlyProvider)
 }
 }
 
 
 // GetSecret is not implemented as this provider is write-only.
 // GetSecret is not implemented as this provider is write-only.
 func (g *Client) GetSecret(_ context.Context, _ esv1.ExternalSecretDataRemoteRef) ([]byte, error) {
 func (g *Client) GetSecret(_ context.Context, _ esv1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	return nil, fmt.Errorf("not implemented - this provider supports write-only operations")
+	return nil, fmt.Errorf(errWriteOnlyProvider)
 }
 }
 
 
 // GetSecretMap is not implemented as this provider is write-only.
 // GetSecretMap is not implemented as this provider is write-only.
 func (g *Client) GetSecretMap(_ context.Context, _ esv1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
 func (g *Client) GetSecretMap(_ context.Context, _ esv1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
-	return nil, fmt.Errorf("not implemented - this provider supports write-only operations")
+	return nil, fmt.Errorf(errWriteOnlyProvider)
 }
 }
 
 
 // Close cleans up any resources held by the client. No-op for this provider.
 // Close cleans up any resources held by the client. No-op for this provider.

+ 66 - 54
providers/v1/ibm/provider.go

@@ -125,10 +125,15 @@ func (ibm *providerIBM) GetSecret(_ context.Context, ref esv1.ExternalSecretData
 		return nil, errors.New(errUninitializedIBMProvider)
 		return nil, errors.New(errUninitializedIBMProvider)
 	}
 	}
 
 
+	secretGroupName, secretType, secretName := parseSecretReference(ref.Key)
+	return ibm.getSecretByType(secretType, secretName, secretGroupName, ref)
+}
+
+func parseSecretReference(key string) (string, string, string) {
 	var secretGroupName string
 	var secretGroupName string
 	secretType := sm.Secret_SecretType_Arbitrary
 	secretType := sm.Secret_SecretType_Arbitrary
-	secretName := ref.Key
-	nameSplitted := strings.Split(secretName, "/")
+	secretName := key
+	nameSplitted := strings.Split(key, "/")
 
 
 	switch len(nameSplitted) {
 	switch len(nameSplitted) {
 	case 2:
 	case 2:
@@ -139,77 +144,84 @@ func (ibm *providerIBM) GetSecret(_ context.Context, ref esv1.ExternalSecretData
 		secretType = nameSplitted[1]
 		secretType = nameSplitted[1]
 		secretName = nameSplitted[2]
 		secretName = nameSplitted[2]
 	}
 	}
+	return secretGroupName, secretType, secretName
+}
 
 
+func (ibm *providerIBM) getSecretByType(secretType, secretName, secretGroupName string, ref esv1.ExternalSecretDataRemoteRef) ([]byte, error) {
 	switch secretType {
 	switch secretType {
 	case sm.Secret_SecretType_Arbitrary:
 	case sm.Secret_SecretType_Arbitrary:
 		return getArbitrarySecret(ibm, &secretName, secretGroupName)
 		return getArbitrarySecret(ibm, &secretName, secretGroupName)
-
 	case sm.Secret_SecretType_UsernamePassword:
 	case sm.Secret_SecretType_UsernamePassword:
-
-		if ref.Property == "" {
-			return nil, errors.New("remoteRef.property required for secret type username_password")
-		}
-		return getUsernamePasswordSecret(ibm, &secretName, ref, secretGroupName)
-
+		return ibm.getUsernamePasswordSecretWithValidation(&secretName, ref, secretGroupName)
 	case sm.Secret_SecretType_IamCredentials:
 	case sm.Secret_SecretType_IamCredentials:
-
 		return getIamCredentialsSecret(ibm, &secretName, secretGroupName)
 		return getIamCredentialsSecret(ibm, &secretName, secretGroupName)
-
 	case sm.Secret_SecretType_ServiceCredentials:
 	case sm.Secret_SecretType_ServiceCredentials:
-
 		return getServiceCredentialsSecret(ibm, &secretName, secretGroupName)
 		return getServiceCredentialsSecret(ibm, &secretName, secretGroupName)
-
 	case sm.Secret_SecretType_ImportedCert:
 	case sm.Secret_SecretType_ImportedCert:
-
-		if ref.Property == "" {
-			return nil, errors.New("remoteRef.property required for secret type imported_cert")
-		}
-
-		return getImportCertSecret(ibm, &secretName, ref, secretGroupName)
-
+		return ibm.getImportCertSecretWithValidation(&secretName, ref, secretGroupName)
 	case sm.Secret_SecretType_PublicCert:
 	case sm.Secret_SecretType_PublicCert:
-
-		if ref.Property == "" {
-			return nil, errors.New("remoteRef.property required for secret type public_cert")
-		}
-
-		return getPublicCertSecret(ibm, &secretName, ref, secretGroupName)
-
+		return ibm.getPublicCertSecretWithValidation(&secretName, ref, secretGroupName)
 	case sm.Secret_SecretType_PrivateCert:
 	case sm.Secret_SecretType_PrivateCert:
+		return ibm.getPrivateCertSecretWithValidation(&secretName, ref, secretGroupName)
+	case sm.Secret_SecretType_Kv:
+		return ibm.getKVSecret(&secretName, secretGroupName, ref)
+	case sm.Secret_SecretType_CustomCredentials:
+		return ibm.getCustomCredentialsSecret(&secretName, secretGroupName, ref)
+	default:
+		return nil, fmt.Errorf("unknown secret type %s", secretType)
+	}
+}
 
 
-		if ref.Property == "" {
-			return nil, errors.New("remoteRef.property required for secret type private_cert")
-		}
-
-		return getPrivateCertSecret(ibm, &secretName, ref, secretGroupName)
+func (ibm *providerIBM) getUsernamePasswordSecretWithValidation(secretName *string, ref esv1.ExternalSecretDataRemoteRef, secretGroupName string) ([]byte, error) {
+	if ref.Property == "" {
+		return nil, errors.New("remoteRef.property required for secret type username_password")
+	}
+	return getUsernamePasswordSecret(ibm, secretName, ref, secretGroupName)
+}
 
 
-	case sm.Secret_SecretType_Kv:
+func (ibm *providerIBM) getImportCertSecretWithValidation(secretName *string, ref esv1.ExternalSecretDataRemoteRef, secretGroupName string) ([]byte, error) {
+	if ref.Property == "" {
+		return nil, errors.New("remoteRef.property required for secret type imported_cert")
+	}
+	return getImportCertSecret(ibm, secretName, ref, secretGroupName)
+}
 
 
-		response, err := getSecretData(ibm, &secretName, sm.Secret_SecretType_Kv, secretGroupName)
-		if err != nil {
-			return nil, err
-		}
-		secret, ok := response.(*sm.KVSecret)
-		if !ok {
-			return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_Kv, "GetSecret")
-		}
-		return getKVOrCustomCredentialsSecret(ref, secret.Data)
+func (ibm *providerIBM) getPublicCertSecretWithValidation(secretName *string, ref esv1.ExternalSecretDataRemoteRef, secretGroupName string) ([]byte, error) {
+	if ref.Property == "" {
+		return nil, errors.New("remoteRef.property required for secret type public_cert")
+	}
+	return getPublicCertSecret(ibm, secretName, ref, secretGroupName)
+}
 
 
-	case sm.Secret_SecretType_CustomCredentials:
+func (ibm *providerIBM) getPrivateCertSecretWithValidation(secretName *string, ref esv1.ExternalSecretDataRemoteRef, secretGroupName string) ([]byte, error) {
+	if ref.Property == "" {
+		return nil, errors.New("remoteRef.property required for secret type private_cert")
+	}
+	return getPrivateCertSecret(ibm, secretName, ref, secretGroupName)
+}
 
 
-		response, err := getSecretData(ibm, &secretName, sm.Secret_SecretType_CustomCredentials, secretGroupName)
-		if err != nil {
-			return nil, err
-		}
-		secret, ok := response.(*sm.CustomCredentialsSecret)
-		if !ok {
-			return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_CustomCredentials, "GetSecret")
-		}
-		return getKVOrCustomCredentialsSecret(ref, secret.CredentialsContent)
+func (ibm *providerIBM) getKVSecret(secretName *string, secretGroupName string, ref esv1.ExternalSecretDataRemoteRef) ([]byte, error) {
+	response, err := getSecretData(ibm, secretName, sm.Secret_SecretType_Kv, secretGroupName)
+	if err != nil {
+		return nil, err
+	}
+	secret, ok := response.(*sm.KVSecret)
+	if !ok {
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_Kv, "GetSecret")
+	}
+	return getKVOrCustomCredentialsSecret(ref, secret.Data)
+}
 
 
-	default:
-		return nil, fmt.Errorf("unknown secret type %s", secretType)
+func (ibm *providerIBM) getCustomCredentialsSecret(secretName *string, secretGroupName string, ref esv1.ExternalSecretDataRemoteRef) ([]byte, error) {
+	response, err := getSecretData(ibm, secretName, sm.Secret_SecretType_CustomCredentials, secretGroupName)
+	if err != nil {
+		return nil, err
+	}
+	secret, ok := response.(*sm.CustomCredentialsSecret)
+	if !ok {
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_CustomCredentials, "GetSecret")
 	}
 	}
+	return getKVOrCustomCredentialsSecret(ref, secret.CredentialsContent)
 }
 }
 
 
 func getArbitrarySecret(ibm *providerIBM, secretName *string, secretGroupName string) ([]byte, error) {
 func getArbitrarySecret(ibm *providerIBM, secretName *string, secretGroupName string) ([]byte, error) {

+ 45 - 27
providers/v1/infisical/provider.go

@@ -464,41 +464,59 @@ func (p *Provider) ValidateStore(store esv1.GenericStore) (admission.Warnings, e
 		return nil, errors.New("invalid infisical store")
 		return nil, errors.New("invalid infisical store")
 	}
 	}
 
 
-	if infisicalStoreSpec.SecretsScope.EnvironmentSlug == "" || infisicalStoreSpec.SecretsScope.ProjectSlug == "" {
-		return nil, errors.New("secretsScope.projectSlug and secretsScope.environmentSlug cannot be empty")
+	if err := validateSecretsScope(infisicalStoreSpec); err != nil {
+		return nil, err
 	}
 	}
 
 
-	// Validate CAProvider namespace requirements
-	if infisicalStoreSpec.CAProvider != nil {
-		if store.GetObjectKind().GroupVersionKind().Kind == esv1.ClusterSecretStoreKind &&
-			infisicalStoreSpec.CAProvider.Namespace == nil {
-			return nil, errors.New("caProvider.namespace is required for ClusterSecretStore")
-		}
-		if store.GetObjectKind().GroupVersionKind().Kind == esv1.SecretStoreKind &&
-			infisicalStoreSpec.CAProvider.Namespace != nil {
-			return nil, errors.New("caProvider.namespace must be empty with SecretStore")
-		}
+	if err := validateCAProvider(store, infisicalStoreSpec); err != nil {
+		return nil, err
 	}
 	}
 
 
-	if infisicalStoreSpec.Auth.UniversalAuthCredentials != nil {
-		uaCredential := infisicalStoreSpec.Auth.UniversalAuthCredentials
-		// to validate reference authentication
-		err := esutils.ValidateReferentSecretSelector(store, uaCredential.ClientID)
-		if err != nil {
-			return nil, err
-		}
+	if err := validateUniversalAuth(store, infisicalStoreSpec); err != nil {
+		return nil, err
+	}
 
 
-		err = esutils.ValidateReferentSecretSelector(store, uaCredential.ClientSecret)
-		if err != nil {
-			return nil, err
-		}
+	return nil, nil
+}
 
 
-		if uaCredential.ClientID.Key == "" || uaCredential.ClientSecret.Key == "" {
-			return nil, errors.New("universalAuthCredentials.clientId and universalAuthCredentials.clientSecret cannot be empty")
-		}
+func validateSecretsScope(spec *esv1.InfisicalProvider) error {
+	if spec.SecretsScope.EnvironmentSlug == "" || spec.SecretsScope.ProjectSlug == "" {
+		return errors.New("secretsScope.projectSlug and secretsScope.environmentSlug cannot be empty")
 	}
 	}
+	return nil
+}
 
 
-	return nil, nil
+func validateCAProvider(store esv1.GenericStore, spec *esv1.InfisicalProvider) error {
+	if spec.CAProvider == nil {
+		return nil
+	}
+
+	storeKind := store.GetObjectKind().GroupVersionKind().Kind
+	if storeKind == esv1.ClusterSecretStoreKind && spec.CAProvider.Namespace == nil {
+		return errors.New("caProvider.namespace is required for ClusterSecretStore")
+	}
+	if storeKind == esv1.SecretStoreKind && spec.CAProvider.Namespace != nil {
+		return errors.New("caProvider.namespace must be empty with SecretStore")
+	}
+	return nil
+}
+
+func validateUniversalAuth(store esv1.GenericStore, spec *esv1.InfisicalProvider) error {
+	if spec.Auth.UniversalAuthCredentials == nil {
+		return nil
+	}
+
+	uaCredential := spec.Auth.UniversalAuthCredentials
+	if err := esutils.ValidateReferentSecretSelector(store, uaCredential.ClientID); err != nil {
+		return err
+	}
+	if err := esutils.ValidateReferentSecretSelector(store, uaCredential.ClientSecret); err != nil {
+		return err
+	}
+	if uaCredential.ClientID.Key == "" || uaCredential.ClientSecret.Key == "" {
+		return errors.New("universalAuthCredentials.clientId and universalAuthCredentials.clientSecret cannot be empty")
+	}
+	return nil
 }
 }
 
 
 // NewProvider creates a new Provider instance.
 // NewProvider creates a new Provider instance.