diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index d5ef2cc43064..c875f0ebf3e7 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -898,6 +898,20 @@ func validateFlags(cmd *cobra.Command, drvName string) { } } + // validate kubeadm extra args + if invalidOpts := bsutil.FindInvalidExtraConfigFlags(config.ExtraOptions); len(invalidOpts) > 0 { + out.ErrT( + out.Warning, + "These --extra-config parameters are invalid: {{.invalid_extra_opts}}", + out.V{"invalid_extra_opts": invalidOpts}, + ) + exit.WithCodeT( + exit.Config, + "Valid components are: {{.valid_extra_opts}}", + out.V{"valid_extra_opts": bsutil.KubeadmExtraConfigOpts}, + ) + } + // check that kubeadm extra args contain only allowed parameters for param := range config.ExtraOptions.AsMap().Get(bsutil.Kubeadm) { if !config.ContainsParam(bsutil.KubeadmExtraArgsAllowed[bsutil.KubeadmCmdParam], param) && diff --git a/pkg/minikube/bootstrapper/bsutil/extraconfig.go b/pkg/minikube/bootstrapper/bsutil/extraconfig.go index 0f64b89f10db..946d087836d2 100644 --- a/pkg/minikube/bootstrapper/bsutil/extraconfig.go +++ b/pkg/minikube/bootstrapper/bsutil/extraconfig.go @@ -95,6 +95,21 @@ func CreateFlagsFromExtraArgs(extraOptions config.ExtraOptionSlice) string { return convertToFlags(kubeadmExtraOpts) } +// FindInvalidExtraConfigFlags returns all invalid 'extra-config' options +func FindInvalidExtraConfigFlags(opts config.ExtraOptionSlice) []string { + invalidOptsMap := make(map[string]struct{}) + var invalidOpts []string + for _, extraOpt := range opts { + if _, ok := componentToKubeadmConfigKey[extraOpt.Component]; !ok { + if _, ok := invalidOptsMap[extraOpt.Component]; !ok { + invalidOpts = append(invalidOpts, extraOpt.Component) + invalidOptsMap[extraOpt.Component] = struct{}{} + } + } + } + return invalidOpts +} + // extraConfigForComponent generates a map of flagname-value pairs for a k8s // component. func extraConfigForComponent(component string, opts config.ExtraOptionSlice, version semver.Version) (map[string]string, error) { @@ -133,20 +148,12 @@ func defaultOptionsForComponentAndVersion(component string, version semver.Versi // newComponentOptions creates a new componentOptions func newComponentOptions(opts config.ExtraOptionSlice, version semver.Version, featureGates string, cp config.Node) ([]componentOptions, error) { - var kubeadmExtraArgs []componentOptions - for _, extraOpt := range opts { - if _, ok := componentToKubeadmConfigKey[extraOpt.Component]; !ok { - return nil, fmt.Errorf("unknown component %q. valid components are: %v", componentToKubeadmConfigKey, componentToKubeadmConfigKey) - } - } - - keys := []string{} - for k := range componentToKubeadmConfigKey { - keys = append(keys, k) + if invalidOpts := FindInvalidExtraConfigFlags(opts); len(invalidOpts) > 0 { + return nil, fmt.Errorf("unknown components %v. valid components are: %v", invalidOpts, KubeadmExtraConfigOpts) } - sort.Strings(keys) - for _, component := range keys { + var kubeadmExtraArgs []componentOptions + for _, component := range KubeadmExtraConfigOpts { kubeadmComponentKey := componentToKubeadmConfigKey[component] if kubeadmComponentKey == "" { continue diff --git a/pkg/minikube/bootstrapper/bsutil/extraconfig_test.go b/pkg/minikube/bootstrapper/bsutil/extraconfig_test.go new file mode 100644 index 000000000000..cb43a77f1507 --- /dev/null +++ b/pkg/minikube/bootstrapper/bsutil/extraconfig_test.go @@ -0,0 +1,59 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 bsutil will eventually be renamed to kubeadm package after getting rid of older one +package bsutil + +import ( + "reflect" + "testing" + + "k8s.io/minikube/pkg/minikube/config" +) + +func TestFindInvalidExtraConfigFlags(t *testing.T) { + defaultOpts := getExtraOpts() + badOption1 := config.ExtraOption{Component: "bad_option_1"} + badOption2 := config.ExtraOption{Component: "bad_option_2"} + tests := []struct { + name string + opts config.ExtraOptionSlice + want []string + }{ + { + name: "with valid options only", + opts: defaultOpts, + want: nil, + }, + { + name: "with invalid options", + opts: append(defaultOpts, badOption1, badOption2), + want: []string{"bad_option_1", "bad_option_2"}, + }, + { + name: "with invalid options and duplicates", + opts: append(defaultOpts, badOption2, badOption1, badOption1), + want: []string{"bad_option_2", "bad_option_1"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := FindInvalidExtraConfigFlags(tt.opts); !reflect.DeepEqual(got, tt.want) { + t.Errorf("FindInvalidExtraConfigFlags() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/minikube/bootstrapper/bsutil/kubeadm.go b/pkg/minikube/bootstrapper/bsutil/kubeadm.go index 7fa1f157dfc9..db5e24485ff4 100644 --- a/pkg/minikube/bootstrapper/bsutil/kubeadm.go +++ b/pkg/minikube/bootstrapper/bsutil/kubeadm.go @@ -147,15 +147,26 @@ func GenerateKubeadmYAML(cc config.ClusterConfig, n config.Node, r cruntime.Mana // These are the components that can be configured // through the "extra-config" const ( - Kubelet = "kubelet" - Kubeadm = "kubeadm" Apiserver = "apiserver" - Scheduler = "scheduler" ControllerManager = "controller-manager" - Kubeproxy = "kube-proxy" + Scheduler = "scheduler" Etcd = "etcd" + Kubeadm = "kubeadm" + Kubeproxy = "kube-proxy" + Kubelet = "kubelet" ) +// KubeadmExtraConfigOpts is a list of allowed "extra-config" components +var KubeadmExtraConfigOpts = []string{ + Apiserver, + ControllerManager, + Scheduler, + Etcd, + Kubeadm, + Kubelet, + Kubeproxy, +} + // InvokeKubeadm returns the invocation command for Kubeadm func InvokeKubeadm(version string) string { return fmt.Sprintf("sudo env PATH=%s:$PATH kubeadm", binRoot(version))