ContainerImage.Pinniped/internal/controller/issuerconfig/kube_config_info_publisher.go

126 lines
3.8 KiB
Go
Raw Normal View History

// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
2020-08-20 17:54:15 +00:00
package issuerconfig
2020-08-20 17:54:15 +00:00
import (
"encoding/base64"
"fmt"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
corev1informers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/klog/v2"
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/concierge/config/v1alpha1"
pinnipedclientset "go.pinniped.dev/generated/1.19/client/concierge/clientset/versioned"
pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/plog"
2020-08-20 17:54:15 +00:00
)
const (
ClusterInfoNamespace = "kube-public"
2020-08-20 17:54:15 +00:00
clusterInfoName = "cluster-info"
clusterInfoConfigMapKey = "kubeconfig"
)
type kubeConigInfoPublisherController struct {
credentialIssuerNamespaceName string
credentialIssuerResourceName string
credentialIssuerLabels map[string]string
serverOverride *string
pinnipedClient pinnipedclientset.Interface
configMapInformer corev1informers.ConfigMapInformer
2020-08-20 17:54:15 +00:00
}
// NewKubeConfigInfoPublisherController returns a controller that syncs the
// configv1alpha1.CredentialIssuer.Status.KubeConfigInfo field with the cluster-info ConfigMap
// in the kube-public namespace.
func NewKubeConfigInfoPublisherController(
credentialIssuerNamespaceName string,
credentialIssuerResourceName string,
credentialIssuerLabels map[string]string,
2020-08-20 17:54:15 +00:00
serverOverride *string,
pinnipedClient pinnipedclientset.Interface,
configMapInformer corev1informers.ConfigMapInformer,
withInformer pinnipedcontroller.WithInformerOptionFunc,
) controllerlib.Controller {
return controllerlib.New(
controllerlib.Config{
2020-08-20 17:54:15 +00:00
Name: "publisher-controller",
Syncer: &kubeConigInfoPublisherController{
credentialIssuerResourceName: credentialIssuerResourceName,
credentialIssuerNamespaceName: credentialIssuerNamespaceName,
credentialIssuerLabels: credentialIssuerLabels,
serverOverride: serverOverride,
pinnipedClient: pinnipedClient,
configMapInformer: configMapInformer,
2020-08-20 17:54:15 +00:00
},
},
withInformer(
configMapInformer,
pinnipedcontroller.NameAndNamespaceExactMatchFilterFactory(clusterInfoName, ClusterInfoNamespace),
controllerlib.InformerOption{},
2020-08-20 17:54:15 +00:00
),
)
}
func (c *kubeConigInfoPublisherController) Sync(ctx controllerlib.Context) error {
2020-08-20 17:54:15 +00:00
configMap, err := c.configMapInformer.
Lister().
ConfigMaps(ClusterInfoNamespace).
Get(clusterInfoName)
notFound := k8serrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("failed to get %s configmap: %w", clusterInfoName, err)
}
if notFound {
plog.Debug(
2020-08-20 17:54:15 +00:00
"could not find config map",
"configmap",
klog.KRef(ClusterInfoNamespace, clusterInfoName),
)
return nil
}
kubeConfig, kubeConfigPresent := configMap.Data[clusterInfoConfigMapKey]
if !kubeConfigPresent {
plog.Debug("could not find kubeconfig configmap key")
2020-08-20 17:54:15 +00:00
return nil
}
config, err := clientcmd.Load([]byte(kubeConfig))
if err != nil {
plog.Debug("could not load kubeconfig configmap key")
return nil
}
2020-08-20 17:54:15 +00:00
var certificateAuthorityData, server string
for _, v := range config.Clusters {
certificateAuthorityData = base64.StdEncoding.EncodeToString(v.CertificateAuthorityData)
server = v.Server
break
}
if c.serverOverride != nil {
server = *c.serverOverride
}
updateServerAndCAFunc := func(c *configv1alpha1.CredentialIssuer) {
c.Status.KubeConfigInfo = &configv1alpha1.CredentialIssuerKubeConfigInfo{
Server: server,
CertificateAuthorityData: certificateAuthorityData,
}
}
return CreateOrUpdateCredentialIssuer(
ctx.Context,
c.credentialIssuerNamespaceName,
c.credentialIssuerResourceName,
c.credentialIssuerLabels,
c.pinnipedClient,
updateServerAndCAFunc,
)
2020-08-20 17:54:15 +00:00
}