kubernetes join_test 源码
kubernetes join_test 代码
文件路径:/cmd/kubeadm/app/cmd/join_test.go
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"path/filepath"
"testing"
"k8s.io/apimachinery/pkg/util/sets"
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
)
var testJoinConfig = fmt.Sprintf(`apiVersion: %s
kind: JoinConfiguration
discovery:
bootstrapToken:
token: abcdef.0123456789abcdef
apiServerEndpoint: 1.2.3.4:6443
unsafeSkipCAVerification: true
nodeRegistration:
criSocket: /run/containerd/containerd.sock
name: someName
ignorePreflightErrors:
- c
- d
`, kubeadmapiv1.SchemeGroupVersion.String())
func TestNewJoinData(t *testing.T) {
// create temp directory
tmpDir, err := os.MkdirTemp("", "kubeadm-join-test")
if err != nil {
t.Errorf("Unable to create temporary directory: %v", err)
}
defer os.RemoveAll(tmpDir)
// create kubeconfig
kubeconfigFilePath := filepath.Join(tmpDir, "test-kubeconfig-file")
kubeconfig := kubeconfigutil.CreateBasic("", "", "", []byte{})
kubeconfigutil.WriteToDisk(kubeconfigFilePath, kubeconfig)
// create config file
configFilePath := filepath.Join(tmpDir, "test-config-file")
cfgFile, err := os.Create(configFilePath)
if err != nil {
t.Errorf("Unable to create file %q: %v", configFilePath, err)
}
defer cfgFile.Close()
if _, err = cfgFile.WriteString(testJoinConfig); err != nil {
t.Fatalf("Unable to write file %q: %v", configFilePath, err)
}
testCases := []struct {
name string
args []string
flags map[string]string
validate func(*testing.T, *joinData)
expectError bool
}{
// Join data passed using flags
{
name: "fails if no discovery method set",
expectError: true,
},
{
name: "fails if both file and bootstrap discovery methods set",
args: []string{"1.2.3.4:6443"},
flags: map[string]string{
options.FileDiscovery: "https://foo",
options.TokenDiscovery: "abcdef.0123456789abcdef",
options.TokenDiscoverySkipCAHash: "true",
},
expectError: true,
},
{
name: "pass if file discovery is set",
flags: map[string]string{
options.FileDiscovery: "https://foo",
},
validate: func(t *testing.T, data *joinData) {
// validate that file discovery settings are set into join data
if data.cfg.Discovery.File == nil || data.cfg.Discovery.File.KubeConfigPath != "https://foo" {
t.Errorf("Invalid data.cfg.Discovery.File")
}
},
},
{
name: "pass if bootstrap discovery is set",
args: []string{"1.2.3.4:6443", "5.6.7.8:6443"},
flags: map[string]string{
options.TokenDiscovery: "abcdef.0123456789abcdef",
options.TokenDiscoverySkipCAHash: "true",
},
validate: func(t *testing.T, data *joinData) {
// validate that bootstrap discovery settings are set into join data
if data.cfg.Discovery.BootstrapToken == nil ||
data.cfg.Discovery.BootstrapToken.APIServerEndpoint != "1.2.3.4:6443" || //only first arg should be kept as APIServerEndpoint
data.cfg.Discovery.BootstrapToken.Token != "abcdef.0123456789abcdef" ||
data.cfg.Discovery.BootstrapToken.UnsafeSkipCAVerification != true {
t.Errorf("Invalid data.cfg.Discovery.BootstrapToken")
}
},
},
{
name: "--token sets TLSBootstrapToken and BootstrapToken.Token if unset",
args: []string{"1.2.3.4:6443"},
flags: map[string]string{
options.TokenStr: "abcdef.0123456789abcdef",
options.TokenDiscoverySkipCAHash: "true",
},
validate: func(t *testing.T, data *joinData) {
// validate that token sets both TLSBootstrapToken and BootstrapToken.Token into join data
if data.cfg.Discovery.TLSBootstrapToken != "abcdef.0123456789abcdef" ||
data.cfg.Discovery.BootstrapToken == nil ||
data.cfg.Discovery.BootstrapToken.Token != "abcdef.0123456789abcdef" {
t.Errorf("Invalid TLSBootstrapToken or BootstrapToken.Token")
}
},
},
{
name: "--token doesn't override TLSBootstrapToken and BootstrapToken.Token if set",
args: []string{"1.2.3.4:6443"},
flags: map[string]string{
options.TokenStr: "aaaaaa.0123456789aaaaaa",
options.TLSBootstrapToken: "abcdef.0123456789abcdef",
options.TokenDiscovery: "defghi.0123456789defghi",
options.TokenDiscoverySkipCAHash: "true",
},
validate: func(t *testing.T, data *joinData) {
// validate that TLSBootstrapToken and BootstrapToken.Token values are preserved into join data
if data.cfg.Discovery.TLSBootstrapToken != "abcdef.0123456789abcdef" ||
data.cfg.Discovery.BootstrapToken == nil ||
data.cfg.Discovery.BootstrapToken.Token != "defghi.0123456789defghi" {
t.Errorf("Invalid TLSBootstrapToken or BootstrapToken.Token")
}
},
},
{
name: "control plane setting are preserved if --control-plane flag is set",
flags: map[string]string{
options.ControlPlane: "true",
options.APIServerAdvertiseAddress: "1.2.3.4",
options.APIServerBindPort: "1234",
options.FileDiscovery: "https://foo", //required only to pass discovery validation
},
validate: func(t *testing.T, data *joinData) {
// validate that control plane attributes are set in join data
if data.cfg.ControlPlane == nil ||
data.cfg.ControlPlane.LocalAPIEndpoint.AdvertiseAddress != "1.2.3.4" ||
data.cfg.ControlPlane.LocalAPIEndpoint.BindPort != 1234 {
t.Errorf("Invalid ControlPlane")
}
},
},
{
name: "control plane setting are cleaned up if --control-plane flag is not set",
flags: map[string]string{
options.ControlPlane: "false",
options.APIServerAdvertiseAddress: "1.2.3.4",
options.APIServerBindPort: "1.2.3.4",
options.FileDiscovery: "https://foo", //required only to pass discovery validation
},
validate: func(t *testing.T, data *joinData) {
// validate that control plane attributes are unset in join data
if data.cfg.ControlPlane != nil {
t.Errorf("Invalid ControlPlane")
}
},
},
{
name: "fails if invalid preflight checks are provided",
flags: map[string]string{
options.IgnorePreflightErrors: "all,something-else",
},
expectError: true,
},
// Join data passed using config file
{
name: "Pass with config from file",
flags: map[string]string{
options.CfgPath: configFilePath,
},
},
{
name: "--cri-socket and --node-name flags override config from file",
flags: map[string]string{
options.CfgPath: configFilePath,
options.NodeName: "anotherName",
},
validate: func(t *testing.T, data *joinData) {
// validate that node-name is overwritten
if data.cfg.NodeRegistration.Name != "anotherName" {
t.Errorf("Invalid NodeRegistration.Name")
}
},
},
{
name: "fail if mixedArguments are passed",
flags: map[string]string{
options.CfgPath: configFilePath,
options.APIServerAdvertiseAddress: "1.2.3.4",
},
expectError: true,
},
// Pre-flight errors:
{
name: "pre-flights errors from CLI args only",
flags: map[string]string{
options.IgnorePreflightErrors: "a,b",
options.FileDiscovery: "https://foo", //required only to pass discovery validation
},
validate: expectedJoinIgnorePreflightErrors(sets.NewString("a", "b")),
},
{
name: "pre-flights errors from JoinConfiguration only",
flags: map[string]string{
options.CfgPath: configFilePath,
},
validate: expectedJoinIgnorePreflightErrors(sets.NewString("c", "d")),
},
{
name: "pre-flights errors from both CLI args and JoinConfiguration",
flags: map[string]string{
options.CfgPath: configFilePath,
options.IgnorePreflightErrors: "a,b",
},
validate: expectedJoinIgnorePreflightErrors(sets.NewString("a", "b", "c", "d")),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// initialize an external join option and inject it to the join cmd
joinOptions := newJoinOptions()
cmd := newCmdJoin(nil, joinOptions)
// sets cmd flags (that will be reflected on the join options)
for f, v := range tc.flags {
cmd.Flags().Set(f, v)
}
// test newJoinData method
data, err := newJoinData(cmd, tc.args, joinOptions, nil, kubeconfigFilePath)
if err != nil && !tc.expectError {
t.Fatalf("newJoinData returned unexpected error: %v", err)
}
if err == nil && tc.expectError {
t.Fatalf("newJoinData didn't return error when expected")
}
// exec additional validation on the returned value
if tc.validate != nil {
tc.validate(t, data)
}
})
}
}
func expectedJoinIgnorePreflightErrors(expected sets.String) func(t *testing.T, data *joinData) {
return func(t *testing.T, data *joinData) {
if !expected.Equal(data.ignorePreflightErrors) {
t.Errorf("Invalid ignore preflight errors. Expected: %v. Actual: %v", expected.List(), data.ignorePreflightErrors.List())
}
if !expected.HasAll(data.cfg.NodeRegistration.IgnorePreflightErrors...) {
t.Errorf("Invalid ignore preflight errors in JoinConfiguration. Expected: %v. Actual: %v", expected.List(), data.cfg.NodeRegistration.IgnorePreflightErrors)
}
}
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦