Files
k3k/pkg/controller/kubeconfig/kubeconfig.go
T
Hussein Galal d19f0f9ca6 virtual-kubelet controller integration (#130)
* Virtual kubelet controller integration

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Add k3k-kubelet image to the release workflow

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Add k3k-kubelet image to the release workflow

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Fix build/release workflow

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Remove pkg directory in k3k-kubelet

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* rename Type to Config

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Move the kubelet and config outside of pkg

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* fix comments

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Fix naming throughout the package

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Fix comments

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* more fixes to naming

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* fixes

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* fixes

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* fixes

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* fixes

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

---------

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>
2024-10-21 22:54:08 +03:00

110 lines
2.9 KiB
Go

package kubeconfig
import (
"context"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"time"
certutil "github.com/rancher/dynamiclistener/cert"
"github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
"github.com/rancher/k3k/pkg/controller"
"github.com/rancher/k3k/pkg/controller/cluster/server"
"github.com/rancher/k3k/pkg/controller/cluster/server/bootstrap"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type KubeConfig struct {
AltNames certutil.AltNames
CN string
ORG []string
ExpiryDate time.Duration
}
func (k *KubeConfig) Extract(ctx context.Context, client client.Client, cluster *v1alpha1.Cluster, hostServerIP string) ([]byte, error) {
nn := types.NamespacedName{
Name: controller.SafeConcatNameWithPrefix(cluster.Name, "bootstrap"),
Namespace: cluster.Namespace,
}
var bootstrapSecret v1.Secret
if err := client.Get(ctx, nn, &bootstrapSecret); err != nil {
return nil, err
}
bootstrapData := bootstrapSecret.Data["bootstrap"]
if bootstrapData == nil {
return nil, errors.New("empty bootstrap")
}
var bootstrap bootstrap.ControlRuntimeBootstrap
if err := json.Unmarshal(bootstrapData, &bootstrap); err != nil {
return nil, err
}
adminCert, adminKey, err := CreateClientCertKey(
k.CN, k.ORG,
&k.AltNames, []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, k.ExpiryDate,
bootstrap.ClientCA.Content,
bootstrap.ClientCAKey.Content)
if err != nil {
return nil, err
}
// get the server service to extract the right IP
nn = types.NamespacedName{
Name: server.ServiceName(cluster.Name),
Namespace: cluster.Namespace,
}
var k3kService v1.Service
if err := client.Get(ctx, nn, &k3kService); err != nil {
return nil, err
}
url := fmt.Sprintf("https://%s:%d", k3kService.Spec.ClusterIP, server.ServerPort)
if k3kService.Spec.Type == v1.ServiceTypeNodePort {
nodePort := k3kService.Spec.Ports[0].NodePort
url = fmt.Sprintf("https://%s:%d", hostServerIP, nodePort)
}
kubeconfigData, err := kubeconfig(url, []byte(bootstrap.ServerCA.Content), adminCert, adminKey)
if err != nil {
return nil, err
}
return kubeconfigData, nil
}
func kubeconfig(url string, serverCA, clientCert, clientKey []byte) ([]byte, error) {
config := clientcmdapi.NewConfig()
cluster := clientcmdapi.NewCluster()
cluster.CertificateAuthorityData = serverCA
cluster.Server = url
authInfo := clientcmdapi.NewAuthInfo()
authInfo.ClientCertificateData = clientCert
authInfo.ClientKeyData = clientKey
context := clientcmdapi.NewContext()
context.AuthInfo = "default"
context.Cluster = "default"
config.Clusters["default"] = cluster
config.AuthInfos["default"] = authInfo
config.Contexts["default"] = context
config.CurrentContext = "default"
kubeconfig, err := clientcmd.Write(*config)
if err != nil {
return nil, err
}
return kubeconfig, nil
}