From cf91dc3d4a521911b2cc630041477e8124fa14f5 Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 20 Feb 2020 10:15:57 -0500 Subject: [PATCH 01/10] use v1alpha1 deliveryspec --- pkg/apis/flows/v1alpha1/sequence_types.go | 3 +-- pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pkg/apis/flows/v1alpha1/sequence_types.go b/pkg/apis/flows/v1alpha1/sequence_types.go index 468226729b2..8652bbe53a8 100644 --- a/pkg/apis/flows/v1alpha1/sequence_types.go +++ b/pkg/apis/flows/v1alpha1/sequence_types.go @@ -22,7 +22,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" - eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/pkg/kmeta" @@ -87,7 +86,7 @@ type SequenceStep struct { // This includes things like retries, DLQ, etc. // Needed for Roundtripping v1alpha1 <-> v1beta1. // +optional - Delivery *eventingduckv1beta1.DeliverySpec `json:"delivery,omitempty"` + Delivery *eventingduckv1alpha1.DeliverySpec `json:"delivery,omitempty"` } type SequenceChannelStatus struct { diff --git a/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go index 6be9d56e8a7..569c1396c8c 100644 --- a/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go @@ -23,7 +23,6 @@ package v1alpha1 import ( runtime "k8s.io/apimachinery/pkg/runtime" duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" - v1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" v1 "knative.dev/pkg/apis/duck/v1" ) @@ -379,7 +378,7 @@ func (in *SequenceStep) DeepCopyInto(out *SequenceStep) { in.Subscriber.DeepCopyInto(&out.Subscriber) if in.Delivery != nil { in, out := &in.Delivery, &out.Delivery - *out = new(v1beta1.DeliverySpec) + *out = new(duckv1alpha1.DeliverySpec) (*in).DeepCopyInto(*out) } return From 037d599508163d95c0a2f92451b85df6e913cdab Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 20 Feb 2020 12:47:20 -0500 Subject: [PATCH 02/10] use v1beta1 DeliverySpec after all --- pkg/apis/flows/v1alpha1/sequence_types.go | 3 ++- pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/apis/flows/v1alpha1/sequence_types.go b/pkg/apis/flows/v1alpha1/sequence_types.go index 8652bbe53a8..468226729b2 100644 --- a/pkg/apis/flows/v1alpha1/sequence_types.go +++ b/pkg/apis/flows/v1alpha1/sequence_types.go @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/pkg/kmeta" @@ -86,7 +87,7 @@ type SequenceStep struct { // This includes things like retries, DLQ, etc. // Needed for Roundtripping v1alpha1 <-> v1beta1. // +optional - Delivery *eventingduckv1alpha1.DeliverySpec `json:"delivery,omitempty"` + Delivery *eventingduckv1beta1.DeliverySpec `json:"delivery,omitempty"` } type SequenceChannelStatus struct { diff --git a/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go index 569c1396c8c..6be9d56e8a7 100644 --- a/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go @@ -23,6 +23,7 @@ package v1alpha1 import ( runtime "k8s.io/apimachinery/pkg/runtime" duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + v1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" v1 "knative.dev/pkg/apis/duck/v1" ) @@ -378,7 +379,7 @@ func (in *SequenceStep) DeepCopyInto(out *SequenceStep) { in.Subscriber.DeepCopyInto(&out.Subscriber) if in.Delivery != nil { in, out := &in.Delivery, &out.Delivery - *out = new(duckv1alpha1.DeliverySpec) + *out = new(v1beta1.DeliverySpec) (*in).DeepCopyInto(*out) } return From 3e303c3111f42b2f69ed5ecc079a984dd5df4c73 Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Wed, 19 Feb 2020 20:27:47 -0500 Subject: [PATCH 03/10] [WIP] sequence and parallel conversion webhook --- cmd/webhook/main.go | 20 ++ config/core/resources/parallel.yaml | 12 +- config/core/resources/sequence.yaml | 12 +- pkg/apis/flows/register.go | 15 ++ .../flows/v1alpha1/parallel_conversion.go | 132 +++++++++++ .../v1alpha1/parallel_conversion_test.go | 223 ++++++++++++++++++ pkg/apis/flows/v1alpha1/parallel_defaults.go | 4 +- .../flows/v1alpha1/parallel_defaults_test.go | 16 +- pkg/apis/flows/v1alpha1/parallel_types.go | 5 +- .../v1alpha1/parallel_validation_test.go | 9 +- .../flows/v1alpha1/sequence_conversion.go | 120 ++++++++++ .../v1alpha1/sequence_conversion_test.go | 218 +++++++++++++++++ pkg/apis/flows/v1alpha1/sequence_defaults.go | 4 +- .../flows/v1alpha1/sequence_defaults_test.go | 22 +- pkg/apis/flows/v1alpha1/sequence_types.go | 7 +- .../v1alpha1/sequence_validation_test.go | 9 +- pkg/apis/flows/v1alpha1/test_helpers.go | 4 +- .../flows/v1alpha1/zz_generated.deepcopy.go | 10 +- pkg/apis/flows/v1beta1/parallel_conversion.go | 34 +++ .../flows/v1beta1/parallel_conversion_test.go | 34 +++ pkg/apis/flows/v1beta1/sequence_conversion.go | 34 +++ .../flows/v1beta1/sequence_conversion_test.go | 34 +++ pkg/reconciler/parallel/parallel_test.go | 4 +- pkg/reconciler/sequence/sequence_test.go | 4 +- pkg/reconciler/testing/parallel.go | 4 +- pkg/reconciler/testing/sequence.go | 4 +- test/e2e/parallel_test.go | 4 +- test/e2e/sequence_test.go | 4 +- 28 files changed, 945 insertions(+), 57 deletions(-) create mode 100644 pkg/apis/flows/v1alpha1/parallel_conversion.go create mode 100644 pkg/apis/flows/v1alpha1/parallel_conversion_test.go create mode 100644 pkg/apis/flows/v1alpha1/sequence_conversion.go create mode 100644 pkg/apis/flows/v1alpha1/sequence_conversion_test.go create mode 100644 pkg/apis/flows/v1beta1/parallel_conversion.go create mode 100644 pkg/apis/flows/v1beta1/parallel_conversion_test.go create mode 100644 pkg/apis/flows/v1beta1/sequence_conversion.go create mode 100644 pkg/apis/flows/v1beta1/sequence_conversion_test.go diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index 0256d7bb8ad..b72b112de46 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -29,7 +29,10 @@ import ( baseeventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" baseeventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + "knative.dev/eventing/pkg/apis/flows" flowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1alpha1" + baseflowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1beta1" + baseflowsv1beta1 "knative.dev/eventing/pkg/apis/flows/v1beta1" legacysourcesv1alpha1 "knative.dev/eventing/pkg/apis/legacysources/v1alpha1" "knative.dev/eventing/pkg/apis/messaging" basemessagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" @@ -208,6 +211,8 @@ func NewConversionController(ctx context.Context, cmw configmap.Watcher) *contro eventingv1beta1_ = baseeventingv1beta1.SchemeGroupVersion.Version messagingv1alpha1_ = basemessagingv1alpha1.SchemeGroupVersion.Version messagingv1beta1_ = basemessagingv1beta1.SchemeGroupVersion.Version + flowsv1alpha1_ = baseflowsv1alpha1.SchemeGroupVersion.Version + flowsv1beta1_ = baseflowsv1beta1.SchemeGroupVersion.Version ) return conversion.NewConversionController(ctx, @@ -256,6 +261,21 @@ func NewConversionController(ctx context.Context, cmw configmap.Watcher) *contro Zygotes: map[string]conversion.ConvertibleObject{ messagingv1alpha1_: &basemessagingv1alpha1.InMemoryChannel{}, messagingv1beta1_: &basemessagingv1beta1.InMemoryChannel{}, + // flows + baseflowsv1beta1.Kind("Sequence"): { + DefinitionName: flows.SequenceResource.String(), + HubVersion: flowsv1alpha1_, + Zygotes: map[string]conversion.ConvertibleObject{ + flowsv1alpha1_: &baseflowsv1alpha1.Sequence{}, + flowsv1beta1_: &baseflowsv1beta1.Sequence{}, + }, + }, + baseflowsv1beta1.Kind("Parallel"): { + DefinitionName: flows.ParallelResource.String(), + HubVersion: flowsv1alpha1_, + Zygotes: map[string]conversion.ConvertibleObject{ + flowsv1alpha1_: &baseflowsv1alpha1.Sequence{}, + flowsv1beta1_: &baseflowsv1beta1.Sequence{}, }, }, }, diff --git a/config/core/resources/parallel.yaml b/config/core/resources/parallel.yaml index c66a90f6b61..026a6364c41 100644 --- a/config/core/resources/parallel.yaml +++ b/config/core/resources/parallel.yaml @@ -21,6 +21,7 @@ metadata: duck.knative.dev/addressable: "true" spec: group: flows.knative.dev + preserveUnknownFields: false names: kind: Parallel plural: parallels @@ -33,6 +34,12 @@ spec: scope: Namespaced subresources: status: {} + conversion: + strategy: Webhook + webhookClientConfig: + service: + name: eventing-webhook + namespace: knative-eventing additionalPrinterColumns: - name: Ready type: string @@ -196,6 +203,9 @@ spec: name: type: string description: "DEPRECATED: use ref.name" + status: + type: object + x-kubernetes-preserve-unknown-fields: true - name: v1beta1 - served: false + served: true storage: false diff --git a/config/core/resources/sequence.yaml b/config/core/resources/sequence.yaml index cd64790f589..3b291eda449 100644 --- a/config/core/resources/sequence.yaml +++ b/config/core/resources/sequence.yaml @@ -21,6 +21,7 @@ metadata: duck.knative.dev/addressable: "true" spec: group: flows.knative.dev + preserveUnknownFields: false names: kind: Sequence plural: sequences @@ -33,6 +34,12 @@ spec: scope: Namespaced subresources: status: {} + conversion: + strategy: Webhook + webhookClientConfig: + service: + name: eventing-webhook + namespace: knative-eventing additionalPrinterColumns: - name: Ready type: string @@ -134,6 +141,9 @@ spec: name: type: string description: "DEPRECATED: use ref.name" + status: + type: object + x-kubernetes-preserve-unknown-fields: true - name: v1beta1 - served: false + served: true storage: false diff --git a/pkg/apis/flows/register.go b/pkg/apis/flows/register.go index d356ace39bc..b65ec231299 100644 --- a/pkg/apis/flows/register.go +++ b/pkg/apis/flows/register.go @@ -16,6 +16,21 @@ limitations under the License. package flows +import "k8s.io/apimachinery/pkg/runtime/schema" + const ( GroupName = "flows.knative.dev" ) + +var ( + // SequenceResource represents a Knative Sequence + SequenceResource = schema.GroupResource{ + Group: GroupName, + Resource: "sequences", + } + // ParallelResource represents a Knative Parallel + ParallelResource = schema.GroupResource{ + Group: GroupName, + Resource: "parallels", + } +) diff --git a/pkg/apis/flows/v1alpha1/parallel_conversion.go b/pkg/apis/flows/v1alpha1/parallel_conversion.go new file mode 100644 index 00000000000..818186a8aa5 --- /dev/null +++ b/pkg/apis/flows/v1alpha1/parallel_conversion.go @@ -0,0 +1,132 @@ +/* +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 v1alpha1 + +import ( + "context" + "fmt" + + "knative.dev/pkg/apis" + + "knative.dev/eventing/pkg/apis/flows/v1beta1" +) + +// ConvertUp implements apis.Convertible +// Converts obj from v1alpha1.Parallel into v1beta1.Parallel +func (source *Parallel) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1beta1.Parallel: + sink.ObjectMeta = source.ObjectMeta + + sink.Spec.Branches = make([]v1beta1.ParallelBranch, len(source.Spec.Branches)) + for i, b := range source.Spec.Branches { + sink.Spec.Branches[i] = v1beta1.ParallelBranch{ + Filter: b.Filter, + Subscriber: b.Subscriber, + Reply: b.Reply, + } + } + + sink.Spec.ChannelTemplate = source.Spec.ChannelTemplate + sink.Spec.Reply = source.Spec.Reply + + sink.Status.Status = source.Status.Status + sink.Status.AddressStatus = source.Status.AddressStatus + + sink.Status.IngressChannelStatus = v1beta1.ParallelChannelStatus{ + Channel: source.Status.IngressChannelStatus.Channel, + ReadyCondition: source.Status.IngressChannelStatus.ReadyCondition, + } + + if source.Status.BranchStatuses != nil { + sink.Status.BranchStatuses = make([]v1beta1.ParallelBranchStatus, len(source.Status.BranchStatuses)) + for i, b := range source.Status.BranchStatuses { + sink.Status.BranchStatuses[i] = v1beta1.ParallelBranchStatus{ + FilterSubscriptionStatus: v1beta1.ParallelSubscriptionStatus{ + Subscription: b.FilterSubscriptionStatus.Subscription, + ReadyCondition: b.FilterSubscriptionStatus.ReadyCondition, + }, + FilterChannelStatus: v1beta1.ParallelChannelStatus{ + Channel: b.FilterChannelStatus.Channel, + ReadyCondition: b.FilterChannelStatus.ReadyCondition, + }, + SubscriptionStatus: v1beta1.ParallelSubscriptionStatus{ + Subscription: b.SubscriptionStatus.Subscription, + ReadyCondition: b.SubscriptionStatus.ReadyCondition, + }, + } + } + } + + return nil + default: + return fmt.Errorf("Unknown conversion, got: %T", sink) + } +} + +// ConvertDown implements apis.Convertible +// Converts obj from v1beta1.Sequence into v1alpha1.Sequence +func (sink *Parallel) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1beta1.Parallel: + sink.ObjectMeta = source.ObjectMeta + + sink.Spec.Branches = make([]ParallelBranch, len(source.Spec.Branches)) + for i, b := range source.Spec.Branches { + sink.Spec.Branches[i] = ParallelBranch{ + Filter: b.Filter, + Subscriber: b.Subscriber, + Reply: b.Reply, + } + } + + sink.Spec.ChannelTemplate = source.Spec.ChannelTemplate + sink.Spec.Reply = source.Spec.Reply + + sink.Status.Status = source.Status.Status + sink.Status.AddressStatus = source.Status.AddressStatus + + sink.Status.IngressChannelStatus = ParallelChannelStatus{ + Channel: source.Status.IngressChannelStatus.Channel, + ReadyCondition: source.Status.IngressChannelStatus.ReadyCondition, + } + + if source.Status.BranchStatuses != nil { + sink.Status.BranchStatuses = make([]ParallelBranchStatus, len(source.Status.BranchStatuses)) + for i, b := range source.Status.BranchStatuses { + sink.Status.BranchStatuses[i] = ParallelBranchStatus{ + FilterSubscriptionStatus: ParallelSubscriptionStatus{ + Subscription: b.FilterSubscriptionStatus.Subscription, + ReadyCondition: b.FilterSubscriptionStatus.ReadyCondition, + }, + FilterChannelStatus: ParallelChannelStatus{ + Channel: b.FilterChannelStatus.Channel, + ReadyCondition: b.FilterChannelStatus.ReadyCondition, + }, + SubscriptionStatus: ParallelSubscriptionStatus{ + Subscription: b.SubscriptionStatus.Subscription, + ReadyCondition: b.SubscriptionStatus.ReadyCondition, + }, + } + } + } + + return nil + default: + return fmt.Errorf("unknown version, got: %T", source) + } +} diff --git a/pkg/apis/flows/v1alpha1/parallel_conversion_test.go b/pkg/apis/flows/v1alpha1/parallel_conversion_test.go new file mode 100644 index 00000000000..2bc552e9493 --- /dev/null +++ b/pkg/apis/flows/v1alpha1/parallel_conversion_test.go @@ -0,0 +1,223 @@ +/* +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 v1alpha1 + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/eventing/pkg/apis/flows/v1beta1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +func TestParallelConversionBadType(t *testing.T) { + good, bad := &Parallel{}, &Parallel{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertDown() = %#v, wanted error", good) + } +} + +func TestParallelRoundTrip(t *testing.T) { + // Just one for now, just adding the for loop for ease of future changes. + versions := []apis.Convertible{&v1beta1.Parallel{}} + + tests := []struct { + name string + in *Parallel + }{{ + name: "min configuration", + in: &Parallel{ + ObjectMeta: metav1.ObjectMeta{ + Name: "par-name", + Namespace: "par-ns", + Generation: 17, + }, + Spec: ParallelSpec{ + Branches: []ParallelBranch{}, + }, + }, + }, { + name: "full configuration", + in: &Parallel{ + ObjectMeta: metav1.ObjectMeta{ + Name: "par-name", + Namespace: "par-ns", + Generation: 17, + }, + Spec: ParallelSpec{ + Branches: []ParallelBranch{ + { + Filter: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "f1Kind", + Namespace: "f1Namespace", + Name: "f1Name", + APIVersion: "f1APIVersion", + }, + URI: apis.HTTP("f1.example.com")}, + + Subscriber: duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "s1Kind", + Namespace: "s1Namespace", + Name: "s1Name", + APIVersion: "s1APIVersion", + }, + URI: apis.HTTP("s1.example.com")}, + + Reply: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "reply1Kind", + Namespace: "reply1Namespace", + Name: "reply1Name", + APIVersion: "reply1APIVersion", + }, + URI: apis.HTTP("reply1.example.com"), + }, + }, + { + Filter: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "f2Kind", + Namespace: "f2Namespace", + Name: "f2Name", + APIVersion: "f2APIVersion", + }, + URI: apis.HTTP("f2.example.com")}, + + Subscriber: duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "s2Kind", + Namespace: "s2Namespace", + Name: "s2Name", + APIVersion: "s2APIVersion", + }, + URI: apis.HTTP("s2.example.com")}, + + Reply: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "reply2Kind", + Namespace: "reply2Namespace", + Name: "reply2Name", + APIVersion: "reply2APIVersion", + }, + URI: apis.HTTP("reply2.example.com"), + }, + }, + }, + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ + TypeMeta: metav1.TypeMeta{ + Kind: "channelKind", + APIVersion: "channelAPIVersion", + }, + }, + Reply: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "replyKind", + Namespace: "replyNamespace", + Name: "replyName", + APIVersion: "replyAPIVersion", + }, + URI: apis.HTTP("reply.example.com"), + }, + }, + Status: ParallelStatus{ + Status: duckv1.Status{ + ObservedGeneration: 1, + Conditions: duckv1.Conditions{{ + Type: "Ready", + Status: "True", + }}, + }, + AddressStatus: duckv1.AddressStatus{ + Address: &duckv1.Addressable{ + URL: apis.HTTP("addressstatus.example.com"), + }, + }, + IngressChannelStatus: ParallelChannelStatus{ + Channel: corev1.ObjectReference{ + Kind: "i-channel-kind", + APIVersion: "i-channel-apiversion", + Name: "i-channel-name", + Namespace: "i-channel-namespace", + }, + ReadyCondition: apis.Condition{Message: "i1-msg"}, + }, + BranchStatuses: []ParallelBranchStatus{ + { + FilterSubscriptionStatus: ParallelSubscriptionStatus{ + Subscription: corev1.ObjectReference{ + Kind: "f1-sub-kind", + APIVersion: "f1-sub-apiversion", + Name: "f1-sub-name", + Namespace: "f1-sub-namespace", + }, + ReadyCondition: apis.Condition{Message: "f1-msg"}, + }, + SubscriptionStatus: ParallelSubscriptionStatus{ + Subscription: corev1.ObjectReference{ + Kind: "s1-sub-kind", + APIVersion: "s1-sub-apiversion", + Name: "s1-sub-name", + Namespace: "s1-sub-namespace", + }, + ReadyCondition: apis.Condition{Message: "s1-msg"}, + }, + FilterChannelStatus: ParallelChannelStatus{ + Channel: corev1.ObjectReference{ + Kind: "s1-channel-kind", + APIVersion: "s1-channel-apiversion", + Name: "s1-channel-name", + Namespace: "s1-channel-namespace", + }, + ReadyCondition: apis.Condition{Message: "c1-msg"}, + }, + }, + }, + }, + }, + }} + + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := test.in.ConvertUp(context.Background(), ver); err != nil { + t.Errorf("ConvertUp() = %v", err) + } + got := &Parallel{} + if err := got.ConvertDown(context.Background(), ver); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + + if diff := cmp.Diff(test.in, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} diff --git a/pkg/apis/flows/v1alpha1/parallel_defaults.go b/pkg/apis/flows/v1alpha1/parallel_defaults.go index 1ef9a588451..98501e472fc 100644 --- a/pkg/apis/flows/v1alpha1/parallel_defaults.go +++ b/pkg/apis/flows/v1alpha1/parallel_defaults.go @@ -19,7 +19,7 @@ package v1alpha1 import ( "context" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" "knative.dev/pkg/apis" ) @@ -28,7 +28,7 @@ func (p *Parallel) SetDefaults(ctx context.Context) { if p != nil && p.Spec.ChannelTemplate == nil { // The singleton may not have been set, if so ignore it and validation will reject the // Channel. - if cd := eventingduckv1alpha1.ChannelDefaulterSingleton; cd != nil { + if cd := messagingv1beta1.ChannelDefaulterSingleton; cd != nil { channelTemplate := cd.GetDefault(p.Namespace) p.Spec.ChannelTemplate = channelTemplate } diff --git a/pkg/apis/flows/v1alpha1/parallel_defaults_test.go b/pkg/apis/flows/v1alpha1/parallel_defaults_test.go index 5c97402971c..aefcf23836c 100644 --- a/pkg/apis/flows/v1alpha1/parallel_defaults_test.go +++ b/pkg/apis/flows/v1alpha1/parallel_defaults_test.go @@ -24,14 +24,14 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/google/go-cmp/cmp" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" duckv1 "knative.dev/pkg/apis/duck/v1" ) func TestParallelSetDefaults(t *testing.T) { testCases := map[string]struct { nilChannelDefaulter bool - channelTemplate *eventingduckv1alpha1.ChannelTemplateSpec + channelTemplate *messagingv1beta1.ChannelTemplateSpec initial Parallel expected Parallel }{ @@ -113,7 +113,7 @@ func TestParallelSetDefaults(t *testing.T) { channelTemplate: defaultChannelTemplate, initial: Parallel{ Spec: ParallelSpec{ - ChannelTemplate: &eventingduckv1alpha1.ChannelTemplateSpec{ + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: v1.TypeMeta{ APIVersion: SchemeGroupVersion.String(), Kind: "OtherChannel", @@ -123,7 +123,7 @@ func TestParallelSetDefaults(t *testing.T) { }, expected: Parallel{ Spec: ParallelSpec{ - ChannelTemplate: &eventingduckv1alpha1.ChannelTemplateSpec{ + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: v1.TypeMeta{ APIVersion: SchemeGroupVersion.String(), Kind: "OtherChannel", @@ -136,10 +136,10 @@ func TestParallelSetDefaults(t *testing.T) { for n, tc := range testCases { t.Run(n, func(t *testing.T) { if !tc.nilChannelDefaulter { - eventingduckv1alpha1.ChannelDefaulterSingleton = ¶llelChannelDefaulter{ + messagingv1beta1.ChannelDefaulterSingleton = ¶llelChannelDefaulter{ channelTemplate: tc.channelTemplate, } - defer func() { eventingduckv1alpha1.ChannelDefaulterSingleton = nil }() + defer func() { messagingv1beta1.ChannelDefaulterSingleton = nil }() } tc.initial.SetDefaults(context.TODO()) if diff := cmp.Diff(tc.expected, tc.initial); diff != "" { @@ -150,9 +150,9 @@ func TestParallelSetDefaults(t *testing.T) { } type parallelChannelDefaulter struct { - channelTemplate *eventingduckv1alpha1.ChannelTemplateSpec + channelTemplate *messagingv1beta1.ChannelTemplateSpec } -func (cd *parallelChannelDefaulter) GetDefault(_ string) *eventingduckv1alpha1.ChannelTemplateSpec { +func (cd *parallelChannelDefaulter) GetDefault(_ string) *messagingv1beta1.ChannelTemplateSpec { return cd.channelTemplate } diff --git a/pkg/apis/flows/v1alpha1/parallel_types.go b/pkg/apis/flows/v1alpha1/parallel_types.go index 9da792ed075..dc00c3cc75c 100644 --- a/pkg/apis/flows/v1alpha1/parallel_types.go +++ b/pkg/apis/flows/v1alpha1/parallel_types.go @@ -21,10 +21,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/pkg/kmeta" + + messagingduckv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" ) // +genclient @@ -70,7 +71,7 @@ type ParallelSpec struct { // ChannelTemplate specifies which Channel CRD to use. If left unspecified, it is set to the default Channel CRD // for the namespace (or cluster, in case there are no defaults for the namespace). // +optional - ChannelTemplate *eventingduckv1alpha1.ChannelTemplateSpec `json:"channelTemplate"` + ChannelTemplate *messagingduckv1beta1.ChannelTemplateSpec `json:"channelTemplate"` // Reply is a Reference to where the result of a case Subscriber gets sent to // when the case does not have a Reply diff --git a/pkg/apis/flows/v1alpha1/parallel_validation_test.go b/pkg/apis/flows/v1alpha1/parallel_validation_test.go index 005d3d846d3..f9fe6ba3729 100644 --- a/pkg/apis/flows/v1alpha1/parallel_validation_test.go +++ b/pkg/apis/flows/v1alpha1/parallel_validation_test.go @@ -23,9 +23,10 @@ import ( "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - eventingduck "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" + + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" ) func TestParallelValidation(t *testing.T) { @@ -47,7 +48,7 @@ func TestParallelValidation(t *testing.T) { func TestParallelSpecValidation(t *testing.T) { subscriberURI := apis.HTTP("example.com") - validChannelTemplate := &eventingduck.ChannelTemplateSpec{ + validChannelTemplate := &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: metav1.TypeMeta{ Kind: "mykind", APIVersion: "myapiversion", @@ -89,7 +90,7 @@ func TestParallelSpecValidation(t *testing.T) { }, { name: "invalid channeltemplatespec missing APIVersion", ts: &ParallelSpec{ - ChannelTemplate: &eventingduck.ChannelTemplateSpec{ + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: metav1.TypeMeta{Kind: "mykind"}, Spec: &runtime.RawExtension{}}, Branches: []ParallelBranch{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, @@ -101,7 +102,7 @@ func TestParallelSpecValidation(t *testing.T) { }, { name: "invalid channeltemplatespec missing Kind", ts: &ParallelSpec{ - ChannelTemplate: &eventingduck.ChannelTemplateSpec{ + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: metav1.TypeMeta{APIVersion: "myapiversion"}, Spec: &runtime.RawExtension{}}, Branches: []ParallelBranch{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, diff --git a/pkg/apis/flows/v1alpha1/sequence_conversion.go b/pkg/apis/flows/v1alpha1/sequence_conversion.go new file mode 100644 index 00000000000..6d9c623861d --- /dev/null +++ b/pkg/apis/flows/v1alpha1/sequence_conversion.go @@ -0,0 +1,120 @@ +/* +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 v1alpha1 + +import ( + "context" + "fmt" + + "knative.dev/pkg/apis" + + "knative.dev/eventing/pkg/apis/flows/v1beta1" +) + +// ConvertUp implements apis.Convertible +// Converts obj from v1alpha1.Sequence into v1beta1.Sequence +func (source *Sequence) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1beta1.Sequence: + sink.ObjectMeta = source.ObjectMeta + + sink.Spec.Steps = make([]v1beta1.SequenceStep, len(source.Spec.Steps)) + for i, s := range source.Spec.Steps { + sink.Spec.Steps[i] = v1beta1.SequenceStep{ + Subscriber: s.Subscriber, + Delivery: s.Delivery, + } + } + + sink.Spec.ChannelTemplate = source.Spec.ChannelTemplate + sink.Spec.Reply = source.Spec.Reply + + sink.Status.Status = source.Status.Status + sink.Status.AddressStatus = source.Status.AddressStatus + + if source.Status.SubscriptionStatuses != nil { + sink.Status.SubscriptionStatuses = make([]v1beta1.SequenceSubscriptionStatus, len(source.Status.SubscriptionStatuses)) + for i, s := range source.Status.SubscriptionStatuses { + sink.Status.SubscriptionStatuses[i] = v1beta1.SequenceSubscriptionStatus{ + Subscription: s.Subscription, + ReadyCondition: s.ReadyCondition, + } + } + } + + if source.Status.ChannelStatuses != nil { + sink.Status.ChannelStatuses = make([]v1beta1.SequenceChannelStatus, len(source.Status.ChannelStatuses)) + for i, s := range source.Status.ChannelStatuses { + sink.Status.ChannelStatuses[i] = v1beta1.SequenceChannelStatus{ + Channel: s.Channel, + ReadyCondition: s.ReadyCondition, + } + } + } + + return nil + default: + return fmt.Errorf("Unknown conversion, got: %T", sink) + } +} + +// ConvertDown implements apis.Convertible +// Converts obj from v1beta1.Sequence into v1alpha1.Sequence +func (sink *Sequence) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1beta1.Sequence: + sink.ObjectMeta = source.ObjectMeta + + sink.Spec.Steps = make([]SequenceStep, len(source.Spec.Steps)) + for i, s := range source.Spec.Steps { + sink.Spec.Steps[i] = SequenceStep{ + Subscriber: s.Subscriber, + Delivery: s.Delivery, + } + } + sink.Spec.ChannelTemplate = source.Spec.ChannelTemplate + + sink.Spec.Reply = source.Spec.Reply + + sink.Status.Status = source.Status.Status + sink.Status.AddressStatus = source.Status.AddressStatus + + if source.Status.SubscriptionStatuses != nil { + sink.Status.SubscriptionStatuses = make([]SequenceSubscriptionStatus, len(source.Status.SubscriptionStatuses)) + for i, s := range source.Status.SubscriptionStatuses { + sink.Status.SubscriptionStatuses[i] = SequenceSubscriptionStatus{ + Subscription: s.Subscription, + ReadyCondition: s.ReadyCondition, + } + } + } + + if source.Status.ChannelStatuses != nil { + sink.Status.ChannelStatuses = make([]SequenceChannelStatus, len(source.Status.ChannelStatuses)) + for i, s := range source.Status.ChannelStatuses { + sink.Status.ChannelStatuses[i] = SequenceChannelStatus{ + Channel: s.Channel, + ReadyCondition: s.ReadyCondition, + } + } + } + + return nil + default: + return fmt.Errorf("unknown version, got: %T", source) + } +} diff --git a/pkg/apis/flows/v1alpha1/sequence_conversion_test.go b/pkg/apis/flows/v1alpha1/sequence_conversion_test.go new file mode 100644 index 00000000000..d5377e4e292 --- /dev/null +++ b/pkg/apis/flows/v1alpha1/sequence_conversion_test.go @@ -0,0 +1,218 @@ +/* +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 v1alpha1 + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + + eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" + "knative.dev/eventing/pkg/apis/flows/v1beta1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" +) + +func TestSequenceConversionBadType(t *testing.T) { + good, bad := &Sequence{}, &Sequence{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertDown() = %#v, wanted error", good) + } +} + +func TestSequenceRoundTrip(t *testing.T) { + // Just one for now, just adding the for loop for ease of future changes. + versions := []apis.Convertible{&v1beta1.Sequence{}} + + linear := eventingduckv1beta1.BackoffPolicyLinear + + tests := []struct { + name string + in *Sequence + }{{ + name: "min configuration", + in: &Sequence{ + ObjectMeta: metav1.ObjectMeta{ + Name: "seq-name", + Namespace: "seq-ns", + Generation: 17, + }, + Spec: SequenceSpec{ + Steps: []SequenceStep{}, + }, + }, + }, { + name: "full configuration", + in: &Sequence{ + ObjectMeta: metav1.ObjectMeta{ + Name: "seq-name", + Namespace: "seq-ns", + Generation: 17, + }, + Spec: SequenceSpec{ + Steps: []SequenceStep{ + { + Subscriber: duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "s1Kind", + Namespace: "s1Namespace", + Name: "s1Name", + APIVersion: "s1APIVersion", + }, + URI: apis.HTTP("s1.example.com")}, + Delivery: &eventingduckv1beta1.DeliverySpec{ + DeadLetterSink: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "dl1Kind", + Namespace: "dl1Namespace", + Name: "dl1Name", + APIVersion: "dl1APIVersion", + }, + URI: apis.HTTP("subscriber.dls1.example.com"), + }, + Retry: pointer.Int32Ptr(5), + BackoffPolicy: &linear, + BackoffDelay: pointer.StringPtr("5s"), + }, + }, + { + Subscriber: duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "s2Kind", + Namespace: "s2Namespace", + Name: "s2Name", + APIVersion: "s2APIVersion", + }, + URI: apis.HTTP("s2.example.com")}, + Delivery: &eventingduckv1beta1.DeliverySpec{ + DeadLetterSink: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "dl2Kind", + Namespace: "dl2Namespace", + Name: "dl2Name", + APIVersion: "dl2APIVersion", + }, + URI: apis.HTTP("subscriber.dls2.example.com"), + }, + Retry: pointer.Int32Ptr(7), + BackoffPolicy: &linear, + BackoffDelay: pointer.StringPtr("8s"), + }, + }, + }, + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ + TypeMeta: metav1.TypeMeta{ + Kind: "channelKind", + APIVersion: "channelAPIVersion", + }, + }, + Reply: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "replyKind", + Namespace: "replyNamespace", + Name: "replyName", + APIVersion: "replyAPIVersion", + }, + URI: apis.HTTP("reply.example.com"), + }, + }, + Status: SequenceStatus{ + Status: duckv1.Status{ + ObservedGeneration: 1, + Conditions: duckv1.Conditions{{ + Type: "Ready", + Status: "True", + }}, + }, + AddressStatus: duckv1.AddressStatus{ + Address: &duckv1.Addressable{ + URL: apis.HTTP("addressstatus.example.com"), + }, + }, + SubscriptionStatuses: []SequenceSubscriptionStatus{ + { + Subscription: corev1.ObjectReference{ + Kind: "s1-sub-kind", + APIVersion: "s1-sub-apiversion", + Name: "s1-sub-name", + Namespace: "s1-sub-namespace", + }, + ReadyCondition: apis.Condition{Message: "s1-msg"}, + }, + { + Subscription: corev1.ObjectReference{ + Kind: "s2-sub-kind", + APIVersion: "s2-sub-apiversion", + Name: "s2-sub-name", + Namespace: "s2-sub-namespace", + }, + ReadyCondition: apis.Condition{Message: "s2-msg"}, + }, + }, + ChannelStatuses: []SequenceChannelStatus{ + { + Channel: corev1.ObjectReference{ + Kind: "s1-channel-kind", + APIVersion: "s1-channel-apiversion", + Name: "s1-channel-name", + Namespace: "s1-channel-namespace", + }, + ReadyCondition: apis.Condition{Message: "s1-msg"}, + }, + { + Channel: corev1.ObjectReference{ + Kind: "s2-channel-kind", + APIVersion: "s2-channel-apiversion", + Name: "s2-channel-name", + Namespace: "s2-channel-namespace", + }, + ReadyCondition: apis.Condition{Message: "s2-msg"}, + }, + }, + }, + }, + }} + + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := test.in.ConvertUp(context.Background(), ver); err != nil { + t.Errorf("ConvertUp() = %v", err) + } + got := &Sequence{} + if err := got.ConvertDown(context.Background(), ver); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + + if diff := cmp.Diff(test.in, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} diff --git a/pkg/apis/flows/v1alpha1/sequence_defaults.go b/pkg/apis/flows/v1alpha1/sequence_defaults.go index 13dddf59fff..56d729ae214 100644 --- a/pkg/apis/flows/v1alpha1/sequence_defaults.go +++ b/pkg/apis/flows/v1alpha1/sequence_defaults.go @@ -19,7 +19,7 @@ package v1alpha1 import ( "context" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" "knative.dev/pkg/apis" ) @@ -28,7 +28,7 @@ func (s *Sequence) SetDefaults(ctx context.Context) { if s != nil && s.Spec.ChannelTemplate == nil { // The singleton may not have been set, if so ignore it and validation will reject the // Channel. - if cd := eventingduckv1alpha1.ChannelDefaulterSingleton; cd != nil { + if cd := messagingv1beta1.ChannelDefaulterSingleton; cd != nil { channelTemplate := cd.GetDefault(s.Namespace) s.Spec.ChannelTemplate = channelTemplate } diff --git a/pkg/apis/flows/v1alpha1/sequence_defaults_test.go b/pkg/apis/flows/v1alpha1/sequence_defaults_test.go index be71fa2f2c0..bedfe64137f 100644 --- a/pkg/apis/flows/v1alpha1/sequence_defaults_test.go +++ b/pkg/apis/flows/v1alpha1/sequence_defaults_test.go @@ -20,12 +20,12 @@ import ( "context" "testing" + "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/google/go-cmp/cmp" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" duckv1 "knative.dev/pkg/apis/duck/v1" + + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" ) const ( @@ -33,7 +33,7 @@ const ( ) var ( - defaultTemplate = &eventingduckv1alpha1.ChannelTemplateSpec{ + defaultTemplate = &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: v1.TypeMeta{ APIVersion: SchemeGroupVersion.String(), Kind: "InMemoryChannel", @@ -44,7 +44,7 @@ var ( func TestSequenceSetDefaults(t *testing.T) { testCases := map[string]struct { nilChannelDefaulter bool - channelTemplate *eventingduckv1alpha1.ChannelTemplateSpec + channelTemplate *messagingv1beta1.ChannelTemplateSpec initial Sequence expected Sequence }{ @@ -95,7 +95,7 @@ func TestSequenceSetDefaults(t *testing.T) { channelTemplate: defaultChannelTemplate, initial: Sequence{ Spec: SequenceSpec{ - ChannelTemplate: &eventingduckv1alpha1.ChannelTemplateSpec{ + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: v1.TypeMeta{ APIVersion: SchemeGroupVersion.String(), Kind: "OtherChannel", @@ -105,7 +105,7 @@ func TestSequenceSetDefaults(t *testing.T) { }, expected: Sequence{ Spec: SequenceSpec{ - ChannelTemplate: &eventingduckv1alpha1.ChannelTemplateSpec{ + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: v1.TypeMeta{ APIVersion: SchemeGroupVersion.String(), Kind: "OtherChannel", @@ -118,10 +118,10 @@ func TestSequenceSetDefaults(t *testing.T) { for n, tc := range testCases { t.Run(n, func(t *testing.T) { if !tc.nilChannelDefaulter { - eventingduckv1alpha1.ChannelDefaulterSingleton = &sequenceChannelDefaulter{ + messagingv1beta1.ChannelDefaulterSingleton = &sequenceChannelDefaulter{ channelTemplate: tc.channelTemplate, } - defer func() { eventingduckv1alpha1.ChannelDefaulterSingleton = nil }() + defer func() { messagingv1beta1.ChannelDefaulterSingleton = nil }() } tc.initial.SetDefaults(context.Background()) if diff := cmp.Diff(tc.expected, tc.initial); diff != "" { @@ -132,9 +132,9 @@ func TestSequenceSetDefaults(t *testing.T) { } type sequenceChannelDefaulter struct { - channelTemplate *eventingduckv1alpha1.ChannelTemplateSpec + channelTemplate *messagingv1beta1.ChannelTemplateSpec } -func (cd *sequenceChannelDefaulter) GetDefault(_ string) *eventingduckv1alpha1.ChannelTemplateSpec { +func (cd *sequenceChannelDefaulter) GetDefault(_ string) *messagingv1beta1.ChannelTemplateSpec { return cd.channelTemplate } diff --git a/pkg/apis/flows/v1alpha1/sequence_types.go b/pkg/apis/flows/v1alpha1/sequence_types.go index 468226729b2..7c3673438c8 100644 --- a/pkg/apis/flows/v1alpha1/sequence_types.go +++ b/pkg/apis/flows/v1alpha1/sequence_types.go @@ -21,11 +21,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" - eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/pkg/kmeta" + + eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" ) // +genclient @@ -72,7 +73,7 @@ type SequenceSpec struct { // ChannelTemplate specifies which Channel CRD to use. If left unspecified, it is set to the default Channel CRD // for the namespace (or cluster, in case there are no defaults for the namespace). // +optional - ChannelTemplate *eventingduckv1alpha1.ChannelTemplateSpec `json:"channelTemplate,omitempty"` + ChannelTemplate *messagingv1beta1.ChannelTemplateSpec `json:"channelTemplate,omitempty"` // Reply is a Reference to where the result of the last Subscriber gets sent to. // +optional diff --git a/pkg/apis/flows/v1alpha1/sequence_validation_test.go b/pkg/apis/flows/v1alpha1/sequence_validation_test.go index 9367d878673..b60a699491f 100644 --- a/pkg/apis/flows/v1alpha1/sequence_validation_test.go +++ b/pkg/apis/flows/v1alpha1/sequence_validation_test.go @@ -23,9 +23,10 @@ import ( "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - eventingduck "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" + + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" ) func TestSequenceValidation(t *testing.T) { @@ -68,7 +69,7 @@ func makeInvalidReply(channelName string) *duckv1.Destination { func TestSequenceSpecValidation(t *testing.T) { subscriberURI := apis.HTTP("example.com") - validChannelTemplate := &eventingduck.ChannelTemplateSpec{ + validChannelTemplate := &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: metav1.TypeMeta{ Kind: "mykind", APIVersion: "myapiversion", @@ -107,7 +108,7 @@ func TestSequenceSpecValidation(t *testing.T) { }, { name: "invalid channeltemplatespec missing APIVersion", ts: &SequenceSpec{ - ChannelTemplate: &eventingduck.ChannelTemplateSpec{TypeMeta: metav1.TypeMeta{Kind: "mykind"}, Spec: &runtime.RawExtension{}}, + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{TypeMeta: metav1.TypeMeta{Kind: "mykind"}, Spec: &runtime.RawExtension{}}, Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, }, want: func() *apis.FieldError { @@ -117,7 +118,7 @@ func TestSequenceSpecValidation(t *testing.T) { }, { name: "invalid channeltemplatespec missing Kind", ts: &SequenceSpec{ - ChannelTemplate: &eventingduck.ChannelTemplateSpec{TypeMeta: metav1.TypeMeta{APIVersion: "myapiversion"}, Spec: &runtime.RawExtension{}}, + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{TypeMeta: metav1.TypeMeta{APIVersion: "myapiversion"}, Spec: &runtime.RawExtension{}}, Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, }, want: func() *apis.FieldError { diff --git a/pkg/apis/flows/v1alpha1/test_helpers.go b/pkg/apis/flows/v1alpha1/test_helpers.go index 9cc7f48074d..4f9ffada5ab 100644 --- a/pkg/apis/flows/v1alpha1/test_helpers.go +++ b/pkg/apis/flows/v1alpha1/test_helpers.go @@ -19,12 +19,12 @@ package v1alpha1 import ( "github.com/google/go-cmp/cmp/cmpopts" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" "knative.dev/pkg/apis" ) var ( - defaultChannelTemplate = &eventingduckv1alpha1.ChannelTemplateSpec{ + defaultChannelTemplate = &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: v1.TypeMeta{ APIVersion: SchemeGroupVersion.String(), Kind: "InMemoryChannel", diff --git a/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go index 6be9d56e8a7..99b10559ddf 100644 --- a/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go @@ -22,8 +22,8 @@ package v1alpha1 import ( runtime "k8s.io/apimachinery/pkg/runtime" - duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" - v1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" + duckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" + v1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" v1 "knative.dev/pkg/apis/duck/v1" ) @@ -164,7 +164,7 @@ func (in *ParallelSpec) DeepCopyInto(out *ParallelSpec) { } if in.ChannelTemplate != nil { in, out := &in.ChannelTemplate, &out.ChannelTemplate - *out = new(duckv1alpha1.ChannelTemplateSpec) + *out = new(v1beta1.ChannelTemplateSpec) (*in).DeepCopyInto(*out) } if in.Reply != nil { @@ -320,7 +320,7 @@ func (in *SequenceSpec) DeepCopyInto(out *SequenceSpec) { } if in.ChannelTemplate != nil { in, out := &in.ChannelTemplate, &out.ChannelTemplate - *out = new(duckv1alpha1.ChannelTemplateSpec) + *out = new(v1beta1.ChannelTemplateSpec) (*in).DeepCopyInto(*out) } if in.Reply != nil { @@ -379,7 +379,7 @@ func (in *SequenceStep) DeepCopyInto(out *SequenceStep) { in.Subscriber.DeepCopyInto(&out.Subscriber) if in.Delivery != nil { in, out := &in.Delivery, &out.Delivery - *out = new(v1beta1.DeliverySpec) + *out = new(duckv1beta1.DeliverySpec) (*in).DeepCopyInto(*out) } return diff --git a/pkg/apis/flows/v1beta1/parallel_conversion.go b/pkg/apis/flows/v1beta1/parallel_conversion.go new file mode 100644 index 00000000000..3f5238e0897 --- /dev/null +++ b/pkg/apis/flows/v1beta1/parallel_conversion.go @@ -0,0 +1,34 @@ +/* +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 v1beta1 + +import ( + "context" + "fmt" + + "knative.dev/pkg/apis" +) + +// ConvertUp implements apis.Convertible +func (source *Parallel) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", sink) +} + +// ConvertDown implements apis.Convertible +func (sink *Parallel) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", source) +} diff --git a/pkg/apis/flows/v1beta1/parallel_conversion_test.go b/pkg/apis/flows/v1beta1/parallel_conversion_test.go new file mode 100644 index 00000000000..fcac77681ec --- /dev/null +++ b/pkg/apis/flows/v1beta1/parallel_conversion_test.go @@ -0,0 +1,34 @@ +/* +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 v1beta1 + +import ( + "context" + "testing" +) + +func TestParallelConversionBadType(t *testing.T) { + good, bad := &Parallel{}, &Parallel{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertDown() = %#v, wanted error", good) + } +} diff --git a/pkg/apis/flows/v1beta1/sequence_conversion.go b/pkg/apis/flows/v1beta1/sequence_conversion.go new file mode 100644 index 00000000000..189c45d7c6c --- /dev/null +++ b/pkg/apis/flows/v1beta1/sequence_conversion.go @@ -0,0 +1,34 @@ +/* +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 v1beta1 + +import ( + "context" + "fmt" + + "knative.dev/pkg/apis" +) + +// ConvertUp implements apis.Convertible +func (source *Sequence) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", sink) +} + +// ConvertDown implements apis.Convertible +func (sink *Sequence) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", source) +} diff --git a/pkg/apis/flows/v1beta1/sequence_conversion_test.go b/pkg/apis/flows/v1beta1/sequence_conversion_test.go new file mode 100644 index 00000000000..9719ca54d5b --- /dev/null +++ b/pkg/apis/flows/v1beta1/sequence_conversion_test.go @@ -0,0 +1,34 @@ +/* +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 v1beta1 + +import ( + "context" + "testing" +) + +func TestSequenceConversionBadType(t *testing.T) { + good, bad := &Sequence{}, &Sequence{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertDown() = %#v, wanted error", good) + } +} diff --git a/pkg/reconciler/parallel/parallel_test.go b/pkg/reconciler/parallel/parallel_test.go index 39c0afbc431..a435d332ef0 100644 --- a/pkg/reconciler/parallel/parallel_test.go +++ b/pkg/reconciler/parallel/parallel_test.go @@ -40,8 +40,8 @@ import ( logtesting "knative.dev/pkg/logging/testing" . "knative.dev/pkg/reconciler/testing" - eventingduck "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/eventing/pkg/apis/flows/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" "knative.dev/eventing/pkg/reconciler" "knative.dev/eventing/pkg/reconciler/parallel/resources" . "knative.dev/eventing/pkg/reconciler/testing" @@ -65,7 +65,7 @@ func init() { func TestAllBranches(t *testing.T) { pKey := testNS + "/" + parallelName - imc := &eventingduck.ChannelTemplateSpec{ + imc := &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: metav1.TypeMeta{ APIVersion: "messaging.knative.dev/v1alpha1", Kind: "inmemorychannel", diff --git a/pkg/reconciler/sequence/sequence_test.go b/pkg/reconciler/sequence/sequence_test.go index 1f07fdbad34..eea9c9376a5 100644 --- a/pkg/reconciler/sequence/sequence_test.go +++ b/pkg/reconciler/sequence/sequence_test.go @@ -40,8 +40,8 @@ import ( logtesting "knative.dev/pkg/logging/testing" . "knative.dev/pkg/reconciler/testing" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/eventing/pkg/apis/flows/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" "knative.dev/eventing/pkg/reconciler" "knative.dev/eventing/pkg/reconciler/sequence/resources" . "knative.dev/eventing/pkg/reconciler/testing" @@ -109,7 +109,7 @@ func createDestination(stepNumber int) duckv1.Destination { func TestAllCases(t *testing.T) { pKey := testNS + "/" + sequenceName - imc := &eventingduckv1alpha1.ChannelTemplateSpec{ + imc := &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: metav1.TypeMeta{ APIVersion: "messaging.knative.dev/v1alpha1", Kind: "inmemorychannel", diff --git a/pkg/reconciler/testing/parallel.go b/pkg/reconciler/testing/parallel.go index e31516d5424..3cdf77664b7 100644 --- a/pkg/reconciler/testing/parallel.go +++ b/pkg/reconciler/testing/parallel.go @@ -21,8 +21,8 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - eventingduck "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/eventing/pkg/apis/flows/v1alpha1" + messagingvbeta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" duckv1 "knative.dev/pkg/apis/duck/v1" ) @@ -66,7 +66,7 @@ func WithFlowsParallelDeleted(p *v1alpha1.Parallel) { p.ObjectMeta.SetDeletionTimestamp(&deleteTime) } -func WithFlowsParallelChannelTemplateSpec(cts *eventingduck.ChannelTemplateSpec) FlowsParallelOption { +func WithFlowsParallelChannelTemplateSpec(cts *messagingvbeta1.ChannelTemplateSpec) FlowsParallelOption { return func(p *v1alpha1.Parallel) { p.Spec.ChannelTemplate = cts } diff --git a/pkg/reconciler/testing/sequence.go b/pkg/reconciler/testing/sequence.go index 26f1108688f..ee9ae21bed4 100644 --- a/pkg/reconciler/testing/sequence.go +++ b/pkg/reconciler/testing/sequence.go @@ -21,8 +21,8 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/eventing/pkg/apis/flows/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" duckv1 "knative.dev/pkg/apis/duck/v1" ) @@ -66,7 +66,7 @@ func WithFlowsSequenceDeleted(p *v1alpha1.Sequence) { p.ObjectMeta.SetDeletionTimestamp(&deleteTime) } -func WithFlowsSequenceChannelTemplateSpec(cts *eventingduckv1alpha1.ChannelTemplateSpec) FlowsSequenceOption { +func WithFlowsSequenceChannelTemplateSpec(cts *messagingv1beta1.ChannelTemplateSpec) FlowsSequenceOption { return func(p *v1alpha1.Sequence) { p.Spec.ChannelTemplate = cts } diff --git a/test/e2e/parallel_test.go b/test/e2e/parallel_test.go index 5c27cb2f1a9..a65650fc4d6 100644 --- a/test/e2e/parallel_test.go +++ b/test/e2e/parallel_test.go @@ -29,8 +29,8 @@ import ( "knative.dev/eventing/test/lib/cloudevents" "knative.dev/eventing/test/lib/resources" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/eventing/pkg/apis/flows/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" eventingtesting "knative.dev/eventing/pkg/reconciler/testing" ) @@ -84,7 +84,7 @@ func TestFlowsParallel(t *testing.T) { } } - channelTemplate := &eventingduckv1alpha1.ChannelTemplateSpec{ + channelTemplate := &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: *(channelTypeMeta), } diff --git a/test/e2e/sequence_test.go b/test/e2e/sequence_test.go index 905341c05c6..bf7fc2588d1 100644 --- a/test/e2e/sequence_test.go +++ b/test/e2e/sequence_test.go @@ -28,8 +28,8 @@ import ( "knative.dev/eventing/test/lib/cloudevents" "knative.dev/eventing/test/lib/resources" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" "knative.dev/eventing/pkg/apis/flows/v1alpha1" + messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1" eventingtesting "knative.dev/eventing/pkg/reconciler/testing" duckv1 "knative.dev/pkg/apis/duck/v1" @@ -81,7 +81,7 @@ func TestFlowsSequence(t *testing.T) { } // create channelTemplate for the Sequence - channelTemplate := &eventingduckv1alpha1.ChannelTemplateSpec{ + channelTemplate := &messagingv1beta1.ChannelTemplateSpec{ TypeMeta: *(channelTypeMeta), } From 2e443b8d7e3d2b668112d7ee202f2bd2fab1294d Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 20 Feb 2020 16:04:11 -0500 Subject: [PATCH 04/10] add v1beta1 schema --- config/core/resources/parallel.yaml | 149 ++++++++++++++++++++++++++++ config/core/resources/sequence.yaml | 95 ++++++++++++++++++ 2 files changed, 244 insertions(+) diff --git a/config/core/resources/parallel.yaml b/config/core/resources/parallel.yaml index 026a6364c41..f0e630c34e4 100644 --- a/config/core/resources/parallel.yaml +++ b/config/core/resources/parallel.yaml @@ -209,3 +209,152 @@ spec: - name: v1beta1 served: true storage: false + schema: + openAPIV3Schema: + type: object + properties: + spec: + required: + - branches + - channelTemplate + type: object + properties: + branches: + type: array + description: "the list of filter/subscribers pairs." + items: + type: object + required: + - subscriber + properties: + filter: + type: object + description: "the destination of the filter expression that is guarding the branch." + properties: + ref: + type: object + description: "a reference to a Kubernetes object from which to retrieve the target URI." + required: + - apiVersion + - kind + - name + properties: + apiVersion: + type: string + minLength: 1 + kind: + type: string + minLength: 1 + name: + type: string + minLength: 1 + uri: + type: string + description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." + subscriber: + type: object + description: "the destination of the events if the filter passes." + properties: + ref: + type: object + description: "a reference to a Kubernetes object from which to retrieve the target URI." + required: + - apiVersion + - kind + - name + properties: + apiVersion: + type: string + minLength: 1 + kind: + type: string + minLength: 1 + name: + type: string + minLength: 1 + uri: + type: string + description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." + reply: + description: "a reference to where the result of the subscriber of this branch gets sent to. If not specified, the result is sent to the Parallel reply." + type: object + properties: + ref: + type: object + description: "a reference to a Kubernetes object from which to retrieve the target URI." + required: + - apiVersion + - kind + - name + properties: + apiVersion: + type: string + minLength: 1 + kind: + type: string + minLength: 1 + name: + type: string + minLength: 1 + uri: + type: string + description: "the target URI. If ref is provided, this must be relative URI reference." + apiVersion: + type: string + description: "DEPRECATED: use ref.apiVersion" + kind: + type: string + description: "DEPRECATED: use ref.kind" + name: + type: string + description: "DEPRECATED: use ref.name" + channelTemplate: + type: object + description: "specifies which Channel to use. If left unspecified, it is set to the default Channel for the namespace (or cluster, in case there are no defaults for the namespace)." + required: + - apiVersion + - kind + properties: + apiVersion: + type: string + minLength: 1 + kind: + type: string + minLength: 1 + spec: + type: object + reply: + type: object + properties: + ref: + type: object + description: "a reference to a Kubernetes object from which to retrieve the target URI." + required: + - apiVersion + - kind + - name + properties: + apiVersion: + type: string + minLength: 1 + kind: + type: string + minLength: 1 + name: + type: string + minLength: 1 + uri: + type: string + description: "the target URI. If ref is provided, this must be relative URI reference." + apiVersion: + type: string + description: "DEPRECATED: use ref.apiVersion" + kind: + type: string + description: "DEPRECATED: use ref.kind" + name: + type: string + description: "DEPRECATED: use ref.name" + status: + type: object + x-kubernetes-preserve-unknown-fields: true diff --git a/config/core/resources/sequence.yaml b/config/core/resources/sequence.yaml index 3b291eda449..3f39e6617e7 100644 --- a/config/core/resources/sequence.yaml +++ b/config/core/resources/sequence.yaml @@ -94,6 +94,10 @@ spec: uri: type: string description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." + delivery: + description: "Step delivery options. More information: https://knative.dev/docs/eventing/event-delivery." + type: object + x-kubernetes-preserve-unknown-fields: true channelTemplate: type: object description: "specifies which Channel to use. If left unspecified, it is set to the default Channel for the namespace (or cluster, in case there are no defaults for the namespace)." @@ -147,3 +151,94 @@ spec: - name: v1beta1 served: true storage: false + schema: + openAPIV3Schema: + type: object + properties: + spec: + required: + - steps + - channelTemplate + type: object + properties: + steps: + type: array + description: "the list of Destinations (processors / functions) that will be called in the order provided." + items: + type: object + description: "a processor / function in the Sequence." + properties: + ref: + type: object + description: "a reference to a Kubernetes object from which to retrieve the target URI." + required: + - apiVersion + - kind + - name + properties: + apiVersion: + type: string + minLength: 1 + kind: + type: string + minLength: 1 + name: + type: string + minLength: 1 + uri: + type: string + description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." + delivery: + description: "Step delivery options. More information: https://knative.dev/docs/eventing/event-delivery." + type: object + x-kubernetes-preserve-unknown-fields: true + channelTemplate: + type: object + description: "specifies which Channel to use. If left unspecified, it is set to the default Channel for the namespace (or cluster, in case there are no defaults for the namespace)." + required: + - apiVersion + - kind + properties: + apiVersion: + type: string + minLength: 1 + kind: + type: string + minLength: 1 + spec: + type: object + reply: + type: object + properties: + ref: + type: object + description: "a reference to a Kubernetes object from which to retrieve the target URI." + required: + - apiVersion + - kind + - name + properties: + apiVersion: + type: string + minLength: 1 + kind: + type: string + minLength: 1 + name: + type: string + minLength: 1 + uri: + type: string + description: "the target URI. If ref is provided, this must be relative URI reference." + apiVersion: + type: string + description: "DEPRECATED: use ref.apiVersion" + kind: + type: string + description: "DEPRECATED: use ref.kind" + name: + type: string + description: "DEPRECATED: use ref.name" + status: + type: object + x-kubernetes-preserve-unknown-fields: true From 9cf2c3282322341d1b6ce3971653704bad876701 Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Thu, 20 Feb 2020 16:26:49 -0500 Subject: [PATCH 05/10] fix schema --- config/core/resources/parallel.yaml | 9 --------- config/core/resources/sequence.yaml | 13 ------------- 2 files changed, 22 deletions(-) diff --git a/config/core/resources/parallel.yaml b/config/core/resources/parallel.yaml index f0e630c34e4..4abb33fd52d 100644 --- a/config/core/resources/parallel.yaml +++ b/config/core/resources/parallel.yaml @@ -194,15 +194,6 @@ spec: uri: type: string description: "the target URI. If ref is provided, this must be relative URI reference." - apiVersion: - type: string - description: "DEPRECATED: use ref.apiVersion" - kind: - type: string - description: "DEPRECATED: use ref.kind" - name: - type: string - description: "DEPRECATED: use ref.name" status: type: object x-kubernetes-preserve-unknown-fields: true diff --git a/config/core/resources/sequence.yaml b/config/core/resources/sequence.yaml index 3f39e6617e7..47c1cbd70a9 100644 --- a/config/core/resources/sequence.yaml +++ b/config/core/resources/sequence.yaml @@ -94,10 +94,6 @@ spec: uri: type: string description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." - delivery: - description: "Step delivery options. More information: https://knative.dev/docs/eventing/event-delivery." - type: object - x-kubernetes-preserve-unknown-fields: true channelTemplate: type: object description: "specifies which Channel to use. If left unspecified, it is set to the default Channel for the namespace (or cluster, in case there are no defaults for the namespace)." @@ -230,15 +226,6 @@ spec: uri: type: string description: "the target URI. If ref is provided, this must be relative URI reference." - apiVersion: - type: string - description: "DEPRECATED: use ref.apiVersion" - kind: - type: string - description: "DEPRECATED: use ref.kind" - name: - type: string - description: "DEPRECATED: use ref.name" status: type: object x-kubernetes-preserve-unknown-fields: true From e65556fa26e095bf57f8a9cd4d0801f33c513c65 Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Fri, 21 Feb 2020 11:57:25 -0500 Subject: [PATCH 06/10] fix json deserialization --- cmd/webhook/main.go | 19 +- config/core/resources/sequence.yaml | 177 +----------------- .../flows/v1alpha1/sequence_conversion.go | 8 +- pkg/apis/flows/v1alpha1/sequence_defaults.go | 2 +- pkg/apis/flows/v1alpha1/sequence_types.go | 2 +- .../flows/v1alpha1/sequence_validation.go | 2 +- .../flows/v1alpha1/zz_generated.deepcopy.go | 2 +- pkg/apis/flows/v1beta1/sequence_defaults.go | 2 +- pkg/apis/flows/v1beta1/sequence_types.go | 2 +- pkg/apis/flows/v1beta1/sequence_validation.go | 2 +- .../flows/v1beta1/zz_generated.deepcopy.go | 2 +- .../sequence/resources/subscription.go | 4 +- 12 files changed, 31 insertions(+), 193 deletions(-) diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index b72b112de46..b8f1eb8723b 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -31,8 +31,7 @@ import ( baseeventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" "knative.dev/eventing/pkg/apis/flows" flowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1alpha1" - baseflowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1beta1" - baseflowsv1beta1 "knative.dev/eventing/pkg/apis/flows/v1beta1" + flowsv1beta1 "knative.dev/eventing/pkg/apis/flows/v1beta1" legacysourcesv1alpha1 "knative.dev/eventing/pkg/apis/legacysources/v1alpha1" "knative.dev/eventing/pkg/apis/messaging" basemessagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" @@ -211,8 +210,8 @@ func NewConversionController(ctx context.Context, cmw configmap.Watcher) *contro eventingv1beta1_ = baseeventingv1beta1.SchemeGroupVersion.Version messagingv1alpha1_ = basemessagingv1alpha1.SchemeGroupVersion.Version messagingv1beta1_ = basemessagingv1beta1.SchemeGroupVersion.Version - flowsv1alpha1_ = baseflowsv1alpha1.SchemeGroupVersion.Version - flowsv1beta1_ = baseflowsv1beta1.SchemeGroupVersion.Version + flowsv1alpha1_ = flowsv1alpha1.SchemeGroupVersion.Version + flowsv1beta1_ = flowsv1beta1.SchemeGroupVersion.Version ) return conversion.NewConversionController(ctx, @@ -262,20 +261,20 @@ func NewConversionController(ctx context.Context, cmw configmap.Watcher) *contro messagingv1alpha1_: &basemessagingv1alpha1.InMemoryChannel{}, messagingv1beta1_: &basemessagingv1beta1.InMemoryChannel{}, // flows - baseflowsv1beta1.Kind("Sequence"): { + flowsv1beta1.Kind("Sequence"): { DefinitionName: flows.SequenceResource.String(), HubVersion: flowsv1alpha1_, Zygotes: map[string]conversion.ConvertibleObject{ - flowsv1alpha1_: &baseflowsv1alpha1.Sequence{}, - flowsv1beta1_: &baseflowsv1beta1.Sequence{}, + flowsv1alpha1_: &flowsv1alpha1.Sequence{}, + flowsv1beta1_: &flowsv1beta1.Sequence{}, }, }, - baseflowsv1beta1.Kind("Parallel"): { + flowsv1beta1.Kind("Parallel"): { DefinitionName: flows.ParallelResource.String(), HubVersion: flowsv1alpha1_, Zygotes: map[string]conversion.ConvertibleObject{ - flowsv1alpha1_: &baseflowsv1alpha1.Sequence{}, - flowsv1beta1_: &baseflowsv1beta1.Sequence{}, + flowsv1alpha1_: &flowsv1alpha1.Parallel{}, + flowsv1beta1_: &flowsv1beta1.Parallel{}, }, }, }, diff --git a/config/core/resources/sequence.yaml b/config/core/resources/sequence.yaml index 47c1cbd70a9..9d0ac8de221 100644 --- a/config/core/resources/sequence.yaml +++ b/config/core/resources/sequence.yaml @@ -22,6 +22,14 @@ metadata: spec: group: flows.knative.dev preserveUnknownFields: false + validation: + openAPIV3Schema: + type: object + # this is a work around so we don't need to flush out the + # schema for each version at this time + # + # see issue: https://github.com/knative/serving/issues/912 + x-kubernetes-preserve-unknown-fields: true names: kind: Sequence plural: sequences @@ -57,175 +65,6 @@ spec: - name: v1alpha1 served: true storage: true - schema: - openAPIV3Schema: - type: object - properties: - spec: - required: - - steps - - channelTemplate - type: object - properties: - steps: - type: array - description: "the list of Destinations (processors / functions) that will be called in the order provided." - items: - type: object - description: "a processor / function in the Sequence." - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." - channelTemplate: - type: object - description: "specifies which Channel to use. If left unspecified, it is set to the default Channel for the namespace (or cluster, in case there are no defaults for the namespace)." - required: - - apiVersion - - kind - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - spec: - type: object - reply: - type: object - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI. If ref is provided, this must be relative URI reference." - apiVersion: - type: string - description: "DEPRECATED: use ref.apiVersion" - kind: - type: string - description: "DEPRECATED: use ref.kind" - name: - type: string - description: "DEPRECATED: use ref.name" - status: - type: object - x-kubernetes-preserve-unknown-fields: true - name: v1beta1 served: true storage: false - schema: - openAPIV3Schema: - type: object - properties: - spec: - required: - - steps - - channelTemplate - type: object - properties: - steps: - type: array - description: "the list of Destinations (processors / functions) that will be called in the order provided." - items: - type: object - description: "a processor / function in the Sequence." - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." - delivery: - description: "Step delivery options. More information: https://knative.dev/docs/eventing/event-delivery." - type: object - x-kubernetes-preserve-unknown-fields: true - channelTemplate: - type: object - description: "specifies which Channel to use. If left unspecified, it is set to the default Channel for the namespace (or cluster, in case there are no defaults for the namespace)." - required: - - apiVersion - - kind - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - spec: - type: object - reply: - type: object - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI. If ref is provided, this must be relative URI reference." - status: - type: object - x-kubernetes-preserve-unknown-fields: true diff --git a/pkg/apis/flows/v1alpha1/sequence_conversion.go b/pkg/apis/flows/v1alpha1/sequence_conversion.go index 6d9c623861d..253c42c72c0 100644 --- a/pkg/apis/flows/v1alpha1/sequence_conversion.go +++ b/pkg/apis/flows/v1alpha1/sequence_conversion.go @@ -35,8 +35,8 @@ func (source *Sequence) ConvertUp(ctx context.Context, obj apis.Convertible) err sink.Spec.Steps = make([]v1beta1.SequenceStep, len(source.Spec.Steps)) for i, s := range source.Spec.Steps { sink.Spec.Steps[i] = v1beta1.SequenceStep{ - Subscriber: s.Subscriber, - Delivery: s.Delivery, + Destination: s.Destination, + Delivery: s.Delivery, } } @@ -82,8 +82,8 @@ func (sink *Sequence) ConvertDown(ctx context.Context, obj apis.Convertible) err sink.Spec.Steps = make([]SequenceStep, len(source.Spec.Steps)) for i, s := range source.Spec.Steps { sink.Spec.Steps[i] = SequenceStep{ - Subscriber: s.Subscriber, - Delivery: s.Delivery, + Destination: s.Destination, + Delivery: s.Delivery, } } sink.Spec.ChannelTemplate = source.Spec.ChannelTemplate diff --git a/pkg/apis/flows/v1alpha1/sequence_defaults.go b/pkg/apis/flows/v1alpha1/sequence_defaults.go index 56d729ae214..56d541f1879 100644 --- a/pkg/apis/flows/v1alpha1/sequence_defaults.go +++ b/pkg/apis/flows/v1alpha1/sequence_defaults.go @@ -48,7 +48,7 @@ func (ss *SequenceSpec) SetDefaults(ctx context.Context) { } func (ss *SequenceStep) SetDefaults(ctx context.Context) { - ss.Subscriber.SetDefaults(ctx) + ss.Destination.SetDefaults(ctx) // No delivery defaults. } diff --git a/pkg/apis/flows/v1alpha1/sequence_types.go b/pkg/apis/flows/v1alpha1/sequence_types.go index 7c3673438c8..0f797cf9d95 100644 --- a/pkg/apis/flows/v1alpha1/sequence_types.go +++ b/pkg/apis/flows/v1alpha1/sequence_types.go @@ -82,7 +82,7 @@ type SequenceSpec struct { type SequenceStep struct { // Subscriber receiving the step event - Subscriber duckv1.Destination `json:",inline"` + duckv1.Destination `json:",inline"` // Delivery is the delivery specification for events to the subscriber // This includes things like retries, DLQ, etc. diff --git a/pkg/apis/flows/v1alpha1/sequence_validation.go b/pkg/apis/flows/v1alpha1/sequence_validation.go index 2c8783e5e09..45ea55c07d1 100644 --- a/pkg/apis/flows/v1alpha1/sequence_validation.go +++ b/pkg/apis/flows/v1alpha1/sequence_validation.go @@ -60,7 +60,7 @@ func (ps *SequenceSpec) Validate(ctx context.Context) *apis.FieldError { } func (ss *SequenceStep) Validate(ctx context.Context) *apis.FieldError { - errs := ss.Subscriber.Validate(ctx) + errs := ss.Destination.Validate(ctx) return errs } diff --git a/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go index 99b10559ddf..401e77f8b17 100644 --- a/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/flows/v1alpha1/zz_generated.deepcopy.go @@ -376,7 +376,7 @@ func (in *SequenceStatus) DeepCopy() *SequenceStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SequenceStep) DeepCopyInto(out *SequenceStep) { *out = *in - in.Subscriber.DeepCopyInto(&out.Subscriber) + in.Destination.DeepCopyInto(&out.Destination) if in.Delivery != nil { in, out := &in.Delivery, &out.Delivery *out = new(duckv1beta1.DeliverySpec) diff --git a/pkg/apis/flows/v1beta1/sequence_defaults.go b/pkg/apis/flows/v1beta1/sequence_defaults.go index 34b7f46863e..9187cb2cbeb 100644 --- a/pkg/apis/flows/v1beta1/sequence_defaults.go +++ b/pkg/apis/flows/v1beta1/sequence_defaults.go @@ -48,7 +48,7 @@ func (ss *SequenceSpec) SetDefaults(ctx context.Context) { } func (ss *SequenceStep) SetDefaults(ctx context.Context) { - ss.Subscriber.SetDefaults(ctx) + ss.Destination.SetDefaults(ctx) // No delivery defaults. } diff --git a/pkg/apis/flows/v1beta1/sequence_types.go b/pkg/apis/flows/v1beta1/sequence_types.go index 2745467c422..75e52f193a0 100644 --- a/pkg/apis/flows/v1beta1/sequence_types.go +++ b/pkg/apis/flows/v1beta1/sequence_types.go @@ -80,7 +80,7 @@ type SequenceSpec struct { type SequenceStep struct { // Subscriber receiving the step event - Subscriber duckv1.Destination `json:",inline"` + duckv1.Destination `json:",inline"` // Delivery is the delivery specification for events to the subscriber // This includes things like retries, DLQ, etc. diff --git a/pkg/apis/flows/v1beta1/sequence_validation.go b/pkg/apis/flows/v1beta1/sequence_validation.go index c0a047e03a9..4c093029ee0 100644 --- a/pkg/apis/flows/v1beta1/sequence_validation.go +++ b/pkg/apis/flows/v1beta1/sequence_validation.go @@ -60,7 +60,7 @@ func (ps *SequenceSpec) Validate(ctx context.Context) *apis.FieldError { } func (ss *SequenceStep) Validate(ctx context.Context) *apis.FieldError { - errs := ss.Subscriber.Validate(ctx) + errs := ss.Destination.Validate(ctx) if ss.Delivery != nil { if de := ss.Delivery.Validate(ctx); de != nil { diff --git a/pkg/apis/flows/v1beta1/zz_generated.deepcopy.go b/pkg/apis/flows/v1beta1/zz_generated.deepcopy.go index 7282fc9f9c6..201996f9694 100644 --- a/pkg/apis/flows/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/flows/v1beta1/zz_generated.deepcopy.go @@ -376,7 +376,7 @@ func (in *SequenceStatus) DeepCopy() *SequenceStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SequenceStep) DeepCopyInto(out *SequenceStep) { *out = *in - in.Subscriber.DeepCopyInto(&out.Subscriber) + in.Destination.DeepCopyInto(&out.Destination) if in.Delivery != nil { in, out := &in.Delivery, &out.Delivery *out = new(duckv1beta1.DeliverySpec) diff --git a/pkg/reconciler/sequence/resources/subscription.go b/pkg/reconciler/sequence/resources/subscription.go index d46ece44f5d..884d1224931 100644 --- a/pkg/reconciler/sequence/resources/subscription.go +++ b/pkg/reconciler/sequence/resources/subscription.go @@ -53,8 +53,8 @@ func NewSubscription(stepNumber int, s *v1alpha1.Sequence) *messagingv1alpha1.Su Name: SequenceChannelName(s.Name, stepNumber), }, Subscriber: &duckv1.Destination{ - Ref: s.Spec.Steps[stepNumber].Subscriber.Ref, - URI: s.Spec.Steps[stepNumber].Subscriber.URI, + Ref: s.Spec.Steps[stepNumber].Destination.Ref, + URI: s.Spec.Steps[stepNumber].Destination.URI, }, }, } From fac97d519be4e5007768c122f510d991825d97f6 Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Fri, 21 Feb 2020 12:52:02 -0500 Subject: [PATCH 07/10] remove parallel schema --- config/core/resources/parallel.yaml | 298 +--------------------------- 1 file changed, 9 insertions(+), 289 deletions(-) diff --git a/config/core/resources/parallel.yaml b/config/core/resources/parallel.yaml index 4abb33fd52d..f3725067493 100644 --- a/config/core/resources/parallel.yaml +++ b/config/core/resources/parallel.yaml @@ -22,6 +22,14 @@ metadata: spec: group: flows.knative.dev preserveUnknownFields: false + validation: + openAPIV3Schema: + type: object + # this is a work around so we don't need to flush out the + # schema for each version at this time + # + # see issue: https://github.com/knative/serving/issues/912 + x-kubernetes-preserve-unknown-fields: true names: kind: Parallel plural: parallels @@ -57,295 +65,7 @@ spec: - name: v1alpha1 served: true storage: true - schema: - openAPIV3Schema: - type: object - properties: - spec: - required: - - branches - - channelTemplate - type: object - properties: - branches: - type: array - description: "the list of filter/subscribers pairs." - items: - type: object - required: - - subscriber - properties: - filter: - type: object - description: "the destination of the filter expression that is guarding the branch." - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." - subscriber: - type: object - description: "the destination of the events if the filter passes." - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." - reply: - description: "a reference to where the result of the subscriber of this branch gets sent to. If not specified, the result is sent to the Parallel reply." - type: object - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI. If ref is provided, this must be relative URI reference." - apiVersion: - type: string - description: "DEPRECATED: use ref.apiVersion" - kind: - type: string - description: "DEPRECATED: use ref.kind" - name: - type: string - description: "DEPRECATED: use ref.name" - channelTemplate: - type: object - description: "specifies which Channel to use. If left unspecified, it is set to the default Channel for the namespace (or cluster, in case there are no defaults for the namespace)." - required: - - apiVersion - - kind - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - spec: - type: object - reply: - type: object - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI. If ref is provided, this must be relative URI reference." - status: - type: object - x-kubernetes-preserve-unknown-fields: true - name: v1beta1 served: true storage: false - schema: - openAPIV3Schema: - type: object - properties: - spec: - required: - - branches - - channelTemplate - type: object - properties: - branches: - type: array - description: "the list of filter/subscribers pairs." - items: - type: object - required: - - subscriber - properties: - filter: - type: object - description: "the destination of the filter expression that is guarding the branch." - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." - subscriber: - type: object - description: "the destination of the events if the filter passes." - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI or, if ref is provided, a relative URI reference that will be combined with ref to produce a target URI." - reply: - description: "a reference to where the result of the subscriber of this branch gets sent to. If not specified, the result is sent to the Parallel reply." - type: object - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI. If ref is provided, this must be relative URI reference." - apiVersion: - type: string - description: "DEPRECATED: use ref.apiVersion" - kind: - type: string - description: "DEPRECATED: use ref.kind" - name: - type: string - description: "DEPRECATED: use ref.name" - channelTemplate: - type: object - description: "specifies which Channel to use. If left unspecified, it is set to the default Channel for the namespace (or cluster, in case there are no defaults for the namespace)." - required: - - apiVersion - - kind - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - spec: - type: object - reply: - type: object - properties: - ref: - type: object - description: "a reference to a Kubernetes object from which to retrieve the target URI." - required: - - apiVersion - - kind - - name - properties: - apiVersion: - type: string - minLength: 1 - kind: - type: string - minLength: 1 - name: - type: string - minLength: 1 - uri: - type: string - description: "the target URI. If ref is provided, this must be relative URI reference." - apiVersion: - type: string - description: "DEPRECATED: use ref.apiVersion" - kind: - type: string - description: "DEPRECATED: use ref.kind" - name: - type: string - description: "DEPRECATED: use ref.name" - status: - type: object - x-kubernetes-preserve-unknown-fields: true + From c3b464485799f2bcc41367c38316903c7bcdffda Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Fri, 21 Feb 2020 13:17:54 -0500 Subject: [PATCH 08/10] add v1beta1 rt tests --- .../v1alpha1/parallel_conversion_test.go | 185 +++++++++++++++++- .../v1alpha1/sequence_conversion_test.go | 181 ++++++++++++++++- .../flows/v1alpha1/sequence_defaults_test.go | 8 +- .../v1alpha1/sequence_validation_test.go | 14 +- .../flows/v1beta1/sequence_defaults_test.go | 8 +- .../in_memory_channel_conversion_test.go | 2 +- 6 files changed, 377 insertions(+), 21 deletions(-) diff --git a/pkg/apis/flows/v1alpha1/parallel_conversion_test.go b/pkg/apis/flows/v1alpha1/parallel_conversion_test.go index 2bc552e9493..c4497862bea 100644 --- a/pkg/apis/flows/v1alpha1/parallel_conversion_test.go +++ b/pkg/apis/flows/v1alpha1/parallel_conversion_test.go @@ -41,7 +41,8 @@ func TestParallelConversionBadType(t *testing.T) { } } -func TestParallelRoundTrip(t *testing.T) { +// Test v1alpha1 -> v1beta1 -> v1alpha1 +func TestParallelRoundTripV1alpha1(t *testing.T) { // Just one for now, just adding the for loop for ease of future changes. versions := []apis.Convertible{&v1beta1.Parallel{}} @@ -221,3 +222,185 @@ func TestParallelRoundTrip(t *testing.T) { } } } + +// Test v1beta1 -> v1alpha1 -> v1beta1 +func TestParallelRoundTripV1beta1(t *testing.T) { + // Just one for now, just adding the for loop for ease of future changes. + versions := []apis.Convertible{&Parallel{}} + + tests := []struct { + name string + in *v1beta1.Parallel + }{{ + name: "min configuration", + in: &v1beta1.Parallel{ + ObjectMeta: metav1.ObjectMeta{ + Name: "par-name", + Namespace: "par-ns", + Generation: 17, + }, + Spec: v1beta1.ParallelSpec{ + Branches: []v1beta1.ParallelBranch{}, + }, + }, + }, { + name: "full configuration", + in: &v1beta1.Parallel{ + ObjectMeta: metav1.ObjectMeta{ + Name: "par-name", + Namespace: "par-ns", + Generation: 17, + }, + Spec: v1beta1.ParallelSpec{ + Branches: []v1beta1.ParallelBranch{ + { + Filter: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "f1Kind", + Namespace: "f1Namespace", + Name: "f1Name", + APIVersion: "f1APIVersion", + }, + URI: apis.HTTP("f1.example.com")}, + + Subscriber: duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "s1Kind", + Namespace: "s1Namespace", + Name: "s1Name", + APIVersion: "s1APIVersion", + }, + URI: apis.HTTP("s1.example.com")}, + + Reply: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "reply1Kind", + Namespace: "reply1Namespace", + Name: "reply1Name", + APIVersion: "reply1APIVersion", + }, + URI: apis.HTTP("reply1.example.com"), + }, + }, + { + Filter: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "f2Kind", + Namespace: "f2Namespace", + Name: "f2Name", + APIVersion: "f2APIVersion", + }, + URI: apis.HTTP("f2.example.com")}, + + Subscriber: duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "s2Kind", + Namespace: "s2Namespace", + Name: "s2Name", + APIVersion: "s2APIVersion", + }, + URI: apis.HTTP("s2.example.com")}, + + Reply: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "reply2Kind", + Namespace: "reply2Namespace", + Name: "reply2Name", + APIVersion: "reply2APIVersion", + }, + URI: apis.HTTP("reply2.example.com"), + }, + }, + }, + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ + TypeMeta: metav1.TypeMeta{ + Kind: "channelKind", + APIVersion: "channelAPIVersion", + }, + }, + Reply: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "replyKind", + Namespace: "replyNamespace", + Name: "replyName", + APIVersion: "replyAPIVersion", + }, + URI: apis.HTTP("reply.example.com"), + }, + }, + Status: v1beta1.ParallelStatus{ + Status: duckv1.Status{ + ObservedGeneration: 1, + Conditions: duckv1.Conditions{{ + Type: "Ready", + Status: "True", + }}, + }, + AddressStatus: duckv1.AddressStatus{ + Address: &duckv1.Addressable{ + URL: apis.HTTP("addressstatus.example.com"), + }, + }, + IngressChannelStatus: v1beta1.ParallelChannelStatus{ + Channel: corev1.ObjectReference{ + Kind: "i-channel-kind", + APIVersion: "i-channel-apiversion", + Name: "i-channel-name", + Namespace: "i-channel-namespace", + }, + ReadyCondition: apis.Condition{Message: "i1-msg"}, + }, + BranchStatuses: []v1beta1.ParallelBranchStatus{ + { + FilterSubscriptionStatus: v1beta1.ParallelSubscriptionStatus{ + Subscription: corev1.ObjectReference{ + Kind: "f1-sub-kind", + APIVersion: "f1-sub-apiversion", + Name: "f1-sub-name", + Namespace: "f1-sub-namespace", + }, + ReadyCondition: apis.Condition{Message: "f1-msg"}, + }, + SubscriptionStatus: v1beta1.ParallelSubscriptionStatus{ + Subscription: corev1.ObjectReference{ + Kind: "s1-sub-kind", + APIVersion: "s1-sub-apiversion", + Name: "s1-sub-name", + Namespace: "s1-sub-namespace", + }, + ReadyCondition: apis.Condition{Message: "s1-msg"}, + }, + FilterChannelStatus: v1beta1.ParallelChannelStatus{ + Channel: corev1.ObjectReference{ + Kind: "s1-channel-kind", + APIVersion: "s1-channel-apiversion", + Name: "s1-channel-name", + Namespace: "s1-channel-namespace", + }, + ReadyCondition: apis.Condition{Message: "c1-msg"}, + }, + }, + }, + }, + }, + }} + + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := ver.ConvertDown(context.Background(), test.in); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + got := &v1beta1.Parallel{} + if err := ver.ConvertUp(context.Background(), got); err != nil { + t.Errorf("ConvertUp() = %v", err) + } + + if diff := cmp.Diff(test.in, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} diff --git a/pkg/apis/flows/v1alpha1/sequence_conversion_test.go b/pkg/apis/flows/v1alpha1/sequence_conversion_test.go index d5377e4e292..7c2ca7b7de9 100644 --- a/pkg/apis/flows/v1alpha1/sequence_conversion_test.go +++ b/pkg/apis/flows/v1alpha1/sequence_conversion_test.go @@ -44,8 +44,8 @@ func TestSequenceConversionBadType(t *testing.T) { } } -func TestSequenceRoundTrip(t *testing.T) { - // Just one for now, just adding the for loop for ease of future changes. +// Test v1alpha1 -> v1beta1 -> v1alpha1 +func TestSequenceRoundTripV1alpha1(t *testing.T) { versions := []apis.Convertible{&v1beta1.Sequence{}} linear := eventingduckv1beta1.BackoffPolicyLinear @@ -76,7 +76,7 @@ func TestSequenceRoundTrip(t *testing.T) { Spec: SequenceSpec{ Steps: []SequenceStep{ { - Subscriber: duckv1.Destination{ + Destination: duckv1.Destination{ Ref: &duckv1.KReference{ Kind: "s1Kind", Namespace: "s1Namespace", @@ -100,7 +100,7 @@ func TestSequenceRoundTrip(t *testing.T) { }, }, { - Subscriber: duckv1.Destination{ + Destination: duckv1.Destination{ Ref: &duckv1.KReference{ Kind: "s2Kind", Namespace: "s2Namespace", @@ -216,3 +216,176 @@ func TestSequenceRoundTrip(t *testing.T) { } } } + +// Test v1beta1 -> v1alpha1 -> v1beta1 +func TestSequenceRoundTripV1beta1(t *testing.T) { + versions := []apis.Convertible{&Sequence{}} + + linear := eventingduckv1beta1.BackoffPolicyLinear + + tests := []struct { + name string + in *v1beta1.Sequence + }{{ + name: "min configuration", + in: &v1beta1.Sequence{ + ObjectMeta: metav1.ObjectMeta{ + Name: "seq-name", + Namespace: "seq-ns", + Generation: 17, + }, + Spec: v1beta1.SequenceSpec{ + Steps: []v1beta1.SequenceStep{}, + }, + }, + }, { + name: "full configuration", + in: &v1beta1.Sequence{ + ObjectMeta: metav1.ObjectMeta{ + Name: "seq-name", + Namespace: "seq-ns", + Generation: 17, + }, + Spec: v1beta1.SequenceSpec{ + Steps: []v1beta1.SequenceStep{ + { + Destination: duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "s1Kind", + Namespace: "s1Namespace", + Name: "s1Name", + APIVersion: "s1APIVersion", + }, + URI: apis.HTTP("s1.example.com")}, + Delivery: &eventingduckv1beta1.DeliverySpec{ + DeadLetterSink: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "dl1Kind", + Namespace: "dl1Namespace", + Name: "dl1Name", + APIVersion: "dl1APIVersion", + }, + URI: apis.HTTP("subscriber.dls1.example.com"), + }, + Retry: pointer.Int32Ptr(5), + BackoffPolicy: &linear, + BackoffDelay: pointer.StringPtr("5s"), + }, + }, + { + Destination: duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "s2Kind", + Namespace: "s2Namespace", + Name: "s2Name", + APIVersion: "s2APIVersion", + }, + URI: apis.HTTP("s2.example.com")}, + Delivery: &eventingduckv1beta1.DeliverySpec{ + DeadLetterSink: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "dl2Kind", + Namespace: "dl2Namespace", + Name: "dl2Name", + APIVersion: "dl2APIVersion", + }, + URI: apis.HTTP("subscriber.dls2.example.com"), + }, + Retry: pointer.Int32Ptr(7), + BackoffPolicy: &linear, + BackoffDelay: pointer.StringPtr("8s"), + }, + }, + }, + ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{ + TypeMeta: metav1.TypeMeta{ + Kind: "channelKind", + APIVersion: "channelAPIVersion", + }, + }, + Reply: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: "replyKind", + Namespace: "replyNamespace", + Name: "replyName", + APIVersion: "replyAPIVersion", + }, + URI: apis.HTTP("reply.example.com"), + }, + }, + Status: v1beta1.SequenceStatus{ + Status: duckv1.Status{ + ObservedGeneration: 1, + Conditions: duckv1.Conditions{{ + Type: "Ready", + Status: "True", + }}, + }, + AddressStatus: duckv1.AddressStatus{ + Address: &duckv1.Addressable{ + URL: apis.HTTP("addressstatus.example.com"), + }, + }, + SubscriptionStatuses: []v1beta1.SequenceSubscriptionStatus{ + { + Subscription: corev1.ObjectReference{ + Kind: "s1-sub-kind", + APIVersion: "s1-sub-apiversion", + Name: "s1-sub-name", + Namespace: "s1-sub-namespace", + }, + ReadyCondition: apis.Condition{Message: "s1-msg"}, + }, + { + Subscription: corev1.ObjectReference{ + Kind: "s2-sub-kind", + APIVersion: "s2-sub-apiversion", + Name: "s2-sub-name", + Namespace: "s2-sub-namespace", + }, + ReadyCondition: apis.Condition{Message: "s2-msg"}, + }, + }, + ChannelStatuses: []v1beta1.SequenceChannelStatus{ + { + Channel: corev1.ObjectReference{ + Kind: "s1-channel-kind", + APIVersion: "s1-channel-apiversion", + Name: "s1-channel-name", + Namespace: "s1-channel-namespace", + }, + ReadyCondition: apis.Condition{Message: "s1-msg"}, + }, + { + Channel: corev1.ObjectReference{ + Kind: "s2-channel-kind", + APIVersion: "s2-channel-apiversion", + Name: "s2-channel-name", + Namespace: "s2-channel-namespace", + }, + ReadyCondition: apis.Condition{Message: "s2-msg"}, + }, + }, + }, + }, + }} + + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := ver.ConvertDown(context.Background(), test.in); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + got := &v1beta1.Sequence{} + if err := ver.ConvertUp(context.Background(), got); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + + if diff := cmp.Diff(test.in, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} diff --git a/pkg/apis/flows/v1alpha1/sequence_defaults_test.go b/pkg/apis/flows/v1alpha1/sequence_defaults_test.go index bedfe64137f..8c20c1ac3a2 100644 --- a/pkg/apis/flows/v1alpha1/sequence_defaults_test.go +++ b/pkg/apis/flows/v1alpha1/sequence_defaults_test.go @@ -69,8 +69,8 @@ func TestSequenceSetDefaults(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Namespace: testNS}, Spec: SequenceSpec{ Steps: []SequenceStep{ - {Subscriber: duckv1.Destination{Ref: &duckv1.KReference{Name: "first"}}}, - {Subscriber: duckv1.Destination{Ref: &duckv1.KReference{Name: "second"}}}, + {Destination: duckv1.Destination{Ref: &duckv1.KReference{Name: "first"}}}, + {Destination: duckv1.Destination{Ref: &duckv1.KReference{Name: "second"}}}, }, Reply: &duckv1.Destination{ Ref: &duckv1.KReference{Name: "reply"}, @@ -82,8 +82,8 @@ func TestSequenceSetDefaults(t *testing.T) { Spec: SequenceSpec{ ChannelTemplate: defaultChannelTemplate, Steps: []SequenceStep{ - {Subscriber: duckv1.Destination{Ref: &duckv1.KReference{Namespace: testNS, Name: "first"}}}, - {Subscriber: duckv1.Destination{Ref: &duckv1.KReference{Namespace: testNS, Name: "second"}}}, + {Destination: duckv1.Destination{Ref: &duckv1.KReference{Namespace: testNS, Name: "first"}}}, + {Destination: duckv1.Destination{Ref: &duckv1.KReference{Namespace: testNS, Name: "second"}}}, }, Reply: &duckv1.Destination{ Ref: &duckv1.KReference{Namespace: testNS, Name: "reply"}, diff --git a/pkg/apis/flows/v1alpha1/sequence_validation_test.go b/pkg/apis/flows/v1alpha1/sequence_validation_test.go index b60a699491f..7d0ded58ebe 100644 --- a/pkg/apis/flows/v1alpha1/sequence_validation_test.go +++ b/pkg/apis/flows/v1alpha1/sequence_validation_test.go @@ -99,7 +99,7 @@ func TestSequenceSpecValidation(t *testing.T) { }, { name: "missing channeltemplatespec", ts: &SequenceSpec{ - Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, + Steps: []SequenceStep{{Destination: duckv1.Destination{URI: subscriberURI}}}, }, want: func() *apis.FieldError { fe := apis.ErrMissingField("channelTemplate") @@ -109,7 +109,7 @@ func TestSequenceSpecValidation(t *testing.T) { name: "invalid channeltemplatespec missing APIVersion", ts: &SequenceSpec{ ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{TypeMeta: metav1.TypeMeta{Kind: "mykind"}, Spec: &runtime.RawExtension{}}, - Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, + Steps: []SequenceStep{{Destination: duckv1.Destination{URI: subscriberURI}}}, }, want: func() *apis.FieldError { fe := apis.ErrMissingField("channelTemplate.apiVersion") @@ -119,7 +119,7 @@ func TestSequenceSpecValidation(t *testing.T) { name: "invalid channeltemplatespec missing Kind", ts: &SequenceSpec{ ChannelTemplate: &messagingv1beta1.ChannelTemplateSpec{TypeMeta: metav1.TypeMeta{APIVersion: "myapiversion"}, Spec: &runtime.RawExtension{}}, - Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, + Steps: []SequenceStep{{Destination: duckv1.Destination{URI: subscriberURI}}}, }, want: func() *apis.FieldError { fe := apis.ErrMissingField("channelTemplate.kind") @@ -129,7 +129,7 @@ func TestSequenceSpecValidation(t *testing.T) { name: "valid sequence", ts: &SequenceSpec{ ChannelTemplate: validChannelTemplate, - Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, + Steps: []SequenceStep{{Destination: duckv1.Destination{URI: subscriberURI}}}, }, want: func() *apis.FieldError { return nil @@ -138,7 +138,7 @@ func TestSequenceSpecValidation(t *testing.T) { name: "valid sequence with valid reply", ts: &SequenceSpec{ ChannelTemplate: validChannelTemplate, - Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, + Steps: []SequenceStep{{Destination: duckv1.Destination{URI: subscriberURI}}}, Reply: makeValidReply("reply-channel"), }, want: func() *apis.FieldError { @@ -148,7 +148,7 @@ func TestSequenceSpecValidation(t *testing.T) { name: "valid sequence with invalid missing name", ts: &SequenceSpec{ ChannelTemplate: validChannelTemplate, - Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, + Steps: []SequenceStep{{Destination: duckv1.Destination{URI: subscriberURI}}}, Reply: &duckv1.Destination{ Ref: &duckv1.KReference{ Namespace: "namespace", @@ -165,7 +165,7 @@ func TestSequenceSpecValidation(t *testing.T) { name: "valid sequence with invalid reply", ts: &SequenceSpec{ ChannelTemplate: validChannelTemplate, - Steps: []SequenceStep{{Subscriber: duckv1.Destination{URI: subscriberURI}}}, + Steps: []SequenceStep{{Destination: duckv1.Destination{URI: subscriberURI}}}, Reply: makeInvalidReply("reply-channel"), }, want: func() *apis.FieldError { diff --git a/pkg/apis/flows/v1beta1/sequence_defaults_test.go b/pkg/apis/flows/v1beta1/sequence_defaults_test.go index 9d7f574533c..d9c8cbe19f8 100644 --- a/pkg/apis/flows/v1beta1/sequence_defaults_test.go +++ b/pkg/apis/flows/v1beta1/sequence_defaults_test.go @@ -69,9 +69,9 @@ func TestSequenceSetDefaults(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Namespace: testNS}, Spec: SequenceSpec{ Steps: []SequenceStep{ - {Subscriber: duckv1.Destination{ + {Destination: duckv1.Destination{ Ref: &duckv1.KReference{Name: "first"}}}, - {Subscriber: duckv1.Destination{ + {Destination: duckv1.Destination{ Ref: &duckv1.KReference{Name: "second"}}}, }, Reply: &duckv1.Destination{ @@ -84,9 +84,9 @@ func TestSequenceSetDefaults(t *testing.T) { Spec: SequenceSpec{ ChannelTemplate: defaultChannelTemplate, Steps: []SequenceStep{ - {Subscriber: duckv1.Destination{ + {Destination: duckv1.Destination{ Ref: &duckv1.KReference{Namespace: testNS, Name: "first"}}}, - {Subscriber: duckv1.Destination{ + {Destination: duckv1.Destination{ Ref: &duckv1.KReference{Namespace: testNS, Name: "second"}}}, }, Reply: &duckv1.Destination{ diff --git a/pkg/apis/messaging/v1alpha1/in_memory_channel_conversion_test.go b/pkg/apis/messaging/v1alpha1/in_memory_channel_conversion_test.go index 99fdc6b1894..a98c5d3b3b6 100644 --- a/pkg/apis/messaging/v1alpha1/in_memory_channel_conversion_test.go +++ b/pkg/apis/messaging/v1alpha1/in_memory_channel_conversion_test.go @@ -168,7 +168,7 @@ func TestInMemoryChannelConversion(t *testing.T) { } } -// Test v1alpha1 -> v1beta1 -> v1alpha1 +// Test v1beta1 -> v1alpha1 -> v1beta1 func TestInMemoryChannelConversionWithV1Beta1(t *testing.T) { // Just one for now, just adding the for loop for ease of future changes. versions := []apis.Convertible{&InMemoryChannel{}} From 145618bb65b8f06fa64bb1f055163fd105921396 Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Fri, 21 Feb 2020 13:36:43 -0500 Subject: [PATCH 09/10] fix build and unit tests --- cmd/webhook/main.go | 2 + pkg/reconciler/sequence/sequence_test.go | 72 ++++++++++++------------ 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index b8f1eb8723b..7391abbdf07 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -260,6 +260,8 @@ func NewConversionController(ctx context.Context, cmw configmap.Watcher) *contro Zygotes: map[string]conversion.ConvertibleObject{ messagingv1alpha1_: &basemessagingv1alpha1.InMemoryChannel{}, messagingv1beta1_: &basemessagingv1beta1.InMemoryChannel{}, + }, + }, // flows flowsv1beta1.Kind("Sequence"): { DefinitionName: flows.SequenceResource.String(), diff --git a/pkg/reconciler/sequence/sequence_test.go b/pkg/reconciler/sequence/sequence_test.go index eea9c9376a5..c3451b21bbb 100644 --- a/pkg/reconciler/sequence/sequence_test.go +++ b/pkg/reconciler/sequence/sequence_test.go @@ -140,7 +140,7 @@ func TestAllCases(t *testing.T) { reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithInitFlowsSequenceConditions, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(0)}}))}, + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(0)}}))}, WantErr: false, WantEvents: []string{ Eventf(corev1.EventTypeNormal, "SequenceReconciled", `Sequence reconciled: "test-namespace/test-sequence"`), @@ -150,13 +150,13 @@ func TestAllCases(t *testing.T) { resources.NewSubscription(0, reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(0)}}))), + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(0)}}))), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithInitFlowsSequenceConditions, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(0)}}), + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(0)}}), reconciletesting.WithFlowsSequenceChannelsNotReady("ChannelsNotReady", "Channels are not ready yet, or there are none"), reconciletesting.WithFlowsSequenceAddressableNotReady("emptyAddress", "addressable is nil"), reconciletesting.WithFlowsSequenceSubscriptionsNotReady("SubscriptionsNotReady", "Subscriptions are not ready yet, or there are none"), @@ -195,7 +195,7 @@ func TestAllCases(t *testing.T) { reconciletesting.WithInitFlowsSequenceConditions, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceReply(createReplyChannel(replyChannelName)), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(0)}}))}, + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(0)}}))}, WantErr: false, WantEvents: []string{ Eventf(corev1.EventTypeNormal, "SequenceReconciled", `Sequence reconciled: "test-namespace/test-sequence"`), @@ -205,13 +205,13 @@ func TestAllCases(t *testing.T) { resources.NewSubscription(0, reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceReply(createReplyChannel(replyChannelName)), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(0)}}))), + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(0)}}))), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithInitFlowsSequenceConditions, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(0)}}), + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(0)}}), reconciletesting.WithFlowsSequenceReply(createReplyChannel(replyChannelName)), reconciletesting.WithFlowsSequenceAddressableNotReady("emptyAddress", "addressable is nil"), reconciletesting.WithFlowsSequenceChannelsNotReady("ChannelsNotReady", "Channels are not ready yet, or there are none"), @@ -252,9 +252,9 @@ func TestAllCases(t *testing.T) { reconciletesting.WithFlowsSequenceGeneration(sequenceGeneration), reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, - {Subscriber: createDestination(1)}, - {Subscriber: createDestination(2)}}))}, + {Destination: createDestination(0)}, + {Destination: createDestination(1)}, + {Destination: createDestination(2)}}))}, WantErr: false, WantEvents: []string{ Eventf(corev1.EventTypeNormal, "SequenceReconciled", `Sequence reconciled: "test-namespace/test-sequence"`), @@ -267,19 +267,19 @@ func TestAllCases(t *testing.T) { reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, - {Subscriber: createDestination(1)}, - {Subscriber: createDestination(2)}}))), + {Destination: createDestination(0)}, + {Destination: createDestination(1)}, + {Destination: createDestination(2)}}))), resources.NewSubscription(1, reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, {Subscriber: createDestination(1)}, {Subscriber: createDestination(2)}}))), + {Destination: createDestination(0)}, {Destination: createDestination(1)}, {Destination: createDestination(2)}}))), resources.NewSubscription(2, reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, {Subscriber: createDestination(1)}, {Subscriber: createDestination(2)}})))}, + {Destination: createDestination(0)}, {Destination: createDestination(1)}, {Destination: createDestination(2)}})))}, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithInitFlowsSequenceConditions, @@ -287,9 +287,9 @@ func TestAllCases(t *testing.T) { reconciletesting.WithFlowsSequenceStatusObservedGeneration(sequenceGeneration), reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, - {Subscriber: createDestination(1)}, - {Subscriber: createDestination(2)}}), + {Destination: createDestination(0)}, + {Destination: createDestination(1)}, + {Destination: createDestination(2)}}), reconciletesting.WithFlowsSequenceChannelsNotReady("ChannelsNotReady", "Channels are not ready yet, or there are none"), reconciletesting.WithFlowsSequenceAddressableNotReady("emptyAddress", "addressable is nil"), reconciletesting.WithFlowsSequenceSubscriptionsNotReady("SubscriptionsNotReady", "Subscriptions are not ready yet, or there are none"), @@ -373,9 +373,9 @@ func TestAllCases(t *testing.T) { reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceReply(createReplyChannel(replyChannelName)), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, - {Subscriber: createDestination(1)}, - {Subscriber: createDestination(2)}}))}, + {Destination: createDestination(0)}, + {Destination: createDestination(1)}, + {Destination: createDestination(2)}}))}, WantErr: false, WantEvents: []string{ Eventf(corev1.EventTypeNormal, "SequenceReconciled", `Sequence reconciled: "test-namespace/test-sequence"`), @@ -388,32 +388,32 @@ func TestAllCases(t *testing.T) { reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceReply(createReplyChannel(replyChannelName)), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, - {Subscriber: createDestination(1)}, - {Subscriber: createDestination(2)}}))), + {Destination: createDestination(0)}, + {Destination: createDestination(1)}, + {Destination: createDestination(2)}}))), resources.NewSubscription(1, reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceReply(createReplyChannel(replyChannelName)), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, - {Subscriber: createDestination(1)}, - {Subscriber: createDestination(2)}}))), + {Destination: createDestination(0)}, + {Destination: createDestination(1)}, + {Destination: createDestination(2)}}))), resources.NewSubscription(2, reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceReply(createReplyChannel(replyChannelName)), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, - {Subscriber: createDestination(1)}, - {Subscriber: createDestination(2)}})))}, + {Destination: createDestination(0)}, + {Destination: createDestination(1)}, + {Destination: createDestination(2)}})))}, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithInitFlowsSequenceConditions, reconciletesting.WithFlowsSequenceReply(createReplyChannel(replyChannelName)), reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{ - {Subscriber: createDestination(0)}, - {Subscriber: createDestination(1)}, - {Subscriber: createDestination(2)}}), + {Destination: createDestination(0)}, + {Destination: createDestination(1)}, + {Destination: createDestination(2)}}), reconciletesting.WithFlowsSequenceChannelsNotReady("ChannelsNotReady", "Channels are not ready yet, or there are none"), reconciletesting.WithFlowsSequenceAddressableNotReady("emptyAddress", "addressable is nil"), reconciletesting.WithFlowsSequenceSubscriptionsNotReady("SubscriptionsNotReady", "Subscriptions are not ready yet, or there are none"), @@ -496,11 +496,11 @@ func TestAllCases(t *testing.T) { reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithInitFlowsSequenceConditions, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(1)}})), + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(1)}})), createChannel(sequenceName, 0), resources.NewSubscription(0, reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(0)}}))), + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(0)}}))), }, WantErr: false, WantEvents: []string{ @@ -512,13 +512,13 @@ func TestAllCases(t *testing.T) { WantCreates: []runtime.Object{ resources.NewSubscription(0, reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(1)}}))), + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(1)}}))), }, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: reconciletesting.NewFlowsSequence(sequenceName, testNS, reconciletesting.WithInitFlowsSequenceConditions, reconciletesting.WithFlowsSequenceChannelTemplateSpec(imc), - reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Subscriber: createDestination(1)}}), + reconciletesting.WithFlowsSequenceSteps([]v1alpha1.SequenceStep{{Destination: createDestination(1)}}), reconciletesting.WithFlowsSequenceChannelsNotReady("ChannelsNotReady", "Channels are not ready yet, or there are none"), reconciletesting.WithFlowsSequenceAddressableNotReady("emptyAddress", "addressable is nil"), reconciletesting.WithFlowsSequenceSubscriptionsNotReady("SubscriptionsNotReady", "Subscriptions are not ready yet, or there are none"), From 14c52d498227ae5f52a29d0c1d7b400b6ec008d5 Mon Sep 17 00:00:00 2001 From: Lionel Villard Date: Fri, 21 Feb 2020 14:04:23 -0500 Subject: [PATCH 10/10] fix e2e --- test/e2e/sequence_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/sequence_test.go b/test/e2e/sequence_test.go index bf7fc2588d1..1c26b65dcc5 100644 --- a/test/e2e/sequence_test.go +++ b/test/e2e/sequence_test.go @@ -73,7 +73,7 @@ func TestFlowsSequence(t *testing.T) { client.CreatePodOrFail(stepperPod, lib.WithService(podName)) // create a new step step := v1alpha1.SequenceStep{ - Subscriber: duckv1.Destination{ + Destination: duckv1.Destination{ Ref: resources.KnativeRefForService(podName, client.Namespace), }} // add the step into steps