From ecdc5e15ce77a974253cc70bdedab941d6096cf8 Mon Sep 17 00:00:00 2001 From: Muhammad Faizan Date: Mon, 20 Nov 2023 21:36:17 +0500 Subject: [PATCH 1/5] Moved api pkg from eventing-controller --- Makefile | 6 +- PROJECT | 27 +- api/eventing/v1alpha1/condition.go | 260 ++++++++ api/eventing/v1alpha1/condition_unit_test.go | 470 +++++++++++++++ api/eventing/v1alpha1/fixtures_test.go | 188 ++++++ api/eventing/v1alpha1/groupversion_info.go | 20 + .../v1alpha1/subscription_conversion.go | 320 ++++++++++ .../subscription_conversion_unit_test.go | 409 +++++++++++++ api/eventing/v1alpha1/subscription_types.go | 280 +++++++++ .../v1alpha1/subscription_types_unit_test.go | 150 +++++ api/eventing/v1alpha1/subscription_webhook.go | 13 + .../v1alpha1/zz_generated.deepcopy.go | 319 ++++++++++ api/eventing/v1alpha2/condition.go | 289 +++++++++ api/eventing/v1alpha2/condition_unit_test.go | 553 ++++++++++++++++++ api/eventing/v1alpha2/constants.go | 23 + api/eventing/v1alpha2/errors.go | 41 ++ api/eventing/v1alpha2/groupversion_info.go | 24 + api/eventing/v1alpha2/status_types.go | 97 +++ api/eventing/v1alpha2/status_types_test.go | 35 ++ api/eventing/v1alpha2/subscription_types.go | 146 +++++ .../v1alpha2/subscription_types_test.go | 68 +++ api/eventing/v1alpha2/subscription_webhook.go | 200 +++++++ .../subscription_webhook_unit_test.go | 473 +++++++++++++++ api/eventing/v1alpha2/utils.go | 29 + .../v1alpha2/zz_generated.deepcopy.go | 246 ++++++++ .../v1alpha1/eventing_types.go | 0 .../v1alpha1/eventing_types_test.go | 0 .../v1alpha1/groupversion_info.go | 0 .../v1alpha1/status.go | 0 .../v1alpha1/status_test.go | 0 .../v1alpha1/zz_generated.deepcopy.go | 2 +- cmd/main.go | 10 +- ...enting.kyma-project.io_subscriptions.yaml} | 14 +- config/crd/kustomization.yaml | 4 +- config/samples/kustomization.yaml | 2 + config/samples/subscription_v1alpha1_js.yaml | 27 + ...subscription_v1alpha2_exact_eventmesh.yaml | 12 + .../subscription_v1alpha2_standard.yaml | 12 + config/webhook/manifests.yaml | 54 ++ docs/user/02-configuration.md | 77 +-- go.mod | 1 - go.sum | 8 +- hack/e2e/cleanup/cleanup_test.go | 2 +- .../common/eventing/testsubscriptioninfo.go | 4 +- hack/e2e/common/fixtures/fixtures.go | 2 +- hack/e2e/common/k8s.go | 6 +- .../testenvironment/test_environment.go | 4 +- hack/e2e/env/env.go | 2 +- hack/e2e/setup/setup_test.go | 2 +- .../subscription/eventmesh/reconciler.go | 2 +- .../reconciler_internal_integration_test.go | 2 +- .../subscription/eventmesh/test/assertions.go | 2 +- .../test/reconciler_integration_test.go | 2 +- .../subscription/eventmesh/test/utils.go | 13 +- .../eventmesh/testwebhookauth/assertions.go | 2 +- .../reconciler_integration_test.go | 0 .../eventmesh/testwebhookauth/utils.go | 13 +- .../eventmesh/testwithory/assertions.go | 2 +- .../reconciler_integration_test.go | 2 +- .../eventmesh/testwithory/utils.go | 13 +- .../subscription/eventmesh/utils.go | 2 +- .../subscription/eventmesh/utils_test.go | 2 +- .../subscription/jetstream/errors.go | 0 .../subscription/jetstream/matchers_test.go | 2 +- .../subscription/jetstream/reconciler.go | 2 +- .../jetstream/reconciler_integration_test.go | 2 +- .../reconciler_internal_unit_test.go | 2 +- .../subscription/jetstream/test_utils_test.go | 12 +- .../subscription/jetstream/utils.go | 2 +- .../subscription/jetstream/utils_unit_test.go | 2 +- .../eventing/controller.go | 2 +- .../eventing/controller_test.go | 2 +- .../eventing/domain.go | 0 .../eventing/domain_test.go | 0 .../eventing/eventmesh.go | 2 +- .../eventing/eventmesh_test.go | 2 +- .../controller/integration_test.go | 6 +- .../controller_switching/integration_test.go | 4 +- .../controllersinglecr/integration_test.go | 2 +- .../nats_disabled/integration_test.go | 4 +- .../validation/integration_test.go | 2 +- .../without_apirule_crd/integration_test.go | 2 +- .../eventing/mocks/controller.go | 0 .../eventing/mocks/manager.go | 0 .../eventing/mocks/nats_config_handler.go | 2 +- .../eventing/nats.go | 2 +- .../eventing/nats_test.go | 4 +- .../eventing/service_instance_secret.go | 0 .../eventing/status.go | 2 +- .../eventing/unit_test.go | 4 +- .../eventing/utils.go | 2 +- .../eventing/utils_test.go | 2 +- .../eventing/webhook.go | 0 .../eventing/webhook_test.go | 0 pkg/backend/eventmesh/eventmesh.go | 2 +- .../eventmesh/eventmesh_integration_test.go | 2 +- pkg/backend/eventmesh/mocks/Backend.go | 2 +- pkg/backend/eventmesh/utils.go | 2 +- pkg/backend/eventmesh/utils_unit_test.go | 2 +- pkg/backend/jetstream/jetstream.go | 4 +- .../jetstream/jetstream_integration_test.go | 2 +- .../jetstream/jetstream_internal_unit_test.go | 2 +- pkg/backend/jetstream/mocks/Backend.go | 2 +- pkg/backend/jetstream/test_helpers.go | 2 +- pkg/backend/jetstream/types.go | 2 +- pkg/backend/jetstream/utils.go | 2 +- .../utils_internal_integration_test.go | 2 +- .../jetstream/utils_internal_unit_test.go | 2 +- pkg/backend/sink/validator.go | 2 +- pkg/backend/sink/validator_test.go | 2 +- pkg/backend/utils/eventmesh_utils.go | 2 +- pkg/backend/utils/eventmesh_utils_test.go | 2 +- pkg/backend/utils/utils.go | 2 +- pkg/env/nats_config.go | 2 +- pkg/env/nats_config_test.go | 32 +- pkg/eventing/deployment.go | 2 +- pkg/eventing/deployment_test.go | 2 +- pkg/eventing/manager.go | 4 +- pkg/eventing/manager_test.go | 6 +- pkg/eventing/mocks/manager.go | 2 +- pkg/eventing/utils.go | 4 +- pkg/eventing/utils_test.go | 2 +- pkg/k8s/client.go | 2 +- pkg/k8s/client_test.go | 2 +- pkg/k8s/mocks/client.go | 2 +- pkg/object/apirule.go | 2 +- pkg/object/apirule_test.go | 7 +- pkg/object/equality.go | 35 +- pkg/object/equality_test.go | 551 ++++++----------- .../eventmesh/eventmesh.go | 7 +- .../eventmesh/eventmesh_test.go | 2 +- pkg/subscriptionmanager/factory.go | 2 +- .../jetstream/jetstream.go | 7 +- .../jetstream/jetstream_test.go | 2 +- pkg/subscriptionmanager/mocks/ec/manager.go | 166 ------ .../mocks/manager_factory.go | 2 +- test/matchers/matchers.go | 4 +- test/utils/integration/integration.go | 6 +- test/utils/options.go | 2 +- test/utils/utils.go | 4 +- testing/matchers.go | 51 +- testing/test_helpers.go | 15 +- 142 files changed, 5184 insertions(+), 841 deletions(-) create mode 100644 api/eventing/v1alpha1/condition.go create mode 100644 api/eventing/v1alpha1/condition_unit_test.go create mode 100644 api/eventing/v1alpha1/fixtures_test.go create mode 100644 api/eventing/v1alpha1/groupversion_info.go create mode 100644 api/eventing/v1alpha1/subscription_conversion.go create mode 100644 api/eventing/v1alpha1/subscription_conversion_unit_test.go create mode 100644 api/eventing/v1alpha1/subscription_types.go create mode 100644 api/eventing/v1alpha1/subscription_types_unit_test.go create mode 100644 api/eventing/v1alpha1/subscription_webhook.go create mode 100644 api/eventing/v1alpha1/zz_generated.deepcopy.go create mode 100644 api/eventing/v1alpha2/condition.go create mode 100644 api/eventing/v1alpha2/condition_unit_test.go create mode 100644 api/eventing/v1alpha2/constants.go create mode 100644 api/eventing/v1alpha2/errors.go create mode 100644 api/eventing/v1alpha2/groupversion_info.go create mode 100644 api/eventing/v1alpha2/status_types.go create mode 100644 api/eventing/v1alpha2/status_types_test.go create mode 100644 api/eventing/v1alpha2/subscription_types.go create mode 100644 api/eventing/v1alpha2/subscription_types_test.go create mode 100644 api/eventing/v1alpha2/subscription_webhook.go create mode 100644 api/eventing/v1alpha2/subscription_webhook_unit_test.go create mode 100644 api/eventing/v1alpha2/utils.go create mode 100644 api/eventing/v1alpha2/zz_generated.deepcopy.go rename api/{operator.kyma-project.io => operator}/v1alpha1/eventing_types.go (100%) rename api/{operator.kyma-project.io => operator}/v1alpha1/eventing_types_test.go (100%) rename api/{operator.kyma-project.io => operator}/v1alpha1/groupversion_info.go (100%) rename api/{operator.kyma-project.io => operator}/v1alpha1/status.go (100%) rename api/{operator.kyma-project.io => operator}/v1alpha1/status_test.go (100%) rename api/{operator.kyma-project.io => operator}/v1alpha1/zz_generated.deepcopy.go (99%) rename config/crd/{external/subscriptions.eventing.kyma-project.io.crd.yaml => bases/eventing.kyma-project.io_subscriptions.yaml} (98%) create mode 100644 config/samples/subscription_v1alpha1_js.yaml create mode 100644 config/samples/subscription_v1alpha2_exact_eventmesh.yaml create mode 100644 config/samples/subscription_v1alpha2_standard.yaml create mode 100644 config/webhook/manifests.yaml rename internal/controller/{ => eventing}/subscription/eventmesh/reconciler.go (99%) rename internal/controller/{ => eventing}/subscription/eventmesh/reconciler_internal_integration_test.go (99%) rename internal/controller/{ => eventing}/subscription/eventmesh/test/assertions.go (95%) rename internal/controller/{ => eventing}/subscription/eventmesh/test/reconciler_integration_test.go (99%) rename internal/controller/{ => eventing}/subscription/eventmesh/test/utils.go (97%) rename internal/controller/{ => eventing}/subscription/eventmesh/testwebhookauth/assertions.go (93%) rename internal/controller/{ => eventing}/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go (100%) rename internal/controller/{ => eventing}/subscription/eventmesh/testwebhookauth/utils.go (96%) rename internal/controller/{ => eventing}/subscription/eventmesh/testwithory/assertions.go (95%) rename internal/controller/{ => eventing}/subscription/eventmesh/testwithory/reconciler_integration_test.go (99%) rename internal/controller/{ => eventing}/subscription/eventmesh/testwithory/utils.go (97%) rename internal/controller/{ => eventing}/subscription/eventmesh/utils.go (97%) rename internal/controller/{ => eventing}/subscription/eventmesh/utils_test.go (98%) rename internal/controller/{ => eventing}/subscription/jetstream/errors.go (100%) rename internal/controller/{ => eventing}/subscription/jetstream/matchers_test.go (94%) rename internal/controller/{ => eventing}/subscription/jetstream/reconciler.go (99%) rename internal/controller/{ => eventing}/subscription/jetstream/reconciler_integration_test.go (99%) rename internal/controller/{ => eventing}/subscription/jetstream/reconciler_internal_unit_test.go (99%) rename internal/controller/{ => eventing}/subscription/jetstream/test_utils_test.go (98%) rename internal/controller/{ => eventing}/subscription/jetstream/utils.go (84%) rename internal/controller/{ => eventing}/subscription/jetstream/utils_unit_test.go (95%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/controller.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/controller_test.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/domain.go (100%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/domain_test.go (100%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/eventmesh.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/eventmesh_test.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/integrationtests/controller/integration_test.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/integrationtests/controller_switching/integration_test.go (98%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/integrationtests/controllersinglecr/integration_test.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/integrationtests/nats_disabled/integration_test.go (98%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/integrationtests/validation/integration_test.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/integrationtests/without_apirule_crd/integration_test.go (98%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/mocks/controller.go (100%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/mocks/manager.go (100%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/mocks/nats_config_handler.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/nats.go (98%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/nats_test.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/service_instance_secret.go (100%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/status.go (99%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/unit_test.go (97%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/utils.go (98%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/utils_test.go (98%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/webhook.go (100%) rename internal/controller/{operator.kyma-project.io => operator}/eventing/webhook_test.go (100%) delete mode 100644 pkg/subscriptionmanager/mocks/ec/manager.go diff --git a/Makefile b/Makefile index a5836056..deda1e5a 100644 --- a/Makefile +++ b/Makefile @@ -155,13 +155,9 @@ ifndef ignore-not-found endif .PHONY: install -install: download-external-crds manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. +install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. $(KUSTOMIZE) build config/crd | kubectl apply -f - -.PHONY: download-external-crds -download-external-crds: - curl -s -L -o config/crd/external/subscriptions.eventing.kyma-project.io.crd.yaml https://raw.githubusercontent.com/kyma-project/kyma/main/installation/resources/crds/eventing/subscriptions.eventing.kyma-project.io.crd.yaml - .PHONY: uninstall uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. $(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f - diff --git a/PROJECT b/PROJECT index 71755207..172a089f 100644 --- a/PROJECT +++ b/PROJECT @@ -16,6 +16,31 @@ resources: domain: kyma-project.io group: operator kind: Eventing - path: github.com/kyma-project/eventing-manager/api/batch/v1alpha1 + path: github.com/kyma-project/eventing-manager/api/operator/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: kyma-project.io + group: eventing + kind: Subscription + path: github.com/kyma-project/eventing-manager/api/eventing/v1alpha1 + version: v1alpha1 + webhooks: + conversion: true + webhookVersion: v1 +- api: + crdVersion: v1 + namespaced: true + domain: kyma-project.io + group: eventing + kind: Subscription + path: github.com/kyma-project/eventing-manager/api/eventing/v1alpha2 + version: v1alpha2 + webhooks: + defaulting: true + validation: true + conversion: true + webhookVersion: v1 version: "3" diff --git a/api/eventing/v1alpha1/condition.go b/api/eventing/v1alpha1/condition.go new file mode 100644 index 00000000..7020c9cf --- /dev/null +++ b/api/eventing/v1alpha1/condition.go @@ -0,0 +1,260 @@ +package v1alpha1 + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type ConditionType string + +const ( + ConditionSubscribed ConditionType = "Subscribed" + ConditionSubscriptionActive ConditionType = "Subscription active" + ConditionAPIRuleStatus ConditionType = "APIRule status" + ConditionWebhookCallStatus ConditionType = "Webhook call status" + + ConditionPublisherProxyReady ConditionType = "Publisher Proxy Ready" + ConditionControllerReady ConditionType = "Subscription Controller Ready" +) + +var allSubscriptionConditions = MakeSubscriptionConditions() + +type Condition struct { + // Short description of the condition. + Type ConditionType `json:"type,omitempty"` + // Status of the condition. The value is either `True`, `False`, or `Unknown`. + Status corev1.ConditionStatus `json:"status"` + // Defines the date of the last condition status change. + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` + // Defines the reason for the condition status change. + Reason ConditionReason `json:"reason,omitempty"` + // Provides more details about the condition status change. + Message string `json:"message,omitempty"` +} + +type ConditionReason string + +const ( + // BEB Conditions. + ConditionReasonSubscriptionActive ConditionReason = "BEB Subscription active" + ConditionReasonSubscriptionNotActive ConditionReason = "BEB Subscription not active" + ConditionReasonSubscriptionDeleted ConditionReason = "BEB Subscription deleted" + ConditionReasonAPIRuleStatusReady ConditionReason = "APIRule status ready" + ConditionReasonAPIRuleStatusNotReady ConditionReason = "APIRule status not ready" + + // Common backend Conditions. + ConditionReasonSubscriptionControllerReady ConditionReason = "Subscription controller started" + ConditionReasonSubscriptionControllerNotReady ConditionReason = "Subscription controller not ready" + ConditionReasonPublisherDeploymentReady ConditionReason = "Publisher proxy deployment ready" + ConditionReasonPublisherDeploymentNotReady ConditionReason = "Publisher proxy deployment not ready" +) + +// initializeConditions sets unset conditions to Unknown. +func initializeConditions(initialConditions, currentConditions []Condition) []Condition { + givenConditions := make(map[ConditionType]Condition) + + // create map of Condition per ConditionType + for _, condition := range currentConditions { + givenConditions[condition.Type] = condition + } + + finalConditions := currentConditions + // check if every Condition is present in the current Conditions + for _, expectedCondition := range initialConditions { + if _, ok := givenConditions[expectedCondition.Type]; !ok { + // and add it if it is missing + finalConditions = append(finalConditions, expectedCondition) + } + } + return finalConditions +} + +// InitializeConditions sets unset Subscription conditions to Unknown. +func (s *SubscriptionStatus) InitializeConditions() { + initialConditions := MakeSubscriptionConditions() + s.Conditions = initializeConditions(initialConditions, s.Conditions) +} + +func (s SubscriptionStatus) IsReady() bool { + if !ContainSameConditionTypes(allSubscriptionConditions, s.Conditions) { + return false + } + + // the subscription is ready if all its conditions are evaluated to true + for _, c := range s.Conditions { + if c.Status != corev1.ConditionTrue { + return false + } + } + return true +} + +func (s SubscriptionStatus) FindCondition(conditionType ConditionType) *Condition { + for _, condition := range s.Conditions { + if conditionType == condition.Type { + return &condition + } + } + return nil +} + +// ShouldUpdateReadyStatus checks if there is a mismatch between the +// subscription Ready Status and the Ready status of all the conditions. +func (s SubscriptionStatus) ShouldUpdateReadyStatus() bool { + if !s.Ready && s.IsReady() || s.Ready && !s.IsReady() { + return true + } + return false +} + +// MakeSubscriptionConditions creates a map of all conditions which the Subscription should have. +func MakeSubscriptionConditions() []Condition { + conditions := []Condition{ + { + Type: ConditionAPIRuleStatus, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + { + Type: ConditionSubscribed, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + { + Type: ConditionSubscriptionActive, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + { + Type: ConditionWebhookCallStatus, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + } + return conditions +} + +func ContainSameConditionTypes(conditions1, conditions2 []Condition) bool { + if len(conditions1) != len(conditions2) { + return false + } + + for _, condition := range conditions1 { + if !containConditionType(conditions2, condition.Type) { + return false + } + } + + return true +} + +func containConditionType(conditions []Condition, conditionType ConditionType) bool { + for _, condition := range conditions { + if condition.Type == conditionType { + return true + } + } + + return false +} + +func MakeCondition(conditionType ConditionType, reason ConditionReason, status corev1.ConditionStatus, message string) Condition { + return Condition{ + Type: conditionType, + Status: status, + LastTransitionTime: metav1.Now(), + Reason: reason, + // TODO: https://github.com/kyma-project/kyma/issues/9770 + Message: message, + } +} + +func (s *SubscriptionStatus) IsConditionSubscribed() bool { + for _, condition := range s.Conditions { + if condition.Type == ConditionSubscribed && condition.Status == corev1.ConditionTrue { + return true + } + } + return false +} + +func (s *SubscriptionStatus) IsConditionWebhookCall() bool { + for _, condition := range s.Conditions { + if condition.Type == ConditionWebhookCallStatus && + (condition.Status == corev1.ConditionTrue || condition.Status == corev1.ConditionUnknown) { + return true + } + } + return false +} + +func (s *SubscriptionStatus) GetConditionAPIRuleStatus() corev1.ConditionStatus { + for _, condition := range s.Conditions { + if condition.Type == ConditionAPIRuleStatus { + return condition.Status + } + } + return corev1.ConditionUnknown +} + +func (s *SubscriptionStatus) SetConditionAPIRuleStatus(err error) { + reason := ConditionReasonAPIRuleStatusReady + status := corev1.ConditionTrue + message := "" + if err != nil { + reason = ConditionReasonAPIRuleStatusNotReady + status = corev1.ConditionFalse + message = err.Error() + } + + newConditions := []Condition{MakeCondition(ConditionAPIRuleStatus, reason, status, message)} + for _, condition := range s.Conditions { + if condition.Type == ConditionAPIRuleStatus { + continue + } + newConditions = append(newConditions, condition) + } + s.Conditions = newConditions +} + +func CreateMessageForConditionReasonSubscriptionCreated(bebName string) string { + return fmt.Sprintf("BEB-subscription-name=%s", bebName) +} + +// ConditionsEquals checks if two list of conditions are equal. +func ConditionsEquals(existing, expected []Condition) bool { + // not equal if length is different + if len(existing) != len(expected) { + return false + } + + // compile map of Conditions per ConditionType + existingMap := make(map[ConditionType]Condition, len(existing)) + for _, value := range existing { + existingMap[value.Type] = value + } + + for _, value := range expected { + if !ConditionEquals(existingMap[value.Type], value) { + return false + } + } + + return true +} + +// ConditionEquals checks if two conditions are equal. +func ConditionEquals(existing, expected Condition) bool { + isTypeEqual := existing.Type == expected.Type + isStatusEqual := existing.Status == expected.Status + isReasonEqual := existing.Reason == expected.Reason + isMessageEqual := existing.Message == expected.Message + + if !isStatusEqual || !isReasonEqual || !isMessageEqual || !isTypeEqual { + return false + } + + return true +} diff --git a/api/eventing/v1alpha1/condition_unit_test.go b/api/eventing/v1alpha1/condition_unit_test.go new file mode 100644 index 00000000..689e66c0 --- /dev/null +++ b/api/eventing/v1alpha1/condition_unit_test.go @@ -0,0 +1,470 @@ +package v1alpha1_test + +import ( + "reflect" + "testing" + "time" + + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" +) + +func Test_InitializeSubscriptionConditions(t *testing.T) { + var tests = []struct { + name string + givenConditions []v1alpha1.Condition + }{ + { + name: "Conditions empty", + givenConditions: v1alpha1.MakeSubscriptionConditions(), + }, + { + name: "Conditions partially initialized", + givenConditions: []v1alpha1.Condition{ + { + Type: v1alpha1.ConditionSubscribed, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // given + g := NewGomegaWithT(t) + s := v1alpha1.SubscriptionStatus{} + s.Conditions = tt.givenConditions + wantConditionTypes := []v1alpha1.ConditionType{ + v1alpha1.ConditionSubscribed, + v1alpha1.ConditionSubscriptionActive, + v1alpha1.ConditionAPIRuleStatus, + v1alpha1.ConditionWebhookCallStatus, + } + + // when + s.InitializeConditions() + + // then + g.Expect(s.Conditions).To(HaveLen(len(wantConditionTypes))) + foundConditionTypes := make([]v1alpha1.ConditionType, 0) + for _, condition := range s.Conditions { + g.Expect(condition.Status).To(BeEquivalentTo(corev1.ConditionUnknown)) + foundConditionTypes = append(foundConditionTypes, condition.Type) + } + g.Expect(wantConditionTypes).To(ConsistOf(foundConditionTypes)) + }) + } +} + +func Test_IsReady(t *testing.T) { + testCases := []struct { + name string + givenConditions []v1alpha1.Condition + wantReadyStatus bool + }{ + { + name: "should not be ready if conditions are nil", + givenConditions: nil, + wantReadyStatus: false, + }, + { + name: "should not be ready if conditions are empty", + givenConditions: []v1alpha1.Condition{{}}, + wantReadyStatus: false, + }, + { + name: "should not be ready if only ConditionSubscribed is available and true", + givenConditions: []v1alpha1.Condition{{Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}}, + wantReadyStatus: false, + }, + { + name: "should not be ready if only ConditionSubscriptionActive is available and true", + givenConditions: []v1alpha1.Condition{{ + Type: v1alpha1.ConditionSubscriptionActive, + Status: corev1.ConditionTrue, + }}, + wantReadyStatus: false, + }, + { + name: "should not be ready if only ConditionAPIRuleStatus is available and true", + givenConditions: []v1alpha1.Condition{{ + Type: v1alpha1.ConditionAPIRuleStatus, + Status: corev1.ConditionTrue, + }}, + wantReadyStatus: false, + }, + { + name: "should not be ready if all conditions are unknown", + givenConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionUnknown}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionUnknown}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionUnknown}, + }, + wantReadyStatus: false, + }, + { + name: "should not be ready if all conditions are false", + givenConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionFalse}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionFalse}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionFalse}, + }, + wantReadyStatus: false, + }, + { + name: "should be ready if all conditions are true", + givenConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionWebhookCallStatus, Status: corev1.ConditionTrue}, + }, + wantReadyStatus: true, + }, + } + + status := v1alpha1.SubscriptionStatus{} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + status.Conditions = tc.givenConditions + if gotReadyStatus := status.IsReady(); tc.wantReadyStatus != gotReadyStatus { + t.Errorf("Subscription status is not valid, want: %v but got: %v", tc.wantReadyStatus, gotReadyStatus) + } + }) + } +} + +func Test_FindCondition(t *testing.T) { + currentTime := metav1.NewTime(time.Now()) + + testCases := []struct { + name string + givenConditions []v1alpha1.Condition + findConditionType v1alpha1.ConditionType + wantCondition *v1alpha1.Condition + }{ + { + name: "should be able to find the present condition", + givenConditions: []v1alpha1.Condition{ + { + Type: v1alpha1.ConditionSubscribed, + Status: corev1.ConditionTrue, + LastTransitionTime: currentTime, + }, { + Type: v1alpha1.ConditionSubscriptionActive, + Status: corev1.ConditionTrue, + LastTransitionTime: currentTime, + }, { + Type: v1alpha1.ConditionAPIRuleStatus, + Status: corev1.ConditionTrue, + LastTransitionTime: currentTime, + }, { + Type: v1alpha1.ConditionWebhookCallStatus, + Status: corev1.ConditionTrue, + LastTransitionTime: currentTime, + }, + }, + findConditionType: v1alpha1.ConditionSubscriptionActive, + wantCondition: &v1alpha1.Condition{ + Type: v1alpha1.ConditionSubscriptionActive, + Status: corev1.ConditionTrue, + LastTransitionTime: currentTime, + }, + }, + { + name: "should not be able to find the non-present condition", + givenConditions: []v1alpha1.Condition{{ + Type: v1alpha1.ConditionSubscribed, + Status: corev1.ConditionTrue, + LastTransitionTime: currentTime, + }, { + Type: v1alpha1.ConditionAPIRuleStatus, + Status: corev1.ConditionTrue, + LastTransitionTime: currentTime, + }, { + Type: v1alpha1.ConditionWebhookCallStatus, + Status: corev1.ConditionTrue, + LastTransitionTime: currentTime, + }}, + findConditionType: v1alpha1.ConditionSubscriptionActive, + wantCondition: nil, + }, + } + + status := v1alpha1.SubscriptionStatus{} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + status.Conditions = tc.givenConditions + gotCondition := status.FindCondition(tc.findConditionType) + + if !reflect.DeepEqual(tc.wantCondition, gotCondition) { + t.Errorf("Subscription FindCondition failed, want: %v but got: %v", tc.wantCondition, gotCondition) + } + }) + } +} + +func Test_ShouldUpdateReadyStatus(t *testing.T) { + testCases := []struct { + name string + subscriptionReady bool + subscriptionConditions []v1alpha1.Condition + wantStatus bool + }{ + { + name: "should not update if the subscription is ready and the conditions are ready", + subscriptionReady: true, + subscriptionConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionWebhookCallStatus, Status: corev1.ConditionTrue}, + }, + wantStatus: false, + }, + { + name: "should not update if the subscription is not ready and the conditions are not ready", + subscriptionReady: false, + subscriptionConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionFalse}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionFalse}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionFalse}, + {Type: v1alpha1.ConditionWebhookCallStatus, Status: corev1.ConditionFalse}, + }, + wantStatus: false, + }, + { + name: "should update if the subscription is not ready and the conditions are ready", + subscriptionReady: false, + subscriptionConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionWebhookCallStatus, Status: corev1.ConditionTrue}, + }, + wantStatus: true, + }, + { + name: "should update if the subscription is ready and the conditions are not ready", + subscriptionReady: true, + subscriptionConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionFalse}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionFalse}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionFalse}, + {Type: v1alpha1.ConditionWebhookCallStatus, Status: corev1.ConditionFalse}, + }, + wantStatus: true, + }, + { + name: "should update if the subscription is ready and some of the conditions are missing", + subscriptionReady: true, + subscriptionConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionUnknown}, + }, + wantStatus: true, + }, + { + name: "should not update if the subscription is not ready and some of the conditions are missing", + subscriptionReady: false, + subscriptionConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionUnknown}, + }, + wantStatus: false, + }, + { + name: "should update if the subscription is ready and the status of the conditions are unknown", + subscriptionReady: true, + subscriptionConditions: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionUnknown}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionUnknown}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionUnknown}, + {Type: v1alpha1.ConditionWebhookCallStatus, Status: corev1.ConditionUnknown}, + }, + wantStatus: true, + }, + } + + status := v1alpha1.SubscriptionStatus{} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + status.Conditions = tc.subscriptionConditions + status.Ready = tc.subscriptionReady + if gotStatus := status.ShouldUpdateReadyStatus(); tc.wantStatus != gotStatus { + t.Errorf("ShouldUpdateReadyStatus is not valid, want: %v but got: %v", tc.wantStatus, gotStatus) + } + }) + } +} + +func Test_conditionsEquals(t *testing.T) { + testCases := []struct { + name string + conditionsSet1 []v1alpha1.Condition + conditionsSet2 []v1alpha1.Condition + wantEqualStatus bool + }{ + { + name: "should not be equal if the number of conditions are not equal", + conditionsSet1: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha1.Condition{}, + wantEqualStatus: false, + }, + { + name: "should be equal if the conditions are the same", + conditionsSet1: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + wantEqualStatus: true, + }, + { + name: "should not be equal if the condition types are different", + conditionsSet1: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionWebhookCallStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionSubscriptionActive, Status: corev1.ConditionTrue}, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the condition types are the same but the status is different", + conditionsSet1: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionFalse}, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the condition types are different but the status is the same", + conditionsSet1: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionFalse}, + }, + conditionsSet2: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the condition types are different and an empty key is referenced", + conditionsSet1: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha1.Condition{ + {Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha1.ConditionControllerReady, Status: corev1.ConditionTrue}, + }, + wantEqualStatus: false, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + want := tc.wantEqualStatus + actual := v1alpha1.ConditionsEquals(tc.conditionsSet1, tc.conditionsSet2) + if actual != want { + t.Errorf("The list of conditions are not equal, want: %v but got: %v", want, actual) + } + }) + } +} + +func Test_conditionEquals(t *testing.T) { + testCases := []struct { + name string + condition1 v1alpha1.Condition + condition2 v1alpha1.Condition + wantEqualStatus bool + }{ + { + name: "should not be equal if the types are the same but the status is different", + condition1: v1alpha1.Condition{ + Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue, + }, + + condition2: v1alpha1.Condition{ + Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionUnknown, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the types are different but the status is the same", + condition1: v1alpha1.Condition{ + Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue, + }, + + condition2: v1alpha1.Condition{ + Type: v1alpha1.ConditionAPIRuleStatus, Status: corev1.ConditionTrue, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the message fields are different", + condition1: v1alpha1.Condition{ + Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue, Message: "", + }, + + condition2: v1alpha1.Condition{ + Type: v1alpha1.ConditionSubscribed, Status: corev1.ConditionTrue, Message: "some message", + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the reason fields are different", + condition1: v1alpha1.Condition{ + Type: v1alpha1.ConditionSubscribed, + Status: corev1.ConditionTrue, + Reason: v1alpha1.ConditionReasonSubscriptionDeleted, + }, + + condition2: v1alpha1.Condition{ + Type: v1alpha1.ConditionSubscribed, + Status: corev1.ConditionTrue, + Reason: v1alpha1.ConditionReasonSubscriptionActive, + }, + wantEqualStatus: false, + }, + { + name: "should be equal if all the fields are the same", + condition1: v1alpha1.Condition{ + Type: v1alpha1.ConditionAPIRuleStatus, + Status: corev1.ConditionFalse, + Reason: v1alpha1.ConditionReasonAPIRuleStatusNotReady, + Message: "API Rule is not ready", + }, + condition2: v1alpha1.Condition{ + Type: v1alpha1.ConditionAPIRuleStatus, + Status: corev1.ConditionFalse, + Reason: v1alpha1.ConditionReasonAPIRuleStatusNotReady, + Message: "API Rule is not ready", + }, + wantEqualStatus: true, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + want := tc.wantEqualStatus + actual := v1alpha1.ConditionEquals(tc.condition1, tc.condition2) + if want != actual { + t.Errorf("The conditions are not equal, want: %v but got: %v", want, actual) + } + }) + } +} diff --git a/api/eventing/v1alpha1/fixtures_test.go b/api/eventing/v1alpha1/fixtures_test.go new file mode 100644 index 00000000..a974c298 --- /dev/null +++ b/api/eventing/v1alpha1/fixtures_test.go @@ -0,0 +1,188 @@ +package v1alpha1_test + +import ( + "fmt" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" + "github.com/kyma-project/eventing-manager/pkg/utils" + eventingtesting "github.com/kyma-project/eventing-manager/testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" +) + +const ( + eventSource = "source" + orderCreatedEventType = "prefix." + "noapp." + "order.created.v1" + orderUpdatedEventType = "prefix." + "app." + "order.updated.v1" + orderDeletedEventType = "prefix." + "noapp." + "order.deleted.v1" + orderDeletedEventTypeNonClean = "prefix." + "noapp." + "order.deleted_&.v1" + orderProcessedEventType = "prefix." + "noapp." + "order.processed.v1" +) + +const ( + defaultName = "test" + defaultNamespace = "test-namespace" + defaultSink = "https://svc2.test.local" + defaultID = "id" + defaultMaxInFlight = 10 + defaultStatusReady = true +) + +var ( + v2DefaultConditions = []v1alpha2.Condition{ + { + Type: v1alpha2.ConditionSubscriptionActive, + Status: "true", + }, + { + Type: v1alpha2.ConditionSubscribed, + Status: "false", + }} +) + +func newDefaultSubscription(opts ...eventingtesting.SubscriptionV1alpha1Opt) *v1alpha1.Subscription { + var defaultConditions []v1alpha1.Condition + for _, condition := range v2DefaultConditions { + defaultConditions = append(defaultConditions, v1alpha1.ConditionV2ToV1(condition)) + } + newSub := &v1alpha1.Subscription{ + TypeMeta: metav1.TypeMeta{ + Kind: "Subscription", + APIVersion: "eventing.kyma-project.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: defaultName, + Namespace: defaultNamespace, + }, + Spec: v1alpha1.SubscriptionSpec{ + Sink: defaultSink, + ID: defaultID, + Config: &v1alpha1.SubscriptionConfig{MaxInFlightMessages: defaultMaxInFlight}, + }, + Status: v1alpha1.SubscriptionStatus{ + Conditions: defaultConditions, + Ready: defaultStatusReady, + Config: &v1alpha1.SubscriptionConfig{MaxInFlightMessages: defaultMaxInFlight}, + }, + } + for _, o := range opts { + o(newSub) + } + + // remove nats specific field in eventmesh case + if newSub.Status.EmsSubscriptionStatus != nil { + newSub.Spec.Config = nil + newSub.Status.Config = nil + } + + return newSub +} + +// extend the v1 Subscription helpers with Status fields + +func v1WithWebhookAuthForBEB() eventingtesting.SubscriptionV1alpha1Opt { + return func(s *v1alpha1.Subscription) { + s.Spec.Protocol = "BEB" + s.Spec.ProtocolSettings = &v1alpha1.ProtocolSettings{ + ContentMode: func() *string { + contentMode := v1alpha1.ProtocolSettingsContentModeBinary + return &contentMode + }(), + Qos: func() *string { + qos := "AT_LEAST_ONCE" + return &qos + }(), + ExemptHandshake: utils.BoolPtr(true), + WebhookAuth: &v1alpha1.WebhookAuth{ + Type: "oauth2", + GrantType: "client_credentials", + ClientID: "xxx", + ClientSecret: "xxx", + TokenURL: "https://oauth2.xxx.com/oauth2/token", + Scope: []string{"guid-identifier", "root"}, + }, + } + } +} + +func v1WithBEBStatusFields() eventingtesting.SubscriptionV1alpha1Opt { + return func(s *v1alpha1.Subscription) { + s.Status.Ev2hash = 123 + s.Status.ExternalSink = "testlink.com" + s.Status.FailedActivation = "123156464672" + s.Status.APIRuleName = "APIRule" + s.Status.EmsSubscriptionStatus = &v1alpha1.EmsSubscriptionStatus{ + SubscriptionStatus: "not active", + SubscriptionStatusReason: "reason", + LastSuccessfulDelivery: "", + LastFailedDelivery: "1345613234", + LastFailedDeliveryReason: "failed", + } + } +} + +func newV2DefaultSubscription(opts ...eventingtesting.SubscriptionOpt) *v1alpha2.Subscription { + newSub := &v1alpha2.Subscription{ + TypeMeta: metav1.TypeMeta{ + Kind: "Subscription", + APIVersion: "eventing.kyma-project.io/v1alpha2", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: defaultName, + Namespace: defaultNamespace, + }, + Spec: v1alpha2.SubscriptionSpec{ + TypeMatching: v1alpha2.TypeMatchingExact, + Sink: defaultSink, + ID: defaultID, + Config: map[string]string{ + v1alpha2.MaxInFlightMessages: fmt.Sprint(defaultMaxInFlight), + }, + }, + Status: v1alpha2.SubscriptionStatus{ + Ready: defaultStatusReady, + Conditions: v2DefaultConditions, + }, + } + for _, o := range opts { + o(newSub) + } + + return newSub +} + +// extend the v2 Subscription helpers with Status fields + +func v2WithBEBStatusFields() eventingtesting.SubscriptionOpt { + return func(s *v1alpha2.Subscription) { + s.Status.Backend.Ev2hash = 123 + s.Status.Backend.ExternalSink = "testlink.com" + s.Status.Backend.FailedActivation = "123156464672" + s.Status.Backend.APIRuleName = "APIRule" + s.Status.Backend.EventMeshSubscriptionStatus = &v1alpha2.EventMeshSubscriptionStatus{ + Status: "not active", + StatusReason: "reason", + LastSuccessfulDelivery: "", + LastFailedDelivery: "1345613234", + LastFailedDeliveryReason: "failed", + } + } +} + +func v2WithStatusTypes(statusTypes []v1alpha2.EventType) eventingtesting.SubscriptionOpt { + return func(sub *v1alpha2.Subscription) { + if statusTypes == nil { + sub.Status.InitializeEventTypes() + return + } + sub.Status.Types = statusTypes + } +} + +func v2WithStatusJetStreamTypes(types []v1alpha2.JetStreamTypes) eventingtesting.SubscriptionOpt { + return func(sub *v1alpha2.Subscription) { + sub.Status.Backend.Types = types + } +} diff --git a/api/eventing/v1alpha1/groupversion_info.go b/api/eventing/v1alpha1/groupversion_info.go new file mode 100644 index 00000000..8f4291fe --- /dev/null +++ b/api/eventing/v1alpha1/groupversion_info.go @@ -0,0 +1,20 @@ +// Package v1alpha1 contains API Schema definitions for the eventing v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=eventing.kyma-project.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "eventing.kyma-project.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/eventing/v1alpha1/subscription_conversion.go b/api/eventing/v1alpha1/subscription_conversion.go new file mode 100644 index 00000000..f6d8205e --- /dev/null +++ b/api/eventing/v1alpha1/subscription_conversion.go @@ -0,0 +1,320 @@ +package v1alpha1 + +import ( + "fmt" + "strconv" + "strings" + + "github.com/kyma-project/eventing-manager/pkg/backend/eventtype" + + "github.com/pkg/errors" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" +) + +const ( + ErrorHubVersionMsg = "hub version is not the expected v1alpha2 version" + ErrorMultipleSourceMsg = "subscription contains more than 1 eventSource" +) + +var v1alpha1TypeCleaner eventtype.Cleaner //nolint:gochecknoglobals // using global var because there is no runtime +// object to hold this instance. + +func InitializeEventTypeCleaner(cleaner eventtype.Cleaner) { + v1alpha1TypeCleaner = cleaner +} + +// ConvertTo converts this Subscription in version v1 to the Hub version v2. +func (src *Subscription) ConvertTo(dstRaw conversion.Hub) error { + dst, ok := dstRaw.(*v1alpha2.Subscription) + if !ok { + return errors.Errorf(ErrorHubVersionMsg) + } + return V1ToV2(src, dst) +} + +// V1ToV2 copies the v1alpha1-type field values into v1alpha2-type field values. +func V1ToV2(src *Subscription, dst *v1alpha2.Subscription) error { + // ObjectMeta + dst.ObjectMeta = src.ObjectMeta + + // SPEC fields + + dst.Spec.ID = src.Spec.ID + dst.Spec.Sink = src.Spec.Sink + dst.Spec.Source = "" + + src.setV2TypeMatching(dst) + + // protocol fields + src.setV2ProtocolFields(dst) + + // Types + if err := src.setV2SpecTypes(dst); err != nil { + return err + } + + // Config + src.natsSpecConfigToV2(dst) + + return nil +} + +// ConvertFrom converts this Subscription from the Hub version (v2) to v1. +func (dst *Subscription) ConvertFrom(srcRaw conversion.Hub) error { //nolint:revive + src, ok := srcRaw.(*v1alpha2.Subscription) + if !ok { + return errors.Errorf(ErrorHubVersionMsg) + } + return V2ToV1(dst, src) +} + +// V2ToV1 copies the v1alpha2-type field values into v1alpha1-type field values. +func V2ToV1(dst *Subscription, src *v1alpha2.Subscription) error { + // ObjectMeta + dst.ObjectMeta = src.ObjectMeta + + dst.Spec.ID = src.Spec.ID + dst.Spec.Sink = src.Spec.Sink + + dst.setV1ProtocolFields(src) + + dst.Spec.Filter = &BEBFilters{ + Filters: []*EventMeshFilter{}, + } + + for _, eventType := range src.Spec.Types { + filter := &EventMeshFilter{ + EventSource: &Filter{ + Property: "source", + Type: fmt.Sprint(v1alpha2.TypeMatchingExact), + Value: src.Spec.Source, + }, + EventType: &Filter{ + Type: fmt.Sprint(v1alpha2.TypeMatchingExact), + Property: "type", + Value: eventType, + }, + } + dst.Spec.Filter.Filters = append(dst.Spec.Filter.Filters, filter) + } + + if src.Spec.Config != nil { + if err := dst.natsSpecConfigToV1(src); err != nil { + return err + } + } + + // Conditions + for _, condition := range src.Status.Conditions { + dst.Status.Conditions = append(dst.Status.Conditions, ConditionV2ToV1(condition)) + } + + dst.Status.Ready = src.Status.Ready + + dst.setV1CleanEvenTypes(src) + dst.bebBackendStatusToV1(src) + dst.natsBackendStatusToV1(src) + + return nil +} + +// setV2TypeMatching sets the default typeMatching on the v1alpha2 Subscription version. +func (src *Subscription) setV2TypeMatching(dst *v1alpha2.Subscription) { + dst.Spec.TypeMatching = v1alpha2.TypeMatchingExact +} + +// setV2ProtocolFields converts the protocol-related fields from v1alpha1 to v1alpha2 Subscription version. +func (src *Subscription) setV2ProtocolFields(dst *v1alpha2.Subscription) { + dst.Spec.Config = map[string]string{} + if src.Spec.Protocol != "" { + dst.Spec.Config[v1alpha2.Protocol] = src.Spec.Protocol + } + // protocol settings + if src.Spec.ProtocolSettings != nil { + if src.Spec.ProtocolSettings.ContentMode != nil { + dst.Spec.Config[v1alpha2.ProtocolSettingsContentMode] = *src.Spec.ProtocolSettings.ContentMode + } + if src.Spec.ProtocolSettings.ExemptHandshake != nil { + dst.Spec.Config[v1alpha2.ProtocolSettingsExemptHandshake] = fmt.Sprint(*src.Spec.ProtocolSettings.ExemptHandshake) + } + if src.Spec.ProtocolSettings.Qos != nil { + dst.Spec.Config[v1alpha2.ProtocolSettingsQos] = *src.Spec.ProtocolSettings.Qos + } + // webhookAuth fields + if src.Spec.ProtocolSettings.WebhookAuth != nil { + if src.Spec.ProtocolSettings.WebhookAuth.Type != "" { + dst.Spec.Config[v1alpha2.WebhookAuthType] = src.Spec.ProtocolSettings.WebhookAuth.Type + } + dst.Spec.Config[v1alpha2.WebhookAuthGrantType] = src.Spec.ProtocolSettings.WebhookAuth.GrantType + dst.Spec.Config[v1alpha2.WebhookAuthClientID] = src.Spec.ProtocolSettings.WebhookAuth.ClientID + dst.Spec.Config[v1alpha2.WebhookAuthClientSecret] = src.Spec.ProtocolSettings.WebhookAuth.ClientSecret + dst.Spec.Config[v1alpha2.WebhookAuthTokenURL] = src.Spec.ProtocolSettings.WebhookAuth.TokenURL + if src.Spec.ProtocolSettings.WebhookAuth.Scope != nil { + dst.Spec.Config[v1alpha2.WebhookAuthScope] = strings.Join(src.Spec.ProtocolSettings.WebhookAuth.Scope, ",") + } + } + } +} + +func (src *Subscription) initializeProtocolSettingsIfNil() { + if src.Spec.ProtocolSettings == nil { + src.Spec.ProtocolSettings = &ProtocolSettings{} + } +} + +func (src *Subscription) initializeWebhookAuthIfNil() { + src.initializeProtocolSettingsIfNil() + if src.Spec.ProtocolSettings.WebhookAuth == nil { + src.Spec.ProtocolSettings.WebhookAuth = &WebhookAuth{} + } +} + +// setV1ProtocolFields converts the protocol-related fields from v1alpha1 to v1alpha2 Subscription version. +func (src *Subscription) setV1ProtocolFields(dst *v1alpha2.Subscription) { + if protocol, ok := dst.Spec.Config[v1alpha2.Protocol]; ok { + src.Spec.Protocol = protocol + } + + if currentMode, ok := dst.Spec.Config[v1alpha2.ProtocolSettingsContentMode]; ok { + src.initializeProtocolSettingsIfNil() + src.Spec.ProtocolSettings.ContentMode = ¤tMode + } + if qos, ok := dst.Spec.Config[v1alpha2.ProtocolSettingsQos]; ok { + src.initializeProtocolSettingsIfNil() + src.Spec.ProtocolSettings.Qos = &qos + } + if exemptHandshake, ok := dst.Spec.Config[v1alpha2.ProtocolSettingsExemptHandshake]; ok { + handshake, err := strconv.ParseBool(exemptHandshake) + if err != nil { + handshake = true + } + src.initializeProtocolSettingsIfNil() + src.Spec.ProtocolSettings.ExemptHandshake = &handshake + } + + if authType, ok := dst.Spec.Config[v1alpha2.WebhookAuthType]; ok { + src.initializeWebhookAuthIfNil() + src.Spec.ProtocolSettings.WebhookAuth.Type = authType + } + if grantType, ok := dst.Spec.Config[v1alpha2.WebhookAuthGrantType]; ok { + src.initializeWebhookAuthIfNil() + src.Spec.ProtocolSettings.WebhookAuth.GrantType = grantType + } + if clientID, ok := dst.Spec.Config[v1alpha2.WebhookAuthClientID]; ok { + src.initializeWebhookAuthIfNil() + src.Spec.ProtocolSettings.WebhookAuth.ClientID = clientID + } + if secret, ok := dst.Spec.Config[v1alpha2.WebhookAuthClientSecret]; ok { + src.initializeWebhookAuthIfNil() + src.Spec.ProtocolSettings.WebhookAuth.ClientSecret = secret + } + if token, ok := dst.Spec.Config[v1alpha2.WebhookAuthTokenURL]; ok { + src.initializeWebhookAuthIfNil() + src.Spec.ProtocolSettings.WebhookAuth.TokenURL = token + } + if scope, ok := dst.Spec.Config[v1alpha2.WebhookAuthScope]; ok { + src.initializeWebhookAuthIfNil() + src.Spec.ProtocolSettings.WebhookAuth.Scope = strings.Split(scope, ",") + } +} + +// setV2SpecTypes sets event types in the Subscription Spec in the v1alpha2 way. +func (src *Subscription) setV2SpecTypes(dst *v1alpha2.Subscription) error { + if v1alpha1TypeCleaner == nil { + return errors.New("event type cleaner is not initialized") + } + + if src.Spec.Filter != nil { + for _, filter := range src.Spec.Filter.Filters { + if dst.Spec.Source == "" { + dst.Spec.Source = filter.EventSource.Value + } + if dst.Spec.Source != "" && filter.EventSource.Value != dst.Spec.Source { + return errors.New(ErrorMultipleSourceMsg) + } + // clean the type and merge segments if needed + cleanedType, err := v1alpha1TypeCleaner.Clean(filter.EventType.Value) + if err != nil { + return err + } + + // add the type to spec + dst.Spec.Types = append(dst.Spec.Types, cleanedType) + } + } + return nil +} + +// natsSpecConfigToV2 converts the v1alpha2 Spec config to v1alpha1. +func (src *Subscription) natsSpecConfigToV1(dst *v1alpha2.Subscription) error { + if maxInFlightMessages, ok := dst.Spec.Config[v1alpha2.MaxInFlightMessages]; ok { + intVal, err := strconv.Atoi(maxInFlightMessages) + if err != nil { + return err + } + src.Spec.Config = &SubscriptionConfig{ + MaxInFlightMessages: intVal, + } + } + return nil +} + +// natsSpecConfigToV2 converts the hardcoded v1alpha1 Spec config to v1alpha2 generic config version. +func (src *Subscription) natsSpecConfigToV2(dst *v1alpha2.Subscription) { + if src.Spec.Config != nil { + if dst.Spec.Config == nil { + dst.Spec.Config = map[string]string{} + } + dst.Spec.Config[v1alpha2.MaxInFlightMessages] = fmt.Sprint(src.Spec.Config.MaxInFlightMessages) + } +} + +// setBEBBackendStatus moves the BEB-related to Backend fields of the Status in the v1alpha2. +func (src *Subscription) bebBackendStatusToV1(dst *v1alpha2.Subscription) { + src.Status.Ev2hash = dst.Status.Backend.Ev2hash + src.Status.Emshash = dst.Status.Backend.EventMeshHash + src.Status.ExternalSink = dst.Status.Backend.ExternalSink + src.Status.FailedActivation = dst.Status.Backend.FailedActivation + src.Status.APIRuleName = dst.Status.Backend.APIRuleName + if dst.Status.Backend.EventMeshSubscriptionStatus != nil { + src.Status.EmsSubscriptionStatus = &EmsSubscriptionStatus{ + SubscriptionStatus: dst.Status.Backend.EventMeshSubscriptionStatus.Status, + SubscriptionStatusReason: dst.Status.Backend.EventMeshSubscriptionStatus.StatusReason, + LastSuccessfulDelivery: dst.Status.Backend.EventMeshSubscriptionStatus.LastSuccessfulDelivery, + LastFailedDelivery: dst.Status.Backend.EventMeshSubscriptionStatus.LastFailedDelivery, + LastFailedDeliveryReason: dst.Status.Backend.EventMeshSubscriptionStatus.LastFailedDeliveryReason, + } + } +} + +// natsBackendStatusToV1 moves the NATS-related to Backend fields of the Status in the v1alpha2. +func (src *Subscription) natsBackendStatusToV1(dst *v1alpha2.Subscription) { + if maxInFlightMessages, ok := dst.Spec.Config[v1alpha2.MaxInFlightMessages]; ok { + intVal, err := strconv.Atoi(maxInFlightMessages) + if err == nil { + src.Status.Config = &SubscriptionConfig{} + src.Status.Config.MaxInFlightMessages = intVal + } + } +} + +// setV1CleanEvenTypes sets the clean event types to v1alpha1 Subscription Status. +func (src *Subscription) setV1CleanEvenTypes(dst *v1alpha2.Subscription) { + src.Status.InitializeCleanEventTypes() + for _, eventType := range dst.Status.Types { + src.Status.CleanEventTypes = append(src.Status.CleanEventTypes, eventType.CleanType) + } +} + +// ConditionV2ToV1 converts the v1alpha2 Condition to v1alpha1 version. +func ConditionV2ToV1(condition v1alpha2.Condition) Condition { + return Condition{ + Type: ConditionType(condition.Type), + Status: condition.Status, + LastTransitionTime: condition.LastTransitionTime, + Reason: ConditionReason(condition.Reason), + Message: condition.Message, + } +} diff --git a/api/eventing/v1alpha1/subscription_conversion_unit_test.go b/api/eventing/v1alpha1/subscription_conversion_unit_test.go new file mode 100644 index 00000000..563caf94 --- /dev/null +++ b/api/eventing/v1alpha1/subscription_conversion_unit_test.go @@ -0,0 +1,409 @@ +package v1alpha1_test + +import ( + "testing" + + "github.com/kyma-project/eventing-manager/pkg/logger" + + "github.com/kyma-project/eventing-manager/pkg/backend/eventtype" + + "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" + + eventingtesting "github.com/kyma-project/eventing-manager/testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" +) + +func Test_Conversion(t *testing.T) { + type TestCase struct { + name string + alpha1Sub *v1alpha1.Subscription + alpha2Sub *v1alpha2.Subscription + wantErrMsgV1toV2 string + wantErrMsgV2toV1 string + } + + testCases := []TestCase{ + { + name: "Converting NATS Subscription with empty Status", + alpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1EmptyFilter(), + eventingtesting.WithV1alpha1EmptyConfig(), + eventingtesting.WithV1alpha1EmptyStatus(), + ), + alpha2Sub: newV2DefaultSubscription( + eventingtesting.WithEmptyStatus(), + eventingtesting.WithEmptyConfig(), + ), + }, + { + name: "Converting NATS Subscription with empty Filters", + alpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1EmptyFilter(), + eventingtesting.WithStatusCleanEventTypes(nil), + ), + alpha2Sub: newV2DefaultSubscription(), + }, + { + name: "Converting NATS Subscription with multiple source which should result in a conversion error", + alpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter("app", orderUpdatedEventType), + eventingtesting.WithV1alpha1Filter("", orderDeletedEventTypeNonClean), + ), + alpha2Sub: newV2DefaultSubscription(), + wantErrMsgV1toV2: v1alpha1.ErrorMultipleSourceMsg, + }, + { + name: "Converting NATS Subscription with non-convertable maxInFlight in the config which should result in a conversion error", + alpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter("", orderUpdatedEventType), + ), + alpha2Sub: newV2DefaultSubscription( + eventingtesting.WithMaxInFlightMessages("nonint"), + ), + wantErrMsgV2toV1: "strconv.Atoi: parsing \"nonint\": invalid syntax", + }, + { + name: "Converting NATS Subscription with Filters", + alpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, orderCreatedEventType), + eventingtesting.WithV1alpha1Filter(eventSource, orderUpdatedEventType), + eventingtesting.WithV1alpha1Filter(eventSource, orderDeletedEventTypeNonClean), + eventingtesting.WithStatusCleanEventTypes([]string{ + orderCreatedEventType, + orderUpdatedEventType, + orderDeletedEventType, + }), + ), + alpha2Sub: newV2DefaultSubscription( + eventingtesting.WithEventSource(eventSource), + eventingtesting.WithTypes([]string{ + orderCreatedEventType, + orderUpdatedEventType, + orderDeletedEventTypeNonClean, + }), + v2WithStatusTypes([]v1alpha2.EventType{ + { + OriginalType: orderCreatedEventType, + CleanType: orderCreatedEventType, + }, + { + OriginalType: orderUpdatedEventType, + CleanType: orderUpdatedEventType, + }, + { + OriginalType: orderDeletedEventTypeNonClean, + CleanType: orderDeletedEventType, + }, + }), + v2WithStatusJetStreamTypes([]v1alpha2.JetStreamTypes{ + { + OriginalType: orderCreatedEventType, + ConsumerName: "", + }, + { + OriginalType: orderUpdatedEventType, + ConsumerName: "", + }, + { + OriginalType: orderDeletedEventTypeNonClean, + ConsumerName: "", + }, + }), + ), + }, + { + name: "Converting BEB Subscription", + alpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1ProtocolEventMesh(), + v1WithWebhookAuthForBEB(), + eventingtesting.WithV1alpha1Filter(eventSource, orderCreatedEventType), + eventingtesting.WithV1alpha1Filter(eventSource, orderUpdatedEventType), + eventingtesting.WithV1alpha1Filter(eventSource, orderDeletedEventTypeNonClean), + eventingtesting.WithStatusCleanEventTypes([]string{ + orderCreatedEventType, + orderUpdatedEventType, + orderDeletedEventType, + }), + v1WithBEBStatusFields(), + ), + alpha2Sub: newV2DefaultSubscription( + eventingtesting.WithEventSource(eventSource), + eventingtesting.WithTypes([]string{ + orderCreatedEventType, + orderUpdatedEventType, + orderDeletedEventTypeNonClean, + }), + eventingtesting.WithProtocolEventMesh(), + eventingtesting.WithWebhookAuthForEventMesh(), + v2WithStatusTypes([]v1alpha2.EventType{ + { + OriginalType: orderCreatedEventType, + CleanType: orderCreatedEventType, + }, + { + OriginalType: orderUpdatedEventType, + CleanType: orderUpdatedEventType, + }, + { + OriginalType: orderDeletedEventTypeNonClean, + CleanType: orderDeletedEventType, + }, + }), + v2WithBEBStatusFields(), + ), + }, + { + name: "Converting Subscription with Protocol, ProtocolSettings and WebhookAuth", + alpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1ProtocolEventMesh(), + eventingtesting.WithV1alpha1ProtocolSettings( + eventingtesting.NewProtocolSettings( + eventingtesting.WithAtLeastOnceQOS(), + eventingtesting.WithRequiredWebhookAuth())), + eventingtesting.WithV1alpha1Filter(eventSource, orderCreatedEventType), + eventingtesting.WithStatusCleanEventTypes([]string{ + orderCreatedEventType, + }), + ), + alpha2Sub: newV2DefaultSubscription( + eventingtesting.WithEventSource(eventSource), + eventingtesting.WithTypes([]string{ + orderCreatedEventType, + }), + eventingtesting.WithProtocolEventMesh(), + eventingtesting.WithConfigValue(v1alpha2.ProtocolSettingsQos, + string(types.QosAtLeastOnce)), + eventingtesting.WithConfigValue(v1alpha2.WebhookAuthGrantType, + "client_credentials"), + eventingtesting.WithConfigValue(v1alpha2.WebhookAuthClientID, + "xxx"), + eventingtesting.WithConfigValue(v1alpha2.WebhookAuthClientSecret, + "xxx"), + eventingtesting.WithConfigValue(v1alpha2.WebhookAuthTokenURL, + "https://oauth2.xxx.com/oauth2/token"), + v2WithStatusTypes([]v1alpha2.EventType{ + { + OriginalType: orderCreatedEventType, + CleanType: orderCreatedEventType, + }, + }), + ), + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + // WHEN + t.Run("Test v1 to v2 conversion", func(t *testing.T) { + // skip the conversion if the backwards conversion cannot succeed + if testCase.wantErrMsgV2toV1 != "" { + return + } + + // initialize dummy cleaner + cleaner := eventtype.CleanerFunc(func(et string) (string, error) { return et, nil }) + v1alpha1.InitializeEventTypeCleaner(cleaner) + + convertedV1Alpha2 := &v1alpha2.Subscription{} + err := v1alpha1.V1ToV2(testCase.alpha1Sub, convertedV1Alpha2) + if err != nil && testCase.wantErrMsgV1toV2 != "" { + require.Equal(t, err.Error(), testCase.wantErrMsgV1toV2) + } else { + require.NoError(t, err) + v1ToV2Assertions(t, testCase.alpha2Sub, convertedV1Alpha2) + } + }) + + // test ConvertFrom + t.Run("Test v2 to v1 conversion", func(t *testing.T) { + // skip the backwards conversion if the initial one cannot succeed + if testCase.wantErrMsgV1toV2 != "" { + return + } + convertedV1Alpha1 := &v1alpha1.Subscription{} + err := v1alpha1.V2ToV1(convertedV1Alpha1, testCase.alpha2Sub) + if err != nil && testCase.wantErrMsgV2toV1 != "" { + require.Equal(t, err.Error(), testCase.wantErrMsgV2toV1) + } else { + require.NoError(t, err) + v2ToV1Assertions(t, testCase.alpha1Sub, convertedV1Alpha1) + } + }) + }) + } +} + +// Test_CleanupInV1ToV2Conversion test the cleaning from non-alphanumeric characters +// and also merging of segments in event types if they exceed the limit. +func Test_CleanupInV1ToV2Conversion(t *testing.T) { + type TestCase struct { + name string + givenAlpha1Sub *v1alpha1.Subscription + givenPrefix string + wantTypes []string + wantError bool + } + + testCases := []TestCase{ + { + name: "success if prefix is empty", + givenAlpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, "testapp.Segment1-Part1-Part2-Ä.Segment2-Part1-Part2-Ä.v1"), + ), + givenPrefix: "", + wantTypes: []string{ + "testapp.Segment1Part1Part2.Segment2Part1Part2.v1", + }, + }, + { + name: "success if the given event has more than two segments", + givenPrefix: "prefix", + givenAlpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, "prefix.testapp.Segment1.Segment2.Segment3."+ + "Segment4-Part1-Part2-Ä.Segment5-Part1-Part2-Ä.v1"), + ), + wantTypes: []string{ + "prefix.testapp.Segment1Segment2Segment3Segment4Part1Part2.Segment5Part1Part2.v1", + }, + wantError: false, + }, + { + name: "success if the application name needs to be cleaned", + givenPrefix: "prefix", + givenAlpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, "prefix.te--s__t!!a@@p##p%%.Segment1-Part1-Part2-Ä."+ + "Segment2-Part1-Part2-Ä.v1"), + ), + wantTypes: []string{ + "prefix.testapp.Segment1Part1Part2.Segment2Part1Part2.v1", + }, + wantError: false, + }, + { + name: "success if the application name needs to be cleaned and event has more than two segments", + givenPrefix: "prefix", + givenAlpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, "prefix.te--s__t!!a@@p##p%%.Segment1.Segment2.Segment3."+ + "Segment4-Part1-Part2-Ä.Segment5-Part1-Part2-Ä.v1"), + ), + wantTypes: []string{ + "prefix.testapp.Segment1Segment2Segment3Segment4Part1Part2.Segment5Part1Part2.v1", + }, + wantError: false, + }, + { + name: "success if there are multiple filters", + givenPrefix: "prefix", + givenAlpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, "prefix.test-app.Segme@@nt1.Segment2.Segment3."+ + "Segment4-Part1-Part2-Ä.Segment5-Part1-Part2-Ä.v1"), + eventingtesting.WithV1alpha1Filter(eventSource, "prefix.testapp.Segment1.Segment2.Segment3."+ + "Segment4-Part1-Part2-Ä.Segment5-Part1-Part2-Ä.v1"), + ), + wantTypes: []string{ + "prefix.testapp.Segment1Segment2Segment3Segment4Part1Part2.Segment5Part1Part2.v1", + "prefix.testapp.Segment1Segment2Segment3Segment4Part1Part2.Segment5Part1Part2.v1", + }, + wantError: false, + }, + // invalid even-types + { + name: "fail if the prefix is invalid", + givenPrefix: "prefix", + givenAlpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, "invalid.test-app.Segme@@nt1.Segment2.Segment3."+ + "Segment4-Part1-Part2-Ä.Segment5-Part1-Part2-Ä.v1"), + ), + wantError: true, + }, + { + name: "fail if the prefix is missing", + givenPrefix: "prefix", + givenAlpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, "test-app.Segme@@nt1.Segment2.Segment3."+ + "Segment4-Part1-Part2-Ä.Segment5-Part1-Part2-Ä.v1"), + ), + wantError: true, + }, + { + name: "fail if the event-type is incomplete", + givenPrefix: "prefix", + givenAlpha1Sub: newDefaultSubscription( + eventingtesting.WithV1alpha1Filter(eventSource, "prefix.testapp.Segment1-Part1-Part2-Ä.v1"), + ), + wantError: true, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + // given + testLogger, err := logger.New("json", "info") + require.NoError(t, err) + + // initialize dummy cleaner + cleaner := eventtype.NewSimpleCleaner(tc.givenPrefix, testLogger) + v1alpha1.InitializeEventTypeCleaner(cleaner) + + // initialize v1alpha2 Subscription instance + convertedV1Alpha2 := &v1alpha2.Subscription{} + + // when + err = v1alpha1.V1ToV2(tc.givenAlpha1Sub, convertedV1Alpha2) + + // then + if tc.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.wantTypes, convertedV1Alpha2.Spec.Types) + } + }) + } +} + +func v1ToV2Assertions(t *testing.T, wantSub, convertedSub *v1alpha2.Subscription) { + assert.Equal(t, wantSub.ObjectMeta, convertedSub.ObjectMeta) + + // Spec + assert.Equal(t, wantSub.Spec.ID, convertedSub.Spec.ID) + assert.Equal(t, wantSub.Spec.Sink, convertedSub.Spec.Sink) + assert.Equal(t, wantSub.Spec.TypeMatching, convertedSub.Spec.TypeMatching) + assert.Equal(t, wantSub.Spec.Source, convertedSub.Spec.Source) + assert.Equal(t, wantSub.Spec.Types, convertedSub.Spec.Types) + assert.Equal(t, wantSub.Spec.Config, convertedSub.Spec.Config) +} + +func v2ToV1Assertions(t *testing.T, wantSub, convertedSub *v1alpha1.Subscription) { + assert.Equal(t, wantSub.ObjectMeta, convertedSub.ObjectMeta) + + // Spec + assert.Equal(t, wantSub.Spec.ID, convertedSub.Spec.ID) + assert.Equal(t, wantSub.Spec.Sink, convertedSub.Spec.Sink) + assert.Equal(t, wantSub.Spec.Protocol, convertedSub.Spec.Protocol) + assert.Equal(t, wantSub.Spec.ProtocolSettings, convertedSub.Spec.ProtocolSettings) + + assert.Equal(t, wantSub.Spec.Filter, convertedSub.Spec.Filter) + assert.Equal(t, wantSub.Spec.Config, convertedSub.Spec.Config) + + // Status + assert.Equal(t, wantSub.Status.Ready, convertedSub.Status.Ready) + assert.Equal(t, wantSub.Status.Conditions, convertedSub.Status.Conditions) + assert.Equal(t, wantSub.Status.CleanEventTypes, convertedSub.Status.CleanEventTypes) + + // BEB fields + assert.Equal(t, wantSub.Status.Ev2hash, convertedSub.Status.Ev2hash) + assert.Equal(t, wantSub.Status.Emshash, convertedSub.Status.Emshash) + assert.Equal(t, wantSub.Status.ExternalSink, convertedSub.Status.ExternalSink) + assert.Equal(t, wantSub.Status.FailedActivation, convertedSub.Status.FailedActivation) + assert.Equal(t, wantSub.Status.APIRuleName, convertedSub.Status.APIRuleName) + assert.Equal(t, wantSub.Status.EmsSubscriptionStatus, convertedSub.Status.EmsSubscriptionStatus) + + assert.Equal(t, wantSub.Status.Config, convertedSub.Status.Config) +} diff --git a/api/eventing/v1alpha1/subscription_types.go b/api/eventing/v1alpha1/subscription_types.go new file mode 100644 index 00000000..6c49daf0 --- /dev/null +++ b/api/eventing/v1alpha1/subscription_types.go @@ -0,0 +1,280 @@ +package v1alpha1 + +import ( + "encoding/json" + + "github.com/mitchellh/hashstructure/v2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyma-project/eventing-manager/pkg/env" +) + +type BackendType string + +const ( + BEBBackendType BackendType = "BEB" + NatsBackendType BackendType = "NATS" +) + +var Finalizer = GroupVersion.Group + +// WebhookAuth defines the Webhook called by an active subscription in BEB. +// TODO: Remove it when depreciating code of v1alpha1 +type WebhookAuth struct { + // Defines the authentication type. + // +optional + Type string `json:"type,omitempty"` + + // Defines the grant type for OAuth2. + GrantType string `json:"grantType"` + + // Defines the clientID for OAuth2. + ClientID string `json:"clientId"` + + // Defines the Client Secret for OAuth2. + ClientSecret string `json:"clientSecret"` + + // Defines the token URL for OAuth2. + TokenURL string `json:"tokenUrl"` + + // Defines the scope for OAuth2. + Scope []string `json:"scope,omitempty"` +} + +// ProtocolSettings defines the CE protocol setting specification implementation. +// TODO: Remove it when depreciating code of v1alpha1 +type ProtocolSettings struct { + // Defines the content mode for eventing based on BEB. + // The value is either `BINARY`, or `STRUCTURED`. + // +optional + ContentMode *string `json:"contentMode,omitempty"` + + // Defines if the exempt handshake for eventing is based on BEB. + // +optional + ExemptHandshake *bool `json:"exemptHandshake,omitempty"` + + // Defines the quality of service for eventing based on BEB. + // +optional + Qos *string `json:"qos,omitempty"` + + // Defines the Webhook called by an active subscription on BEB. + // +optional + WebhookAuth *WebhookAuth `json:"webhookAuth,omitempty"` +} + +// TODO: Remove it when depreciating code of v1alpha1 +const ( + ProtocolSettingsContentModeBinary string = "BINARY" + ProtocolSettingsContentModeStructured string = "STRUCTURED" +) + +// Filter defines the CE filter element. +type Filter struct { + // Defines the type of the filter. + // +optional + Type string `json:"type,omitempty"` + + // Defines the property of the filter. + Property string `json:"property"` + + // Defines the value of the filter. + Value string `json:"value"` +} + +// Defines the BEB filter element as a combination of two CE filter elements. +type EventMeshFilter struct { + // Defines the source of the CE filter. + EventSource *Filter `json:"eventSource"` + + // Defines the type of the CE filter. + EventType *Filter `json:"eventType"` +} + +func (bf *EventMeshFilter) hash() (uint64, error) { + return hashstructure.Hash(bf, hashstructure.FormatV2, nil) +} + +// BEBFilters defines the list of BEB filters. +type BEBFilters struct { + // Contains a `URI-reference` to the CloudEvent filter dialect. See + // [here](https://github.com/cloudevents/spec/blob/main/subscriptions/spec.md#3241-filter-dialects) for more details. + // +optional + Dialect string `json:"dialect,omitempty"` + + Filters []*EventMeshFilter `json:"filters"` +} + +// Deduplicate returns a deduplicated copy of BEBFilters. +func (bf *BEBFilters) Deduplicate() (*BEBFilters, error) { + seen := map[uint64]struct{}{} + result := &BEBFilters{ + Dialect: bf.Dialect, + } + for _, f := range bf.Filters { + h, err := f.hash() + if err != nil { + return nil, err + } + if _, exists := seen[h]; !exists { + result.Filters = append(result.Filters, f) + seen[h] = struct{}{} + } + } + return result, nil +} + +type SubscriptionConfig struct { + // Defines how many not-ACKed messages can be in flight simultaneously. + // +optional + // +kubebuilder:validation:Minimum=1 + MaxInFlightMessages int `json:"maxInFlightMessages,omitempty"` +} + +// MergeSubsConfigs returns a valid subscription config object based on the provided config, +// complemented with default values, if necessary. +func MergeSubsConfigs(config *SubscriptionConfig, defaults *env.DefaultSubscriptionConfig) *SubscriptionConfig { + merged := &SubscriptionConfig{ + MaxInFlightMessages: defaults.MaxInFlightMessages, + } + if config == nil { + return merged + } + if config.MaxInFlightMessages >= 1 { + merged.MaxInFlightMessages = config.MaxInFlightMessages + } + return merged +} + +// SubscriptionSpec defines the desired state of Subscription. +type SubscriptionSpec struct { + // Unique identifier of the Subscription, read-only. + // +optional + ID string `json:"id,omitempty"` + + // Defines the CE protocol specification implementation. + // +optional + Protocol string `json:"protocol,omitempty"` + + // Defines the CE protocol settings specification implementation. + // +optional + ProtocolSettings *ProtocolSettings `json:"protocolsettings,omitempty"` + + // Kubernetes Service that should be used as a target for the events that match the Subscription. + // Must exist in the same Namespace as the Subscription. + Sink string `json:"sink"` + + // Defines which events will be sent to the sink. + Filter *BEBFilters `json:"filter"` + + // Defines additional configuration for the active backend. + // +optional + Config *SubscriptionConfig `json:"config,omitempty"` +} + +type EmsSubscriptionStatus struct { + // Status of the Subscription as reported by EventMesh. + // +optional + SubscriptionStatus string `json:"subscriptionStatus,omitempty"` + + // Reason for the current status. + // +optional + SubscriptionStatusReason string `json:"subscriptionStatusReason,omitempty"` + + // Timestamp of the last successful delivery. + // +optional + LastSuccessfulDelivery string `json:"lastSuccessfulDelivery,omitempty"` + + // Timestamp of the last failed delivery. + // +optional + LastFailedDelivery string `json:"lastFailedDelivery,omitempty"` + + // Reason for the last failed delivery. + // +optional + LastFailedDeliveryReason string `json:"lastFailedDeliveryReason,omitempty"` +} + +// SubscriptionStatus defines the observed state of the Subscription. +type SubscriptionStatus struct { + // Current state of the Subscription. + // +optional + Conditions []Condition `json:"conditions,omitempty"` + + // Overall readiness of the Subscription. + Ready bool `json:"ready"` + + // CleanEventTypes defines the filter's event types after cleanup to use it with the configured backend. + CleanEventTypes []string `json:"cleanEventTypes"` + + // Defines the checksum for the Subscription custom resource. + // +optional + Ev2hash int64 `json:"ev2hash,omitempty"` + + // Defines the checksum for the Subscription in EventMesh. + // +optional + Emshash int64 `json:"emshash,omitempty"` + + // Defines the webhook URL which is used by EventMesh to trigger subscribers. + // +optional + ExternalSink string `json:"externalSink,omitempty"` + + // Defines the reason if a Subscription failed activation in EventMesh. + // +optional + FailedActivation string `json:"failedActivation,omitempty"` + + // Defines the name of the APIRule which is used by the Subscription. + // +optional + APIRuleName string `json:"apiRuleName,omitempty"` + + // Defines the status of the Subscription in EventMesh. + // +optional + EmsSubscriptionStatus *EmsSubscriptionStatus `json:"emsSubscriptionStatus,omitempty"` + + // Defines the configurations that have been applied to the eventing backend when creating this Subscription. + // +optional + Config *SubscriptionConfig `json:"config,omitempty"` +} + +// Subscription is the Schema for the subscriptions API. +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:deprecatedversion:warning=The v1alpha1 API version is deprecated as of Kyma 2.14.X. +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" +// +kubebuilder:printcolumn:name="Clean Event Types",type="string",JSONPath=".status.cleanEventTypes" +type Subscription struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SubscriptionSpec `json:"spec,omitempty"` + Status SubscriptionStatus `json:"status,omitempty"` +} + +// MarshalJSON implements the json.Marshaler interface. +// If the SubscriptionStatus.CleanEventTypes is nil, it will be initialized to an empty slice of stings. +// It is needed because the Kubernetes APIServer will reject requests containing null in the JSON payload. +func (s Subscription) MarshalJSON() ([]byte, error) { + // Use type alias to copy the subscription without causing an infinite recursion when calling json.Marshal. + type Alias Subscription + a := Alias(s) + if a.Status.CleanEventTypes == nil { + a.Status.InitializeCleanEventTypes() + } + return json.Marshal(a) +} + +// SubscriptionList contains a list of Subscription. +// +kubebuilder:object:root=true +type SubscriptionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Subscription `json:"items"` +} + +// InitializeCleanEventTypes initializes the SubscriptionStatus.CleanEventTypes with an empty slice of strings. +func (s *SubscriptionStatus) InitializeCleanEventTypes() { + s.CleanEventTypes = []string{} +} + +func init() { //nolint:gochecknoinits + SchemeBuilder.Register(&Subscription{}, &SubscriptionList{}) +} diff --git a/api/eventing/v1alpha1/subscription_types_unit_test.go b/api/eventing/v1alpha1/subscription_types_unit_test.go new file mode 100644 index 00000000..ce2f62be --- /dev/null +++ b/api/eventing/v1alpha1/subscription_types_unit_test.go @@ -0,0 +1,150 @@ +package v1alpha1_test + +import ( + "reflect" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/kyma-project/eventing-manager/pkg/env" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" +) + +func TestBEBFilters_Deduplicate(t *testing.T) { + filter1 := &v1alpha1.EventMeshFilter{ + EventSource: &v1alpha1.Filter{ + Type: "exact", + Property: "source", + Value: "", + }, + EventType: &v1alpha1.Filter{ + Type: "exact", + Property: "type", + Value: orderCreatedEventType, + }, + } + filter2 := &v1alpha1.EventMeshFilter{ + EventSource: &v1alpha1.Filter{ + Type: "exact", + Property: "source", + Value: "", + }, + EventType: &v1alpha1.Filter{ + Type: "exact", + Property: "type", + Value: orderProcessedEventType, + }, + } + filter3 := &v1alpha1.EventMeshFilter{ + EventSource: &v1alpha1.Filter{ + Type: "exact", + Property: "source", + Value: "/external/system/id", + }, + EventType: &v1alpha1.Filter{ + Type: "exact", + Property: "type", + Value: orderCreatedEventType, + }, + } + tests := []struct { + caseName string + input *v1alpha1.BEBFilters + expected *v1alpha1.BEBFilters + expectErr bool + }{ + { + caseName: "Only one filter", + input: &v1alpha1.BEBFilters{ + Dialect: "beb", + Filters: []*v1alpha1.EventMeshFilter{filter1}, + }, + expected: &v1alpha1.BEBFilters{ + Dialect: "beb", + Filters: []*v1alpha1.EventMeshFilter{filter1}, + }, + expectErr: false, + }, + { + caseName: "Filters with duplicate", + input: &v1alpha1.BEBFilters{ + Dialect: "nats", + Filters: []*v1alpha1.EventMeshFilter{filter1, filter1}, + }, + expected: &v1alpha1.BEBFilters{ + Dialect: "nats", + Filters: []*v1alpha1.EventMeshFilter{filter1}, + }, + expectErr: false, + }, + { + caseName: "Filters without duplicate", + input: &v1alpha1.BEBFilters{ + Filters: []*v1alpha1.EventMeshFilter{filter1, filter2, filter3}, + }, + expected: &v1alpha1.BEBFilters{ + Filters: []*v1alpha1.EventMeshFilter{filter1, filter2, filter3}, + }, + expectErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.caseName, func(t *testing.T) { + got, err := tt.input.Deduplicate() + if (err != nil) != tt.expectErr { + t.Errorf("Deduplicate() error = %v, expectErr %v", err, tt.expected) + return + } + if !reflect.DeepEqual(got, tt.expected) { + t.Errorf("Deduplicate() got = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestMergeSubsConfigs(t *testing.T) { + defaultConf := &env.DefaultSubscriptionConfig{MaxInFlightMessages: 4} + tests := []struct { + caseName string + inputConf *v1alpha1.SubscriptionConfig + inputDefaults *env.DefaultSubscriptionConfig + expectedOutput *v1alpha1.SubscriptionConfig + }{ + { + caseName: "nil input config", + inputConf: nil, + inputDefaults: defaultConf, + expectedOutput: &v1alpha1.SubscriptionConfig{MaxInFlightMessages: 4}, + }, + { + caseName: "default is overridden", + inputConf: &v1alpha1.SubscriptionConfig{MaxInFlightMessages: 10}, + inputDefaults: defaultConf, + expectedOutput: &v1alpha1.SubscriptionConfig{MaxInFlightMessages: 10}, + }, + { + caseName: "provided input is invalid", + inputConf: &v1alpha1.SubscriptionConfig{MaxInFlightMessages: 0}, + inputDefaults: defaultConf, + expectedOutput: &v1alpha1.SubscriptionConfig{MaxInFlightMessages: 4}, + }, + } + + for _, tt := range tests { + t.Run(tt.caseName, func(t *testing.T) { + got := v1alpha1.MergeSubsConfigs(tt.inputConf, tt.inputDefaults) + if !reflect.DeepEqual(got, tt.expectedOutput) { + t.Errorf("MergeSubsConfigs() got = %v, want = %v", got, tt.expectedOutput) + } + }) + } +} + +func TestInitializeCleanEventTypes(t *testing.T) { + s := v1alpha1.Subscription{} + require.Nil(t, s.Status.CleanEventTypes) + + s.Status.InitializeCleanEventTypes() + require.NotNil(t, s.Status.CleanEventTypes) +} diff --git a/api/eventing/v1alpha1/subscription_webhook.go b/api/eventing/v1alpha1/subscription_webhook.go new file mode 100644 index 00000000..e4988c49 --- /dev/null +++ b/api/eventing/v1alpha1/subscription_webhook.go @@ -0,0 +1,13 @@ +package v1alpha1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" +) + +func (r *Subscription) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/api/eventing/v1alpha1/zz_generated.deepcopy.go b/api/eventing/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000..f53715e8 --- /dev/null +++ b/api/eventing/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,319 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2023. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BEBFilters) DeepCopyInto(out *BEBFilters) { + *out = *in + if in.Filters != nil { + in, out := &in.Filters, &out.Filters + *out = make([]*EventMeshFilter, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(EventMeshFilter) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BEBFilters. +func (in *BEBFilters) DeepCopy() *BEBFilters { + if in == nil { + return nil + } + out := new(BEBFilters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Condition) DeepCopyInto(out *Condition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. +func (in *Condition) DeepCopy() *Condition { + if in == nil { + return nil + } + out := new(Condition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EmsSubscriptionStatus) DeepCopyInto(out *EmsSubscriptionStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmsSubscriptionStatus. +func (in *EmsSubscriptionStatus) DeepCopy() *EmsSubscriptionStatus { + if in == nil { + return nil + } + out := new(EmsSubscriptionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventMeshFilter) DeepCopyInto(out *EventMeshFilter) { + *out = *in + if in.EventSource != nil { + in, out := &in.EventSource, &out.EventSource + *out = new(Filter) + **out = **in + } + if in.EventType != nil { + in, out := &in.EventType, &out.EventType + *out = new(Filter) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventMeshFilter. +func (in *EventMeshFilter) DeepCopy() *EventMeshFilter { + if in == nil { + return nil + } + out := new(EventMeshFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Filter) DeepCopyInto(out *Filter) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Filter. +func (in *Filter) DeepCopy() *Filter { + if in == nil { + return nil + } + out := new(Filter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProtocolSettings) DeepCopyInto(out *ProtocolSettings) { + *out = *in + if in.ContentMode != nil { + in, out := &in.ContentMode, &out.ContentMode + *out = new(string) + **out = **in + } + if in.ExemptHandshake != nil { + in, out := &in.ExemptHandshake, &out.ExemptHandshake + *out = new(bool) + **out = **in + } + if in.Qos != nil { + in, out := &in.Qos, &out.Qos + *out = new(string) + **out = **in + } + if in.WebhookAuth != nil { + in, out := &in.WebhookAuth, &out.WebhookAuth + *out = new(WebhookAuth) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProtocolSettings. +func (in *ProtocolSettings) DeepCopy() *ProtocolSettings { + if in == nil { + return nil + } + out := new(ProtocolSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Subscription) DeepCopyInto(out *Subscription) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subscription. +func (in *Subscription) DeepCopy() *Subscription { + if in == nil { + return nil + } + out := new(Subscription) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Subscription) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionConfig) DeepCopyInto(out *SubscriptionConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionConfig. +func (in *SubscriptionConfig) DeepCopy() *SubscriptionConfig { + if in == nil { + return nil + } + out := new(SubscriptionConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionList) DeepCopyInto(out *SubscriptionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Subscription, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionList. +func (in *SubscriptionList) DeepCopy() *SubscriptionList { + if in == nil { + return nil + } + out := new(SubscriptionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SubscriptionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionSpec) DeepCopyInto(out *SubscriptionSpec) { + *out = *in + if in.ProtocolSettings != nil { + in, out := &in.ProtocolSettings, &out.ProtocolSettings + *out = new(ProtocolSettings) + (*in).DeepCopyInto(*out) + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(BEBFilters) + (*in).DeepCopyInto(*out) + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = new(SubscriptionConfig) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionSpec. +func (in *SubscriptionSpec) DeepCopy() *SubscriptionSpec { + if in == nil { + return nil + } + out := new(SubscriptionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionStatus) DeepCopyInto(out *SubscriptionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CleanEventTypes != nil { + in, out := &in.CleanEventTypes, &out.CleanEventTypes + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.EmsSubscriptionStatus != nil { + in, out := &in.EmsSubscriptionStatus, &out.EmsSubscriptionStatus + *out = new(EmsSubscriptionStatus) + **out = **in + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = new(SubscriptionConfig) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionStatus. +func (in *SubscriptionStatus) DeepCopy() *SubscriptionStatus { + if in == nil { + return nil + } + out := new(SubscriptionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WebhookAuth) DeepCopyInto(out *WebhookAuth) { + *out = *in + if in.Scope != nil { + in, out := &in.Scope, &out.Scope + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookAuth. +func (in *WebhookAuth) DeepCopy() *WebhookAuth { + if in == nil { + return nil + } + out := new(WebhookAuth) + in.DeepCopyInto(out) + return out +} diff --git a/api/eventing/v1alpha2/condition.go b/api/eventing/v1alpha2/condition.go new file mode 100644 index 00000000..50d33005 --- /dev/null +++ b/api/eventing/v1alpha2/condition.go @@ -0,0 +1,289 @@ +package v1alpha2 + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type ConditionType string + +const ( + ConditionSubscribed ConditionType = "Subscribed" + ConditionSubscriptionActive ConditionType = "Subscription active" + ConditionAPIRuleStatus ConditionType = "APIRule status" + ConditionWebhookCallStatus ConditionType = "Webhook call status" + + ConditionPublisherProxyReady ConditionType = "Publisher Proxy Ready" + ConditionControllerReady ConditionType = "Subscription Controller Ready" +) + +var allSubscriptionConditions = MakeSubscriptionConditions() + +type Condition struct { + // Short description of the condition. + Type ConditionType `json:"type,omitempty"` + + // Status of the condition. The value is either `True`, `False`, or `Unknown`. + Status corev1.ConditionStatus `json:"status"` + + // Defines the date of the last condition status change. + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` + // Defines the reason for the condition status change. + Reason ConditionReason `json:"reason,omitempty"` + // Provides more details about the condition status change. + Message string `json:"message,omitempty"` +} + +type ConditionReason string + +const ( + // JetStream Conditions. + ConditionReasonNATSSubscriptionActive ConditionReason = "NATS Subscription active" + ConditionReasonNATSSubscriptionNotActive ConditionReason = "NATS Subscription not active" + + // EventMesh Conditions. + ConditionReasonSubscriptionCreated ConditionReason = "EventMesh Subscription created" + ConditionReasonSubscriptionCreationFailed ConditionReason = "EventMesh Subscription creation failed" + ConditionReasonSubscriptionActive ConditionReason = "EventMesh Subscription active" + ConditionReasonSubscriptionNotActive ConditionReason = "EventMesh Subscription not active" + ConditionReasonSubscriptionDeleted ConditionReason = "EventMesh Subscription deleted" + ConditionReasonAPIRuleStatusReady ConditionReason = "APIRule status ready" + ConditionReasonAPIRuleStatusNotReady ConditionReason = "APIRule status not ready" + ConditionReasonWebhookCallStatus ConditionReason = "EventMesh Subscription webhook call no errors status" +) + +// initializeConditions sets unset conditions to Unknown. +func initializeConditions(initialConditions, currentConditions []Condition) []Condition { + givenConditions := make(map[ConditionType]Condition) + + // Create map of Condition per ConditionType. + for _, condition := range currentConditions { + givenConditions[condition.Type] = condition + } + + finalConditions := currentConditions + // Check if every Condition is present in the current Conditions. + for _, expectedCondition := range initialConditions { + if _, ok := givenConditions[expectedCondition.Type]; !ok { + // and add it if it is missing + finalConditions = append(finalConditions, expectedCondition) + } + } + return finalConditions +} + +// InitializeConditions sets unset Subscription conditions to Unknown. +func (s *SubscriptionStatus) InitializeConditions() { + initialConditions := MakeSubscriptionConditions() + s.Conditions = initializeConditions(initialConditions, s.Conditions) +} + +func (s SubscriptionStatus) IsReady() bool { + if !ContainSameConditionTypes(allSubscriptionConditions, s.Conditions) { + return false + } + + // The Subscription is ready if all its conditions are evaluated to true. + for _, c := range s.Conditions { + if c.Status != corev1.ConditionTrue { + return false + } + } + return true +} + +func (s SubscriptionStatus) FindCondition(conditionType ConditionType) *Condition { + for _, condition := range s.Conditions { + if conditionType == condition.Type { + return &condition + } + } + return nil +} + +// ShouldUpdateReadyStatus checks if there is a mismatch between the +// Subscription Ready status and the Ready status of all the conditions. +func (s SubscriptionStatus) ShouldUpdateReadyStatus() bool { + if !s.Ready && s.IsReady() || s.Ready && !s.IsReady() { + return true + } + return false +} + +// MakeSubscriptionConditions creates a map of all conditions which the Subscription should have. +func MakeSubscriptionConditions() []Condition { + conditions := []Condition{ + { + Type: ConditionAPIRuleStatus, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + { + Type: ConditionSubscribed, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + { + Type: ConditionSubscriptionActive, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + { + Type: ConditionWebhookCallStatus, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + } + return conditions +} + +func ContainSameConditionTypes(conditions1, conditions2 []Condition) bool { + if len(conditions1) != len(conditions2) { + return false + } + + for _, condition := range conditions1 { + if !containConditionType(conditions2, condition.Type) { + return false + } + } + + return true +} + +func containConditionType(conditions []Condition, conditionType ConditionType) bool { + for _, condition := range conditions { + if condition.Type == conditionType { + return true + } + } + + return false +} + +func MakeCondition(conditionType ConditionType, reason ConditionReason, status corev1.ConditionStatus, message string) Condition { + return Condition{ + Type: conditionType, + Status: status, + LastTransitionTime: metav1.Now(), + Reason: reason, + Message: message, + } +} + +func (s *SubscriptionStatus) IsConditionSubscribed() bool { + for _, condition := range s.Conditions { + if condition.Type == ConditionSubscribed && condition.Status == corev1.ConditionTrue { + return true + } + } + return false +} + +func (s *SubscriptionStatus) IsConditionWebhookCall() bool { + for _, condition := range s.Conditions { + if condition.Type == ConditionWebhookCallStatus && + (condition.Status == corev1.ConditionTrue || condition.Status == corev1.ConditionUnknown) { + return true + } + } + return false +} + +func (s *SubscriptionStatus) GetConditionAPIRuleStatus() corev1.ConditionStatus { + for _, condition := range s.Conditions { + if condition.Type == ConditionAPIRuleStatus { + return condition.Status + } + } + return corev1.ConditionUnknown +} + +func (s *SubscriptionStatus) SetConditionAPIRuleStatus(err error) { + reason := ConditionReasonAPIRuleStatusReady + status := corev1.ConditionTrue + message := "" + if err != nil { + reason = ConditionReasonAPIRuleStatusNotReady + status = corev1.ConditionFalse + message = err.Error() + } + + newConditions := []Condition{MakeCondition(ConditionAPIRuleStatus, reason, status, message)} + for _, condition := range s.Conditions { + if condition.Type == ConditionAPIRuleStatus { + continue + } + newConditions = append(newConditions, condition) + } + s.Conditions = newConditions +} + +// ConditionsEquals checks if two list of conditions are equal. +func ConditionsEquals(existing, expected []Condition) bool { + // not equal if length is different + if len(existing) != len(expected) { + return false + } + + // compile map of Conditions per ConditionType + existingMap := make(map[ConditionType]Condition, len(existing)) + for _, value := range existing { + existingMap[value.Type] = value + } + + for _, value := range expected { + if !ConditionEquals(existingMap[value.Type], value) { + return false + } + } + + return true +} + +// ConditionsEquals checks if two conditions are equal. +func ConditionEquals(existing, expected Condition) bool { + isTypeEqual := existing.Type == expected.Type + isStatusEqual := existing.Status == expected.Status + isReasonEqual := existing.Reason == expected.Reason + isMessageEqual := existing.Message == expected.Message + + if !isStatusEqual || !isReasonEqual || !isMessageEqual || !isTypeEqual { + return false + } + + return true +} + +func CreateMessageForConditionReasonSubscriptionCreated(eventMeshName string) string { + return fmt.Sprintf("EventMesh subscription name is: %s", eventMeshName) +} + +// GetSubscriptionActiveCondition updates the ConditionSubscriptionActive condition based on the given error value. +func GetSubscriptionActiveCondition(sub *Subscription, err error) []Condition { + subscriptionActiveCondition := Condition{ + Type: ConditionSubscriptionActive, + LastTransitionTime: metav1.Now(), + } + if err == nil { + subscriptionActiveCondition.Status = corev1.ConditionTrue + subscriptionActiveCondition.Reason = ConditionReasonNATSSubscriptionActive + } else { + subscriptionActiveCondition.Message = err.Error() + subscriptionActiveCondition.Reason = ConditionReasonNATSSubscriptionNotActive + subscriptionActiveCondition.Status = corev1.ConditionFalse + } + for _, activeCond := range sub.Status.Conditions { + if activeCond.Type == ConditionSubscriptionActive { + if subscriptionActiveCondition.Status == activeCond.Status && + subscriptionActiveCondition.Reason == activeCond.Reason && + subscriptionActiveCondition.Message == activeCond.Message { + return []Condition{activeCond} + } + } + } + + return []Condition{subscriptionActiveCondition} +} diff --git a/api/eventing/v1alpha2/condition_unit_test.go b/api/eventing/v1alpha2/condition_unit_test.go new file mode 100644 index 00000000..86368d02 --- /dev/null +++ b/api/eventing/v1alpha2/condition_unit_test.go @@ -0,0 +1,553 @@ +package v1alpha2_test + +import ( + "reflect" + "testing" + "time" + + eventingtesting "github.com/kyma-project/eventing-manager/testing" + "github.com/pkg/errors" + + "github.com/stretchr/testify/require" + + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" +) + +func Test_InitializeSubscriptionConditions(t *testing.T) { + var tests = []struct { + name string + givenConditions []v1alpha2.Condition + }{ + { + name: "Conditions empty", + givenConditions: v1alpha2.MakeSubscriptionConditions(), + }, + { + name: "Conditions partially initialized", + givenConditions: []v1alpha2.Condition{ + { + Type: v1alpha2.ConditionSubscribed, + LastTransitionTime: metav1.Now(), + Status: corev1.ConditionUnknown, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // given + g := NewGomegaWithT(t) + s := v1alpha2.SubscriptionStatus{} + s.Conditions = tt.givenConditions + wantConditionTypes := []v1alpha2.ConditionType{ + v1alpha2.ConditionSubscribed, + v1alpha2.ConditionSubscriptionActive, + v1alpha2.ConditionAPIRuleStatus, + v1alpha2.ConditionWebhookCallStatus, + } + + // when + s.InitializeConditions() + + // then + g.Expect(s.Conditions).To(HaveLen(len(wantConditionTypes))) + foundConditionTypes := make([]v1alpha2.ConditionType, 0) + for _, condition := range s.Conditions { + g.Expect(condition.Status).To(BeEquivalentTo(corev1.ConditionUnknown)) + foundConditionTypes = append(foundConditionTypes, condition.Type) + } + g.Expect(wantConditionTypes).To(ConsistOf(foundConditionTypes)) + }) + } +} + +func Test_IsReady(t *testing.T) { + testCases := []struct { + name string + givenConditions []v1alpha2.Condition + wantReadyStatus bool + }{ + { + name: "should not be ready if conditions are nil", + givenConditions: nil, + wantReadyStatus: false, + }, + { + name: "should not be ready if conditions are empty", + givenConditions: []v1alpha2.Condition{{}}, + wantReadyStatus: false, + }, + { + name: "should not be ready if only ConditionSubscribed is available and true", + givenConditions: []v1alpha2.Condition{{ + Type: v1alpha2.ConditionSubscribed, + Status: corev1.ConditionTrue, + }}, + wantReadyStatus: false, + }, + { + name: "should not be ready if only ConditionSubscriptionActive is available and true", + givenConditions: []v1alpha2.Condition{{ + Type: v1alpha2.ConditionSubscriptionActive, + Status: corev1.ConditionTrue, + }}, + wantReadyStatus: false, + }, + { + name: "should not be ready if only ConditionAPIRuleStatus is available and true", + givenConditions: []v1alpha2.Condition{{ + Type: v1alpha2.ConditionAPIRuleStatus, + Status: corev1.ConditionTrue, + }}, + wantReadyStatus: false, + }, + { + name: "should not be ready if all conditions are unknown", + givenConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionUnknown}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionUnknown}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionUnknown}, + }, + wantReadyStatus: false, + }, + { + name: "should not be ready if all conditions are false", + givenConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionFalse}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionFalse}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionFalse}, + }, + wantReadyStatus: false, + }, + { + name: "should be ready if all conditions are true", + givenConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionTrue}, + }, + wantReadyStatus: true, + }, + } + + status := v1alpha2.SubscriptionStatus{} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + status.Conditions = tc.givenConditions + if gotReadyStatus := status.IsReady(); tc.wantReadyStatus != gotReadyStatus { + t.Errorf("Subscription status is not valid, want: %v but got: %v", tc.wantReadyStatus, gotReadyStatus) + } + }) + } +} + +func Test_FindCondition(t *testing.T) { + currentTime := metav1.NewTime(time.Now()) + + testCases := []struct { + name string + givenConditions []v1alpha2.Condition + findConditionType v1alpha2.ConditionType + wantCondition *v1alpha2.Condition + }{ + { + name: "should be able to find the present condition", + givenConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue, LastTransitionTime: currentTime}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionTrue, LastTransitionTime: currentTime}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue, LastTransitionTime: currentTime}, + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionTrue, LastTransitionTime: currentTime}, + }, + findConditionType: v1alpha2.ConditionSubscriptionActive, + wantCondition: &v1alpha2.Condition{ + Type: v1alpha2.ConditionSubscriptionActive, + Status: corev1.ConditionTrue, LastTransitionTime: currentTime, + }, + }, + { + name: "should not be able to find the non-present condition", + givenConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue, LastTransitionTime: currentTime}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue, LastTransitionTime: currentTime}, + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionTrue, LastTransitionTime: currentTime}, + }, + findConditionType: v1alpha2.ConditionSubscriptionActive, + wantCondition: nil, + }, + } + + status := v1alpha2.SubscriptionStatus{} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + status.Conditions = tc.givenConditions + + if gotCondition := status.FindCondition(tc.findConditionType); !reflect.DeepEqual(tc.wantCondition, gotCondition) { + t.Errorf("Subscription FindCondition failed, want: %v but got: %v", tc.wantCondition, gotCondition) + } + }) + } +} + +func Test_ShouldUpdateReadyStatus(t *testing.T) { + testCases := []struct { + name string + subscriptionReady bool + subscriptionConditions []v1alpha2.Condition + wantStatus bool + }{ + { + name: "should not update if the subscription is ready and the conditions are ready", + subscriptionReady: true, + subscriptionConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionTrue}, + }, + wantStatus: false, + }, + { + name: "should not update if the subscription is not ready and the conditions are not ready", + subscriptionReady: false, + subscriptionConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionFalse}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionFalse}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionFalse}, + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionFalse}, + }, + wantStatus: false, + }, + { + name: "should update if the subscription is not ready and the conditions are ready", + subscriptionReady: false, + subscriptionConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionTrue}, + }, + wantStatus: true, + }, + { + name: "should update if the subscription is ready and the conditions are not ready", + subscriptionReady: true, + subscriptionConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionFalse}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionFalse}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionFalse}, + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionFalse}, + }, + wantStatus: true, + }, + { + name: "should update if the subscription is ready and some of the conditions are missing", + subscriptionReady: true, + subscriptionConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionUnknown}, + }, + wantStatus: true, + }, + { + name: "should not update if the subscription is not ready and some of the conditions are missing", + subscriptionReady: false, + subscriptionConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionUnknown}, + }, + wantStatus: false, + }, + { + name: "should update if the subscription is ready and the status of the conditions are unknown", + subscriptionReady: true, + subscriptionConditions: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionUnknown}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionUnknown}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionUnknown}, + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionUnknown}, + }, + wantStatus: true, + }, + } + + status := v1alpha2.SubscriptionStatus{} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + status.Conditions = tc.subscriptionConditions + status.Ready = tc.subscriptionReady + if gotStatus := status.ShouldUpdateReadyStatus(); tc.wantStatus != gotStatus { + t.Errorf("ShouldUpdateReadyStatus is not valid, want: %v but got: %v", tc.wantStatus, gotStatus) + } + }) + } +} + +func Test_conditionsEquals(t *testing.T) { + testCases := []struct { + name string + conditionsSet1 []v1alpha2.Condition + conditionsSet2 []v1alpha2.Condition + wantEqualStatus bool + }{ + { + name: "should not be equal if the number of conditions are not equal", + conditionsSet1: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha2.Condition{}, + wantEqualStatus: false, + }, + { + name: "should be equal if the conditions are the same", + conditionsSet1: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + wantEqualStatus: true, + }, + { + name: "should not be equal if the condition types are different", + conditionsSet1: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionWebhookCallStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionSubscriptionActive, Status: corev1.ConditionTrue}, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the condition types are the same but the status is different", + conditionsSet1: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionFalse}, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the condition types are different but the status is the same", + conditionsSet1: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionFalse}, + }, + conditionsSet2: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the condition types are different and an empty key is referenced", + conditionsSet1: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + }, + conditionsSet2: []v1alpha2.Condition{ + {Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue}, + {Type: v1alpha2.ConditionControllerReady, Status: corev1.ConditionTrue}, + }, + wantEqualStatus: false, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if gotEqualStatus := v1alpha2.ConditionsEquals(tc.conditionsSet1, tc.conditionsSet2); tc.wantEqualStatus != gotEqualStatus { + t.Errorf("The list of conditions are not equal, want: %v but got: %v", tc.wantEqualStatus, gotEqualStatus) + } + }) + } +} + +func Test_conditionEquals(t *testing.T) { + testCases := []struct { + name string + condition1 v1alpha2.Condition + condition2 v1alpha2.Condition + wantEqualStatus bool + }{ + { + name: "should not be equal if the types are the same but the status is different", + condition1: v1alpha2.Condition{ + Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue, + }, + + condition2: v1alpha2.Condition{ + Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionUnknown, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the types are different but the status is the same", + condition1: v1alpha2.Condition{ + Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue, + }, + + condition2: v1alpha2.Condition{ + Type: v1alpha2.ConditionAPIRuleStatus, Status: corev1.ConditionTrue, + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the message fields are different", + condition1: v1alpha2.Condition{ + Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue, Message: "", + }, + + condition2: v1alpha2.Condition{ + Type: v1alpha2.ConditionSubscribed, Status: corev1.ConditionTrue, Message: "some message", + }, + wantEqualStatus: false, + }, + { + name: "should not be equal if the reason fields are different", + condition1: v1alpha2.Condition{ + Type: v1alpha2.ConditionSubscribed, + Status: corev1.ConditionTrue, + Reason: v1alpha2.ConditionReasonSubscriptionDeleted, + }, + + condition2: v1alpha2.Condition{ + Type: v1alpha2.ConditionSubscribed, + Status: corev1.ConditionTrue, + Reason: v1alpha2.ConditionReasonSubscriptionActive, + }, + wantEqualStatus: false, + }, + { + name: "should be equal if all the fields are the same", + condition1: v1alpha2.Condition{ + Type: v1alpha2.ConditionAPIRuleStatus, + Status: corev1.ConditionFalse, + Reason: v1alpha2.ConditionReasonAPIRuleStatusNotReady, + Message: "API Rule is not ready", + }, + condition2: v1alpha2.Condition{ + Type: v1alpha2.ConditionAPIRuleStatus, + Status: corev1.ConditionFalse, + Reason: v1alpha2.ConditionReasonAPIRuleStatusNotReady, + Message: "API Rule is not ready", + }, + wantEqualStatus: true, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if gotEqualStatus := v1alpha2.ConditionEquals(tc.condition1, tc.condition2); tc.wantEqualStatus != gotEqualStatus { + t.Errorf("The conditions are not equal, want: %v but got: %v", tc.wantEqualStatus, gotEqualStatus) + } + }) + } +} + +func Test_CreateMessageForConditionReasonSubscriptionCreated(t *testing.T) { + testCases := []struct { + name string + givenName string + wantName string + }{ + { + name: "with name 1", + givenName: "test-one", + wantName: "EventMesh subscription name is: test-one", + }, + { + name: "with name 2", + givenName: "test-second", + wantName: "EventMesh subscription name is: test-second", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + require.Equal(t, tc.wantName, v1alpha2.CreateMessageForConditionReasonSubscriptionCreated(tc.givenName)) + }) + } +} + +func Test_SetConditionSubscriptionActive(t *testing.T) { + err := errors.New("some error") + conditionReady := v1alpha2.MakeCondition( + v1alpha2.ConditionSubscriptionActive, + v1alpha2.ConditionReasonNATSSubscriptionActive, + corev1.ConditionTrue, "") + conditionReady.LastTransitionTime = metav1.NewTime(time.Now().AddDate(0, 0, -1)) + conditionNotReady := v1alpha2.MakeCondition( + v1alpha2.ConditionSubscriptionActive, + v1alpha2.ConditionReasonNATSSubscriptionNotActive, + corev1.ConditionFalse, err.Error()) + conditionNotReady.LastTransitionTime = metav1.NewTime(time.Now().AddDate(0, 0, -2)) + sub := eventingtesting.NewSubscription("test", "test") + + testCases := []struct { + name string + givenConditions []v1alpha2.Condition + givenError error + wantConditions []v1alpha2.Condition + wantLastTransitionTime *metav1.Time + }{ + { + name: "no error should set the condition to ready", + givenError: nil, + givenConditions: []v1alpha2.Condition{conditionNotReady}, + wantConditions: []v1alpha2.Condition{conditionReady}, + }, + { + name: "error should set the condition to not ready", + givenError: err, + givenConditions: []v1alpha2.Condition{conditionReady}, + wantConditions: []v1alpha2.Condition{conditionNotReady}, + }, + { + name: "the same condition should not change the lastTransitionTime in case of Sub active", + givenError: nil, + givenConditions: []v1alpha2.Condition{conditionReady}, + wantConditions: []v1alpha2.Condition{{ + Type: v1alpha2.ConditionSubscriptionActive, + Reason: v1alpha2.ConditionReasonNATSSubscriptionActive, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.Now(), + }}, + wantLastTransitionTime: &conditionReady.LastTransitionTime, + }, + { + name: "the same condition should not change the lastTransitionTime in case of error", + givenError: err, + givenConditions: []v1alpha2.Condition{conditionNotReady}, + wantConditions: []v1alpha2.Condition{{ + Type: v1alpha2.ConditionSubscriptionActive, + Reason: v1alpha2.ConditionReasonNATSSubscriptionNotActive, + Status: corev1.ConditionFalse, + Message: err.Error(), + LastTransitionTime: metav1.Now(), + }}, + wantLastTransitionTime: &conditionNotReady.LastTransitionTime, + }, + } + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + // given + sub.Status.Conditions = tc.givenConditions + + // when + conditions := v1alpha2.GetSubscriptionActiveCondition(sub, tc.givenError) + + // then + require.True(t, v1alpha2.ConditionsEquals(conditions, tc.wantConditions)) + if tc.wantLastTransitionTime != nil { + require.Equal(t, *tc.wantLastTransitionTime, conditions[0].LastTransitionTime) + } + }) + } +} diff --git a/api/eventing/v1alpha2/constants.go b/api/eventing/v1alpha2/constants.go new file mode 100644 index 00000000..3536f72d --- /dev/null +++ b/api/eventing/v1alpha2/constants.go @@ -0,0 +1,23 @@ +package v1alpha2 + +const ( + TypeMatchingStandard TypeMatching = "standard" + TypeMatchingExact TypeMatching = "exact" + + // config fields. + MaxInFlightMessages = "maxInFlightMessages" + + // protocol settings. + Protocol = "protocol" + ProtocolSettingsContentMode = "contentMode" + ProtocolSettingsExemptHandshake = "exemptHandshake" + ProtocolSettingsQos = "qos" + + // webhook auth fields. + WebhookAuthType = "type" + WebhookAuthGrantType = "grantType" + WebhookAuthClientID = "clientId" + WebhookAuthClientSecret = "clientSecret" + WebhookAuthTokenURL = "tokenUrl" + WebhookAuthScope = "scope" +) diff --git a/api/eventing/v1alpha2/errors.go b/api/eventing/v1alpha2/errors.go new file mode 100644 index 00000000..09fe2668 --- /dev/null +++ b/api/eventing/v1alpha2/errors.go @@ -0,0 +1,41 @@ +package v1alpha2 + +import ( + "fmt" + "strconv" + + "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" + + "k8s.io/apimachinery/pkg/util/validation/field" +) + +//nolint:gochecknoglobals // these are required for testing +var ( + SourcePath = field.NewPath("spec").Child("source") + TypesPath = field.NewPath("spec").Child("types") + ConfigPath = field.NewPath("spec").Child("config") + SinkPath = field.NewPath("spec").Child("sink") + NSPath = field.NewPath("metadata").Child("namespace") + + EmptyErrDetail = "must not be empty" + InvalidURIErrDetail = "must be valid as per RFC 3986" + DuplicateTypesErrDetail = "must not have duplicate types" + LengthErrDetail = "must not be of length zero" + MinSegmentErrDetail = fmt.Sprintf("must have minimum %s segments", strconv.Itoa(minEventTypeSegments)) + InvalidPrefixErrDetail = fmt.Sprintf("must not have %s as type prefix", InvalidPrefix) + StringIntErrDetail = fmt.Sprintf("%s must be a stringified int value", MaxInFlightMessages) + + InvalidQosErrDetail = fmt.Sprintf("must be a valid QoS value %s or %s", + types.QosAtLeastOnce, types.QosAtMostOnce) + InvalidAuthTypeErrDetail = fmt.Sprintf("must be a valid Auth Type value %s", types.AuthTypeClientCredentials) + InvalidGrantTypeErrDetail = fmt.Sprintf("must be a valid Grant Type value %s", types.GrantTypeClientCredentials) + + MissingSchemeErrDetail = "must have URL scheme 'http' or 'https'" + SuffixMissingErrDetail = fmt.Sprintf("must have valid sink URL suffix %s", ClusterLocalURLSuffix) + SubDomainsErrDetail = fmt.Sprintf("must have sink URL with %d sub-domains: ", subdomainSegments) + NSMismatchErrDetail = "must have the same namespace as the subscriber: " +) + +func MakeInvalidFieldError(path *field.Path, subName, detail string) *field.Error { + return field.Invalid(path, subName, detail) +} diff --git a/api/eventing/v1alpha2/groupversion_info.go b/api/eventing/v1alpha2/groupversion_info.go new file mode 100644 index 00000000..bb2cb894 --- /dev/null +++ b/api/eventing/v1alpha2/groupversion_info.go @@ -0,0 +1,24 @@ +// Package v1alpha2 contains API Schema definitions for the eventing v1alpha2 API group. +// +kubebuilder:object:generate=true +// +groupName=eventing.kyma-project.io +package v1alpha2 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "eventing.kyma-project.io", Version: "v1alpha2"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme + + //nolint:gochecknoglobals // required for tests + // GroupKind is group kind to identify these objects. + GroupKind = schema.GroupKind{Group: "eventing.kyma-project.io", Kind: "Subscription"} +) diff --git a/api/eventing/v1alpha2/status_types.go b/api/eventing/v1alpha2/status_types.go new file mode 100644 index 00000000..5ce64c7a --- /dev/null +++ b/api/eventing/v1alpha2/status_types.go @@ -0,0 +1,97 @@ +package v1alpha2 + +type EventType struct { + // Event type as specified in the Subscription spec. + OriginalType string `json:"originalType"` + // Event type after it was cleaned up from backend compatible characters. + CleanType string `json:"cleanType"` +} + +// Backend contains Backend-specific fields. +type Backend struct { + // EventMesh-specific fields + + // Checksum for the Subscription custom resource. + // +optional + Ev2hash int64 `json:"ev2hash,omitempty"` + + // Hash used to identify an EventMesh Subscription retrieved from the server without the WebhookAuth config. + // +optional + EventMeshHash int64 `json:"emshash,omitempty"` + + // Hash used to identify an EventMesh Subscription posted to the server without the WebhookAuth config. + // +optional + EventMeshLocalHash int64 `json:"eventMeshLocalHash,omitempty"` + + // Hash used to identify the WebhookAuth of an EventMesh Subscription existing on the server. + // +optional + WebhookAuthHash int64 `json:"webhookAuthHash,omitempty"` + + // Webhook URL used by EventMesh to trigger subscribers. + // +optional + ExternalSink string `json:"externalSink,omitempty"` + + // Provides the reason if a Subscription failed activation in EventMesh. + // +optional + FailedActivation string `json:"failedActivation,omitempty"` + + // Name of the APIRule which is used by the Subscription. + // +optional + APIRuleName string `json:"apiRuleName,omitempty"` + + // Status of the Subscription as reported by EventMesh. + // +optional + EventMeshSubscriptionStatus *EventMeshSubscriptionStatus `json:"emsSubscriptionStatus,omitempty"` + + // List of event type to consumer name mappings for the NATS backend. + // +optional + Types []JetStreamTypes `json:"types,omitempty"` + + // List of mappings from event type to EventMesh compatible types. Used only with EventMesh as the backend. + // +optional + EmsTypes []EventMeshTypes `json:"emsTypes,omitempty"` +} + +type EventMeshSubscriptionStatus struct { + // Status of the Subscription as reported by the backend. + // +optional + Status string `json:"status,omitempty"` + + // Reason for the current status. + // +optional + StatusReason string `json:"statusReason,omitempty"` + + // Timestamp of the last successful delivery. + // +optional + LastSuccessfulDelivery string `json:"lastSuccessfulDelivery,omitempty"` + + // Timestamp of the last failed delivery. + // +optional + LastFailedDelivery string `json:"lastFailedDelivery,omitempty"` + + // Reason for the last failed delivery. + // +optional + LastFailedDeliveryReason string `json:"lastFailedDeliveryReason,omitempty"` +} + +type JetStreamTypes struct { + // Event type that was originally used to subscribe. + OriginalType string `json:"originalType"` + // Name of the JetStream consumer created for the event type. + ConsumerName string `json:"consumerName,omitempty"` +} + +type EventMeshTypes struct { + // Event type that was originally used to subscribe. + OriginalType string `json:"originalType"` + // Event type that is used on the EventMesh backend. + EventMeshType string `json:"eventMeshType"` +} + +// CopyHashes copies the precomputed hashes from the given backend. +func (b *Backend) CopyHashes(src Backend) { + b.Ev2hash = src.Ev2hash + b.EventMeshHash = src.EventMeshHash + b.WebhookAuthHash = src.WebhookAuthHash + b.EventMeshLocalHash = src.EventMeshLocalHash +} diff --git a/api/eventing/v1alpha2/status_types_test.go b/api/eventing/v1alpha2/status_types_test.go new file mode 100644 index 00000000..d3fbe441 --- /dev/null +++ b/api/eventing/v1alpha2/status_types_test.go @@ -0,0 +1,35 @@ +package v1alpha2 + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBackend_CopyHashes(t *testing.T) { + // given + b := Backend{} + + // then + require.Equal(t, int64(0), b.Ev2hash) + require.Equal(t, int64(0), b.EventMeshHash) + require.Equal(t, int64(0), b.WebhookAuthHash) + require.Equal(t, int64(0), b.EventMeshLocalHash) + + // given + src := Backend{ + Ev2hash: int64(1118518533334734626), + EventMeshHash: int64(1748405436686967274), + WebhookAuthHash: int64(1118518533334734627), + EventMeshLocalHash: int64(1883494500014499539), + } + + // when + b.CopyHashes(src) + + // then + require.Equal(t, src.Ev2hash, b.Ev2hash) + require.Equal(t, src.EventMeshHash, b.EventMeshHash) + require.Equal(t, src.WebhookAuthHash, b.WebhookAuthHash) + require.Equal(t, src.EventMeshLocalHash, b.EventMeshLocalHash) +} diff --git a/api/eventing/v1alpha2/subscription_types.go b/api/eventing/v1alpha2/subscription_types.go new file mode 100644 index 00000000..ff5f28c0 --- /dev/null +++ b/api/eventing/v1alpha2/subscription_types.go @@ -0,0 +1,146 @@ +package v1alpha2 + +import ( + "encoding/json" + "strconv" + + "github.com/kyma-project/eventing-manager/pkg/env" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + + "github.com/kyma-project/eventing-manager/pkg/utils" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type TypeMatching string + +var Finalizer = GroupVersion.Group + +// Defines the desired state of the Subscription. +type SubscriptionSpec struct { + // Unique identifier of the Subscription, read-only. + // +optional + ID string `json:"id,omitempty"` + + // Kubernetes Service that should be used as a target for the events that match the Subscription. + // Must exist in the same Namespace as the Subscription. + Sink string `json:"sink"` + + // Defines how types should be handled.
+ // - `standard`: backend-specific logic will be applied to the configured source and types.
+ // - `exact`: no further processing will be applied to the configured source and types. + TypeMatching TypeMatching `json:"typeMatching,omitempty"` + + // Defines the origin of the event. + Source string `json:"source"` + + // List of event types that will be used for subscribing on the backend. + Types []string `json:"types"` + + // Map of configuration options that will be applied on the backend. + // +optional + Config map[string]string `json:"config,omitempty"` +} + +// SubscriptionStatus defines the observed state of Subscription. +// +kubebuilder:subresource:status +type SubscriptionStatus struct { + // Current state of the Subscription. + // +optional + Conditions []Condition `json:"conditions,omitempty"` + + // Overall readiness of the Subscription. + Ready bool `json:"ready"` + + // List of event types after cleanup for use with the configured backend. + Types []EventType `json:"types"` + + // Backend-specific status which is applicable to the active backend only. + Backend Backend `json:"backend,omitempty"` +} + +// +kubebuilder:storageversion +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// Subscription is the Schema for the subscriptions API. +type Subscription struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SubscriptionSpec `json:"spec,omitempty"` + Status SubscriptionStatus `json:"status,omitempty"` +} + +// MarshalJSON implements the json.Marshaler interface. +// If the SubscriptionStatus.CleanEventTypes is nil, it will be initialized to an empty slice of stings. +// It is needed because the Kubernetes APIServer will reject requests containing null in the JSON payload. +func (s Subscription) MarshalJSON() ([]byte, error) { + // Use type alias to copy the subscription without causing an infinite recursion when calling json.Marshal. + type Alias Subscription + a := Alias(s) + if a.Status.Types == nil { + a.Status.InitializeEventTypes() + } + return json.Marshal(a) +} + +// GetMaxInFlightMessages tries to convert the string-type maxInFlight to the integer. +func (s *Subscription) GetMaxInFlightMessages(defaults *env.DefaultSubscriptionConfig) int { + val, err := strconv.Atoi(s.Spec.Config[MaxInFlightMessages]) + if err != nil { + return defaults.MaxInFlightMessages + } + return val +} + +// InitializeEventTypes initializes the SubscriptionStatus.Types with an empty slice of EventType. +func (s *SubscriptionStatus) InitializeEventTypes() { + s.Types = []EventType{} +} + +// GetUniqueTypes returns the de-duplicated types from subscription spec. +func (s *Subscription) GetUniqueTypes() []string { + result := make([]string, 0, len(s.Spec.Types)) + for _, t := range s.Spec.Types { + if !utils.ContainsString(result, t) { + result = append(result, t) + } + } + + return result +} + +func (s *Subscription) DuplicateWithStatusDefaults() *Subscription { + desiredSub := s.DeepCopy() + desiredSub.Status = SubscriptionStatus{} + return desiredSub +} + +func (s *Subscription) ToUnstructuredSub() (*unstructured.Unstructured, error) { + object, err := k8sruntime.DefaultUnstructuredConverter.ToUnstructured(&s) + if err != nil { + return nil, err + } + return &unstructured.Unstructured{Object: object}, nil +} + +// +kubebuilder:object:root=true + +// SubscriptionList contains a list of Subscription. +type SubscriptionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Subscription `json:"items"` +} + +func init() { //nolint:gochecknoinits + SchemeBuilder.Register(&Subscription{}, &SubscriptionList{}) +} + +// Hub marks this type as a conversion hub. +func (*Subscription) Hub() {} diff --git a/api/eventing/v1alpha2/subscription_types_test.go b/api/eventing/v1alpha2/subscription_types_test.go new file mode 100644 index 00000000..78610994 --- /dev/null +++ b/api/eventing/v1alpha2/subscription_types_test.go @@ -0,0 +1,68 @@ +package v1alpha2_test + +import ( + "testing" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" + + "github.com/kyma-project/eventing-manager/pkg/env" + "github.com/stretchr/testify/assert" +) + +func TestGetMaxInFlightMessages(t *testing.T) { + defaultSubConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: 5} + testCases := []struct { + name string + givenSubscription *v1alpha2.Subscription + wantResult int + }{ + { + name: "function should give the default MaxInFlight if the Subscription config is missing", + givenSubscription: &v1alpha2.Subscription{ + Spec: v1alpha2.SubscriptionSpec{ + Config: nil, + }, + }, + wantResult: defaultSubConfig.MaxInFlightMessages, + }, + { + name: "function should give the default MaxInFlight if it is missing in the Subscription config", + givenSubscription: &v1alpha2.Subscription{ + Spec: v1alpha2.SubscriptionSpec{ + Config: map[string]string{ + "otherConfigKey": "20"}, + }, + }, + wantResult: defaultSubConfig.MaxInFlightMessages, + }, + { + name: "function should give the expectedConfig", + givenSubscription: &v1alpha2.Subscription{ + Spec: v1alpha2.SubscriptionSpec{ + Config: map[string]string{ + v1alpha2.MaxInFlightMessages: "20"}, + }, + }, + wantResult: 20, + }, + { + name: "function should result into an error", + givenSubscription: &v1alpha2.Subscription{ + Spec: v1alpha2.SubscriptionSpec{ + Config: map[string]string{ + v1alpha2.MaxInFlightMessages: "nonInt"}, + }, + }, + wantResult: defaultSubConfig.MaxInFlightMessages, + }, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + result := tc.givenSubscription.GetMaxInFlightMessages(&defaultSubConfig) + + assert.Equal(t, tc.wantResult, result) + }) + } +} diff --git a/api/eventing/v1alpha2/subscription_webhook.go b/api/eventing/v1alpha2/subscription_webhook.go new file mode 100644 index 00000000..5b03e393 --- /dev/null +++ b/api/eventing/v1alpha2/subscription_webhook.go @@ -0,0 +1,200 @@ +package v1alpha2 + +import ( + "strconv" + "strings" + + "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" + + "github.com/kyma-project/eventing-manager/pkg/utils" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +const ( + DefaultMaxInFlightMessages = "10" + minEventTypeSegments = 2 + subdomainSegments = 5 + InvalidPrefix = "sap.kyma.custom" + ClusterLocalURLSuffix = "svc.cluster.local" + ValidSource = "source" +) + +func (s *Subscription) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(s). + Complete() +} + +//nolint: lll +//+kubebuilder:webhook:path=/mutate-eventing-kyma-project-io-v1alpha2-subscription,mutating=true,failurePolicy=fail,sideEffects=None,groups=eventing.kyma-project.io,resources=subscriptions,verbs=create;update,versions=v1alpha2,name=msubscription.kb.io,admissionReviewVersions=v1beta1 + +var _ webhook.Defaulter = &Subscription{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type. +func (s *Subscription) Default() { + if s.Spec.TypeMatching == "" { + s.Spec.TypeMatching = TypeMatchingStandard + } + if s.Spec.Config[MaxInFlightMessages] == "" { + if s.Spec.Config == nil { + s.Spec.Config = map[string]string{} + } + s.Spec.Config[MaxInFlightMessages] = DefaultMaxInFlightMessages + } +} + +//nolint: lll +//+kubebuilder:webhook:path=/validate-eventing-kyma-project-io-v1alpha2-subscription,mutating=false,failurePolicy=fail,sideEffects=None,groups=eventing.kyma-project.io,resources=subscriptions,verbs=create;update,versions=v1alpha2,name=vsubscription.kb.io,admissionReviewVersions=v1beta1 + +var _ webhook.Validator = &Subscription{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type. +func (s *Subscription) ValidateCreate() (admission.Warnings, error) { + return s.ValidateSubscription() +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. +func (s *Subscription) ValidateUpdate(_ runtime.Object) (admission.Warnings, error) { + return s.ValidateSubscription() +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type. +func (s *Subscription) ValidateDelete() (admission.Warnings, error) { + return nil, nil +} + +func (s *Subscription) ValidateSubscription() (admission.Warnings, error) { + var allErrs field.ErrorList + + if err := s.validateSubscriptionSource(); err != nil { + allErrs = append(allErrs, err) + } + if err := s.validateSubscriptionTypes(); err != nil { + allErrs = append(allErrs, err) + } + if err := s.validateSubscriptionConfig(); err != nil { + allErrs = append(allErrs, err...) + } + if err := s.validateSubscriptionSink(); err != nil { + allErrs = append(allErrs, err) + } + if len(allErrs) == 0 { + return nil, nil + } + + return nil, apierrors.NewInvalid(GroupKind, s.Name, allErrs) +} + +func (s *Subscription) validateSubscriptionSource() *field.Error { + if s.Spec.Source == "" && s.Spec.TypeMatching != TypeMatchingExact { + return MakeInvalidFieldError(SourcePath, s.Name, EmptyErrDetail) + } + // Check only if the source is valid for the cloud event, with a valid event type. + if IsInvalidCE(s.Spec.Source, "") { + return MakeInvalidFieldError(SourcePath, s.Name, InvalidURIErrDetail) + } + return nil +} + +func (s *Subscription) validateSubscriptionTypes() *field.Error { + if s.Spec.Types == nil || len(s.Spec.Types) == 0 { + return MakeInvalidFieldError(TypesPath, s.Name, EmptyErrDetail) + } + if len(s.GetUniqueTypes()) != len(s.Spec.Types) { + return MakeInvalidFieldError(TypesPath, s.Name, DuplicateTypesErrDetail) + } + for _, etype := range s.Spec.Types { + if len(etype) == 0 { + return MakeInvalidFieldError(TypesPath, s.Name, LengthErrDetail) + } + if segments := strings.Split(etype, "."); len(segments) < minEventTypeSegments { + return MakeInvalidFieldError(TypesPath, s.Name, MinSegmentErrDetail) + } + if s.Spec.TypeMatching != TypeMatchingExact && strings.HasPrefix(etype, InvalidPrefix) { + return MakeInvalidFieldError(TypesPath, s.Name, InvalidPrefixErrDetail) + } + // Check only is the event type is valid for the cloud event, with a valid source. + if IsInvalidCE(ValidSource, etype) { + return MakeInvalidFieldError(TypesPath, s.Name, InvalidURIErrDetail) + } + } + return nil +} + +func (s *Subscription) validateSubscriptionConfig() field.ErrorList { + var allErrs field.ErrorList + if isNotInt(s.Spec.Config[MaxInFlightMessages]) { + allErrs = append(allErrs, MakeInvalidFieldError(ConfigPath, s.Name, StringIntErrDetail)) + } + if s.ifKeyExistsInConfig(ProtocolSettingsQos) && types.IsInvalidQoS(s.Spec.Config[ProtocolSettingsQos]) { + allErrs = append(allErrs, MakeInvalidFieldError(ConfigPath, s.Name, InvalidQosErrDetail)) + } + if s.ifKeyExistsInConfig(WebhookAuthType) && types.IsInvalidAuthType(s.Spec.Config[WebhookAuthType]) { + allErrs = append(allErrs, MakeInvalidFieldError(ConfigPath, s.Name, InvalidAuthTypeErrDetail)) + } + if s.ifKeyExistsInConfig(WebhookAuthGrantType) && types.IsInvalidGrantType(s.Spec.Config[WebhookAuthGrantType]) { + allErrs = append(allErrs, MakeInvalidFieldError(ConfigPath, s.Name, InvalidGrantTypeErrDetail)) + } + return allErrs +} + +func (s *Subscription) validateSubscriptionSink() *field.Error { + if s.Spec.Sink == "" { + return MakeInvalidFieldError(SinkPath, s.Name, EmptyErrDetail) + } + + if !utils.IsValidScheme(s.Spec.Sink) { + return MakeInvalidFieldError(SinkPath, s.Name, MissingSchemeErrDetail) + } + + trimmedHost, subDomains, err := utils.GetSinkData(s.Spec.Sink) + if err != nil { + return MakeInvalidFieldError(SinkPath, s.Name, err.Error()) + } + + // Validate sink URL is a cluster local URL. + if !strings.HasSuffix(trimmedHost, ClusterLocalURLSuffix) { + return MakeInvalidFieldError(SinkPath, s.Name, SuffixMissingErrDetail) + } + + // We expected a sink in the format "service.namespace.svc.cluster.local". + if len(subDomains) != subdomainSegments { + return MakeInvalidFieldError(SinkPath, s.Name, SubDomainsErrDetail+trimmedHost) + } + + // Assumption: Subscription CR and Subscriber should be deployed in the same namespace. + svcNs := subDomains[1] + if s.Namespace != svcNs { + return MakeInvalidFieldError(NSPath, s.Name, NSMismatchErrDetail+svcNs) + } + + return nil +} + +func (s *Subscription) ifKeyExistsInConfig(key string) bool { + _, ok := s.Spec.Config[key] + return ok +} + +func isNotInt(value string) bool { + if _, err := strconv.Atoi(value); err != nil { + return true + } + return false +} + +func IsInvalidCE(source, eventType string) bool { + if source == "" { + return false + } + newEvent := utils.GetCloudEvent(eventType) + newEvent.SetSource(source) + err := newEvent.Validate() + return err != nil +} diff --git a/api/eventing/v1alpha2/subscription_webhook_unit_test.go b/api/eventing/v1alpha2/subscription_webhook_unit_test.go new file mode 100644 index 00000000..5fb87974 --- /dev/null +++ b/api/eventing/v1alpha2/subscription_webhook_unit_test.go @@ -0,0 +1,473 @@ +package v1alpha2_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/util/validation/field" + + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" + eventingtesting "github.com/kyma-project/eventing-manager/testing" +) + +const ( + subName = "sub" + subNamespace = "test" + sink = "https://eventing-nats.test.svc.cluster.local:8080" +) + +func Test_Default(t *testing.T) { + t.Parallel() + type TestCase struct { + name string + givenSub *v1alpha2.Subscription + wantSub *v1alpha2.Subscription + } + + testCases := []TestCase{ + { + name: "Add TypeMatching Standard and default MaxInFlightMessages value", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + ), + wantSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + ), + }, + { + name: "Add TypeMatching Standard only", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages("20"), + ), + wantSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages("20"), + eventingtesting.WithTypeMatchingStandard(), + ), + }, + { + name: "Add default MaxInFlightMessages value only", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithTypeMatchingExact(), + ), + wantSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithTypeMatchingExact(), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + ), + }, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + tc.givenSub.Default() + require.Equal(t, tc.givenSub, tc.wantSub) + }) + } +} + +func Test_validateSubscription(t *testing.T) { + t.Parallel() + type TestCase struct { + name string + givenSub *v1alpha2.Subscription + wantErr error + } + + testCases := []TestCase{ + { + name: "A valid subscription should not have errors", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithWebhookAuthForEventMesh(), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: nil, + }, + { + name: "empty source and TypeMatching Standard should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SourcePath, + subName, v1alpha2.EmptyErrDetail)}), + }, + { + name: "valid source and TypeMatching Standard should not return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: nil, + }, + { + name: "empty source and TypeMatching Exact should not return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingExact(), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: nil, + }, + { + name: "invalid URI reference as source should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource("s%ourc%e"), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SourcePath, + subName, v1alpha2.InvalidURIErrDetail)}), + }, + { + name: "nil types field should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.TypesPath, + subName, v1alpha2.EmptyErrDetail)}), + }, + { + name: "empty types field should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithTypes([]string{}), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.TypesPath, + subName, v1alpha2.EmptyErrDetail)}), + }, + { + name: "duplicate types should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithTypes([]string{eventingtesting.OrderCreatedV1Event, + eventingtesting.OrderCreatedV1Event}), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.TypesPath, + subName, v1alpha2.DuplicateTypesErrDetail)}), + }, + { + name: "empty event type should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithTypes([]string{eventingtesting.OrderCreatedV1Event, ""}), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.TypesPath, + subName, v1alpha2.LengthErrDetail)}), + }, + { + name: "lower than min segments should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithTypes([]string{"order"}), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.TypesPath, + subName, v1alpha2.MinSegmentErrDetail)}), + }, + { + name: "invalid prefix should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithTypes([]string{v1alpha2.InvalidPrefix}), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.TypesPath, + subName, v1alpha2.InvalidPrefixErrDetail)}), + }, + { + name: "invalid prefix with exact should not return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingExact(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithTypes([]string{v1alpha2.InvalidPrefix}), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(sink), + ), + wantErr: nil, + }, + { + name: "invalid maxInFlight value should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages("invalid"), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.ConfigPath, + subName, v1alpha2.StringIntErrDetail)}), + }, + { + name: "invalid QoS value should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithInvalidProtocolSettingsQos(), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.ConfigPath, + subName, v1alpha2.InvalidQosErrDetail)}), + }, + { + name: "invalid webhook auth type value should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithInvalidWebhookAuthType(), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.ConfigPath, + subName, v1alpha2.InvalidAuthTypeErrDetail)}), + }, + { + name: "invalid webhook grant type value should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithInvalidWebhookAuthGrantType(), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.ConfigPath, + subName, v1alpha2.InvalidGrantTypeErrDetail)}), + }, + { + name: "missing sink should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SinkPath, + subName, v1alpha2.EmptyErrDetail)}), + }, + { + name: "sink with invalid scheme should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink(subNamespace), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SinkPath, + subName, v1alpha2.MissingSchemeErrDetail)}), + }, + { + name: "sink with invalid URL should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink("http://invalid Sink"), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SinkPath, + subName, "failed to parse subscription sink URL: "+ + "parse \"http://invalid Sink\": invalid character \" \" in host name")}), + }, + { + name: "sink with invalid suffix should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink("https://svc2.test.local"), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SinkPath, + subName, v1alpha2.SuffixMissingErrDetail)}), + }, + { + name: "sink with invalid suffix and port should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink("https://svc2.test.local:8080"), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SinkPath, + subName, v1alpha2.SuffixMissingErrDetail)}), + }, + { + name: "sink with invalid number of subdomains should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink("https://svc.cluster.local:8080"), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SinkPath, + subName, v1alpha2.SubDomainsErrDetail+"svc.cluster.local")}), + }, + { + name: "sink with different namespace should return error", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithSource(eventingtesting.EventSourceClean), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages(v1alpha2.DefaultMaxInFlightMessages), + eventingtesting.WithSink("https://eventing-nats.kyma-system.svc.cluster.local"), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.NSPath, + subName, v1alpha2.NSMismatchErrDetail+"kyma-system")}), + }, + { + name: "multiple errors should be reported if exists", + givenSub: eventingtesting.NewSubscription(subName, subNamespace, + eventingtesting.WithTypeMatchingStandard(), + eventingtesting.WithEventType(eventingtesting.OrderCreatedV1Event), + eventingtesting.WithMaxInFlightMessages("invalid"), + eventingtesting.WithSink(sink), + ), + wantErr: apierrors.NewInvalid( + v1alpha2.GroupKind, subName, + field.ErrorList{v1alpha2.MakeInvalidFieldError(v1alpha2.SourcePath, + subName, v1alpha2.EmptyErrDetail), + v1alpha2.MakeInvalidFieldError(v1alpha2.ConfigPath, + subName, v1alpha2.StringIntErrDetail)}), + }, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + _, err := tc.givenSub.ValidateSubscription() + require.Equal(t, err, tc.wantErr) + }) + } +} + +func Test_IsInvalidCESource(t *testing.T) { + t.Parallel() + type TestCase struct { + name string + givenSource string + givenType string + wantIsInvalid bool + } + + testCases := []TestCase{ + { + name: "invalid URI Path source should be invalid", + givenSource: "app%%type", + givenType: "order.created.v1", + wantIsInvalid: true, + }, + { + name: "valid URI Path source should not be invalid", + givenSource: "t..e--s__t!!a@@**p##p&&", + givenType: "", + wantIsInvalid: false, + }, + { + name: "should ignore check if the source is empty", + givenSource: "", + givenType: "", + wantIsInvalid: false, + }, + { + name: "invalid type should be invalid", + givenSource: "source", + givenType: " ", // space is an invalid type for cloud event + wantIsInvalid: true, + }, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + gotIsInvalid := v1alpha2.IsInvalidCE(tc.givenSource, tc.givenType) + require.Equal(t, tc.wantIsInvalid, gotIsInvalid) + }) + } +} diff --git a/api/eventing/v1alpha2/utils.go b/api/eventing/v1alpha2/utils.go new file mode 100644 index 00000000..d16dfc66 --- /dev/null +++ b/api/eventing/v1alpha2/utils.go @@ -0,0 +1,29 @@ +package v1alpha2 + +import ( + "encoding/json" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func SubscriptionGroupVersionResource() schema.GroupVersionResource { + return schema.GroupVersionResource{ + Version: GroupVersion.Version, + Group: GroupVersion.Group, + Resource: "subscriptions", + } +} + +func ConvertUnstructListToSubList(unstructuredList *unstructured.UnstructuredList) (*SubscriptionList, error) { + subscriptionList := new(SubscriptionList) + subscriptionListBytes, err := unstructuredList.MarshalJSON() + if err != nil { + return nil, err + } + err = json.Unmarshal(subscriptionListBytes, subscriptionList) + if err != nil { + return nil, err + } + return subscriptionList, nil +} diff --git a/api/eventing/v1alpha2/zz_generated.deepcopy.go b/api/eventing/v1alpha2/zz_generated.deepcopy.go new file mode 100644 index 00000000..194c3af6 --- /dev/null +++ b/api/eventing/v1alpha2/zz_generated.deepcopy.go @@ -0,0 +1,246 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2023. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Backend) DeepCopyInto(out *Backend) { + *out = *in + if in.EventMeshSubscriptionStatus != nil { + in, out := &in.EventMeshSubscriptionStatus, &out.EventMeshSubscriptionStatus + *out = new(EventMeshSubscriptionStatus) + **out = **in + } + if in.Types != nil { + in, out := &in.Types, &out.Types + *out = make([]JetStreamTypes, len(*in)) + copy(*out, *in) + } + if in.EmsTypes != nil { + in, out := &in.EmsTypes, &out.EmsTypes + *out = make([]EventMeshTypes, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Backend. +func (in *Backend) DeepCopy() *Backend { + if in == nil { + return nil + } + out := new(Backend) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Condition) DeepCopyInto(out *Condition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. +func (in *Condition) DeepCopy() *Condition { + if in == nil { + return nil + } + out := new(Condition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventMeshSubscriptionStatus) DeepCopyInto(out *EventMeshSubscriptionStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventMeshSubscriptionStatus. +func (in *EventMeshSubscriptionStatus) DeepCopy() *EventMeshSubscriptionStatus { + if in == nil { + return nil + } + out := new(EventMeshSubscriptionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventMeshTypes) DeepCopyInto(out *EventMeshTypes) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventMeshTypes. +func (in *EventMeshTypes) DeepCopy() *EventMeshTypes { + if in == nil { + return nil + } + out := new(EventMeshTypes) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventType) DeepCopyInto(out *EventType) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventType. +func (in *EventType) DeepCopy() *EventType { + if in == nil { + return nil + } + out := new(EventType) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JetStreamTypes) DeepCopyInto(out *JetStreamTypes) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JetStreamTypes. +func (in *JetStreamTypes) DeepCopy() *JetStreamTypes { + if in == nil { + return nil + } + out := new(JetStreamTypes) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Subscription) DeepCopyInto(out *Subscription) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subscription. +func (in *Subscription) DeepCopy() *Subscription { + if in == nil { + return nil + } + out := new(Subscription) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Subscription) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionList) DeepCopyInto(out *SubscriptionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Subscription, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionList. +func (in *SubscriptionList) DeepCopy() *SubscriptionList { + if in == nil { + return nil + } + out := new(SubscriptionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SubscriptionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionSpec) DeepCopyInto(out *SubscriptionSpec) { + *out = *in + if in.Types != nil { + in, out := &in.Types, &out.Types + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionSpec. +func (in *SubscriptionSpec) DeepCopy() *SubscriptionSpec { + if in == nil { + return nil + } + out := new(SubscriptionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionStatus) DeepCopyInto(out *SubscriptionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Types != nil { + in, out := &in.Types, &out.Types + *out = make([]EventType, len(*in)) + copy(*out, *in) + } + in.Backend.DeepCopyInto(&out.Backend) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionStatus. +func (in *SubscriptionStatus) DeepCopy() *SubscriptionStatus { + if in == nil { + return nil + } + out := new(SubscriptionStatus) + in.DeepCopyInto(out) + return out +} diff --git a/api/operator.kyma-project.io/v1alpha1/eventing_types.go b/api/operator/v1alpha1/eventing_types.go similarity index 100% rename from api/operator.kyma-project.io/v1alpha1/eventing_types.go rename to api/operator/v1alpha1/eventing_types.go diff --git a/api/operator.kyma-project.io/v1alpha1/eventing_types_test.go b/api/operator/v1alpha1/eventing_types_test.go similarity index 100% rename from api/operator.kyma-project.io/v1alpha1/eventing_types_test.go rename to api/operator/v1alpha1/eventing_types_test.go diff --git a/api/operator.kyma-project.io/v1alpha1/groupversion_info.go b/api/operator/v1alpha1/groupversion_info.go similarity index 100% rename from api/operator.kyma-project.io/v1alpha1/groupversion_info.go rename to api/operator/v1alpha1/groupversion_info.go diff --git a/api/operator.kyma-project.io/v1alpha1/status.go b/api/operator/v1alpha1/status.go similarity index 100% rename from api/operator.kyma-project.io/v1alpha1/status.go rename to api/operator/v1alpha1/status.go diff --git a/api/operator.kyma-project.io/v1alpha1/status_test.go b/api/operator/v1alpha1/status_test.go similarity index 100% rename from api/operator.kyma-project.io/v1alpha1/status_test.go rename to api/operator/v1alpha1/status_test.go diff --git a/api/operator.kyma-project.io/v1alpha1/zz_generated.deepcopy.go b/api/operator/v1alpha1/zz_generated.deepcopy.go similarity index 99% rename from api/operator.kyma-project.io/v1alpha1/zz_generated.deepcopy.go rename to api/operator/v1alpha1/zz_generated.deepcopy.go index 99b1cdc5..28204a61 100644 --- a/api/operator.kyma-project.io/v1alpha1/zz_generated.deepcopy.go +++ b/api/operator/v1alpha1/zz_generated.deepcopy.go @@ -22,7 +22,7 @@ limitations under the License. package v1alpha1 import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) diff --git a/cmd/main.go b/cmd/main.go index 38df4ee3..114b27da 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -22,13 +22,13 @@ import ( "log" "os" - eventingcontroller "github.com/kyma-project/eventing-manager/internal/controller/operator.kyma-project.io/eventing" + eventingcontroller "github.com/kyma-project/eventing-manager/internal/controller/operator/eventing" istiopeerauthentication "github.com/kyma-project/eventing-manager/pkg/istio/peerauthentication" "github.com/go-logr/zapr" - subscriptionv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" - subscriptionv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + subscriptionv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" + subscriptionv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" apiclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -58,7 +58,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" //+kubebuilder:scaffold:imports ) @@ -78,6 +78,8 @@ func init() { utilruntime.Must(jetstream.AddToScheme(scheme)) utilruntime.Must(jetstream.AddV1Alpha2ToScheme(scheme)) + utilruntime.Must(subscriptionv1alpha1.AddToScheme(scheme)) + utilruntime.Must(subscriptionv1alpha2.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } diff --git a/config/crd/external/subscriptions.eventing.kyma-project.io.crd.yaml b/config/crd/bases/eventing.kyma-project.io_subscriptions.yaml similarity index 98% rename from config/crd/external/subscriptions.eventing.kyma-project.io.crd.yaml rename to config/crd/bases/eventing.kyma-project.io_subscriptions.yaml index eeef8c34..b980cd35 100644 --- a/config/crd/external/subscriptions.eventing.kyma-project.io.crd.yaml +++ b/config/crd/bases/eventing.kyma-project.io_subscriptions.yaml @@ -1,20 +1,12 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.1 + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null name: subscriptions.eventing.kyma-project.io spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: eventing-controller-webhook-service - namespace: kyma-system - path: /convert - conversionReviewVersions: - - v1 group: eventing.kyma-project.io names: kind: Subscription diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index fb52b857..0955426d 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -3,7 +3,7 @@ # It should be run by config/default resources: - bases/operator.kyma-project.io_eventings.yaml -- external/subscriptions.eventing.kyma-project.io.crd.yaml +- bases/eventing.kyma-project.io_subscriptions.yaml #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: @@ -11,11 +11,13 @@ patchesStrategicMerge: # patches here are for enabling the conversion webhook for each CRD #- patches/webhook_in_eventings.yaml - patches/webhook_in_subscriptions.yaml +#- patches/webhook_in_subscriptions.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD #- patches/cainjection_in_eventings.yaml +#- patches/cainjection_in_subscriptions.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index cde2664d..9f82fd03 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -3,4 +3,6 @@ namespace: eventing-manager resources: - default.yaml +- eventing.kyma-project.io_v1alpha1_subscription.yaml +- eventing.kyma-project.io_v1alpha2_subscription.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/subscription_v1alpha1_js.yaml b/config/samples/subscription_v1alpha1_js.yaml new file mode 100644 index 00000000..86840626 --- /dev/null +++ b/config/samples/subscription_v1alpha1_js.yaml @@ -0,0 +1,27 @@ +apiVersion: eventing.kyma-project.io/v1alpha1 +kind: Subscription +metadata: + name: test-noapp1 + namespace: tunas-testing +spec: + filter: + filters: + - eventSource: + property: source + type: exact + value: "noapp" + eventType: + property: type + type: exact + value: sap.kyma.custom.noapp.order.created.v1 + - eventSource: + property: source + type: exact + value: "noapp" + eventType: + property: type + type: exact + value: sap.kyma.custom.noapp.order.created.v2 + protocol: "" + protocolsettings: {} + sink: http://test.tunas-testing.svc.cluster.local \ No newline at end of file diff --git a/config/samples/subscription_v1alpha2_exact_eventmesh.yaml b/config/samples/subscription_v1alpha2_exact_eventmesh.yaml new file mode 100644 index 00000000..9b1f57c5 --- /dev/null +++ b/config/samples/subscription_v1alpha2_exact_eventmesh.yaml @@ -0,0 +1,12 @@ +apiVersion: eventing.kyma-project.io/v1alpha2 +kind: Subscription +metadata: + name: test-noapp-exact + namespace: tunas-testing +spec: + sink: http://test.tunas-testing.svc.cluster.local + typeMatching: exact + source: "/default/sap.kyma/tunas-develop" + types: + - sap.kyma.custom.noapp.order.created.v1 + diff --git a/config/samples/subscription_v1alpha2_standard.yaml b/config/samples/subscription_v1alpha2_standard.yaml new file mode 100644 index 00000000..3de98a14 --- /dev/null +++ b/config/samples/subscription_v1alpha2_standard.yaml @@ -0,0 +1,12 @@ +apiVersion: eventing.kyma-project.io/v1alpha2 +kind: Subscription +metadata: + name: test-noapp + namespace: tunas-testing +spec: + sink: http://test.tunas-testing.svc.cluster.local + typeMatching: standard + source: "noapp" + types: + - order.created.v1 + diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml new file mode 100644 index 00000000..3698c7dc --- /dev/null +++ b/config/webhook/manifests.yaml @@ -0,0 +1,54 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-eventing-kyma-project-io-v1alpha2-subscription + failurePolicy: Fail + name: msubscription.kb.io + rules: + - apiGroups: + - eventing.kyma-project.io + apiVersions: + - v1alpha2 + operations: + - CREATE + - UPDATE + resources: + - subscriptions + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-eventing-kyma-project-io-v1alpha2-subscription + failurePolicy: Fail + name: vsubscription.kb.io + rules: + - apiGroups: + - eventing.kyma-project.io + apiVersions: + - v1alpha2 + operations: + - CREATE + - UPDATE + resources: + - subscriptions + sideEffects: None diff --git a/docs/user/02-configuration.md b/docs/user/02-configuration.md index da4db46f..a3303cd1 100644 --- a/docs/user/02-configuration.md +++ b/docs/user/02-configuration.md @@ -28,46 +28,49 @@ Use the following sample CRs as guidance. Each can be applied immediately when y **Spec:** -| Parameter | Type | Description | -|----------------------------------------------------------|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **annotations** | map\[string\]string | Annotations allows to add annotations to resources. | -| **backend** (required) | object | Backend defines the active backend used by Eventing. | -| **backend.​config** | object | Config defines configuration for eventing backend. | -| **backend.​config.​domain** | string | Domain defines the cluster public domain used to configure the EventMesh Subscriptions and their corresponding ApiRules. | -| **backend.​config.​eventMeshSecret** | string | EventMeshSecret defines the namespaced name of K8s Secret containing EventMesh credentials. The format of name is "namespace/name". | -| **backend.​config.​eventTypePrefix** | string | | -| **backend.​config.​natsMaxMsgsPerTopic** | integer | NATSMaxMsgsPerTopic limits how many messages in the NATS stream to retain per subject. | -| **backend.​config.​natsStreamMaxSize** | \{integer or string\} | NATSStreamMaxSize defines the maximum storage size for stream data. | -| **backend.​config.​natsStreamReplicas** | integer | NATSStreamReplicas defines the number of replicas for stream. | -| **backend.​config.​natsStreamStorageType** | string | NATSStreamStorageType defines the storage type for stream data. | -| **backend.​type** (required) | string | Type defines which backend to use. The value is either `EventMesh`, or `NATS`. | -| **labels** | map\[string\]string | Labels allows to add Labels to resources. | -| **logging** | object | Logging defines the log level for eventing-manager. | -| **logging.​logLevel** | string | LogLevel defines the log level. | -| **publisher** | object | Publisher defines the configurations for eventing-publisher-proxy. | -| **publisher.​replicas** | object | Replicas defines the scaling min/max for eventing-publisher-proxy. | -| **publisher.​replicas.​max** | integer | Max defines maximum number of replicas. | -| **publisher.​replicas.​min** | integer | Min defines minimum number of replicas. | -| **publisher.​resources** | object | Resources defines resources for eventing-publisher-proxy. | -| **publisher.​resources.​claims** | \[\]object | Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. | -| **publisher.​resources.​claims.​name** (required) | string | Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. | -| **publisher.​resources.​limits** | map\[string\]\{integer or string\} | Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | +| Parameter | Type | Description | +| ---- | ----------- | ---- | +| **annotations** | map\[string\]string | Annotations allows to add annotations to resources. | +| **backend** (required) | object | Backend defines the active backend used by Eventing. | +| **backend.​config** | object | Config defines configuration for eventing backend. | +| **backend.​config.​domain** | string | Domain defines the cluster public domain used to configure the EventMesh Subscriptions and their corresponding ApiRules. | +| **backend.​config.​eventMeshSecret** | string | EventMeshSecret defines the namespaced name of K8s Secret containing EventMesh credentials. The format of name is "namespace/name". | +| **backend.​config.​eventTypePrefix** | string | | +| **backend.​config.​natsMaxMsgsPerTopic** | integer | NATSMaxMsgsPerTopic limits how many messages in the NATS stream to retain per subject. | +| **backend.​config.​natsStreamMaxSize** | \{integer or string\} | NATSStreamMaxSize defines the maximum storage size for stream data. | +| **backend.​config.​natsStreamReplicas** | integer | NATSStreamReplicas defines the number of replicas for stream. | +| **backend.​config.​natsStreamStorageType** | string | NATSStreamStorageType defines the storage type for stream data. | +| **backend.​type** (required) | string | Type defines which backend to use. The value is either `EventMesh`, or `NATS`. | +| **labels** | map\[string\]string | Labels allows to add Labels to resources. | +| **logging** | object | Logging defines the log level for eventing-manager. | +| **logging.​logLevel** | string | LogLevel defines the log level. | +| **publisher** | object | Publisher defines the configurations for eventing-publisher-proxy. | +| **publisher.​replicas** | object | Replicas defines the scaling min/max for eventing-publisher-proxy. | +| **publisher.​replicas.​max** | integer | Max defines maximum number of replicas. | +| **publisher.​replicas.​min** | integer | Min defines minimum number of replicas. | +| **publisher.​resources** | object | Resources defines resources for eventing-publisher-proxy. | +| **publisher.​resources.​claims** | \[\]object | Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. + This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. | +| **publisher.​resources.​claims.​name** (required) | string | Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. | +| **publisher.​resources.​limits** | map\[string\]\{integer or string\} | Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | **publisher.​resources.​requests** | map\[string\]\{integer or string\} | Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | **Status:** -| Parameter | Type | Description | -|------------------------------------------------------|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **activeBackend** (required) | string | | -| **conditions** | \[\]object | Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` | -| // other fields } | | | -| **conditions.​lastTransitionTime** (required) | string | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. | -| **conditions.​message** (required) | string | message is a human readable message indicating details about the transition. This may be an empty string. | -| **conditions.​observedGeneration** | integer | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. | -| **conditions.​reason** (required) | string | reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. | -| **conditions.​status** (required) | string | status of the condition, one of `True`, `False`, `Unknown`. | -| **conditions.​type** (required) | string | type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) | -| **specHash** (required) | integer | | -| **state** (required) | string | | +| Parameter | Type | Description | +| ---- | ----------- | ---- | +| **activeBackend** (required) | string | | +| **conditions** | \[\]object | Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + // other fields } | +| **conditions.​lastTransitionTime** (required) | string | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. | +| **conditions.​message** (required) | string | message is a human readable message indicating details about the transition. This may be an empty string. | +| **conditions.​observedGeneration** | integer | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. | +| **conditions.​reason** (required) | string | reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. | +| **conditions.​status** (required) | string | status of the condition, one of True, False, Unknown. | +| **conditions.​type** (required) | string | type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) | +| **specHash** (required) | integer | | +| **state** (required) | string | | diff --git a/go.mod b/go.mod index 1babdb80..2f067be4 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,6 @@ require ( github.com/kelseyhightower/envconfig v1.4.0 github.com/kyma-incubator/api-gateway v0.0.0-20220819093753-296e6704d413 github.com/kyma-project/kyma/common/logging v0.0.0-20231113125307-562a57ab5198 - github.com/kyma-project/kyma/components/eventing-controller v0.0.0-20231113125307-562a57ab5198 github.com/kyma-project/nats-manager v1.0.2 github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/nats-io/nats-server/v2 v2.10.5 diff --git a/go.sum b/go.sum index 028d751a..2b342e0d 100644 --- a/go.sum +++ b/go.sum @@ -220,12 +220,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kyma-project/api-gateway v0.0.0-20220819093753-296e6704d413 h1:fkGKNOFbltycpdQ7yCGfa+7MpH9X18F09x+n7Tgfp7A= github.com/kyma-project/api-gateway v0.0.0-20220819093753-296e6704d413/go.mod h1:5kBV6C2JEaapjTAn10Mo81Te4e6LN3epexUCSLXgQLI= -github.com/kyma-project/api-gateway v0.0.0-20231025094533-b7f4433b5cac h1:1lgrll58pt2J3KmgaxuhxmQ5S5pmRHd5Ecd0R/jtuGU= -github.com/kyma-project/api-gateway v0.0.0-20231025094533-b7f4433b5cac/go.mod h1:liAdIi2zvHbrK4K6Xi+pHUz2cnU70QRkhuUqhVF6Hmo= github.com/kyma-project/kyma/common/logging v0.0.0-20231113125307-562a57ab5198 h1:xz4kPj7u51OgP+0f58OeaQlyiGm6AwEHALjbiLeK3Ec= github.com/kyma-project/kyma/common/logging v0.0.0-20231113125307-562a57ab5198/go.mod h1:JGb5RBi8Uz+RZ/jf54+qA+RqY6uPQBJ8pO1w3KSwm1Q= -github.com/kyma-project/kyma/components/eventing-controller v0.0.0-20231113125307-562a57ab5198 h1:/o4jabncHPmpvgFzGQ6TBzjbHmf111FDkOzgmdH3L4I= -github.com/kyma-project/kyma/components/eventing-controller v0.0.0-20231113125307-562a57ab5198/go.mod h1:myk9NTLyoeWE5uo5y9oECUJqBkwcWPWW/8jq5g6EPy8= github.com/kyma-project/nats-manager v1.0.2 h1:uJiVrLFFqnOsnz1IGNn76fm5cQoK+4L8GxP829mX2C8= github.com/kyma-project/nats-manager v1.0.2/go.mod h1:gC0W/C2NgpmVnG/5v5f76ijNw5aloQLEkSuVOElB9gk= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -297,8 +293,8 @@ github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= diff --git a/hack/e2e/cleanup/cleanup_test.go b/hack/e2e/cleanup/cleanup_test.go index d98c388f..4ca6b1a2 100644 --- a/hack/e2e/cleanup/cleanup_test.go +++ b/hack/e2e/cleanup/cleanup_test.go @@ -17,7 +17,7 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/hack/e2e/common/testenvironment" "github.com/kyma-project/eventing-manager/pkg/eventing" diff --git a/hack/e2e/common/eventing/testsubscriptioninfo.go b/hack/e2e/common/eventing/testsubscriptioninfo.go index 9d10b5b8..0a261bdd 100644 --- a/hack/e2e/common/eventing/testsubscriptioninfo.go +++ b/hack/e2e/common/eventing/testsubscriptioninfo.go @@ -1,8 +1,8 @@ package eventing import ( - ecv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" - ecv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + ecv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" + ecv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/hack/e2e/common/fixtures/fixtures.go b/hack/e2e/common/fixtures/fixtures.go index f09e1895..37a57127 100644 --- a/hack/e2e/common/fixtures/fixtures.go +++ b/hack/e2e/common/fixtures/fixtures.go @@ -12,7 +12,7 @@ import ( "github.com/kyma-project/eventing-manager/hack/e2e/common/eventing" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/hack/e2e/common/k8s.go b/hack/e2e/common/k8s.go index 7039dc54..ddc94c3d 100644 --- a/hack/e2e/common/k8s.go +++ b/hack/e2e/common/k8s.go @@ -6,10 +6,10 @@ import ( "k8s.io/client-go/dynamic" - ecv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" - ecv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + ecv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" + ecv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" diff --git a/hack/e2e/common/testenvironment/test_environment.go b/hack/e2e/common/testenvironment/test_environment.go index f118580c..fac19e06 100644 --- a/hack/e2e/common/testenvironment/test_environment.go +++ b/hack/e2e/common/testenvironment/test_environment.go @@ -15,9 +15,9 @@ import ( cloudevents "github.com/cloudevents/sdk-go/v2" "github.com/cloudevents/sdk-go/v2/binding" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" - ecv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + ecv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" diff --git a/hack/e2e/env/env.go b/hack/e2e/env/env.go index 802fb64f..f2363912 100644 --- a/hack/e2e/env/env.go +++ b/hack/e2e/env/env.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/kelseyhightower/envconfig" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" ) // E2EConfig represents the environment config for the end-to-end tests for eventing-manager. diff --git a/hack/e2e/setup/setup_test.go b/hack/e2e/setup/setup_test.go index e7c5d7a7..60c38c0b 100644 --- a/hack/e2e/setup/setup_test.go +++ b/hack/e2e/setup/setup_test.go @@ -19,7 +19,7 @@ import ( "github.com/pkg/errors" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/eventing" "github.com/stretchr/testify/require" diff --git a/internal/controller/subscription/eventmesh/reconciler.go b/internal/controller/eventing/subscription/eventmesh/reconciler.go similarity index 99% rename from internal/controller/subscription/eventmesh/reconciler.go rename to internal/controller/eventing/subscription/eventmesh/reconciler.go index 8649f310..b5763c42 100644 --- a/internal/controller/subscription/eventmesh/reconciler.go +++ b/internal/controller/eventing/subscription/eventmesh/reconciler.go @@ -30,8 +30,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/source" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/eventmesh" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" "go.uber.org/zap" diff --git a/internal/controller/subscription/eventmesh/reconciler_internal_integration_test.go b/internal/controller/eventing/subscription/eventmesh/reconciler_internal_integration_test.go similarity index 99% rename from internal/controller/subscription/eventmesh/reconciler_internal_integration_test.go rename to internal/controller/eventing/subscription/eventmesh/reconciler_internal_integration_test.go index a3bff798..81674c5a 100644 --- a/internal/controller/subscription/eventmesh/reconciler_internal_integration_test.go +++ b/internal/controller/eventing/subscription/eventmesh/reconciler_internal_integration_test.go @@ -22,6 +22,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" "github.com/kyma-project/eventing-manager/pkg/backend/eventmesh" "github.com/kyma-project/eventing-manager/pkg/backend/eventmesh/mocks" @@ -35,7 +36,6 @@ import ( "github.com/kyma-project/eventing-manager/pkg/object" "github.com/kyma-project/eventing-manager/test/utils" reconcilertesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) // TestReconciler_Reconcile tests the return values of the Reconcile() method of the reconciler. diff --git a/internal/controller/subscription/eventmesh/test/assertions.go b/internal/controller/eventing/subscription/eventmesh/test/assertions.go similarity index 95% rename from internal/controller/subscription/eventmesh/test/assertions.go rename to internal/controller/eventing/subscription/eventmesh/test/assertions.go index 8fd52c27..e24bf8ba 100644 --- a/internal/controller/subscription/eventmesh/test/assertions.go +++ b/internal/controller/eventing/subscription/eventmesh/test/assertions.go @@ -9,7 +9,7 @@ import ( "k8s.io/apimachinery/pkg/types" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" ) // getSubscriptionAssert fetches a subscription using the lookupKey and allows making assertions on it. diff --git a/internal/controller/subscription/eventmesh/test/reconciler_integration_test.go b/internal/controller/eventing/subscription/eventmesh/test/reconciler_integration_test.go similarity index 99% rename from internal/controller/subscription/eventmesh/test/reconciler_integration_test.go rename to internal/controller/eventing/subscription/eventmesh/test/reconciler_integration_test.go index 808d6556..3d492f32 100644 --- a/internal/controller/subscription/eventmesh/test/reconciler_integration_test.go +++ b/internal/controller/eventing/subscription/eventmesh/test/reconciler_integration_test.go @@ -16,7 +16,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" eventMeshtypes "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" "github.com/kyma-project/eventing-manager/pkg/object" diff --git a/internal/controller/subscription/eventmesh/test/utils.go b/internal/controller/eventing/subscription/eventmesh/test/utils.go similarity index 97% rename from internal/controller/subscription/eventmesh/test/utils.go rename to internal/controller/eventing/subscription/eventmesh/test/utils.go index 33f201a1..fed93518 100644 --- a/internal/controller/subscription/eventmesh/test/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/test/utils.go @@ -13,6 +13,8 @@ import ( "testing" "time" + eventmeshreconciler "github.com/kyma-project/eventing-manager/internal/controller/eventing/subscription/eventmesh" + "github.com/avast/retry-go/v3" "github.com/go-logr/zapr" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" @@ -35,9 +37,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" - eventmeshreconciler "github.com/kyma-project/eventing-manager/internal/controller/subscription/eventmesh" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" backendeventmesh "github.com/kyma-project/eventing-manager/pkg/backend/eventmesh" "github.com/kyma-project/eventing-manager/pkg/backend/metrics" @@ -204,14 +205,14 @@ func startTestEnv() (*rest.Config, error) { useExistingCluster := useExistingCluster emTestEnsemble.testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ - filepath.Join("../../../../../", "config", "crd", "bases"), - filepath.Join("../../../../../", "config", "crd", "external"), - filepath.Join("../../../../../", "config", "crd", "for-tests"), + filepath.Join("../../../../../../", "config", "crd", "bases"), + filepath.Join("../../../../../../", "config", "crd", "external"), + filepath.Join("../../../../../../", "config", "crd", "for-tests"), }, AttachControlPlaneOutput: attachControlPlaneOutput, UseExistingCluster: &useExistingCluster, WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("../../../../../", "config", "webhook")}, + Paths: []string{filepath.Join("../../../../../../", "config", "webhook")}, }, } diff --git a/internal/controller/subscription/eventmesh/testwebhookauth/assertions.go b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/assertions.go similarity index 93% rename from internal/controller/subscription/eventmesh/testwebhookauth/assertions.go rename to internal/controller/eventing/subscription/eventmesh/testwebhookauth/assertions.go index cf48b2c1..67ff903b 100644 --- a/internal/controller/subscription/eventmesh/testwebhookauth/assertions.go +++ b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/assertions.go @@ -8,7 +8,7 @@ import ( "k8s.io/apimachinery/pkg/types" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" ) // getSubscriptionAssert fetches a subscription using the lookupKey and allows making assertions on it. diff --git a/internal/controller/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go similarity index 100% rename from internal/controller/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go rename to internal/controller/eventing/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go diff --git a/internal/controller/subscription/eventmesh/testwebhookauth/utils.go b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go similarity index 96% rename from internal/controller/subscription/eventmesh/testwebhookauth/utils.go rename to internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go index 2f5a85c4..e9ecd42d 100644 --- a/internal/controller/subscription/eventmesh/testwebhookauth/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go @@ -11,6 +11,8 @@ import ( "testing" "time" + eventmeshreconciler "github.com/kyma-project/eventing-manager/internal/controller/eventing/subscription/eventmesh" + "github.com/avast/retry-go/v3" "github.com/go-logr/zapr" "github.com/stretchr/testify/require" @@ -32,7 +34,7 @@ import ( apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" kymalogger "github.com/kyma-project/kyma/common/logging/logger" - eventmeshreconciler "github.com/kyma-project/eventing-manager/internal/controller/subscription/eventmesh" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" backendeventmesh "github.com/kyma-project/eventing-manager/pkg/backend/eventmesh" "github.com/kyma-project/eventing-manager/pkg/backend/metrics" @@ -45,7 +47,6 @@ import ( "github.com/kyma-project/eventing-manager/pkg/utils" testutils "github.com/kyma-project/eventing-manager/test/utils" reconcilertesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) type eventMeshTestEnsemble struct { @@ -199,14 +200,14 @@ func startAndWaitForWebhookServer(manager manager.Manager, installOpts *envtest. func startTestEnv() (*rest.Config, error) { emTestEnsemble.testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ - filepath.Join("../../../../../", "config", "crd", "bases"), - filepath.Join("../../../../../", "config", "crd", "external"), - filepath.Join("../../../../../", "config", "crd", "for-tests"), + filepath.Join("../../../../../../", "config", "crd", "bases"), + filepath.Join("../../../../../../", "config", "crd", "external"), + filepath.Join("../../../../../../", "config", "crd", "for-tests"), }, AttachControlPlaneOutput: attachControlPlaneOutput, UseExistingCluster: utils.BoolPtr(useExistingCluster), WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("../../../../../", "config", "webhook")}, + Paths: []string{filepath.Join("../../../../../../", "config", "webhook")}, }, } diff --git a/internal/controller/subscription/eventmesh/testwithory/assertions.go b/internal/controller/eventing/subscription/eventmesh/testwithory/assertions.go similarity index 95% rename from internal/controller/subscription/eventmesh/testwithory/assertions.go rename to internal/controller/eventing/subscription/eventmesh/testwithory/assertions.go index e872778a..e14fbbed 100644 --- a/internal/controller/subscription/eventmesh/testwithory/assertions.go +++ b/internal/controller/eventing/subscription/eventmesh/testwithory/assertions.go @@ -9,7 +9,7 @@ import ( "k8s.io/apimachinery/pkg/types" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" ) // getSubscriptionAssert fetches a subscription using the lookupKey and allows making assertions on it. diff --git a/internal/controller/subscription/eventmesh/testwithory/reconciler_integration_test.go b/internal/controller/eventing/subscription/eventmesh/testwithory/reconciler_integration_test.go similarity index 99% rename from internal/controller/subscription/eventmesh/testwithory/reconciler_integration_test.go rename to internal/controller/eventing/subscription/eventmesh/testwithory/reconciler_integration_test.go index 3e11e7b6..83cebad4 100644 --- a/internal/controller/subscription/eventmesh/testwithory/reconciler_integration_test.go +++ b/internal/controller/eventing/subscription/eventmesh/testwithory/reconciler_integration_test.go @@ -16,7 +16,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" eventMeshtypes "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" "github.com/kyma-project/eventing-manager/pkg/object" diff --git a/internal/controller/subscription/eventmesh/testwithory/utils.go b/internal/controller/eventing/subscription/eventmesh/testwithory/utils.go similarity index 97% rename from internal/controller/subscription/eventmesh/testwithory/utils.go rename to internal/controller/eventing/subscription/eventmesh/testwithory/utils.go index 7147114a..e1b84dbc 100644 --- a/internal/controller/subscription/eventmesh/testwithory/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/testwithory/utils.go @@ -13,6 +13,8 @@ import ( "testing" "time" + eventmeshreconciler "github.com/kyma-project/eventing-manager/internal/controller/eventing/subscription/eventmesh" + "github.com/avast/retry-go/v3" "github.com/go-logr/zapr" "github.com/stretchr/testify/require" @@ -36,7 +38,7 @@ import ( apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" kymalogger "github.com/kyma-project/kyma/common/logging/logger" - eventmeshreconciler "github.com/kyma-project/eventing-manager/internal/controller/subscription/eventmesh" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" backendeventmesh "github.com/kyma-project/eventing-manager/pkg/backend/eventmesh" "github.com/kyma-project/eventing-manager/pkg/backend/metrics" @@ -50,7 +52,6 @@ import ( "github.com/kyma-project/eventing-manager/pkg/utils" testutils "github.com/kyma-project/eventing-manager/test/utils" reconcilertesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) type eventMeshTestEnsemble struct { @@ -203,14 +204,14 @@ func startTestEnv() (*rest.Config, error) { useExistingCluster := useExistingCluster emTestEnsemble.testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ - filepath.Join("../../../../../", "config", "crd", "bases"), - filepath.Join("../../../../../", "config", "crd", "external"), - filepath.Join("../../../../../", "config", "crd", "for-tests"), + filepath.Join("../../../../../../", "config", "crd", "bases"), + filepath.Join("../../../../../../", "config", "crd", "external"), + filepath.Join("../../../../../../", "config", "crd", "for-tests"), }, AttachControlPlaneOutput: attachControlPlaneOutput, UseExistingCluster: &useExistingCluster, WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("../../../../../", "config", "webhook")}, + Paths: []string{filepath.Join("../../../../../../", "config", "webhook")}, }, } diff --git a/internal/controller/subscription/eventmesh/utils.go b/internal/controller/eventing/subscription/eventmesh/utils.go similarity index 97% rename from internal/controller/subscription/eventmesh/utils.go rename to internal/controller/eventing/subscription/eventmesh/utils.go index f7c236fa..f1c104a8 100644 --- a/internal/controller/subscription/eventmesh/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/utils.go @@ -6,7 +6,7 @@ import ( "strings" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/pkg/errors" "go.uber.org/zap" "golang.org/x/xerrors" diff --git a/internal/controller/subscription/eventmesh/utils_test.go b/internal/controller/eventing/subscription/eventmesh/utils_test.go similarity index 98% rename from internal/controller/subscription/eventmesh/utils_test.go rename to internal/controller/eventing/subscription/eventmesh/utils_test.go index ac1681b5..81c38079 100644 --- a/internal/controller/subscription/eventmesh/utils_test.go +++ b/internal/controller/eventing/subscription/eventmesh/utils_test.go @@ -9,10 +9,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" eventinglogger "github.com/kyma-project/eventing-manager/pkg/logger" reconcilertesting "github.com/kyma-project/eventing-manager/testing" kymalogger "github.com/kyma-project/kyma/common/logging/logger" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) func Test_isInDeletion(t *testing.T) { diff --git a/internal/controller/subscription/jetstream/errors.go b/internal/controller/eventing/subscription/jetstream/errors.go similarity index 100% rename from internal/controller/subscription/jetstream/errors.go rename to internal/controller/eventing/subscription/jetstream/errors.go diff --git a/internal/controller/subscription/jetstream/matchers_test.go b/internal/controller/eventing/subscription/jetstream/matchers_test.go similarity index 94% rename from internal/controller/subscription/jetstream/matchers_test.go rename to internal/controller/eventing/subscription/jetstream/matchers_test.go index a0428860..1448ddd4 100644 --- a/internal/controller/subscription/jetstream/matchers_test.go +++ b/internal/controller/eventing/subscription/jetstream/matchers_test.go @@ -5,8 +5,8 @@ import ( "github.com/kyma-project/eventing-manager/pkg/env" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/jetstream" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" "github.com/onsi/gomega" gomegatypes "github.com/onsi/gomega/types" ) diff --git a/internal/controller/subscription/jetstream/reconciler.go b/internal/controller/eventing/subscription/jetstream/reconciler.go similarity index 99% rename from internal/controller/subscription/jetstream/reconciler.go rename to internal/controller/eventing/subscription/jetstream/reconciler.go index 060bf528..487f9953 100644 --- a/internal/controller/subscription/jetstream/reconciler.go +++ b/internal/controller/eventing/subscription/jetstream/reconciler.go @@ -32,9 +32,9 @@ import ( backendutils "github.com/kyma-project/eventing-manager/pkg/backend/utils" "github.com/kyma-project/eventing-manager/pkg/utils" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/jetstream" "github.com/kyma-project/eventing-manager/pkg/logger" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) const ( diff --git a/internal/controller/subscription/jetstream/reconciler_integration_test.go b/internal/controller/eventing/subscription/jetstream/reconciler_integration_test.go similarity index 99% rename from internal/controller/subscription/jetstream/reconciler_integration_test.go rename to internal/controller/eventing/subscription/jetstream/reconciler_integration_test.go index 96c24065..ebc2a331 100644 --- a/internal/controller/subscription/jetstream/reconciler_integration_test.go +++ b/internal/controller/eventing/subscription/jetstream/reconciler_integration_test.go @@ -14,7 +14,7 @@ import ( eventingtesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" ) // TestMain pre-hook and post-hook to run before and after all tests. diff --git a/internal/controller/subscription/jetstream/reconciler_internal_unit_test.go b/internal/controller/eventing/subscription/jetstream/reconciler_internal_unit_test.go similarity index 99% rename from internal/controller/subscription/jetstream/reconciler_internal_unit_test.go rename to internal/controller/eventing/subscription/jetstream/reconciler_internal_unit_test.go index c5e0b7a9..02d337d3 100644 --- a/internal/controller/subscription/jetstream/reconciler_internal_unit_test.go +++ b/internal/controller/eventing/subscription/jetstream/reconciler_internal_unit_test.go @@ -18,6 +18,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" "github.com/kyma-project/eventing-manager/pkg/backend/jetstream" "github.com/kyma-project/eventing-manager/pkg/backend/jetstream/mocks" @@ -26,7 +27,6 @@ import ( "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/logger" controllertesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) const ( diff --git a/internal/controller/subscription/jetstream/test_utils_test.go b/internal/controller/eventing/subscription/jetstream/test_utils_test.go similarity index 98% rename from internal/controller/subscription/jetstream/test_utils_test.go rename to internal/controller/eventing/subscription/jetstream/test_utils_test.go index 371ce64c..a8a4e429 100644 --- a/internal/controller/subscription/jetstream/test_utils_test.go +++ b/internal/controller/eventing/subscription/jetstream/test_utils_test.go @@ -10,9 +10,9 @@ import ( "testing" "time" - "github.com/kyma-project/eventing-manager/pkg/backend/sink" + ctrljetstream "github.com/kyma-project/eventing-manager/internal/controller/eventing/subscription/jetstream" - ctrljetstream "github.com/kyma-project/eventing-manager/internal/controller/subscription/jetstream" + "github.com/kyma-project/eventing-manager/pkg/backend/sink" "github.com/avast/retry-go/v3" "github.com/kyma-project/eventing-manager/internal/controller/events" @@ -31,6 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" cleanerv1alpha2 "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" "github.com/kyma-project/eventing-manager/pkg/backend/jetstream" "github.com/kyma-project/eventing-manager/pkg/backend/metrics" @@ -38,7 +39,6 @@ import ( "github.com/kyma-project/eventing-manager/pkg/logger" eventingtesting "github.com/kyma-project/eventing-manager/testing" kymalogger "github.com/kyma-project/kyma/common/logging/logger" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" "github.com/onsi/gomega" gomegatypes "github.com/onsi/gomega/types" "k8s.io/client-go/kubernetes/scheme" @@ -113,14 +113,14 @@ func setupSuite() error { NatsServer: natsServer, TestEnv: &envtest.Environment{ CRDDirectoryPaths: []string{ - filepath.Join("../../../../", "config", "crd", "bases"), - filepath.Join("../../../../", "config", "crd", "external"), + filepath.Join("../../../../../", "config", "crd", "bases"), + filepath.Join("../../../../../", "config", "crd", "external"), }, AttachControlPlaneOutput: attachControlPlaneOutput, UseExistingCluster: &useExistingCluster, WebhookInstallOptions: envtest.WebhookInstallOptions{ Paths: []string{ - filepath.Join("../../../../", "config", "webhook", "webhook_configs.yaml"), + filepath.Join("../../../../../", "config", "webhook", "webhook_configs.yaml"), }, }, }, diff --git a/internal/controller/subscription/jetstream/utils.go b/internal/controller/eventing/subscription/jetstream/utils.go similarity index 84% rename from internal/controller/subscription/jetstream/utils.go rename to internal/controller/eventing/subscription/jetstream/utils.go index 0878ad33..f2ef95e5 100644 --- a/internal/controller/subscription/jetstream/utils.go +++ b/internal/controller/eventing/subscription/jetstream/utils.go @@ -1,8 +1,8 @@ package jetstream import ( + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/utils" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) // isInDeletion checks if the subscription needs to be deleted. diff --git a/internal/controller/subscription/jetstream/utils_unit_test.go b/internal/controller/eventing/subscription/jetstream/utils_unit_test.go similarity index 95% rename from internal/controller/subscription/jetstream/utils_unit_test.go rename to internal/controller/eventing/subscription/jetstream/utils_unit_test.go index 9e21135a..e4d4a666 100644 --- a/internal/controller/subscription/jetstream/utils_unit_test.go +++ b/internal/controller/eventing/subscription/jetstream/utils_unit_test.go @@ -3,8 +3,8 @@ package jetstream import ( "testing" + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" subtesting "github.com/kyma-project/eventing-manager/testing" - "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" "github.com/stretchr/testify/require" ) diff --git a/internal/controller/operator.kyma-project.io/eventing/controller.go b/internal/controller/operator/eventing/controller.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/controller.go rename to internal/controller/operator/eventing/controller.go index eb5b676d..068dd437 100644 --- a/internal/controller/operator.kyma-project.io/eventing/controller.go +++ b/internal/controller/operator/eventing/controller.go @@ -43,7 +43,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/options" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/eventing" diff --git a/internal/controller/operator.kyma-project.io/eventing/controller_test.go b/internal/controller/operator/eventing/controller_test.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/controller_test.go rename to internal/controller/operator/eventing/controller_test.go index 337e1aca..1955da7d 100644 --- a/internal/controller/operator.kyma-project.io/eventing/controller_test.go +++ b/internal/controller/operator/eventing/controller_test.go @@ -9,7 +9,7 @@ import ( "github.com/kyma-project/eventing-manager/pkg/watcher" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" submanagermocks "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager/mocks" watchmock "github.com/kyma-project/eventing-manager/pkg/watcher/mocks" testutils "github.com/kyma-project/eventing-manager/test/utils" diff --git a/internal/controller/operator.kyma-project.io/eventing/domain.go b/internal/controller/operator/eventing/domain.go similarity index 100% rename from internal/controller/operator.kyma-project.io/eventing/domain.go rename to internal/controller/operator/eventing/domain.go diff --git a/internal/controller/operator.kyma-project.io/eventing/domain_test.go b/internal/controller/operator/eventing/domain_test.go similarity index 100% rename from internal/controller/operator.kyma-project.io/eventing/domain_test.go rename to internal/controller/operator/eventing/domain_test.go diff --git a/internal/controller/operator.kyma-project.io/eventing/eventmesh.go b/internal/controller/operator/eventing/eventmesh.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/eventmesh.go rename to internal/controller/operator/eventing/eventmesh.go index 8c6bbbd1..8a946a16 100644 --- a/internal/controller/operator.kyma-project.io/eventing/eventmesh.go +++ b/internal/controller/operator/eventing/eventmesh.go @@ -14,7 +14,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/eventing" subscriptionmanager "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager" diff --git a/internal/controller/operator.kyma-project.io/eventing/eventmesh_test.go b/internal/controller/operator/eventing/eventmesh_test.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/eventmesh_test.go rename to internal/controller/operator/eventing/eventmesh_test.go index 9aa3f916..f0a3aab9 100644 --- a/internal/controller/operator.kyma-project.io/eventing/eventmesh_test.go +++ b/internal/controller/operator/eventing/eventmesh_test.go @@ -7,7 +7,7 @@ import ( "github.com/kyma-project/eventing-manager/pkg/eventing" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/k8s" k8smocks "github.com/kyma-project/eventing-manager/pkg/k8s/mocks" diff --git a/internal/controller/operator.kyma-project.io/eventing/integrationtests/controller/integration_test.go b/internal/controller/operator/eventing/integrationtests/controller/integration_test.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/integrationtests/controller/integration_test.go rename to internal/controller/operator/eventing/integrationtests/controller/integration_test.go index c87daf3a..489f9500 100644 --- a/internal/controller/operator.kyma-project.io/eventing/integrationtests/controller/integration_test.go +++ b/internal/controller/operator/eventing/integrationtests/controller/integration_test.go @@ -7,7 +7,7 @@ import ( "os" "testing" - eventingcontroller "github.com/kyma-project/eventing-manager/internal/controller/operator.kyma-project.io/eventing" + eventingcontroller "github.com/kyma-project/eventing-manager/internal/controller/operator/eventing" "github.com/onsi/gomega" gomegatypes "github.com/onsi/gomega/types" @@ -17,11 +17,11 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - eventinv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventinv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" natsv1alpha1 "github.com/kyma-project/nats-manager/api/v1alpha1" natstestutils "github.com/kyma-project/nats-manager/testutils" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/eventing" "github.com/kyma-project/eventing-manager/pkg/k8s" "github.com/kyma-project/eventing-manager/test/matchers" diff --git a/internal/controller/operator.kyma-project.io/eventing/integrationtests/controller_switching/integration_test.go b/internal/controller/operator/eventing/integrationtests/controller_switching/integration_test.go similarity index 98% rename from internal/controller/operator.kyma-project.io/eventing/integrationtests/controller_switching/integration_test.go rename to internal/controller/operator/eventing/integrationtests/controller_switching/integration_test.go index a35a9406..9786283a 100644 --- a/internal/controller/operator.kyma-project.io/eventing/integrationtests/controller_switching/integration_test.go +++ b/internal/controller/operator/eventing/integrationtests/controller_switching/integration_test.go @@ -5,9 +5,9 @@ import ( "os" "testing" - eventingcontroller "github.com/kyma-project/eventing-manager/internal/controller/operator.kyma-project.io/eventing" + eventingcontroller "github.com/kyma-project/eventing-manager/internal/controller/operator/eventing" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/eventing" "github.com/kyma-project/eventing-manager/test/matchers" "github.com/kyma-project/eventing-manager/test/utils" diff --git a/internal/controller/operator.kyma-project.io/eventing/integrationtests/controllersinglecr/integration_test.go b/internal/controller/operator/eventing/integrationtests/controllersinglecr/integration_test.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/integrationtests/controllersinglecr/integration_test.go rename to internal/controller/operator/eventing/integrationtests/controllersinglecr/integration_test.go index bab75f13..b82d1528 100644 --- a/internal/controller/operator.kyma-project.io/eventing/integrationtests/controllersinglecr/integration_test.go +++ b/internal/controller/operator/eventing/integrationtests/controllersinglecr/integration_test.go @@ -7,7 +7,7 @@ import ( natstestutils "github.com/kyma-project/nats-manager/testutils" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/test/matchers" testutils "github.com/kyma-project/eventing-manager/test/utils" diff --git a/internal/controller/operator.kyma-project.io/eventing/integrationtests/nats_disabled/integration_test.go b/internal/controller/operator/eventing/integrationtests/nats_disabled/integration_test.go similarity index 98% rename from internal/controller/operator.kyma-project.io/eventing/integrationtests/nats_disabled/integration_test.go rename to internal/controller/operator/eventing/integrationtests/nats_disabled/integration_test.go index 6b250c94..ff62eb80 100644 --- a/internal/controller/operator.kyma-project.io/eventing/integrationtests/nats_disabled/integration_test.go +++ b/internal/controller/operator/eventing/integrationtests/nats_disabled/integration_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - eventingcontroller "github.com/kyma-project/eventing-manager/internal/controller/operator.kyma-project.io/eventing" + eventingcontroller "github.com/kyma-project/eventing-manager/internal/controller/operator/eventing" "github.com/kyma-project/eventing-manager/pkg/k8s" "github.com/kyma-project/eventing-manager/test/matchers" @@ -13,7 +13,7 @@ import ( natstestutils "github.com/kyma-project/nats-manager/testutils" "github.com/onsi/gomega" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/eventing" testutils "github.com/kyma-project/eventing-manager/test/utils/integration" "github.com/stretchr/testify/require" diff --git a/internal/controller/operator.kyma-project.io/eventing/integrationtests/validation/integration_test.go b/internal/controller/operator/eventing/integrationtests/validation/integration_test.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/integrationtests/validation/integration_test.go rename to internal/controller/operator/eventing/integrationtests/validation/integration_test.go index 0bae7405..5e010e59 100644 --- a/internal/controller/operator.kyma-project.io/eventing/integrationtests/validation/integration_test.go +++ b/internal/controller/operator/eventing/integrationtests/validation/integration_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/test" eventingMatchers "github.com/kyma-project/eventing-manager/test/matchers" "github.com/kyma-project/eventing-manager/test/utils/integration" diff --git a/internal/controller/operator.kyma-project.io/eventing/integrationtests/without_apirule_crd/integration_test.go b/internal/controller/operator/eventing/integrationtests/without_apirule_crd/integration_test.go similarity index 98% rename from internal/controller/operator.kyma-project.io/eventing/integrationtests/without_apirule_crd/integration_test.go rename to internal/controller/operator/eventing/integrationtests/without_apirule_crd/integration_test.go index 584d62d0..fbbf4fd6 100644 --- a/internal/controller/operator.kyma-project.io/eventing/integrationtests/without_apirule_crd/integration_test.go +++ b/internal/controller/operator/eventing/integrationtests/without_apirule_crd/integration_test.go @@ -4,7 +4,7 @@ import ( "os" "testing" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/test/matchers" "github.com/kyma-project/eventing-manager/test/utils" testutils "github.com/kyma-project/eventing-manager/test/utils/integration" diff --git a/internal/controller/operator.kyma-project.io/eventing/mocks/controller.go b/internal/controller/operator/eventing/mocks/controller.go similarity index 100% rename from internal/controller/operator.kyma-project.io/eventing/mocks/controller.go rename to internal/controller/operator/eventing/mocks/controller.go diff --git a/internal/controller/operator.kyma-project.io/eventing/mocks/manager.go b/internal/controller/operator/eventing/mocks/manager.go similarity index 100% rename from internal/controller/operator.kyma-project.io/eventing/mocks/manager.go rename to internal/controller/operator/eventing/mocks/manager.go diff --git a/internal/controller/operator.kyma-project.io/eventing/mocks/nats_config_handler.go b/internal/controller/operator/eventing/mocks/nats_config_handler.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/mocks/nats_config_handler.go rename to internal/controller/operator/eventing/mocks/nats_config_handler.go index c1e1c6c0..adc5591a 100644 --- a/internal/controller/operator.kyma-project.io/eventing/mocks/nats_config_handler.go +++ b/internal/controller/operator/eventing/mocks/nats_config_handler.go @@ -9,7 +9,7 @@ import ( mock "github.com/stretchr/testify/mock" - v1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + v1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" ) // NatsConfigHandler is an autogenerated mock type for the NatsConfigHandler type diff --git a/internal/controller/operator.kyma-project.io/eventing/nats.go b/internal/controller/operator/eventing/nats.go similarity index 98% rename from internal/controller/operator.kyma-project.io/eventing/nats.go rename to internal/controller/operator/eventing/nats.go index 621f3c47..cd3d18a1 100644 --- a/internal/controller/operator.kyma-project.io/eventing/nats.go +++ b/internal/controller/operator/eventing/nats.go @@ -6,7 +6,7 @@ import ( "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/options" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/k8s" diff --git a/internal/controller/operator.kyma-project.io/eventing/nats_test.go b/internal/controller/operator/eventing/nats_test.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/nats_test.go rename to internal/controller/operator/eventing/nats_test.go index 388a8942..bf86aa86 100644 --- a/internal/controller/operator.kyma-project.io/eventing/nats_test.go +++ b/internal/controller/operator/eventing/nats_test.go @@ -7,11 +7,11 @@ import ( "testing" "time" - "github.com/kyma-project/eventing-manager/internal/controller/operator.kyma-project.io/eventing/mocks" + "github.com/kyma-project/eventing-manager/internal/controller/operator/eventing/mocks" submanagermocks "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager/mocks" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/options" "github.com/kyma-project/eventing-manager/pkg/env" managermocks "github.com/kyma-project/eventing-manager/pkg/eventing/mocks" diff --git a/internal/controller/operator.kyma-project.io/eventing/service_instance_secret.go b/internal/controller/operator/eventing/service_instance_secret.go similarity index 100% rename from internal/controller/operator.kyma-project.io/eventing/service_instance_secret.go rename to internal/controller/operator/eventing/service_instance_secret.go diff --git a/internal/controller/operator.kyma-project.io/eventing/status.go b/internal/controller/operator/eventing/status.go similarity index 99% rename from internal/controller/operator.kyma-project.io/eventing/status.go rename to internal/controller/operator/eventing/status.go index 2182ea0d..deb918c5 100644 --- a/internal/controller/operator.kyma-project.io/eventing/status.go +++ b/internal/controller/operator/eventing/status.go @@ -5,7 +5,7 @@ import ( "errors" "time" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "go.uber.org/zap" v1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/internal/controller/operator.kyma-project.io/eventing/unit_test.go b/internal/controller/operator/eventing/unit_test.go similarity index 97% rename from internal/controller/operator.kyma-project.io/eventing/unit_test.go rename to internal/controller/operator/eventing/unit_test.go index 1a49086f..b6dbb9c3 100644 --- a/internal/controller/operator.kyma-project.io/eventing/unit_test.go +++ b/internal/controller/operator/eventing/unit_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - ctrlmocks "github.com/kyma-project/eventing-manager/internal/controller/operator.kyma-project.io/eventing/mocks" + ctrlmocks "github.com/kyma-project/eventing-manager/internal/controller/operator/eventing/mocks" apiclientsetfake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake" @@ -20,7 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" managermocks "github.com/kyma-project/eventing-manager/pkg/eventing/mocks" natsv1alpha1 "github.com/kyma-project/nats-manager/api/v1alpha1" "github.com/stretchr/testify/require" diff --git a/internal/controller/operator.kyma-project.io/eventing/utils.go b/internal/controller/operator/eventing/utils.go similarity index 98% rename from internal/controller/operator.kyma-project.io/eventing/utils.go rename to internal/controller/operator/eventing/utils.go index e6234c12..1c010ea6 100644 --- a/internal/controller/operator.kyma-project.io/eventing/utils.go +++ b/internal/controller/operator/eventing/utils.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/mitchellh/hashstructure/v2" ctrl "sigs.k8s.io/controller-runtime" diff --git a/internal/controller/operator.kyma-project.io/eventing/utils_test.go b/internal/controller/operator/eventing/utils_test.go similarity index 98% rename from internal/controller/operator.kyma-project.io/eventing/utils_test.go rename to internal/controller/operator/eventing/utils_test.go index 1172930d..2489b9aa 100644 --- a/internal/controller/operator.kyma-project.io/eventing/utils_test.go +++ b/internal/controller/operator/eventing/utils_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" - eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/test/utils" "github.com/stretchr/testify/require" ) diff --git a/internal/controller/operator.kyma-project.io/eventing/webhook.go b/internal/controller/operator/eventing/webhook.go similarity index 100% rename from internal/controller/operator.kyma-project.io/eventing/webhook.go rename to internal/controller/operator/eventing/webhook.go diff --git a/internal/controller/operator.kyma-project.io/eventing/webhook_test.go b/internal/controller/operator/eventing/webhook_test.go similarity index 100% rename from internal/controller/operator.kyma-project.io/eventing/webhook_test.go rename to internal/controller/operator/eventing/webhook_test.go diff --git a/pkg/backend/eventmesh/eventmesh.go b/pkg/backend/eventmesh/eventmesh.go index 18f1682f..bd09b480 100644 --- a/pkg/backend/eventmesh/eventmesh.go +++ b/pkg/backend/eventmesh/eventmesh.go @@ -8,6 +8,7 @@ import ( "go.uber.org/zap" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" backendutils "github.com/kyma-project/eventing-manager/pkg/backend/utils" "github.com/kyma-project/eventing-manager/pkg/ems/api/events/client" @@ -17,7 +18,6 @@ import ( "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/featureflags" "github.com/kyma-project/eventing-manager/pkg/logger" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) const ( diff --git a/pkg/backend/eventmesh/eventmesh_integration_test.go b/pkg/backend/eventmesh/eventmesh_integration_test.go index 7ff656e7..1ee71d60 100644 --- a/pkg/backend/eventmesh/eventmesh_integration_test.go +++ b/pkg/backend/eventmesh/eventmesh_integration_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" backendutils "github.com/kyma-project/eventing-manager/pkg/backend/utils" PublisherManagerMock "github.com/kyma-project/eventing-manager/pkg/ems/api/events/client/mocks" @@ -15,7 +16,6 @@ import ( "github.com/kyma-project/eventing-manager/pkg/logger" controllertesting "github.com/kyma-project/eventing-manager/testing" kymalogger "github.com/kyma-project/kyma/common/logging/logger" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) func Test_getProcessedEventTypes(t *testing.T) { diff --git a/pkg/backend/eventmesh/mocks/Backend.go b/pkg/backend/eventmesh/mocks/Backend.go index 9e40283e..18d512c0 100644 --- a/pkg/backend/eventmesh/mocks/Backend.go +++ b/pkg/backend/eventmesh/mocks/Backend.go @@ -8,7 +8,7 @@ import ( mock "github.com/stretchr/testify/mock" - v1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + v1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" v1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" ) diff --git a/pkg/backend/eventmesh/utils.go b/pkg/backend/eventmesh/utils.go index fc732713..950033ec 100644 --- a/pkg/backend/eventmesh/utils.go +++ b/pkg/backend/eventmesh/utils.go @@ -4,9 +4,9 @@ import ( "fmt" "strings" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" backendutils "github.com/kyma-project/eventing-manager/pkg/backend/utils" "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) // getEventMeshSubject appends the prefix to subject. diff --git a/pkg/backend/eventmesh/utils_unit_test.go b/pkg/backend/eventmesh/utils_unit_test.go index 556ac1ae..521470fc 100644 --- a/pkg/backend/eventmesh/utils_unit_test.go +++ b/pkg/backend/eventmesh/utils_unit_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/require" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" backendutils "github.com/kyma-project/eventing-manager/pkg/backend/utils" eventingtesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) func Test_IsEventTypeSegmentsOverLimit(t *testing.T) { diff --git a/pkg/backend/jetstream/jetstream.go b/pkg/backend/jetstream/jetstream.go index ded9e7ac..aeeafb83 100644 --- a/pkg/backend/jetstream/jetstream.go +++ b/pkg/backend/jetstream/jetstream.go @@ -19,8 +19,8 @@ import ( "github.com/pkg/errors" "go.uber.org/zap" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" - ecenv "github.com/kyma-project/kyma/components/eventing-controller/pkg/env" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" + ecenv "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" backendmetrics "github.com/kyma-project/eventing-manager/pkg/backend/metrics" diff --git a/pkg/backend/jetstream/jetstream_integration_test.go b/pkg/backend/jetstream/jetstream_integration_test.go index 6cab3e64..d8bd38e0 100644 --- a/pkg/backend/jetstream/jetstream_integration_test.go +++ b/pkg/backend/jetstream/jetstream_integration_test.go @@ -13,13 +13,13 @@ import ( kymalogger "github.com/kyma-project/kyma/common/logging/logger" "github.com/stretchr/testify/require" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" "github.com/kyma-project/eventing-manager/pkg/backend/metrics" "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/logger" evtesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) // TestJetStreamSubAfterSync_SinkChange tests the SyncSubscription method diff --git a/pkg/backend/jetstream/jetstream_internal_unit_test.go b/pkg/backend/jetstream/jetstream_internal_unit_test.go index 71874ae0..fb617701 100644 --- a/pkg/backend/jetstream/jetstream_internal_unit_test.go +++ b/pkg/backend/jetstream/jetstream_internal_unit_test.go @@ -13,10 +13,10 @@ import ( "github.com/stretchr/testify/assert" + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" "github.com/kyma-project/eventing-manager/pkg/backend/metrics" subtesting "github.com/kyma-project/eventing-manager/testing" - "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) diff --git a/pkg/backend/jetstream/mocks/Backend.go b/pkg/backend/jetstream/mocks/Backend.go index 1dab8391..c3e98314 100644 --- a/pkg/backend/jetstream/mocks/Backend.go +++ b/pkg/backend/jetstream/mocks/Backend.go @@ -11,7 +11,7 @@ import ( utils "github.com/kyma-project/eventing-manager/pkg/backend/utils" - v1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + v1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" ) // Backend is an autogenerated mock type for the Backend type diff --git a/pkg/backend/jetstream/test_helpers.go b/pkg/backend/jetstream/test_helpers.go index f5e2de9c..3d024e1a 100644 --- a/pkg/backend/jetstream/test_helpers.go +++ b/pkg/backend/jetstream/test_helpers.go @@ -18,9 +18,9 @@ import ( v2 "github.com/cloudevents/sdk-go/v2" "github.com/cloudevents/sdk-go/v2/binding" cev2http "github.com/cloudevents/sdk-go/v2/protocol/http" + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" evtesting "github.com/kyma-project/eventing-manager/testing" - "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) const ( diff --git a/pkg/backend/jetstream/types.go b/pkg/backend/jetstream/types.go index f4f29cbe..62c94f5b 100644 --- a/pkg/backend/jetstream/types.go +++ b/pkg/backend/jetstream/types.go @@ -9,11 +9,11 @@ import ( "github.com/nats-io/nats.go" cev2 "github.com/cloudevents/sdk-go/v2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" backendmetrics "github.com/kyma-project/eventing-manager/pkg/backend/metrics" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/logger" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) const ( diff --git a/pkg/backend/jetstream/utils.go b/pkg/backend/jetstream/utils.go index bcdb2fdf..8371812f 100644 --- a/pkg/backend/jetstream/utils.go +++ b/pkg/backend/jetstream/utils.go @@ -15,8 +15,8 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/types" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) const ( diff --git a/pkg/backend/jetstream/utils_internal_integration_test.go b/pkg/backend/jetstream/utils_internal_integration_test.go index 72883fcd..a0fd0e22 100644 --- a/pkg/backend/jetstream/utils_internal_integration_test.go +++ b/pkg/backend/jetstream/utils_internal_integration_test.go @@ -3,8 +3,8 @@ package jetstream import ( "testing" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" evtesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" "github.com/stretchr/testify/require" ) diff --git a/pkg/backend/jetstream/utils_internal_unit_test.go b/pkg/backend/jetstream/utils_internal_unit_test.go index 8b08c72c..519d6f96 100644 --- a/pkg/backend/jetstream/utils_internal_unit_test.go +++ b/pkg/backend/jetstream/utils_internal_unit_test.go @@ -11,10 +11,10 @@ import ( kymalogger "github.com/kyma-project/kyma/common/logging/logger" "github.com/stretchr/testify/require" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" "github.com/kyma-project/eventing-manager/pkg/logger" evtesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) // maxJetStreamConsumerNameLength is the maximum preferred length for the JetStream consumer names diff --git a/pkg/backend/sink/validator.go b/pkg/backend/sink/validator.go index a84bccbe..5171a528 100644 --- a/pkg/backend/sink/validator.go +++ b/pkg/backend/sink/validator.go @@ -12,8 +12,8 @@ import ( "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/internal/controller/events" - "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) type Validator interface { diff --git a/pkg/backend/sink/validator_test.go b/pkg/backend/sink/validator_test.go index 63046f42..de3f4f5c 100644 --- a/pkg/backend/sink/validator_test.go +++ b/pkg/backend/sink/validator_test.go @@ -12,8 +12,8 @@ import ( "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client/fake" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" controllertesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) func TestSinkValidator(t *testing.T) { diff --git a/pkg/backend/utils/eventmesh_utils.go b/pkg/backend/utils/eventmesh_utils.go index e772cef4..d9ac30d7 100644 --- a/pkg/backend/utils/eventmesh_utils.go +++ b/pkg/backend/utils/eventmesh_utils.go @@ -9,9 +9,9 @@ import ( "github.com/pkg/errors" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" "github.com/kyma-project/eventing-manager/pkg/featureflags" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) // eventMeshSubscriptionNameMapper maps a Kyma subscription to an ID that can be used on the EventMesh backend, diff --git a/pkg/backend/utils/eventmesh_utils_test.go b/pkg/backend/utils/eventmesh_utils_test.go index a4fdd251..4f63de10 100644 --- a/pkg/backend/utils/eventmesh_utils_test.go +++ b/pkg/backend/utils/eventmesh_utils_test.go @@ -15,9 +15,9 @@ import ( . "github.com/onsi/gomega" v1meta "k8s.io/apimachinery/pkg/apis/meta/v1" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" eventingtesting "github.com/kyma-project/eventing-manager/testing" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) func TestConvertKymaSubToEventMeshSub(t *testing.T) { diff --git a/pkg/backend/utils/utils.go b/pkg/backend/utils/utils.go index 4f906ef5..e2e32449 100644 --- a/pkg/backend/utils/utils.go +++ b/pkg/backend/utils/utils.go @@ -6,7 +6,7 @@ import ( "fmt" "net/url" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/pkg/errors" "go.uber.org/zap" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/env/nats_config.go b/pkg/env/nats_config.go index 6ab9a8a3..4029cf6f 100644 --- a/pkg/env/nats_config.go +++ b/pkg/env/nats_config.go @@ -4,7 +4,7 @@ import ( "strings" "time" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kelseyhightower/envconfig" ) diff --git a/pkg/env/nats_config_test.go b/pkg/env/nats_config_test.go index 67c9c1a6..fdddc0ad 100644 --- a/pkg/env/nats_config_test.go +++ b/pkg/env/nats_config_test.go @@ -7,7 +7,10 @@ import ( "testing" "time" - "github.com/kyma-project/eventing-manager/test/utils" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/stretchr/testify/require" ) @@ -29,10 +32,29 @@ func Test_GetNewNATSConfig(t *testing.T) { JSConsumerDeliverPolicy: "DeliverNew", } - givenEventing := utils.NewEventingCR( - utils.WithEventingStreamData("Memory", "650M", 5, 5000), - utils.WithEventingEventTypePrefix("sap.kyma.custom"), - ) + givenEventing := &v1alpha1.Eventing{ + TypeMeta: metav1.TypeMeta{ + Kind: "Eventing", + APIVersion: "operator.kyma-project.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "test-ns", + UID: "1234-5678-1234-5678", + }, + Spec: v1alpha1.EventingSpec{ + Backend: v1alpha1.Backend{ + Type: v1alpha1.NatsBackendType, + Config: v1alpha1.BackendConfig{ + EventTypePrefix: "sap.kyma.custom", + NATSStreamStorageType: "Memory", + NATSStreamMaxSize: resource.MustParse("650M"), + NATSStreamReplicas: 5, + NATSMaxMsgsPerTopic: 5000, + }, + }, + }, + } // when result := givenConfig.GetNewNATSConfig(*givenEventing) diff --git a/pkg/eventing/deployment.go b/pkg/eventing/deployment.go index d3a18316..fae7c6ef 100644 --- a/pkg/eventing/deployment.go +++ b/pkg/eventing/deployment.go @@ -11,7 +11,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/utils" ) diff --git a/pkg/eventing/deployment_test.go b/pkg/eventing/deployment_test.go index 1d0ff82a..07c02b87 100644 --- a/pkg/eventing/deployment_test.go +++ b/pkg/eventing/deployment_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/test" testutils "github.com/kyma-project/eventing-manager/test/utils" diff --git a/pkg/eventing/manager.go b/pkg/eventing/manager.go index 7ed46c42..1f577e23 100644 --- a/pkg/eventing/manager.go +++ b/pkg/eventing/manager.go @@ -4,14 +4,14 @@ import ( "context" "fmt" - ecv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" + ecv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/k8s" "github.com/kyma-project/eventing-manager/pkg/logger" diff --git a/pkg/eventing/manager_test.go b/pkg/eventing/manager_test.go index 363b7176..3e8632f6 100644 --- a/pkg/eventing/manager_test.go +++ b/pkg/eventing/manager_test.go @@ -17,15 +17,15 @@ import ( "k8s.io/apimachinery/pkg/runtime" - ecv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + ecv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" natsv1alpha1 "github.com/kyma-project/nats-manager/api/v1alpha1" natstestutils "github.com/kyma-project/nats-manager/testutils" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/env" k8smocks "github.com/kyma-project/eventing-manager/pkg/k8s/mocks" testutils "github.com/kyma-project/eventing-manager/test/utils" diff --git a/pkg/eventing/mocks/manager.go b/pkg/eventing/mocks/manager.go index 3d927b26..276ce666 100644 --- a/pkg/eventing/mocks/manager.go +++ b/pkg/eventing/mocks/manager.go @@ -11,7 +11,7 @@ import ( v1 "k8s.io/api/apps/v1" - v1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + v1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" ) // Manager is an autogenerated mock type for the Manager type diff --git a/pkg/eventing/utils.go b/pkg/eventing/utils.go index d8421bfb..2167060b 100644 --- a/pkg/eventing/utils.go +++ b/pkg/eventing/utils.go @@ -3,8 +3,8 @@ package eventing import ( "fmt" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" - ecv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" + ecv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" diff --git a/pkg/eventing/utils_test.go b/pkg/eventing/utils_test.go index 635d6fda..f549ee64 100644 --- a/pkg/eventing/utils_test.go +++ b/pkg/eventing/utils_test.go @@ -3,7 +3,7 @@ package eventing import ( "testing" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/k8s/client.go b/pkg/k8s/client.go index ab39af5b..8d80982a 100644 --- a/pkg/k8s/client.go +++ b/pkg/k8s/client.go @@ -20,7 +20,7 @@ import ( "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" natsv1alpha1 "github.com/kyma-project/nats-manager/api/v1alpha1" ) diff --git a/pkg/k8s/client_test.go b/pkg/k8s/client_test.go index a5a48135..493e58c1 100644 --- a/pkg/k8s/client_test.go +++ b/pkg/k8s/client_test.go @@ -11,7 +11,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" testutils "github.com/kyma-project/eventing-manager/test/utils" diff --git a/pkg/k8s/mocks/client.go b/pkg/k8s/mocks/client.go index 35c6ef5c..87946f13 100644 --- a/pkg/k8s/mocks/client.go +++ b/pkg/k8s/mocks/client.go @@ -18,7 +18,7 @@ import ( v1alpha1 "github.com/kyma-project/nats-manager/api/v1alpha1" - v1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + v1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" v1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" ) diff --git a/pkg/object/apirule.go b/pkg/object/apirule.go index 1237fd5b..0fbbb396 100644 --- a/pkg/object/apirule.go +++ b/pkg/object/apirule.go @@ -8,8 +8,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/featureflags" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) const ( diff --git a/pkg/object/apirule_test.go b/pkg/object/apirule_test.go index 86315ee8..12c23616 100644 --- a/pkg/object/apirule_test.go +++ b/pkg/object/apirule_test.go @@ -2,14 +2,15 @@ package object import ( "fmt" + "reflect" + "testing" + "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/ptr" - "reflect" - "testing" ) func TestApplyExistingAPIRuleAttributes(t *testing.T) { diff --git a/pkg/object/equality.go b/pkg/object/equality.go index 8851bc2a..eb34f719 100644 --- a/pkg/object/equality.go +++ b/pkg/object/equality.go @@ -11,15 +11,13 @@ import ( "k8s.io/apimachinery/pkg/conversion" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" ) // Semantic can do semantic deep equality checks for API objects. Fields which // are not relevant for the reconciliation logic are intentionally omitted. var Semantic = conversion.EqualitiesOrDie( apiRuleEqual, - eventingBackendEqual, publisherProxyDeploymentEqual, serviceAccountEqual, clusterRoleEqual, @@ -209,26 +207,6 @@ func ownerReferencesDeepEqual(ors1, ors2 []v1.OwnerReference) bool { return true } -// eventingBackendEqual asserts the equality of two EventingBackend objects. -func eventingBackendEqual(b1, b2 *eventingv1alpha1.EventingBackend) bool { - if b1 == nil || b2 == nil { - return false - } - if b1 == b2 { - return true - } - - if !reflect.DeepEqual(b1.Labels, b2.Labels) { - return false - } - - if !reflect.DeepEqual(b1.Spec, b2.Spec) { - return false - } - - return true -} - // publisherProxyDeploymentEqual asserts the equality of two Deployment objects // for event publisher proxy deployments. func publisherProxyDeploymentEqual(d1, d2 *appsv1.Deployment) bool { @@ -414,17 +392,6 @@ func realProto(pr corev1.Protocol) corev1.Protocol { return pr } -func IsBackendStatusEqual(oldStatus, newStatus eventingv1alpha1.EventingBackendStatus) bool { - oldStatusWithoutCond := oldStatus.DeepCopy() - newStatusWithoutCond := newStatus.DeepCopy() - - // remove conditions, so that we don't compare them - oldStatusWithoutCond.Conditions = []eventingv1alpha1.Condition{} - newStatusWithoutCond.Conditions = []eventingv1alpha1.Condition{} - - return reflect.DeepEqual(oldStatusWithoutCond, newStatusWithoutCond) && eventingv1alpha1.ConditionsEquals(oldStatus.Conditions, newStatus.Conditions) -} - func IsSubscriptionStatusEqual(oldStatus, newStatus eventingv1alpha2.SubscriptionStatus) bool { oldStatusWithoutCond := oldStatus.DeepCopy() newStatusWithoutCond := newStatus.DeepCopy() diff --git a/pkg/object/equality_test.go b/pkg/object/equality_test.go index 056aafe8..159aa3b1 100644 --- a/pkg/object/equality_test.go +++ b/pkg/object/equality_test.go @@ -1,12 +1,12 @@ package object import ( - "k8s.io/apimachinery/pkg/util/intstr" "net/http" "testing" + "k8s.io/apimachinery/pkg/util/intstr" + "github.com/stretchr/testify/require" - appsv1 "k8s.io/api/apps/v1" v2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -16,12 +16,7 @@ import ( "k8s.io/utils/ptr" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" - "github.com/kyma-project/kyma/components/eventing-controller/pkg/deployment" - "github.com/kyma-project/kyma/components/eventing-controller/pkg/env" - - "github.com/kyma-project/eventing-manager/pkg/utils" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" ) func TestApiRuleEqual(t *testing.T) { @@ -187,202 +182,6 @@ func TestApiRuleEqual(t *testing.T) { } } -func TestEventingBackendEqual(t *testing.T) { - emptyBackend := eventingv1alpha1.EventingBackend{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: "bar", - }, - Spec: eventingv1alpha1.EventingBackendSpec{}, - } - - testCases := map[string]struct { - getBackend1 func() *eventingv1alpha1.EventingBackend - getBackend2 func() *eventingv1alpha1.EventingBackend - expectedResult bool - }{ - "should be unequal if labels are different": { - getBackend1: func() *eventingv1alpha1.EventingBackend { - b := emptyBackend.DeepCopy() - b.Labels = map[string]string{"k1": "v1"} - return b - }, - getBackend2: func() *eventingv1alpha1.EventingBackend { - return emptyBackend.DeepCopy() - }, - expectedResult: false, - }, - "should be equal if labels are the same": { - getBackend1: func() *eventingv1alpha1.EventingBackend { - b := emptyBackend.DeepCopy() - b.Labels = map[string]string{"k1": "v1"} - return b - }, - getBackend2: func() *eventingv1alpha1.EventingBackend { - b := emptyBackend.DeepCopy() - b.Name = "bar" - b.Labels = map[string]string{"k1": "v1"} - return b - }, - expectedResult: true, - }, - } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - if eventingBackendEqual(tc.getBackend1(), tc.getBackend2()) != tc.expectedResult { - t.Errorf("expected output to be %t", tc.expectedResult) - } - }) - } -} - -func TestEventingBackendStatusEqual(t *testing.T) { - testCases := []struct { - name string - givenBackendStatus1 eventingv1alpha1.EventingBackendStatus - givenBackendStatus2 eventingv1alpha1.EventingBackendStatus - wantResult bool - }{ - { - name: "should be unequal if ready status is different", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - EventingReady: utils.BoolPtr(false), - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - EventingReady: utils.BoolPtr(true), - }, - wantResult: false, - }, - { - name: "should be unequal if missing secret", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - EventingReady: utils.BoolPtr(false), - BEBSecretName: "secret", - BEBSecretNamespace: "default", - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - EventingReady: utils.BoolPtr(false), - }, - wantResult: false, - }, - { - name: "should be unequal if different secretName", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - EventingReady: utils.BoolPtr(false), - BEBSecretName: "secret", - BEBSecretNamespace: "default", - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - EventingReady: utils.BoolPtr(false), - BEBSecretName: "secretnew", - BEBSecretNamespace: "default", - }, - wantResult: false, - }, - { - name: "should be unequal if different secretNamespace", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - EventingReady: utils.BoolPtr(false), - BEBSecretName: "secret", - BEBSecretNamespace: "default", - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - EventingReady: utils.BoolPtr(false), - BEBSecretName: "secret", - BEBSecretNamespace: "kyma-system", - }, - wantResult: false, - }, - { - name: "should be unequal if missing backend", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - Backend: eventingv1alpha1.NatsBackendType, - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{}, - wantResult: false, - }, - { - name: "should be unequal if different backend", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - Backend: eventingv1alpha1.NatsBackendType, - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - Backend: eventingv1alpha1.BEBBackendType, - }, - wantResult: false, - }, - { - name: "should be unequal if conditions different", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - Conditions: []eventingv1alpha1.Condition{ - {Type: eventingv1alpha1.ConditionPublisherProxyReady, Status: corev1.ConditionTrue}, - }, - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - Conditions: []eventingv1alpha1.Condition{ - {Type: eventingv1alpha1.ConditionPublisherProxyReady, Status: corev1.ConditionFalse}, - }, - }, - wantResult: false, - }, - { - name: "should be unequal if conditions missing", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - Conditions: []eventingv1alpha1.Condition{ - {Type: eventingv1alpha1.ConditionPublisherProxyReady, Status: corev1.ConditionTrue}, - }, - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - Conditions: []eventingv1alpha1.Condition{}, - }, - wantResult: false, - }, - { - name: "should be unequal if conditions different", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - Conditions: []eventingv1alpha1.Condition{ - {Type: eventingv1alpha1.ConditionPublisherProxyReady, Status: corev1.ConditionTrue}, - }, - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - Conditions: []eventingv1alpha1.Condition{ - {Type: eventingv1alpha1.ConditionControllerReady, Status: corev1.ConditionTrue}, - }, - }, - wantResult: false, - }, - { - name: "should be equal if the status are the same", - givenBackendStatus1: eventingv1alpha1.EventingBackendStatus{ - Backend: eventingv1alpha1.NatsBackendType, - Conditions: []eventingv1alpha1.Condition{ - {Type: eventingv1alpha1.ConditionControllerReady, Status: corev1.ConditionTrue}, - {Type: eventingv1alpha1.ConditionPublisherProxyReady, Status: corev1.ConditionTrue}, - }, - EventingReady: utils.BoolPtr(true), - }, - givenBackendStatus2: eventingv1alpha1.EventingBackendStatus{ - Backend: eventingv1alpha1.NatsBackendType, - Conditions: []eventingv1alpha1.Condition{ - {Type: eventingv1alpha1.ConditionControllerReady, Status: corev1.ConditionTrue}, - {Type: eventingv1alpha1.ConditionPublisherProxyReady, Status: corev1.ConditionTrue}, - }, - EventingReady: utils.BoolPtr(true), - }, - wantResult: true, - }, - } - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - if IsBackendStatusEqual(tc.givenBackendStatus1, tc.givenBackendStatus2) != tc.wantResult { - t.Errorf("expected output to be %t", tc.wantResult) - } - }) - } -} - func Test_isSubscriptionStatusEqual(t *testing.T) { testCases := []struct { name string @@ -455,178 +254,178 @@ func Test_isSubscriptionStatusEqual(t *testing.T) { } } -func TestPublisherProxyDeploymentEqual(t *testing.T) { - publisherCfg := env.PublisherConfig{ - Image: "publisher", - PortNum: 0, - MetricsPortNum: 0, - ServiceAccount: "publisher-sa", - Replicas: 1, - RequestsCPU: "32m", - RequestsMemory: "64Mi", - LimitsCPU: "64m", - LimitsMemory: "128Mi", - } - natsConfig := env.NATSConfig{ - EventTypePrefix: "prefix", - JSStreamName: "kyma", - } - defaultNATSPublisher := deployment.NewNATSPublisherDeployment(natsConfig, publisherCfg) - defaultBEBPublisher := deployment.NewBEBPublisherDeployment(publisherCfg) - - testCases := map[string]struct { - getPublisher1 func() *appsv1.Deployment - getPublisher2 func() *appsv1.Deployment - expectedResult bool - }{ - "should be equal if same default NATS publisher": { - getPublisher1: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Name = "publisher1" - return p - }, - getPublisher2: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Name = "publisher2" - return p - }, - expectedResult: true, - }, - "should be equal if same default BEB publisher": { - getPublisher1: func() *appsv1.Deployment { - p := defaultBEBPublisher.DeepCopy() - p.Name = "publisher1" - return p - }, - getPublisher2: func() *appsv1.Deployment { - p := defaultBEBPublisher.DeepCopy() - p.Name = "publisher2" - return p - }, - expectedResult: true, - }, - "should be unequal if publisher types are different": { - getPublisher1: func() *appsv1.Deployment { - return defaultBEBPublisher.DeepCopy() - }, - getPublisher2: func() *appsv1.Deployment { - return defaultNATSPublisher.DeepCopy() - }, - expectedResult: false, - }, - "should be unequal if publisher image changes": { - getPublisher1: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Spec.Containers[0].Image = "new-publisher-img" - return p - }, - getPublisher2: func() *appsv1.Deployment { - return defaultNATSPublisher.DeepCopy() - }, - expectedResult: false, - }, - "should be unequal if env var changes": { - getPublisher1: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Spec.Containers[0].Env[0].Value = "new-value" - return p - }, - getPublisher2: func() *appsv1.Deployment { - return defaultNATSPublisher.DeepCopy() - }, - expectedResult: false, - }, - "should be equal if replicas changes": { - getPublisher1: func() *appsv1.Deployment { - replicas := int32(1) - p := defaultNATSPublisher.DeepCopy() - p.Spec.Replicas = &replicas - return p - }, - getPublisher2: func() *appsv1.Deployment { - replicas := int32(2) - p := defaultNATSPublisher.DeepCopy() - p.Spec.Replicas = &replicas - return p - }, - expectedResult: true, - }, - "should be equal if replicas are the same": { - getPublisher1: func() *appsv1.Deployment { - replicas := int32(2) - p := defaultNATSPublisher.DeepCopy() - p.Spec.Replicas = &replicas - return p - }, - getPublisher2: func() *appsv1.Deployment { - replicas := int32(2) - p := defaultNATSPublisher.DeepCopy() - p.Spec.Replicas = &replicas - return p - }, - expectedResult: true, - }, - "should be equal if spec annotations are nil and empty": { - getPublisher1: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Annotations = nil - return p - }, - getPublisher2: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Annotations = map[string]string{} - return p - }, - expectedResult: true, - }, - "should be unequal if spec annotations changes": { - getPublisher1: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Annotations = map[string]string{"key": "value1"} - return p - }, - getPublisher2: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Annotations = map[string]string{"key": "value2"} - return p - }, - expectedResult: false, - }, - "should be equal if spec Labels are nil and empty": { - getPublisher1: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Labels = nil - return p - }, - getPublisher2: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Labels = map[string]string{} - return p - }, - expectedResult: true, - }, - "should be unequal if spec Labels changes": { - getPublisher1: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Labels = map[string]string{"key": "value1"} - return p - }, - getPublisher2: func() *appsv1.Deployment { - p := defaultNATSPublisher.DeepCopy() - p.Spec.Template.Labels = map[string]string{"key": "value2"} - return p - }, - expectedResult: false, - }, - } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - if publisherProxyDeploymentEqual(tc.getPublisher1(), tc.getPublisher2()) != tc.expectedResult { - t.Errorf("expected output to be %t", tc.expectedResult) - } - }) - } -} +//func TestPublisherProxyDeploymentEqual(t *testing.T) { +// publisherCfg := env.PublisherConfig{ +// Image: "publisher", +// PortNum: 0, +// MetricsPortNum: 0, +// ServiceAccount: "publisher-sa", +// Replicas: 1, +// RequestsCPU: "32m", +// RequestsMemory: "64Mi", +// LimitsCPU: "64m", +// LimitsMemory: "128Mi", +// } +// natsConfig := env.NATSConfig{ +// EventTypePrefix: "prefix", +// JSStreamName: "kyma", +// } +// defaultNATSPublisher := eventingpkg.NewNATSPublisherDeployment(natsConfig, publisherCfg) +// defaultBEBPublisher := eventingpkg.NewBEBPublisherDeployment(publisherCfg) +// +// testCases := map[string]struct { +// getPublisher1 func() *appsv1.Deployment +// getPublisher2 func() *appsv1.Deployment +// expectedResult bool +// }{ +// "should be equal if same default NATS publisher": { +// getPublisher1: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Name = "publisher1" +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Name = "publisher2" +// return p +// }, +// expectedResult: true, +// }, +// "should be equal if same default BEB publisher": { +// getPublisher1: func() *appsv1.Deployment { +// p := defaultBEBPublisher.DeepCopy() +// p.Name = "publisher1" +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// p := defaultBEBPublisher.DeepCopy() +// p.Name = "publisher2" +// return p +// }, +// expectedResult: true, +// }, +// "should be unequal if publisher types are different": { +// getPublisher1: func() *appsv1.Deployment { +// return defaultBEBPublisher.DeepCopy() +// }, +// getPublisher2: func() *appsv1.Deployment { +// return defaultNATSPublisher.DeepCopy() +// }, +// expectedResult: false, +// }, +// "should be unequal if publisher image changes": { +// getPublisher1: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Spec.Containers[0].Image = "new-publisher-img" +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// return defaultNATSPublisher.DeepCopy() +// }, +// expectedResult: false, +// }, +// "should be unequal if env var changes": { +// getPublisher1: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Spec.Containers[0].Env[0].Value = "new-value" +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// return defaultNATSPublisher.DeepCopy() +// }, +// expectedResult: false, +// }, +// "should be equal if replicas changes": { +// getPublisher1: func() *appsv1.Deployment { +// replicas := int32(1) +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Replicas = &replicas +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// replicas := int32(2) +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Replicas = &replicas +// return p +// }, +// expectedResult: true, +// }, +// "should be equal if replicas are the same": { +// getPublisher1: func() *appsv1.Deployment { +// replicas := int32(2) +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Replicas = &replicas +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// replicas := int32(2) +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Replicas = &replicas +// return p +// }, +// expectedResult: true, +// }, +// "should be equal if spec annotations are nil and empty": { +// getPublisher1: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Annotations = nil +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Annotations = map[string]string{} +// return p +// }, +// expectedResult: true, +// }, +// "should be unequal if spec annotations changes": { +// getPublisher1: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Annotations = map[string]string{"key": "value1"} +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Annotations = map[string]string{"key": "value2"} +// return p +// }, +// expectedResult: false, +// }, +// "should be equal if spec Labels are nil and empty": { +// getPublisher1: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Labels = nil +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Labels = map[string]string{} +// return p +// }, +// expectedResult: true, +// }, +// "should be unequal if spec Labels changes": { +// getPublisher1: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Labels = map[string]string{"key": "value1"} +// return p +// }, +// getPublisher2: func() *appsv1.Deployment { +// p := defaultNATSPublisher.DeepCopy() +// p.Spec.Template.Labels = map[string]string{"key": "value2"} +// return p +// }, +// expectedResult: false, +// }, +// } +// for name, tc := range testCases { +// t.Run(name, func(t *testing.T) { +// if publisherProxyDeploymentEqual(tc.getPublisher1(), tc.getPublisher2()) != tc.expectedResult { +// t.Errorf("expected output to be %t", tc.expectedResult) +// } +// }) +// } +//} func Test_ownerReferencesDeepEqual(t *testing.T) { ownerReference := func(version, kind, name, uid string, controller, block *bool) metav1.OwnerReference { diff --git a/pkg/subscriptionmanager/eventmesh/eventmesh.go b/pkg/subscriptionmanager/eventmesh/eventmesh.go index 772bfc43..60243ded 100644 --- a/pkg/subscriptionmanager/eventmesh/eventmesh.go +++ b/pkg/subscriptionmanager/eventmesh/eventmesh.go @@ -6,12 +6,14 @@ import ( "strings" "time" + "github.com/kyma-project/eventing-manager/internal/controller/eventing/subscription/eventmesh" + "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" "github.com/kyma-project/eventing-manager/pkg/backend/metrics" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/pkg/errors" "go.uber.org/zap" @@ -25,7 +27,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/manager" - "github.com/kyma-project/eventing-manager/internal/controller/subscription/eventmesh" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" backendeventmesh "github.com/kyma-project/eventing-manager/pkg/backend/eventmesh" "github.com/kyma-project/eventing-manager/pkg/backend/eventtype" "github.com/kyma-project/eventing-manager/pkg/backend/sink" @@ -33,7 +35,6 @@ import ( "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/logger" subscriptionmanager "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager" - eventingv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" ) const ( diff --git a/pkg/subscriptionmanager/eventmesh/eventmesh_test.go b/pkg/subscriptionmanager/eventmesh/eventmesh_test.go index 259a9256..20590027 100644 --- a/pkg/subscriptionmanager/eventmesh/eventmesh_test.go +++ b/pkg/subscriptionmanager/eventmesh/eventmesh_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/require" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/cleaner" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" "k8s.io/client-go/dynamic" "sigs.k8s.io/controller-runtime/pkg/manager" diff --git a/pkg/subscriptionmanager/factory.go b/pkg/subscriptionmanager/factory.go index ba1db706..958988a1 100644 --- a/pkg/subscriptionmanager/factory.go +++ b/pkg/subscriptionmanager/factory.go @@ -6,7 +6,7 @@ import ( "github.com/kyma-project/eventing-manager/pkg/backend/metrics" "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/env" eclogger "github.com/kyma-project/eventing-manager/pkg/logger" "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/eventmesh" diff --git a/pkg/subscriptionmanager/jetstream/jetstream.go b/pkg/subscriptionmanager/jetstream/jetstream.go index 3ac015f1..878d63ca 100644 --- a/pkg/subscriptionmanager/jetstream/jetstream.go +++ b/pkg/subscriptionmanager/jetstream/jetstream.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + "github.com/kyma-project/eventing-manager/internal/controller/eventing/subscription/jetstream" + manager2 "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager" "github.com/kyma-project/eventing-manager/pkg/backend/sink" @@ -25,14 +27,13 @@ import ( "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/manager" - "github.com/kyma-project/eventing-manager/internal/controller/subscription/jetstream" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/backend/eventtype" backendjetstream "github.com/kyma-project/eventing-manager/pkg/backend/jetstream" backendmetrics "github.com/kyma-project/eventing-manager/pkg/backend/metrics" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/logger" - eventingv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) const ( diff --git a/pkg/subscriptionmanager/jetstream/jetstream_test.go b/pkg/subscriptionmanager/jetstream/jetstream_test.go index 0aaf6dc7..099a736a 100644 --- a/pkg/subscriptionmanager/jetstream/jetstream_test.go +++ b/pkg/subscriptionmanager/jetstream/jetstream_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" kymalogger "github.com/kyma-project/kyma/common/logging/logger" "github.com/nats-io/nats-server/v2/server" diff --git a/pkg/subscriptionmanager/mocks/ec/manager.go b/pkg/subscriptionmanager/mocks/ec/manager.go deleted file mode 100644 index 913f6b72..00000000 --- a/pkg/subscriptionmanager/mocks/ec/manager.go +++ /dev/null @@ -1,166 +0,0 @@ -// Code generated by mockery v2.30.16. DO NOT EDIT. - -package mocks - -import ( - env "github.com/kyma-project/kyma/components/eventing-controller/pkg/env" - manager "sigs.k8s.io/controller-runtime/pkg/manager" - - mock "github.com/stretchr/testify/mock" - - subscriptionmanager "github.com/kyma-project/kyma/components/eventing-controller/pkg/subscriptionmanager" -) - -// Manager is an autogenerated mock type for the Manager type -type Manager struct { - mock.Mock -} - -type Manager_Expecter struct { - mock *mock.Mock -} - -func (_m *Manager) EXPECT() *Manager_Expecter { - return &Manager_Expecter{mock: &_m.Mock} -} - -// Init provides a mock function with given fields: mgr -func (_m *Manager) Init(mgr manager.Manager) error { - ret := _m.Called(mgr) - - var r0 error - if rf, ok := ret.Get(0).(func(manager.Manager) error); ok { - r0 = rf(mgr) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Manager_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' -type Manager_Init_Call struct { - *mock.Call -} - -// Init is a helper method to define mock.On call -// - mgr manager.Manager -func (_e *Manager_Expecter) Init(mgr interface{}) *Manager_Init_Call { - return &Manager_Init_Call{Call: _e.mock.On("Init", mgr)} -} - -func (_c *Manager_Init_Call) Run(run func(mgr manager.Manager)) *Manager_Init_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(manager.Manager)) - }) - return _c -} - -func (_c *Manager_Init_Call) Return(_a0 error) *Manager_Init_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *Manager_Init_Call) RunAndReturn(run func(manager.Manager) error) *Manager_Init_Call { - _c.Call.Return(run) - return _c -} - -// Start provides a mock function with given fields: defaultSubsConfig, params -func (_m *Manager) Start(defaultSubsConfig env.DefaultSubscriptionConfig, params subscriptionmanager.Params) error { - ret := _m.Called(defaultSubsConfig, params) - - var r0 error - if rf, ok := ret.Get(0).(func(env.DefaultSubscriptionConfig, subscriptionmanager.Params) error); ok { - r0 = rf(defaultSubsConfig, params) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Manager_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' -type Manager_Start_Call struct { - *mock.Call -} - -// Start is a helper method to define mock.On call -// - defaultSubsConfig env.DefaultSubscriptionConfig -// - params subscriptionmanager.Params -func (_e *Manager_Expecter) Start(defaultSubsConfig interface{}, params interface{}) *Manager_Start_Call { - return &Manager_Start_Call{Call: _e.mock.On("Start", defaultSubsConfig, params)} -} - -func (_c *Manager_Start_Call) Run(run func(defaultSubsConfig env.DefaultSubscriptionConfig, params subscriptionmanager.Params)) *Manager_Start_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(env.DefaultSubscriptionConfig), args[1].(subscriptionmanager.Params)) - }) - return _c -} - -func (_c *Manager_Start_Call) Return(_a0 error) *Manager_Start_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *Manager_Start_Call) RunAndReturn(run func(env.DefaultSubscriptionConfig, subscriptionmanager.Params) error) *Manager_Start_Call { - _c.Call.Return(run) - return _c -} - -// Stop provides a mock function with given fields: runCleanup -func (_m *Manager) Stop(runCleanup bool) error { - ret := _m.Called(runCleanup) - - var r0 error - if rf, ok := ret.Get(0).(func(bool) error); ok { - r0 = rf(runCleanup) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Manager_Stop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Stop' -type Manager_Stop_Call struct { - *mock.Call -} - -// Stop is a helper method to define mock.On call -// - runCleanup bool -func (_e *Manager_Expecter) Stop(runCleanup interface{}) *Manager_Stop_Call { - return &Manager_Stop_Call{Call: _e.mock.On("Stop", runCleanup)} -} - -func (_c *Manager_Stop_Call) Run(run func(runCleanup bool)) *Manager_Stop_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(bool)) - }) - return _c -} - -func (_c *Manager_Stop_Call) Return(_a0 error) *Manager_Stop_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *Manager_Stop_Call) RunAndReturn(run func(bool) error) *Manager_Stop_Call { - _c.Call.Return(run) - return _c -} - -// NewManager creates a new instance of Manager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewManager(t interface { - mock.TestingT - Cleanup(func()) -}) *Manager { - mock := &Manager{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/subscriptionmanager/mocks/manager_factory.go b/pkg/subscriptionmanager/mocks/manager_factory.go index 4477f8e7..1eb0e996 100644 --- a/pkg/subscriptionmanager/mocks/manager_factory.go +++ b/pkg/subscriptionmanager/mocks/manager_factory.go @@ -7,7 +7,7 @@ import ( manager "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager" mock "github.com/stretchr/testify/mock" - v1alpha1 "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + v1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" ) // ManagerFactory is an autogenerated mock type for the ManagerFactory type diff --git a/test/matchers/matchers.go b/test/matchers/matchers.go index 67de9ec5..c9f46741 100644 --- a/test/matchers/matchers.go +++ b/test/matchers/matchers.go @@ -1,8 +1,8 @@ package matchers import ( - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" - "github.com/kyma-project/eventing-manager/internal/controller/operator.kyma-project.io/eventing" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" + "github.com/kyma-project/eventing-manager/internal/controller/operator/eventing" "github.com/onsi/gomega" "github.com/onsi/gomega/gstruct" gomegatypes "github.com/onsi/gomega/types" diff --git a/test/utils/integration/integration.go b/test/utils/integration/integration.go index a5b5ea31..58cc916c 100644 --- a/test/utils/integration/integration.go +++ b/test/utils/integration/integration.go @@ -11,7 +11,7 @@ import ( "testing" "time" - eventing2 "github.com/kyma-project/eventing-manager/internal/controller/operator.kyma-project.io/eventing" + eventing2 "github.com/kyma-project/eventing-manager/internal/controller/operator/eventing" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager" @@ -43,7 +43,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" natsv1alpha1 "github.com/kyma-project/nats-manager/api/v1alpha1" "github.com/kyma-project/nats-manager/testutils" admissionv1 "k8s.io/api/admissionregistration/v1" @@ -53,7 +53,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" "github.com/kyma-project/eventing-manager/options" "github.com/kyma-project/eventing-manager/pkg/env" "github.com/kyma-project/eventing-manager/pkg/eventing" diff --git a/test/utils/options.go b/test/utils/options.go index ea9cca2d..20478109 100644 --- a/test/utils/options.go +++ b/test/utils/options.go @@ -1,7 +1,7 @@ package utils import ( - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/test/utils/utils.go b/test/utils/utils.go index 7f70223a..849c9f44 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -11,7 +11,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" - eventinv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" + eventinv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -20,7 +20,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/kyma-project/eventing-manager/api/operator.kyma-project.io/v1alpha1" + "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/testing/matchers.go b/testing/matchers.go index e2224f15..85fd00d4 100644 --- a/testing/matchers.go +++ b/testing/matchers.go @@ -13,34 +13,11 @@ import ( "k8s.io/apimachinery/pkg/types" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/constants" "github.com/kyma-project/eventing-manager/pkg/object" - eventingv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" ) -// -// string matchers -// - -func HaveEventingBackendReady() gomegatypes.GomegaMatcher { - return WithTransform(func(s *eventingv1alpha1.EventingBackendStatus) bool { - return *s.EventingReady - }, BeTrue()) -} - -func HaveEventingBackendNotReady() gomegatypes.GomegaMatcher { - return WithTransform(func(s *eventingv1alpha1.EventingBackendStatus) bool { - return *s.EventingReady - }, BeFalse()) -} - -func HaveBackendType(backendType eventingv1alpha1.BackendType) gomegatypes.GomegaMatcher { - return WithTransform(func(s *eventingv1alpha1.EventingBackendStatus) eventingv1alpha1.BackendType { - return s.Backend - }, Equal(backendType)) -} - // // APIRule matchers // @@ -114,20 +91,6 @@ func HaveAPIRuleOwnersRefs(uids ...types.UID) gomegatypes.GomegaMatcher { }, Equal(uids)) } -// -// Subscription matchers -// - -func HaveBackendCondition(condition eventingv1alpha1.Condition) gomegatypes.GomegaMatcher { - return WithTransform(func(s *eventingv1alpha1.EventingBackendStatus) []eventingv1alpha1.Condition { - return s.Conditions - }, ContainElement(MatchFields(IgnoreExtras|IgnoreMissing, Fields{ - "Type": Equal(condition.Type), - "Reason": Equal(condition.Reason), - "Status": Equal(condition.Status), - }))) -} - // // int matchers // @@ -177,18 +140,6 @@ func HaveValidBEBNamespace(bebNamespaceKey, namespace string) gomegatypes.Gomega }, BeTrue()) } -func HaveNoBEBSecretNameAndNamespace() gomegatypes.GomegaMatcher { - return WithTransform(func(s *eventingv1alpha1.EventingBackendStatus) bool { - return s.BEBSecretName == "" && s.BEBSecretNamespace == "" - }, BeTrue()) -} - -func HaveBEBSecretNameAndNamespace(bebSecretName, namespace string) gomegatypes.GomegaMatcher { - return WithTransform(func(s *eventingv1alpha1.EventingBackendStatus) bool { - return s.BEBSecretName == bebSecretName && s.BEBSecretNamespace == namespace - }, BeTrue()) -} - func HaveSubscriptionName(name string) gomegatypes.GomegaMatcher { return WithTransform(func(s *eventingv1alpha2.Subscription) string { return s.Name }, Equal(name)) } diff --git a/testing/test_helpers.go b/testing/test_helpers.go index bc62c389..f44576a1 100644 --- a/testing/test_helpers.go +++ b/testing/test_helpers.go @@ -9,8 +9,8 @@ import ( "k8s.io/client-go/dynamic" dynamicfake "k8s.io/client-go/dynamic/fake" + eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" "github.com/kyma-project/eventing-manager/pkg/object" - eventingv1alpha2 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha2" apigatewayv1beta1 "github.com/kyma-incubator/api-gateway/api/v1beta1" corev1 "k8s.io/api/core/v1" @@ -19,9 +19,9 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + eventingv1alpha1 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha1" "github.com/kyma-project/eventing-manager/pkg/ems/api/events/types" "github.com/kyma-project/eventing-manager/pkg/utils" - eventingv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1" ) const ( @@ -257,17 +257,6 @@ func NewNamespace(name string) *corev1.Namespace { return &namespace } -func NewEventingBackend(name, namespace string) *eventingv1alpha1.EventingBackend { - return &eventingv1alpha1.EventingBackend{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: eventingv1alpha1.EventingBackendSpec{}, - Status: eventingv1alpha1.EventingBackendStatus{}, - } -} - func GetStructuredMessageHeaders() http.Header { return http.Header{"Content-Type": []string{"application/cloudevents+json"}} } From db3721d6b3ce7b8e5b52f845caba183c5b54e78d Mon Sep 17 00:00:00 2001 From: Muhammad Faizan Date: Mon, 20 Nov 2023 21:56:40 +0500 Subject: [PATCH 2/5] updated samples --- config/samples/kustomization.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 9f82fd03..cde2664d 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -3,6 +3,4 @@ namespace: eventing-manager resources: - default.yaml -- eventing.kyma-project.io_v1alpha1_subscription.yaml -- eventing.kyma-project.io_v1alpha2_subscription.yaml #+kubebuilder:scaffold:manifestskustomizesamples From 4ee34aecaa5af3cd0e15f696e2deaaf3fa73e5c6 Mon Sep 17 00:00:00 2001 From: Mansur Uralov Date: Tue, 21 Nov 2023 18:05:27 +0100 Subject: [PATCH 3/5] Fix failing tests --- test/utils/integration/integration.go | 1 - 1 file changed, 1 deletion(-) diff --git a/test/utils/integration/integration.go b/test/utils/integration/integration.go index 58cc916c..ed8c5135 100644 --- a/test/utils/integration/integration.go +++ b/test/utils/integration/integration.go @@ -299,7 +299,6 @@ func StartEnvTest(config TestEnvironmentConfig) (*envtest.Environment, *rest.Con // define CRDs to include. includedCRDs := []string{ filepath.Join(config.ProjectRootDir, "config", "crd", "bases"), - filepath.Join(config.ProjectRootDir, "config", "crd", "external"), } if config.ApplicationRuleCRDEnabled { includedCRDs = append(includedCRDs, From 752e1f48c9b7ec9050d65430fb5a6973e99f34fe Mon Sep 17 00:00:00 2001 From: Mansur Uralov Date: Thu, 23 Nov 2023 17:48:30 +0100 Subject: [PATCH 4/5] Delete external CRD folder --- .../controller/eventing/subscription/eventmesh/test/utils.go | 1 - .../eventing/subscription/eventmesh/testwebhookauth/utils.go | 1 - .../eventing/subscription/eventmesh/testwithory/utils.go | 1 - .../eventing/subscription/jetstream/test_utils_test.go | 1 - 4 files changed, 4 deletions(-) diff --git a/internal/controller/eventing/subscription/eventmesh/test/utils.go b/internal/controller/eventing/subscription/eventmesh/test/utils.go index fed93518..537aa814 100644 --- a/internal/controller/eventing/subscription/eventmesh/test/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/test/utils.go @@ -206,7 +206,6 @@ func startTestEnv() (*rest.Config, error) { emTestEnsemble.testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("../../../../../../", "config", "crd", "bases"), - filepath.Join("../../../../../../", "config", "crd", "external"), filepath.Join("../../../../../../", "config", "crd", "for-tests"), }, AttachControlPlaneOutput: attachControlPlaneOutput, diff --git a/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go index e9ecd42d..6f95ca53 100644 --- a/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go @@ -201,7 +201,6 @@ func startTestEnv() (*rest.Config, error) { emTestEnsemble.testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("../../../../../../", "config", "crd", "bases"), - filepath.Join("../../../../../../", "config", "crd", "external"), filepath.Join("../../../../../../", "config", "crd", "for-tests"), }, AttachControlPlaneOutput: attachControlPlaneOutput, diff --git a/internal/controller/eventing/subscription/eventmesh/testwithory/utils.go b/internal/controller/eventing/subscription/eventmesh/testwithory/utils.go index e1b84dbc..cce3adcb 100644 --- a/internal/controller/eventing/subscription/eventmesh/testwithory/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/testwithory/utils.go @@ -205,7 +205,6 @@ func startTestEnv() (*rest.Config, error) { emTestEnsemble.testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("../../../../../../", "config", "crd", "bases"), - filepath.Join("../../../../../../", "config", "crd", "external"), filepath.Join("../../../../../../", "config", "crd", "for-tests"), }, AttachControlPlaneOutput: attachControlPlaneOutput, diff --git a/internal/controller/eventing/subscription/jetstream/test_utils_test.go b/internal/controller/eventing/subscription/jetstream/test_utils_test.go index a8a4e429..5fd626b7 100644 --- a/internal/controller/eventing/subscription/jetstream/test_utils_test.go +++ b/internal/controller/eventing/subscription/jetstream/test_utils_test.go @@ -114,7 +114,6 @@ func setupSuite() error { TestEnv: &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("../../../../../", "config", "crd", "bases"), - filepath.Join("../../../../../", "config", "crd", "external"), }, AttachControlPlaneOutput: attachControlPlaneOutput, UseExistingCluster: &useExistingCluster, From e93404a0ad600af4d3a972af38c2952965047d87 Mon Sep 17 00:00:00 2001 From: Mansur Uralov Date: Fri, 24 Nov 2023 15:04:04 +0100 Subject: [PATCH 5/5] Revert 02-configuration.md doc --- docs/user/02-configuration.md | 79 +++++++++++++++++------------------ 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/docs/user/02-configuration.md b/docs/user/02-configuration.md index a3303cd1..65a72b6d 100644 --- a/docs/user/02-configuration.md +++ b/docs/user/02-configuration.md @@ -28,49 +28,46 @@ Use the following sample CRs as guidance. Each can be applied immediately when y **Spec:** -| Parameter | Type | Description | -| ---- | ----------- | ---- | -| **annotations** | map\[string\]string | Annotations allows to add annotations to resources. | -| **backend** (required) | object | Backend defines the active backend used by Eventing. | -| **backend.​config** | object | Config defines configuration for eventing backend. | -| **backend.​config.​domain** | string | Domain defines the cluster public domain used to configure the EventMesh Subscriptions and their corresponding ApiRules. | -| **backend.​config.​eventMeshSecret** | string | EventMeshSecret defines the namespaced name of K8s Secret containing EventMesh credentials. The format of name is "namespace/name". | -| **backend.​config.​eventTypePrefix** | string | | -| **backend.​config.​natsMaxMsgsPerTopic** | integer | NATSMaxMsgsPerTopic limits how many messages in the NATS stream to retain per subject. | -| **backend.​config.​natsStreamMaxSize** | \{integer or string\} | NATSStreamMaxSize defines the maximum storage size for stream data. | -| **backend.​config.​natsStreamReplicas** | integer | NATSStreamReplicas defines the number of replicas for stream. | -| **backend.​config.​natsStreamStorageType** | string | NATSStreamStorageType defines the storage type for stream data. | -| **backend.​type** (required) | string | Type defines which backend to use. The value is either `EventMesh`, or `NATS`. | -| **labels** | map\[string\]string | Labels allows to add Labels to resources. | -| **logging** | object | Logging defines the log level for eventing-manager. | -| **logging.​logLevel** | string | LogLevel defines the log level. | -| **publisher** | object | Publisher defines the configurations for eventing-publisher-proxy. | -| **publisher.​replicas** | object | Replicas defines the scaling min/max for eventing-publisher-proxy. | -| **publisher.​replicas.​max** | integer | Max defines maximum number of replicas. | -| **publisher.​replicas.​min** | integer | Min defines minimum number of replicas. | -| **publisher.​resources** | object | Resources defines resources for eventing-publisher-proxy. | -| **publisher.​resources.​claims** | \[\]object | Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. - This field is immutable. It can only be set for containers. | -| **publisher.​resources.​claims.​name** (required) | string | Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. | -| **publisher.​resources.​limits** | map\[string\]\{integer or string\} | Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | +| Parameter | Type | Description | +|----------------------------------------------------------|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **annotations** | map\[string\]string | Annotations allows to add annotations to resources. | +| **backend** (required) | object | Backend defines the active backend used by Eventing. | +| **backend.​config** | object | Config defines configuration for eventing backend. | +| **backend.​config.​domain** | string | Domain defines the cluster public domain used to configure the EventMesh Subscriptions and their corresponding ApiRules. | +| **backend.​config.​eventMeshSecret** | string | EventMeshSecret defines the namespaced name of K8s Secret containing EventMesh credentials. The format of name is "namespace/name". | +| **backend.​config.​eventTypePrefix** | string | | +| **backend.​config.​natsMaxMsgsPerTopic** | integer | NATSMaxMsgsPerTopic limits how many messages in the NATS stream to retain per subject. | +| **backend.​config.​natsStreamMaxSize** | \{integer or string\} | NATSStreamMaxSize defines the maximum storage size for stream data. | +| **backend.​config.​natsStreamReplicas** | integer | NATSStreamReplicas defines the number of replicas for stream. | +| **backend.​config.​natsStreamStorageType** | string | NATSStreamStorageType defines the storage type for stream data. | +| **backend.​type** (required) | string | Type defines which backend to use. The value is either `EventMesh`, or `NATS`. | +| **labels** | map\[string\]string | Labels allows to add Labels to resources. | +| **logging** | object | Logging defines the log level for eventing-manager. | +| **logging.​logLevel** | string | LogLevel defines the log level. | +| **publisher** | object | Publisher defines the configurations for eventing-publisher-proxy. | +| **publisher.​replicas** | object | Replicas defines the scaling min/max for eventing-publisher-proxy. | +| **publisher.​replicas.​max** | integer | Max defines maximum number of replicas. | +| **publisher.​replicas.​min** | integer | Min defines minimum number of replicas. | +| **publisher.​resources** | object | Resources defines resources for eventing-publisher-proxy. | +| **publisher.​resources.​claims** | \[\]object | Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. | +| **publisher.​resources.​claims.​name** (required) | string | Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. | +| **publisher.​resources.​limits** | map\[string\]\{integer or string\} | Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | **publisher.​resources.​requests** | map\[string\]\{integer or string\} | Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | **Status:** -| Parameter | Type | Description | -| ---- | ----------- | ---- | -| **activeBackend** (required) | string | | -| **conditions** | \[\]object | Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` - // other fields } | -| **conditions.​lastTransitionTime** (required) | string | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. | -| **conditions.​message** (required) | string | message is a human readable message indicating details about the transition. This may be an empty string. | -| **conditions.​observedGeneration** | integer | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. | -| **conditions.​reason** (required) | string | reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. | -| **conditions.​status** (required) | string | status of the condition, one of True, False, Unknown. | -| **conditions.​type** (required) | string | type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) | -| **specHash** (required) | integer | | -| **state** (required) | string | | +| Parameter | Type | Description | +|------------------------------------------------------|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **activeBackend** (required) | string | | +| **conditions** | \[\]object | Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` | +| // other fields } | | | +| **conditions.​lastTransitionTime** (required) | string | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. | +| **conditions.​message** (required) | string | message is a human readable message indicating details about the transition. This may be an empty string. | +| **conditions.​observedGeneration** | integer | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. | +| **conditions.​reason** (required) | string | reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. | +| **conditions.​status** (required) | string | status of the condition, one of `True`, `False`, `Unknown`. | +| **conditions.​type** (required) | string | type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) | +| **specHash** (required) | integer | | +| **state** (required) | string | | - + \ No newline at end of file