Merge pull request #3892 from 11janci/jjanik-expose-pod-cidr
Expose ‘—pod-network-cidr’ argument in minikubepull/4296/head
commit
35dc6a2ff2
|
|
@ -42,6 +42,7 @@ import (
|
|||
cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config"
|
||||
cmdutil "k8s.io/minikube/cmd/util"
|
||||
"k8s.io/minikube/pkg/minikube/bootstrapper"
|
||||
"k8s.io/minikube/pkg/minikube/bootstrapper/kubeadm"
|
||||
"k8s.io/minikube/pkg/minikube/cluster"
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/console"
|
||||
|
|
@ -145,7 +146,8 @@ func init() {
|
|||
startCmd.Flags().Var(&extraOptions, "extra-config",
|
||||
`A set of key=value pairs that describe configuration that may be passed to different components.
|
||||
The key should be '.' separated, and the first part before the dot is the component to apply the configuration to.
|
||||
Valid components are: kubelet, kubeadm, apiserver, controller-manager, etcd, proxy, scheduler.`)
|
||||
Valid components are: kubelet, kubeadm, apiserver, controller-manager, etcd, proxy, scheduler
|
||||
Valid kubeadm parameters: `+fmt.Sprintf("%s, %s", strings.Join(kubeadm.KubeadmExtraArgsWhitelist[kubeadm.KubeadmCmdParam], ", "), strings.Join(kubeadm.KubeadmExtraArgsWhitelist[kubeadm.KubeadmConfigParam], ",")))
|
||||
startCmd.Flags().String(uuid, "", "Provide VM UUID to restore MAC address (only supported with Hyperkit driver).")
|
||||
startCmd.Flags().String(vpnkitSock, "", "Location of the VPNKit socket used for networking. If empty, disables Hyperkit VPNKitSock, if 'auto' uses Docker for Mac VPNKit connection, otherwise uses the specified VSock.")
|
||||
startCmd.Flags().StringSlice(vsockPorts, []string{}, "List of guest VSock ports that should be exposed as sockets on the host (Only supported on with hyperkit now).")
|
||||
|
|
@ -336,6 +338,14 @@ func validateConfig() {
|
|||
if viper.GetBool(hidden) && viper.GetString(vmDriver) != "kvm2" {
|
||||
exit.Usage("Sorry, the --hidden feature is currently only supported with --vm-driver=kvm2")
|
||||
}
|
||||
|
||||
// check that kubeadm extra args contain only whitelisted parameters
|
||||
for param := range extraOptions.AsMap().Get(kubeadm.Kubeadm) {
|
||||
if !pkgutil.ContainsString(kubeadm.KubeadmExtraArgsWhitelist[kubeadm.KubeadmCmdParam], param) &&
|
||||
!pkgutil.ContainsString(kubeadm.KubeadmExtraArgsWhitelist[kubeadm.KubeadmConfigParam], param) {
|
||||
exit.Usage("Sorry, the kubeadm.%s parameter is currently not supported by --extra-config", param)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// doCacheBinaries caches Kubernetes binaries in the foreground
|
||||
|
|
|
|||
|
|
@ -44,6 +44,35 @@ import (
|
|||
"k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
// enum to differentiate kubeadm command line parameters from kubeadm config file parameters (see the
|
||||
// KubeadmExtraArgsWhitelist variable below for more info)
|
||||
const (
|
||||
KubeadmCmdParam = iota
|
||||
KubeadmConfigParam = iota
|
||||
)
|
||||
|
||||
// KubeadmExtraArgsWhitelist is a whitelist of supported kubeadm params that can be supplied to kubeadm through
|
||||
// minikube's ExtraArgs parameter. The list is split into two parts - params that can be supplied as flags on the
|
||||
// command line and params that have to be inserted into the kubeadm config file. This is because of a kubeadm
|
||||
// constraint which allows only certain params to be provided from the command line when the --config parameter
|
||||
// is specified
|
||||
var KubeadmExtraArgsWhitelist = map[int][]string{
|
||||
KubeadmCmdParam: {
|
||||
"ignore-preflight-errors",
|
||||
"dry-run",
|
||||
"kubeconfig",
|
||||
"kubeconfig-dir",
|
||||
"node-name",
|
||||
"cri-socket",
|
||||
"experimental-upload-certs",
|
||||
"certificate-key",
|
||||
"rootfs",
|
||||
},
|
||||
KubeadmConfigParam: {
|
||||
"pod-network-cidr",
|
||||
},
|
||||
}
|
||||
|
||||
// SkipPreflights are preflight checks we always skip.
|
||||
var SkipPreflights = []string{
|
||||
// We use --ignore-preflight-errors=DirAvailable since we have our own custom addons
|
||||
|
|
@ -163,6 +192,21 @@ func (k *Bootstrapper) LogCommands(o bootstrapper.LogOptions) map[string]string
|
|||
}
|
||||
}
|
||||
|
||||
// createFlagsFromExtraArgs converts kubeadm extra args into flags to be supplied from the commad linne
|
||||
func createFlagsFromExtraArgs(extraOptions util.ExtraOptionSlice) string {
|
||||
kubeadmExtraOpts := extraOptions.AsMap().Get(Kubeadm)
|
||||
|
||||
// kubeadm allows only a small set of parameters to be supplied from the command line when the --config param
|
||||
// is specified, here we remove those that are not allowed
|
||||
for opt := range kubeadmExtraOpts {
|
||||
if !util.ContainsString(KubeadmExtraArgsWhitelist[KubeadmCmdParam], opt) {
|
||||
// kubeadmExtraOpts is a copy so safe to delete
|
||||
delete(kubeadmExtraOpts, opt)
|
||||
}
|
||||
}
|
||||
return convertToFlags(kubeadmExtraOpts)
|
||||
}
|
||||
|
||||
// StartCluster starts the cluster
|
||||
func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error {
|
||||
version, err := ParseKubernetesVersion(k8s.KubernetesVersion)
|
||||
|
|
@ -170,11 +214,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error {
|
|||
return errors.Wrap(err, "parsing kubernetes version")
|
||||
}
|
||||
|
||||
extraOpts, err := ExtraConfigForComponent(Kubeadm, k8s.ExtraOptions, version)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "generating extra configuration for kubelet")
|
||||
}
|
||||
extraFlags := convertToFlags(extraOpts)
|
||||
extraFlags := createFlagsFromExtraArgs(k8s.ExtraOptions)
|
||||
|
||||
r, err := cruntime.New(cruntime.Config{Type: k8s.ContainerRuntime})
|
||||
if err != nil {
|
||||
|
|
@ -475,6 +515,25 @@ sudo systemctl start kubelet
|
|||
return nil
|
||||
}
|
||||
|
||||
// createExtraComponentConfig generates a map of component to extra args for all of the components except kubeadm
|
||||
func createExtraComponentConfig(extraOptions util.ExtraOptionSlice, version semver.Version, componentFeatureArgs string) ([]ComponentExtraArgs, error) {
|
||||
extraArgsSlice, err := NewComponentExtraArgs(extraOptions, version, componentFeatureArgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// kubeadm extra args should not be included in the kubeadm config in the extra args section (instead, they must
|
||||
// be inserted explicitly in the appropriate places or supplied from the command line); here we remove all of the
|
||||
// kubeadm extra args from the slice
|
||||
for i, extraArgs := range extraArgsSlice {
|
||||
if extraArgs.Component == Kubeadm {
|
||||
extraArgsSlice = append(extraArgsSlice[:i], extraArgsSlice[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return extraArgsSlice, nil
|
||||
}
|
||||
|
||||
func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, error) {
|
||||
version, err := ParseKubernetesVersion(k8s.KubernetesVersion)
|
||||
if err != nil {
|
||||
|
|
@ -487,8 +546,7 @@ func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, er
|
|||
return "", errors.Wrap(err, "parses feature gate config for kubeadm and component")
|
||||
}
|
||||
|
||||
// generates a map of component to extra args for apiserver, controller-manager, and scheduler
|
||||
extraComponentConfig, err := NewComponentExtraArgs(k8s.ExtraOptions, version, componentFeatureArgs)
|
||||
extraComponentConfig, err := createExtraComponentConfig(k8s.ExtraOptions, version, componentFeatureArgs)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "generating extra component config for kubeadm")
|
||||
}
|
||||
|
|
@ -502,6 +560,7 @@ func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, er
|
|||
opts := struct {
|
||||
CertDir string
|
||||
ServiceCIDR string
|
||||
PodSubnet string
|
||||
AdvertiseAddress string
|
||||
APIServerPort int
|
||||
KubernetesVersion string
|
||||
|
|
@ -515,6 +574,7 @@ func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, er
|
|||
}{
|
||||
CertDir: util.DefaultCertPath,
|
||||
ServiceCIDR: util.DefaultServiceCIDR,
|
||||
PodSubnet: k8s.ExtraOptions.Get("pod-network-cidr", Kubeadm),
|
||||
AdvertiseAddress: k8s.NodeIP,
|
||||
APIServerPort: nodePort,
|
||||
KubernetesVersion: k8s.KubernetesVersion,
|
||||
|
|
|
|||
|
|
@ -153,6 +153,24 @@ func TestGenerateConfig(t *testing.T) {
|
|||
Key: "scheduler-name",
|
||||
Value: "mini-scheduler",
|
||||
},
|
||||
util.ExtraOption{
|
||||
Component: Kubeadm,
|
||||
Key: "ignore-preflight-errors",
|
||||
Value: "true",
|
||||
},
|
||||
util.ExtraOption{
|
||||
Component: Kubeadm,
|
||||
Key: "dry-run",
|
||||
Value: "true",
|
||||
},
|
||||
}
|
||||
|
||||
extraOptsPodCidr := util.ExtraOptionSlice{
|
||||
util.ExtraOption{
|
||||
Component: Kubeadm,
|
||||
Key: "pod-network-cidr",
|
||||
Value: "192.168.32.0/20",
|
||||
},
|
||||
}
|
||||
|
||||
// Test version policy: Last 4 major releases (slightly looser than our general policy)
|
||||
|
|
@ -177,6 +195,7 @@ func TestGenerateConfig(t *testing.T) {
|
|||
{"crio-options-gates", "crio", false, config.KubernetesConfig{ExtraOptions: extraOpts, FeatureGates: "a=b"}},
|
||||
{"unknown-component", "docker", true, config.KubernetesConfig{ExtraOptions: util.ExtraOptionSlice{util.ExtraOption{Component: "not-a-real-component", Key: "killswitch", Value: "true"}}}},
|
||||
{"containerd-api-port", "containerd", false, config.KubernetesConfig{NodePort: 12345}},
|
||||
{"containerd-pod-network-cidr", "containerd", false, config.KubernetesConfig{ExtraOptions: extraOptsPodCidr}},
|
||||
{"image-repository", "docker", false, config.KubernetesConfig{ImageRepository: "test/repo"}},
|
||||
}
|
||||
for vname, version := range versions {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ etcd:
|
|||
kubernetesVersion: {{.KubernetesVersion}}
|
||||
networking:
|
||||
dnsDomain: cluster.local
|
||||
podSubnet: ""
|
||||
podSubnet: {{if .PodSubnet}}{{.PodSubnet}}{{else}}""{{end}}
|
||||
serviceSubnet: {{.ServiceCIDR}}
|
||||
---
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
|
|
|
|||
43
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__default.yaml
vendored
Normal file
43
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__default.yaml
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: InitConfiguration
|
||||
localAPIEndpoint:
|
||||
advertiseAddress: 1.1.1.1
|
||||
bindPort: 8443
|
||||
bootstrapTokens:
|
||||
- groups:
|
||||
- system:bootstrappers:kubeadm:default-node-token
|
||||
ttl: 24h0m0s
|
||||
usages:
|
||||
- signing
|
||||
- authentication
|
||||
nodeRegistration:
|
||||
criSocket: /run/containerd/containerd.sock
|
||||
name: mk
|
||||
taints: []
|
||||
---
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: ClusterConfiguration
|
||||
apiServer:
|
||||
extraArgs:
|
||||
enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota"
|
||||
certificatesDir: /var/lib/minikube/certs/
|
||||
clusterName: kubernetes
|
||||
controlPlaneEndpoint: localhost:8443
|
||||
dns:
|
||||
type: CoreDNS
|
||||
etcd:
|
||||
local:
|
||||
dataDir: /data/minikube
|
||||
kubernetesVersion: v1.14.1
|
||||
networking:
|
||||
dnsDomain: cluster.local
|
||||
podSubnet: ""
|
||||
serviceSubnet: 10.96.0.0/12
|
||||
---
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
kind: KubeletConfiguration
|
||||
imageGCHighThresholdPercent: 100
|
||||
evictionHard:
|
||||
nodefs.available: "0%"
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
43
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__new.yaml
vendored
Normal file
43
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__new.yaml
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: InitConfiguration
|
||||
localAPIEndpoint:
|
||||
advertiseAddress: 1.1.1.1
|
||||
bindPort: 8443
|
||||
bootstrapTokens:
|
||||
- groups:
|
||||
- system:bootstrappers:kubeadm:default-node-token
|
||||
ttl: 24h0m0s
|
||||
usages:
|
||||
- signing
|
||||
- authentication
|
||||
nodeRegistration:
|
||||
criSocket: /run/containerd/containerd.sock
|
||||
name: mk
|
||||
taints: []
|
||||
---
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: ClusterConfiguration
|
||||
apiServer:
|
||||
extraArgs:
|
||||
enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota"
|
||||
certificatesDir: /var/lib/minikube/certs/
|
||||
clusterName: kubernetes
|
||||
controlPlaneEndpoint: localhost:8443
|
||||
dns:
|
||||
type: CoreDNS
|
||||
etcd:
|
||||
local:
|
||||
dataDir: /data/minikube
|
||||
kubernetesVersion: v1.14.0
|
||||
networking:
|
||||
dnsDomain: cluster.local
|
||||
podSubnet: ""
|
||||
serviceSubnet: 10.96.0.0/12
|
||||
---
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
kind: KubeletConfiguration
|
||||
imageGCHighThresholdPercent: 100
|
||||
evictionHard:
|
||||
nodefs.available: "0%"
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
17
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__obsolete.yaml
vendored
Normal file
17
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__obsolete.yaml
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
apiVersion: kubeadm.k8s.io/v1alpha1
|
||||
kind: MasterConfiguration
|
||||
noTaintMaster: true
|
||||
api:
|
||||
advertiseAddress: 1.1.1.1
|
||||
bindPort: 8443
|
||||
controlPlaneEndpoint: localhost
|
||||
kubernetesVersion: v1.10.0
|
||||
certificatesDir: /var/lib/minikube/certs/
|
||||
networking:
|
||||
serviceSubnet: 10.96.0.0/12
|
||||
etcd:
|
||||
dataDir: /data/minikube
|
||||
nodeName: mk
|
||||
criSocket: /run/containerd/containerd.sock
|
||||
apiServerExtraArgs:
|
||||
admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota"
|
||||
39
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__old.yaml
vendored
Normal file
39
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__old.yaml
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
kind: InitConfiguration
|
||||
apiEndpoint:
|
||||
advertiseAddress: 1.1.1.1
|
||||
bindPort: 8443
|
||||
bootstrapTokens:
|
||||
- groups:
|
||||
- system:bootstrappers:kubeadm:default-node-token
|
||||
ttl: 24h0m0s
|
||||
usages:
|
||||
- signing
|
||||
- authentication
|
||||
nodeRegistration:
|
||||
criSocket: /run/containerd/containerd.sock
|
||||
name: mk
|
||||
taints: []
|
||||
---
|
||||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
kind: ClusterConfiguration
|
||||
apiServerExtraArgs:
|
||||
enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota"
|
||||
certificatesDir: /var/lib/minikube/certs/
|
||||
clusterName: kubernetes
|
||||
controlPlaneEndpoint: localhost:8443
|
||||
etcd:
|
||||
local:
|
||||
dataDir: /data/minikube
|
||||
kubernetesVersion: v1.12.0
|
||||
networking:
|
||||
dnsDomain: cluster.local
|
||||
podSubnet: 192.168.32.0/20
|
||||
serviceSubnet: 10.96.0.0/12
|
||||
---
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
kind: KubeletConfiguration
|
||||
evictionHard:
|
||||
nodefs.available: "0%"
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
39
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__recent.yaml
vendored
Normal file
39
pkg/minikube/bootstrapper/kubeadm/testdata/containerd-pod-network-cidr__recent.yaml
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
kind: InitConfiguration
|
||||
apiEndpoint:
|
||||
advertiseAddress: 1.1.1.1
|
||||
bindPort: 8443
|
||||
bootstrapTokens:
|
||||
- groups:
|
||||
- system:bootstrappers:kubeadm:default-node-token
|
||||
ttl: 24h0m0s
|
||||
usages:
|
||||
- signing
|
||||
- authentication
|
||||
nodeRegistration:
|
||||
criSocket: /run/containerd/containerd.sock
|
||||
name: mk
|
||||
taints: []
|
||||
---
|
||||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
kind: ClusterConfiguration
|
||||
apiServerExtraArgs:
|
||||
enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota"
|
||||
certificatesDir: /var/lib/minikube/certs/
|
||||
clusterName: kubernetes
|
||||
controlPlaneEndpoint: localhost:8443
|
||||
etcd:
|
||||
local:
|
||||
dataDir: /data/minikube
|
||||
kubernetesVersion: v1.13.0
|
||||
networking:
|
||||
dnsDomain: cluster.local
|
||||
podSubnet: 192.168.32.0/20
|
||||
serviceSubnet: 10.96.0.0/12
|
||||
---
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
kind: KubeletConfiguration
|
||||
evictionHard:
|
||||
nodefs.available: "0%"
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
|
|
@ -26,9 +26,6 @@ controllerManager:
|
|||
extraArgs:
|
||||
feature-gates: "a=b"
|
||||
kube-api-burst: "32"
|
||||
kubeadm:
|
||||
extraArgs:
|
||||
feature-gates: "a=b"
|
||||
scheduler:
|
||||
extraArgs:
|
||||
feature-gates: "a=b"
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@ controllerManager:
|
|||
extraArgs:
|
||||
feature-gates: "a=b"
|
||||
kube-api-burst: "32"
|
||||
kubeadm:
|
||||
extraArgs:
|
||||
feature-gates: "a=b"
|
||||
scheduler:
|
||||
extraArgs:
|
||||
feature-gates: "a=b"
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ apiServerExtraArgs:
|
|||
controllerManagerExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
kube-api-burst: "32"
|
||||
kubeadmExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
schedulerExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
scheduler-name: "mini-scheduler"
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ apiServerExtraArgs:
|
|||
controllerManagerExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
kube-api-burst: "32"
|
||||
kubeadmExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
schedulerExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
scheduler-name: "mini-scheduler"
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ apiServerExtraArgs:
|
|||
controllerManagerExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
kube-api-burst: "32"
|
||||
kubeadmExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
schedulerExtraArgs:
|
||||
feature-gates: "a=b"
|
||||
scheduler-name: "mini-scheduler"
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ func (e *ExtraOption) String() string {
|
|||
// ExtraOptionSlice is a slice of ExtraOption
|
||||
type ExtraOptionSlice []ExtraOption
|
||||
|
||||
// ComponentExtraOptionMap maps components to their extra opts, which is a map of keys to values
|
||||
type ComponentExtraOptionMap map[string]map[string]string
|
||||
|
||||
// Set parses the string value into a slice
|
||||
func (es *ExtraOptionSlice) Set(value string) error {
|
||||
// The component is the value before the first dot.
|
||||
|
|
@ -68,7 +71,39 @@ func (es *ExtraOptionSlice) String() string {
|
|||
return strings.Join(s, " ")
|
||||
}
|
||||
|
||||
// Get finds and returns the value of an argument with the specified key and component (optional) or an empty string
|
||||
// if not found. If component contains more than one value, the value for the first component found is returned. If
|
||||
// component is not specified, all of the components are used.
|
||||
func (es *ExtraOptionSlice) Get(key string, component ...string) string {
|
||||
for _, opt := range *es {
|
||||
if component == nil || ContainsString(component, opt.Component) {
|
||||
if opt.Key == key {
|
||||
return opt.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// AsMap converts the slice to a map of components to a map of keys and values.
|
||||
func (es *ExtraOptionSlice) AsMap() ComponentExtraOptionMap {
|
||||
ret := ComponentExtraOptionMap{}
|
||||
for _, opt := range *es {
|
||||
if _, ok := ret[opt.Component]; !ok {
|
||||
ret[opt.Component] = map[string]string{opt.Key: opt.Value}
|
||||
} else {
|
||||
ret[opt.Component][opt.Key] = opt.Value
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Type returns the type
|
||||
func (es *ExtraOptionSlice) Type() string {
|
||||
return "ExtraOption"
|
||||
}
|
||||
|
||||
// Get returns the extra option map of keys to values for the specified component
|
||||
func (cm ComponentExtraOptionMap) Get(component string) map[string]string {
|
||||
return cm[component]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,3 +78,57 @@ func TestValidFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
extraOptions := ExtraOptionSlice{
|
||||
ExtraOption{Component: "c1", Key: "bar", Value: "c1-bar"},
|
||||
ExtraOption{Component: "c1", Key: "bar-baz", Value: "c1-bar-baz"},
|
||||
ExtraOption{Component: "c2", Key: "bar", Value: "c2-bar"},
|
||||
ExtraOption{Component: "c3", Key: "bar", Value: "c3-bar"},
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
searchKey string
|
||||
searchComponent []string
|
||||
expRes string
|
||||
values ExtraOptionSlice
|
||||
}{
|
||||
{"nonexistent", nil, "", extraOptions},
|
||||
{"nonexistent", []string{"c1"}, "", extraOptions},
|
||||
{"bar", []string{"c2"}, "c2-bar", extraOptions},
|
||||
{"bar", []string{"c2", "c3"}, "c2-bar", extraOptions},
|
||||
{"bar", nil, "c1-bar", extraOptions},
|
||||
} {
|
||||
if res := tc.values.Get(tc.searchKey, tc.searchComponent...); res != tc.expRes {
|
||||
t.Errorf("Unexpected value. Expected %s, got %s", tc.expRes, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsMap(t *testing.T) {
|
||||
extraOptions := ExtraOptionSlice{
|
||||
ExtraOption{Component: "c1", Key: "bar", Value: "c1-bar"},
|
||||
ExtraOption{Component: "c1", Key: "bar-baz", Value: "c1-bar-baz"},
|
||||
ExtraOption{Component: "c2", Key: "bar", Value: "c2-bar"},
|
||||
ExtraOption{Component: "c3", Key: "bar", Value: "c3-bar"},
|
||||
}
|
||||
|
||||
expectedRes := ComponentExtraOptionMap{
|
||||
"c1": {
|
||||
"bar": "c1-bar",
|
||||
"bar-baz": "c1-bar-baz",
|
||||
},
|
||||
"c2": {
|
||||
"bar": "c2-bar",
|
||||
},
|
||||
"c3": {
|
||||
"bar": "c3-bar",
|
||||
},
|
||||
}
|
||||
|
||||
res := extraOptions.AsMap()
|
||||
|
||||
if !reflect.DeepEqual(expectedRes, res) {
|
||||
t.Errorf("Unexpected value. Expected %s, got %s", expectedRes, res)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,3 +273,14 @@ func ConcatStrings(src []string, prefix string, postfix string) []string {
|
|||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// ContainsString checks if a given slice of strings contains the provided string.
|
||||
// If a modifier func is provided, it is called with the slice item before the comparation.
|
||||
func ContainsString(slice []string, s string) bool {
|
||||
for _, item := range slice {
|
||||
if item == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ func TestStartStop(t *testing.T) {
|
|||
"ServerSideApply=true",
|
||||
"--network-plugin=cni",
|
||||
"--extra-config=kubelet.network-plugin=cni",
|
||||
"--extra-config=kubeadm.pod-network-cidr=192.168.111.111/16",
|
||||
fmt.Sprintf("--kubernetes-version=%s", constants.NewestKubernetesVersion),
|
||||
}},
|
||||
{"containerd_and_non_default_apiserver_port", []string{
|
||||
|
|
|
|||
Loading…
Reference in New Issue