From ee73af19efd65d385a77a2ad1991e50585600045 Mon Sep 17 00:00:00 2001 From: Grace Gao <52978759+grac3gao@users.noreply.github.com> Date: Tue, 26 May 2020 18:00:49 -0700 Subject: [PATCH] Add k8s service account under identity spec (#1128) * add k8s service account * change * add intevents * add channel * change channel --- config/core/resources/channel.yaml | 16 ++++-- .../core/resources/cloudauditlogssource.yaml | 8 ++- config/core/resources/cloudbuildsource.yaml | 8 ++- config/core/resources/cloudpubsubsource.yaml | 8 ++- .../core/resources/cloudschedulersource.yaml | 8 ++- config/core/resources/cloudstoragesource.yaml | 12 ++-- .../core/resources/old_pullsubscription.yaml | 3 + config/core/resources/old_topic.yaml | 3 + config/core/resources/pullsubscription.yaml | 3 + config/core/resources/topic.yaml | 3 + pkg/apis/convert/conversion_helper.go | 4 +- pkg/apis/convert/conversion_helper_test.go | 2 +- pkg/apis/duck/v1alpha1/credentials.go | 38 ++++++++++--- pkg/apis/duck/v1alpha1/credentials_test.go | 10 ++-- pkg/apis/duck/v1alpha1/identity_types.go | 5 ++ pkg/apis/duck/v1alpha1/pubsub_defaults.go | 3 +- pkg/apis/duck/v1beta1/credentials.go | 30 +++++----- pkg/apis/duck/v1beta1/credentials_test.go | 6 +- pkg/apis/duck/v1beta1/identity_types.go | 5 +- pkg/apis/duck/v1beta1/pubsub_defaults.go | 2 +- .../cloudauditlogssource_conversion_test.go | 2 +- .../cloudauditlogssource_types_test.go | 6 +- .../cloudauditlogssource_validation.go | 2 +- .../cloudauditlogssource_validation_test.go | 14 ++--- .../v1alpha1/cloudbuildsource_types_test.go | 6 +- .../v1alpha1/cloudbuildsource_validation.go | 2 +- .../cloudbuildsource_validation_test.go | 8 +-- .../v1alpha1/cloudpubsubsource_types_test.go | 4 +- .../v1alpha1/cloudpubsubsource_validation.go | 2 +- .../cloudpubsubsource_validation_test.go | 8 +-- .../cloudschedulersource_types_test.go | 4 +- .../cloudschedulersource_validation.go | 2 +- .../cloudschedulersource_validation_test.go | 14 ++--- .../cloudstoragesource_conversion_test.go | 11 ++-- .../v1alpha1/cloudstoragesource_types.go | 7 --- .../v1alpha1/cloudstoragesource_types_test.go | 4 +- .../v1alpha1/cloudstoragesource_validation.go | 2 +- .../cloudstoragesource_validation_test.go | 18 +++--- .../cloudauditlogssource_types_test.go | 6 +- .../cloudauditlogssource_validation.go | 2 +- .../cloudauditlogssource_validation_test.go | 14 ++--- .../v1beta1/cloudpubsubsource_types_test.go | 6 +- .../v1beta1/cloudpubsubsource_validation.go | 2 +- .../cloudpubsubsource_validation_test.go | 10 ++-- .../cloudschedulersource_types_test.go | 6 +- .../cloudschedulersource_validation.go | 2 +- .../cloudschedulersource_validation_test.go | 16 +++--- .../v1beta1/cloudstoragesource_types.go | 7 --- .../v1beta1/cloudstoragesource_types_test.go | 6 +- .../v1beta1/cloudstoragesource_validation.go | 2 +- .../cloudstoragesource_validation_test.go | 20 +++---- .../pullsubscription_conversion_test.go | 2 +- .../v1alpha1/pullsubscription_types_test.go | 6 +- .../intevents/v1alpha1/topic_types_test.go | 6 +- .../v1beta1/pullsubscription_types_test.go | 6 +- .../intevents/v1beta1/topic_types_test.go | 6 +- .../v1alpha1/channel_conversion_test.go | 2 +- .../messaging/v1alpha1/channel_defaults.go | 3 +- .../messaging/v1alpha1/channel_types_test.go | 4 +- .../messaging/v1alpha1/channel_validation.go | 2 +- .../v1alpha1/channel_validation_test.go | 22 ++++---- .../messaging/v1beta1/channel_defaults.go | 2 +- .../messaging/v1beta1/channel_types_test.go | 6 +- .../messaging/v1beta1/channel_validation.go | 4 +- .../v1beta1/channel_validation_test.go | 24 ++++---- .../pullsubscription_conversion_test.go | 2 +- .../v1alpha1/pullsubscription_types_test.go | 6 +- pkg/apis/pubsub/v1alpha1/topic_types_test.go | 6 +- .../v1beta1/pullsubscription_types_test.go | 6 +- pkg/apis/pubsub/v1beta1/topic_types_test.go | 6 +- .../resources/receive_adapter.go | 11 ++++ .../intevents/resources/pullsubscription.go | 1 + pkg/reconciler/intevents/resources/topic.go | 1 + .../intevents/topic/resources/publisher.go | 11 ++++ pkg/reconciler/messaging/channel/channel.go | 55 ++++++++++--------- .../channel/resources/pullsubscription.go | 20 ++++--- .../messaging/channel/resources/topic.go | 18 +++--- .../resources/receive_adapter.go | 11 ++++ .../pubsub/resources/pullsubscription.go | 1 + pkg/reconciler/pubsub/resources/topic.go | 1 + .../pubsub/topic/resources/publisher.go | 11 ++++ test/e2e/test_pullsubscription.go | 4 +- 82 files changed, 384 insertions(+), 274 deletions(-) diff --git a/config/core/resources/channel.yaml b/config/core/resources/channel.yaml index d4b6dda8c2..02b166d5cd 100644 --- a/config/core/resources/channel.yaml +++ b/config/core/resources/channel.yaml @@ -76,8 +76,14 @@ spec: type: string description: > GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service - account must be a valid Google service account (see + account must be a valid Google service account. (see https://cloud.google.com/iam/docs/service-accounts). + serviceAccountName: + type: string + description: > + k8s service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. + The value of the k8s service account must be a valid DNS subdomain name. + (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names) secret: type: object description: > @@ -209,12 +215,12 @@ spec: spec: type: object properties: - googleServiceAccount: + serviceAccountName: type: string description: > - GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service - account must be a valid Google service account (see - https://cloud.google.com/iam/docs/service-accounts). + Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. + The value of the Kubernetes service account must be a valid DNS subdomain name. + (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names) secret: type: object description: > diff --git a/config/core/resources/cloudauditlogssource.yaml b/config/core/resources/cloudauditlogssource.yaml index 2947dfbbdc..4de46a466e 100644 --- a/config/core/resources/cloudauditlogssource.yaml +++ b/config/core/resources/cloudauditlogssource.yaml @@ -114,8 +114,14 @@ spec: type: string description: > GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service - account must be a valid Google service account (see + account must be a valid Google service account. (see https://cloud.google.com/iam/docs/service-accounts). + serviceAccountName: + type: string + description: > + Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. + The value of the Kubernetes service account must be a valid DNS subdomain name. + (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names) secret: type: object description: > diff --git a/config/core/resources/cloudbuildsource.yaml b/config/core/resources/cloudbuildsource.yaml index 213aba1b7f..3bb4a81ca1 100644 --- a/config/core/resources/cloudbuildsource.yaml +++ b/config/core/resources/cloudbuildsource.yaml @@ -104,8 +104,14 @@ spec: type: string description: > GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service - account must be a valid Google service account (see + account must be a valid Google service account. (see https://cloud.google.com/iam/docs/service-accounts). + serviceAccountName: + type: string + description: > + Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. + The value of the Kubernetes service account must be a valid DNS subdomain name. + (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names) secret: type: object description: > diff --git a/config/core/resources/cloudpubsubsource.yaml b/config/core/resources/cloudpubsubsource.yaml index 106bd7adab..578a95f9be 100644 --- a/config/core/resources/cloudpubsubsource.yaml +++ b/config/core/resources/cloudpubsubsource.yaml @@ -113,8 +113,14 @@ spec: type: string description: > GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service - account must be a valid Google service account (see + account must be a valid Google service account. (see https://cloud.google.com/iam/docs/service-accounts). + serviceAccountName: + type: string + description: > + Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. + The value of the Kubernetes service account must be a valid DNS subdomain name. + (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names) secret: type: object description: > diff --git a/config/core/resources/cloudschedulersource.yaml b/config/core/resources/cloudschedulersource.yaml index ae200bfb7f..a6bad81cc3 100644 --- a/config/core/resources/cloudschedulersource.yaml +++ b/config/core/resources/cloudschedulersource.yaml @@ -115,8 +115,14 @@ spec: type: string description: > GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service - account must be a valid Google service account (see + account must be a valid Google service account. (see https://cloud.google.com/iam/docs/service-accounts). + serviceAccountName: + type: string + description: > + Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. + The value of the Kubernetes service account must be a valid DNS subdomain name. + (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names) secret: type: object description: > diff --git a/config/core/resources/cloudstoragesource.yaml b/config/core/resources/cloudstoragesource.yaml index 0290f0c089..4d67763591 100644 --- a/config/core/resources/cloudstoragesource.yaml +++ b/config/core/resources/cloudstoragesource.yaml @@ -116,8 +116,14 @@ spec: type: string description: > GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service - account must be a valid Google service account (see + account must be a valid Google service account. (see https://cloud.google.com/iam/docs/service-accounts). + serviceAccountName: + type: string + description: > + Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. + The value of the Kubernetes service account must be a valid DNS subdomain name. + (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names) secret: type: object description: > @@ -137,10 +143,6 @@ spec: description: > Google Cloud Project ID of the project into which the topic should be created. If omitted uses the Project ID from the GKE cluster metadata service. - serviceAccountName: - type: string - description: > - Service Account to run Receive Adapter as. If omitted, uses 'default'. bucket: type: string description: > diff --git a/config/core/resources/old_pullsubscription.yaml b/config/core/resources/old_pullsubscription.yaml index 70c2c3243e..3e6a7115eb 100644 --- a/config/core/resources/old_pullsubscription.yaml +++ b/config/core/resources/old_pullsubscription.yaml @@ -70,6 +70,9 @@ spec: googleServiceAccount: type: string description: "GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service account must be a valid Google service account (see https://cloud.google.com/iam/docs/service-accounts)." + serviceAccountName: + type: string + description: "Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. The value of the Kubernetes service account must be a valid DNS subdomain name. (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names)" secret: type: object description: "Credential used to poll the Cloud Pub/Sub Subscription. It is not used to create or delete the Subscription, only to poll it. The value of the secret entry must be a service account key in the JSON format (see https://cloud.google.com/iam/docs/creating-managing-service-account-keys). Defaults to secret.name of 'google-cloud-key' and secret.key of 'key.json'." diff --git a/config/core/resources/old_topic.yaml b/config/core/resources/old_topic.yaml index 29371408eb..b19ec14525 100644 --- a/config/core/resources/old_topic.yaml +++ b/config/core/resources/old_topic.yaml @@ -72,6 +72,9 @@ spec: googleServiceAccount: type: string description: "GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service account must be a valid Google service account (see https://cloud.google.com/iam/docs/service-accounts)." + serviceAccountName: + type: string + description: "Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. The value of the Kubernetes service account must be a valid DNS subdomain name. (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names)" secret: type: object description: "Credential used to poll the Cloud Pub/Sub Subscription. It is not used to create or delete the Subscription, only to poll it. The value of the secret entry must be a service account key in the JSON format (see https://cloud.google.com/iam/docs/creating-managing-service-account-keys). Defaults to secret.name of 'google-cloud-key' and secret.key of 'key.json'." diff --git a/config/core/resources/pullsubscription.yaml b/config/core/resources/pullsubscription.yaml index d11f9f9428..b67ca2dc14 100644 --- a/config/core/resources/pullsubscription.yaml +++ b/config/core/resources/pullsubscription.yaml @@ -70,6 +70,9 @@ spec: googleServiceAccount: type: string description: "GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service account must be a valid Google service account (see https://cloud.google.com/iam/docs/service-accounts)." + serviceAccountName: + type: string + description: "Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. The value of the Kubernetes service account must be a valid DNS subdomain name. (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names)" secret: type: object description: "Credential used to poll the Cloud Pub/Sub Subscription. It is not used to create or delete the Subscription, only to poll it. The value of the secret entry must be a service account key in the JSON format (see https://cloud.google.com/iam/docs/creating-managing-service-account-keys). Defaults to secret.name of 'google-cloud-key' and secret.key of 'key.json'." diff --git a/config/core/resources/topic.yaml b/config/core/resources/topic.yaml index 10bebc6342..5112e15b15 100644 --- a/config/core/resources/topic.yaml +++ b/config/core/resources/topic.yaml @@ -72,6 +72,9 @@ spec: googleServiceAccount: type: string description: "GCP service account used to poll the Cloud Pub/Sub Subscription. The value of the service account must be a valid Google service account (see https://cloud.google.com/iam/docs/service-accounts)." + serviceAccountName: + type: string + description: "Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. The value of the Kubernetes service account must be a valid DNS subdomain name. (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names)" secret: type: object description: "Credential used to poll the Cloud Pub/Sub Subscription. It is not used to create or delete the Subscription, only to poll it. The value of the secret entry must be a service account key in the JSON format (see https://cloud.google.com/iam/docs/creating-managing-service-account-keys). Defaults to secret.name of 'google-cloud-key' and secret.key of 'key.json'." diff --git a/pkg/apis/convert/conversion_helper.go b/pkg/apis/convert/conversion_helper.go index f908afe5ba..21e3ff737c 100644 --- a/pkg/apis/convert/conversion_helper.go +++ b/pkg/apis/convert/conversion_helper.go @@ -46,12 +46,12 @@ func FromV1beta1PubSubSpec(from duckv1beta1.PubSubSpec) duckv1alpha1.PubSubSpec func ToV1beta1IdentitySpec(from duckv1alpha1.IdentitySpec) duckv1beta1.IdentitySpec { to := duckv1beta1.IdentitySpec{} - to.GoogleServiceAccount = from.GoogleServiceAccount + to.ServiceAccountName = from.ServiceAccountName return to } func FromV1beta1IdentitySpec(from duckv1beta1.IdentitySpec) duckv1alpha1.IdentitySpec { to := duckv1alpha1.IdentitySpec{} - to.GoogleServiceAccount = from.GoogleServiceAccount + to.ServiceAccountName = from.ServiceAccountName return to } diff --git a/pkg/apis/convert/conversion_helper_test.go b/pkg/apis/convert/conversion_helper_test.go index 4ed4ffbf89..869ae790ac 100644 --- a/pkg/apis/convert/conversion_helper_test.go +++ b/pkg/apis/convert/conversion_helper_test.go @@ -69,7 +69,7 @@ var ( } completeIdentitySpec = duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: "googleServiceAccount", + ServiceAccountName: "k8sServiceAccount", } completeSecret = &v1.SecretKeySelector{ diff --git a/pkg/apis/duck/v1alpha1/credentials.go b/pkg/apis/duck/v1alpha1/credentials.go index bf79195c8e..9f2dc6c270 100644 --- a/pkg/apis/duck/v1alpha1/credentials.go +++ b/pkg/apis/duck/v1alpha1/credentials.go @@ -31,7 +31,8 @@ const ( ) var ( - validation_regexp = regexp.MustCompile(`^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`) + validation_regexp = regexp.MustCompile(`^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`) + validation_regexp_k8s = regexp.MustCompile(`^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`) ) // DefaultGoogleCloudSecretSelector is the default secret selector used to load @@ -45,19 +46,25 @@ func DefaultGoogleCloudSecretSelector() *corev1.SecretKeySelector { } } -// ValidateCredential checks secret and GCP service account. -func ValidateCredential(secret *corev1.SecretKeySelector, gServiceAccountName string) *apis.FieldError { - if secret != nil && !equality.Semantic.DeepEqual(secret, &corev1.SecretKeySelector{}) && gServiceAccountName != "" { +// ValidateCredential checks secret and service account. +func ValidateCredential(secret *corev1.SecretKeySelector, gServiceAccountName string, kServiceAccountName string) *apis.FieldError { + if secret != nil && !equality.Semantic.DeepEqual(secret, &corev1.SecretKeySelector{}) && kServiceAccountName != "" { return &apis.FieldError{ - Message: "Can't have spec.googleServiceAccount and spec.secret at the same time", + Message: "Can't have spec.serviceAccountName and spec.secret at the same time", Paths: []string{""}, } } else if secret != nil && !equality.Semantic.DeepEqual(secret, &corev1.SecretKeySelector{}) { return validateSecret(secret) - } else if gServiceAccountName != "" { - return validateGCPServiceAccount(gServiceAccountName) + } else { + var errs *apis.FieldError + if kServiceAccountName != "" { + errs = errs.Also(validateK8sServiceAccount(kServiceAccountName)) + } + if gServiceAccountName != "" { + errs = errs.Also(validateGCPServiceAccount(gServiceAccountName)) + } + return errs } - return nil } func validateSecret(secret *corev1.SecretKeySelector) *apis.FieldError { @@ -89,3 +96,18 @@ func validateGCPServiceAccount(gServiceAccountName string) *apis.FieldError { } return nil } + +func validateK8sServiceAccount(kServiceAccountName string) *apis.FieldError { + // The name of a k8s ServiceAccount object must be a valid DNS subdomain name. + // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names + + match := validation_regexp_k8s.FindStringSubmatch(kServiceAccountName) + if len(match) == 0 { + return &apis.FieldError{ + Message: fmt.Sprintf(`invalid value: %s, serviceAccountName should have format: ^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`, + kServiceAccountName), + Paths: []string{"serviceAccountName"}, + } + } + return nil +} diff --git a/pkg/apis/duck/v1alpha1/credentials_test.go b/pkg/apis/duck/v1alpha1/credentials_test.go index 0c9d3d5a86..54e23294b2 100644 --- a/pkg/apis/duck/v1alpha1/credentials_test.go +++ b/pkg/apis/duck/v1alpha1/credentials_test.go @@ -59,26 +59,26 @@ func TestValidateCredential(t *testing.T) { serviceAccount: "", wantErr: true, }, { - name: "nil secret, and valid service account", + name: "nil secret, and valid k8s service account", secret: nil, - serviceAccount: "test123@test123.iam.gserviceaccount.com", + serviceAccount: "test123", wantErr: false, }, { name: "nil secret, and invalid service account", secret: nil, - serviceAccount: "test@test", + serviceAccount: "@test", wantErr: true, }, { name: "secret and service account exist at the same time", secret: DefaultGoogleCloudSecretSelector(), - serviceAccount: "test@test.iam.gserviceaccount.com", + serviceAccount: "test", wantErr: true, }} defer logtesting.ClearAll() for _, tc := range testCases { - errs := ValidateCredential(tc.secret, tc.serviceAccount) + errs := ValidateCredential(tc.secret, "", tc.serviceAccount) got := errs != nil if diff := cmp.Diff(tc.wantErr, got); diff != "" { t.Errorf("unexpected resource (-want, +got) = %v", diff) diff --git a/pkg/apis/duck/v1alpha1/identity_types.go b/pkg/apis/duck/v1alpha1/identity_types.go index 378c3abee3..4e3d2f653e 100644 --- a/pkg/apis/duck/v1alpha1/identity_types.go +++ b/pkg/apis/duck/v1alpha1/identity_types.go @@ -23,6 +23,11 @@ type IdentitySpec struct { // If not specified, defaults to use secret. // +optional GoogleServiceAccount string `json:"googleServiceAccount,omitempty"` + // ServiceAccountName is the k8s service account which binds to a google service account. + // This google service account has required permissions to poll from a Cloud Pub/Sub subscription. + // If not specified, defaults to use secret. + // +optional + ServiceAccountName string `json:"serviceAccountName,omitempty"` } // IdentityStatus inherits duck/v1 Status and adds a ServiceAccountName. diff --git a/pkg/apis/duck/v1alpha1/pubsub_defaults.go b/pkg/apis/duck/v1alpha1/pubsub_defaults.go index b6318e9dc5..48fdcc3393 100644 --- a/pkg/apis/duck/v1alpha1/pubsub_defaults.go +++ b/pkg/apis/duck/v1alpha1/pubsub_defaults.go @@ -22,7 +22,8 @@ import ( ) func (s *PubSubSpec) SetPubSubDefaults() { - if s.GoogleServiceAccount == "" && (s.Secret == nil || equality.Semantic.DeepEqual(s.Secret, &corev1.SecretKeySelector{})) { + if s.GoogleServiceAccount == "" && s.ServiceAccountName == "" && + (s.Secret == nil || equality.Semantic.DeepEqual(s.Secret, &corev1.SecretKeySelector{})) { s.Secret = DefaultGoogleCloudSecretSelector() } } diff --git a/pkg/apis/duck/v1beta1/credentials.go b/pkg/apis/duck/v1beta1/credentials.go index c7c1686220..50c147be87 100644 --- a/pkg/apis/duck/v1beta1/credentials.go +++ b/pkg/apis/duck/v1beta1/credentials.go @@ -31,7 +31,7 @@ const ( ) var ( - validation_regexp = regexp.MustCompile(`^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`) + validation_regexp_k8s = regexp.MustCompile(`^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`) ) // DefaultGoogleCloudSecretSelector is the default secret selector used to load @@ -46,16 +46,16 @@ func DefaultGoogleCloudSecretSelector() *corev1.SecretKeySelector { } // ValidateCredential checks secret and GCP service account. -func ValidateCredential(secret *corev1.SecretKeySelector, gServiceAccountName string) *apis.FieldError { - if secret != nil && !equality.Semantic.DeepEqual(secret, &corev1.SecretKeySelector{}) && gServiceAccountName != "" { +func ValidateCredential(secret *corev1.SecretKeySelector, kServiceAccountName string) *apis.FieldError { + if secret != nil && !equality.Semantic.DeepEqual(secret, &corev1.SecretKeySelector{}) && kServiceAccountName != "" { return &apis.FieldError{ - Message: "Can't have spec.googleServiceAccount and spec.secret at the same time", + Message: "Can't have spec.serviceAccountName and spec.secret at the same time", Paths: []string{""}, } } else if secret != nil && !equality.Semantic.DeepEqual(secret, &corev1.SecretKeySelector{}) { return validateSecret(secret) - } else if gServiceAccountName != "" { - return validateGCPServiceAccount(gServiceAccountName) + } else if kServiceAccountName != "" { + return validateK8sServiceAccount(kServiceAccountName) } return nil } @@ -71,20 +71,16 @@ func validateSecret(secret *corev1.SecretKeySelector) *apis.FieldError { return errs } -func validateGCPServiceAccount(gServiceAccountName string) *apis.FieldError { - // The format of gServiceAccountName is service-account-name@project-id.iam.gserviceaccount.com +func validateK8sServiceAccount(kServiceAccountName string) *apis.FieldError { + // The name of a k8s ServiceAccount object must be a valid DNS subdomain name. + // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names - // Service account name must be between 6 and 30 characters (inclusive), - // must begin with a lowercase letter, and consist of lowercase alphanumeric characters that can be separated by hyphens. - - // Project IDs must start with a lowercase letter and can have lowercase ASCII letters, digits or hyphens, - // must be between 6 and 30 characters. - match := validation_regexp.FindStringSubmatch(gServiceAccountName) + match := validation_regexp_k8s.FindStringSubmatch(kServiceAccountName) if len(match) == 0 { return &apis.FieldError{ - Message: fmt.Sprintf(`invalid value: %s, googleServiceAccount should have format: ^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`, - gServiceAccountName), - Paths: []string{"googleServiceAccount"}, + Message: fmt.Sprintf(`invalid value: %s, serviceAccountName should have format: ^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`, + kServiceAccountName), + Paths: []string{"serviceAccountName"}, } } return nil diff --git a/pkg/apis/duck/v1beta1/credentials_test.go b/pkg/apis/duck/v1beta1/credentials_test.go index e0e03ccc50..e6256bbd4f 100644 --- a/pkg/apis/duck/v1beta1/credentials_test.go +++ b/pkg/apis/duck/v1beta1/credentials_test.go @@ -61,17 +61,17 @@ func TestValidateCredential(t *testing.T) { }, { name: "nil secret, and valid service account", secret: nil, - serviceAccount: "test123@test123.iam.gserviceaccount.com", + serviceAccount: "test", wantErr: false, }, { name: "nil secret, and invalid service account", secret: nil, - serviceAccount: "test@test", + serviceAccount: "@test", wantErr: true, }, { name: "secret and service account exist at the same time", secret: DefaultGoogleCloudSecretSelector(), - serviceAccount: "test@test.iam.gserviceaccount.com", + serviceAccount: "test", wantErr: true, }} diff --git a/pkg/apis/duck/v1beta1/identity_types.go b/pkg/apis/duck/v1beta1/identity_types.go index 317288dc70..4a75f5db2b 100644 --- a/pkg/apis/duck/v1beta1/identity_types.go +++ b/pkg/apis/duck/v1beta1/identity_types.go @@ -19,10 +19,11 @@ import ( ) type IdentitySpec struct { - // GoogleServiceAccount is the GCP service account which has required permissions to poll from a Cloud Pub/Sub subscription. + // ServiceAccountName is the k8s service account which binds to a google service account. + // This google service account has required permissions to poll from a Cloud Pub/Sub subscription. // If not specified, defaults to use secret. // +optional - GoogleServiceAccount string `json:"googleServiceAccount,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty"` } // IdentityStatus inherits duck/v1 Status and adds a ServiceAccountName. diff --git a/pkg/apis/duck/v1beta1/pubsub_defaults.go b/pkg/apis/duck/v1beta1/pubsub_defaults.go index 28c65d90cd..7e3f549401 100644 --- a/pkg/apis/duck/v1beta1/pubsub_defaults.go +++ b/pkg/apis/duck/v1beta1/pubsub_defaults.go @@ -22,7 +22,7 @@ import ( ) func (s *PubSubSpec) SetPubSubDefaults() { - if s.GoogleServiceAccount == "" && (s.Secret == nil || equality.Semantic.DeepEqual(s.Secret, &corev1.SecretKeySelector{})) { + if s.ServiceAccountName == "" && (s.Secret == nil || equality.Semantic.DeepEqual(s.Secret, &corev1.SecretKeySelector{})) { s.Secret = DefaultGoogleCloudSecretSelector() } } diff --git a/pkg/apis/events/v1alpha1/cloudauditlogssource_conversion_test.go b/pkg/apis/events/v1alpha1/cloudauditlogssource_conversion_test.go index 448802a2a8..df47aec55e 100644 --- a/pkg/apis/events/v1alpha1/cloudauditlogssource_conversion_test.go +++ b/pkg/apis/events/v1alpha1/cloudauditlogssource_conversion_test.go @@ -99,7 +99,7 @@ var ( } completeIdentitySpec = duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: "googleServiceAccount", + ServiceAccountName: "k8sServiceAccount", } completeSecret = &v1.SecretKeySelector{ diff --git a/pkg/apis/events/v1alpha1/cloudauditlogssource_types_test.go b/pkg/apis/events/v1alpha1/cloudauditlogssource_types_test.go index e39703f980..4994e8cbc4 100644 --- a/pkg/apis/events/v1alpha1/cloudauditlogssource_types_test.go +++ b/pkg/apis/events/v1alpha1/cloudauditlogssource_types_test.go @@ -93,13 +93,13 @@ func TestCloudAuditLogsSourceIdentitySpec(t *testing.T) { Spec: CloudAuditLogsSourceSpec{ PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/events/v1alpha1/cloudauditlogssource_validation.go b/pkg/apis/events/v1alpha1/cloudauditlogssource_validation.go index c74f831059..3f9018ba54 100644 --- a/pkg/apis/events/v1alpha1/cloudauditlogssource_validation.go +++ b/pkg/apis/events/v1alpha1/cloudauditlogssource_validation.go @@ -51,7 +51,7 @@ func (current *CloudAuditLogsSourceSpec) Validate(ctx context.Context) *apis.Fie errs = errs.Also(apis.ErrMissingField("methodName")) } - if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1alpha1/cloudauditlogssource_validation_test.go b/pkg/apis/events/v1alpha1/cloudauditlogssource_validation_test.go index a2372e2f08..fb21e61b34 100644 --- a/pkg/apis/events/v1alpha1/cloudauditlogssource_validation_test.go +++ b/pkg/apis/events/v1alpha1/cloudauditlogssource_validation_test.go @@ -54,8 +54,8 @@ var ( Project: "my-eventing-project", }, } - validServiceAccountName = "test123@test123.iam.gserviceaccount.com" - invalidServiceAccountName = "test@test.iam.kserviceaccount.com" + validServiceAccountName = "test" + invalidServiceAccountName = "@test" ) func TestCloudAuditLogsSourceValidationFields(t *testing.T) { @@ -116,18 +116,18 @@ func TestCloudAuditLogsSourceValidationFields(t *testing.T) { }(), error: true, }, - "invalid GCP service account": { + "invalid k8s service account": { spec: func() CloudAuditLogsSourceSpec { obj := auditLogsSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = invalidServiceAccountName return *obj }(), error: true, }, - "have GCP service account and secret at the same time": { + "have k8s service account and secret at the same time": { spec: func() CloudAuditLogsSourceSpec { obj := auditLogsSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = validServiceAccountName obj.Secret = duckv1alpha1.DefaultGoogleCloudSecretSelector() return *obj }(), @@ -221,7 +221,7 @@ func TestCloudAuditLogsSourceCheckImmutableFields(t *testing.T) { updated: CloudAuditLogsSourceSpec{ PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: "new-service-account", + ServiceAccountName: "new-service-account", }, Secret: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ diff --git a/pkg/apis/events/v1alpha1/cloudbuildsource_types_test.go b/pkg/apis/events/v1alpha1/cloudbuildsource_types_test.go index c03145ae0e..72412f0b3d 100644 --- a/pkg/apis/events/v1alpha1/cloudbuildsource_types_test.go +++ b/pkg/apis/events/v1alpha1/cloudbuildsource_types_test.go @@ -54,13 +54,13 @@ func TestCloudBuildSourceIdentitySpec(t *testing.T) { Spec: CloudBuildSourceSpec{ PubSubSpec: v1alpha1.PubSubSpec{ IdentitySpec: v1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/events/v1alpha1/cloudbuildsource_validation.go b/pkg/apis/events/v1alpha1/cloudbuildsource_validation.go index 3d0b390910..f579b73d24 100644 --- a/pkg/apis/events/v1alpha1/cloudbuildsource_validation.go +++ b/pkg/apis/events/v1alpha1/cloudbuildsource_validation.go @@ -46,7 +46,7 @@ func (current *CloudBuildSourceSpec) Validate(ctx context.Context) *apis.FieldEr errs = errs.Also(err.ViaField("sink")) } - if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1alpha1/cloudbuildsource_validation_test.go b/pkg/apis/events/v1alpha1/cloudbuildsource_validation_test.go index 734502b122..eeb92118d2 100644 --- a/pkg/apis/events/v1alpha1/cloudbuildsource_validation_test.go +++ b/pkg/apis/events/v1alpha1/cloudbuildsource_validation_test.go @@ -173,18 +173,18 @@ func TestCloudBuildSourceCheckValidationFields(t *testing.T) { }(), error: false, }, - "invalid GCP service account": { + "invalid k8s service account": { spec: func() CloudBuildSourceSpec { obj := buildSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = invalidServiceAccountName return *obj }(), error: true, }, - "have GCP service account and secret at the same time": { + "have k8s service account and secret at the same time": { spec: func() CloudBuildSourceSpec { obj := buildSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = validServiceAccountName obj.Secret = duckv1alpha1.DefaultGoogleCloudSecretSelector() return *obj }(), diff --git a/pkg/apis/events/v1alpha1/cloudpubsubsource_types_test.go b/pkg/apis/events/v1alpha1/cloudpubsubsource_types_test.go index 166614a11a..7988779cbb 100644 --- a/pkg/apis/events/v1alpha1/cloudpubsubsource_types_test.go +++ b/pkg/apis/events/v1alpha1/cloudpubsubsource_types_test.go @@ -100,12 +100,12 @@ func TestCloudPubSubSourceIdentitySpec(t *testing.T) { Spec: CloudPubSubSourceSpec{ PubSubSpec: v1alpha1.PubSubSpec{ IdentitySpec: v1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + GoogleServiceAccount: "test", }, }, }, } - want := "test@test" + want := "test" got := s.IdentitySpec().GoogleServiceAccount if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) diff --git a/pkg/apis/events/v1alpha1/cloudpubsubsource_validation.go b/pkg/apis/events/v1alpha1/cloudpubsubsource_validation.go index c1349dc8ff..ce8beee20f 100644 --- a/pkg/apis/events/v1alpha1/cloudpubsubsource_validation.go +++ b/pkg/apis/events/v1alpha1/cloudpubsubsource_validation.go @@ -77,7 +77,7 @@ func (current *CloudPubSubSourceSpec) Validate(ctx context.Context) *apis.FieldE } } - if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1alpha1/cloudpubsubsource_validation_test.go b/pkg/apis/events/v1alpha1/cloudpubsubsource_validation_test.go index c381071f52..8d128e1b7c 100644 --- a/pkg/apis/events/v1alpha1/cloudpubsubsource_validation_test.go +++ b/pkg/apis/events/v1alpha1/cloudpubsubsource_validation_test.go @@ -196,18 +196,18 @@ func TestCloudPubSubSourceCheckValidationFields(t *testing.T) { }(), error: false, }, - "invalid GCP service account": { + "invalid k8s service account": { spec: func() CloudPubSubSourceSpec { obj := pubSubSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = invalidServiceAccountName return *obj }(), error: true, }, - "have GCP service account and secret at the same time": { + "have k8s service account and secret at the same time": { spec: func() CloudPubSubSourceSpec { obj := pubSubSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = validServiceAccountName obj.Secret = duckv1alpha1.DefaultGoogleCloudSecretSelector() return *obj }(), diff --git a/pkg/apis/events/v1alpha1/cloudschedulersource_types_test.go b/pkg/apis/events/v1alpha1/cloudschedulersource_types_test.go index c09d76995b..fe0df1b2ed 100644 --- a/pkg/apis/events/v1alpha1/cloudschedulersource_types_test.go +++ b/pkg/apis/events/v1alpha1/cloudschedulersource_types_test.go @@ -83,12 +83,12 @@ func TestCloudSchedulerSourceIdentitySpec(t *testing.T) { Spec: CloudSchedulerSourceSpec{ PubSubSpec: v1alpha1.PubSubSpec{ IdentitySpec: v1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + GoogleServiceAccount: "test", }, }, }, } - want := "test@test" + want := "test" got := s.IdentitySpec().GoogleServiceAccount if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) diff --git a/pkg/apis/events/v1alpha1/cloudschedulersource_validation.go b/pkg/apis/events/v1alpha1/cloudschedulersource_validation.go index f3d83e718a..15d1a4e05f 100644 --- a/pkg/apis/events/v1alpha1/cloudschedulersource_validation.go +++ b/pkg/apis/events/v1alpha1/cloudschedulersource_validation.go @@ -59,7 +59,7 @@ func (current *CloudSchedulerSourceSpec) Validate(ctx context.Context) *apis.Fie errs = errs.Also(apis.ErrMissingField("data")) } - if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1alpha1/cloudschedulersource_validation_test.go b/pkg/apis/events/v1alpha1/cloudschedulersource_validation_test.go index 2e74578eff..1d4bf02288 100644 --- a/pkg/apis/events/v1alpha1/cloudschedulersource_validation_test.go +++ b/pkg/apis/events/v1alpha1/cloudschedulersource_validation_test.go @@ -277,14 +277,14 @@ func TestCloudSchedulerSourceSpecValidationFields(t *testing.T) { return fe }(), }, { - name: "invalid GCP service account", + name: "invalid k8s service account", spec: &CloudSchedulerSourceSpec{ Location: "my-test-location", Schedule: "* * * * *", Data: "data", PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: invalidServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -300,20 +300,20 @@ func TestCloudSchedulerSourceSpecValidationFields(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: `invalid value: test@test.iam.kserviceaccount.com, googleServiceAccount should have format: ^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`, - Paths: []string{"googleServiceAccount"}, + Message: `invalid value: @test, serviceAccountName should have format: ^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`, + Paths: []string{"serviceAccountName"}, } return fe }(), }, { - name: "have GCP service account and secret at the same time", + name: "have k8s service account and secret at the same time", spec: &CloudSchedulerSourceSpec{ Location: "my-test-location", Schedule: "* * * * *", Data: "data", PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: validServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -333,7 +333,7 @@ func TestCloudSchedulerSourceSpecValidationFields(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: "Can't have spec.googleServiceAccount and spec.secret at the same time", + Message: "Can't have spec.serviceAccountName and spec.secret at the same time", Paths: []string{""}, } return fe diff --git a/pkg/apis/events/v1alpha1/cloudstoragesource_conversion_test.go b/pkg/apis/events/v1alpha1/cloudstoragesource_conversion_test.go index 381feb8caf..b614cbe89a 100644 --- a/pkg/apis/events/v1alpha1/cloudstoragesource_conversion_test.go +++ b/pkg/apis/events/v1alpha1/cloudstoragesource_conversion_test.go @@ -37,12 +37,11 @@ var ( completeCloudStorageSource = &CloudStorageSource{ ObjectMeta: completeObjectMeta, Spec: CloudStorageSourceSpec{ - PubSubSpec: completePubSubSpec, - ServiceAccountName: "serviceAccountName", - Bucket: "bucket", - EventTypes: []string{"event", "types"}, - ObjectNamePrefix: "objectNamePrefix", - PayloadFormat: "payloadFormat", + PubSubSpec: completePubSubSpec, + Bucket: "bucket", + EventTypes: []string{"event", "types"}, + ObjectNamePrefix: "objectNamePrefix", + PayloadFormat: "payloadFormat", }, Status: CloudStorageSourceStatus{ PubSubStatus: completePubSubStatus, diff --git a/pkg/apis/events/v1alpha1/cloudstoragesource_types.go b/pkg/apis/events/v1alpha1/cloudstoragesource_types.go index b37e6e8697..df63175b57 100644 --- a/pkg/apis/events/v1alpha1/cloudstoragesource_types.go +++ b/pkg/apis/events/v1alpha1/cloudstoragesource_types.go @@ -62,13 +62,6 @@ type CloudStorageSourceSpec struct { // Sink, CloudEventOverrides, Secret, PubSubSecret, and Project duckv1alpha1.PubSubSpec `json:",inline"` - // ServiceAccountName holds the name of the Kubernetes service account - // as which the underlying K8s resources should be run. If unspecified - // this will default to the "default" service account for the namespace - // in which the GCS exists. - // +optional - ServiceAccountName string `json:"serviceAccountName,omitempty"` - // Bucket to subscribe to. Bucket string `json:"bucket"` diff --git a/pkg/apis/events/v1alpha1/cloudstoragesource_types_test.go b/pkg/apis/events/v1alpha1/cloudstoragesource_types_test.go index 5b1896b10c..cb3bf8850a 100644 --- a/pkg/apis/events/v1alpha1/cloudstoragesource_types_test.go +++ b/pkg/apis/events/v1alpha1/cloudstoragesource_types_test.go @@ -81,12 +81,12 @@ func TestCloudStorageSourceIdentitySpec(t *testing.T) { Spec: CloudStorageSourceSpec{ PubSubSpec: v1alpha1.PubSubSpec{ IdentitySpec: v1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + GoogleServiceAccount: "test", }, }, }, } - want := "test@test" + want := "test" got := s.IdentitySpec().GoogleServiceAccount if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) diff --git a/pkg/apis/events/v1alpha1/cloudstoragesource_validation.go b/pkg/apis/events/v1alpha1/cloudstoragesource_validation.go index 1f1d1e7cee..ee1dd8578d 100644 --- a/pkg/apis/events/v1alpha1/cloudstoragesource_validation.go +++ b/pkg/apis/events/v1alpha1/cloudstoragesource_validation.go @@ -49,7 +49,7 @@ func (current *CloudStorageSourceSpec) Validate(ctx context.Context) *apis.Field errs = errs.Also(apis.ErrMissingField("bucket")) } - if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1alpha1.ValidateCredential(current.Secret, current.GoogleServiceAccount, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1alpha1/cloudstoragesource_validation_test.go b/pkg/apis/events/v1alpha1/cloudstoragesource_validation_test.go index 6e54c9d524..99bf789a1e 100644 --- a/pkg/apis/events/v1alpha1/cloudstoragesource_validation_test.go +++ b/pkg/apis/events/v1alpha1/cloudstoragesource_validation_test.go @@ -256,12 +256,12 @@ func TestSpecValidationFields(t *testing.T) { return fe }(), }, { - name: "invalid GCP service account", + name: "invalid k8s service account", spec: &CloudStorageSourceSpec{ Bucket: "my-test-bucket", PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: invalidServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -277,18 +277,18 @@ func TestSpecValidationFields(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: `invalid value: test@test.iam.kserviceaccount.com, googleServiceAccount should have format: ^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`, - Paths: []string{"googleServiceAccount"}, + Message: `invalid value: @test, serviceAccountName should have format: ^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`, + Paths: []string{"serviceAccountName"}, } return fe }(), }, { - name: "valid GCP service account", + name: "valid k8s service account", spec: &CloudStorageSourceSpec{ Bucket: "my-test-bucket", PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: validServiceAccountName, + ServiceAccountName: validServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -304,12 +304,12 @@ func TestSpecValidationFields(t *testing.T) { }, want: nil, }, { - name: "have GCP service account and secret at the same time", + name: "have k8s service account and secret at the same time", spec: &CloudStorageSourceSpec{ Bucket: "my-test-bucket", PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: validServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -329,7 +329,7 @@ func TestSpecValidationFields(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: "Can't have spec.googleServiceAccount and spec.secret at the same time", + Message: "Can't have spec.serviceAccountName and spec.secret at the same time", Paths: []string{""}, } return fe diff --git a/pkg/apis/events/v1beta1/cloudauditlogssource_types_test.go b/pkg/apis/events/v1beta1/cloudauditlogssource_types_test.go index 8c2b75e42c..7ee88f194a 100644 --- a/pkg/apis/events/v1beta1/cloudauditlogssource_types_test.go +++ b/pkg/apis/events/v1beta1/cloudauditlogssource_types_test.go @@ -93,13 +93,13 @@ func TestCloudAuditLogsSourceIdentitySpec(t *testing.T) { Spec: CloudAuditLogsSourceSpec{ PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/events/v1beta1/cloudauditlogssource_validation.go b/pkg/apis/events/v1beta1/cloudauditlogssource_validation.go index 8edd6954fe..e0fe3e7e4c 100644 --- a/pkg/apis/events/v1beta1/cloudauditlogssource_validation.go +++ b/pkg/apis/events/v1beta1/cloudauditlogssource_validation.go @@ -50,7 +50,7 @@ func (current *CloudAuditLogsSourceSpec) Validate(ctx context.Context) *apis.Fie errs = errs.Also(apis.ErrMissingField("methodName")) } - if err := duckv1beta1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1beta1.ValidateCredential(current.Secret, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1beta1/cloudauditlogssource_validation_test.go b/pkg/apis/events/v1beta1/cloudauditlogssource_validation_test.go index 8fc21846c9..039d196868 100644 --- a/pkg/apis/events/v1beta1/cloudauditlogssource_validation_test.go +++ b/pkg/apis/events/v1beta1/cloudauditlogssource_validation_test.go @@ -50,8 +50,8 @@ var ( Project: "my-eventing-project", }, } - validServiceAccountName = "test123@test123.iam.gserviceaccount.com" - invalidServiceAccountName = "test@test.iam.kserviceaccount.com" + validServiceAccountName = "test" + invalidServiceAccountName = "@test" ) func TestCloudAuditLogsSourceValidationFields(t *testing.T) { @@ -112,18 +112,18 @@ func TestCloudAuditLogsSourceValidationFields(t *testing.T) { }(), error: true, }, - "invalid GCP service account": { + "invalid k8s service account": { spec: func() CloudAuditLogsSourceSpec { obj := auditLogsSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = invalidServiceAccountName return *obj }(), error: true, }, - "have GCP service account and secret at the same time": { + "have k8s service account and secret at the same time": { spec: func() CloudAuditLogsSourceSpec { obj := auditLogsSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = validServiceAccountName obj.Secret = duckv1beta1.DefaultGoogleCloudSecretSelector() return *obj }(), @@ -206,7 +206,7 @@ func TestCloudAuditLogsSourceCheckImmutableFields(t *testing.T) { updated: CloudAuditLogsSourceSpec{ PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: "new-service-account", + ServiceAccountName: "new-service-account", }, Secret: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ diff --git a/pkg/apis/events/v1beta1/cloudpubsubsource_types_test.go b/pkg/apis/events/v1beta1/cloudpubsubsource_types_test.go index 2ff5797827..3be55e3ab6 100644 --- a/pkg/apis/events/v1beta1/cloudpubsubsource_types_test.go +++ b/pkg/apis/events/v1beta1/cloudpubsubsource_types_test.go @@ -100,13 +100,13 @@ func TestCloudPubSubSourceIdentitySpec(t *testing.T) { Spec: CloudPubSubSourceSpec{ PubSubSpec: v1beta1.PubSubSpec{ IdentitySpec: v1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/events/v1beta1/cloudpubsubsource_validation.go b/pkg/apis/events/v1beta1/cloudpubsubsource_validation.go index 2d35668dbe..292a700ee7 100644 --- a/pkg/apis/events/v1beta1/cloudpubsubsource_validation.go +++ b/pkg/apis/events/v1beta1/cloudpubsubsource_validation.go @@ -76,7 +76,7 @@ func (current *CloudPubSubSourceSpec) Validate(ctx context.Context) *apis.FieldE } } - if err := duckv1beta1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1beta1.ValidateCredential(current.Secret, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1beta1/cloudpubsubsource_validation_test.go b/pkg/apis/events/v1beta1/cloudpubsubsource_validation_test.go index ea9213393e..a784203a43 100644 --- a/pkg/apis/events/v1beta1/cloudpubsubsource_validation_test.go +++ b/pkg/apis/events/v1beta1/cloudpubsubsource_validation_test.go @@ -192,18 +192,18 @@ func TestCloudPubSubSourceCheckValidationFields(t *testing.T) { }(), error: false, }, - "invalid GCP service account": { + "invalid k8s service account": { spec: func() CloudPubSubSourceSpec { obj := pubSubSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = invalidServiceAccountName return *obj }(), error: true, }, - "have GCP service account and secret at the same time": { + "have k8s service account and secret at the same time": { spec: func() CloudPubSubSourceSpec { obj := pubSubSourceSpec.DeepCopy() - obj.GoogleServiceAccount = invalidServiceAccountName + obj.ServiceAccountName = validServiceAccountName obj.Secret = duckv1beta1.DefaultGoogleCloudSecretSelector() return *obj }(), @@ -292,7 +292,7 @@ func TestCloudPubSubSourceCheckImmutableFields(t *testing.T) { updated: CloudPubSubSourceSpec{ PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: "new-service-account", + ServiceAccountName: "new-service-account", }, Secret: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ diff --git a/pkg/apis/events/v1beta1/cloudschedulersource_types_test.go b/pkg/apis/events/v1beta1/cloudschedulersource_types_test.go index ca33ea52d4..e224ad63e0 100644 --- a/pkg/apis/events/v1beta1/cloudschedulersource_types_test.go +++ b/pkg/apis/events/v1beta1/cloudschedulersource_types_test.go @@ -83,13 +83,13 @@ func TestCloudSchedulerSourceIdentitySpec(t *testing.T) { Spec: CloudSchedulerSourceSpec{ PubSubSpec: v1beta1.PubSubSpec{ IdentitySpec: v1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/events/v1beta1/cloudschedulersource_validation.go b/pkg/apis/events/v1beta1/cloudschedulersource_validation.go index b7d42e5093..1597101869 100644 --- a/pkg/apis/events/v1beta1/cloudschedulersource_validation.go +++ b/pkg/apis/events/v1beta1/cloudschedulersource_validation.go @@ -57,7 +57,7 @@ func (current *CloudSchedulerSourceSpec) Validate(ctx context.Context) *apis.Fie errs = errs.Also(apis.ErrMissingField("data")) } - if err := duckv1beta1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1beta1.ValidateCredential(current.Secret, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1beta1/cloudschedulersource_validation_test.go b/pkg/apis/events/v1beta1/cloudschedulersource_validation_test.go index 11a02e814e..ede9e10409 100644 --- a/pkg/apis/events/v1beta1/cloudschedulersource_validation_test.go +++ b/pkg/apis/events/v1beta1/cloudschedulersource_validation_test.go @@ -274,14 +274,14 @@ func TestCloudSchedulerSourceSpecValidationFields(t *testing.T) { return fe }(), }, { - name: "invalid GCP service account", + name: "invalid k8s service account", spec: &CloudSchedulerSourceSpec{ Location: "my-test-location", Schedule: "* * * * *", Data: "data", PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: invalidServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -297,20 +297,20 @@ func TestCloudSchedulerSourceSpecValidationFields(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: `invalid value: test@test.iam.kserviceaccount.com, googleServiceAccount should have format: ^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`, - Paths: []string{"googleServiceAccount"}, + Message: `invalid value: @test, serviceAccountName should have format: ^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`, + Paths: []string{"serviceAccountName"}, } return fe }(), }, { - name: "have GCP service account and secret at the same time", + name: "have k8s service account and secret at the same time", spec: &CloudSchedulerSourceSpec{ Location: "my-test-location", Schedule: "* * * * *", Data: "data", PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: validServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -330,7 +330,7 @@ func TestCloudSchedulerSourceSpecValidationFields(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: "Can't have spec.googleServiceAccount and spec.secret at the same time", + Message: "Can't have spec.serviceAccountName and spec.secret at the same time", Paths: []string{""}, } return fe @@ -428,7 +428,7 @@ func TestCloudSchedulerSourceSpecCheckImmutableFields(t *testing.T) { Data: schedulerWithSecret.Data, PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: "new-service-account", + ServiceAccountName: "new-service-account", }, SourceSpec: schedulerWithSecret.SourceSpec, Secret: schedulerWithSecret.Secret, diff --git a/pkg/apis/events/v1beta1/cloudstoragesource_types.go b/pkg/apis/events/v1beta1/cloudstoragesource_types.go index ffc61ee991..f68f864a0e 100644 --- a/pkg/apis/events/v1beta1/cloudstoragesource_types.go +++ b/pkg/apis/events/v1beta1/cloudstoragesource_types.go @@ -60,13 +60,6 @@ type CloudStorageSourceSpec struct { // Sink, CloudEventOverrides, Secret, PubSubSecret, and Project duckv1beta1.PubSubSpec `json:",inline"` - // ServiceAccountName holds the name of the Kubernetes service account - // as which the underlying K8s resources should be run. If unspecified - // this will default to the "default" service account for the namespace - // in which the GCS exists. - // +optional - ServiceAccountName string `json:"serviceAccountName,omitempty"` - // Bucket to subscribe to. Bucket string `json:"bucket"` diff --git a/pkg/apis/events/v1beta1/cloudstoragesource_types_test.go b/pkg/apis/events/v1beta1/cloudstoragesource_types_test.go index f41ad5bc6a..010c514f99 100644 --- a/pkg/apis/events/v1beta1/cloudstoragesource_types_test.go +++ b/pkg/apis/events/v1beta1/cloudstoragesource_types_test.go @@ -81,13 +81,13 @@ func TestCloudStorageSourceIdentitySpec(t *testing.T) { Spec: CloudStorageSourceSpec{ PubSubSpec: v1beta1.PubSubSpec{ IdentitySpec: v1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/events/v1beta1/cloudstoragesource_validation.go b/pkg/apis/events/v1beta1/cloudstoragesource_validation.go index 044d524d73..93ca9c4790 100644 --- a/pkg/apis/events/v1beta1/cloudstoragesource_validation.go +++ b/pkg/apis/events/v1beta1/cloudstoragesource_validation.go @@ -48,7 +48,7 @@ func (current *CloudStorageSourceSpec) Validate(ctx context.Context) *apis.Field errs = errs.Also(apis.ErrMissingField("bucket")) } - if err := duckv1beta1.ValidateCredential(current.Secret, current.GoogleServiceAccount); err != nil { + if err := duckv1beta1.ValidateCredential(current.Secret, current.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/events/v1beta1/cloudstoragesource_validation_test.go b/pkg/apis/events/v1beta1/cloudstoragesource_validation_test.go index b9cbef7f06..18e186df80 100644 --- a/pkg/apis/events/v1beta1/cloudstoragesource_validation_test.go +++ b/pkg/apis/events/v1beta1/cloudstoragesource_validation_test.go @@ -252,12 +252,12 @@ func TestSpecValidationFields(t *testing.T) { return fe }(), }, { - name: "invalid GCP service account", + name: "invalid k8s service account", spec: &CloudStorageSourceSpec{ Bucket: "my-test-bucket", PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: invalidServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -273,18 +273,18 @@ func TestSpecValidationFields(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: `invalid value: test@test.iam.kserviceaccount.com, googleServiceAccount should have format: ^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`, - Paths: []string{"googleServiceAccount"}, + Message: `invalid value: @test, serviceAccountName should have format: ^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`, + Paths: []string{"serviceAccountName"}, } return fe }(), }, { - name: "valid GCP service account", + name: "valid k8s service account", spec: &CloudStorageSourceSpec{ Bucket: "my-test-bucket", PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: validServiceAccountName, + ServiceAccountName: validServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -300,12 +300,12 @@ func TestSpecValidationFields(t *testing.T) { }, want: nil, }, { - name: "have GCP service account and secret at the same time", + name: "have k8s service account and secret at the same time", spec: &CloudStorageSourceSpec{ Bucket: "my-test-bucket", PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: validServiceAccountName, }, SourceSpec: duckv1.SourceSpec{ Sink: duckv1.Destination{ @@ -325,7 +325,7 @@ func TestSpecValidationFields(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: "Can't have spec.googleServiceAccount and spec.secret at the same time", + Message: "Can't have spec.serviceAccountName and spec.secret at the same time", Paths: []string{""}, } return fe @@ -439,7 +439,7 @@ func TestCheckImmutableFields(t *testing.T) { PayloadFormat: storageSourceSpec.PayloadFormat, PubSubSpec: duckv1beta1.PubSubSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: "new-service-account", + ServiceAccountName: "new-service-account", }, SourceSpec: storageSourceSpec.SourceSpec, Secret: storageSourceSpec.Secret, diff --git a/pkg/apis/intevents/v1alpha1/pullsubscription_conversion_test.go b/pkg/apis/intevents/v1alpha1/pullsubscription_conversion_test.go index 3456a77da7..3aa2165705 100644 --- a/pkg/apis/intevents/v1alpha1/pullsubscription_conversion_test.go +++ b/pkg/apis/intevents/v1alpha1/pullsubscription_conversion_test.go @@ -100,7 +100,7 @@ var ( } completeIdentitySpec = duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: "googleServiceAccount", + ServiceAccountName: "k8sServiceAccount", } completeSecret = &v1.SecretKeySelector{ diff --git a/pkg/apis/intevents/v1alpha1/pullsubscription_types_test.go b/pkg/apis/intevents/v1alpha1/pullsubscription_types_test.go index a0d8a95ac0..b71452df62 100644 --- a/pkg/apis/intevents/v1alpha1/pullsubscription_types_test.go +++ b/pkg/apis/intevents/v1alpha1/pullsubscription_types_test.go @@ -100,13 +100,13 @@ func TestPullSubscriptionIdentitySpec(t *testing.T) { Spec: PullSubscriptionSpec{ PubSubSpec: v1alpha1.PubSubSpec{ IdentitySpec: v1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/intevents/v1alpha1/topic_types_test.go b/pkg/apis/intevents/v1alpha1/topic_types_test.go index ba914ea33f..0fff5deff7 100644 --- a/pkg/apis/intevents/v1alpha1/topic_types_test.go +++ b/pkg/apis/intevents/v1alpha1/topic_types_test.go @@ -46,12 +46,12 @@ func TestTopicIdentitySpec(t *testing.T) { s := &Topic{ Spec: TopicSpec{ IdentitySpec: v1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/intevents/v1beta1/pullsubscription_types_test.go b/pkg/apis/intevents/v1beta1/pullsubscription_types_test.go index 498d6b2575..ad292b58fd 100644 --- a/pkg/apis/intevents/v1beta1/pullsubscription_types_test.go +++ b/pkg/apis/intevents/v1beta1/pullsubscription_types_test.go @@ -100,13 +100,13 @@ func TestPullSubscriptionIdentitySpec(t *testing.T) { Spec: PullSubscriptionSpec{ PubSubSpec: v1beta1.PubSubSpec{ IdentitySpec: v1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/intevents/v1beta1/topic_types_test.go b/pkg/apis/intevents/v1beta1/topic_types_test.go index b38a177204..d4b58fa0c4 100644 --- a/pkg/apis/intevents/v1beta1/topic_types_test.go +++ b/pkg/apis/intevents/v1beta1/topic_types_test.go @@ -46,12 +46,12 @@ func TestTopicIdentitySpec(t *testing.T) { s := &Topic{ Spec: TopicSpec{ IdentitySpec: v1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/messaging/v1alpha1/channel_conversion_test.go b/pkg/apis/messaging/v1alpha1/channel_conversion_test.go index ece5f32b6c..8b3a1bfc87 100644 --- a/pkg/apis/messaging/v1alpha1/channel_conversion_test.go +++ b/pkg/apis/messaging/v1alpha1/channel_conversion_test.go @@ -98,7 +98,7 @@ var ( } completeIdentitySpec = duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: "googleServiceAccount", + ServiceAccountName: "k8sServiceAccount", } completeSecret = &v1.SecretKeySelector{ diff --git a/pkg/apis/messaging/v1alpha1/channel_defaults.go b/pkg/apis/messaging/v1alpha1/channel_defaults.go index bec669d96d..25d7289d70 100644 --- a/pkg/apis/messaging/v1alpha1/channel_defaults.go +++ b/pkg/apis/messaging/v1alpha1/channel_defaults.go @@ -66,7 +66,8 @@ func (c *Channel) SetDefaults(ctx context.Context) { } func (cs *ChannelSpec) SetDefaults(ctx context.Context) { - if cs.GoogleServiceAccount == "" && (cs.Secret == nil || equality.Semantic.DeepEqual(cs.Secret, &corev1.SecretKeySelector{})) { + if cs.GoogleServiceAccount == "" && cs.ServiceAccountName == "" && + (cs.Secret == nil || equality.Semantic.DeepEqual(cs.Secret, &corev1.SecretKeySelector{})) { cs.Secret = defaultSecretSelector() } } diff --git a/pkg/apis/messaging/v1alpha1/channel_types_test.go b/pkg/apis/messaging/v1alpha1/channel_types_test.go index a92881ee67..94ecf39418 100644 --- a/pkg/apis/messaging/v1alpha1/channel_types_test.go +++ b/pkg/apis/messaging/v1alpha1/channel_types_test.go @@ -47,11 +47,11 @@ func TestChannelIdentitySpec(t *testing.T) { s := &Channel{ Spec: ChannelSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + GoogleServiceAccount: "test", }, }, } - want := "test@test" + want := "test" got := s.IdentitySpec().GoogleServiceAccount if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) diff --git a/pkg/apis/messaging/v1alpha1/channel_validation.go b/pkg/apis/messaging/v1alpha1/channel_validation.go index 9323e7c9c6..89a02ee9ce 100644 --- a/pkg/apis/messaging/v1alpha1/channel_validation.go +++ b/pkg/apis/messaging/v1alpha1/channel_validation.go @@ -44,7 +44,7 @@ func (cs *ChannelSpec) Validate(ctx context.Context) *apis.FieldError { } } - if err := duckv1alpha1.ValidateCredential(cs.Secret, cs.GoogleServiceAccount); err != nil { + if err := duckv1alpha1.ValidateCredential(cs.Secret, cs.GoogleServiceAccount, cs.ServiceAccountName); err != nil { errs = errs.Also(err) } diff --git a/pkg/apis/messaging/v1alpha1/channel_validation_test.go b/pkg/apis/messaging/v1alpha1/channel_validation_test.go index 170f20269d..7e6a7fad5c 100644 --- a/pkg/apis/messaging/v1alpha1/channel_validation_test.go +++ b/pkg/apis/messaging/v1alpha1/channel_validation_test.go @@ -32,8 +32,8 @@ import ( ) var ( - validServiceAccountName = "test123@test123.iam.gserviceaccount.com" - invalidServiceAccountName = "test@test.iam.kserviceaccount.com" + validServiceAccountName = "test" + invalidServiceAccountName = "@test" channelSpec = ChannelSpec{ Subscribable: &eventingduck.Subscribable{ @@ -141,7 +141,7 @@ func TestChannelValidation(t *testing.T) { }, want: nil, }, { - name: "invalid GCP service account", + name: "invalid k8s service account", cr: &Channel{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ @@ -150,7 +150,7 @@ func TestChannelValidation(t *testing.T) { }, Spec: ChannelSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: invalidServiceAccountName, }, Subscribable: &eventingduck.Subscribable{ Subscribers: []eventingduck.SubscriberSpec{{ @@ -161,13 +161,13 @@ func TestChannelValidation(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: `invalid value: test@test.iam.kserviceaccount.com, googleServiceAccount should have format: ^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`, - Paths: []string{"spec.googleServiceAccount"}, + Message: `invalid value: @test, serviceAccountName should have format: ^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`, + Paths: []string{"spec.serviceAccountName"}, } return fe }(), }, { - name: "valid GCP service account", + name: "valid k8s service account", cr: &Channel{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ @@ -176,7 +176,7 @@ func TestChannelValidation(t *testing.T) { }, Spec: ChannelSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: validServiceAccountName, + ServiceAccountName: validServiceAccountName, }, Subscribable: &eventingduck.Subscribable{ Subscribers: []eventingduck.SubscriberSpec{{ @@ -187,7 +187,7 @@ func TestChannelValidation(t *testing.T) { }, want: nil, }, { - name: "have GCP service account and secret at the same time", + name: "have k8s service account and secret at the same time", cr: &Channel{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ @@ -196,7 +196,7 @@ func TestChannelValidation(t *testing.T) { }, Spec: ChannelSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: validServiceAccountName, + ServiceAccountName: validServiceAccountName, }, Secret: defaultSecretSelector(), Subscribable: &eventingduck.Subscribable{ @@ -208,7 +208,7 @@ func TestChannelValidation(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: "Can't have spec.googleServiceAccount and spec.secret at the same time", + Message: "Can't have spec.serviceAccountName and spec.secret at the same time", Paths: []string{"spec"}, } return fe diff --git a/pkg/apis/messaging/v1beta1/channel_defaults.go b/pkg/apis/messaging/v1beta1/channel_defaults.go index 361a978909..dcb936812d 100644 --- a/pkg/apis/messaging/v1beta1/channel_defaults.go +++ b/pkg/apis/messaging/v1beta1/channel_defaults.go @@ -62,7 +62,7 @@ func (c *Channel) SetDefaults(ctx context.Context) { } func (cs *ChannelSpec) SetDefaults(_ context.Context) { - if cs.GoogleServiceAccount == "" && (cs.Secret == nil || equality.Semantic.DeepEqual(cs.Secret, &corev1.SecretKeySelector{})) { + if cs.ServiceAccountName == "" && (cs.Secret == nil || equality.Semantic.DeepEqual(cs.Secret, &corev1.SecretKeySelector{})) { cs.Secret = defaultSecretSelector() } } diff --git a/pkg/apis/messaging/v1beta1/channel_types_test.go b/pkg/apis/messaging/v1beta1/channel_types_test.go index 24f97f6ede..4339593e13 100644 --- a/pkg/apis/messaging/v1beta1/channel_types_test.go +++ b/pkg/apis/messaging/v1beta1/channel_types_test.go @@ -47,12 +47,12 @@ func TestChannelIdentitySpec(t *testing.T) { s := &Channel{ Spec: ChannelSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/messaging/v1beta1/channel_validation.go b/pkg/apis/messaging/v1beta1/channel_validation.go index 39ac0bf203..b6b1ab0847 100644 --- a/pkg/apis/messaging/v1beta1/channel_validation.go +++ b/pkg/apis/messaging/v1beta1/channel_validation.go @@ -42,7 +42,7 @@ func (cs *ChannelSpec) Validate(ctx context.Context) *apis.FieldError { } } - if err := duckv1beta1.ValidateCredential(cs.Secret, cs.GoogleServiceAccount); err != nil { + if err := duckv1beta1.ValidateCredential(cs.Secret, cs.ServiceAccountName); err != nil { errs = errs.Also(err) } @@ -65,7 +65,7 @@ func (current *Channel) CheckImmutableFields(ctx context.Context, original *Chan } } - if diff := cmp.Diff(original.Spec.GoogleServiceAccount, current.Spec.GoogleServiceAccount); diff != "" { + if diff := cmp.Diff(original.Spec.ServiceAccountName, current.Spec.ServiceAccountName); diff != "" { return &apis.FieldError{ Message: "Immutable fields changed (-old +new)", Paths: []string{"status", "serviceAccount"}, diff --git a/pkg/apis/messaging/v1beta1/channel_validation_test.go b/pkg/apis/messaging/v1beta1/channel_validation_test.go index 489bb552fb..837d97bf73 100644 --- a/pkg/apis/messaging/v1beta1/channel_validation_test.go +++ b/pkg/apis/messaging/v1beta1/channel_validation_test.go @@ -29,8 +29,8 @@ import ( ) var ( - validServiceAccountName = "test123@test123.iam.gserviceaccount.com" - invalidServiceAccountName = "test@test.iam.kserviceaccount.com" + validServiceAccountName = "test" + invalidServiceAccountName = "@test" channelSpec = ChannelSpec{ SubscribableSpec: &eventingduck.SubscribableSpec{ @@ -113,11 +113,11 @@ func TestChannelValidation(t *testing.T) { }, want: nil, }, { - name: "invalid GCP service account", + name: "invalid k8s service account", cr: &Channel{ Spec: ChannelSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: invalidServiceAccountName, + ServiceAccountName: invalidServiceAccountName, }, SubscribableSpec: &eventingduck.SubscribableSpec{ Subscribers: []eventingduck.SubscriberSpec{{ @@ -128,17 +128,17 @@ func TestChannelValidation(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: `invalid value: test@test.iam.kserviceaccount.com, googleServiceAccount should have format: ^[a-z][a-z0-9-]{5,29}@[a-z][a-z0-9-]{5,29}.iam.gserviceaccount.com$`, - Paths: []string{"spec.googleServiceAccount"}, + Message: `invalid value: @test, serviceAccountName should have format: ^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`, + Paths: []string{"spec.serviceAccountName"}, } return fe }(), }, { - name: "valid GCP service account", + name: "valid k8s service account", cr: &Channel{ Spec: ChannelSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: validServiceAccountName, + ServiceAccountName: validServiceAccountName, }, SubscribableSpec: &eventingduck.SubscribableSpec{ Subscribers: []eventingduck.SubscriberSpec{{ @@ -149,11 +149,11 @@ func TestChannelValidation(t *testing.T) { }, want: nil, }, { - name: "have GCP service account and secret at the same time", + name: "have k8s service account and secret at the same time", cr: &Channel{ Spec: ChannelSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: validServiceAccountName, + ServiceAccountName: validServiceAccountName, }, Secret: defaultSecretSelector(), SubscribableSpec: &eventingduck.SubscribableSpec{ @@ -165,7 +165,7 @@ func TestChannelValidation(t *testing.T) { }, want: func() *apis.FieldError { fe := &apis.FieldError{ - Message: "Can't have spec.googleServiceAccount and spec.secret at the same time", + Message: "Can't have spec.serviceAccountName and spec.secret at the same time", Paths: []string{"spec"}, } return fe @@ -195,7 +195,7 @@ func TestCheckImmutableFields(t *testing.T) { orig: &channelSpec, updated: ChannelSpec{ IdentitySpec: duckv1beta1.IdentitySpec{ - GoogleServiceAccount: "new-service-account", + ServiceAccountName: "new-service-account", }, }, allowed: false, diff --git a/pkg/apis/pubsub/v1alpha1/pullsubscription_conversion_test.go b/pkg/apis/pubsub/v1alpha1/pullsubscription_conversion_test.go index d033ff7b30..bf77ae3fb8 100644 --- a/pkg/apis/pubsub/v1alpha1/pullsubscription_conversion_test.go +++ b/pkg/apis/pubsub/v1alpha1/pullsubscription_conversion_test.go @@ -100,7 +100,7 @@ var ( } completeIdentitySpec = duckv1alpha1.IdentitySpec{ - GoogleServiceAccount: "googleServiceAccount", + ServiceAccountName: "k8sServiceAccount", } completeSecret = &v1.SecretKeySelector{ diff --git a/pkg/apis/pubsub/v1alpha1/pullsubscription_types_test.go b/pkg/apis/pubsub/v1alpha1/pullsubscription_types_test.go index efcab5db19..1c2b7e7d0d 100644 --- a/pkg/apis/pubsub/v1alpha1/pullsubscription_types_test.go +++ b/pkg/apis/pubsub/v1alpha1/pullsubscription_types_test.go @@ -100,13 +100,13 @@ func TestPullSubscriptionIdentitySpec(t *testing.T) { Spec: PullSubscriptionSpec{ PubSubSpec: v1alpha1.PubSubSpec{ IdentitySpec: v1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/pubsub/v1alpha1/topic_types_test.go b/pkg/apis/pubsub/v1alpha1/topic_types_test.go index 9d2b65fef5..1ff00a6996 100644 --- a/pkg/apis/pubsub/v1alpha1/topic_types_test.go +++ b/pkg/apis/pubsub/v1alpha1/topic_types_test.go @@ -46,12 +46,12 @@ func TestTopicIdentitySpec(t *testing.T) { s := &Topic{ Spec: TopicSpec{ IdentitySpec: v1alpha1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/pubsub/v1beta1/pullsubscription_types_test.go b/pkg/apis/pubsub/v1beta1/pullsubscription_types_test.go index a33ed786ea..3d7e5bce88 100644 --- a/pkg/apis/pubsub/v1beta1/pullsubscription_types_test.go +++ b/pkg/apis/pubsub/v1beta1/pullsubscription_types_test.go @@ -100,13 +100,13 @@ func TestPullSubscriptionIdentitySpec(t *testing.T) { Spec: PullSubscriptionSpec{ PubSubSpec: v1beta1.PubSubSpec{ IdentitySpec: v1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/apis/pubsub/v1beta1/topic_types_test.go b/pkg/apis/pubsub/v1beta1/topic_types_test.go index 098ad000a4..64d3c871e8 100644 --- a/pkg/apis/pubsub/v1beta1/topic_types_test.go +++ b/pkg/apis/pubsub/v1beta1/topic_types_test.go @@ -46,12 +46,12 @@ func TestTopicIdentitySpec(t *testing.T) { s := &Topic{ Spec: TopicSpec{ IdentitySpec: v1beta1.IdentitySpec{ - GoogleServiceAccount: "test@test", + ServiceAccountName: "test", }, }, } - want := "test@test" - got := s.IdentitySpec().GoogleServiceAccount + want := "test" + got := s.IdentitySpec().ServiceAccountName if diff := cmp.Diff(want, got); diff != "" { t.Errorf("failed to get expected (-want, +got) = %v", diff) } diff --git a/pkg/reconciler/intevents/pullsubscription/resources/receive_adapter.go b/pkg/reconciler/intevents/pullsubscription/resources/receive_adapter.go index 62943839b2..a47852c991 100644 --- a/pkg/reconciler/intevents/pullsubscription/resources/receive_adapter.go +++ b/pkg/reconciler/intevents/pullsubscription/resources/receive_adapter.go @@ -162,6 +162,17 @@ func makeReceiveAdapterPodSpec(ctx context.Context, args *ReceiveAdapterArgs) *c } } + // If k8s service account is specified, use that service account as credential. + if args.Source.Spec.ServiceAccountName != "" { + kServiceAccountName := args.Source.Spec.ServiceAccountName + return &corev1.PodSpec{ + ServiceAccountName: kServiceAccountName, + Containers: []corev1.Container{ + receiveAdapterContainer, + }, + } + } + // Otherwise, use secret as credential. secret := args.Source.Spec.Secret credsFile := fmt.Sprintf("%s/%s", credsMountPath, secret.Key) diff --git a/pkg/reconciler/intevents/resources/pullsubscription.go b/pkg/reconciler/intevents/resources/pullsubscription.go index 0ea5a6bd0a..d74bcb703e 100644 --- a/pkg/reconciler/intevents/resources/pullsubscription.go +++ b/pkg/reconciler/intevents/resources/pullsubscription.go @@ -52,6 +52,7 @@ func MakePullSubscription(args *PullSubscriptionArgs) *inteventsv1alpha1.PullSub PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ GoogleServiceAccount: args.Spec.IdentitySpec.GoogleServiceAccount, + ServiceAccountName: args.Spec.IdentitySpec.ServiceAccountName, }, Secret: args.Spec.Secret, Project: args.Spec.Project, diff --git a/pkg/reconciler/intevents/resources/topic.go b/pkg/reconciler/intevents/resources/topic.go index 327dd120ab..bd49a0cf78 100644 --- a/pkg/reconciler/intevents/resources/topic.go +++ b/pkg/reconciler/intevents/resources/topic.go @@ -48,6 +48,7 @@ func MakeTopic(args *TopicArgs) *inteventsv1alpha1.Topic { Spec: inteventsv1alpha1.TopicSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ GoogleServiceAccount: args.Spec.IdentitySpec.GoogleServiceAccount, + ServiceAccountName: args.Spec.IdentitySpec.ServiceAccountName, }, Secret: args.Spec.Secret, Project: args.Spec.Project, diff --git a/pkg/reconciler/intevents/topic/resources/publisher.go b/pkg/reconciler/intevents/topic/resources/publisher.go index c71f3e74c9..0492c06fbc 100644 --- a/pkg/reconciler/intevents/topic/resources/publisher.go +++ b/pkg/reconciler/intevents/topic/resources/publisher.go @@ -81,6 +81,17 @@ func makePublisherPodSpec(args *PublisherArgs) *corev1.PodSpec { } } + // If k8s service account is specified, use that service account as credential. + if args.Topic.Spec.ServiceAccountName != "" { + kServiceAccountName := args.Topic.Spec.ServiceAccountName + return &corev1.PodSpec{ + ServiceAccountName: kServiceAccountName, + Containers: []corev1.Container{ + publisherContainer, + }, + } + } + // Otherwise, use secret as credential. secret := args.Topic.Spec.Secret if secret == nil { diff --git a/pkg/reconciler/messaging/channel/channel.go b/pkg/reconciler/messaging/channel/channel.go index 3f42e14b9b..bbf54d3586 100644 --- a/pkg/reconciler/messaging/channel/channel.go +++ b/pkg/reconciler/messaging/channel/channel.go @@ -159,15 +159,16 @@ func (r *Reconciler) syncSubscribers(ctx context.Context, channel *v1alpha1.Chan genName := resources.GenerateSubscriptionName(s.UID) ps := resources.MakePullSubscription(&resources.PullSubscriptionArgs{ - Owner: channel, - Name: genName, - Project: channel.Spec.Project, - Topic: channel.Status.TopicID, - ServiceAccount: channel.Spec.GoogleServiceAccount, - Secret: channel.Spec.Secret, - Labels: resources.GetPullSubscriptionLabels(controllerAgentName, channel.Name, genName, string(channel.UID)), - Annotations: resources.GetPullSubscriptionAnnotations(channel.Name, clusterName), - Subscriber: s, + Owner: channel, + Name: genName, + Project: channel.Spec.Project, + Topic: channel.Status.TopicID, + ServiceAccount: channel.Spec.GoogleServiceAccount, + ServiceAccountName: channel.Spec.ServiceAccountName, + Secret: channel.Spec.Secret, + Labels: resources.GetPullSubscriptionLabels(controllerAgentName, channel.Name, genName, string(channel.UID)), + Annotations: resources.GetPullSubscriptionAnnotations(channel.Name, clusterName), + Subscriber: s, }) ps, err := r.RunClientSet.InternalV1alpha1().PullSubscriptions(channel.Namespace).Create(ps) if apierrs.IsAlreadyExists(err) { @@ -194,15 +195,16 @@ func (r *Reconciler) syncSubscribers(ctx context.Context, channel *v1alpha1.Chan genName := resources.GenerateSubscriptionName(s.UID) ps := resources.MakePullSubscription(&resources.PullSubscriptionArgs{ - Owner: channel, - Name: genName, - Project: channel.Spec.Project, - Topic: channel.Status.TopicID, - ServiceAccount: channel.Spec.GoogleServiceAccount, - Secret: channel.Spec.Secret, - Labels: resources.GetPullSubscriptionLabels(controllerAgentName, channel.Name, genName, string(channel.UID)), - Annotations: resources.GetPullSubscriptionAnnotations(channel.Name, clusterName), - Subscriber: s, + Owner: channel, + Name: genName, + Project: channel.Spec.Project, + Topic: channel.Status.TopicID, + ServiceAccount: channel.Spec.GoogleServiceAccount, + ServiceAccountName: channel.Spec.ServiceAccountName, + Secret: channel.Spec.Secret, + Labels: resources.GetPullSubscriptionLabels(controllerAgentName, channel.Name, genName, string(channel.UID)), + Annotations: resources.GetPullSubscriptionAnnotations(channel.Name, clusterName), + Subscriber: s, }) existingPs, found := pullsubs[genName] @@ -309,14 +311,15 @@ func (r *Reconciler) reconcileTopic(ctx context.Context, channel *v1alpha1.Chann } clusterName := channel.GetAnnotations()[duckv1alpha1.ClusterNameAnnotation] t := resources.MakeTopic(&resources.TopicArgs{ - Owner: channel, - Name: resources.GeneratePublisherName(channel), - Project: channel.Spec.Project, - ServiceAccount: channel.Spec.GoogleServiceAccount, - Secret: channel.Spec.Secret, - Topic: resources.GenerateTopicID(channel.UID), - Labels: resources.GetLabels(controllerAgentName, channel.Name, string(channel.UID)), - Annotations: resources.GetTopicAnnotations(clusterName), + Owner: channel, + Name: resources.GeneratePublisherName(channel), + Project: channel.Spec.Project, + ServiceAccount: channel.Spec.GoogleServiceAccount, + ServiceAccountName: channel.Spec.ServiceAccountName, + Secret: channel.Spec.Secret, + Topic: resources.GenerateTopicID(channel.UID), + Labels: resources.GetLabels(controllerAgentName, channel.Name, string(channel.UID)), + Annotations: resources.GetTopicAnnotations(clusterName), }) topic, err = r.RunClientSet.InternalV1alpha1().Topics(channel.Namespace).Create(t) diff --git a/pkg/reconciler/messaging/channel/resources/pullsubscription.go b/pkg/reconciler/messaging/channel/resources/pullsubscription.go index e7adbee268..c96a111ad0 100644 --- a/pkg/reconciler/messaging/channel/resources/pullsubscription.go +++ b/pkg/reconciler/messaging/channel/resources/pullsubscription.go @@ -30,15 +30,16 @@ import ( // PullSubscriptionArgs are the arguments needed to create a Channel Subscriber. // Every field is required. type PullSubscriptionArgs struct { - Owner kmeta.OwnerRefable - Name string - Project string - Topic string - ServiceAccount string - Secret *corev1.SecretKeySelector - Labels map[string]string - Annotations map[string]string - Subscriber duckv1alpha1.SubscriberSpec + Owner kmeta.OwnerRefable + Name string + Project string + Topic string + ServiceAccount string + ServiceAccountName string + Secret *corev1.SecretKeySelector + Labels map[string]string + Annotations map[string]string + Subscriber duckv1alpha1.SubscriberSpec } // MakePullSubscription generates (but does not insert into K8s) the @@ -50,6 +51,7 @@ func MakePullSubscription(args *PullSubscriptionArgs) *v1alpha1.PullSubscription SourceSpec: duckv1.SourceSpec{}, IdentitySpec: gcpduckv1alpha1.IdentitySpec{ GoogleServiceAccount: args.ServiceAccount, + ServiceAccountName: args.ServiceAccountName, }, Secret: args.Secret, Project: args.Project, diff --git a/pkg/reconciler/messaging/channel/resources/topic.go b/pkg/reconciler/messaging/channel/resources/topic.go index d0d326970d..f90245f666 100644 --- a/pkg/reconciler/messaging/channel/resources/topic.go +++ b/pkg/reconciler/messaging/channel/resources/topic.go @@ -29,14 +29,15 @@ import ( // TopicArgs are the arguments needed to create a Channel Topic. // Every field is required. type TopicArgs struct { - Owner kmeta.OwnerRefable - Name string - Project string - Topic string - ServiceAccount string - Secret *corev1.SecretKeySelector - Labels map[string]string - Annotations map[string]string + Owner kmeta.OwnerRefable + Name string + Project string + Topic string + ServiceAccount string + ServiceAccountName string + Secret *corev1.SecretKeySelector + Labels map[string]string + Annotations map[string]string } // MakeInvoker generates (but does not insert into K8s) the Topic for Channels. @@ -52,6 +53,7 @@ func MakeTopic(args *TopicArgs) *v1alpha1.Topic { Spec: v1alpha1.TopicSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ GoogleServiceAccount: args.ServiceAccount, + ServiceAccountName: args.ServiceAccountName, }, Secret: args.Secret, Project: args.Project, diff --git a/pkg/reconciler/pubsub/pullsubscription/resources/receive_adapter.go b/pkg/reconciler/pubsub/pullsubscription/resources/receive_adapter.go index 6d561cbb14..8c423132fa 100644 --- a/pkg/reconciler/pubsub/pullsubscription/resources/receive_adapter.go +++ b/pkg/reconciler/pubsub/pullsubscription/resources/receive_adapter.go @@ -163,6 +163,17 @@ func makeReceiveAdapterPodSpec(ctx context.Context, args *ReceiveAdapterArgs) *c } } + // If k8s service account is specified, use that service account as credential. + if args.Source.Spec.ServiceAccountName != "" { + kServiceAccountName := args.Source.Spec.ServiceAccountName + return &corev1.PodSpec{ + ServiceAccountName: kServiceAccountName, + Containers: []corev1.Container{ + receiveAdapterContainer, + }, + } + } + // Otherwise, use secret as credential. secret := args.Source.Spec.Secret credsFile := fmt.Sprintf("%s/%s", credsMountPath, secret.Key) diff --git a/pkg/reconciler/pubsub/resources/pullsubscription.go b/pkg/reconciler/pubsub/resources/pullsubscription.go index 4cdb7d2c33..7f1e8917d4 100644 --- a/pkg/reconciler/pubsub/resources/pullsubscription.go +++ b/pkg/reconciler/pubsub/resources/pullsubscription.go @@ -52,6 +52,7 @@ func MakePullSubscription(args *PullSubscriptionArgs) *pubsubv1alpha1.PullSubscr PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ GoogleServiceAccount: args.Spec.IdentitySpec.GoogleServiceAccount, + ServiceAccountName: args.Spec.IdentitySpec.ServiceAccountName, }, Secret: args.Spec.Secret, Project: args.Spec.Project, diff --git a/pkg/reconciler/pubsub/resources/topic.go b/pkg/reconciler/pubsub/resources/topic.go index 3891e165b8..5ce804ad85 100644 --- a/pkg/reconciler/pubsub/resources/topic.go +++ b/pkg/reconciler/pubsub/resources/topic.go @@ -48,6 +48,7 @@ func MakeTopic(args *TopicArgs) *pubsubv1alpha1.Topic { Spec: pubsubv1alpha1.TopicSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ GoogleServiceAccount: args.Spec.IdentitySpec.GoogleServiceAccount, + ServiceAccountName: args.Spec.IdentitySpec.ServiceAccountName, }, Secret: args.Spec.Secret, Project: args.Spec.Project, diff --git a/pkg/reconciler/pubsub/topic/resources/publisher.go b/pkg/reconciler/pubsub/topic/resources/publisher.go index a26aee0ea9..c174143316 100644 --- a/pkg/reconciler/pubsub/topic/resources/publisher.go +++ b/pkg/reconciler/pubsub/topic/resources/publisher.go @@ -82,6 +82,17 @@ func makePublisherPodSpec(args *PublisherArgs) *corev1.PodSpec { } } + // If k8s service account is specified, use that service account as credential. + if args.Topic.Spec.ServiceAccountName != "" { + kServiceAccountName := args.Topic.Spec.ServiceAccountName + return &corev1.PodSpec{ + ServiceAccountName: kServiceAccountName, + Containers: []corev1.Container{ + publisherContainer, + }, + } + } + // Otherwise, use secret as credential. secret := args.Topic.Spec.Secret if secret == nil { diff --git a/test/e2e/test_pullsubscription.go b/test/e2e/test_pullsubscription.go index 82d1d1d852..e23554c682 100644 --- a/test/e2e/test_pullsubscription.go +++ b/test/e2e/test_pullsubscription.go @@ -52,7 +52,7 @@ func SmokePullSubscriptionTestImpl(t *testing.T, authConfig lib.AuthConfig) { Topic: topic, PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - authConfig.PubsubServiceAccount, + GoogleServiceAccount: authConfig.PubsubServiceAccount, }, }, }), @@ -86,7 +86,7 @@ func PullSubscriptionWithTargetTestImpl(t *testing.T, authConfig lib.AuthConfig) Topic: topicName, PubSubSpec: duckv1alpha1.PubSubSpec{ IdentitySpec: duckv1alpha1.IdentitySpec{ - authConfig.PubsubServiceAccount, + GoogleServiceAccount: authConfig.PubsubServiceAccount, }, }, }), kngcptesting.WithPullSubscriptionSink(lib.ServiceGVK, targetName))