ContainerImage.Pinniped/internal/controller/issuerconfig/issuerconfig.go
Ryan Richard c6c2c525a6 Upgrade the linter and fix all new linter warnings
Also fix some tests that were broken by bumping golang and dependencies
in the previous commits.

Note that in addition to changes made to satisfy the linter which do not
impact the behavior of the code, this commit also adds ReadHeaderTimeout
to all usages of http.Server to satisfy the linter (and because it
seemed like a good suggestion).
2022-08-24 14:45:55 -07:00

87 lines
3.2 KiB
Go

// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package issuerconfig contains helpers for updating CredentialIssuer status entries.
package issuerconfig
import (
"context"
"fmt"
"sort"
apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
"go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
)
// Update a strategy on an existing CredentialIssuer, merging into any existing strategy entries.
func Update(ctx context.Context, client versioned.Interface, issuer *v1alpha1.CredentialIssuer, strategy v1alpha1.CredentialIssuerStrategy) error {
// Update the existing object to merge in the new strategy.
updated := issuer.DeepCopy()
mergeStrategy(&updated.Status, strategy)
// If the status has not changed, we're done.
if apiequality.Semantic.DeepEqual(issuer.Status, updated.Status) {
return nil
}
if _, err := client.ConfigV1alpha1().CredentialIssuers().UpdateStatus(ctx, updated, metav1.UpdateOptions{}); err != nil {
return fmt.Errorf("failed to update CredentialIssuer status: %w", err)
}
return nil
}
func mergeStrategy(configToUpdate *v1alpha1.CredentialIssuerStatus, strategy v1alpha1.CredentialIssuerStrategy) {
var existing *v1alpha1.CredentialIssuerStrategy
for i := range configToUpdate.Strategies {
if configToUpdate.Strategies[i].Type == strategy.Type {
existing = &configToUpdate.Strategies[i]
break
}
}
if existing != nil {
if !equalExceptLastUpdated(existing, &strategy) {
strategy.DeepCopyInto(existing)
}
} else {
configToUpdate.Strategies = append(configToUpdate.Strategies, strategy)
}
sort.Stable(sortableStrategies(configToUpdate.Strategies))
// Special case: the "TokenCredentialRequestAPI" data is mirrored into the deprecated status.kubeConfigInfo field.
if strategy.Frontend != nil && strategy.Frontend.Type == v1alpha1.TokenCredentialRequestAPIFrontendType {
configToUpdate.KubeConfigInfo = &v1alpha1.CredentialIssuerKubeConfigInfo{
Server: strategy.Frontend.TokenCredentialRequestAPIInfo.Server,
CertificateAuthorityData: strategy.Frontend.TokenCredentialRequestAPIInfo.CertificateAuthorityData,
}
}
}
// weights are a set of priorities for each strategy type.
var weights = map[v1alpha1.StrategyType]int{ //nolint:gochecknoglobals
v1alpha1.KubeClusterSigningCertificateStrategyType: 2, // most preferred strategy
v1alpha1.ImpersonationProxyStrategyType: 1,
// unknown strategy types will have weight 0 by default
}
type sortableStrategies []v1alpha1.CredentialIssuerStrategy
func (s sortableStrategies) Len() int { return len(s) }
func (s sortableStrategies) Less(i, j int) bool {
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] }
func equalExceptLastUpdated(s1, s2 *v1alpha1.CredentialIssuerStrategy) bool {
s1 = s1.DeepCopy()
s2 = s2.DeepCopy()
s1.LastUpdateTime = metav1.Time{}
s2.LastUpdateTime = metav1.Time{}
return apiequality.Semantic.DeepEqual(s1, s2)
}