Sort CredentialIssuer strategies in preferred order.

This updates our issuerconfig.UpdateStrategy to sort strategies according to a weighted preference.
The TokenCredentialRequest API strategy is preffered, followed by impersonation proxy, followed by any other unknown types.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
Matt Moyer 2021-03-03 14:03:27 -06:00
parent 0799a538dc
commit f4fcb9bde6
No known key found for this signature in database
GPG Key ID: EAE88AD172C5AE2D
3 changed files with 48 additions and 5 deletions

View File

@ -2116,7 +2116,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
requireLoadBalancerWasCreated(kubeAPIClient.Actions()[1]) requireLoadBalancerWasCreated(kubeAPIClient.Actions()[1])
requireCASecretWasCreated(kubeAPIClient.Actions()[2]) requireCASecretWasCreated(kubeAPIClient.Actions()[2])
credentialIssuer := getCredentialIssuer() credentialIssuer := getCredentialIssuer()
r.Equal([]v1alpha1.CredentialIssuerStrategy{newPendingStrategy(), preExistingStrategy}, credentialIssuer.Status.Strategies) r.Equal([]v1alpha1.CredentialIssuerStrategy{preExistingStrategy, newPendingStrategy()}, credentialIssuer.Status.Strategies)
}) })
}) })
}, spec.Parallel(), spec.Report(report.Terminal{})) }, spec.Parallel(), spec.Report(report.Terminal{}))

View File

@ -52,9 +52,21 @@ func mergeStrategy(configToUpdate *v1alpha1.CredentialIssuerStatus, strategy v1a
} }
} }
// TODO: sort strategies by server preference rather than alphanumerically by type. // weights are a set of priorities for each strategy type.
//nolint: gochecknoglobals
var weights = map[v1alpha1.StrategyType]int{
v1alpha1.KubeClusterSigningCertificateStrategyType: 2, // most preferred strategy
v1alpha1.ImpersonationProxyStrategyType: 1,
// unknown strategy types will have weight 0 by default
}
type sortableStrategies []v1alpha1.CredentialIssuerStrategy type sortableStrategies []v1alpha1.CredentialIssuerStrategy
func (s sortableStrategies) Len() int { return len(s) } func (s sortableStrategies) Len() int { return len(s) }
func (s sortableStrategies) Less(i, j int) bool { return s[i].Type < s[j].Type } func (s sortableStrategies) Less(i, j int) bool {
func (s sortableStrategies) Swap(i, j int) { s[i], s[j] = s[j], s[i] } if wi, wj := weights[s[i].Type], weights[s[j].Type]; wi != wj {
return wi > wj
}
return s[i].Type < s[j].Type
}
func (s sortableStrategies) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

View File

@ -4,9 +4,13 @@
package issuerconfig package issuerconfig
import ( import (
"math/rand"
"sort"
"testing" "testing"
"testing/quick"
"time" "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -185,3 +189,30 @@ func TestMergeStrategy(t *testing.T) {
}) })
} }
} }
func TestStrategySorting(t *testing.T) {
expected := []v1alpha1.CredentialIssuerStrategy{
{Type: v1alpha1.KubeClusterSigningCertificateStrategyType},
{Type: v1alpha1.ImpersonationProxyStrategyType},
{Type: "Type1"},
{Type: "Type2"},
{Type: "Type3"},
}
require.NoError(t, quick.Check(func(seed int64) bool {
// Create a randomly shuffled copy of the expected output.
//nolint:gosec // this is not meant to be a secure random, just a seeded RNG for shuffling deterministically
rng := rand.New(rand.NewSource(seed))
output := make([]v1alpha1.CredentialIssuerStrategy, len(expected))
copy(output, expected)
rng.Shuffle(
len(output),
func(i, j int) { output[i], output[j] = output[j], output[i] },
)
// Sort it using the code under test.
sort.Stable(sortableStrategies(output))
// Assert that it's sorted back to the expected output order.
return assert.Equal(t, expected, output)
}, nil))
}