Skip to content

Commit 9ec52fc

Browse files
authored
Merge pull request kubernetes#128283 from bzsuni/bz/ut/kubeadm
kubeadm: Add UT for cmd/kubeadm/app/cmd/util/join.go
2 parents 1148e5e + 80fe671 commit 9ec52fc

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package util
18+
19+
import (
20+
"encoding/base64"
21+
"os"
22+
"path/filepath"
23+
"testing"
24+
25+
"github.com/stretchr/testify/require"
26+
27+
"k8s.io/client-go/tools/clientcmd"
28+
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
29+
)
30+
31+
type testKubeConfigSpec struct {
32+
certificateAuthorityData string
33+
certificateAuthorityFile string
34+
server string
35+
clusterName string
36+
contextName string
37+
user string
38+
}
39+
40+
func generateTestKubeConfig(spec testKubeConfigSpec) *clientcmdapi.Config {
41+
cluster := clientcmdapi.NewCluster()
42+
43+
if spec.certificateAuthorityData != "" {
44+
decodedData, _ := base64.StdEncoding.DecodeString(spec.certificateAuthorityData)
45+
cluster.CertificateAuthorityData = decodedData
46+
} else if spec.certificateAuthorityFile != "" {
47+
cluster.CertificateAuthority = spec.certificateAuthorityFile
48+
}
49+
50+
cluster.Server = spec.server
51+
52+
context := clientcmdapi.NewContext()
53+
context.Cluster = spec.clusterName
54+
context.AuthInfo = spec.user
55+
56+
return &clientcmdapi.Config{
57+
Clusters: map[string]*clientcmdapi.Cluster{
58+
spec.clusterName: cluster,
59+
},
60+
Contexts: map[string]*clientcmdapi.Context{
61+
spec.contextName: context,
62+
},
63+
CurrentContext: spec.contextName,
64+
}
65+
}
66+
67+
func generateValidKubeConfig() *clientcmdapi.Config {
68+
return generateTestKubeConfig(testKubeConfigSpec{
69+
certificateAuthorityData: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNU1URXlNREF3TkRrME1sb1hEVEk1TVRFeE56QXdORGswTWxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTXFRCmN0RUN6QTh5RlN1Vll1cE9VWWdyVG1mUWVLZS85QmFEV2FnYXE3b3c5K0kySXZzZldGdmxyRDhRUXI4c2VhNnEKeGpxN1RWNjdWYjRSeEJhb1lEQSt5STV2SWN1aldVeFVMdW42NGx1M1E2aUMxc2oyVW5tVXBJZGdhelJYWEVrWgp2eEE2RWJBbm94QTArbEJPbjFDWldsMjNJUTRzNzBvMmhaN3dJcC92ZXZCODhSUlJqcXR2Z2M1ZWxzanNibURGCkxTN0wxWnV5ZThjNmdTOTNiUitWalZtU0lmcjFJRXEwNzQ4dElJeVhqQVZDV1BWQ3Z1UDQxTWxmUGMvSlZwWkQKdUQyK3BPNlpZUkVjZEFuT2YyZUQ0L2VMT01La280TDFkU0Z5OUpLTTVQTG5PQzBaazBBWU9kMXZTOERUQWZ4agpYUEVJWThPQllGaGxzeGY0VEU4Q0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFIL09ZcTh6eWwxK3pTVG11b3czeUkvMTVQTDEKZGw4aEI3SUtuWk5XbUMvTFRkbS8rbm9oM1NiMUlkUnY2SGtLZy9HVW4wVU11UlVuZ0xoanUzRU80b3pKUFFjWApxdWF4emdtVEtOV0o2RXJEdlJ2V2hHWDBaY2JkQmZaditkb3d5UnF6ZDVubEo0OWhDK05ydEZGUXE2UDA1QlluCjdTZW1ndXFlWG1Yd0lqMlNhKzFEZVI2bFJtOW84c2hBWWpueVRoVUZxYU1uMThrSTNTQU5KNXZrLzNERnJQRU8KQ0tDOUV6Rmt1Mmt1eGcyZE0xMlBiUkdaUTJvMEs2SEVaZ3JySUtUUE95M29jYjhyOU0wYVNGaGpPVi9OcUdBNApTYXVwWFNXNlhmdklpL1VIb0liVTNwTmNzblVKR25RZlF2aXA5NVhLay9ncWNVcittNTB2eGd1bXh0QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==",
70+
server: "test-server:6443",
71+
clusterName: "somecluster",
72+
contextName: "test@somecluster",
73+
user: "test",
74+
})
75+
}
76+
77+
func generateMissingCAKubeConfig() *clientcmdapi.Config {
78+
return generateTestKubeConfig(testKubeConfigSpec{
79+
server: "test-server:6443",
80+
clusterName: "somecluster",
81+
contextName: "test@somecluster",
82+
user: "test",
83+
})
84+
}
85+
86+
func generateInvalidFilePathKubeConfig() *clientcmdapi.Config {
87+
return generateTestKubeConfig(testKubeConfigSpec{
88+
certificateAuthorityFile: "invalid-file",
89+
server: "test-server:6443",
90+
clusterName: "somecluster",
91+
contextName: "test@somecluster",
92+
user: "test",
93+
})
94+
}
95+
96+
func generateInvalidCAKubeConfig() *clientcmdapi.Config {
97+
return generateTestKubeConfig(testKubeConfigSpec{
98+
certificateAuthorityData: "invalid-data",
99+
server: "test-server:6443",
100+
clusterName: "somecluster",
101+
contextName: "test@somecluster",
102+
user: "test",
103+
})
104+
}
105+
106+
func TestGetJoinCommand(t *testing.T) {
107+
tests := []struct {
108+
name string
109+
kubeConfig *clientcmdapi.Config
110+
expectError bool
111+
errorMessage string
112+
token string
113+
expectRes string
114+
}{
115+
{
116+
name: "Success with valid kubeconfig and token",
117+
kubeConfig: generateValidKubeConfig(),
118+
token: "test-token",
119+
expectError: false,
120+
expectRes: "kubeadm join test-server:6443 --token <value withheld> \\\n\t--discovery-token-ca-cert-hash",
121+
},
122+
{
123+
124+
name: "Error to load kubeconfig",
125+
kubeConfig: nil,
126+
token: "test-token",
127+
expectError: true,
128+
errorMessage: "failed to load kubeconfig",
129+
},
130+
131+
{
132+
name: "Error to get default cluster config",
133+
kubeConfig: &clientcmdapi.Config{},
134+
token: "test-token",
135+
expectError: true,
136+
errorMessage: "failed to get default cluster config",
137+
},
138+
{
139+
name: "Error when CA certificate is invalid",
140+
kubeConfig: generateInvalidCAKubeConfig(),
141+
expectError: true,
142+
errorMessage: "failed to parse CA certificate from kubeconfig",
143+
},
144+
{
145+
name: "Error when CA certificate file path is invalid",
146+
kubeConfig: generateInvalidFilePathKubeConfig(),
147+
token: "test-token",
148+
expectError: true,
149+
errorMessage: "failed to load CA certificate referenced by kubeconfig",
150+
},
151+
{
152+
name: "Error when CA certificate is missing",
153+
kubeConfig: generateMissingCAKubeConfig(),
154+
token: "test-token",
155+
expectError: true,
156+
errorMessage: "no CA certificates found in kubeconfig",
157+
},
158+
}
159+
160+
for _, tt := range tests {
161+
t.Run(tt.name, func(t *testing.T) {
162+
tmpDir, err := os.MkdirTemp("", "kubeadm-join-test")
163+
if err != nil {
164+
t.Fatalf("Unable to create temporary directory: %v", err)
165+
}
166+
defer func() {
167+
err := os.RemoveAll(tmpDir)
168+
if err != nil {
169+
t.Fatalf("Unable to remove temporary directory: %v", err)
170+
}
171+
}()
172+
173+
configFilePath := filepath.Join(tmpDir, "test-config-file")
174+
if tt.kubeConfig != nil {
175+
configBytes, err := clientcmd.Write(*tt.kubeConfig)
176+
if err != nil {
177+
t.Fatalf("Failed to clientcmd.Write: %v", err)
178+
}
179+
err = os.WriteFile(configFilePath, configBytes, 0644)
180+
if err != nil {
181+
t.Fatalf("Failed to os.WriteFile: %v", err)
182+
}
183+
}
184+
185+
res, err := getJoinCommand(configFilePath, tt.token, "", true, true, true)
186+
187+
if tt.expectError {
188+
require.Error(t, err)
189+
require.Contains(t, err.Error(), tt.errorMessage)
190+
} else {
191+
require.NoError(t, err)
192+
}
193+
require.Contains(t, res, tt.expectRes)
194+
})
195+
}
196+
}

0 commit comments

Comments
 (0)