Merge pull request #71040 from fabriziopandini/kubeadm-phases-local-flags

Kubeadm phases - add local flags
pull/58/head
k8s-ci-robot 2018-11-14 17:25:30 -08:00 committed by GitHub
commit bb2fcd90f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 109 additions and 71 deletions

View File

@ -155,7 +155,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
// defines additional flag that are not used by the init command but that could be eventually used
// by the sub-commands automatically generated for phases
initRunner.SetPhaseSubcommandsAdditionalFlags(func(flags *flag.FlagSet) {
initRunner.SetAdditionalFlags(func(flags *flag.FlagSet) {
options.AddImageMetaFlags(flags, &initOptions.externalcfg.ImageRepository)
options.AddKubeConfigFlag(flags, &initOptions.kubeconfigPath)
options.AddKubeConfigDirFlag(flags, &initOptions.kubeconfigDir)

View File

@ -47,23 +47,23 @@ type addonData interface {
// NewAddonPhase returns the addon Cobra command
func NewAddonPhase() workflow.Phase {
return workflow.Phase{
Name: "addon",
Short: "Installs required addons for passing Conformance tests",
CmdFlags: getAddonPhaseFlags("all"),
Name: "addon",
Short: "Installs required addons for passing Conformance tests",
InheritFlags: getAddonPhaseFlags("all"),
Phases: []workflow.Phase{
{
Name: "coredns",
Short: "Installs the CoreDNS addon to a Kubernetes cluster",
Long: coreDNSAddonLongDesc,
CmdFlags: getAddonPhaseFlags("coredns"),
Run: runCoreDNSAddon,
Name: "coredns",
Short: "Installs the CoreDNS addon to a Kubernetes cluster",
Long: coreDNSAddonLongDesc,
InheritFlags: getAddonPhaseFlags("coredns"),
Run: runCoreDNSAddon,
},
{
Name: "kube-proxy",
Short: "Installs the kube-proxy addon to a Kubernetes cluster",
Long: kubeProxyAddonLongDesc,
CmdFlags: getAddonPhaseFlags("kube-proxy"),
Run: runKubeProxyAddon,
Name: "kube-proxy",
Short: "Installs the kube-proxy addon to a Kubernetes cluster",
Long: kubeProxyAddonLongDesc,
InheritFlags: getAddonPhaseFlags("kube-proxy"),
Run: runKubeProxyAddon,
},
},
}

View File

@ -64,7 +64,7 @@ func NewBootstrapTokenPhase() workflow.Phase {
Short: "Generates bootstrap tokens used to join a node to a cluster",
Example: bootstrapTokenExamples,
Long: bootstrapTokenLongDesc,
CmdFlags: []string{
InheritFlags: []string{
options.CfgPath,
options.KubeconfigDir,
options.SkipTokenPrint,

View File

@ -60,11 +60,11 @@ type certsData interface {
// NewCertsPhase returns the phase for the certs
func NewCertsPhase() workflow.Phase {
return workflow.Phase{
Name: "certs",
Short: "Certificate generation",
Phases: newCertSubPhases(),
Run: runCerts,
CmdFlags: getCertPhaseFlags("all"),
Name: "certs",
Short: "Certificate generation",
Phases: newCertSubPhases(),
Run: runCerts,
InheritFlags: getCertPhaseFlags("all"),
}
}
@ -107,8 +107,8 @@ func newCertSubPhase(certSpec *certsphase.KubeadmCert, run func(c workflow.RunDa
certSpec.BaseName,
getSANDescription(certSpec),
),
Run: run,
CmdFlags: getCertPhaseFlags(certSpec.Name),
Run: run,
InheritFlags: getCertPhaseFlags(certSpec.Name),
}
return phase
}

View File

@ -77,18 +77,18 @@ func NewControlPlanePhase() workflow.Phase {
newControlPlaneSubPhase(kubeadmconstants.KubeControllerManager),
newControlPlaneSubPhase(kubeadmconstants.KubeScheduler),
},
Run: runControlPlanePhase,
CmdFlags: getControlPlanePhaseFlags("all"),
Run: runControlPlanePhase,
InheritFlags: getControlPlanePhaseFlags("all"),
}
return phase
}
func newControlPlaneSubPhase(component string) workflow.Phase {
phase := workflow.Phase{
Name: controlPlanePhaseProperties[component].name,
Short: controlPlanePhaseProperties[component].short,
Run: runControlPlaneSubPhase(component),
CmdFlags: getControlPlanePhaseFlags(component),
Name: controlPlanePhaseProperties[component].name,
Short: controlPlanePhaseProperties[component].short,
Run: runControlPlaneSubPhase(component),
InheritFlags: getControlPlanePhaseFlags(component),
}
return phase
}

View File

@ -54,18 +54,18 @@ func NewEtcdPhase() workflow.Phase {
Phases: []workflow.Phase{
newEtcdLocalSubPhase(),
},
CmdFlags: getEtcdPhaseFlags(),
InheritFlags: getEtcdPhaseFlags(),
}
return phase
}
func newEtcdLocalSubPhase() workflow.Phase {
phase := workflow.Phase{
Name: "local",
Short: "Generates the static Pod manifest file for a local, single-node local etcd instance.",
Example: etcdLocalExample,
Run: runEtcdPhaseLocal(),
CmdFlags: getEtcdPhaseFlags(),
Name: "local",
Short: "Generates the static Pod manifest file for a local, single-node local etcd instance.",
Example: etcdLocalExample,
Run: runEtcdPhaseLocal(),
InheritFlags: getEtcdPhaseFlags(),
}
return phase
}

View File

@ -83,19 +83,19 @@ func NewKubeConfigPhase() workflow.Phase {
NewKubeConfigFilePhase(kubeadmconstants.ControllerManagerKubeConfigFileName),
NewKubeConfigFilePhase(kubeadmconstants.SchedulerKubeConfigFileName),
},
Run: runKubeConfig,
CmdFlags: getKubeConfigPhaseFlags("all"),
Run: runKubeConfig,
InheritFlags: getKubeConfigPhaseFlags("all"),
}
}
// NewKubeConfigFilePhase creates a kubeadm workflow phase that creates a kubeconfig file.
func NewKubeConfigFilePhase(kubeConfigFileName string) workflow.Phase {
return workflow.Phase{
Name: kubeconfigFilePhaseProperties[kubeConfigFileName].name,
Short: kubeconfigFilePhaseProperties[kubeConfigFileName].short,
Long: fmt.Sprintf(kubeconfigFilePhaseProperties[kubeConfigFileName].long, kubeConfigFileName),
Run: runKubeConfigFile(kubeConfigFileName),
CmdFlags: getKubeConfigPhaseFlags(kubeConfigFileName),
Name: kubeconfigFilePhaseProperties[kubeConfigFileName].name,
Short: kubeconfigFilePhaseProperties[kubeConfigFileName].short,
Long: fmt.Sprintf(kubeconfigFilePhaseProperties[kubeConfigFileName].long, kubeConfigFileName),
Run: runKubeConfigFile(kubeConfigFileName),
InheritFlags: getKubeConfigPhaseFlags(kubeConfigFileName),
}
}

View File

@ -50,7 +50,7 @@ func NewKubeletStartPhase() workflow.Phase {
Long: "Writes a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)starts kubelet.",
Example: kubeletStartPhaseExample,
Run: runKubeletStart,
CmdFlags: []string{
InheritFlags: []string{
options.CfgPath,
options.NodeCRISocket,
options.NodeName,

View File

@ -48,7 +48,7 @@ func NewMarkControlPlanePhase() workflow.Phase {
Name: "mark-control-plane",
Short: "Mark a node as a control-plane",
Example: markControlPlaneExample,
CmdFlags: []string{
InheritFlags: []string{
options.NodeName,
},
Run: runMarkControlPlane,

View File

@ -53,7 +53,7 @@ func NewPreflightMasterPhase() workflow.Phase {
Long: "Run master pre-flight checks, functionally equivalent to what implemented by kubeadm init.",
Example: masterPreflightExample,
Run: runPreflightMaster,
CmdFlags: []string{
InheritFlags: []string{
options.CfgPath,
options.IgnorePreflightErrors,
},

View File

@ -72,20 +72,20 @@ func NewUploadConfigPhase() workflow.Phase {
Long: cmdutil.MacroCommandLongDescription,
Phases: []workflow.Phase{
{
Name: "kubeadm",
Short: "Uploads the kubeadm ClusterConfiguration to a ConfigMap",
Long: uploadKubeadmConfigLongDesc,
Example: uploadKubeadmConfigExample,
Run: runUploadKubeadmConfig,
CmdFlags: getUploadConfigPhaseFlags(),
Name: "kubeadm",
Short: "Uploads the kubeadm ClusterConfiguration to a ConfigMap",
Long: uploadKubeadmConfigLongDesc,
Example: uploadKubeadmConfigExample,
Run: runUploadKubeadmConfig,
InheritFlags: getUploadConfigPhaseFlags(),
},
{
Name: "kubelet",
Short: "Uploads the kubelet component config to a ConfigMap",
Long: uploadKubeletConfigLongDesc,
Example: uploadKubeletConfigExample,
Run: runUploadKubeletConfig,
CmdFlags: getUploadConfigPhaseFlags(),
Name: "kubelet",
Short: "Uploads the kubelet component config to a ConfigMap",
Long: uploadKubeletConfigLongDesc,
Example: uploadKubeletConfigExample,
Run: runUploadKubeletConfig,
InheritFlags: getUploadConfigPhaseFlags(),
},
},
}

View File

@ -16,6 +16,8 @@ limitations under the License.
package workflow
import "github.com/spf13/pflag"
// Phase provides an implementation of a workflow phase that allows
// creation of new phases by simply instantiating a variable of this type.
type Phase struct {
@ -53,11 +55,17 @@ type Phase struct {
// If this function return nil, the phase action is always executed.
RunIf func(data RunData) (bool, error)
// CmdFlags defines the list of flags that should be assigned to the cobra command generated
// for this phase; flags are inherited from the parent command or defined as additional flags
// in the phase runner. If the values is not set or empty, no flags will be assigned to the command
// InheritFlags defines the list of flags that the cobra command generated for this phase should Inherit
// from local flags defined in the parent command / or additional flags defined in the phase runner.
// If the values is not set or empty, no flags will be assigned to the command
// Nb. global flags are automatically inherited by nested cobra command
CmdFlags []string
InheritFlags []string
// LocalFlags defines the list of flags that should be assigned to the cobra command generated
// for this phase.
// Nb. if two or phases have the same local flags, please consider using local flags in the parent command
// or additional flags defined in the phase runner.
LocalFlags *pflag.FlagSet
}
// AppendPhase adds the given phase to the nested, ordered sequence of phases.

View File

@ -60,8 +60,8 @@ type Runner struct {
// more than one time)
runData RunData
// cmdAdditionalFlags holds additional flags that could be added to the subcommands generated
// for each phase. Flags could be inherited from the parent command too
// cmdAdditionalFlags holds additional, shared flags that could be added to the subcommands generated
// for phases. Flags could be inherited from the parent command too or added directly to each phase
cmdAdditionalFlags *pflag.FlagSet
// phaseRunners is part of the internal state of the runner and provides
@ -269,10 +269,11 @@ func (e *Runner) Help(cmdUse string) string {
return line
}
// SetPhaseSubcommandsAdditionalFlags allows to define flags to be added
// SetAdditionalFlags allows to define flags to be added
// to the subcommands generated for each phase (but not existing in the parent command).
// Please note that this command needs to be done before BindToCommand.
func (e *Runner) SetPhaseSubcommandsAdditionalFlags(fn func(*pflag.FlagSet)) {
// Nb. if a flag is used only by one phase, please consider using phase LocalFlags.
func (e *Runner) SetAdditionalFlags(fn func(*pflag.FlagSet)) {
// creates a new NewFlagSet
e.cmdAdditionalFlags = pflag.NewFlagSet("phaseAdditionalFlags", pflag.ContinueOnError)
// invokes the function that sets additional flags
@ -325,11 +326,18 @@ func (e *Runner) BindToCommand(cmd *cobra.Command) {
// makes the new command inherits local flags from the parent command
// Nb. global flags will be inherited automatically
inheritsFlags(cmd.Flags(), phaseCmd.Flags(), p.CmdFlags)
inheritsFlags(cmd.Flags(), phaseCmd.Flags(), p.InheritFlags)
// If defined, additional flags for phases should be added as well
// makes the new command inherits additional flags for phases
if e.cmdAdditionalFlags != nil {
inheritsFlags(e.cmdAdditionalFlags, phaseCmd.Flags(), p.CmdFlags)
inheritsFlags(e.cmdAdditionalFlags, phaseCmd.Flags(), p.InheritFlags)
}
// If defined, added phase local flags
if p.LocalFlags != nil {
p.LocalFlags.VisitAll(func(f *pflag.Flag) {
phaseCmd.Flags().AddFlag(f)
})
}
// adds the command to parent

View File

@ -284,14 +284,25 @@ func TestHelp(t *testing.T) {
func phaseBuilder4(name string, cmdFlags []string, phases ...Phase) Phase {
return Phase{
Name: name,
Phases: phases,
CmdFlags: cmdFlags,
Name: name,
Phases: phases,
InheritFlags: cmdFlags,
}
}
func phaseBuilder5(name string, flags *pflag.FlagSet) Phase {
return Phase{
Name: name,
LocalFlags: flags,
}
}
func TestBindToCommand(t *testing.T) {
var dummy string
localFlags := pflag.NewFlagSet("dummy", pflag.ContinueOnError)
localFlags.StringVarP(&dummy, "flag4", "d", "d", "d")
var usecases = []struct {
name string
runner Runner
@ -339,6 +350,15 @@ func TestBindToCommand(t *testing.T) {
"phase baz": {"flag1"},
},
},
{
name: "it should be possible to apply custom flags to single phases",
runner: Runner{
Phases: []Phase{phaseBuilder5("foo", localFlags)},
},
expectedCmdAndFlags: map[string][]string{
"phase foo": {"flag4"},
},
},
{
name: "all the above applies to nested phases too",
runner: Runner{
@ -346,6 +366,7 @@ func TestBindToCommand(t *testing.T) {
phaseBuilder4("foo", []string{"flag3"},
phaseBuilder4("bar", []string{"flag1", "flag2", "flag3"}),
phaseBuilder4("baz", []string{"flag1"}), //test if additional flags are filtered too
phaseBuilder5("qux", localFlags),
),
},
},
@ -357,6 +378,7 @@ func TestBindToCommand(t *testing.T) {
"phase foo": {"flag3"},
"phase foo bar": {"flag1", "flag2", "flag3"},
"phase foo baz": {"flag1"},
"phase foo qux": {"flag4"},
},
},
}
@ -372,7 +394,7 @@ func TestBindToCommand(t *testing.T) {
cmd.Flags().StringVarP(&dummy2, "flag2", "b", "b", "b")
if rt.setAdditionalFlags != nil {
rt.runner.SetPhaseSubcommandsAdditionalFlags(rt.setAdditionalFlags)
rt.runner.SetAdditionalFlags(rt.setAdditionalFlags)
}
rt.runner.BindToCommand(cmd)