Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Align runtime-watcher registry and make configurable #1868

14 changes: 1 addition & 13 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion config/watcher/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
48 changes: 31 additions & 17 deletions internal/pkg/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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.")
Expand Down Expand Up @@ -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
Expand All @@ -302,32 +309,39 @@ 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{
2048: false, // 2048 is a valid value for cert-manager, but explicitly prohibited as not compliant to security requirements
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)
}
205 changes: 205 additions & 0 deletions internal/pkg/flags/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
}
Loading