diff --git a/cli/cmds/cluster_create.go b/cli/cmds/cluster_create.go index 266a1bb2..2103bc4a 100644 --- a/cli/cmds/cluster_create.go +++ b/cli/cmds/cluster_create.go @@ -142,7 +142,7 @@ func createAction(appCtx *AppContext, config *CreateConfig) cli.ActionFunc { var kubeconfig *clientcmdapi.Config if err := retry.OnError(availableBackoff, apierrors.IsNotFound, func() error { - kubeconfig, err = cfg.Extract(ctx, client, cluster, host[0]) + kubeconfig, err = cfg.Generate(ctx, client, cluster, host[0]) return err }); err != nil { return err diff --git a/cli/cmds/kubeconfig.go b/cli/cmds/kubeconfig.go index 4022ffd2..8a28e7e9 100644 --- a/cli/cmds/kubeconfig.go +++ b/cli/cmds/kubeconfig.go @@ -148,7 +148,7 @@ func generate(appCtx *AppContext) cli.ActionFunc { var kubeconfig *clientcmdapi.Config if err := retry.OnError(controller.Backoff, apierrors.IsNotFound, func() error { - kubeconfig, err = cfg.Extract(ctx, client, &cluster, host[0]) + kubeconfig, err = cfg.Generate(ctx, client, &cluster, host[0]) return err }); err != nil { return err diff --git a/pkg/controller/cluster/cluster.go b/pkg/controller/cluster/cluster.go index 4243ff2f..fcf7f373 100644 --- a/pkg/controller/cluster/cluster.go +++ b/pkg/controller/cluster/cluster.go @@ -15,6 +15,7 @@ import ( "github.com/rancher/k3k/pkg/controller/cluster/agent" "github.com/rancher/k3k/pkg/controller/cluster/server" "github.com/rancher/k3k/pkg/controller/cluster/server/bootstrap" + "github.com/rancher/k3k/pkg/controller/kubeconfig" "github.com/rancher/k3k/pkg/controller/policy" apps "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" @@ -25,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/discovery" + "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/workqueue" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -289,6 +291,10 @@ func (c *ClusterReconciler) reconcileCluster(ctx context.Context, cluster *v1alp return err } + if err := c.ensureKubeconfigSecret(ctx, cluster, serviceIP, token); err != nil { + return err + } + return c.bindNodeProxyClusterRole(ctx, cluster) } @@ -324,6 +330,45 @@ func (c *ClusterReconciler) ensureBootstrapSecret(ctx context.Context, cluster * return err } +// ensureKubeconfigSecret will create or update the Secret containing the kubeconfig data from the k3s server +func (c *ClusterReconciler) ensureKubeconfigSecret(ctx context.Context, cluster *v1alpha1.Cluster, serviceIP, token string) error { + log := ctrl.LoggerFrom(ctx) + log.Info("ensuring kubeconfig secret") + + adminKubeconfig := kubeconfig.New() + + kubeconfig, err := adminKubeconfig.Generate(ctx, c.Client, cluster, serviceIP) + if err != nil { + return err + } + + kubeconfigData, err := clientcmd.Write(*kubeconfig) + if err != nil { + return err + } + + kubeconfigSecret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: controller.SafeConcatNameWithPrefix(cluster.Name, "kubeconfig"), + Namespace: cluster.Namespace, + }, + } + + _, err = controllerutil.CreateOrUpdate(ctx, c.Client, kubeconfigSecret, func() error { + if err := controllerutil.SetControllerReference(cluster, kubeconfigSecret, c.Scheme); err != nil { + return err + } + + kubeconfigSecret.Data = map[string][]byte{ + "kubeconfig.yaml": kubeconfigData, + } + + return nil + }) + + return err +} + func (c *ClusterReconciler) createClusterConfigs(ctx context.Context, cluster *v1alpha1.Cluster, server *server.Server, serviceIP string) error { // create init node config initServerConfig, err := server.Config(true, serviceIP) diff --git a/pkg/controller/kubeconfig/kubeconfig.go b/pkg/controller/kubeconfig/kubeconfig.go index eebfe1ba..20a03619 100644 --- a/pkg/controller/kubeconfig/kubeconfig.go +++ b/pkg/controller/kubeconfig/kubeconfig.go @@ -37,7 +37,7 @@ func New() *KubeConfig { } } -func (k *KubeConfig) Extract(ctx context.Context, client client.Client, cluster *v1alpha1.Cluster, hostServerIP string) (*clientcmdapi.Config, error) { +func (k *KubeConfig) Generate(ctx context.Context, client client.Client, cluster *v1alpha1.Cluster, hostServerIP string) (*clientcmdapi.Config, error) { bootstrapData, err := bootstrap.GetFromSecret(ctx, client, cluster) if err != nil { return nil, err diff --git a/tests/common_test.go b/tests/common_test.go index ee5d6c22..e0fbea90 100644 --- a/tests/common_test.go +++ b/tests/common_test.go @@ -191,7 +191,7 @@ func NewVirtualK8sClientAndConfig(cluster *v1alpha1.Cluster) (*kubernetes.Client vKubeconfig := kubeconfig.New() kubeletAltName := fmt.Sprintf("k3k-%s-kubelet", cluster.Name) vKubeconfig.AltNames = certs.AddSANs([]string{hostIP, kubeletAltName}) - config, err = vKubeconfig.Extract(ctx, k8sClient, cluster, hostIP) + config, err = vKubeconfig.Generate(ctx, k8sClient, cluster, hostIP) return err }). WithTimeout(time.Minute * 2).