Skip to content

Commit 9f32854

Browse files
authored
Merge pull request kubernetes#94879 from knight42/refactor/kubeadm-alpha-kubeconfig
kubeadm: make "alpha kubeconfig user" accept --config
2 parents b03a4ac + 36eb74a commit 9f32854

File tree

3 files changed

+81
-44
lines changed

3 files changed

+81
-44
lines changed

cmd/kubeadm/app/cmd/alpha/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ go_test(
6767
"//cmd/kubeadm/test:go_default_library",
6868
"//cmd/kubeadm/test/cmd:go_default_library",
6969
"//cmd/kubeadm/test/kubeconfig:go_default_library",
70+
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
7071
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
7172
"//vendor/github.com/spf13/cobra:go_default_library",
7273
"//vendor/github.com/spf13/pflag:go_default_library",
7374
"//vendor/github.com/stretchr/testify/assert:go_default_library",
7475
"//vendor/github.com/stretchr/testify/require:go_default_library",
76+
"//vendor/sigs.k8s.io/yaml:go_default_library",
7577
],
7678
)

cmd/kubeadm/app/cmd/alpha/kubeconfig.go

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ package alpha
1919
import (
2020
"io"
2121

22-
"github.com/pkg/errors"
2322
"github.com/spf13/cobra"
24-
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
23+
2524
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
2625
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
2726
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
@@ -39,8 +38,8 @@ var (
3938
` + cmdutil.AlphaDisclaimer)
4039

4140
userKubeconfigExample = cmdutil.Examples(`
42-
# Output a kubeconfig file for an additional user named foo
43-
kubeadm alpha kubeconfig user --client-name=foo
41+
# Output a kubeconfig file for an additional user named foo using a kubeadm config file bar
42+
kubeadm alpha kubeconfig user --client-name=foo --config=bar
4443
`)
4544
)
4645

@@ -62,12 +61,10 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
6261
initCfg := &kubeadmapiv1beta2.InitConfiguration{}
6362
clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{}
6463

65-
// Default values for the cobra help text
66-
kubeadmscheme.Scheme.Default(initCfg)
67-
kubeadmscheme.Scheme.Default(clusterCfg)
68-
69-
var token, clientName string
70-
var organizations []string
64+
var (
65+
token, clientName, cfgPath string
66+
organizations []string
67+
)
7168

7269
// Creates the UX Command
7370
cmd := &cobra.Command{
@@ -76,39 +73,31 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
7673
Long: userKubeconfigLongDesc,
7774
Example: userKubeconfigExample,
7875
RunE: func(cmd *cobra.Command, args []string) error {
79-
if clientName == "" {
80-
return errors.New("missing required argument --client-name")
81-
}
82-
8376
// This call returns the ready-to-use configuration based on the defaults populated by flags
84-
internalcfg, err := configutil.DefaultedInitConfiguration(initCfg, clusterCfg)
77+
internalCfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, initCfg, clusterCfg)
8578
if err != nil {
8679
return err
8780
}
8881

8982
// if the kubeconfig file for an additional user has to use a token, use it
9083
if token != "" {
91-
return kubeconfigphase.WriteKubeConfigWithToken(out, internalcfg, clientName, token)
84+
return kubeconfigphase.WriteKubeConfigWithToken(out, internalCfg, clientName, token)
9285
}
9386

9487
// Otherwise, write a kubeconfig file with a generate client cert
95-
return kubeconfigphase.WriteKubeConfigWithClientCert(out, internalcfg, clientName, organizations)
88+
return kubeconfigphase.WriteKubeConfigWithClientCert(out, internalCfg, clientName, organizations)
9689
},
9790
Args: cobra.NoArgs,
9891
}
9992

100-
// Add ClusterConfiguration backed flags to the command
101-
cmd.Flags().StringVar(&clusterCfg.CertificatesDir, options.CertificatesDir, clusterCfg.CertificatesDir, "The path where certificates are stored")
102-
cmd.Flags().StringVar(&clusterCfg.ClusterName, "cluster-name", clusterCfg.ClusterName, "Cluster name to be used in kubeconfig")
103-
104-
// Add InitConfiguration backed flags to the command
105-
cmd.Flags().StringVar(&initCfg.LocalAPIEndpoint.AdvertiseAddress, options.APIServerAdvertiseAddress, initCfg.LocalAPIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on")
106-
cmd.Flags().Int32Var(&initCfg.LocalAPIEndpoint.BindPort, options.APIServerBindPort, initCfg.LocalAPIEndpoint.BindPort, "The port the API server is accessible on")
93+
options.AddConfigFlag(cmd.Flags(), &cfgPath)
10794

10895
// Add command specific flags
10996
cmd.Flags().StringVar(&token, options.TokenStr, token, "The token that should be used as the authentication mechanism for this kubeconfig, instead of client certificates")
11097
cmd.Flags().StringVar(&clientName, "client-name", clientName, "The name of user. It will be used as the CN if client certificates are created")
11198
cmd.Flags().StringSliceVar(&organizations, "org", organizations, "The orgnizations of the client certificate. It will be used as the O if client certificates are created")
11299

100+
cmd.MarkFlagRequired(options.CfgPath)
101+
cmd.MarkFlagRequired("client-name")
113102
return cmd
114103
}

cmd/kubeadm/app/cmd/alpha/kubeconfig_test.go

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,61 @@ package alpha
1919
import (
2020
"bytes"
2121
"fmt"
22+
"io/ioutil"
2223
"os"
24+
"path/filepath"
2325
"testing"
2426

27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2528
"k8s.io/client-go/tools/clientcmd"
29+
"sigs.k8s.io/yaml"
30+
31+
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
2632
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
2733
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
2834
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
2935
kubeconfigtestutil "k8s.io/kubernetes/cmd/kubeadm/test/kubeconfig"
3036
)
3137

38+
func generateTestKubeadmConfig(dir, id, certDir, clusterName string) (string, error) {
39+
cfgPath := filepath.Join(dir, id)
40+
initCfg := kubeadmapiv1beta2.InitConfiguration{
41+
TypeMeta: metav1.TypeMeta{
42+
APIVersion: "kubeadm.k8s.io/v1beta2",
43+
Kind: "InitConfiguration",
44+
},
45+
LocalAPIEndpoint: kubeadmapiv1beta2.APIEndpoint{
46+
AdvertiseAddress: "1.2.3.4",
47+
BindPort: 1234,
48+
},
49+
}
50+
clusterCfg := kubeadmapiv1beta2.ClusterConfiguration{
51+
TypeMeta: metav1.TypeMeta{
52+
APIVersion: "kubeadm.k8s.io/v1beta2",
53+
Kind: "ClusterConfiguration",
54+
},
55+
CertificatesDir: certDir,
56+
ClusterName: clusterName,
57+
KubernetesVersion: "v1.19.0",
58+
}
59+
60+
var buf bytes.Buffer
61+
data, err := yaml.Marshal(&initCfg)
62+
if err != nil {
63+
return "", err
64+
}
65+
buf.Write(data)
66+
buf.WriteString("---\n")
67+
data, err = yaml.Marshal(&clusterCfg)
68+
if err != nil {
69+
return "", err
70+
}
71+
buf.Write(data)
72+
73+
err = ioutil.WriteFile(cfgPath, buf.Bytes(), 0644)
74+
return cfgPath, err
75+
}
76+
3277
func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) {
3378

3479
// Temporary folders for the test case
@@ -44,19 +89,12 @@ func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) {
4489
t.Fatalf("couldn't retrieve ca cert: %v", err)
4590
}
4691

47-
commonFlags := []string{
48-
"--apiserver-advertise-address=1.2.3.4",
49-
"--apiserver-bind-port=1234",
50-
"--client-name=myUser",
51-
fmt.Sprintf("--cert-dir=%s", pkidir),
52-
}
53-
5492
var tests = []struct {
5593
name string
5694
command string
95+
clusterName string
5796
withClientCert bool
5897
withToken bool
59-
withClusterName bool
6098
additionalFlags []string
6199
}{
62100
{
@@ -65,11 +103,10 @@ func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) {
65103
withClientCert: true,
66104
},
67105
{
68-
name: "user subCommand withClientCert",
69-
command: "user",
70-
withClientCert: true,
71-
withClusterName: true,
72-
additionalFlags: []string{"--cluster-name=my-cluster"},
106+
name: "user subCommand withClientCert",
107+
command: "user",
108+
withClientCert: true,
109+
clusterName: "my-cluster",
73110
},
74111
{
75112
name: "user subCommand withToken",
@@ -81,8 +118,8 @@ func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) {
81118
name: "user subCommand withToken",
82119
withToken: true,
83120
command: "user",
84-
withClusterName: true,
85-
additionalFlags: []string{"--token=123456", "--cluster-name=my-cluster"},
121+
clusterName: "my-cluster-with-token",
122+
additionalFlags: []string{"--token=123456"},
86123
},
87124
}
88125

@@ -93,18 +130,27 @@ func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) {
93130
// Get subcommands working in the temporary directory
94131
cmd := newCmdUserKubeConfig(buf)
95132

133+
cfgPath, err := generateTestKubeadmConfig(tmpdir, test.name, pkidir, test.clusterName)
134+
if err != nil {
135+
t.Fatalf("Failed to generate kubeadm config: %v", err)
136+
}
137+
138+
commonFlags := []string{
139+
"--client-name=myUser",
140+
fmt.Sprintf("--config=%s", cfgPath),
141+
}
142+
96143
// Execute the subcommand
97144
allFlags := append(commonFlags, test.additionalFlags...)
98145
cmd.SetArgs(allFlags)
99146
if err := cmd.Execute(); err != nil {
100-
t.Fatal("Could not execute subcommand")
147+
t.Fatalf("Could not execute subcommand: %v", err)
101148
}
102149

103150
// reads kubeconfig written to stdout
104151
config, err := clientcmd.Load(buf.Bytes())
105152
if err != nil {
106-
t.Errorf("couldn't read kubeconfig file from buffer: %v", err)
107-
return
153+
t.Fatalf("couldn't read kubeconfig file from buffer: %v", err)
108154
}
109155

110156
// checks that CLI flags are properly propagated
@@ -120,9 +166,9 @@ func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) {
120166
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithToken(t, config, "myUser", "123456")
121167
}
122168

123-
if test.withClusterName {
169+
if len(test.clusterName) > 0 {
124170
// checks that kubeconfig files have expected cluster name
125-
kubeconfigtestutil.AssertKubeConfigCurrentContextWithClusterName(t, config, "my-cluster")
171+
kubeconfigtestutil.AssertKubeConfigCurrentContextWithClusterName(t, config, test.clusterName)
126172
}
127173
})
128174
}

0 commit comments

Comments
 (0)