forked from Azure/fleet
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: update crp default func (Azure#734)
- Loading branch information
Showing
7 changed files
with
255 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
Copyright (c) Microsoft Corporation. | ||
Licensed under the MIT license. | ||
*/ | ||
|
||
// Package defaulter is an interface for setting default values for a resource. | ||
package defaulter | ||
|
||
import ( | ||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/util/intstr" | ||
"k8s.io/utils/ptr" | ||
|
||
fleetv1beta1 "go.goms.io/fleet/apis/placement/v1beta1" | ||
) | ||
|
||
const ( | ||
// DefaultMaxUnavailableValue is the default value of MaxUnavailable in the rolling update config. | ||
DefaultMaxUnavailableValue = "25%" | ||
|
||
// DefaultMaxSurgeValue is the default value of MaxSurge in the rolling update config. | ||
DefaultMaxSurgeValue = "25%" | ||
|
||
// DefaultUnavailablePeriodSeconds is the default period of time we consider a newly applied workload as unavailable. | ||
DefaultUnavailablePeriodSeconds = 60 | ||
|
||
// DefaultMaxSkewValue is the default degree to which resources may be unevenly distributed. | ||
DefaultMaxSkewValue = 1 | ||
|
||
// DefaultRevisionHistoryLimitValue is the default value of RevisionHistoryLimit. | ||
DefaultRevisionHistoryLimitValue = 10 | ||
) | ||
|
||
// SetDefaultsClusterResourcePlacement sets the default values for ClusterResourcePlacement. | ||
func SetDefaultsClusterResourcePlacement(obj *fleetv1beta1.ClusterResourcePlacement) { | ||
if obj.Spec.Policy == nil { | ||
obj.Spec.Policy = &fleetv1beta1.PlacementPolicy{ | ||
PlacementType: fleetv1beta1.PickAllPlacementType, | ||
} | ||
} | ||
|
||
if obj.Spec.Policy.TopologySpreadConstraints != nil { | ||
for i := range obj.Spec.Policy.TopologySpreadConstraints { | ||
if obj.Spec.Policy.TopologySpreadConstraints[i].MaxSkew == nil { | ||
obj.Spec.Policy.TopologySpreadConstraints[i].MaxSkew = ptr.To(int32(DefaultMaxSkewValue)) | ||
} | ||
if obj.Spec.Policy.TopologySpreadConstraints[i].WhenUnsatisfiable == "" { | ||
obj.Spec.Policy.TopologySpreadConstraints[i].WhenUnsatisfiable = fleetv1beta1.DoNotSchedule | ||
} | ||
} | ||
} | ||
|
||
if obj.Spec.Policy.Tolerations != nil { | ||
for i := range obj.Spec.Policy.Tolerations { | ||
if obj.Spec.Policy.Tolerations[i].Operator == "" { | ||
obj.Spec.Policy.Tolerations[i].Operator = corev1.TolerationOpEqual | ||
} | ||
} | ||
} | ||
|
||
strategy := &obj.Spec.Strategy | ||
if strategy.Type == "" { | ||
strategy.Type = fleetv1beta1.RollingUpdateRolloutStrategyType | ||
} | ||
if strategy.Type == fleetv1beta1.RollingUpdateRolloutStrategyType { | ||
if strategy.RollingUpdate == nil { | ||
strategy.RollingUpdate = &fleetv1beta1.RollingUpdateConfig{} | ||
} | ||
if strategy.RollingUpdate.MaxUnavailable == nil { | ||
strategy.RollingUpdate.MaxUnavailable = ptr.To(intstr.FromString(DefaultMaxUnavailableValue)) | ||
} | ||
if strategy.RollingUpdate.MaxSurge == nil { | ||
strategy.RollingUpdate.MaxSurge = ptr.To(intstr.FromString(DefaultMaxSurgeValue)) | ||
} | ||
if strategy.RollingUpdate.UnavailablePeriodSeconds == nil { | ||
strategy.RollingUpdate.UnavailablePeriodSeconds = ptr.To(DefaultUnavailablePeriodSeconds) | ||
} | ||
} | ||
|
||
if obj.Spec.Strategy.ApplyStrategy == nil { | ||
obj.Spec.Strategy.ApplyStrategy = &fleetv1beta1.ApplyStrategy{} | ||
} | ||
if obj.Spec.Strategy.ApplyStrategy.Type == "" { | ||
obj.Spec.Strategy.ApplyStrategy.Type = fleetv1beta1.ApplyStrategyTypeClientSideApply | ||
} | ||
if obj.Spec.Strategy.ApplyStrategy.Type == fleetv1beta1.ApplyStrategyTypeServerSideApply && obj.Spec.Strategy.ApplyStrategy.ServerSideApplyConfig == nil { | ||
obj.Spec.Strategy.ApplyStrategy.ServerSideApplyConfig = &fleetv1beta1.ServerSideApplyConfig{ | ||
ForceConflicts: false, | ||
} | ||
} | ||
|
||
if obj.Spec.RevisionHistoryLimit == nil { | ||
obj.Spec.RevisionHistoryLimit = ptr.To(int32(DefaultRevisionHistoryLimitValue)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
/* | ||
Copyright (c) Microsoft Corporation. | ||
Licensed under the MIT license. | ||
*/ | ||
|
||
package defaulter | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/util/intstr" | ||
"k8s.io/utils/ptr" | ||
|
||
fleetv1beta1 "go.goms.io/fleet/apis/placement/v1beta1" | ||
) | ||
|
||
func TestSetDefaultsClusterResourcePlacement(t *testing.T) { | ||
tests := map[string]struct { | ||
obj *fleetv1beta1.ClusterResourcePlacement | ||
wantObj *fleetv1beta1.ClusterResourcePlacement | ||
}{ | ||
"ClusterResourcePlacement with nil Spec": { | ||
obj: &fleetv1beta1.ClusterResourcePlacement{ | ||
Spec: fleetv1beta1.ClusterResourcePlacementSpec{}, | ||
}, | ||
wantObj: &fleetv1beta1.ClusterResourcePlacement{ | ||
Spec: fleetv1beta1.ClusterResourcePlacementSpec{ | ||
Policy: &fleetv1beta1.PlacementPolicy{ | ||
PlacementType: fleetv1beta1.PickAllPlacementType, | ||
}, | ||
Strategy: fleetv1beta1.RolloutStrategy{ | ||
Type: fleetv1beta1.RollingUpdateRolloutStrategyType, | ||
RollingUpdate: &fleetv1beta1.RollingUpdateConfig{ | ||
MaxUnavailable: ptr.To(intstr.FromString(DefaultMaxUnavailableValue)), | ||
MaxSurge: ptr.To(intstr.FromString(DefaultMaxSurgeValue)), | ||
UnavailablePeriodSeconds: ptr.To(DefaultUnavailablePeriodSeconds), | ||
}, | ||
ApplyStrategy: &fleetv1beta1.ApplyStrategy{ | ||
Type: fleetv1beta1.ApplyStrategyTypeClientSideApply, | ||
}, | ||
}, | ||
RevisionHistoryLimit: ptr.To(int32(DefaultRevisionHistoryLimitValue)), | ||
}, | ||
}, | ||
}, | ||
"ClusterResourcePlacement with nil TopologySpreadConstraints & Tolerations fields": { | ||
obj: &fleetv1beta1.ClusterResourcePlacement{ | ||
Spec: fleetv1beta1.ClusterResourcePlacementSpec{ | ||
Policy: &fleetv1beta1.PlacementPolicy{ | ||
TopologySpreadConstraints: []fleetv1beta1.TopologySpreadConstraint{ | ||
{ | ||
TopologyKey: "kubernetes.io/hostname", | ||
}, | ||
}, | ||
Tolerations: []fleetv1beta1.Toleration{ | ||
{ | ||
Key: "key", | ||
Value: "value", | ||
}, | ||
}, | ||
}, | ||
Strategy: fleetv1beta1.RolloutStrategy{ | ||
Type: fleetv1beta1.RollingUpdateRolloutStrategyType, | ||
RollingUpdate: &fleetv1beta1.RollingUpdateConfig{ | ||
MaxUnavailable: ptr.To(intstr.FromString("%15")), | ||
MaxSurge: ptr.To(intstr.FromString("%15")), | ||
UnavailablePeriodSeconds: ptr.To(15), | ||
}, | ||
ApplyStrategy: &fleetv1beta1.ApplyStrategy{ | ||
Type: fleetv1beta1.ApplyStrategyTypeClientSideApply, | ||
}, | ||
}, | ||
RevisionHistoryLimit: ptr.To(int32(10)), | ||
}, | ||
}, | ||
wantObj: &fleetv1beta1.ClusterResourcePlacement{ | ||
Spec: fleetv1beta1.ClusterResourcePlacementSpec{ | ||
Policy: &fleetv1beta1.PlacementPolicy{ | ||
TopologySpreadConstraints: []fleetv1beta1.TopologySpreadConstraint{ | ||
{ | ||
TopologyKey: "kubernetes.io/hostname", | ||
MaxSkew: ptr.To(int32(DefaultMaxSkewValue)), | ||
WhenUnsatisfiable: fleetv1beta1.DoNotSchedule, | ||
}, | ||
}, | ||
Tolerations: []fleetv1beta1.Toleration{ | ||
{ | ||
Key: "key", | ||
Value: "value", | ||
Operator: corev1.TolerationOpEqual, | ||
}, | ||
}, | ||
}, | ||
Strategy: fleetv1beta1.RolloutStrategy{ | ||
Type: fleetv1beta1.RollingUpdateRolloutStrategyType, | ||
RollingUpdate: &fleetv1beta1.RollingUpdateConfig{ | ||
MaxUnavailable: ptr.To(intstr.FromString("%15")), | ||
MaxSurge: ptr.To(intstr.FromString("%15")), | ||
UnavailablePeriodSeconds: ptr.To(15), | ||
}, | ||
ApplyStrategy: &fleetv1beta1.ApplyStrategy{ | ||
Type: fleetv1beta1.ApplyStrategyTypeClientSideApply, | ||
}, | ||
}, | ||
RevisionHistoryLimit: ptr.To(int32(10)), | ||
}, | ||
}, | ||
}, | ||
"ClusterResourcePlacement with serverside apply config not set": { | ||
obj: &fleetv1beta1.ClusterResourcePlacement{ | ||
Spec: fleetv1beta1.ClusterResourcePlacementSpec{ | ||
Strategy: fleetv1beta1.RolloutStrategy{ | ||
ApplyStrategy: &fleetv1beta1.ApplyStrategy{ | ||
Type: fleetv1beta1.ApplyStrategyTypeServerSideApply, | ||
}, | ||
}, | ||
}, | ||
}, | ||
wantObj: &fleetv1beta1.ClusterResourcePlacement{ | ||
Spec: fleetv1beta1.ClusterResourcePlacementSpec{ | ||
Policy: &fleetv1beta1.PlacementPolicy{ | ||
PlacementType: fleetv1beta1.PickAllPlacementType, | ||
}, | ||
Strategy: fleetv1beta1.RolloutStrategy{ | ||
Type: fleetv1beta1.RollingUpdateRolloutStrategyType, | ||
RollingUpdate: &fleetv1beta1.RollingUpdateConfig{ | ||
MaxUnavailable: ptr.To(intstr.FromString(DefaultMaxUnavailableValue)), | ||
MaxSurge: ptr.To(intstr.FromString(DefaultMaxSurgeValue)), | ||
UnavailablePeriodSeconds: ptr.To(DefaultUnavailablePeriodSeconds), | ||
}, | ||
ApplyStrategy: &fleetv1beta1.ApplyStrategy{ | ||
Type: fleetv1beta1.ApplyStrategyTypeServerSideApply, | ||
ServerSideApplyConfig: &fleetv1beta1.ServerSideApplyConfig{ | ||
ForceConflicts: false, | ||
}, | ||
}, | ||
}, | ||
RevisionHistoryLimit: ptr.To(int32(DefaultRevisionHistoryLimitValue)), | ||
}, | ||
}, | ||
}, | ||
} | ||
for name, tt := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
SetDefaultsClusterResourcePlacement(tt.obj) | ||
if diff := cmp.Diff(tt.wantObj, tt.obj); diff != "" { | ||
t.Errorf("SetDefaultsClusterResourcePlacement() mismatch (-want +got):\n%s", diff) | ||
} | ||
}) | ||
} | ||
} |