diff --git a/operator/pkg/preflight/configconnectorcontextchecker.go b/operator/pkg/preflight/configconnectorcontextchecker.go index e4e882b21d..47f31399f4 100644 --- a/operator/pkg/preflight/configconnectorcontextchecker.go +++ b/operator/pkg/preflight/configconnectorcontextchecker.go @@ -17,6 +17,7 @@ package preflight import ( "context" "fmt" + "regexp" corev1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/apis/core/v1beta1" "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/k8s" @@ -52,5 +53,21 @@ func (c *ConfigConnectorContextChecker) Preflight(_ context.Context, o declarati return fmt.Errorf("spec.billingProject must be set if spec.requestProjectPolicy is set to %v", k8s.BillingProjectPolicy) } + if err := validateGSAFormat(ccc.Spec.GoogleServiceAccount); err != nil { + return err + } + + return nil +} + +func validateGSAFormat(gsa string) error { + if gsa == "" { // GoogleServiceAccount is a required field. We do not need to fail here. + return nil + } + validGSAPattern := `^[A-Za-z0-9._%+\-]+@[a-z0-9.\-]+\.gserviceaccount.com$` + emailRegex := regexp.MustCompile(validGSAPattern) + if !emailRegex.MatchString(gsa) { + return fmt.Errorf("invalid GoogleServiceAccount format for %q", gsa) + } return nil } diff --git a/operator/pkg/preflight/configconnectorcontextchecker_test.go b/operator/pkg/preflight/configconnectorcontextchecker_test.go index d25a9601b2..97fe93ac8f 100644 --- a/operator/pkg/preflight/configconnectorcontextchecker_test.go +++ b/operator/pkg/preflight/configconnectorcontextchecker_test.go @@ -169,3 +169,49 @@ func TestConfigConnectorContextChecker(t *testing.T) { }) } } + +func TestValidateGSAFormat(t *testing.T) { + tests := []struct { + name string + gsa string + err error + }{ + { + name: "empty", + gsa: "", + err: nil, + }, + { + name: "valid GSA format", + gsa: "foo@abc.gserviceaccount.com", + err: nil, + }, + { + name: "valid GSA format", + gsa: "foo@abc.def.gserviceaccount.com", + err: nil, + }, + { + name: "valid GSA format", + gsa: "foo@abc.def.ghi.gserviceaccount.com", + err: nil, + }, + { + name: "invalid GSA format", + gsa: "abc", + err: fmt.Errorf("invalid GoogleServiceAccount format for %q", "abc"), + }, + { + name: "invalid GSA format", + gsa: "foo@bar.com", + err: fmt.Errorf("invalid GoogleServiceAccount format for %q", "foo@bar.com"), + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + err := validateGSAFormat(tc.gsa) + asserts.AssertErrorIsExpected(t, err, tc.err) + }) + } +}