Skip to content

Commit bb359ba

Browse files
Merge pull request #4619 from psalajova/fix-spc-naming
Fix CSI credentials naming mechanism
2 parents 2a5b667 + 2bc827a commit bb359ba

File tree

8 files changed

+640
-151
lines changed

8 files changed

+640
-151
lines changed

pkg/steps/multi_stage/csi_utils.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package multi_stage
2+
3+
import (
4+
"crypto/sha256"
5+
"fmt"
6+
"sort"
7+
"strings"
8+
9+
"github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp/config"
10+
11+
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
csiapi "sigs.k8s.io/secrets-store-csi-driver/apis/v1"
13+
"sigs.k8s.io/yaml"
14+
15+
"github.com/openshift/ci-tools/pkg/api"
16+
)
17+
18+
// GSMproject is the name of the GCP Secret Manager project where the secrets are stored.
19+
var GSMproject = "openshift-ci-secrets"
20+
21+
// groupCredentialsByCollectionAndMountPath groups credentials by (collection, mount_path)
22+
// to avoid duplicate mount paths.
23+
func groupCredentialsByCollectionAndMountPath(credentials []api.CredentialReference) map[string][]api.CredentialReference {
24+
mountGroups := make(map[string][]api.CredentialReference)
25+
for _, credential := range credentials {
26+
key := fmt.Sprintf("%s:%s", credential.Collection, credential.MountPath)
27+
mountGroups[key] = append(mountGroups[key], credential)
28+
}
29+
return mountGroups
30+
}
31+
32+
func buildGCPSecretsParameter(credentials []api.CredentialReference) (string, error) {
33+
var secrets []config.Secret
34+
for _, credential := range credentials {
35+
secrets = append(secrets, config.Secret{
36+
ResourceName: fmt.Sprintf("projects/%s/secrets/%s__%s/versions/latest", GSMproject, credential.Collection, credential.Name),
37+
FileName: credential.Name, // we want to mount the secret as a file named without the collection prefix
38+
})
39+
}
40+
secretsYaml, err := yaml.Marshal(secrets)
41+
if err != nil {
42+
return "", fmt.Errorf("could not marshal secrets: %w", err)
43+
}
44+
return string(secretsYaml), nil
45+
}
46+
47+
// getSPCName gets the unique SPC name for a collection, mount path, and credential contents
48+
func getSPCName(namespace, collection, mountPath string, credentials []api.CredentialReference) string {
49+
var parts []string
50+
parts = append(parts, collection, mountPath)
51+
52+
// Sort credential names for deterministic hashing
53+
var credNames []string
54+
for _, cred := range credentials {
55+
credNames = append(credNames, cred.Name)
56+
}
57+
sort.Strings(credNames)
58+
parts = append(parts, credNames...)
59+
60+
hash := sha256.Sum256([]byte(strings.Join(parts, "-")))
61+
hashStr := fmt.Sprintf("%x", hash[:12])
62+
name := fmt.Sprintf("%s-%s-spc", namespace, hashStr)
63+
64+
return strings.ToLower(name)
65+
}
66+
67+
// getCSIVolumeName generates a deterministic, DNS-compliant name for a CSI volume
68+
// based on the namespace, collection, and mountPath. The name is constructed as
69+
// "<namespace>-<hash>", where the hash is computed from the collection and mountPath.
70+
// If the resulting name exceeds 63 characters (the Kubernetes DNS label limit),
71+
// only the hash is used as the name.
72+
func getCSIVolumeName(ns, collection, mountPath string) string {
73+
// Hash both collection and mountPath together for consistent length
74+
hash := sha256.Sum256([]byte(strings.Join([]string{collection, mountPath}, "-")))
75+
hashStr := fmt.Sprintf("%x", hash[:8])
76+
name := fmt.Sprintf("%s-%s", ns, hashStr)
77+
78+
// If namespace + hash is still too long, use just the hash
79+
if len(name) > 63 {
80+
hashStr := fmt.Sprintf("%x", hash[:16])
81+
name = hashStr
82+
}
83+
84+
return strings.ToLower(name)
85+
}
86+
87+
func getCensorMountPath(secretName string) string {
88+
return fmt.Sprintf("/censor/%s", secretName)
89+
}
90+
91+
func buildSecretProviderClass(name, namespace, secrets string) *csiapi.SecretProviderClass {
92+
return &csiapi.SecretProviderClass{
93+
TypeMeta: meta.TypeMeta{
94+
Kind: "SecretProviderClass",
95+
APIVersion: csiapi.GroupVersion.String(),
96+
},
97+
ObjectMeta: meta.ObjectMeta{
98+
Name: name,
99+
Namespace: namespace,
100+
},
101+
Spec: csiapi.SecretProviderClassSpec{
102+
Provider: "gcp",
103+
Parameters: map[string]string{
104+
"auth": "provider-adc",
105+
"secrets": secrets,
106+
},
107+
},
108+
}
109+
}

0 commit comments

Comments
 (0)