Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added leader election config for non-ha sno clusters
added functions to help default leader election config for sno clusters updated controller builder to use sno leader election when user provdes no options and we are currently running in sno control plane topology Signed-off-by: ehila <ehila@redhat.com> feat: added cluster infra status check for leader election added check for sno topology for leader election config Signed-off-by: ehila <ehila@redhat.com> upkeep: updated warning message for clarity Signed-off-by: ehila <ehila@redhat.com> docs: added calculations and context added calculations for the sno leader election numbers added more comments around method to provide context and reasoning Signed-off-by: ehila <ehila@redhat.com> feat: added LE disable check and tests added check for LE disable flag and SingleReplica before calling SNO leader election method added tests for LeaderElectionSNOConfig and LeaderElectionDefaulting for expected behavior Signed-off-by: ehila <ehila@redhat.com> test: fixed test case for defaults Signed-off-by: ehila <ehila@redhat.com> test: changed unit test to use reflect package changed unit test for equaility check to use reflect.DeepEqual instead of assert.Equal to follow convention of other unit tests Signed-off-by: ehila <ehila@redhat.com> test: fix unit test when running in cluster fixed unit test that reads in namespace from cluster as fallback Signed-off-by: ehila <ehila@redhat.com> fix: added nil check for infraStatus and error out if not populated Signed-off-by: ehila <ehila@redhat.com> fix: added flag to derive user intent on leader election added a flag to signal if the user supplied any leader election config added logic to allow us to override the leader election if the user has provided no configs added unit tests for sno config logic method Signed-off-by: ehila <ehila@redhat.com> feat: removed un-needed method removed GetClusterInfraStatusOrDie method, not needed Signed-off-by: ehila <ehila@redhat.com> refactor: changed variable name and logging message updated flag variable name to be more explicit inverted logic to match variable name updated messaging to match for event recorder and logging statement Signed-off-by: ehila <ehila@redhat.com> feat: changed flag logic to match recommendation Signed-off-by: ehila <ehila@redhat.com>
- Loading branch information
Showing
5 changed files
with
312 additions
and
8 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 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,178 @@ | ||
package leaderelection | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
"time" | ||
|
||
configv1 "github.com/openshift/api/config/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
func TestLeaderElectionSNOConfig(t *testing.T) { | ||
testCases := []struct { | ||
desc string | ||
inputConfig configv1.LeaderElection | ||
expectedConfig configv1.LeaderElection | ||
}{ | ||
{ | ||
desc: "should not alter disable flag when true", | ||
inputConfig: configv1.LeaderElection{ | ||
Disable: true, | ||
}, | ||
expectedConfig: configv1.LeaderElection{ | ||
Disable: true, | ||
LeaseDuration: metav1.Duration{Duration: 270 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 240 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 60 * time.Second}, | ||
}, | ||
}, | ||
{ | ||
desc: "should not alter disable flag when false", | ||
inputConfig: configv1.LeaderElection{ | ||
Disable: false, | ||
}, | ||
expectedConfig: configv1.LeaderElection{ | ||
Disable: false, | ||
LeaseDuration: metav1.Duration{Duration: 270 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 240 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 60 * time.Second}, | ||
}, | ||
}, | ||
{ | ||
desc: "should change durations when none are provided", | ||
inputConfig: configv1.LeaderElection{}, | ||
expectedConfig: configv1.LeaderElection{ | ||
LeaseDuration: metav1.Duration{Duration: 270 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 240 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 60 * time.Second}, | ||
}, | ||
}, | ||
{ | ||
desc: "should change durations for sno configs", | ||
inputConfig: configv1.LeaderElection{ | ||
LeaseDuration: metav1.Duration{Duration: 60 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 40 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 20 * time.Second}, | ||
}, | ||
expectedConfig: configv1.LeaderElection{ | ||
LeaseDuration: metav1.Duration{Duration: 270 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 240 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 60 * time.Second}, | ||
}, | ||
}, | ||
} | ||
for _, tc := range testCases { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
resultConfig := LeaderElectionSNOConfig(tc.inputConfig) | ||
if !reflect.DeepEqual(tc.expectedConfig, resultConfig) { | ||
t.Errorf("expected %#v, got %#v", tc.expectedConfig, resultConfig) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestLeaderElectionDefaulting(t *testing.T) { | ||
testCases := []struct { | ||
desc string | ||
defaultNamespace string | ||
defaultName string | ||
inputConfig configv1.LeaderElection | ||
expectedConfig configv1.LeaderElection | ||
}{ | ||
{ | ||
desc: "should not alter disable flag when true", | ||
inputConfig: configv1.LeaderElection{ | ||
Disable: true, | ||
}, | ||
expectedConfig: configv1.LeaderElection{ | ||
Disable: true, | ||
LeaseDuration: metav1.Duration{Duration: 137 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 107 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 26 * time.Second}, | ||
}, | ||
}, | ||
{ | ||
desc: "should not alter disable flag when false", | ||
inputConfig: configv1.LeaderElection{ | ||
Disable: false, | ||
}, | ||
expectedConfig: configv1.LeaderElection{ | ||
Disable: false, | ||
LeaseDuration: metav1.Duration{Duration: 137 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 107 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 26 * time.Second}, | ||
}, | ||
}, | ||
{ | ||
desc: "should change durations when none are provided", | ||
inputConfig: configv1.LeaderElection{}, | ||
expectedConfig: configv1.LeaderElection{ | ||
LeaseDuration: metav1.Duration{Duration: 137 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 107 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 26 * time.Second}, | ||
}, | ||
}, | ||
{ | ||
desc: "should use default name and namespace when none is provided", | ||
inputConfig: configv1.LeaderElection{}, | ||
defaultName: "new-default-name", | ||
defaultNamespace: "new-default-namespace", | ||
expectedConfig: configv1.LeaderElection{ | ||
LeaseDuration: metav1.Duration{Duration: 137 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 107 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 26 * time.Second}, | ||
Name: "new-default-name", | ||
Namespace: "new-default-namespace", | ||
}, | ||
}, | ||
{ | ||
desc: "should not alter durations when values are provided", | ||
inputConfig: configv1.LeaderElection{ | ||
LeaseDuration: metav1.Duration{Duration: 60 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 40 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 20 * time.Second}, | ||
}, | ||
expectedConfig: configv1.LeaderElection{ | ||
LeaseDuration: metav1.Duration{Duration: 60 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 40 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 20 * time.Second}, | ||
}, | ||
}, | ||
{ | ||
desc: "should not alter when durations, name and namespace are provided", | ||
defaultName: "new-default-name", | ||
defaultNamespace: "new-default-namespace", | ||
inputConfig: configv1.LeaderElection{ | ||
Name: "original-name", | ||
Namespace: "original-namespace", | ||
LeaseDuration: metav1.Duration{Duration: 60 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 40 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 20 * time.Second}, | ||
}, | ||
expectedConfig: configv1.LeaderElection{ | ||
Name: "original-name", | ||
Namespace: "original-namespace", | ||
LeaseDuration: metav1.Duration{Duration: 60 * time.Second}, | ||
RenewDeadline: metav1.Duration{Duration: 40 * time.Second}, | ||
RetryPeriod: metav1.Duration{Duration: 20 * time.Second}, | ||
}, | ||
}, | ||
} | ||
for _, tc := range testCases { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
resultConfig := LeaderElectionDefaulting(tc.inputConfig, tc.defaultNamespace, tc.defaultName) | ||
|
||
// When testing in clusters, namespace is read from /var/run/secrets/kubernetes.io/serviceaccount/namespace in LeaderElectionDefaulting if none is provided. | ||
// We configure expectedConfig.Namespace to equal resultConfig.Namespace if no default or input namespace is provided | ||
// so we use the dynamic namespace read in from the environment | ||
if tc.defaultNamespace == "" && tc.inputConfig.Namespace == "" { | ||
tc.expectedConfig.Namespace = resultConfig.Namespace | ||
} | ||
|
||
if !reflect.DeepEqual(tc.expectedConfig, resultConfig) { | ||
t.Errorf("expected %#v, got %#v", tc.expectedConfig, resultConfig) | ||
} | ||
}) | ||
} | ||
} |
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