From 28af8f96cd8eaee5e3d1d22c68cfbf582ee170ad Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 4 Jun 2020 11:58:16 -0400 Subject: [PATCH] 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 c95ba2f19ad..7271f124528 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 25a0439949f..440eaecd3c5 100644 --- a/pkg/reconciler/mtbroker/broker_test.go +++ b/pkg/reconciler/mtbroker/broker_test.go @@ -1508,7 +1508,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 494bce3c60a..fb357804f21 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" @@ -84,7 +83,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) { @@ -100,32 +99,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{ @@ -135,15 +138,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), ), NewChannel(sinkName, testNS, WithInitChannelConditions, @@ -156,37 +161,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), ), NewChannel(sinkName, testNS, WithInitChannelConditions, @@ -199,37 +207,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), ), NewChannel(sinkName, testNS, WithInitChannelConditions, @@ -242,43 +253,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, ), NewChannel(sinkName, testNS, WithInitChannelConditions, @@ -288,23 +301,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{ @@ -313,15 +327,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), ), NewChannel(sinkName, testNS, WithInitChannelConditions, @@ -334,37 +350,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), ), NewChannel(sinkName, testNS, WithInitChannelConditions, @@ -377,38 +396,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), ), NewChannel(sinkName, testNS, WithInitChannelConditions, @@ -424,38 +447,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), ), NewChannel(sinkName, testNS, WithInitChannelConditions, @@ -474,23 +500,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{{ @@ -504,7 +531,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, @@ -513,7 +540,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, @@ -530,7 +557,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) @@ -538,19 +565,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