Skip to content

Commit 1afb01f

Browse files
authored
Simplify kubeconfig retrieval by using k0s kubeconfig command (#720)
* Simplify kubeconfig retrieval by using k0s kubeconfig command Signed-off-by: Kimmo Lehto <[email protected]> * Restore --kubeconfig-api-address functionality Signed-off-by: Kimmo Lehto <[email protected]> --------- Signed-off-by: Kimmo Lehto <[email protected]>
1 parent aaa01d2 commit 1afb01f

File tree

2 files changed

+25
-153
lines changed

2 files changed

+25
-153
lines changed

phase/get_kubeconfig.go

Lines changed: 25 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import (
44
"fmt"
55
"strings"
66

7-
"github.com/k0sproject/dig"
8-
"github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster"
7+
"github.com/k0sproject/rig/exec"
8+
log "github.com/sirupsen/logrus"
99
"gopkg.in/yaml.v2"
10-
"k8s.io/client-go/tools/clientcmd"
1110
)
1211

1312
// GetKubeconfig is a phase to get and dump the admin kubeconfig
@@ -16,108 +15,51 @@ type GetKubeconfig struct {
1615
APIAddress string
1716
}
1817

18+
type kubeconfig struct {
19+
Clusters []struct {
20+
Cluster struct {
21+
Server string `yaml:"server"`
22+
} `yaml:"cluster"`
23+
} `yaml:"clusters"`
24+
}
25+
1926
// Title for the phase
2027
func (p *GetKubeconfig) Title() string {
2128
return "Get admin kubeconfig"
2229
}
2330

24-
var readKubeconfig = func(h *cluster.Host) (string, error) {
25-
return h.Configurer.ReadFile(h, h.Configurer.KubeconfigPath(h, h.K0sDataDir()))
26-
}
27-
28-
var k0sConfig = func(h *cluster.Host) (dig.Mapping, error) {
29-
cfgContent, err := h.Configurer.ReadFile(h, h.Configurer.K0sConfigPath())
30-
if err != nil {
31-
return nil, fmt.Errorf("read k0s config from host: %w", err)
32-
}
33-
34-
var cfg dig.Mapping
35-
if err := yaml.Unmarshal([]byte(cfgContent), &cfg); err != nil {
36-
return nil, fmt.Errorf("unmarshal k0s config: %w", err)
37-
}
38-
39-
if err != nil {
40-
return nil, fmt.Errorf("parse k0s config: %w", err)
41-
}
42-
43-
return cfg, nil
44-
}
45-
4631
func (p *GetKubeconfig) DryRun() error {
4732
p.DryMsg(p.Config.Spec.Hosts.Controllers()[0], "get admin kubeconfig")
4833
return nil
4934
}
5035

5136
// Run the phase
5237
func (p *GetKubeconfig) Run() error {
53-
h := p.Config.Spec.Hosts.Controllers()[0]
54-
55-
cfg, err := k0sConfig(h)
56-
if err != nil {
57-
return err
58-
}
38+
h := p.Config.Spec.K0sLeader()
5939

60-
output, err := readKubeconfig(h)
40+
output, err := h.ExecOutput(h.Configurer.K0sCmdf("kubeconfig admin"), exec.Sudo(h))
6141
if err != nil {
6242
return fmt.Errorf("read kubeconfig from host: %w", err)
6343
}
6444

65-
if p.APIAddress == "" {
66-
// the controller admin.conf is aways pointing to localhost, thus we need to change the address
67-
// something usable from outside
68-
address := h.Address()
69-
if a, ok := cfg.Dig("spec", "api", "externalAddress").(string); ok && a != "" {
70-
address = a
45+
if p.APIAddress != "" {
46+
log.Debugf("%s: replacing api address with %v", h, p.APIAddress)
47+
kubeconf := kubeconfig{}
48+
if err := yaml.Unmarshal([]byte(output), &kubeconf); err != nil {
49+
return fmt.Errorf("unmarshal kubeconfig: %w", err)
7150
}
72-
73-
port := 6443
74-
if p, ok := cfg.Dig("spec", "api", "port").(int); ok && p != 0 {
75-
port = p
51+
if len(kubeconf.Clusters) == 0 {
52+
return fmt.Errorf("no clusters found in kubeconfig")
7653
}
77-
78-
if strings.Contains(address, ":") {
79-
p.APIAddress = fmt.Sprintf("https://[%s]:%d", address, port)
80-
} else {
81-
p.APIAddress = fmt.Sprintf("https://%s:%d", address, port)
54+
server := kubeconf.Clusters[0].Cluster.Server
55+
if server == "" {
56+
return fmt.Errorf("no server found in kubeconfig")
8257
}
58+
log.Debugf("%s: replacing %v with %v", h, server, p.APIAddress)
59+
output = strings.ReplaceAll(output, server, p.APIAddress)
8360
}
8461

85-
cfgString, err := kubeConfig(output, p.Config.Metadata.Name, p.APIAddress)
86-
if err != nil {
87-
return err
88-
}
89-
90-
p.Config.Metadata.Kubeconfig = cfgString
62+
p.Config.Metadata.Kubeconfig = output
9163

9264
return nil
9365
}
94-
95-
// kubeConfig reads in the raw kubeconfig and changes the given address
96-
// and cluster name into it
97-
func kubeConfig(raw string, name string, address string) (string, error) {
98-
cfg, err := clientcmd.Load([]byte(raw))
99-
if err != nil {
100-
return "", err
101-
}
102-
103-
cfg.Clusters[name] = cfg.Clusters["local"]
104-
delete(cfg.Clusters, "local")
105-
cfg.Clusters[name].Server = address
106-
107-
cfg.Contexts[name] = cfg.Contexts["Default"]
108-
delete(cfg.Contexts, "Default")
109-
cfg.Contexts[name].Cluster = name
110-
cfg.Contexts[name].AuthInfo = "admin"
111-
112-
cfg.CurrentContext = name
113-
114-
cfg.AuthInfos["admin"] = cfg.AuthInfos["user"]
115-
delete(cfg.AuthInfos, "user")
116-
117-
out, err := clientcmd.Write(*cfg)
118-
if err != nil {
119-
return "", err
120-
}
121-
122-
return string(out), nil
123-
}

phase/get_kubeconfig_test.go

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)