diff --git a/pkg/operator/options/options.go b/pkg/operator/options/options.go index 296eecd683..24a92bb747 100644 --- a/pkg/operator/options/options.go +++ b/pkg/operator/options/options.go @@ -59,6 +59,7 @@ type FeatureGates struct { NodeRepair bool ReservedCapacity bool SpotToSpotConsolidation bool + NodeOverlay bool } // Options contains all CLI flags / env vars for karpenter-core. It adheres to the options.Injectable interface. @@ -122,7 +123,7 @@ func (o *Options) AddFlags(fs *FlagSet) { fs.DurationVar(&o.BatchIdleDuration, "batch-idle-duration", env.WithDefaultDuration("BATCH_IDLE_DURATION", time.Second), "The maximum amount of time with no new pending pods that if exceeded ends the current batching window. If pods arrive faster than this time, the batching window will be extended up to the maxDuration. If they arrive slower, the pods will be batched separately.") fs.StringVar(&o.preferencePolicyRaw, "preference-policy", env.WithDefaultString("PREFERENCE_POLICY", string(PreferencePolicyRespect)), "How the Karpenter scheduler should treat preferences. Preferences include preferredDuringSchedulingIgnoreDuringExecution node and pod affinities/anti-affinities and ScheduleAnyways topologySpreadConstraints. Can be one of 'Ignore' and 'Respect'") fs.StringVar(&o.minValuesPolicyRaw, "min-values-policy", env.WithDefaultString("MIN_VALUES_POLICY", string(MinValuesPolicyStrict)), "Min values policy for scheduling. Options include 'Strict' for existing behavior where min values are strictly enforced or 'BestEffort' where Karpenter relaxes min values when it isn't satisfied.") - fs.StringVar(&o.FeatureGates.inputStr, "feature-gates", env.WithDefaultString("FEATURE_GATES", "NodeRepair=false,ReservedCapacity=true,SpotToSpotConsolidation=false"), "Optional features can be enabled / disabled using feature gates. Current options are: NodeRepair, ReservedCapacity, and SpotToSpotConsolidation.") + fs.StringVar(&o.FeatureGates.inputStr, "feature-gates", env.WithDefaultString("FEATURE_GATES", "NodeRepair=false,ReservedCapacity=true,SpotToSpotConsolidation=false,NodeOverlay=false"), "Optional features can be enabled / disabled using feature gates. Current options are: NodeRepair, ReservedCapacity, and SpotToSpotConsolidation.") } func (o *Options) Parse(fs *FlagSet, args ...string) error { @@ -184,6 +185,9 @@ func ParseFeatureGates(gateStr string) (FeatureGates, error) { if val, ok := gateMap["ReservedCapacity"]; ok { gates.ReservedCapacity = val } + if val, ok := gateMap["NodeOverlay"]; ok { + gates.NodeOverlay = val + } return gates, nil } diff --git a/pkg/operator/options/suite_test.go b/pkg/operator/options/suite_test.go index 267e0fd637..a77a6e7063 100644 --- a/pkg/operator/options/suite_test.go +++ b/pkg/operator/options/suite_test.go @@ -120,6 +120,7 @@ var _ = Describe("Options", func() { ReservedCapacity: lo.ToPtr(true), NodeRepair: lo.ToPtr(false), SpotToSpotConsolidation: lo.ToPtr(false), + NodeOverlay: lo.ToPtr(false), }, })) }) @@ -146,7 +147,7 @@ var _ = Describe("Options", func() { "--batch-idle-duration", "5s", "--preference-policy", "Ignore", "--min-values-policy", "BestEffort", - "--feature-gates", "ReservedCapacity=false,SpotToSpotConsolidation=true,NodeRepair=true", + "--feature-gates", "ReservedCapacity=false,SpotToSpotConsolidation=true,NodeRepair=true,NodeOverlay=true", ) Expect(err).To(BeNil()) expectOptionsMatch(opts, test.Options(test.OptionsFields{ @@ -171,6 +172,7 @@ var _ = Describe("Options", func() { ReservedCapacity: lo.ToPtr(false), NodeRepair: lo.ToPtr(true), SpotToSpotConsolidation: lo.ToPtr(true), + NodeOverlay: lo.ToPtr(true), }, })) }) @@ -193,7 +195,7 @@ var _ = Describe("Options", func() { os.Setenv("BATCH_IDLE_DURATION", "5s") os.Setenv("PREFERENCE_POLICY", "Ignore") os.Setenv("MIN_VALUES_POLICY", "BestEffort") - os.Setenv("FEATURE_GATES", "ReservedCapacity=false,SpotToSpotConsolidation=true,NodeRepair=true") + os.Setenv("FEATURE_GATES", "ReservedCapacity=false,SpotToSpotConsolidation=true,NodeRepair=true,NodeOverlay=true") fs = &options.FlagSet{ FlagSet: flag.NewFlagSet("karpenter", flag.ContinueOnError), } @@ -222,6 +224,7 @@ var _ = Describe("Options", func() { ReservedCapacity: lo.ToPtr(false), NodeRepair: lo.ToPtr(true), SpotToSpotConsolidation: lo.ToPtr(true), + NodeOverlay: lo.ToPtr(true), }, })) }) @@ -239,7 +242,7 @@ var _ = Describe("Options", func() { os.Setenv("BATCH_IDLE_DURATION", "5s") os.Setenv("PREFERENCE_POLICY", "Ignore") os.Setenv("MIN_VALUES_POLICY", "BestEffort") - os.Setenv("FEATURE_GATES", "ReservedCapacity=false,SpotToSpotConsolidation=true,NodeRepair=true") + os.Setenv("FEATURE_GATES", "ReservedCapacity=false,SpotToSpotConsolidation=true,NodeRepair=true,NodeOverlay=true") fs = &options.FlagSet{ FlagSet: flag.NewFlagSet("karpenter", flag.ContinueOnError), } @@ -275,6 +278,7 @@ var _ = Describe("Options", func() { ReservedCapacity: lo.ToPtr(false), NodeRepair: lo.ToPtr(true), SpotToSpotConsolidation: lo.ToPtr(true), + NodeOverlay: lo.ToPtr(true), }, })) }) @@ -305,6 +309,7 @@ var _ = Describe("Options", func() { Entry("when ReservedCapacity is overridden", "ReservedCapacity"), Entry("when NodeRepair is overridden", "NodeRepair"), Entry("when SpotToSpotConsolidation is overridden", "SpotToSpotConsolidation"), + Entry("when NodeOverlay is overridden", "NodeOverlay"), ) }) @@ -360,5 +365,6 @@ func expectOptionsMatch(optsA, optsB *options.Options) { Expect(optsA.MinValuesPolicy).To(Equal(optsB.MinValuesPolicy)) Expect(optsA.FeatureGates.ReservedCapacity).To(Equal(optsB.FeatureGates.ReservedCapacity)) Expect(optsA.FeatureGates.NodeRepair).To(Equal(optsB.FeatureGates.NodeRepair)) + Expect(optsA.FeatureGates.NodeOverlay).To(Equal(optsB.FeatureGates.NodeOverlay)) Expect(optsA.FeatureGates.SpotToSpotConsolidation).To(Equal(optsB.FeatureGates.SpotToSpotConsolidation)) } diff --git a/pkg/test/options.go b/pkg/test/options.go index 1499315eb1..f4f5d846ac 100644 --- a/pkg/test/options.go +++ b/pkg/test/options.go @@ -53,6 +53,7 @@ type FeatureGates struct { NodeRepair *bool ReservedCapacity *bool SpotToSpotConsolidation *bool + NodeOverlay *bool } func Options(overrides ...OptionsFields) *options.Options { @@ -84,6 +85,7 @@ func Options(overrides ...OptionsFields) *options.Options { NodeRepair: lo.FromPtrOr(opts.FeatureGates.NodeRepair, false), ReservedCapacity: lo.FromPtrOr(opts.FeatureGates.ReservedCapacity, true), SpotToSpotConsolidation: lo.FromPtrOr(opts.FeatureGates.SpotToSpotConsolidation, false), + NodeOverlay: lo.FromPtrOr(opts.FeatureGates.NodeOverlay, false), }, } }