kubeadm: join ux changes

This commit is contained in:
Derek McQuay 2017-02-22 12:53:01 -08:00
parent 81d01a84e0
commit 1d37c6be49
No known key found for this signature in database
GPG Key ID: 92A7BC0C86B0B91A
12 changed files with 244 additions and 197 deletions

View File

@ -37,7 +37,12 @@ func KubeadmFuzzerFuncs(t apitesting.TestingCommon) []interface{} {
func(obj *kubeadm.NodeConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj)
obj.CACertPath = "foo"
obj.Discovery.Token = &kubeadm.TokenDiscovery{}
obj.CACertPath = "foo"
obj.DiscoveryFile = "foo"
obj.DiscoveryToken = "foo"
obj.DiscoveryTokenAPIServers = []string{"foo"}
obj.TLSBootstrapToken = "foo"
obj.Token = "foo"
},
}
}

View File

@ -92,8 +92,13 @@ type Etcd struct {
type NodeConfiguration struct {
metav1.TypeMeta
Discovery Discovery
CACertPath string
CACertPath string
DiscoveryFile string
DiscoveryToken string
// Currently we only pay attention to one api server but hope to support >1 in the future
DiscoveryTokenAPIServers []string
TLSBootstrapToken string
Token string
}
// ClusterInfo TODO add description

View File

@ -16,7 +16,11 @@ limitations under the License.
package v1alpha1
import "k8s.io/apimachinery/pkg/runtime"
import (
"net/url"
"k8s.io/apimachinery/pkg/runtime"
)
const (
DefaultServiceDNSDomain = "cluster.local"
@ -68,4 +72,17 @@ func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
if obj.CACertPath == "" {
obj.CACertPath = DefaultCACertPath
}
if len(obj.TLSBootstrapToken) == 0 {
obj.TLSBootstrapToken = obj.Token
}
if len(obj.DiscoveryToken) == 0 && len(obj.DiscoveryFile) == 0 {
obj.DiscoveryToken = obj.Token
}
// Make sure file URLs become paths
if len(obj.DiscoveryFile) != 0 {
u, err := url.Parse(obj.DiscoveryFile)
if err == nil && u.Scheme == "file" {
obj.DiscoveryFile = u.Path
}
}
}

View File

@ -82,8 +82,12 @@ type Etcd struct {
type NodeConfiguration struct {
metav1.TypeMeta `json:",inline"`
Discovery Discovery `json:"discovery"`
CACertPath string `json:"caCertPath"`
CACertPath string `json:"caCertPath"`
DiscoveryFile string `json:"discoveryFile"`
DiscoveryToken string `json:"discoveryToken"`
DiscoveryTokenAPIServers []string `json:"discoveryTokenAPIServers"`
TLSBootstrapToken string `json:"tlsBootstrapToken"`
Token string `json:"token"`
}
// ClusterInfo TODO add description

View File

@ -8,6 +8,17 @@ load(
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["validation_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
],
)
go_library(
name = "go_default_library",
srcs = ["validation.go"],
@ -15,6 +26,7 @@ go_library(
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/util/token:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
"//pkg/registry/core/service/ipallocator:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
@ -33,14 +45,3 @@ filegroup(
srcs = [":package-srcs"],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["validation_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
],
)

View File

@ -17,13 +17,17 @@ limitations under the License.
package validation
import (
"fmt"
"net"
"net/url"
"os"
"path"
"strings"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
)
@ -45,7 +49,6 @@ var cloudproviders = []string{
func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateDiscovery(&c.Discovery, field.NewPath("discovery"))...)
allErrs = append(allErrs, ValidateServiceSubnet(c.Networking.ServiceSubnet, field.NewPath("service subnet"))...)
allErrs = append(allErrs, ValidateCloudProvider(c.CloudProvider, field.NewPath("cloudprovider"))...)
allErrs = append(allErrs, ValidateAuthorizationMode(c.AuthorizationMode, field.NewPath("authorization-mode"))...)
@ -54,70 +57,107 @@ func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList
func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateDiscovery(&c.Discovery, field.NewPath("discovery"))...)
allErrs = append(allErrs, ValidateDiscovery(c, field.NewPath("discovery"))...)
if !path.IsAbs(c.CACertPath) || !strings.HasSuffix(c.CACertPath, ".crt") {
allErrs = append(allErrs, field.Invalid(field.NewPath("ca-cert-path"), nil, "the ca certificate path must be an absolute path"))
}
return allErrs
}
func ValidateDiscovery(c *kubeadm.Discovery, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
var count int
if c.Token != nil {
allErrs = append(allErrs, ValidateTokenDiscovery(c.Token, fldPath)...)
count++
}
if c.File != nil {
allErrs = append(allErrs, ValidateFileDiscovery(c.File, fldPath)...)
count++
}
if c.HTTPS != nil {
allErrs = append(allErrs, ValidateHTTPSDiscovery(c.HTTPS, fldPath)...)
count++
}
if count != 1 {
allErrs = append(allErrs, field.Invalid(fldPath, nil, "exactly one discovery strategy can be provided"))
}
return allErrs
}
func ValidateFileDiscovery(c *kubeadm.FileDiscovery, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
return allErrs
}
func ValidateHTTPSDiscovery(c *kubeadm.HTTPSDiscovery, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
return allErrs
}
func ValidateTokenDiscovery(c *kubeadm.TokenDiscovery, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(c.ID) == 0 || len(c.Secret) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath, nil, "token must be specific as <ID>:<Secret>"))
}
if len(c.Addresses) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath, nil, "at least one address is required"))
allErrs = append(allErrs, field.Invalid(field.NewPath("ca-cert-path"), c.CACertPath, "the ca certificate path must be an absolute path"))
}
return allErrs
}
func ValidateAuthorizationMode(authzMode string, fldPath *field.Path) field.ErrorList {
if !authzmodes.IsValidAuthorizationMode(authzMode) {
return field.ErrorList{field.Invalid(fldPath, nil, "invalid authorization mode")}
return field.ErrorList{field.Invalid(fldPath, authzMode, "invalid authorization mode")}
}
return field.ErrorList{}
}
func ValidateDiscovery(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(c.DiscoveryToken) != 0 {
allErrs = append(allErrs, ValidateToken(c.DiscoveryToken, fldPath)...)
}
if len(c.DiscoveryFile) != 0 {
allErrs = append(allErrs, ValidateDiscoveryFile(c.DiscoveryFile, fldPath)...)
}
allErrs = append(allErrs, ValidateArgSelection(c, fldPath)...)
allErrs = append(allErrs, ValidateToken(c.TLSBootstrapToken, fldPath)...)
allErrs = append(allErrs, ValidateJoinDiscoveryTokenAPIServer(c, fldPath)...)
return allErrs
}
func ValidateArgSelection(cfg *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(cfg.DiscoveryToken) != 0 && len(cfg.DiscoveryFile) != 0 {
allErrs = append(allErrs, field.Invalid(fldPath, "", "DiscoveryToken and DiscoveryFile cannot both be set"))
}
if len(cfg.DiscoveryToken) == 0 && len(cfg.DiscoveryFile) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath, "", "DiscoveryToken or DiscoveryFile must be set"))
}
if len(cfg.DiscoveryTokenAPIServers) < 1 && len(cfg.DiscoveryToken) != 0 {
allErrs = append(allErrs, field.Required(fldPath, "DiscoveryTokenAPIServers not set"))
}
// TODO remove once we support multiple api servers
if len(cfg.DiscoveryTokenAPIServers) > 1 {
fmt.Println("[validation] WARNING: kubeadm doesn't fully support multiple API Servers yet")
}
return allErrs
}
func ValidateJoinDiscoveryTokenAPIServer(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for _, m := range c.DiscoveryTokenAPIServers {
_, _, err := net.SplitHostPort(m)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath, m, err.Error()))
}
}
return allErrs
}
func ValidateDiscoveryFile(discoveryFile string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
u, err := url.Parse(discoveryFile)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath, discoveryFile, "not a valid HTTPS URL or a file on disk"))
return allErrs
}
if u.Scheme == "" {
// URIs with no scheme should be treated as files
if _, err := os.Stat(discoveryFile); os.IsNotExist(err) {
allErrs = append(allErrs, field.Invalid(fldPath, discoveryFile, "not a valid HTTPS URL or a file on disk"))
}
return allErrs
}
if u.Scheme != "https" {
allErrs = append(allErrs, field.Invalid(fldPath, discoveryFile, "if an URL is used, the scheme must be https"))
}
return allErrs
}
func ValidateToken(t string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
id, secret, err := tokenutil.ParseToken(t)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath, nil, err.Error()))
}
if len(id) == 0 || len(secret) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath, nil, "token must be of form '[a-z0-9]{6}.[a-z0-9]{16}'"))
}
return allErrs
}
func ValidateServiceSubnet(subnet string, fldPath *field.Path) field.ErrorList {
_, svcSubnet, err := net.ParseCIDR(subnet)
if err != nil {
return field.ErrorList{field.Invalid(fldPath, nil, "couldn't parse the service subnet")}
}
numAddresses := ipallocator.RangeSize(svcSubnet)
if numAddresses < kubeadmconstants.MinimumAddressesInServiceSubnet {
if numAddresses < constants.MinimumAddressesInServiceSubnet {
return field.ErrorList{field.Invalid(fldPath, nil, "service subnet is too small")}
}
return field.ErrorList{}

View File

@ -25,17 +25,16 @@ import (
func TestValidateTokenDiscovery(t *testing.T) {
var tests = []struct {
c *kubeadm.TokenDiscovery
c *kubeadm.NodeConfiguration
f *field.Path
expected bool
}{
{&kubeadm.TokenDiscovery{ID: "772ef5", Secret: "6b6baab1d4a0a171", Addresses: []string{"192.168.122.100:9898"}}, nil, true},
{&kubeadm.TokenDiscovery{ID: "", Secret: "6b6baab1d4a0a171", Addresses: []string{"192.168.122.100:9898"}}, nil, false},
{&kubeadm.TokenDiscovery{ID: "772ef5", Secret: "", Addresses: []string{"192.168.122.100:9898"}}, nil, false},
{&kubeadm.TokenDiscovery{ID: "772ef5", Secret: "6b6baab1d4a0a171", Addresses: []string{}}, nil, false},
{&kubeadm.NodeConfiguration{Token: "772ef5.6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"192.168.122.100:9898"}}, nil, true},
{&kubeadm.NodeConfiguration{Token: ".6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"192.168.122.100:9898"}}, nil, false},
{&kubeadm.NodeConfiguration{Token: "772ef5.", DiscoveryTokenAPIServers: []string{"192.168.122.100:9898"}}, nil, false},
}
for _, rt := range tests {
err := ValidateTokenDiscovery(rt.c, rt.f).ToAggregate()
err := ValidateToken(rt.c.Token, rt.f).ToAggregate()
if (err == nil) != rt.expected {
t.Errorf(
"failed ValidateTokenDiscovery:\n\texpected: %t\n\t actual: %t",
@ -125,21 +124,6 @@ func TestValidateMasterConfiguration(t *testing.T) {
expected bool
}{
{&kubeadm.MasterConfiguration{}, false},
{&kubeadm.MasterConfiguration{
Discovery: kubeadm.Discovery{
HTTPS: &kubeadm.HTTPSDiscovery{URL: "foo"},
File: &kubeadm.FileDiscovery{Path: "foo"},
Token: &kubeadm.TokenDiscovery{
ID: "abcdef",
Secret: "1234567890123456",
Addresses: []string{"foobar"},
},
},
AuthorizationMode: "RBAC",
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
},
}, false},
{&kubeadm.MasterConfiguration{
Discovery: kubeadm.Discovery{
HTTPS: &kubeadm.HTTPSDiscovery{URL: "foo"},
@ -191,45 +175,10 @@ func TestValidateNodeConfiguration(t *testing.T) {
}{
{&kubeadm.NodeConfiguration{}, false},
{&kubeadm.NodeConfiguration{
Discovery: kubeadm.Discovery{
HTTPS: &kubeadm.HTTPSDiscovery{URL: "foo"},
File: &kubeadm.FileDiscovery{Path: "foo"},
Token: &kubeadm.TokenDiscovery{
ID: "abcdef",
Secret: "1234567890123456",
Addresses: []string{"foobar"},
},
},
CACertPath: "/some/cert.crt",
DiscoveryFile: "foo",
DiscoveryToken: "abcdef.1234567890123456@foobar",
CACertPath: "/some/cert.crt",
}, false},
{&kubeadm.NodeConfiguration{
Discovery: kubeadm.Discovery{
HTTPS: &kubeadm.HTTPSDiscovery{URL: "foo"},
},
CACertPath: "/some/path", // no .crt suffix
}, false},
{&kubeadm.NodeConfiguration{
Discovery: kubeadm.Discovery{
HTTPS: &kubeadm.HTTPSDiscovery{URL: "foo"},
},
CACertPath: "/some/cert.crt",
}, true},
{&kubeadm.NodeConfiguration{
Discovery: kubeadm.Discovery{
File: &kubeadm.FileDiscovery{Path: "foo"},
},
CACertPath: "/some/other/cert.crt",
}, true},
{&kubeadm.NodeConfiguration{
Discovery: kubeadm.Discovery{
Token: &kubeadm.TokenDiscovery{
ID: "abcdef",
Secret: "1234567890123456",
Addresses: []string{"foobar"},
},
},
CACertPath: "/a/third/cert.crt",
}, true},
}
for _, rt := range tests {
actual := ValidateNodeConfiguration(rt.s)

View File

@ -52,37 +52,76 @@ var (
// NewCmdJoin returns "kubeadm join" command.
func NewCmdJoin(out io.Writer) *cobra.Command {
versioned := &kubeadmapiext.NodeConfiguration{}
api.Scheme.Default(versioned)
cfg := kubeadmapi.NodeConfiguration{}
api.Scheme.Convert(versioned, &cfg, nil)
cfg := &kubeadmapiext.NodeConfiguration{}
api.Scheme.Default(cfg)
var skipPreFlight bool
var cfgPath string
cmd := &cobra.Command{
Use: "join <master address>",
Use: "join <flags> [DiscoveryTokenAPIServers]",
Short: "Run this on any machine you wish to join an existing cluster",
Long: dedent.Dedent(`
When joining a kubeadm initialized cluster, we need to establish
bidirectional trust. This is split into discovery (having the Node
trust the Kubernetes Master) and TLS bootstrap (having the Kubernetes
Master trust the Node).
There are 2 main schemes for discovery. The first is to use a shared
token along with the IP address of the API server. The second is to
provide a file (a subset of the standard kubeconfig file). This file
can be a local file or downloaded via an HTTPS URL. The forms are
kubeadm join --discovery-token abcdef.1234567890abcdef 1.2.3.4:6443,
kubeadm join --discovery-file path/to/file.conf or kubeadm join
--discovery-file https://url/file.conf. Only one form can be used. If
the discovery information is loaded from a URL, HTTPS must be used and
the host installed CA bundle is used to verify the connection.
The TLS bootstrap mechanism is also driven via a shared token. This is
used to temporarily authenticate with the Kubernetes Master to submit a
certificate signing request (CSR) for a locally created key pair. By
default kubeadm will set up the Kubernetes Master to automatically
approve these signing requests. This token is passed in with the
--tls-bootstrap-token abcdef.1234567890abcdef flag.
Often times the same token is use for both parts. In this case, the
--token flag can be used instead of specifying the each token
individually.
`),
Run: func(cmd *cobra.Command, args []string) {
j, err := NewJoin(cfgPath, args, &cfg, skipPreFlight)
cfg.DiscoveryTokenAPIServers = args
api.Scheme.Default(cfg)
internalcfg := &kubeadmapi.NodeConfiguration{}
api.Scheme.Convert(cfg, internalcfg, nil)
j, err := NewJoin(cfgPath, args, internalcfg, skipPreFlight)
kubeadmutil.CheckErr(err)
kubeadmutil.CheckErr(j.Validate())
kubeadmutil.CheckErr(j.Run(out))
},
}
cmd.PersistentFlags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file")
cmd.PersistentFlags().StringVar(
&cfgPath, "config", cfgPath,
"Path to kubeadm config file")
cmd.PersistentFlags().StringVar(
&cfg.DiscoveryFile, "discovery-file", "",
"A file or url from which to load cluster information")
cmd.PersistentFlags().StringVar(
&cfg.DiscoveryToken, "discovery-token", "",
"A token used to validate cluster information fetched from the master")
cmd.PersistentFlags().StringVar(
&cfg.TLSBootstrapToken, "tls-bootstrap-token", "",
"A token used for TLS bootstrapping")
cmd.PersistentFlags().StringVar(
&cfg.Token, "token", "",
"Use this token for both discovery-token and tls-bootstrap-token")
cmd.PersistentFlags().BoolVar(
&skipPreFlight, "skip-preflight-checks", false,
"skip preflight checks normally run before modifying the system",
)
cmd.PersistentFlags().Var(
discovery.NewDiscoveryValue(&cfg.Discovery), "discovery",
"The discovery method kubeadm will use for connecting nodes to the master",
)
return cmd
}
@ -131,7 +170,7 @@ func (j *Join) Validate() error {
// Run executes worker node provisioning and tries to join an existing cluster.
func (j *Join) Run(out io.Writer) error {
cfg, err := discovery.For(j.cfg.Discovery)
cfg, err := discovery.For(j.cfg)
if err != nil {
return err
}

View File

@ -20,6 +20,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
@ -29,27 +30,34 @@ import (
)
// For identifies and executes the desired discovery mechanism.
func For(d kubeadmapi.Discovery) (*clientcmdapi.Config, error) {
func For(d *kubeadmapi.NodeConfiguration) (*clientcmdapi.Config, error) {
switch {
case d.File != nil:
return runFileDiscovery(d.File)
case d.HTTPS != nil:
return runHTTPSDiscovery(d.HTTPS)
case d.Token != nil:
return runTokenDiscovery(d.Token)
case len(d.DiscoveryFile) != 0:
if isHTTPSURL(d.DiscoveryFile) {
return runHTTPSDiscovery(d.DiscoveryFile)
}
return runFileDiscovery(d.DiscoveryFile)
case len(d.DiscoveryToken) != 0:
return runTokenDiscovery(d.DiscoveryToken, d.DiscoveryTokenAPIServers)
default:
return nil, fmt.Errorf("couldn't find a valid discovery configuration.")
}
}
// isHTTPSURL checks whether the string is parsable as an URL
func isHTTPSURL(s string) bool {
u, err := url.Parse(s)
return err == nil && u.Scheme == "https"
}
// runFileDiscovery executes file-based discovery.
func runFileDiscovery(fd *kubeadmapi.FileDiscovery) (*clientcmdapi.Config, error) {
return clientcmd.LoadFromFile(fd.Path)
func runFileDiscovery(fd string) (*clientcmdapi.Config, error) {
return clientcmd.LoadFromFile(fd)
}
// runHTTPSDiscovery executes HTTPS-based discovery.
func runHTTPSDiscovery(hd *kubeadmapi.HTTPSDiscovery) (*clientcmdapi.Config, error) {
response, err := http.Get(hd.URL)
func runHTTPSDiscovery(hd string) (*clientcmdapi.Config, error) {
response, err := http.Get(hd)
if err != nil {
return nil, err
}
@ -64,17 +72,23 @@ func runHTTPSDiscovery(hd *kubeadmapi.HTTPSDiscovery) (*clientcmdapi.Config, err
}
// runTokenDiscovery executes token-based discovery.
func runTokenDiscovery(td *kubeadmapi.TokenDiscovery) (*clientcmdapi.Config, error) {
if valid, err := tokenutil.ValidateToken(td); valid == false {
func runTokenDiscovery(td string, m []string) (*clientcmdapi.Config, error) {
id, secret, err := tokenutil.ParseToken(td)
if err != nil {
return nil, err
}
t := &kubeadmapi.TokenDiscovery{ID: id, Secret: secret, Addresses: m}
if valid, err := tokenutil.ValidateToken(t); valid == false {
return nil, err
}
clusterInfo, err := kubenode.RetrieveTrustedClusterInfo(td)
clusterInfo, err := kubenode.RetrieveTrustedClusterInfo(t)
if err != nil {
return nil, err
}
cfg, err := kubenode.EstablishMasterConnection(td, clusterInfo)
cfg, err := kubenode.EstablishMasterConnection(t, clusterInfo)
if err != nil {
return nil, err
}

View File

@ -24,40 +24,37 @@ import (
func TestFor(t *testing.T) {
tests := []struct {
d kubeadm.Discovery
d kubeadm.NodeConfiguration
expect bool
}{
{d: kubeadm.Discovery{}, expect: false},
{d: kubeadm.NodeConfiguration{}, expect: false},
{
d: kubeadm.Discovery{
HTTPS: &kubeadm.HTTPSDiscovery{URL: "notnil"},
d: kubeadm.NodeConfiguration{
DiscoveryFile: "notnil",
},
expect: false,
},
{
d: kubeadm.Discovery{
HTTPS: &kubeadm.HTTPSDiscovery{URL: "http://localhost"},
d: kubeadm.NodeConfiguration{
DiscoveryFile: "https://localhost",
},
expect: false,
},
{
d: kubeadm.Discovery{
File: &kubeadm.FileDiscovery{Path: "notnil"},
d: kubeadm.NodeConfiguration{
DiscoveryFile: "notnil",
},
expect: false,
},
{
d: kubeadm.Discovery{
Token: &kubeadm.TokenDiscovery{
ID: "foo",
Secret: "bar",
Addresses: []string{"foobar"},
},
}, expect: false,
d: kubeadm.NodeConfiguration{
DiscoveryToken: "foo.bar@foobar",
},
expect: false,
},
}
for _, rt := range tests {
_, actual := For(rt.d)
_, actual := For(&rt.d)
if (actual == nil) != rt.expect {
t.Errorf(
"failed For:\n\texpected: %t\n\t actual: %t",

View File

@ -46,32 +46,3 @@ func TestCmdJoinConfig(t *testing.T) {
kubeadmReset()
}
}
func TestCmdJoinDiscovery(t *testing.T) {
if *kubeadmCmdSkip {
t.Log("kubeadm cmd tests being skipped")
t.Skip()
}
var initTest = []struct {
args string
expected bool
}{
{"--discovery=foobar", false},
{"--dicovery=magic", false},
}
for _, rt := range initTest {
_, _, actual := RunCmd(*kubeadmPath, "join", rt.args, "--skip-preflight-checks")
if (actual == nil) != rt.expected {
t.Errorf(
"failed CmdJoinDiscovery running 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",
rt.args,
actual,
rt.expected,
(actual == nil),
)
}
kubeadmReset()
}
}

View File

@ -154,7 +154,9 @@ disable-attach-detach-reconcile-sync
disable-filter
disable-kubenet
disable-log-dump
discovery-file
discovery-port
discovery-token
dns-bind-address
dns-port
dns-provider
@ -647,6 +649,7 @@ tcp-services
terminated-pod-gc-threshold
test-flags
test-timeout
tls-bootstrap-token
tls-ca-file
tls-cert-file
tls-private-key-file
@ -666,6 +669,8 @@ upgrade-image
upgrade-target
use-kubernetes-cluster-service
use-kubernetes-version
use-service-account-credentials
use-taint-based-evictions
user-whitelist
use-service-account-credentials
use-service-account-credentials