mirror of
https://github.com/rancher/k3k.git
synced 2026-04-05 10:16:56 +00:00
* adding scripts for asciidoc cli generation * fix small typos to align to existing docs * added pandoc * pandoc check
154 lines
4.1 KiB
Go
154 lines
4.1 KiB
Go
package cmds
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
"k8s.io/apiserver/pkg/authentication/user"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
"k8s.io/client-go/util/retry"
|
|
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
|
|
|
"github.com/rancher/k3k/pkg/apis/k3k.io/v1beta1"
|
|
"github.com/rancher/k3k/pkg/controller"
|
|
"github.com/rancher/k3k/pkg/controller/certs"
|
|
"github.com/rancher/k3k/pkg/controller/kubeconfig"
|
|
)
|
|
|
|
type GenerateKubeconfigConfig struct {
|
|
name string
|
|
configName string
|
|
cn string
|
|
org []string
|
|
altNames []string
|
|
expirationDays int64
|
|
kubeconfigServerHost string
|
|
}
|
|
|
|
func NewKubeconfigCmd(appCtx *AppContext) *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "kubeconfig",
|
|
Short: "Manage kubeconfig for clusters.",
|
|
}
|
|
|
|
cmd.AddCommand(
|
|
NewKubeconfigGenerateCmd(appCtx),
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func NewKubeconfigGenerateCmd(appCtx *AppContext) *cobra.Command {
|
|
cfg := &GenerateKubeconfigConfig{}
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "generate",
|
|
Short: "Generate kubeconfig for clusters.",
|
|
RunE: generate(appCtx, cfg),
|
|
Args: cobra.NoArgs,
|
|
}
|
|
|
|
CobraFlagNamespace(appCtx, cmd.Flags())
|
|
generateKubeconfigFlags(cmd, cfg)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func generateKubeconfigFlags(cmd *cobra.Command, cfg *GenerateKubeconfigConfig) {
|
|
cmd.Flags().StringVar(&cfg.name, "name", "", "cluster name")
|
|
cmd.Flags().StringVar(&cfg.configName, "config-name", "", "the name of the generated kubeconfig file")
|
|
cmd.Flags().StringVar(&cfg.cn, "cn", controller.AdminCommonName, "Common name (CN) of the generated certificates for the kubeconfig")
|
|
cmd.Flags().StringSliceVar(&cfg.org, "org", nil, "Organization name (ORG) of the generated certificates for the kubeconfig")
|
|
cmd.Flags().StringSliceVar(&cfg.altNames, "altNames", nil, "altNames of the generated certificates for the kubeconfig")
|
|
cmd.Flags().Int64Var(&cfg.expirationDays, "expiration-days", 365, "Expiration date of the certificates used for the kubeconfig")
|
|
cmd.Flags().StringVar(&cfg.kubeconfigServerHost, "kubeconfig-server", "", "override the kubeconfig server host")
|
|
}
|
|
|
|
func generate(appCtx *AppContext, cfg *GenerateKubeconfigConfig) func(cmd *cobra.Command, args []string) error {
|
|
return func(cmd *cobra.Command, args []string) error {
|
|
ctx := context.Background()
|
|
client := appCtx.Client
|
|
|
|
clusterKey := types.NamespacedName{
|
|
Name: cfg.name,
|
|
Namespace: appCtx.Namespace(cfg.name),
|
|
}
|
|
|
|
var cluster v1beta1.Cluster
|
|
|
|
if err := client.Get(ctx, clusterKey, &cluster); err != nil {
|
|
return err
|
|
}
|
|
|
|
url, err := url.Parse(appCtx.RestConfig.Host)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
host := strings.Split(url.Host, ":")
|
|
if cfg.kubeconfigServerHost != "" {
|
|
host = []string{cfg.kubeconfigServerHost}
|
|
cfg.altNames = append(cfg.altNames, cfg.kubeconfigServerHost)
|
|
}
|
|
|
|
certAltNames := certs.AddSANs(cfg.altNames)
|
|
|
|
if len(cfg.org) == 0 {
|
|
cfg.org = []string{user.SystemPrivilegedGroup}
|
|
}
|
|
|
|
kubeCfg := kubeconfig.KubeConfig{
|
|
CN: cfg.cn,
|
|
ORG: cfg.org,
|
|
ExpiryDate: time.Hour * 24 * time.Duration(cfg.expirationDays),
|
|
AltNames: certAltNames,
|
|
}
|
|
|
|
logrus.Infof("waiting for cluster to be available..")
|
|
|
|
var kubeconfig *clientcmdapi.Config
|
|
|
|
if err := retry.OnError(controller.Backoff, apierrors.IsNotFound, func() error {
|
|
kubeconfig, err = kubeCfg.Generate(ctx, client, &cluster, host[0], 0)
|
|
return err
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
|
|
return writeKubeconfigFile(&cluster, kubeconfig, cfg.configName)
|
|
}
|
|
}
|
|
|
|
func writeKubeconfigFile(cluster *v1beta1.Cluster, kubeconfig *clientcmdapi.Config, configName string) error {
|
|
if configName == "" {
|
|
configName = cluster.Namespace + "-" + cluster.Name + "-kubeconfig.yaml"
|
|
}
|
|
|
|
pwd, err := os.Getwd()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
logrus.Infof(`You can start using the cluster with:
|
|
|
|
export KUBECONFIG=%s
|
|
kubectl cluster-info
|
|
`, filepath.Join(pwd, configName))
|
|
|
|
kubeconfigData, err := clientcmd.Write(*kubeconfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.WriteFile(configName, kubeconfigData, 0o644)
|
|
}
|