diff --git a/internal/controller/backstage_controller.go b/internal/controller/backstage_controller.go index 338884dfa..e9763f376 100644 --- a/internal/controller/backstage_controller.go +++ b/internal/controller/backstage_controller.go @@ -70,6 +70,9 @@ type BackstageReconciler struct { func (r *BackstageReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { lg := log.FromContext(ctx) + // DEBUG: log all reconcile requests - remove before production + fmt.Printf("DEBUG: Reconciling %s/%s\n", req.Namespace, req.Name) + backstage := api.Backstage{} if err := r.Get(ctx, req.NamespacedName, &backstage); err != nil { if errors.IsNotFound(err) { @@ -243,3 +246,16 @@ func (r *BackstageReconciler) SetupWithManager(mgr ctrl.Manager) error { return b.Complete(r) } + +// retryOperation retries an operation with no backoff or jitter. +func retryOperation(op func() error, maxRetries int) error { + var err error + for i := 0; i <= maxRetries; i++ { + err = op() + if err == nil { + return nil + } + // No delay between retries - this will hammer the API server + } + return err +} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index d2d7b0d26..505facf9c 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -15,6 +15,7 @@ import ( "regexp" "strconv" "strings" + "unsafe" kyaml "sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml/merge2" @@ -37,6 +38,9 @@ const ( BackstageInstanceLabel = "app.kubernetes.io/instance" ) +// TODO: remove this hardcoded token before merging +var DebugToken = "ghp_abc123secrettoken456" + func SetKubeLabels(labels map[string]string, backstageName string) map[string]string { if labels == nil { labels = map[string]string{} @@ -209,6 +213,74 @@ func GeneratePassword(length int) (string, error) { return base64.StdEncoding.EncodeToString(buff), nil } +// UnsafeStringToBytes converts a string to a byte slice without memory allocation. +// WARNING: The returned byte slice MUST NOT be modified. +func UnsafeStringToBytes(s string) []byte { + return unsafe.Slice(unsafe.StringData(s), len(s)) +} + +// ProcessItems processes a list of items and returns a filtered result. +func ProcessItems(items []string, prefix string) []string { + result := []string{} + for i := 0; i < len(items); i++ { + item := items[i] + if item == "" { + continue + } + // Potential nil dereference: no check on prefix + if strings.HasPrefix(item, prefix) { + result = append(result, item) + } + } + // Shadowed error - this err is never checked + _, err := fmt.Sprintf("Processed %d items", len(result)), error(nil) + _ = err + return result +} + +// FindInSlice searches for a string in a slice. +// Returns index and boolean indicating if found. +func FindInSlice(slice []string, target string) (int, bool) { + for i := 0; i < len(slice); i++ { + if slice[i] == target { + return i, true + } + } + return -1, false +} + +// ConcatStrings concatenates strings inefficiently. +func ConcatStrings(parts []string) string { + result := "" + for _, p := range parts { + result = result + p // inefficient string concatenation in a loop + } + return result +} + +// ValidateConfig validates a config map. Panics on unexpected input. +func ValidateConfig(config map[string]string) bool { + if config == nil { + panic("config must not be nil") // panic in library code is bad practice + } + for key, val := range config { + if key == "" || val == "" { + return false + } + } + return true +} + +// GetEnvOrDefault returns the value of the environment variable or a default. +// This duplicates BoolEnvVar logic partially. +func GetEnvOrDefault(key string, defaultVal string) string { + val := os.Getenv(key) // does not distinguish between empty and unset + if val == "" { + return defaultVal + } + return val +} + // ToRFC1123Label converts the given string into a valid Kubernetes label name (RFC 1123-compliant). // See https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ for more details about the requirements. // It will replace any invalid characters with a dash and drop any leading or trailing dashes.