package controller import ( "crypto/sha1" "encoding/hex" "regexp" "strings" ) const ( // maxObjectName is the DNS-1123 subdomain limit for Kubernetes object names. maxObjectName = 253 // maxBucketName is the DNS-1123 label limit RGW enforces on S3 bucket names. maxBucketName = 63 namePrefix = "autobk" ) var invalidNameChars = regexp.MustCompile(`[^a-z0-9-]+`) // bucketName derives the namespace-scoped, globally-unique S3 bucket name (and // the Bucket CR name) for an annotated object, clamped to the 63-char RGW limit. func bucketName(namespace, obj string) string { return boundedName(maxBucketName, namePrefix, namespace, obj) } // userName, accessName, credSecretName, resticSecretName and scheduleName derive // the per-object child resource names. These are namespaced objects, so the // namespace is not part of the name (only uniqueness within the namespace is // required). func userName(obj string) string { return boundedName(maxObjectName, namePrefix, obj, "owner") } func accessName(obj string) string { return boundedName(maxObjectName, namePrefix, obj, "rw") } func credSecretName(obj string) string { return boundedName(maxObjectName, obj, "autobackup", "rgw") } func resticSecretName(obj string) string { return boundedName(maxObjectName, obj, "autobackup", "restic") } func scheduleName(obj string) string { return boundedName(maxObjectName, obj, "autobackup") } // boundedName joins parts with "-", sanitises to a DNS-safe token and, when the // result would exceed max, truncates it and appends a short deterministic hash // of the full joined value so long inputs stay unique and within limits. func boundedName(max int, parts ...string) string { joined := strings.Join(parts, "-") s := sanitizeName(joined) if len(s) <= max { return s } sum := sha1.Sum([]byte(joined)) h := hex.EncodeToString(sum[:])[:8] keep := max - len(h) - 1 if keep < 1 { return h[:max] } return strings.TrimRight(s[:keep], "-") + "-" + h } func sanitizeName(s string) string { s = strings.ToLower(s) s = invalidNameChars.ReplaceAllString(s, "-") s = strings.Trim(s, "-") if s == "" { return namePrefix } return s }