kubeadm phases add all subcommands

This commit is contained in:
fabriziopandini 2018-11-16 16:39:04 +01:00
parent 9e2820e4c9
commit 1308c7d2f5
8 changed files with 92 additions and 25 deletions

View File

@ -23,6 +23,7 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
dnsaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns" dnsaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
proxyaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy" proxyaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy"
"k8s.io/kubernetes/pkg/util/normalizer" "k8s.io/kubernetes/pkg/util/normalizer"
@ -47,10 +48,16 @@ type addonData interface {
// NewAddonPhase returns the addon Cobra command // NewAddonPhase returns the addon Cobra command
func NewAddonPhase() workflow.Phase { func NewAddonPhase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "addon", Name: "addon",
Short: "Installs required addons for passing Conformance tests", Short: "Installs required addons for passing Conformance tests",
InheritFlags: getAddonPhaseFlags("all"), Long: cmdutil.MacroCommandLongDescription,
Phases: []workflow.Phase{ Phases: []workflow.Phase{
{
Name: "all",
Short: "Installs all the addons",
InheritFlags: getAddonPhaseFlags("all"),
RunAllSiblings: true,
},
{ {
Name: "coredns", Name: "coredns",
Short: "Installs the CoreDNS addon to a Kubernetes cluster", Short: "Installs the CoreDNS addon to a Kubernetes cluster",

View File

@ -66,12 +66,11 @@ type certsData interface {
// NewCertsPhase returns the phase for the certs // NewCertsPhase returns the phase for the certs
func NewCertsPhase() workflow.Phase { func NewCertsPhase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "certs", Name: "certs",
Short: "Certificate generation", Short: "Certificate generation",
Phases: newCertSubPhases(), Phases: newCertSubPhases(),
Run: runCerts, Run: runCerts,
InheritFlags: getCertPhaseFlags("all"), Long: cmdutil.MacroCommandLongDescription,
LocalFlags: localFlags(),
} }
} }
@ -86,6 +85,17 @@ func localFlags() *pflag.FlagSet {
func newCertSubPhases() []workflow.Phase { func newCertSubPhases() []workflow.Phase {
subPhases := []workflow.Phase{} subPhases := []workflow.Phase{}
// All subphase
allPhase := workflow.Phase{
Name: "all",
Short: "Generates all certificates",
InheritFlags: getCertPhaseFlags("all"),
RunAllSiblings: true,
LocalFlags: localFlags(),
}
subPhases = append(subPhases, allPhase)
certTree, _ := certsphase.GetDefaultCertList().AsMap().CertTree() certTree, _ := certsphase.GetDefaultCertList().AsMap().CertTree()
for ca, certList := range certTree { for ca, certList := range certTree {

View File

@ -19,9 +19,11 @@ package phases
import ( import (
"errors" "errors"
"fmt" "fmt"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
"k8s.io/kubernetes/pkg/util/normalizer" "k8s.io/kubernetes/pkg/util/normalizer"
@ -69,16 +71,21 @@ func getPhaseDescription(component string) string {
// NewControlPlanePhase creates a kubeadm workflow phase that implements bootstrapping the control plane. // NewControlPlanePhase creates a kubeadm workflow phase that implements bootstrapping the control plane.
func NewControlPlanePhase() workflow.Phase { func NewControlPlanePhase() workflow.Phase {
phase := workflow.Phase{ phase := workflow.Phase{
Name: "control-plane", Name: "control-plane",
Short: "Generates all static Pod manifest files necessary to establish the control plane", Short: "Generates all static Pod manifest files necessary to establish the control plane",
Example: controlPlaneExample, Long: cmdutil.MacroCommandLongDescription,
Phases: []workflow.Phase{ Phases: []workflow.Phase{
{
Name: "all",
Short: "Generates all static Pod manifest files",
InheritFlags: getControlPlanePhaseFlags("all"),
RunAllSiblings: true,
},
newControlPlaneSubPhase(kubeadmconstants.KubeAPIServer), newControlPlaneSubPhase(kubeadmconstants.KubeAPIServer),
newControlPlaneSubPhase(kubeadmconstants.KubeControllerManager), newControlPlaneSubPhase(kubeadmconstants.KubeControllerManager),
newControlPlaneSubPhase(kubeadmconstants.KubeScheduler), newControlPlaneSubPhase(kubeadmconstants.KubeScheduler),
}, },
Run: runControlPlanePhase, Run: runControlPlanePhase,
InheritFlags: getControlPlanePhaseFlags("all"),
} }
return phase return phase
} }

View File

@ -24,6 +24,7 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
"k8s.io/kubernetes/pkg/util/normalizer" "k8s.io/kubernetes/pkg/util/normalizer"
) )
@ -48,13 +49,12 @@ type etcdData interface {
// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd. // NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewEtcdPhase() workflow.Phase { func NewEtcdPhase() workflow.Phase {
phase := workflow.Phase{ phase := workflow.Phase{
Name: "etcd", Name: "etcd",
Short: "Generates static Pod manifest file for local etcd.", Short: "Generates static Pod manifest file for local etcd.",
Example: etcdLocalExample, Long: cmdutil.MacroCommandLongDescription,
Phases: []workflow.Phase{ Phases: []workflow.Phase{
newEtcdLocalSubPhase(), newEtcdLocalSubPhase(),
}, },
InheritFlags: getEtcdPhaseFlags(),
} }
return phase return phase
} }

View File

@ -23,6 +23,7 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
"k8s.io/kubernetes/pkg/util/normalizer" "k8s.io/kubernetes/pkg/util/normalizer"
@ -77,14 +78,20 @@ func NewKubeConfigPhase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "kubeconfig", Name: "kubeconfig",
Short: "Generates all kubeconfig files necessary to establish the control plane and the admin kubeconfig file", Short: "Generates all kubeconfig files necessary to establish the control plane and the admin kubeconfig file",
Long: cmdutil.MacroCommandLongDescription,
Phases: []workflow.Phase{ Phases: []workflow.Phase{
{
Name: "all",
Short: "Generates all kubeconfig files",
InheritFlags: getKubeConfigPhaseFlags("all"),
RunAllSiblings: true,
},
NewKubeConfigFilePhase(kubeadmconstants.AdminKubeConfigFileName), NewKubeConfigFilePhase(kubeadmconstants.AdminKubeConfigFileName),
NewKubeConfigFilePhase(kubeadmconstants.KubeletKubeConfigFileName), NewKubeConfigFilePhase(kubeadmconstants.KubeletKubeConfigFileName),
NewKubeConfigFilePhase(kubeadmconstants.ControllerManagerKubeConfigFileName), NewKubeConfigFilePhase(kubeadmconstants.ControllerManagerKubeConfigFileName),
NewKubeConfigFilePhase(kubeadmconstants.SchedulerKubeConfigFileName), NewKubeConfigFilePhase(kubeadmconstants.SchedulerKubeConfigFileName),
}, },
Run: runKubeConfig, Run: runKubeConfig,
InheritFlags: getKubeConfigPhaseFlags("all"),
} }
} }

View File

@ -71,6 +71,11 @@ func NewUploadConfigPhase() workflow.Phase {
Short: "Uploads the kubeadm and kubelet configuration to a ConfigMap", Short: "Uploads the kubeadm and kubelet configuration to a ConfigMap",
Long: cmdutil.MacroCommandLongDescription, Long: cmdutil.MacroCommandLongDescription,
Phases: []workflow.Phase{ Phases: []workflow.Phase{
{
Name: "all",
Short: "Uploads all configuration to a config map",
RunAllSiblings: true,
},
{ {
Name: "kubeadm", Name: "kubeadm",
Short: "Uploads the kubeadm ClusterConfiguration to a ConfigMap", Short: "Uploads the kubeadm ClusterConfiguration to a ConfigMap",

View File

@ -45,6 +45,11 @@ type Phase struct {
// Phases defines a nested, ordered sequence of phases. // Phases defines a nested, ordered sequence of phases.
Phases []Phase Phases []Phase
// RunAllSiblings allows to assign to a phase the responsibility to
// run all the sibling phases
// Nb. phase marked as RunAllSiblings can not have Run functions
RunAllSiblings bool
// Run defines a function implementing the phase action. // Run defines a function implementing the phase action.
// It is recommended to implent type assertion, e.g. using golang type switch, // It is recommended to implent type assertion, e.g. using golang type switch,
// for validating the RunData type. // for validating the RunData type.

View File

@ -211,6 +211,12 @@ func (e *Runner) Run() error {
return nil return nil
} }
// Errors if phases that are meant to create special subcommands only
// are wrongly assigned Run Methods
if p.RunAllSiblings && (p.RunIf != nil || p.Run != nil) {
return errors.Wrapf(err, "phase marked as RunAllSiblings can not have Run functions %s", p.generatedName)
}
// If the phase defines a condition to be checked before executing the phase action. // If the phase defines a condition to be checked before executing the phase action.
if p.RunIf != nil { if p.RunIf != nil {
// Check the condition and returns if the condition isn't satisfied (or fails) // Check the condition and returns if the condition isn't satisfied (or fails)
@ -244,7 +250,7 @@ func (e *Runner) Help(cmdUse string) string {
// computes the max length of for each phase use line // computes the max length of for each phase use line
maxLength := 0 maxLength := 0
e.visitAll(func(p *phaseRunner) error { e.visitAll(func(p *phaseRunner) error {
if !p.Hidden { if !p.Hidden && !p.RunAllSiblings {
length := len(p.use) length := len(p.use)
if maxLength < length { if maxLength < length {
maxLength = length maxLength = length
@ -259,7 +265,7 @@ func (e *Runner) Help(cmdUse string) string {
line += "```\n" line += "```\n"
offset := 2 offset := 2
e.visitAll(func(p *phaseRunner) error { e.visitAll(func(p *phaseRunner) error {
if !p.Hidden { if !p.Hidden && !p.RunAllSiblings {
padding := maxLength - len(p.use) + offset padding := maxLength - len(p.use) + offset
line += strings.Repeat(" ", offset*p.level) // indentation line += strings.Repeat(" ", offset*p.level) // indentation
line += p.use // name + aliases line += p.use // name + aliases
@ -312,17 +318,31 @@ func (e *Runner) BindToCommand(cmd *cobra.Command) {
return nil return nil
} }
// creates nested phase subcommand // initialize phase selector
var phaseCmd = &cobra.Command{ phaseSelector := p.generatedName
// if requested, set the phase to run all the sibling phases
if p.RunAllSiblings {
phaseSelector = p.parent.generatedName
}
// creates phase subcommand
phaseCmd := &cobra.Command{
Use: strings.ToLower(p.Name), Use: strings.ToLower(p.Name),
Short: p.Short, Short: p.Short,
Long: p.Long, Long: p.Long,
Example: p.Example, Example: p.Example,
Aliases: p.Aliases, Aliases: p.Aliases,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
// if the phase has subphases, print the help and exits
if len(p.Phases) > 0 {
cmd.Help()
return
}
// overrides the command triggering the Runner using the phaseCmd // overrides the command triggering the Runner using the phaseCmd
e.runCmd = cmd e.runCmd = cmd
e.Options.FilterPhases = []string{p.generatedName} e.Options.FilterPhases = []string{phaseSelector}
if err := e.Run(); err != nil { if err := e.Run(); err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
os.Exit(1) os.Exit(1)
@ -405,6 +425,12 @@ func (e *Runner) prepareForExecution() {
e.phaseRunners = []*phaseRunner{} e.phaseRunners = []*phaseRunner{}
var parentRunner *phaseRunner var parentRunner *phaseRunner
for _, phase := range e.Phases { for _, phase := range e.Phases {
// skips phases that are meant to create special subcommands only
if phase.RunAllSiblings {
continue
}
// add phases to the execution list
addPhaseRunner(e, parentRunner, phase) addPhaseRunner(e, parentRunner, phase)
} }
} }