From 88df65b2cdc63812bff7305e7d836ebca079884e Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Mon, 27 May 2024 13:53:24 +0300 Subject: [PATCH] Simplify kubeconfig retrieval by using k0s kubeconfig command Signed-off-by: Kimmo Lehto --- phase/get_kubeconfig.go | 94 ++---------------------------------- phase/get_kubeconfig_test.go | 70 --------------------------- 2 files changed, 4 insertions(+), 160 deletions(-) delete mode 100644 phase/get_kubeconfig_test.go diff --git a/phase/get_kubeconfig.go b/phase/get_kubeconfig.go index 93853c08..ef29c79a 100644 --- a/phase/get_kubeconfig.go +++ b/phase/get_kubeconfig.go @@ -2,12 +2,8 @@ package phase import ( "fmt" - "strings" - "github.com/k0sproject/dig" - "github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster" - "gopkg.in/yaml.v2" - "k8s.io/client-go/tools/clientcmd" + "github.com/k0sproject/rig/exec" ) // GetKubeconfig is a phase to get and dump the admin kubeconfig @@ -21,28 +17,6 @@ func (p *GetKubeconfig) Title() string { return "Get admin kubeconfig" } -var readKubeconfig = func(h *cluster.Host) (string, error) { - return h.Configurer.ReadFile(h, h.Configurer.KubeconfigPath(h, h.K0sDataDir())) -} - -var k0sConfig = func(h *cluster.Host) (dig.Mapping, error) { - cfgContent, err := h.Configurer.ReadFile(h, h.Configurer.K0sConfigPath()) - if err != nil { - return nil, fmt.Errorf("read k0s config from host: %w", err) - } - - var cfg dig.Mapping - if err := yaml.Unmarshal([]byte(cfgContent), &cfg); err != nil { - return nil, fmt.Errorf("unmarshal k0s config: %w", err) - } - - if err != nil { - return nil, fmt.Errorf("parse k0s config: %w", err) - } - - return cfg, nil -} - func (p *GetKubeconfig) DryRun() error { p.DryMsg(p.Config.Spec.Hosts.Controllers()[0], "get admin kubeconfig") return nil @@ -50,74 +24,14 @@ func (p *GetKubeconfig) DryRun() error { // Run the phase func (p *GetKubeconfig) Run() error { - h := p.Config.Spec.Hosts.Controllers()[0] - - cfg, err := k0sConfig(h) - if err != nil { - return err - } + h := p.Config.Spec.K0sLeader() - output, err := readKubeconfig(h) + output, err := h.ExecOutput(h.Configurer.K0sCmdf("kubeconfig admin"), exec.Sudo(h)) if err != nil { return fmt.Errorf("read kubeconfig from host: %w", err) } - if p.APIAddress == "" { - // the controller admin.conf is aways pointing to localhost, thus we need to change the address - // something usable from outside - address := h.Address() - if a, ok := cfg.Dig("spec", "api", "externalAddress").(string); ok && a != "" { - address = a - } - - port := 6443 - if p, ok := cfg.Dig("spec", "api", "port").(int); ok && p != 0 { - port = p - } - - if strings.Contains(address, ":") { - p.APIAddress = fmt.Sprintf("https://[%s]:%d", address, port) - } else { - p.APIAddress = fmt.Sprintf("https://%s:%d", address, port) - } - } - - cfgString, err := kubeConfig(output, p.Config.Metadata.Name, p.APIAddress) - if err != nil { - return err - } - - p.Config.Metadata.Kubeconfig = cfgString + p.Config.Metadata.Kubeconfig = output return nil } - -// kubeConfig reads in the raw kubeconfig and changes the given address -// and cluster name into it -func kubeConfig(raw string, name string, address string) (string, error) { - cfg, err := clientcmd.Load([]byte(raw)) - if err != nil { - return "", err - } - - cfg.Clusters[name] = cfg.Clusters["local"] - delete(cfg.Clusters, "local") - cfg.Clusters[name].Server = address - - cfg.Contexts[name] = cfg.Contexts["Default"] - delete(cfg.Contexts, "Default") - cfg.Contexts[name].Cluster = name - cfg.Contexts[name].AuthInfo = "admin" - - cfg.CurrentContext = name - - cfg.AuthInfos["admin"] = cfg.AuthInfos["user"] - delete(cfg.AuthInfos, "user") - - out, err := clientcmd.Write(*cfg) - if err != nil { - return "", err - } - - return string(out), nil -} diff --git a/phase/get_kubeconfig_test.go b/phase/get_kubeconfig_test.go deleted file mode 100644 index cb42fc64..00000000 --- a/phase/get_kubeconfig_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package phase - -import ( - "strings" - "testing" - - "github.com/k0sproject/dig" - "github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1" - "github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster" - "github.com/k0sproject/rig" - "github.com/stretchr/testify/require" - "k8s.io/client-go/tools/clientcmd" -) - -func fakeReader(h *cluster.Host) (string, error) { - return strings.ReplaceAll(`apiVersion: v1 -clusters: -- cluster: - server: https://localhost:6443 - name: local -contexts: -- context: - cluster: local - user: user - name: Default -current-context: Default -kind: Config -preferences: {} -users: -- name: user - user: -`, "\t", " "), nil -} - -func TestGetKubeconfig(t *testing.T) { - cfg := &v1beta1.Cluster{ - Metadata: &v1beta1.ClusterMetadata{ - Name: "k0s", - }, - Spec: &cluster.Spec{ - K0s: &cluster.K0s{Config: dig.Mapping{}}, - Hosts: []*cluster.Host{ - {Role: "controller", Connection: rig.Connection{SSH: &rig.SSH{Address: "10.0.0.1", Port: 22}}}, - }, - }, - } - - origReadKubeconfig := readKubeconfig - defer func() { readKubeconfig = origReadKubeconfig }() - readKubeconfig = fakeReader - - origK0sConfig := k0sConfig - defer func() { k0sConfig = origK0sConfig }() - k0sConfig = func(h *cluster.Host) (dig.Mapping, error) { - return cfg.Spec.K0s.Config, nil - } - - p := GetKubeconfig{GenericPhase: GenericPhase{Config: cfg}} - require.NoError(t, p.Run()) - conf, err := clientcmd.Load([]byte(cfg.Metadata.Kubeconfig)) - require.NoError(t, err) - require.Equal(t, "https://10.0.0.1:6443", conf.Clusters["k0s"].Server) - - cfg.Spec.Hosts[0].Connection.SSH.Address = "abcd:efgh:ijkl:mnop" - p.APIAddress = "" - require.NoError(t, p.Run()) - conf, err = clientcmd.Load([]byte(cfg.Metadata.Kubeconfig)) - require.NoError(t, err) - require.Equal(t, "https://[abcd:efgh:ijkl:mnop]:6443", conf.Clusters["k0s"].Server) -}