diff --git a/api/v1alpha1/instancegroup_types.go b/api/v1alpha1/instancegroup_types.go index 9d1bdb14..b011921b 100644 --- a/api/v1alpha1/instancegroup_types.go +++ b/api/v1alpha1/instancegroup_types.go @@ -368,6 +368,15 @@ type InstanceGroupStatus struct { type InstanceGroupConditionType string +type ValidationOverrides struct { + scalingConfigurationOverride *ScalingConfigurationType +} + +func NewValidationOverrides(defaultScalingConfiguration *ScalingConfigurationType) *ValidationOverrides { + return &ValidationOverrides{ + scalingConfigurationOverride: defaultScalingConfiguration, + } +} func NewInstanceGroupCondition(cType InstanceGroupConditionType, status corev1.ConditionStatus) InstanceGroupCondition { return InstanceGroupCondition{ Type: cType, @@ -409,7 +418,7 @@ func (ig *InstanceGroup) Locked() bool { return false } -func (s *EKSSpec) Validate() error { +func (s *EKSSpec) Validate(overrides *ValidationOverrides) error { var ( configuration = s.EKSConfiguration configType = s.Type @@ -420,6 +429,9 @@ func (s *EKSSpec) Validate() error { if s.Type != LaunchConfiguration && s.Type != LaunchTemplate { s.Type = LaunchTemplate + if overrides.scalingConfigurationOverride != nil { + s.Type = *overrides.scalingConfigurationOverride + } } if s.Type == LaunchConfiguration { @@ -700,7 +712,7 @@ func (m *MixedInstancesPolicySpec) Validate() error { return nil } -func (ig *InstanceGroup) Validate() error { +func (ig *InstanceGroup) Validate(overrides *ValidationOverrides) error { s := ig.Spec if !common.ContainsEqualFold(Provisioners, s.Provisioner) { @@ -735,7 +747,7 @@ func (ig *InstanceGroup) Validate() error { config := ig.GetEKSConfiguration() spec := ig.GetEKSSpec() - if err := spec.Validate(); err != nil { + if err := spec.Validate(overrides); err != nil { return err } diff --git a/api/v1alpha1/instancegroup_types_test.go b/api/v1alpha1/instancegroup_types_test.go index 6b6e1be2..5a85134f 100644 --- a/api/v1alpha1/instancegroup_types_test.go +++ b/api/v1alpha1/instancegroup_types_test.go @@ -25,7 +25,7 @@ type EksUnitTest struct { } func (u *EksUnitTest) Run(t *testing.T) string { - err := u.InstanceGroup.Validate() + err := u.InstanceGroup.Validate(&ValidationOverrides{}) if err == nil { return aws.StringValue(nil) } else { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 83dce64f..576601b7 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -668,6 +668,26 @@ func (in *UserDataStage) DeepCopy() *UserDataStage { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidationOverrides) DeepCopyInto(out *ValidationOverrides) { + *out = *in + if in.scalingConfigurationOverride != nil { + in, out := &in.scalingConfigurationOverride, &out.scalingConfigurationOverride + *out = new(ScalingConfigurationType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidationOverrides. +func (in *ValidationOverrides) DeepCopy() *ValidationOverrides { + if in == nil { + return nil + } + out := new(ValidationOverrides) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WarmPoolSpec) DeepCopyInto(out *WarmPoolSpec) { *out = *in diff --git a/controllers/instancegroup_controller.go b/controllers/instancegroup_controller.go index f4902688..76e6d86b 100644 --- a/controllers/instancegroup_controller.go +++ b/controllers/instancegroup_controller.go @@ -43,19 +43,19 @@ import ( // InstanceGroupReconciler reconciles an InstanceGroup object type InstanceGroupReconciler struct { client.Client - SpotRecommendationTime float64 - ConfigNamespace string - NodeRelabel bool - Log logr.Logger - MaxParallel int - Auth *InstanceGroupAuthenticator - ConfigMap *corev1.ConfigMap - Namespaces map[string]corev1.Namespace - NamespacesLock *sync.RWMutex - ConfigRetention int - Metrics *common.MetricsCollector - DisableWinClusterInjection bool - SetDefaultConfigurationToLaunchConfig bool + SpotRecommendationTime float64 + ConfigNamespace string + NodeRelabel bool + Log logr.Logger + MaxParallel int + Auth *InstanceGroupAuthenticator + ConfigMap *corev1.ConfigMap + Namespaces map[string]corev1.Namespace + NamespacesLock *sync.RWMutex + ConfigRetention int + Metrics *common.MetricsCollector + DisableWinClusterInjection bool + DefaultScalingConfiguration *v1alpha1.ScalingConfigurationType } type InstanceGroupAuthenticator struct { @@ -196,13 +196,9 @@ func (r *InstanceGroupReconciler) Reconcile(ctxt context.Context, req ctrl.Reque } // for igs without any config type mentioned, allow the default to be set to launchconfig. - if r.SetDefaultConfigurationToLaunchConfig { - if input.InstanceGroup.Spec.EKSSpec.Type != v1alpha1.LaunchConfiguration && input.InstanceGroup.Spec.EKSSpec.Type != v1alpha1.LaunchTemplate { - input.InstanceGroup.Spec.EKSSpec.Type = v1alpha1.LaunchConfiguration - } - } - - if err = input.InstanceGroup.Validate(); err != nil { + overrides := v1alpha1.NewValidationOverrides(r.DefaultScalingConfiguration) + + if err = input.InstanceGroup.Validate(overrides); err != nil { ctx.SetState(v1alpha1.ReconcileErr) r.PatchStatus(input.InstanceGroup, statusPatch) r.Metrics.IncFail(instanceGroup.NamespacedName(), ErrorReasonValidationFailed) diff --git a/controllers/provisioners/eks/upgrade_test.go b/controllers/provisioners/eks/upgrade_test.go index 12bb7362..c5f2d213 100644 --- a/controllers/provisioners/eks/upgrade_test.go +++ b/controllers/provisioners/eks/upgrade_test.go @@ -96,7 +96,7 @@ func TestUpgradeCRDStrategyValidation(t *testing.T) { t.Logf("#%v - %+v", i, tc.input) var errOccured bool ig.SetUpgradeStrategy(tc.input) - err := ig.Validate() + err := ig.Validate(&v1alpha1.ValidationOverrides{}) if err != nil { t.Log(err) errOccured = true diff --git a/main.go b/main.go index adc93cb9..65497fce 100644 --- a/main.go +++ b/main.go @@ -65,17 +65,17 @@ func main() { printVersion() var ( - metricsAddr string - configNamespace string - spotRecommendationTime float64 - enableLeaderElection bool - nodeRelabel bool - disableWinClusterInjection bool - maxParallel int - maxAPIRetries int - configRetention int - err error - setDefaultConfigurationToLaunchConfig bool + metricsAddr string + configNamespace string + spotRecommendationTime float64 + enableLeaderElection bool + nodeRelabel bool + disableWinClusterInjection bool + maxParallel int + maxAPIRetries int + configRetention int + err error + defaultScalingConfiguration string ) flag.IntVar(&maxParallel, "max-workers", 5, "The number of maximum parallel reconciles") @@ -88,7 +88,7 @@ func main() { "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.") flag.BoolVar(&nodeRelabel, "node-relabel", true, "relabel nodes as they join with kubernetes.io/role label via controller") flag.BoolVar(&disableWinClusterInjection, "disable-windows-cluster-ca-injection", false, "Setting this to true will cause the ClusterCA and Endpoint to not be injected for Windows nodes") - flag.BoolVar(&setDefaultConfigurationToLaunchConfig, "scaling-configuration-to-launchconfig", false, "By default ASGs will have launchtemplates. Set this flag to true if launchconfigs needs to be the default.") + flag.StringVar(&defaultScalingConfiguration, "", string(instancemgrv1alpha1.LaunchTemplate), "By default ASGs will have launchtemplates. Set this flag to true if launchconfigs needs to be the default.") flag.Parse() ctrl.SetLogger(zap.New(zap.UseDevMode(true))) @@ -151,20 +151,21 @@ func main() { setupLog.Info("instance-manager configmap does not exist, will not load defaults/boundaries") } + defaultScalingConfigurationType := instancemgrv1alpha1.ScalingConfigurationType(defaultScalingConfiguration) err = (&controllers.InstanceGroupReconciler{ - Metrics: controllerCollector, - ConfigMap: cm, - ConfigRetention: configRetention, - SpotRecommendationTime: spotRecommendationTime, - ConfigNamespace: configNamespace, - Namespaces: make(map[string]corev1.Namespace), - NamespacesLock: &sync.RWMutex{}, - NodeRelabel: nodeRelabel, - DisableWinClusterInjection: disableWinClusterInjection, - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("controllers").WithName("instancegroup"), - MaxParallel: maxParallel, - SetDefaultConfigurationToLaunchConfig: setDefaultConfigurationToLaunchConfig, + Metrics: controllerCollector, + ConfigMap: cm, + ConfigRetention: configRetention, + SpotRecommendationTime: spotRecommendationTime, + ConfigNamespace: configNamespace, + Namespaces: make(map[string]corev1.Namespace), + NamespacesLock: &sync.RWMutex{}, + NodeRelabel: nodeRelabel, + DisableWinClusterInjection: disableWinClusterInjection, + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("instancegroup"), + MaxParallel: maxParallel, + DefaultScalingConfiguration: &defaultScalingConfigurationType, Auth: &controllers.InstanceGroupAuthenticator{ Aws: awsWorker, Kubernetes: kube,