From e4f22bee4173a5f1377ad8f1cf74efafb8931212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schw=C3=A4gerl?= Date: Mon, 23 Sep 2024 16:01:08 +0200 Subject: [PATCH] chore: Align runtime-watcher registry and make configurable (#1868) * chore: Align runtime-watcher registry and make configurable * bump watcher version * fix linting * test flag defaults * remove efault for watcher image * describe and logs * quote value * test echo; no wait for build-iamge * test echo * PR instead of PR_target * revert test stuff; add flag default * default watcher image * remove quotes * revert faulty image name --- cmd/main.go | 14 +- config/watcher/kustomization.yaml | 5 +- internal/pkg/flags/flags.go | 48 ++++--- internal/pkg/flags/flags_test.go | 205 ++++++++++++++++++++++++++++++ 4 files changed, 241 insertions(+), 31 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 0dc6c2e41f..76895134b7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -322,7 +322,7 @@ func createSkrWebhookManager(mgr ctrl.Manager, skrContextFactory remote.SkrConte caCertificateCache := watcher.NewCACertificateCache(flagVar.CaCertCacheTTL) config := watcher.SkrWebhookManagerConfig{ SKRWatcherPath: flagVar.WatcherResourcesPath, - SkrWatcherImage: getWatcherImg(flagVar), + SkrWatcherImage: flagVar.GetWatcherImage(), SkrWebhookCPULimits: flagVar.WatcherResourceLimitsCPU, SkrWebhookMemoryLimits: flagVar.WatcherResourceLimitsMemory, RemoteSyncNamespace: flagVar.RemoteSyncNamespace, @@ -355,18 +355,6 @@ func createSkrWebhookManager(mgr ctrl.Manager, skrContextFactory remote.SkrConte resolvedKcpAddr) } -const ( - watcherRegProd = "europe-docker.pkg.dev/kyma-project/prod/runtime-watcher-skr" - watcherRegDev = "europe-docker.pkg.dev/kyma-project/dev/runtime-watcher" -) - -func getWatcherImg(flagVar *flags.FlagVar) string { - if flagVar.UseWatcherDevRegistry { - return fmt.Sprintf("%s:%s", watcherRegDev, flagVar.WatcherImageTag) - } - return fmt.Sprintf("%s:%s", watcherRegProd, flagVar.WatcherImageTag) -} - func setupPurgeReconciler(mgr ctrl.Manager, skrContextProvider remote.SkrContextProvider, event event.Event, diff --git a/config/watcher/kustomization.yaml b/config/watcher/kustomization.yaml index 32d8fb53c9..6465269610 100644 --- a/config/watcher/kustomization.yaml +++ b/config/watcher/kustomization.yaml @@ -18,7 +18,10 @@ patches: value: --skr-watcher-path=/skr-webhook - op: add path: /spec/template/spec/containers/0/args/- - value: --skr-watcher-image-tag=1.1.1 + value: --skr-watcher-image-tag=1.1.4 + - op: add + path: /spec/template/spec/containers/0/args/- + value: --skr-watcher-image-registry=europe-docker.pkg.dev/kyma-project/prod - op: add path: /spec/template/spec/containers/0/args/- value: --enable-domain-name-pinning=true diff --git a/internal/pkg/flags/flags.go b/internal/pkg/flags/flags.go index b6d9fbf4db..daaaa79ab7 100644 --- a/internal/pkg/flags/flags.go +++ b/internal/pkg/flags/flags.go @@ -54,6 +54,9 @@ const ( DefaultKymaListenerAddress = ":8082" DefaultManifestListenerAddress = ":8083" DefaultPprofAddress = ":8084" + DefaultWatcherImageTag = "1.1.4" + DefaultWatcherImageName = "runtime-watcher" + DefaultWatcherImageRegistry = "europe-docker.pkg.dev/kyma-project/prod" DefaultWatcherResourcesPath = "./skr-webhook" DefaultWatcherResourceLimitsCPU = "0.1" DefaultWatcherResourceLimitsMemory = "200Mi" @@ -64,12 +67,13 @@ const ( ) var ( - errMissingWatcherImageTag = errors.New("runtime watcher image tag is not provided") - errWatcherDirNotExist = errors.New("failed to locate watcher resource manifest folder") - errLeaderElectionTimeoutConfig = errors.New("configured leader-election-renew-deadline must be less than leader-election-lease-duration") - errInvalidSelfSignedCertKeyLength = errors.New("invalid self-signed-cert-key-size: must be 4096") - errInvalidManifestRequeueJitterPercentage = errors.New("invalid manifest requeue jitter percentage: must be between 0 and 0.05") - errInvalidManifestRequeueJitterProbability = errors.New("invalid manifest requeue jitter probability: must be between 0 and 1") + ErrMissingWatcherImageTag = errors.New("runtime watcher image tag is not provided") + ErrMissingWatcherImageRegistry = errors.New("runtime watcher image registry is not provided") + ErrWatcherDirNotExist = errors.New("failed to locate watcher resource manifest folder") + ErrLeaderElectionTimeoutConfig = errors.New("configured leader-election-renew-deadline must be less than leader-election-lease-duration") + ErrInvalidSelfSignedCertKeyLength = errors.New("invalid self-signed-cert-key-size: must be 4096") + ErrInvalidManifestRequeueJitterPercentage = errors.New("invalid manifest requeue jitter percentage: must be between 0 and 0.05") + ErrInvalidManifestRequeueJitterProbability = errors.New("invalid manifest requeue jitter probability: must be between 0 and 1") ) //nolint:funlen // defines all program flags @@ -216,10 +220,12 @@ func DefineFlagVar() *FlagVar { flag.StringVar(&flagVar.DropCrdStoredVersionMap, "drop-crd-stored-version-map", DefaultDropCrdStoredVersionMap, "Specify the API versions to be dropped from the storage version. The input format should be a "+ "comma-separated list of API versions, where each API version is in the format 'kind:version'.") - flag.StringVar(&flagVar.WatcherImageTag, "skr-watcher-image-tag", "", + flag.StringVar(&flagVar.WatcherImageName, "skr-watcher-image-name", DefaultWatcherImageName, + `Image name to be used for the SKR watcher image.`) + flag.StringVar(&flagVar.WatcherImageTag, "skr-watcher-image-tag", DefaultWatcherImageTag, `Image tag to be used for the SKR watcher image.`) - flag.BoolVar(&flagVar.UseWatcherDevRegistry, "watcher-dev-registry", false, - `Enable to use the dev registry for fetching the watcher image.`) + flag.StringVar(&flagVar.WatcherImageRegistry, "skr-watcher-image-registry", DefaultWatcherImageRegistry, + `Image registry to be used for the SKR watcher image.`) flag.StringVar(&flagVar.WatcherResourceLimitsMemory, "skr-webhook-memory-limits", DefaultWatcherResourceLimitsMemory, "The resources.limits.memory for skr webhook.") @@ -289,8 +295,9 @@ type FlagVar struct { SelfSignedCertRenewBuffer time.Duration SelfSignedCertKeySize int DropCrdStoredVersionMap string - UseWatcherDevRegistry bool WatcherImageTag string + WatcherImageName string + WatcherImageRegistry string WatcherResourceLimitsMemory string WatcherResourceLimitsCPU string WatcherResourcesPath string @@ -302,16 +309,19 @@ type FlagVar struct { func (f FlagVar) Validate() error { if f.EnableKcpWatcher { if f.WatcherImageTag == "" { - return errMissingWatcherImageTag + return ErrMissingWatcherImageTag + } + if f.WatcherImageRegistry == "" { + return ErrMissingWatcherImageRegistry } dirInfo, err := os.Stat(f.WatcherResourcesPath) if err != nil || !dirInfo.IsDir() { - return errWatcherDirNotExist + return ErrWatcherDirNotExist } } if f.LeaderElectionRenewDeadline >= f.LeaderElectionLeaseDuration { - return fmt.Errorf("%w (%.1f[s])", errLeaderElectionTimeoutConfig, f.LeaderElectionLeaseDuration.Seconds()) + return fmt.Errorf("%w (%.1f[s])", ErrLeaderElectionTimeoutConfig, f.LeaderElectionLeaseDuration.Seconds()) } if !map[int]bool{ @@ -319,15 +329,19 @@ func (f FlagVar) Validate() error { 4096: true, 8192: false, // see https://github.com/kyma-project/lifecycle-manager/issues/1793 }[f.SelfSignedCertKeySize] { - return errInvalidSelfSignedCertKeyLength + return ErrInvalidSelfSignedCertKeyLength } if f.ManifestRequeueJitterProbability < 0 || f.ManifestRequeueJitterProbability > 0.05 { - return errInvalidManifestRequeueJitterPercentage + return ErrInvalidManifestRequeueJitterPercentage } - if f.ManifestRequeueJitterProbability < 0 || f.ManifestRequeueJitterProbability > 1 { - return errInvalidManifestRequeueJitterProbability + if f.ManifestRequeueJitterPercentage < 0 || f.ManifestRequeueJitterPercentage > 1 { + return ErrInvalidManifestRequeueJitterProbability } return nil } + +func (f FlagVar) GetWatcherImage() string { + return fmt.Sprintf("%s/%s:%s", f.WatcherImageRegistry, f.WatcherImageName, f.WatcherImageTag) +} diff --git a/internal/pkg/flags/flags_test.go b/internal/pkg/flags/flags_test.go index 3052f0a03a..9b097c3d39 100644 --- a/internal/pkg/flags/flags_test.go +++ b/internal/pkg/flags/flags_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/kyma-project/lifecycle-manager/pkg/log" . "github.com/kyma-project/lifecycle-manager/internal/pkg/flags" @@ -223,6 +225,16 @@ func Test_ConstantFlags(t *testing.T) { constValue: DefaultPprofAddress, expectedValue: ":8084", }, + { + constName: "WatcherImageName", + constValue: DefaultWatcherImageName, + expectedValue: "runtime-watcher", + }, + { + constName: "WatcherImageRegistry", + constValue: DefaultWatcherImageRegistry, + expectedValue: "europe-docker.pkg.dev/kyma-project/prod", + }, { constName: "DefaultWatcherResourcesPath", constValue: DefaultWatcherResourcesPath, @@ -265,3 +277,196 @@ func Test_ConstantFlags(t *testing.T) { }) } } + +func Test_Flags_Validate(t *testing.T) { + tests := []struct { + name string + flags FlagVar + err error + }{ + { + name: "WatcherImageTag is required", + flags: newFlagVarBuilder().withEnabledKcpWatcher(true).withWatcherImageTag("").build(), + err: ErrMissingWatcherImageTag, + }, + { + name: "WatcherImageTag is NOT required", + flags: newFlagVarBuilder().withWatcherImageTag("").build(), + err: nil, + }, + { + name: "WatcherImageRegistry is required", + flags: newFlagVarBuilder().withEnabledKcpWatcher(true).withWatcherImageRegistry("").build(), + err: ErrMissingWatcherImageRegistry, + }, + { + name: "WatcherImageRegistry is NOT required", + flags: newFlagVarBuilder().withWatcherImageRegistry("").build(), + err: nil, + }, + { + name: "WatcherResourcesPath is required", + flags: newFlagVarBuilder().withEnabledKcpWatcher(true).withWatcherResourcesPath("").build(), + err: ErrWatcherDirNotExist, + }, + { + name: "WatcherResourcesPath is NOT required", + flags: newFlagVarBuilder().withWatcherResourcesPath("").build(), + err: nil, + }, + { + name: "LeaderElectionRenewDeadline > LeaderElectionLeaseDuration", + flags: newFlagVarBuilder().withLeaderElectionRenewDeadline(2).withLeaderElectionLeaseDuration(1).build(), + err: ErrLeaderElectionTimeoutConfig, + }, + { + name: "LeaderElectionRenewDeadline = LeaderElectionLeaseDuration", + flags: newFlagVarBuilder().withLeaderElectionRenewDeadline(1).withLeaderElectionLeaseDuration(1).build(), + err: ErrLeaderElectionTimeoutConfig, + }, + { + name: "LeaderElectionRenewDeadline < LeaderElectionLeaseDuration", + flags: newFlagVarBuilder().withLeaderElectionRenewDeadline(1).withLeaderElectionLeaseDuration(2).build(), + err: nil, + }, + { + name: "SelfSignedCertKeySize 2048", + flags: newFlagVarBuilder().withSelfSignedCertKeySize(2048).build(), + err: ErrInvalidSelfSignedCertKeyLength, + }, + { + name: "SelfSignedCertKeySize 8192", + flags: newFlagVarBuilder().withSelfSignedCertKeySize(8192).build(), + err: ErrInvalidSelfSignedCertKeyLength, + }, + { + name: "SelfSignedCertKeySize 4711", + flags: newFlagVarBuilder().withSelfSignedCertKeySize(4711).build(), + err: ErrInvalidSelfSignedCertKeyLength, + }, + { + name: "SelfSignedCertKeySize 4096", + flags: newFlagVarBuilder().withSelfSignedCertKeySize(4096).build(), + err: nil, + }, + { + name: "ManifestRequeueJitterProbability < 0", + flags: newFlagVarBuilder().withManifestRequeueJitterProbability(-1).build(), + err: ErrInvalidManifestRequeueJitterPercentage, + }, + { + name: "ManifestRequeueJitterProbability > 0.05", + flags: newFlagVarBuilder().withManifestRequeueJitterProbability(0.1).build(), + err: ErrInvalidManifestRequeueJitterPercentage, + }, + { + name: "ManifestRequeueJitterProbability 0.01", + flags: newFlagVarBuilder().withManifestRequeueJitterProbability(0.01).build(), + err: nil, + }, + { + name: "ManifestRequeueJitterPercentage < 0", + flags: newFlagVarBuilder().withManifestRequeueJitterPercentage(-1).build(), + err: ErrInvalidManifestRequeueJitterProbability, + }, + { + name: "ManifestRequeueJitterPercentage > 0.05", + flags: newFlagVarBuilder().withManifestRequeueJitterPercentage(2).build(), + err: ErrInvalidManifestRequeueJitterProbability, + }, + { + name: "ManifestRequeueJitterPercentage 0.1", + flags: newFlagVarBuilder().withManifestRequeueJitterPercentage(0.1).build(), + err: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.flags.Validate() + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + } else { + require.NoError(t, err) + } + }) + } +} + +// test builder + +type flagVarBuilder struct { + flags FlagVar +} + +func newFlagVarBuilder() *flagVarBuilder { + builder := &flagVarBuilder{ + flags: FlagVar{}, + } + + return builder. + withEnabledKcpWatcher(false). + withWatcherImageTag("v1.0.0"). + withWatcherImageName("runtime-watcher"). + withWatcherImageRegistry("foo.bar"). + withWatcherResourcesPath("./skr-webhook"). + withLeaderElectionRenewDeadline(120 * time.Second). + withLeaderElectionLeaseDuration(180 * time.Second). + withSelfSignedCertKeySize(4096). + withManifestRequeueJitterProbability(0.01). + withManifestRequeueJitterPercentage(0.1) +} + +func (b *flagVarBuilder) build() FlagVar { + return b.flags +} + +func (b *flagVarBuilder) withEnabledKcpWatcher(enabled bool) *flagVarBuilder { + b.flags.EnableKcpWatcher = enabled + return b +} + +func (b *flagVarBuilder) withWatcherImageTag(tag string) *flagVarBuilder { + b.flags.WatcherImageTag = tag + return b +} + +func (b *flagVarBuilder) withWatcherImageName(name string) *flagVarBuilder { + b.flags.WatcherImageName = name + return b +} + +func (b *flagVarBuilder) withWatcherImageRegistry(registry string) *flagVarBuilder { + b.flags.WatcherImageRegistry = registry + return b +} + +func (b *flagVarBuilder) withWatcherResourcesPath(path string) *flagVarBuilder { + b.flags.WatcherResourcesPath = path + return b +} + +func (b *flagVarBuilder) withLeaderElectionRenewDeadline(duration time.Duration) *flagVarBuilder { + b.flags.LeaderElectionRenewDeadline = duration + return b +} + +func (b *flagVarBuilder) withLeaderElectionLeaseDuration(duration time.Duration) *flagVarBuilder { + b.flags.LeaderElectionLeaseDuration = duration + return b +} + +func (b *flagVarBuilder) withSelfSignedCertKeySize(size int) *flagVarBuilder { + b.flags.SelfSignedCertKeySize = size + return b +} + +func (b *flagVarBuilder) withManifestRequeueJitterProbability(probability float64) *flagVarBuilder { + b.flags.ManifestRequeueJitterProbability = probability + return b +} + +func (b *flagVarBuilder) withManifestRequeueJitterPercentage(percentage float64) *flagVarBuilder { + b.flags.ManifestRequeueJitterPercentage = percentage + return b +}