From 44e4d8dcf6513e5d3b9099bee9768134246984dc Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 4 Jun 2020 11:58:16 -0400 Subject: [PATCH 1/4] WIP: upgrade pingsource storage to v1alpha2 --- .../200-pingsource-adapter-clusterrole.yaml | 1 + config/core/resources/pingsource.yaml | 6 +- .../roles/pingsource-adapter-clusterrole.yaml | 21 + config/pre-install/v0.16.0/clusterrole.yaml | 2 + .../v0.16.0/storage-version-migration.yaml | 1 + pkg/adapter/mtping/controller.go | 3 +- pkg/adapter/mtping/pingsource_test.go | 8 +- pkg/adapter/ping/adapter.go | 6 +- pkg/reconciler/mtbroker/broker_test.go | 2 +- pkg/reconciler/pingsource/controller.go | 20 +- pkg/reconciler/pingsource/controller_test.go | 4 +- pkg/reconciler/pingsource/pingsource.go | 125 +++-- pkg/reconciler/pingsource/pingsource_test.go | 443 ++++++++++-------- .../pingsource/resources/receive_adapter.go | 45 +- .../resources/receive_adapter_test.go | 28 +- .../pingsource/resources/role_binding.go | 51 ++ .../pingsource/resources/role_binding_test.go | 75 +++ .../pingsource/resources/service_account.go | 38 ++ .../resources/service_account_test.go | 60 +++ pkg/reconciler/testing/pingsource.go | 31 +- 20 files changed, 646 insertions(+), 324 deletions(-) create mode 120000 config/200-pingsource-adapter-clusterrole.yaml create mode 100644 config/core/roles/pingsource-adapter-clusterrole.yaml create mode 100644 pkg/reconciler/pingsource/resources/role_binding.go create mode 100644 pkg/reconciler/pingsource/resources/role_binding_test.go create mode 100644 pkg/reconciler/pingsource/resources/service_account.go create mode 100644 pkg/reconciler/pingsource/resources/service_account_test.go diff --git a/config/200-pingsource-adapter-clusterrole.yaml b/config/200-pingsource-adapter-clusterrole.yaml new file mode 120000 index 00000000000..329497a8c6c --- /dev/null +++ b/config/200-pingsource-adapter-clusterrole.yaml @@ -0,0 +1 @@ +core/roles/pingsource-adapter-clusterrole.yaml \ No newline at end of file diff --git a/config/core/resources/pingsource.yaml b/config/core/resources/pingsource.yaml index 24f44474e43..cd7e086b23c 100644 --- a/config/core/resources/pingsource.yaml +++ b/config/core/resources/pingsource.yaml @@ -70,8 +70,8 @@ spec: JSONPath: .metadata.creationTimestamp versions: - name: v1alpha1 - served: true - storage: true + served: false + storage: false - name: v1alpha2 served: true - storage: false + storage: true diff --git a/config/core/roles/pingsource-adapter-clusterrole.yaml b/config/core/roles/pingsource-adapter-clusterrole.yaml new file mode 100644 index 00000000000..03e4fa397b5 --- /dev/null +++ b/config/core/roles/pingsource-adapter-clusterrole.yaml @@ -0,0 +1,21 @@ +# Copyright 2020 The Knative Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: knative-eventing-pingsource-adapter + labels: + eventing.knative.dev/release: devel +rules: [] diff --git a/config/pre-install/v0.16.0/clusterrole.yaml b/config/pre-install/v0.16.0/clusterrole.yaml index 9d8c9cd7dd9..55c0b85eb58 100644 --- a/config/pre-install/v0.16.0/clusterrole.yaml +++ b/config/pre-install/v0.16.0/clusterrole.yaml @@ -34,8 +34,10 @@ rules: # Our own resources we care about. - apiGroups: - "eventing.knative.dev" + - "sources.knative.dev" resources: - "brokers" + - "pingsources" verbs: - "get" - "list" diff --git a/config/pre-install/v0.16.0/storage-version-migration.yaml b/config/pre-install/v0.16.0/storage-version-migration.yaml index 18aca9c8935..0a7221959e3 100644 --- a/config/pre-install/v0.16.0/storage-version-migration.yaml +++ b/config/pre-install/v0.16.0/storage-version-migration.yaml @@ -37,3 +37,4 @@ spec: image: ko://knative.dev/eventing/vendor/knative.dev/pkg/apiextensions/storageversion/cmd/migrate args: - "brokers.eventing.knative.dev" + - "pingsources.eventing.knative.dev" diff --git a/pkg/adapter/mtping/controller.go b/pkg/adapter/mtping/controller.go index c569d62165b..7c3232a243b 100644 --- a/pkg/adapter/mtping/controller.go +++ b/pkg/adapter/mtping/controller.go @@ -20,8 +20,6 @@ import ( "context" "sync" - "knative.dev/eventing/pkg/adapter/v2" - "github.com/robfig/cron/v3" "go.uber.org/zap" "knative.dev/pkg/configmap" @@ -29,6 +27,7 @@ import ( "knative.dev/pkg/logging" "knative.dev/pkg/source" + "knative.dev/eventing/pkg/adapter/v2" eventingclient "knative.dev/eventing/pkg/client/injection/client" pingsourceinformer "knative.dev/eventing/pkg/client/injection/informers/sources/v1alpha2/pingsource" pingsourcereconciler "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha2/pingsource" diff --git a/pkg/adapter/mtping/pingsource_test.go b/pkg/adapter/mtping/pingsource_test.go index 706521cbdd7..5e2bef8c054 100644 --- a/pkg/adapter/mtping/pingsource_test.go +++ b/pkg/adapter/mtping/pingsource_test.go @@ -87,7 +87,7 @@ func TestAllCases(t *testing.T) { WithValidPingSourceV1A2Schedule, WithPingSourceV1A2Deployed, WithPingSourceV1A2Sink(sinkURI), - WithPingSourceV1A2EventType, + WithPingSourceV1A2CloudEventAttributes, ), }, WantEvents: []string{ @@ -114,7 +114,7 @@ func TestAllCases(t *testing.T) { WithValidPingSourceV1A2Schedule, WithPingSourceV1A2Deployed, WithPingSourceV1A2Sink(sinkURI), - WithPingSourceV1A2EventType, + WithPingSourceV1A2CloudEventAttributes, WithPingSourceV1A2Finalizers(defaultFinalizerName), ), }, @@ -136,7 +136,7 @@ func TestAllCases(t *testing.T) { WithValidPingSourceV1A2Schedule, WithPingSourceV1A2Deployed, WithPingSourceV1A2Sink(sinkURI), - WithPingSourceV1A2EventType, + WithPingSourceV1A2CloudEventAttributes, WithPingSourceV1A2Finalizers(defaultFinalizerName), WithPingSourceV1A2Deleted, ), @@ -165,7 +165,7 @@ func TestAllCases(t *testing.T) { WithValidPingSourceV1A2Schedule, WithPingSourceV1A2Deployed, WithPingSourceV1A2Sink(sinkURI), - WithPingSourceV1A2EventType, + WithPingSourceV1A2CloudEventAttributes, WithPingSourceV1A2Deleted, ), }, diff --git a/pkg/adapter/ping/adapter.go b/pkg/adapter/ping/adapter.go index e5c4f6ca3bd..6c7eb22d7b0 100644 --- a/pkg/adapter/ping/adapter.go +++ b/pkg/adapter/ping/adapter.go @@ -25,10 +25,10 @@ import ( cloudevents "github.com/cloudevents/sdk-go/v2" "github.com/robfig/cron/v3" "go.uber.org/zap" - sourcesv1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" "knative.dev/pkg/logging" "knative.dev/eventing/pkg/adapter/v2" + sourcesv1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2" ) type envConfig struct { @@ -100,8 +100,8 @@ func (a *pingAdapter) start(stopCh <-chan struct{}) error { func (a *pingAdapter) cronTick() { ctx := context.Background() event := cloudevents.NewEvent(cloudevents.VersionV1) - event.SetType(sourcesv1alpha1.PingSourceEventType) - event.SetSource(sourcesv1alpha1.PingSourceSource(a.Namespace, a.Name)) + event.SetType(sourcesv1alpha2.PingSourceEventType) + event.SetSource(sourcesv1alpha2.PingSourceSource(a.Namespace, a.Name)) if err := event.SetData(cloudevents.ApplicationJSON, message(a.Data)); err != nil { logging.FromContext(ctx).Errorw("ping failed to set event data", zap.Error(err)) } diff --git a/pkg/reconciler/mtbroker/broker_test.go b/pkg/reconciler/mtbroker/broker_test.go index fbed56818b2..e196d2b9e19 100644 --- a/pkg/reconciler/mtbroker/broker_test.go +++ b/pkg/reconciler/mtbroker/broker_test.go @@ -1486,7 +1486,7 @@ func makeReadyPingSource() *sourcesv1alpha2.PingSource { rtv1alpha1.WithValidPingSourceV1A2Schedule, rtv1alpha1.WithValidPingSourceV1A2Resources, rtv1alpha1.WithPingSourceV1A2Deployed, - rtv1alpha1.WithPingSourceV1A2EventType, + rtv1alpha1.WithPingSourceV1A2CloudEventAttributes, rtv1alpha1.WithPingSourceV1A2Sink(u), ) } diff --git a/pkg/reconciler/pingsource/controller.go b/pkg/reconciler/pingsource/controller.go index 0f527b85263..ab46c202e9b 100644 --- a/pkg/reconciler/pingsource/controller.go +++ b/pkg/reconciler/pingsource/controller.go @@ -22,7 +22,6 @@ import ( "github.com/kelseyhightower/envconfig" appsv1 "k8s.io/api/apps/v1" "k8s.io/client-go/tools/cache" - "knative.dev/eventing/pkg/apis/sources/v1alpha1" "knative.dev/pkg/configmap" "knative.dev/pkg/controller" "knative.dev/pkg/logging" @@ -31,10 +30,13 @@ import ( "knative.dev/pkg/system" "knative.dev/pkg/tracker" - pingsourceinformer "knative.dev/eventing/pkg/client/injection/informers/sources/v1alpha1/pingsource" - pingsourcereconciler "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha1/pingsource" + "knative.dev/eventing/pkg/apis/sources/v1alpha2" + "knative.dev/pkg/client/injection/kube/informers/rbac/v1/rolebinding" + pingsourceinformer "knative.dev/eventing/pkg/client/injection/informers/sources/v1alpha2/pingsource" + pingsourcereconciler "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha2/pingsource" kubeclient "knative.dev/pkg/client/injection/kube/client" deploymentinformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment" + "knative.dev/pkg/client/injection/kube/informers/core/v1/serviceaccount" ) // envConfig will be used to extract the required environment variables using @@ -54,11 +56,15 @@ func NewController( deploymentInformer := deploymentinformer.Get(ctx) pingSourceInformer := pingsourceinformer.Get(ctx) + serviceAccountInformer := serviceaccount.Get(ctx) + roleBindingInformer := rolebinding.Get(ctx) r := &Reconciler{ - kubeClientSet: kubeclient.Get(ctx), - pingLister: pingSourceInformer.Lister(), - deploymentLister: deploymentInformer.Lister(), + kubeClientSet: kubeclient.Get(ctx), + pingLister: pingSourceInformer.Lister(), + deploymentLister: deploymentInformer.Lister(), + serviceAccountLister: serviceAccountInformer.Lister(), + roleBindingLister: roleBindingInformer.Lister(), loggingContext: ctx, } @@ -79,7 +85,7 @@ func NewController( // Watch for deployments owned by the source deploymentInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ - FilterFunc: controller.FilterControllerGK(v1alpha1.Kind("PingSource")), + FilterFunc: controller.FilterControllerGK(v1alpha2.Kind("PingSource")), Handler: controller.HandleAll(impl.EnqueueControllerOf), }) diff --git a/pkg/reconciler/pingsource/controller_test.go b/pkg/reconciler/pingsource/controller_test.go index 297642091b5..5d9ba1b541b 100644 --- a/pkg/reconciler/pingsource/controller_test.go +++ b/pkg/reconciler/pingsource/controller_test.go @@ -27,9 +27,11 @@ import ( // Fake injection informers _ "knative.dev/eventing/pkg/client/injection/informers/eventing/v1beta1/eventtype/fake" - _ "knative.dev/eventing/pkg/client/injection/informers/sources/v1alpha1/pingsource/fake" + _ "knative.dev/eventing/pkg/client/injection/informers/sources/v1alpha2/pingsource/fake" _ "knative.dev/pkg/client/injection/ducks/duck/v1/addressable/fake" _ "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment/fake" + _ "knative.dev/pkg/client/injection/kube/informers/core/v1/serviceaccount/fake" + _ "knative.dev/pkg/client/injection/kube/informers/rbac/v1/rolebinding/fake" ) func TestNew(t *testing.T) { diff --git a/pkg/reconciler/pingsource/pingsource.go b/pkg/reconciler/pingsource/pingsource.go index 3aadc54e332..d3eb1460b27 100644 --- a/pkg/reconciler/pingsource/pingsource.go +++ b/pkg/reconciler/pingsource/pingsource.go @@ -21,12 +21,16 @@ import ( "encoding/json" "fmt" + rbacv1 "k8s.io/api/rbac/v1" + corev1listers "k8s.io/client-go/listers/core/v1" + rbacv1listers "k8s.io/client-go/listers/rbac/v1" + "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" appsv1listers "k8s.io/client-go/listers/apps/v1" @@ -41,9 +45,9 @@ import ( "knative.dev/pkg/tracker" "knative.dev/eventing/pkg/apis/eventing" - "knative.dev/eventing/pkg/apis/sources/v1alpha1" - pingsourcereconciler "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha1/pingsource" - listers "knative.dev/eventing/pkg/client/listers/sources/v1alpha1" + "knative.dev/eventing/pkg/apis/sources/v1alpha2" + pingsourcereconciler "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha2/pingsource" + listers "knative.dev/eventing/pkg/client/listers/sources/v1alpha2" "knative.dev/eventing/pkg/logging" "knative.dev/eventing/pkg/reconciler/pingsource/resources" "knative.dev/eventing/pkg/utils" @@ -51,11 +55,15 @@ import ( const ( // Name of the corev1.Events emitted from the reconciliation process - pingSourceDeploymentCreated = "PingSourceDeploymentCreated" - pingSourceDeploymentUpdated = "PingSourceDeploymentUpdated" - pingSourceDeploymentDeleted = "PingSourceDeploymentDeleted" - component = "pingsource" - mtadapterName = "pingsource-mt-adapter" + pingSourceDeploymentCreated = "PingSourceDeploymentCreated" + pingSourceDeploymentUpdated = "PingSourceDeploymentUpdated" + pingSourceDeploymentDeleted = "PingSourceDeploymentDeleted" + pingSourceServiceAccountCreated = "PingSourceServiceAccountCreated" + pingSourceRoleBindingCreated = "PingSourceRoleBindingCreated" + + component = "pingsource" + mtadapterName = "pingsource-mt-adapter" + stadapterClusterRoleName = "knative-eventing-pingsource-adapter" ) // newReconciledNormal makes a new reconciler event with event type Normal, and @@ -69,6 +77,14 @@ func newWarningSinkNotFound(sink *duckv1.Destination) pkgreconciler.Event { return pkgreconciler.NewEvent(corev1.EventTypeWarning, "SinkNotFound", "Sink not found: %s", string(b)) } +func newServiceAccountWarn(err error) pkgreconciler.Event { + return pkgreconciler.NewEvent(corev1.EventTypeWarning, "PingSourceServiceAccountFailed", "Reconciling PingSource ServiceAccount failed: %s", err) +} + +func newRoleBindingWarn(err error) pkgreconciler.Event { + return pkgreconciler.NewEvent(corev1.EventTypeWarning, "PingSourceRoleBindingFailed", "Reconciling PingSource RoleBinding failed: %s", err) +} + type Reconciler struct { kubeClientSet kubernetes.Interface @@ -76,8 +92,10 @@ type Reconciler struct { receiveMTAdapterImage string // listers index properties about resources - pingLister listers.PingSourceLister - deploymentLister appsv1listers.DeploymentLister + pingLister listers.PingSourceLister + deploymentLister appsv1listers.DeploymentLister + serviceAccountLister corev1listers.ServiceAccountLister + roleBindingLister rbacv1listers.RoleBindingLister // tracking mt adapter deployment changes tracker tracker.Interface @@ -91,7 +109,7 @@ type Reconciler struct { // Check that our Reconciler implements ReconcileKind var _ pingsourcereconciler.Interface = (*Reconciler)(nil) -func (r *Reconciler) ReconcileKind(ctx context.Context, source *v1alpha1.PingSource) pkgreconciler.Event { +func (r *Reconciler) ReconcileKind(ctx context.Context, source *v1alpha2.PingSource) pkgreconciler.Event { // This Source attempts to reconcile three things. // 1. Determine the sink's URI. // - Nothing to delete. @@ -161,18 +179,56 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, source *v1alpha1.PingSou } source.Status.CloudEventAttributes = []duckv1.CloudEventAttributes{{ - Type: v1alpha1.PingSourceEventType, - Source: v1alpha1.PingSourceSource(source.Namespace, source.Name), + Type: v1alpha2.PingSourceEventType, + Source: v1alpha2.PingSourceSource(source.Namespace, source.Name), }} return newReconciledNormal(source.Namespace, source.Name) } -func (r *Reconciler) createReceiveAdapter(ctx context.Context, src *v1alpha1.PingSource, sinkURI *apis.URL) (*appsv1.Deployment, error) { - if err := checkResourcesStatus(src); err != nil { - return nil, err +func (r *Reconciler) reconcileServiceAccount(ctx context.Context, source *v1alpha2.PingSource) (*corev1.ServiceAccount, error) { + saName := resources.CreateReceiveAdapterName(source.Name, source.UID) + sa, err := r.serviceAccountLister.ServiceAccounts(source.Namespace).Get(saName) + if err != nil { + if apierrors.IsNotFound(err) { + expected := resources.MakeServiceAccount(source, saName) + sa, err := r.kubeClientSet.CoreV1().ServiceAccounts(source.Namespace).Create(expected) + if err != nil { + return sa, newServiceAccountWarn(err) + } + controller.GetEventRecorder(ctx).Eventf(source, corev1.EventTypeNormal, pingSourceServiceAccountCreated, "PingSource ServiceAccount created") + return sa, nil + } + + logging.FromContext(ctx).Error("Unable to get the PingSource ServiceAccount", zap.Error(err)) + source.Status.Annotations["serviceAccount"] = "Failed to get ServiceAccount" + return nil, newServiceAccountWarn(err) } + return sa, nil +} + +func (r *Reconciler) reconcileRoleBinding(ctx context.Context, source *v1alpha2.PingSource) (*rbacv1.RoleBinding, error) { + rbName := resources.CreateReceiveAdapterName(source.Name, source.UID) + rb, err := r.roleBindingLister.RoleBindings(source.Namespace).Get(rbName) + if err != nil { + if apierrors.IsNotFound(err) { + expected := resources.MakeRoleBinding(source, rbName, stadapterClusterRoleName) + rb, err := r.kubeClientSet.RbacV1().RoleBindings(source.Namespace).Create(expected) + if err != nil { + return rb, newRoleBindingWarn(err) + } + controller.GetEventRecorder(ctx).Eventf(source, corev1.EventTypeNormal, pingSourceRoleBindingCreated, "PingSource RoleBinding created") + return rb, nil + } + logging.FromContext(ctx).Error("Unable to get the PingSource RoleBinding", zap.Error(err)) + source.Status.Annotations["roleBinding"] = "Failed to get PingSource RoleBinding" + return nil, newRoleBindingWarn(err) + } + return rb, nil +} + +func (r *Reconciler) createReceiveAdapter(ctx context.Context, src *v1alpha2.PingSource, sinkURI *apis.URL) (*appsv1.Deployment, error) { loggingConfig, err := pkgLogging.LoggingConfigToJson(r.loggingConfig) if err != nil { logging.FromContext(ctx).Error("error while converting logging config to JSON", zap.Any("receiveAdapter", err)) @@ -228,11 +284,7 @@ func (r *Reconciler) createReceiveAdapter(ctx context.Context, src *v1alpha1.Pin return ra, nil } -func (r *Reconciler) reconcileMTReceiveAdapter(ctx context.Context, source *v1alpha1.PingSource) (*appsv1.Deployment, error) { - if err := checkResourcesStatus(source); err != nil { - return nil, err - } - +func (r *Reconciler) reconcileMTReceiveAdapter(ctx context.Context, source *v1alpha2.PingSource) (*appsv1.Deployment, error) { args := resources.MTArgs{ ServiceAccountName: mtadapterName, MTAdapterName: mtadapterName, @@ -265,35 +317,6 @@ func (r *Reconciler) reconcileMTReceiveAdapter(ctx context.Context, source *v1al return d, nil } -func checkResourcesStatus(src *v1alpha1.PingSource) error { - for _, rsrc := range []struct { - key string - field string - }{{ - key: "Request.CPU", - field: src.Spec.Resources.Requests.ResourceCPU, - }, { - key: "Request.Memory", - field: src.Spec.Resources.Requests.ResourceMemory, - }, { - key: "Limit.CPU", - field: src.Spec.Resources.Limits.ResourceCPU, - }, { - key: "Limit.Memory", - field: src.Spec.Resources.Limits.ResourceMemory, - }} { - // In the event the field isn't specified, we assign a default in the receive_adapter - if rsrc.field != "" { - if _, err := resource.ParseQuantity(rsrc.field); err != nil { - src.Status.MarkResourcesIncorrect("Incorrect Resource", "%s: %q, Error: %s", rsrc.key, rsrc.field, err) - return fmt.Errorf("incorrect resource specification, %s: %q: %v", rsrc.key, rsrc.field, err) - } - } - } - src.Status.MarkResourcesCorrect() - return nil -} - func podSpecChanged(oldPodSpec corev1.PodSpec, newPodSpec corev1.PodSpec) bool { if !equality.Semantic.DeepDerivative(newPodSpec, oldPodSpec) { return true diff --git a/pkg/reconciler/pingsource/pingsource_test.go b/pkg/reconciler/pingsource/pingsource_test.go index 299c5b9f657..cb213a21e28 100644 --- a/pkg/reconciler/pingsource/pingsource_test.go +++ b/pkg/reconciler/pingsource/pingsource_test.go @@ -27,14 +27,13 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes/scheme" clientgotesting "k8s.io/client-go/testing" - sourcesv1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" + sourcesv1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2" fakeeventingclient "knative.dev/eventing/pkg/client/injection/client/fake" - "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha1/pingsource" + "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha2/pingsource" "knative.dev/eventing/pkg/reconciler/pingsource/resources" "knative.dev/eventing/pkg/utils" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" - duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" "knative.dev/pkg/client/injection/ducks/duck/v1/addressable" fakekubeclient "knative.dev/pkg/client/injection/kube/client/fake" "knative.dev/pkg/configmap" @@ -85,7 +84,7 @@ func init() { // Add types to scheme _ = appsv1.AddToScheme(scheme.Scheme) _ = corev1.AddToScheme(scheme.Scheme) - _ = duckv1alpha1.AddToScheme(scheme.Scheme) + _ = duckv1.AddToScheme(scheme.Scheme) } func TestAllCases(t *testing.T) { @@ -101,32 +100,36 @@ func TestAllCases(t *testing.T) { }, { Name: "missing sink", Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), ), }, Key: testNS + "/" + sourceName, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithInitPingSourceConditions, - WithPingSourceStatusObservedGeneration(generation), - WithPingSourceSinkNotFound, + WithInitPingSourceV1A2Conditions, + WithPingSourceV1A2StatusObservedGeneration(generation), + WithPingSourceV1A2SinkNotFound, ), }}, WantEvents: []string{ @@ -136,15 +139,17 @@ func TestAllCases(t *testing.T) { }, { Name: "valid", Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), ), rtv1beta1.NewChannel(sinkName, testNS, rtv1beta1.WithInitChannelConditions, @@ -157,37 +162,40 @@ func TestAllCases(t *testing.T) { Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceDeployed, - WithPingSourceSink(sinkURI), - WithPingSourceEventType, - WithPingSourceStatusObservedGeneration(generation), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2Deployed, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2CloudEventAttributes, + WithPingSourceV1A2StatusObservedGeneration(generation), ), }}, }, { Name: "valid with sink URI", Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDestURI, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDestURI, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), ), rtv1beta1.NewChannel(sinkName, testNS, rtv1beta1.WithInitChannelConditions, @@ -200,37 +208,40 @@ func TestAllCases(t *testing.T) { Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDestURI, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDestURI, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceDeployed, - WithPingSourceSink(sinkURI), - WithPingSourceEventType, - WithPingSourceStatusObservedGeneration(generation), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2Deployed, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2CloudEventAttributes, + WithPingSourceV1A2StatusObservedGeneration(generation), ), }}, }, { Name: "valid, existing ra", Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), ), rtv1beta1.NewChannel(sinkName, testNS, rtv1beta1.WithInitChannelConditions, @@ -243,43 +254,45 @@ func TestAllCases(t *testing.T) { Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceDeployed, - WithPingSourceSink(sinkURI), - WithPingSourceEventType, - WithPingSourceStatusObservedGeneration(generation), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2Deployed, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2CloudEventAttributes, + WithPingSourceV1A2StatusObservedGeneration(generation), ), }}, }, { Name: "valid, no change", Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceDeployed, - WithPingSourceSink(sinkURI), - WithPingSourceEventType, + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2Deployed, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2CloudEventAttributes, ), rtv1beta1.NewChannel(sinkName, testNS, rtv1beta1.WithInitChannelConditions, @@ -289,23 +302,24 @@ func TestAllCases(t *testing.T) { }, Key: testNS + "/" + sourceName, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceDeployed, - WithPingSourceSink(sinkURI), - WithPingSourceEventType, - WithPingSourceStatusObservedGeneration(generation), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2Deployed, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2CloudEventAttributes, + WithPingSourceV1A2StatusObservedGeneration(generation), ), }}, WantEvents: []string{ @@ -314,15 +328,17 @@ func TestAllCases(t *testing.T) { }, { Name: "valid", Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), ), rtv1beta1.NewChannel(sinkName, testNS, rtv1beta1.WithInitChannelConditions, @@ -335,37 +351,40 @@ func TestAllCases(t *testing.T) { Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceDeployed, - WithPingSourceSink(sinkURI), - WithPingSourceEventType, - WithPingSourceStatusObservedGeneration(generation), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2Deployed, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2CloudEventAttributes, + WithPingSourceV1A2StatusObservedGeneration(generation), ), }}, }, { Name: "valid with cluster scope annotation", Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceClusterScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ClusterScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), ), rtv1beta1.NewChannel(sinkName, testNS, rtv1beta1.WithInitChannelConditions, @@ -378,38 +397,42 @@ func TestAllCases(t *testing.T) { Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceClusterScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ClusterScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceDeployed, - WithPingSourceSink(sinkURI), - WithPingSourceEventType, - WithPingSourceStatusObservedGeneration(generation), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + + WithPingSourceV1A2Deployed, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2CloudEventAttributes, + WithPingSourceV1A2StatusObservedGeneration(generation), ), }}, }, { Name: "valid with cluster scope annotation, create deployment", SkipNamespaceValidation: true, Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceClusterScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ClusterScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), ), rtv1beta1.NewChannel(sinkName, testNS, rtv1beta1.WithInitChannelConditions, @@ -425,38 +448,41 @@ func TestAllCases(t *testing.T) { MakeMTAdapter(), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceClusterScopeAnnotation, - WithPingSourceUID(sourceUID), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ClusterScopeAnnotation, + WithPingSourceV1A2UID(sourceUID), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithPingSourceNotDeployed(mtadapterName), - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceEventType, - WithPingSourceSink(sinkURI), - WithPingSourceStatusObservedGeneration(generation), + WithPingSourceV1A2NotDeployed(mtadapterName), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2CloudEventAttributes, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2StatusObservedGeneration(generation), ), }}, }, { Name: "deprecated named adapter deployment found", SkipNamespaceValidation: true, Objects: []runtime.Object{ - NewPingSourceV1Alpha1(sourceNameLong, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + NewPingSourceV1Alpha2(sourceNameLong, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUIDLong), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUIDLong), + WithPingSourceV1A2ObjectMetaGeneration(generation), ), rtv1beta1.NewChannel(sinkName, testNS, rtv1beta1.WithInitChannelConditions, @@ -475,23 +501,24 @@ func TestAllCases(t *testing.T) { makeReceiveAdapterWithSinkAndCustomData(sourceNameLong, sourceUIDLong, sinkDest), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ - Object: NewPingSourceV1Alpha1(sourceNameLong, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + Object: NewPingSourceV1Alpha2(sourceNameLong, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &sinkDest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: sinkDest, + }, }), - WithPingSourceResourceScopeAnnotation, - WithPingSourceUID(sourceUIDLong), - WithPingSourceObjectMetaGeneration(generation), + WithPingSourceV1A2ResourceScopeAnnotation, + WithPingSourceV1A2UID(sourceUIDLong), + WithPingSourceV1A2ObjectMetaGeneration(generation), // Status Update: - WithPingSourceNotDeployed(makeReceiveAdapterWithSinkAndCustomData(sourceNameLong, sourceUIDLong, sinkDest).Name), - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithValidPingSourceResources, - WithPingSourceEventType, - WithPingSourceSink(sinkURI), - WithPingSourceStatusObservedGeneration(generation), + WithPingSourceV1A2NotDeployed(makeReceiveAdapterWithSinkAndCustomData(sourceNameLong, sourceUIDLong, sinkDest).Name), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2CloudEventAttributes, + WithPingSourceV1A2Sink(sinkURI), + WithPingSourceV1A2StatusObservedGeneration(generation), ), }}, WantDeletes: []clientgotesting.DeleteActionImpl{{ @@ -505,7 +532,7 @@ func TestAllCases(t *testing.T) { ctx = addressable.WithDuck(ctx) r := &Reconciler{ kubeClientSet: fakekubeclient.Get(ctx), - pingLister: listers.GetPingSourceLister(), + pingLister: listers.GetPingSourceV1alpha2Lister(), deploymentLister: listers.GetDeploymentLister(), tracker: tracker.New(func(types.NamespacedName) {}, 0), receiveAdapterImage: image, @@ -514,7 +541,7 @@ func TestAllCases(t *testing.T) { r.sinkResolver = resolver.NewURIResolver(ctx, func(types.NamespacedName) {}) return pingsource.NewReconciler(ctx, logging.FromContext(ctx), - fakeeventingclient.Get(ctx), listers.GetPingSourceLister(), + fakeeventingclient.Get(ctx), listers.GetPingSourceV1alpha2Lister(), controller.GetEventRecorder(ctx), r) }, true, @@ -531,7 +558,7 @@ func makeAvailableReceiveAdapter(dest duckv1.Destination) *appsv1.Deployment { // makeAvailableReceiveAdapterDeprecatedName needed to simulate pre 0.14 adapter whose name was generated using utils.GenerateFixedName func makeAvailableReceiveAdapterDeprecatedName(sourceName string, sourceUID string, dest duckv1.Destination) *appsv1.Deployment { ra := makeReceiveAdapterWithSink(dest) - src := &sourcesv1alpha1.PingSource{} + src := &sourcesv1alpha2.PingSource{} src.UID = types.UID(sourceUID) ra.Name = utils.GenerateFixedName(src, fmt.Sprintf("pingsource-%s", sourceName)) WithDeploymentAvailable()(ra) @@ -539,19 +566,21 @@ func makeAvailableReceiveAdapterDeprecatedName(sourceName string, sourceUID stri } func makeReceiveAdapterWithSinkAndCustomData(sourceName, sourceUID string, dest duckv1.Destination) *appsv1.Deployment { - source := NewPingSourceV1Alpha1(sourceName, testNS, - WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ + source := NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ Schedule: testSchedule, - Data: testData, - Sink: &dest, + JsonData: testData, + SourceSpec: duckv1.SourceSpec{ + Sink: dest, + }, }, ), - WithPingSourceUID(sourceUID), + WithPingSourceV1A2UID(sourceUID), // Status Update: - WithInitPingSourceConditions, - WithValidPingSourceSchedule, - WithPingSourceDeployed, - WithPingSourceSink(sinkURI), + WithInitPingSourceV1A2Conditions, + WithValidPingSourceV1A2Schedule, + WithPingSourceV1A2Deployed, + WithPingSourceV1A2Sink(sinkURI), ) args := resources.Args{ diff --git a/pkg/reconciler/pingsource/resources/receive_adapter.go b/pkg/reconciler/pingsource/resources/receive_adapter.go index 69be997ca77..9e14f4b27f1 100644 --- a/pkg/reconciler/pingsource/resources/receive_adapter.go +++ b/pkg/reconciler/pingsource/resources/receive_adapter.go @@ -25,7 +25,8 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "knative.dev/eventing/pkg/apis/sources/v1alpha1" + "k8s.io/apimachinery/pkg/types" + "knative.dev/eventing/pkg/apis/sources/v1alpha2" "knative.dev/pkg/kmeta" ) @@ -34,53 +35,41 @@ var ( one = int32(1) ) -// ReceiveAdapterArgs are the arguments needed to create a Cron Job Source Receive Adapter. Every +// ReceiveAdapterArgs are the arguments needed to create a PingSource Receive Adapter. Every // field is required. type Args struct { Image string - Source *v1alpha1.PingSource + Source *v1alpha2.PingSource Labels map[string]string SinkURI *apis.URL MetricsConfig string LoggingConfig string } +func CreateReceiveAdapterName(name string, uid types.UID) string { + return kmeta.ChildName(fmt.Sprintf("pingsource-%s-", name), string(uid)) +} + // MakeReceiveAdapter generates (but does not insert into K8s) the Receive Adapter Deployment for // PingSources. func MakeReceiveAdapter(args *Args) *v1.Deployment { - name := args.Source.ObjectMeta.Name - RequestResourceCPU, err := resource.ParseQuantity(args.Source.Spec.Resources.Requests.ResourceCPU) - if err != nil { - RequestResourceCPU = resource.MustParse("250m") - } - RequestResourceMemory, err := resource.ParseQuantity(args.Source.Spec.Resources.Requests.ResourceMemory) - if err != nil { - RequestResourceMemory = resource.MustParse("512Mi") - } - LimitResourceCPU, err := resource.ParseQuantity(args.Source.Spec.Resources.Limits.ResourceCPU) - if err != nil { - LimitResourceCPU = resource.MustParse("250m") - } - LimitResourceMemory, err := resource.ParseQuantity(args.Source.Spec.Resources.Limits.ResourceMemory) - if err != nil { - LimitResourceMemory = resource.MustParse("512Mi") - } - res := corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceCPU: RequestResourceCPU, - corev1.ResourceMemory: RequestResourceMemory, + corev1.ResourceCPU: resource.MustParse("10m"), + corev1.ResourceMemory: resource.MustParse("32Mi"), }, Limits: corev1.ResourceList{ - corev1.ResourceCPU: LimitResourceCPU, - corev1.ResourceMemory: LimitResourceMemory, + corev1.ResourceCPU: resource.MustParse("20m"), + corev1.ResourceMemory: resource.MustParse("64Mi"), }, } + name := CreateReceiveAdapterName(args.Source.Name, args.Source.GetUID()) + return &v1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Namespace: args.Source.Namespace, - Name: kmeta.ChildName(fmt.Sprintf("pingsource-%s-", name), string(args.Source.GetUID())), + Name: name, Labels: args.Labels, OwnerReferences: []metav1.OwnerReference{ *kmeta.NewControllerRef(args.Source), @@ -96,7 +85,7 @@ func MakeReceiveAdapter(args *Args) *v1.Deployment { Labels: args.Labels, }, Spec: corev1.PodSpec{ - ServiceAccountName: args.Source.Spec.ServiceAccountName, + ServiceAccountName: name, Containers: []corev1.Container{ { Name: "receive-adapter", @@ -113,7 +102,7 @@ func MakeReceiveAdapter(args *Args) *v1.Deployment { }, { Name: "DATA", - Value: args.Source.Spec.Data, + Value: args.Source.Spec.JsonData, }, { Name: "K_SINK", diff --git a/pkg/reconciler/pingsource/resources/receive_adapter_test.go b/pkg/reconciler/pingsource/resources/receive_adapter_test.go index b27c93ed8ee..538e7f8604f 100644 --- a/pkg/reconciler/pingsource/resources/receive_adapter_test.go +++ b/pkg/reconciler/pingsource/resources/receive_adapter_test.go @@ -20,28 +20,26 @@ import ( "fmt" "testing" - "knative.dev/pkg/apis" - v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "knative.dev/eventing/pkg/apis/sources/v1alpha1" + "knative.dev/pkg/apis" "knative.dev/pkg/kmp" + + "knative.dev/eventing/pkg/apis/sources/v1alpha2" ) func TestMakeReceiveAdapter(t *testing.T) { - src := &v1alpha1.PingSource{ + src := &v1alpha2.PingSource{ ObjectMeta: metav1.ObjectMeta{ Name: "source-name", Namespace: "source-namespace", UID: "source-uid", }, - Spec: v1alpha1.PingSourceSpec{ - ServiceAccountName: "source-svc-acct", - Schedule: "*/2 * * * *", - Data: "data", + Spec: v1alpha2.PingSourceSpec{ + Schedule: "*/2 * * * *", + JsonData: "data", }, } @@ -68,7 +66,7 @@ func TestMakeReceiveAdapter(t *testing.T) { "test-key2": "test-value2", }, OwnerReferences: []metav1.OwnerReference{{ - APIVersion: "sources.knative.dev/v1alpha1", + APIVersion: "sources.knative.dev/v1alpha2", Kind: "PingSource", Name: src.Name, UID: src.UID, @@ -92,7 +90,7 @@ func TestMakeReceiveAdapter(t *testing.T) { }, }, Spec: corev1.PodSpec{ - ServiceAccountName: "source-svc-acct", + ServiceAccountName: "pingsource-source-name-source-uid", Containers: []corev1.Container{ { Name: "receive-adapter", @@ -137,12 +135,12 @@ func TestMakeReceiveAdapter(t *testing.T) { }, Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("250m"), - corev1.ResourceMemory: resource.MustParse("512Mi"), + corev1.ResourceCPU: resource.MustParse("20m"), + corev1.ResourceMemory: resource.MustParse("64Mi"), }, Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("250m"), - corev1.ResourceMemory: resource.MustParse("512Mi"), + corev1.ResourceCPU: resource.MustParse("10m"), + corev1.ResourceMemory: resource.MustParse("32Mi"), }, }, }, diff --git a/pkg/reconciler/pingsource/resources/role_binding.go b/pkg/reconciler/pingsource/resources/role_binding.go new file mode 100644 index 00000000000..138a3d9cb5f --- /dev/null +++ b/pkg/reconciler/pingsource/resources/role_binding.go @@ -0,0 +1,51 @@ +/* +Copyright 2020 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resources + +import ( + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/kmeta" + + "knative.dev/eventing/pkg/apis/sources/v1alpha2" +) + +// MakeRoleBinding creates a RoleBinding object for the single-tenant receive adapter +// service account 'sa' in the Namespace 'ns'. +func MakeRoleBinding(source *v1alpha2.PingSource, name string, clusterRoleName string) *rbacv1.RoleBinding { + return &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: source.Namespace, + OwnerReferences: []metav1.OwnerReference{ + *kmeta.NewControllerRef(source), + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: clusterRoleName, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Namespace: source.Namespace, + Name: name, + }, + }, + } +} diff --git a/pkg/reconciler/pingsource/resources/role_binding_test.go b/pkg/reconciler/pingsource/resources/role_binding_test.go new file mode 100644 index 00000000000..a3ad7245fae --- /dev/null +++ b/pkg/reconciler/pingsource/resources/role_binding_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2020 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resources + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/kmeta" + + "knative.dev/eventing/pkg/apis/sources/v1alpha2" +) + +func TestNewRoleBinding(t *testing.T) { + const ( + rbName = "my-test-role-binding" + crName = "my-test-cluster-role" + testNS = "test-ns" + ) + src := &v1alpha2.PingSource{ + ObjectMeta: metav1.ObjectMeta{ + Name: "source-name", + Namespace: testNS, + UID: "source-uid", + }, + Spec: v1alpha2.PingSourceSpec{ + Schedule: "*/2 * * * *", + JsonData: "data", + }, + } + + want := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: rbName, + Namespace: testNS, + OwnerReferences: []metav1.OwnerReference{ + *kmeta.NewControllerRef(src), + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: crName, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Namespace: testNS, + Name: rbName, + }, + }, + } + + got := MakeRoleBinding(src, rbName, crName) + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected condition (-want, +got) = %v", diff) + } +} diff --git a/pkg/reconciler/pingsource/resources/service_account.go b/pkg/reconciler/pingsource/resources/service_account.go new file mode 100644 index 00000000000..f1dee692707 --- /dev/null +++ b/pkg/reconciler/pingsource/resources/service_account.go @@ -0,0 +1,38 @@ +/* +Copyright 2020 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resources + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/kmeta" + + "knative.dev/eventing/pkg/apis/sources/v1alpha2" +) + +// MakeServiceAccount creates a ServiceAccount object for the given PingSource +func MakeServiceAccount(source *v1alpha2.PingSource, name string) *corev1.ServiceAccount { + return &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: source.Namespace, + Name: name, + OwnerReferences: []metav1.OwnerReference{ + *kmeta.NewControllerRef(source), + }, + }, + } +} diff --git a/pkg/reconciler/pingsource/resources/service_account_test.go b/pkg/reconciler/pingsource/resources/service_account_test.go new file mode 100644 index 00000000000..a031fd8ce40 --- /dev/null +++ b/pkg/reconciler/pingsource/resources/service_account_test.go @@ -0,0 +1,60 @@ +/* +Copyright 2020 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resources + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/kmeta" + + "knative.dev/eventing/pkg/apis/sources/v1alpha2" +) + +func TestNewServiceAccount(t *testing.T) { + testNS := "test-ns" + testName := "test-name" + src := &v1alpha2.PingSource{ + ObjectMeta: metav1.ObjectMeta{ + Name: testName, + Namespace: testNS, + UID: "source-uid", + }, + Spec: v1alpha2.PingSourceSpec{ + Schedule: "*/2 * * * *", + JsonData: "data", + }, + } + + want := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNS, + Name: testName, + OwnerReferences: []metav1.OwnerReference{ + *kmeta.NewControllerRef(src), + }, + }, + } + + got := MakeServiceAccount(src, testName) + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected condition (-want, +got) = %v", diff) + } +} diff --git a/pkg/reconciler/testing/pingsource.go b/pkg/reconciler/testing/pingsource.go index e3aacf5bd71..2b5fcc45d0c 100644 --- a/pkg/reconciler/testing/pingsource.go +++ b/pkg/reconciler/testing/pingsource.go @@ -74,6 +74,12 @@ func WithPingSourceUID(uid string) PingSourceOption { } } +func WithPingSourceV1A2UID(uid string) PingSourceV1A2Option { + return func(c *v1alpha2.PingSource) { + c.UID = types.UID(uid) + } +} + func WithPingSourceResourceScopeAnnotation(c *v1alpha1.PingSource) { if c.Annotations == nil { c.Annotations = make(map[string]string) @@ -149,6 +155,12 @@ func WithPingSourceNotDeployed(name string) PingSourceOption { } } +func WithPingSourceV1A2NotDeployed(name string) PingSourceV1A2Option { + return func(s *v1alpha2.PingSource) { + s.Status.PropagateDeploymentAvailability(NewDeployment(name, "any")) + } +} + func WithPingSourceDeployed(s *v1alpha1.PingSource) { s.Status.PropagateDeploymentAvailability(NewDeployment("any", "any", WithDeploymentAvailable())) } @@ -164,8 +176,11 @@ func WithPingSourceEventType(s *v1alpha1.PingSource) { }} } -func WithPingSourceV1A2EventType(s *v1alpha2.PingSource) { - s.Status.MarkEventType() +func WithPingSourceV1A2CloudEventAttributes(s *v1alpha2.PingSource) { + s.Status.CloudEventAttributes = []duckv1.CloudEventAttributes{{ + Type: v1alpha2.PingSourceEventType, + Source: v1alpha2.PingSourceSource(s.Namespace, s.Name), + }} } func WithValidPingSourceResources(s *v1alpha1.PingSource) { @@ -205,12 +220,24 @@ func WithPingSourceStatusObservedGeneration(generation int64) PingSourceOption { } } +func WithPingSourceV1A2StatusObservedGeneration(generation int64) PingSourceV1A2Option { + return func(c *v1alpha2.PingSource) { + c.Status.ObservedGeneration = generation + } +} + func WithPingSourceObjectMetaGeneration(generation int64) PingSourceOption { return func(c *v1alpha1.PingSource) { c.ObjectMeta.Generation = generation } } +func WithPingSourceV1A2ObjectMetaGeneration(generation int64) PingSourceV1A2Option { + return func(c *v1alpha2.PingSource) { + c.ObjectMeta.Generation = generation + } +} + func WithPingSourceV1A2Finalizers(finalizers ...string) PingSourceV1A2Option { return func(c *v1alpha2.PingSource) { c.Finalizers = finalizers From 7f5fae6ece1ededea738a0984798bdd799b2432d Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 4 Jun 2020 13:58:06 -0400 Subject: [PATCH 2/4] fix e2e --- config/pre-install/v0.16.0/pingsource.yaml | 77 +++++++++++++++++++ .../v0.16.0/storage-version-migration.yaml | 2 +- pkg/reconciler/pingsource/controller.go | 2 +- pkg/reconciler/pingsource/pingsource.go | 10 +++ test/e2e/source_ping_test.go | 39 ---------- 5 files changed, 89 insertions(+), 41 deletions(-) create mode 100644 config/pre-install/v0.16.0/pingsource.yaml diff --git a/config/pre-install/v0.16.0/pingsource.yaml b/config/pre-install/v0.16.0/pingsource.yaml new file mode 100644 index 00000000000..cd7e086b23c --- /dev/null +++ b/config/pre-install/v0.16.0/pingsource.yaml @@ -0,0 +1,77 @@ +# Copyright 2020 The Knative Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + labels: + eventing.knative.dev/release: devel + eventing.knative.dev/source: "true" + duck.knative.dev/source: "true" + knative.dev/crd-install: "true" + annotations: + # TODO add schemas and descriptions + registry.knative.dev/eventTypes: | + [ + { "type": "dev.knative.sources.ping" } + ] + name: pingsources.sources.knative.dev +spec: + group: sources.knative.dev + names: + categories: + - all + - knative + - eventing + - sources + kind: PingSource + plural: pingsources + scope: Namespaced + subresources: + status: {} + preserveUnknownFields: false + validation: + openAPIV3Schema: + type: object + # this is a work around so we don't need to flesh out the + # schema for each version at this time + # + # see issue: https://github.com/knative/serving/issues/912 + x-kubernetes-preserve-unknown-fields: true + conversion: + strategy: Webhook + webhookClientConfig: + service: + name: eventing-webhook + namespace: knative-eventing + additionalPrinterColumns: + - name: Ready + type: string + JSONPath: ".status.conditions[?(@.type=='Ready')].status" + - name: Reason + type: string + JSONPath: ".status.conditions[?(@.type=='Ready')].reason" + - name: Sink + type: string + JSONPath: .status.sinkUri + - name: Age + type: date + JSONPath: .metadata.creationTimestamp + versions: + - name: v1alpha1 + served: false + storage: false + - name: v1alpha2 + served: true + storage: true diff --git a/config/pre-install/v0.16.0/storage-version-migration.yaml b/config/pre-install/v0.16.0/storage-version-migration.yaml index 0a7221959e3..09751496e00 100644 --- a/config/pre-install/v0.16.0/storage-version-migration.yaml +++ b/config/pre-install/v0.16.0/storage-version-migration.yaml @@ -37,4 +37,4 @@ spec: image: ko://knative.dev/eventing/vendor/knative.dev/pkg/apiextensions/storageversion/cmd/migrate args: - "brokers.eventing.knative.dev" - - "pingsources.eventing.knative.dev" + - "pingsources.sources.knative.dev" diff --git a/pkg/reconciler/pingsource/controller.go b/pkg/reconciler/pingsource/controller.go index ab46c202e9b..9e98726540c 100644 --- a/pkg/reconciler/pingsource/controller.go +++ b/pkg/reconciler/pingsource/controller.go @@ -31,12 +31,12 @@ import ( "knative.dev/pkg/tracker" "knative.dev/eventing/pkg/apis/sources/v1alpha2" - "knative.dev/pkg/client/injection/kube/informers/rbac/v1/rolebinding" pingsourceinformer "knative.dev/eventing/pkg/client/injection/informers/sources/v1alpha2/pingsource" pingsourcereconciler "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha2/pingsource" kubeclient "knative.dev/pkg/client/injection/kube/client" deploymentinformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment" "knative.dev/pkg/client/injection/kube/informers/core/v1/serviceaccount" + "knative.dev/pkg/client/injection/kube/informers/rbac/v1/rolebinding" ) // envConfig will be used to extract the required environment variables using diff --git a/pkg/reconciler/pingsource/pingsource.go b/pkg/reconciler/pingsource/pingsource.go index d3eb1460b27..3c1fd85eca8 100644 --- a/pkg/reconciler/pingsource/pingsource.go +++ b/pkg/reconciler/pingsource/pingsource.go @@ -170,6 +170,16 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, source *v1alpha2.PingSou return err } } else { + if _, err := r.reconcileServiceAccount(ctx, source); err != nil { + logging.FromContext(ctx).Error("Unable to create the receive adapter service account", zap.Error(err)) + return fmt.Errorf("creating receive adapter service account: %v", err) + } + + if _, err := r.reconcileRoleBinding(ctx, source); err != nil { + logging.FromContext(ctx).Error("Unable to create the receive adapter role binding", zap.Error(err)) + return fmt.Errorf("creating receive adapter role binding: %v", err) + } + ra, err := r.createReceiveAdapter(ctx, source, sinkURI) if err != nil { logging.FromContext(ctx).Error("Unable to create the receive adapter", zap.Error(err)) diff --git a/test/e2e/source_ping_test.go b/test/e2e/source_ping_test.go index d746600abfb..4ee24c52ba1 100644 --- a/test/e2e/source_ping_test.go +++ b/test/e2e/source_ping_test.go @@ -33,48 +33,9 @@ import ( "knative.dev/eventing/test/lib/resources" duckv1 "knative.dev/pkg/apis/duck/v1" - sourcesv1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" eventingtesting "knative.dev/eventing/pkg/reconciler/testing" ) -func TestPingSourceV1Alpha1(t *testing.T) { - const ( - sourceName = "e2e-ping-source" - // Every 1 minute starting from now - schedule = "*/1 * * * *" - - recordEventPodName = "e2e-ping-source-logger-pod-v1alpha1" - ) - - client := setup(t, true) - defer tearDown(client) - - // create event logger pod and service - eventTracker, _ := recordevents.StartEventRecordOrFail(client, recordEventPodName) - defer eventTracker.Cleanup() - - // create cron job source - data := fmt.Sprintf(`{"msg":"TestPingSource %s"}`, uuid.NewUUID()) - source := eventingtesting.NewPingSourceV1Alpha1( - sourceName, - client.Namespace, - eventingtesting.WithPingSourceSpec(sourcesv1alpha1.PingSourceSpec{ - Schedule: schedule, - Data: data, - Sink: &duckv1.Destination{Ref: resources.KnativeRefForService(recordEventPodName, client.Namespace)}, - }), - ) - client.CreatePingSourceV1Alpha1OrFail(source) - - // wait for all test resources to be ready - client.WaitForAllTestResourcesReadyOrFail() - - eventTracker.AssertExact(1, recordevents.MatchEvent( - HasSource(sourcesv1alpha1.PingSourceSource(client.Namespace, sourceName)), - HasData([]byte(data)), - )) -} - func TestPingSourceV1Alpha2(t *testing.T) { const ( sourceName = "e2e-ping-source" From db56628cbdfd2f50b9b6860221fa6b32e60398ae Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 4 Jun 2020 14:40:21 -0400 Subject: [PATCH 3/4] fix unit tests (again) --- pkg/reconciler/pingsource/pingsource_test.go | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/pkg/reconciler/pingsource/pingsource_test.go b/pkg/reconciler/pingsource/pingsource_test.go index cb213a21e28..ae38e92c217 100644 --- a/pkg/reconciler/pingsource/pingsource_test.go +++ b/pkg/reconciler/pingsource/pingsource_test.go @@ -23,6 +23,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes/scheme" @@ -75,6 +76,7 @@ const ( testNS = "testnamespace" testSchedule = "*/2 * * * *" testData = "data" + crName = "knative-eventing-pingsource-adapter" sinkName = "testsink" generation = 1 @@ -159,8 +161,14 @@ func TestAllCases(t *testing.T) { }, Key: testNS + "/" + sourceName, WantEvents: []string{ + Eventf(corev1.EventTypeNormal, "PingSourceServiceAccountCreated", `PingSource ServiceAccount created`), + Eventf(corev1.EventTypeNormal, "PingSourceRoleBindingCreated", `PingSource RoleBinding created`), Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, + WantCreates: []runtime.Object{ + MakeServiceAccount(sourceName, sourceUID), + MakeRoleBinding(sourceName, sourceUID), + }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: NewPingSourceV1Alpha2(sourceName, testNS, WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ @@ -205,8 +213,14 @@ func TestAllCases(t *testing.T) { }, Key: testNS + "/" + sourceName, WantEvents: []string{ + Eventf(corev1.EventTypeNormal, "PingSourceServiceAccountCreated", `PingSource ServiceAccount created`), + Eventf(corev1.EventTypeNormal, "PingSourceRoleBindingCreated", `PingSource RoleBinding created`), Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, + WantCreates: []runtime.Object{ + MakeServiceAccount(sourceName, sourceUID), + MakeRoleBinding(sourceName, sourceUID), + }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: NewPingSourceV1Alpha2(sourceName, testNS, WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ @@ -251,8 +265,14 @@ func TestAllCases(t *testing.T) { }, Key: testNS + "/" + sourceName, WantEvents: []string{ + Eventf(corev1.EventTypeNormal, "PingSourceServiceAccountCreated", `PingSource ServiceAccount created`), + Eventf(corev1.EventTypeNormal, "PingSourceRoleBindingCreated", `PingSource RoleBinding created`), Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, + WantCreates: []runtime.Object{ + MakeServiceAccount(sourceName, sourceUID), + MakeRoleBinding(sourceName, sourceUID), + }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: NewPingSourceV1Alpha2(sourceName, testNS, WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ @@ -299,6 +319,8 @@ func TestAllCases(t *testing.T) { rtv1beta1.WithChannelAddress(sinkDNS), ), makeAvailableReceiveAdapter(sinkDest), + MakeServiceAccount(sourceName, sourceUID), + MakeRoleBinding(sourceName, sourceUID), }, Key: testNS + "/" + sourceName, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ @@ -348,8 +370,14 @@ func TestAllCases(t *testing.T) { }, Key: testNS + "/" + sourceName, WantEvents: []string{ + Eventf(corev1.EventTypeNormal, "PingSourceServiceAccountCreated", `PingSource ServiceAccount created`), + Eventf(corev1.EventTypeNormal, "PingSourceRoleBindingCreated", `PingSource RoleBinding created`), Eventf(corev1.EventTypeNormal, "PingSourceReconciled", `PingSource reconciled: "%s/%s"`, testNS, sourceName), }, + WantCreates: []runtime.Object{ + MakeServiceAccount(sourceName, sourceUID), + MakeRoleBinding(sourceName, sourceUID), + }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: NewPingSourceV1Alpha2(sourceName, testNS, WithPingSourceV1A2Spec(sourcesv1alpha2.PingSourceSpec{ @@ -489,6 +517,8 @@ func TestAllCases(t *testing.T) { rtv1beta1.WithChannelAddress(sinkDNS), ), makeAvailableReceiveAdapterDeprecatedName(sourceNameLong, sourceUIDLong, sinkDest), + MakeServiceAccount(sourceNameLong, sourceUIDLong), + MakeRoleBinding(sourceNameLong, sourceUIDLong), }, Key: testNS + "/" + sourceNameLong, WantEvents: []string{ @@ -534,6 +564,8 @@ func TestAllCases(t *testing.T) { kubeClientSet: fakekubeclient.Get(ctx), pingLister: listers.GetPingSourceV1alpha2Lister(), deploymentLister: listers.GetDeploymentLister(), + serviceAccountLister: listers.GetServiceAccountLister(), + roleBindingLister: listers.GetRoleBindingLister(), tracker: tracker.New(func(types.NamespacedName) {}, 0), receiveAdapterImage: image, receiveMTAdapterImage: mtimage, @@ -610,3 +642,15 @@ func makeAvailableMTAdapter() *appsv1.Deployment { WithDeploymentAvailable()(ma) return ma } + +func MakeServiceAccount(sourceName, sourceUID string) *corev1.ServiceAccount { + source := NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2UID(sourceUID)) + return resources.MakeServiceAccount(source, resources.CreateReceiveAdapterName(sourceName, types.UID(sourceUID))) +} + +func MakeRoleBinding(sourceName, sourceUID string) *rbacv1.RoleBinding { + source := NewPingSourceV1Alpha2(sourceName, testNS, + WithPingSourceV1A2UID(sourceUID)) + return resources.MakeRoleBinding(source, resources.CreateReceiveAdapterName(sourceName, types.UID(sourceUID)), crName) +} From 3d8803b76db72d1cf811ab9c0a85515b17d6f5c7 Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 4 Jun 2020 17:05:52 -0400 Subject: [PATCH 4/4] move MakeServiceAccount to pkg/reconciler/resources --- pkg/reconciler/pingsource/pingsource.go | 3 ++- pkg/reconciler/pingsource/pingsource_test.go | 3 ++- .../{pingsource => }/resources/service_account.go | 10 ++++------ .../resources/service_account_test.go | 11 +++-------- 4 files changed, 11 insertions(+), 16 deletions(-) rename pkg/reconciler/{pingsource => }/resources/service_account.go (80%) rename pkg/reconciler/{pingsource => }/resources/service_account_test.go (85%) diff --git a/pkg/reconciler/pingsource/pingsource.go b/pkg/reconciler/pingsource/pingsource.go index 3c1fd85eca8..0496ad6ce91 100644 --- a/pkg/reconciler/pingsource/pingsource.go +++ b/pkg/reconciler/pingsource/pingsource.go @@ -50,6 +50,7 @@ import ( listers "knative.dev/eventing/pkg/client/listers/sources/v1alpha2" "knative.dev/eventing/pkg/logging" "knative.dev/eventing/pkg/reconciler/pingsource/resources" + recresources "knative.dev/eventing/pkg/reconciler/resources" "knative.dev/eventing/pkg/utils" ) @@ -201,7 +202,7 @@ func (r *Reconciler) reconcileServiceAccount(ctx context.Context, source *v1alph sa, err := r.serviceAccountLister.ServiceAccounts(source.Namespace).Get(saName) if err != nil { if apierrors.IsNotFound(err) { - expected := resources.MakeServiceAccount(source, saName) + expected := recresources.MakeServiceAccount(source, saName) sa, err := r.kubeClientSet.CoreV1().ServiceAccounts(source.Namespace).Create(expected) if err != nil { return sa, newServiceAccountWarn(err) diff --git a/pkg/reconciler/pingsource/pingsource_test.go b/pkg/reconciler/pingsource/pingsource_test.go index ae38e92c217..0a4a8f6108f 100644 --- a/pkg/reconciler/pingsource/pingsource_test.go +++ b/pkg/reconciler/pingsource/pingsource_test.go @@ -32,6 +32,7 @@ import ( fakeeventingclient "knative.dev/eventing/pkg/client/injection/client/fake" "knative.dev/eventing/pkg/client/injection/reconciler/sources/v1alpha2/pingsource" "knative.dev/eventing/pkg/reconciler/pingsource/resources" + recresources "knative.dev/eventing/pkg/reconciler/resources" "knative.dev/eventing/pkg/utils" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" @@ -646,7 +647,7 @@ func makeAvailableMTAdapter() *appsv1.Deployment { func MakeServiceAccount(sourceName, sourceUID string) *corev1.ServiceAccount { source := NewPingSourceV1Alpha2(sourceName, testNS, WithPingSourceV1A2UID(sourceUID)) - return resources.MakeServiceAccount(source, resources.CreateReceiveAdapterName(sourceName, types.UID(sourceUID))) + return recresources.MakeServiceAccount(source, resources.CreateReceiveAdapterName(sourceName, types.UID(sourceUID))) } func MakeRoleBinding(sourceName, sourceUID string) *rbacv1.RoleBinding { diff --git a/pkg/reconciler/pingsource/resources/service_account.go b/pkg/reconciler/resources/service_account.go similarity index 80% rename from pkg/reconciler/pingsource/resources/service_account.go rename to pkg/reconciler/resources/service_account.go index f1dee692707..f756be2546f 100644 --- a/pkg/reconciler/pingsource/resources/service_account.go +++ b/pkg/reconciler/resources/service_account.go @@ -20,18 +20,16 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/kmeta" - - "knative.dev/eventing/pkg/apis/sources/v1alpha2" ) -// MakeServiceAccount creates a ServiceAccount object for the given PingSource -func MakeServiceAccount(source *v1alpha2.PingSource, name string) *corev1.ServiceAccount { +// MakeServiceAccount creates a ServiceAccount object for the given referable object +func MakeServiceAccount(obj kmeta.OwnerRefable, name string) *corev1.ServiceAccount { return &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ - Namespace: source.Namespace, + Namespace: obj.GetObjectMeta().GetNamespace(), Name: name, OwnerReferences: []metav1.OwnerReference{ - *kmeta.NewControllerRef(source), + *kmeta.NewControllerRef(obj), }, }, } diff --git a/pkg/reconciler/pingsource/resources/service_account_test.go b/pkg/reconciler/resources/service_account_test.go similarity index 85% rename from pkg/reconciler/pingsource/resources/service_account_test.go rename to pkg/reconciler/resources/service_account_test.go index a031fd8ce40..a9c13ef3d12 100644 --- a/pkg/reconciler/pingsource/resources/service_account_test.go +++ b/pkg/reconciler/resources/service_account_test.go @@ -30,15 +30,10 @@ import ( func TestNewServiceAccount(t *testing.T) { testNS := "test-ns" testName := "test-name" - src := &v1alpha2.PingSource{ + obj := &v1alpha2.PingSource{ ObjectMeta: metav1.ObjectMeta{ Name: testName, Namespace: testNS, - UID: "source-uid", - }, - Spec: v1alpha2.PingSourceSpec{ - Schedule: "*/2 * * * *", - JsonData: "data", }, } @@ -47,12 +42,12 @@ func TestNewServiceAccount(t *testing.T) { Namespace: testNS, Name: testName, OwnerReferences: []metav1.OwnerReference{ - *kmeta.NewControllerRef(src), + *kmeta.NewControllerRef(obj), }, }, } - got := MakeServiceAccount(src, testName) + got := MakeServiceAccount(obj, testName) if diff := cmp.Diff(want, got); diff != "" { t.Errorf("unexpected condition (-want, +got) = %v", diff)