From f7a57b518f26cdd1817fd79dc200ab0bbe1bd58e Mon Sep 17 00:00:00 2001 From: m00g3n Date: Wed, 9 Aug 2023 16:38:44 +0200 Subject: [PATCH 1/3] fix caching --- .../.gitignore | 4 + .../Makefile | 29 +++ ...centralapplicationconnectivityvalidator.go | 13 +- .../options.go | 53 ++--- .../options_test.go | 5 +- .../go.mod | 15 +- .../go.sum | 19 +- ...applications.applicationconnector.crd.yaml | 183 ++++++++++++++++++ .../controller/cache_sync_controller_test.go | 102 ++++++++++ .../internal/controller/cachesync.go | 12 +- .../controller/cachesynccontroller.go | 9 +- .../controller/controller_suite_test.go | 13 ++ .../internal/controller/suite_test.go | 161 +++++++++++++++ .../internal/validationproxy/handler.go | 20 +- .../templates/deployment.yaml | 2 - .../values.yaml | 2 +- resources/application-connector/values.yaml | 2 +- 17 files changed, 585 insertions(+), 59 deletions(-) create mode 100644 components/central-application-connectivity-validator/hack/applications.applicationconnector.crd.yaml create mode 100644 components/central-application-connectivity-validator/internal/controller/cache_sync_controller_test.go create mode 100644 components/central-application-connectivity-validator/internal/controller/controller_suite_test.go create mode 100644 components/central-application-connectivity-validator/internal/controller/suite_test.go diff --git a/components/central-application-connectivity-validator/.gitignore b/components/central-application-connectivity-validator/.gitignore index d78ef924b553..2cb965c5e69b 100644 --- a/components/central-application-connectivity-validator/.gitignore +++ b/components/central-application-connectivity-validator/.gitignore @@ -7,6 +7,10 @@ # Binaries /centralapplicationconnectivityvalidator +bin + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out # Software licenses /licenses diff --git a/components/central-application-connectivity-validator/Makefile b/components/central-application-connectivity-validator/Makefile index c8c1c8c2b13b..2a06e2eed860 100644 --- a/components/central-application-connectivity-validator/Makefile +++ b/components/central-application-connectivity-validator/Makefile @@ -2,6 +2,9 @@ APP_NAME = central-application-connectivity-validator APP_PATH = components/$(APP_NAME) SCRIPTS_DIR = $(realpath $(shell pwd)/../..)/common/makefiles +# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. +ENVTEST_K8S_VERSION = 1.25.0 + override ENTRYPOINT = cmd/centralapplicationconnectivityvalidator/ include $(SCRIPTS_DIR)/generic-make-go.mk @@ -14,3 +17,29 @@ release: .PHONY: path-to-referenced-charts path-to-referenced-charts: @echo "resources/application-connector" + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +COVERPROFILE ?= cover.out + +.PHONY: fmt +fmt: ## Run go fmt against code. + go fmt ./... + +.PHONY: vet +vet: ## Run go vet against code. + go vet ./... + +ENVTEST ?= $(LOCALBIN)/setup-envtest + +.PHONY: envtest +envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. +$(ENVTEST): $(LOCALBIN) + test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + +.PHONY: test +test: fmt vet envtest ## Run tests. + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile $(COVERPROFILE) diff --git a/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/centralapplicationconnectivityvalidator.go b/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/centralapplicationconnectivityvalidator.go index a337d40173ab..2c8419d0c77b 100644 --- a/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/centralapplicationconnectivityvalidator.go +++ b/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/centralapplicationconnectivityvalidator.go @@ -87,8 +87,8 @@ func main() { log.WithContext().With("options", options).Info("Starting Validation Proxy.") idCache := cache.New( - time.Duration(options.cacheExpirationSeconds)*time.Second, - time.Duration(options.cacheCleanupIntervalSeconds)*time.Second, + cache.NoExpiration, + cache.NoExpiration, ) idCache.OnEvicted(func(key string, i interface{}) { log.WithContext(). @@ -127,7 +127,14 @@ func main() { log.WithContext().Error("Unable to start manager: %s", err.Error()) os.Exit(1) } - if err = controller.NewController(log, mgr.GetClient(), idCache, options.appNamePlaceholder, options.eventingPathPrefixV1, options.eventingPathPrefixV2, options.eventingPathPrefixEvents).SetupWithManager(mgr); err != nil { + if err = controller.NewController( + log, + mgr.GetClient(), + idCache, + options.appNamePlaceholder, + options.eventingPathPrefixV1, + options.eventingPathPrefixV2, + options.eventingPathPrefixEvents).SetupWithManager(mgr); err != nil { log.WithContext().Error("Unable to create reconciler: %s", err.Error()) os.Exit(1) } diff --git a/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/options.go b/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/options.go index d54d9ab8faf4..c7346586601b 100644 --- a/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/options.go +++ b/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/options.go @@ -3,27 +3,23 @@ package main import ( "flag" "fmt" + "github.com/vrischmann/envconfig" + "k8s.io/client-go/tools/clientcmd" "os" "strings" "time" - - "k8s.io/client-go/tools/clientcmd" - - "github.com/vrischmann/envconfig" ) type args struct { - proxyPort int - externalAPIPort int - eventingPathPrefixV1 string - eventingPathPrefixV2 string - eventingPublisherHost string - eventingPathPrefixEvents string - eventingDestinationPath string - appNamePlaceholder string - cacheExpirationSeconds int - cacheCleanupIntervalSeconds int - syncPeriod time.Duration + proxyPort int + externalAPIPort int + eventingPathPrefixV1 string + eventingPathPrefixV2 string + eventingPublisherHost string + eventingPathPrefixEvents string + eventingDestinationPath string + appNamePlaceholder string + syncPeriod time.Duration } type config struct { @@ -45,8 +41,6 @@ func parseOptions() (*options, error) { eventingDestinationPath := flag.String("eventingDestinationPath", "/publish", "Path of the destination of the requests to the Eventing") eventingPathPrefixEvents := flag.String("eventingPathPrefixEvents", "/events", "Prefix of paths that is directed to the Cloud Events based Eventing") appNamePlaceholder := flag.String("appNamePlaceholder", "%%APP_NAME%%", "Path URL placeholder used for an application name") - cacheExpirationSeconds := flag.Int("cacheExpirationSeconds", 90, "Expiration time for client IDs stored in cache expressed in seconds") - cacheCleanupIntervalSeconds := flag.Int("cacheCleanupIntervalSeconds", 20, "Clean up interval controls how often the client IDs stored in cache are removed") syncPeriod := flag.Duration("syncPeriod", 45*time.Second, "Sync period in seconds how often controller should periodically reconcile Application resource.") flag.Parse() @@ -58,17 +52,15 @@ func parseOptions() (*options, error) { return &options{ args: args{ - proxyPort: *proxyPort, - externalAPIPort: *externalAPIPort, - eventingPathPrefixV1: *eventingPathPrefixV1, - eventingPathPrefixV2: *eventingPathPrefixV2, - eventingPublisherHost: *eventingPublisherHost, - eventingPathPrefixEvents: *eventingPathPrefixEvents, - eventingDestinationPath: *eventingDestinationPath, - appNamePlaceholder: *appNamePlaceholder, - cacheExpirationSeconds: *cacheExpirationSeconds, - cacheCleanupIntervalSeconds: *cacheCleanupIntervalSeconds, - syncPeriod: *syncPeriod, + proxyPort: *proxyPort, + externalAPIPort: *externalAPIPort, + eventingPathPrefixV1: *eventingPathPrefixV1, + eventingPathPrefixV2: *eventingPathPrefixV2, + eventingPublisherHost: *eventingPublisherHost, + eventingPathPrefixEvents: *eventingPathPrefixEvents, + eventingDestinationPath: *eventingDestinationPath, + appNamePlaceholder: *appNamePlaceholder, + syncPeriod: *syncPeriod, }, config: c, }, nil @@ -80,13 +72,11 @@ func (o *options) String() string { "--eventingPathPrefixEvents=%s --eventingPublisherHost=%s "+ "--eventingDestinationPath=%s "+ "--appNamePlaceholder=%s "+ - "--cacheExpirationSeconds=%d --cacheCleanupIntervalSeconds=%d "+ "--syncPeriod=%d APP_LOG_FORMAT=%s APP_LOG_LEVEL=%s KUBECONFIG=%s", o.proxyPort, o.externalAPIPort, o.eventingPathPrefixV1, o.eventingPathPrefixV2, o.eventingPathPrefixEvents, o.eventingPublisherHost, o.eventingDestinationPath, o.appNamePlaceholder, - o.cacheExpirationSeconds, o.cacheCleanupIntervalSeconds, o.syncPeriod, o.LogFormat, o.LogLevel, os.Getenv(clientcmd.RecommendedConfigPathEnvVar)) } @@ -103,8 +93,5 @@ func (o *options) validate() error { if !strings.Contains(o.eventingPathPrefixEvents, o.appNamePlaceholder) { return fmt.Errorf("eventingPathPrefixEvents '%s' should contain appNamePlaceholder '%s'", o.eventingPathPrefixEvents, o.appNamePlaceholder) } - if o.syncPeriod > time.Duration(o.cacheExpirationSeconds)*time.Second { - return fmt.Errorf("syncPeriod '%v' greater than cacheExpirationSeconds '%v' will cause unwanted cache eviction", o.syncPeriod, o.cacheExpirationSeconds) - } return nil } diff --git a/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/options_test.go b/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/options_test.go index 713b9b4403ad..a57eaaa1283b 100644 --- a/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/options_test.go +++ b/components/central-application-connectivity-validator/cmd/centralapplicationconnectivityvalidator/options_test.go @@ -64,14 +64,13 @@ func TestOptionsValidation(t *testing.T) { }, }, { - name: "syncPeriod greater than cacheExpirationSeconds", - valid: false, + name: "syncPeriod is set", + valid: true, args: args{ appNamePlaceholder: "%%APP_NAME%%", eventingPathPrefixV1: "/%%APP_NAME%%/v1/events", eventingPathPrefixV2: "/%%APP_NAME%%/v2/events", eventingPathPrefixEvents: "/%%APP_NAME%%/events", - cacheExpirationSeconds: 120, syncPeriod: 121 * time.Second, }, }, diff --git a/components/central-application-connectivity-validator/go.mod b/components/central-application-connectivity-validator/go.mod index 3dd6282f45a2..cebfd0ebf8c0 100644 --- a/components/central-application-connectivity-validator/go.mod +++ b/components/central-application-connectivity-validator/go.mod @@ -7,10 +7,13 @@ require ( github.com/kyma-project/kyma/common/logging v0.0.0-20230130154909-4c81ab2cee61 github.com/kyma-project/kyma/components/central-application-gateway v0.0.0-20230130154909-4c81ab2cee61 github.com/oklog/run v1.1.0 + github.com/onsi/ginkgo/v2 v2.11.0 + github.com/onsi/gomega v1.27.8 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/stretchr/testify v1.8.4 github.com/vrischmann/envconfig v1.3.0 go.uber.org/zap v1.24.0 + k8s.io/api v0.26.7 k8s.io/apimachinery v0.27.4 k8s.io/client-go v0.26.7 sigs.k8s.io/controller-runtime v0.14.6 @@ -24,17 +27,19 @@ require ( github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/zapr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.1.0 // indirect + github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect github.com/google/uuid v1.3.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -54,19 +59,19 @@ require ( github.com/spf13/pflag v1.0.5 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - golang.org/x/net v0.8.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/sys v0.6.0 // indirect + golang.org/x/sys v0.9.0 // indirect golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.9.3 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.26.7 // indirect k8s.io/apiextensions-apiserver v0.26.1 // indirect k8s.io/component-base v0.26.1 // indirect k8s.io/klog/v2 v2.90.1 // indirect diff --git a/components/central-application-connectivity-validator/go.sum b/components/central-application-connectivity-validator/go.sum index 63142de1713b..971c29aaa198 100644 --- a/components/central-application-connectivity-validator/go.sum +++ b/components/central-application-connectivity-validator/go.sum @@ -85,8 +85,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= @@ -96,7 +96,8 @@ github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -159,6 +160,7 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -169,6 +171,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -220,8 +223,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= -github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -333,6 +338,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -409,7 +415,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= +golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/components/central-application-connectivity-validator/hack/applications.applicationconnector.crd.yaml b/components/central-application-connectivity-validator/hack/applications.applicationconnector.crd.yaml new file mode 100644 index 000000000000..1a7b6518af71 --- /dev/null +++ b/components/central-application-connectivity-validator/hack/applications.applicationconnector.crd.yaml @@ -0,0 +1,183 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + name: applications.applicationconnector.kyma-project.io +spec: + group: applicationconnector.kyma-project.io + preserveUnknownFields: false + versions: + - name: v1alpha1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + properties: + compassMetadata: + type: object + required: + - "authentication" + properties: + applicationId: + type: string + authentication: + type: object + required: + - "clientIds" + properties: + clientIds: + type: array + items: + type: string + accessLabel: + type: string + maxLength: 63 + pattern: '^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$' + description: + type: string + skipInstallation: + type: boolean + skipVerify: + type: boolean + encodeUrl: + type: boolean + default: true + labels: + nullable: true + additionalProperties: + type: string + type: object + tenant: + type: string + group: + type: string + tags: + nullable: true + description: New fields used by V2 version + items: + type: string + type: array + displayName: + type: string + providerDisplayName: + type: string + longDescription: + type: string + services: + type: array + items: + type: object + required: + - "id" + - "name" + - "displayName" + - "providerDisplayName" + - "description" + - "entries" + properties: + id: + type: string + name: + type: string + identifier: + type: string + labels: + nullable: true + additionalProperties: + type: string + description: Deprecated + type: object + displayName: + type: string + description: + type: string + longDescription: + type: string + providerDisplayName: + type: string + authCreateParameterSchema: + description: New fields used by V2 version + type: string + entries: + type: array + items: + type: object + required: + - "type" + properties: + apiType: + type: string + type: + type: string + enum: + - "API" + - "Events" + gatewayUrl: + type: string + centralGatewayUrl: + type: string + accessLabel: + type: string + maxLength: 63 + pattern: '^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$' + targetUrl: + type: string + id: + type: string + name: + description: New fields used by V2 version + type: string + requestParametersSecretName: + type: string + specificationUrl: + type: string + credentials: + type: object + required: + - "type" + - "secretName" + properties: + type: + type: string + secretName: + type: string + authenticationUrl: + type: string + csrfInfo: + type: object + required: + - "tokenEndpointURL" + properties: + tokenEndpointURL: + type: string + tags: + type: array + items: + type: string + type: object + status: + properties: + installationStatus: + description: Represents the status of Application release installation + properties: + description: + type: string + status: + type: string + required: + - status + type: object + required: + - installationStatus + type: object + scope: Cluster + names: + plural: applications + singular: application + kind: Application + shortNames: + - app diff --git a/components/central-application-connectivity-validator/internal/controller/cache_sync_controller_test.go b/components/central-application-connectivity-validator/internal/controller/cache_sync_controller_test.go new file mode 100644 index 000000000000..d253013bc93e --- /dev/null +++ b/components/central-application-connectivity-validator/internal/controller/cache_sync_controller_test.go @@ -0,0 +1,102 @@ +package controller_test + +import ( + "fmt" + "net/http" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "context" + "time" + + "github.com/kyma-project/kyma/components/central-application-gateway/pkg/apis/applicationconnector/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type testResult struct { + err error + statusCode int +} + +var _ = Describe("Cache synchronization controller", func() { + Context("When controller is running", func() { + + appCount := 1000 + + It("should not fail with cache miss", func() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) + defer cancel() + + for i := 0; i < appCount; i++ { + testApplication := fmt.Sprintf("ta%d", i) + app := application(testApplication) + Expect(k8sClient.Create(ctx, &app)).To(BeNil()) + + Eventually(func() bool { + _, found := idCache.Get(testApplication) + return found + }, 5*time.Second).Should(BeTrue()) + } + + counter := 0 + client := http.Client{} + + Consistently(func() testResult { + if counter == appCount { + counter = 0 + } + ta := fmt.Sprintf("ta%d", counter) + URL := fmt.Sprintf("http://localhost:%s/%s/v2/events", testProxyServerPort, ta) + req, err := http.NewRequest(http.MethodGet, URL, nil) + Expect(err).Should(BeNil()) + + req.Header.Add("X-Forwarded-Client-Cert", fmt.Sprintf(`Subject="CN=%s"`, ta)) + + resp, err := client.Do(req) + counter++ + return testResult{ + err: err, + statusCode: resp.StatusCode, + } + }, time.Second*10, time.Millisecond*25).Should(Equal(testResult{ + statusCode: http.StatusOK, + })) + }) + + It("should delete application cache when cr is deleted", func() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) + defer cancel() + + appName := "deleteme" + app := application(appName) + Expect(k8sClient.Create(ctx, &app)).To(BeNil()) + + Eventually(func() bool { + _, found := idCache.Get(appName) + return found + }).Should(BeTrue()) + + Expect(k8sClient.Delete(ctx, &app)).Should(BeNil()) + + Eventually(func() bool { + _, found := idCache.Get(appName) + return found + }).Should(BeFalse()) + }) + + }) +}) + +func application(name string) v1alpha1.Application { + return v1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "applicationconnector.kyma-project.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1alpha1.ApplicationSpec{}, + } +} diff --git a/components/central-application-connectivity-validator/internal/controller/cachesync.go b/components/central-application-connectivity-validator/internal/controller/cachesync.go index c2154cd1d0dd..6196b937a770 100644 --- a/components/central-application-connectivity-validator/internal/controller/cachesync.go +++ b/components/central-application-connectivity-validator/internal/controller/cachesync.go @@ -34,7 +34,15 @@ type CachedAppData struct { AppPathPrefixEvents string } -func NewCacheSync(log *logger.Logger, client client.Reader, appCache *gocache.Cache, controllerName, appNamePlaceholder, eventingPathPrefixV1, eventingPathPrefixV2, eventingPathPrefixEvents string) CacheSync { +func NewCacheSync( + log *logger.Logger, + client client.Reader, + appCache *gocache.Cache, + controllerName, + appNamePlaceholder, + eventingPathPrefixV1, + eventingPathPrefixV2, + eventingPathPrefixEvents string) CacheSync { return &cacheSync{ client: client, appCache: appCache, @@ -91,7 +99,7 @@ func (c *cacheSync) Sync(ctx context.Context, applicationName string) error { func (c *cacheSync) syncApplication(application *v1alpha1.Application) { key := application.Name - if !application.ObjectMeta.DeletionTimestamp.IsZero() { + if !application.DeletionTimestamp.IsZero() { c.appCache.Delete(key) c.log.WithContext(). With("controller", c.controllerName). diff --git a/components/central-application-connectivity-validator/internal/controller/cachesynccontroller.go b/components/central-application-connectivity-validator/internal/controller/cachesynccontroller.go index fee8ed42e403..0ea01f09d7c4 100644 --- a/components/central-application-connectivity-validator/internal/controller/cachesynccontroller.go +++ b/components/central-application-connectivity-validator/internal/controller/cachesynccontroller.go @@ -20,7 +20,14 @@ type controller struct { cacheSync CacheSync } -func NewController(log *logger.Logger, client client.Client, appCache *gocache.Cache, appNamePlaceholder, eventingPathPrefixV1, eventingPathPrefixV2, eventingPathPrefixEvents string) Controller { +func NewController( + log *logger.Logger, + client client.Client, + appCache *gocache.Cache, + appNamePlaceholder, + eventingPathPrefixV1, + eventingPathPrefixV2, + eventingPathPrefixEvents string) Controller { return &controller{ cacheSync: NewCacheSync(log, client, appCache, "cache_sync_controller", appNamePlaceholder, eventingPathPrefixV1, eventingPathPrefixV2, eventingPathPrefixEvents), } diff --git a/components/central-application-connectivity-validator/internal/controller/controller_suite_test.go b/components/central-application-connectivity-validator/internal/controller/controller_suite_test.go new file mode 100644 index 000000000000..ff9b1c1a965c --- /dev/null +++ b/components/central-application-connectivity-validator/internal/controller/controller_suite_test.go @@ -0,0 +1,13 @@ +package controller_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestController(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Controller Suite") +} diff --git a/components/central-application-connectivity-validator/internal/controller/suite_test.go b/components/central-application-connectivity-validator/internal/controller/suite_test.go new file mode 100644 index 000000000000..23f78afea59a --- /dev/null +++ b/components/central-application-connectivity-validator/internal/controller/suite_test.go @@ -0,0 +1,161 @@ +package controller_test + +import ( + "fmt" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "context" + "io" + "net" + "net/http" + "path/filepath" + "strings" + + "github.com/kyma-project/kyma/common/logging/logger" + "github.com/kyma-project/kyma/common/logging/tracing" + "github.com/kyma-project/kyma/components/central-application-connectivity-validator/internal/controller" + "github.com/kyma-project/kyma/components/central-application-connectivity-validator/internal/validationproxy" + "github.com/kyma-project/kyma/components/central-application-gateway/pkg/apis/applicationconnector/v1alpha1" + "github.com/patrickmn/go-cache" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/utils/pointer" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +var ( + testEnv *envtest.Environment + config *rest.Config + k8sClient client.Client + suiteCtx context.Context + cancelSuiteCtx context.CancelFunc + + idCache *cache.Cache + appNamePlaceholder = "%%APP_NAME%%" + eventingPathPrefixV1 = "/%%APP_NAME%%/v1/events" + eventingPathPrefixV2 = "/%%APP_NAME%%/v2/events" + eventingPathPrefix = "/%%APP_NAME%%/events" + eventingPublisherHost = "eventing-event-publisher-proxy.kyma-system" + eventingDestinationPath = "/publish" + testProxyServerPort = "8078" +) + +type testTransport struct { +} + +func (t testTransport) RoundTrip(req *http.Request) (*http.Response, error) { + responseBody := "eventing-event-publisher-proxy.kyma-system: [OK]" + respReader := io.NopCloser(strings.NewReader(responseBody)) + resp := http.Response{ + StatusCode: http.StatusOK, + Body: respReader, + ContentLength: int64(len(responseBody)), + Header: map[string][]string{ + "Content-Type": {"text/plain"}, + }, + } + return &resp, nil +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + suiteCtx, cancelSuiteCtx = context.WithCancel(context.Background()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "hack")}, + ErrorIfCRDPathMissing: true, + } + + var err error + // config is defined in this file globally. + config, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(config).NotTo(BeNil()) + + err = v1alpha1.AddToScheme(scheme.Scheme) + Expect(err).To(BeNil()) + + k8sClient, err = client.New(config, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + k8sManager, err := ctrl.NewManager(config, ctrl.Options{ + Scheme: scheme.Scheme, + SyncPeriod: pointer.Duration(time.Second * 2), + }) + Expect(err).ToNot(HaveOccurred()) + + idCache = cache.New( + cache.NoExpiration, + cache.NoExpiration, + ) + + log, err := logger.New(logger.TEXT, logger.DEBUG) + Expect(err).Should(BeNil()) + + controller := controller.NewController( + log, + k8sClient, + idCache, + appNamePlaceholder, + eventingPathPrefixV1, + eventingPathPrefixV2, + eventingPathPrefix, + ) + err = controller.SetupWithManager(k8sManager) + Expect(err).To(BeNil()) + + ceProxyTransport := &testTransport{} + + proxyHandler := validationproxy.NewProxyHandler( + eventingPublisherHost, + eventingDestinationPath, + idCache, + log, + validationproxy.WithCEProxyTransport(ceProxyTransport)) + + tracingMiddleware := tracing.NewTracingMiddleware(proxyHandler.ProxyAppConnectorRequests) + + go func() { + defer GinkgoRecover() + + srv := http.Server{ + Handler: validationproxy.NewHandler(tracingMiddleware), + Addr: fmt.Sprintf(":%s", testProxyServerPort), + } + + defer func() { + if err := srv.Shutdown(suiteCtx); err != nil { + logf.Log.Error(err, "while shutting down http server") + } + }() + + ln, err := net.Listen("tcp", srv.Addr) + Expect(err).Should(BeNil()) + + err = srv.Serve(ln) + Expect(err).Should(BeNil()) + }() + + go func() { + err = k8sManager.Start(suiteCtx) + Expect(err).ToNot(HaveOccurred(), "failed to run manager") + }() +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + cancelSuiteCtx() + + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/components/central-application-connectivity-validator/internal/validationproxy/handler.go b/components/central-application-connectivity-validator/internal/validationproxy/handler.go index 486fe6338a81..9db5b214e204 100644 --- a/components/central-application-connectivity-validator/internal/validationproxy/handler.go +++ b/components/central-application-connectivity-validator/internal/validationproxy/handler.go @@ -43,12 +43,22 @@ type proxyHandler struct { cache Cache } +type option func(*proxyHandler) + +func WithCEProxyTransport(t http.RoundTripper) func(*proxyHandler) { + return func(p *proxyHandler) { + p.cloudEventsProxy.Transport = t + } +} + func NewProxyHandler( eventingPublisherHost string, eventingDestinationPath string, cache Cache, - log *logger.Logger) *proxyHandler { - return &proxyHandler{ + log *logger.Logger, + ops ...option) ProxyHandler { + + out := proxyHandler{ eventingPublisherHost: eventingPublisherHost, legacyEventsProxy: createReverseProxy(log, eventingPublisherHost, withEmptyRequestHost, withEmptyXFwdClientCert, withHTTPScheme), @@ -58,6 +68,12 @@ func NewProxyHandler( log: log, subjectRegex: regexp.MustCompile(`Subject="(.*?)"`), } + + for _, f := range ops { + f(&out) + } + + return &out } func (ph *proxyHandler) ProxyAppConnectorRequests(w http.ResponseWriter, r *http.Request) { diff --git a/resources/application-connector/charts/central-application-connectivity-validator/templates/deployment.yaml b/resources/application-connector/charts/central-application-connectivity-validator/templates/deployment.yaml index cf79c624b6b3..3025349267be 100644 --- a/resources/application-connector/charts/central-application-connectivity-validator/templates/deployment.yaml +++ b/resources/application-connector/charts/central-application-connectivity-validator/templates/deployment.yaml @@ -42,8 +42,6 @@ spec: - "--eventingDestinationPath=/{{ .Values.eventPublisherProxy.publishCEEndpoint }}" - "--eventingPathPrefixEvents=/%%APP_NAME%%/events" - "--appNamePlaceholder=%%APP_NAME%%" - - "--cacheExpirationSeconds={{ .Values.deployment.args.cacheExpirationSeconds }}" - - "--cacheCleanupIntervalSeconds={{ .Values.deployment.args.cacheCleanupIntervalSeconds }}" env: - name: APP_LOG_FORMAT value: {{ .Values.global.log.format | quote }} diff --git a/resources/application-connector/charts/central-application-connectivity-validator/values.yaml b/resources/application-connector/charts/central-application-connectivity-validator/values.yaml index 009904b4bce3..3294187b51b2 100644 --- a/resources/application-connector/charts/central-application-connectivity-validator/values.yaml +++ b/resources/application-connector/charts/central-application-connectivity-validator/values.yaml @@ -37,4 +37,4 @@ istio: gateway: name: kyma-gateway nameMtls: kyma-gateway-application-connector - namespace: kyma-system \ No newline at end of file + namespace: kyma-system diff --git a/resources/application-connector/values.yaml b/resources/application-connector/values.yaml index 87455499a125..18c86e556369 100644 --- a/resources/application-connector/values.yaml +++ b/resources/application-connector/values.yaml @@ -31,7 +31,7 @@ global: images: central_application_connectivity_validator: name: "central-application-connectivity-validator" - version: "PR-17914" + version: "PR-17957" directory: "dev" central_application_gateway: name: "central-application-gateway" From ea8e507d0e7f1e62045a951506b462b72427bae8 Mon Sep 17 00:00:00 2001 From: m00g3n Date: Wed, 16 Aug 2023 12:19:19 +0200 Subject: [PATCH 2/3] code review comments addressed --- .../central-application-connectivity-validator/values.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/application-connector/charts/central-application-connectivity-validator/values.yaml b/resources/application-connector/charts/central-application-connectivity-validator/values.yaml index 3294187b51b2..318cc667e246 100644 --- a/resources/application-connector/charts/central-application-connectivity-validator/values.yaml +++ b/resources/application-connector/charts/central-application-connectivity-validator/values.yaml @@ -4,8 +4,6 @@ deployment: args: proxyPort: &proxyPort 8080 externalAPIPort: &externalAPIPort 8081 - cacheExpirationSeconds: 90 - cacheCleanupIntervalSeconds: 15 resources: limits: cpu: 500m From 759c1ba8a0f35462fdc9da0d8a8d96edb0bfaf73 Mon Sep 17 00:00:00 2001 From: m00g3n Date: Wed, 16 Aug 2023 17:36:29 +0200 Subject: [PATCH 3/3] update central-application-connectivity-validator test data --- .../patches/central-application-connectivity-validator.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/components/application-connector/resources/patches/central-application-connectivity-validator.json b/tests/components/application-connector/resources/patches/central-application-connectivity-validator.json index ceae634c5ef1..b676d8dd54dd 100644 --- a/tests/components/application-connector/resources/patches/central-application-connectivity-validator.json +++ b/tests/components/application-connector/resources/patches/central-application-connectivity-validator.json @@ -12,8 +12,6 @@ "--eventingDestinationPath=/anything/rewrite", "--eventingPathPrefixEvents=/%%APP_NAME%%/events", "--appNamePlaceholder=%%APP_NAME%%", - "--cacheExpirationSeconds=90", - "--cacheCleanupIntervalSeconds=15" ] }, {