mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
cleanup: kubeadm upgrade plan supports json/yaml output
Co-authored-by: Lubomir I. Ivanov <neolit123@gmail.com>
This commit is contained in:
parent
79ecd60208
commit
22fb3be96d
@ -78,7 +78,7 @@ type ComponentConfigVersionState struct {
|
||||
type UpgradePlan struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
Components []*ComponentUpgradePlan
|
||||
Components []ComponentUpgradePlan
|
||||
|
||||
ConfigVersions []ComponentConfigVersionState
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ type ComponentConfigVersionState struct {
|
||||
type UpgradePlan struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
Components []*ComponentUpgradePlan `json:"components"`
|
||||
Components []ComponentUpgradePlan `json:"components"`
|
||||
|
||||
ConfigVersions []ComponentConfigVersionState `json:"configVersions"`
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ func Convert_output_Images_To_v1alpha2_Images(in *output.Images, out *Images, s
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha2_UpgradePlan_To_output_UpgradePlan(in *UpgradePlan, out *output.UpgradePlan, s conversion.Scope) error {
|
||||
out.Components = *(*[]*output.ComponentUpgradePlan)(unsafe.Pointer(&in.Components))
|
||||
out.Components = *(*[]output.ComponentUpgradePlan)(unsafe.Pointer(&in.Components))
|
||||
out.ConfigVersions = *(*[]output.ComponentConfigVersionState)(unsafe.Pointer(&in.ConfigVersions))
|
||||
return nil
|
||||
}
|
||||
@ -191,7 +191,7 @@ func Convert_v1alpha2_UpgradePlan_To_output_UpgradePlan(in *UpgradePlan, out *ou
|
||||
}
|
||||
|
||||
func autoConvert_output_UpgradePlan_To_v1alpha2_UpgradePlan(in *output.UpgradePlan, out *UpgradePlan, s conversion.Scope) error {
|
||||
out.Components = *(*[]*ComponentUpgradePlan)(unsafe.Pointer(&in.Components))
|
||||
out.Components = *(*[]ComponentUpgradePlan)(unsafe.Pointer(&in.Components))
|
||||
out.ConfigVersions = *(*[]ComponentConfigVersionState)(unsafe.Pointer(&in.ConfigVersions))
|
||||
return nil
|
||||
}
|
||||
|
@ -128,14 +128,8 @@ func (in *UpgradePlan) DeepCopyInto(out *UpgradePlan) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Components != nil {
|
||||
in, out := &in.Components, &out.Components
|
||||
*out = make([]*ComponentUpgradePlan, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(ComponentUpgradePlan)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
*out = make([]ComponentUpgradePlan, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ConfigVersions != nil {
|
||||
in, out := &in.ConfigVersions, &out.ConfigVersions
|
||||
|
10
cmd/kubeadm/app/apis/output/zz_generated.deepcopy.go
generated
10
cmd/kubeadm/app/apis/output/zz_generated.deepcopy.go
generated
@ -128,14 +128,8 @@ func (in *UpgradePlan) DeepCopyInto(out *UpgradePlan) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Components != nil {
|
||||
in, out := &in.Components, &out.Components
|
||||
*out = make([]*ComponentUpgradePlan, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(ComponentUpgradePlan)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
*out = make([]ComponentUpgradePlan, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ConfigVersions != nil {
|
||||
in, out := &in.ConfigVersions, &out.ConfigVersions
|
||||
|
@ -39,7 +39,6 @@ import (
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -333,7 +332,7 @@ func getInternalCfg(cfgPath string, kubeconfigPath string, cfg kubeadmapiv1.Clus
|
||||
if cfgPath == "" {
|
||||
client, err := kubeconfigutil.ClientSetFromFile(kubeconfigPath)
|
||||
if err == nil {
|
||||
internalcfg, err := configutil.FetchInitConfigurationFromCluster(client, &output.TextPrinter{}, logPrefix, false, false)
|
||||
internalcfg, err := configutil.FetchInitConfigurationFromCluster(client, nil, logPrefix, false, false)
|
||||
if err == nil {
|
||||
fmt.Println() // add empty line to separate the FetchInitConfigurationFromCluster output from the command output
|
||||
return internalcfg, nil
|
||||
|
@ -371,7 +371,7 @@ func newCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Comman
|
||||
|
||||
printer, err := outputFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "could not construct output printer")
|
||||
}
|
||||
|
||||
imagesList, err := NewImagesList(cfgPath, externalcfg)
|
||||
@ -424,7 +424,7 @@ func (itp *imageTextPrinter) PrintObj(obj runtime.Object, writer io.Writer) erro
|
||||
// imageTextPrintFlags provides flags necessary for printing image in a text form.
|
||||
type imageTextPrintFlags struct{}
|
||||
|
||||
// ToPrinter returns kubeadm printer for the text output format
|
||||
// ToPrinter returns a kubeadm printer for the text output format
|
||||
func (ipf *imageTextPrintFlags) ToPrinter(outputFormat string) (output.Printer, error) {
|
||||
if outputFormat == output.TextOutput {
|
||||
return &imageTextPrinter{}, nil
|
||||
|
@ -47,7 +47,6 @@ import (
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -619,7 +618,7 @@ func fetchInitConfiguration(tlsBootstrapCfg *clientcmdapi.Config) (*kubeadmapi.I
|
||||
}
|
||||
|
||||
// Fetches the init configuration
|
||||
initConfiguration, err := configutil.FetchInitConfigurationFromCluster(tlsClient, &output.TextPrinter{}, "preflight", true, false)
|
||||
initConfiguration, err := configutil.FetchInitConfigurationFromCluster(tlsClient, nil, "preflight", true, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap")
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ import (
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
|
||||
utilruntime "k8s.io/kubernetes/cmd/kubeadm/app/util/runtime"
|
||||
)
|
||||
|
||||
@ -99,7 +98,7 @@ func newResetData(cmd *cobra.Command, options *resetOptions, in io.Reader, out i
|
||||
client, err := getClientset(options.kubeconfigPath, false)
|
||||
if err == nil {
|
||||
klog.V(1).Infof("[reset] Loaded client set from kubeconfig file: %s", options.kubeconfigPath)
|
||||
cfg, err = configutil.FetchInitConfigurationFromCluster(client, &output.TextPrinter{}, "reset", false, false)
|
||||
cfg, err = configutil.FetchInitConfigurationFromCluster(client, nil, "reset", false, false)
|
||||
if err != nil {
|
||||
klog.Warningf("[reset] Unable to fetch the kubeadm-config ConfigMap from cluster: %v", err)
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ func newCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
|
||||
|
||||
printer, err := outputFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "could not construct output printer")
|
||||
}
|
||||
|
||||
return RunListTokens(out, errW, client, printer)
|
||||
@ -354,7 +354,7 @@ func (ttp *tokenTextPrinter) PrintObj(obj runtime.Object, writer io.Writer) erro
|
||||
// tokenTextPrintFlags provides flags necessary for printing bootstrap token in a text form.
|
||||
type tokenTextPrintFlags struct{}
|
||||
|
||||
// ToPrinter returns kubeadm printer for the text output format
|
||||
// ToPrinter returns a kubeadm printer for the text output format
|
||||
func (tpf *tokenTextPrintFlags) ToPrinter(outputFormat string) (output.Printer, error) {
|
||||
if outputFormat == output.TextOutput {
|
||||
return &tokenTextPrinter{columns: []string{"TOKEN", "TTL", "EXPIRES", "USAGES", "DESCRIPTION", "EXTRA GROUPS"}}, nil
|
||||
|
@ -137,12 +137,12 @@ func enforceRequirements(flags *applyPlanFlags, args []string, dryRun bool, upgr
|
||||
if apierrors.IsNotFound(err) {
|
||||
printer.Printf("[upgrade/config] In order to upgrade, a ConfigMap called %q in the %s namespace must exist.\n", constants.KubeadmConfigConfigMap, metav1.NamespaceSystem)
|
||||
printer.Printf("[upgrade/config] Without this information, 'kubeadm upgrade' won't know how to configure your upgraded cluster.\n")
|
||||
printer.Printf("\n")
|
||||
printer.Println()
|
||||
printer.Printf("[upgrade/config] Next steps:\n")
|
||||
printer.Printf("\t- OPTION 1: Run 'kubeadm config upload from-flags' and specify the same CLI arguments you passed to 'kubeadm init' when you created your control-plane.\n")
|
||||
printer.Printf("\t- OPTION 2: Run 'kubeadm config upload from-file' and specify the same config file you passed to 'kubeadm init' when you created your control-plane.\n")
|
||||
printer.Printf("\t- OPTION 3: Pass a config file to 'kubeadm upgrade' using the --config flag.\n")
|
||||
printer.Printf("\n")
|
||||
printer.Println()
|
||||
err = errors.Errorf("the ConfigMap %q in the %s namespace used for getting configuration information was not found", constants.KubeadmConfigConfigMap, metav1.NamespaceSystem)
|
||||
}
|
||||
return nil, nil, nil, errors.Wrap(err, "[upgrade/config] FATAL")
|
||||
|
@ -37,7 +37,6 @@ import (
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
|
||||
)
|
||||
|
||||
type diffFlags struct {
|
||||
@ -119,7 +118,7 @@ func runDiff(flags *diffFlags, args []string) error {
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath)
|
||||
}
|
||||
cfg, err = configutil.FetchInitConfigurationFromCluster(client, &output.TextPrinter{}, "upgrade/diff", false, false)
|
||||
cfg, err = configutil.FetchInitConfigurationFromCluster(client, nil, "upgrade/diff", false, false)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -33,7 +33,6 @@ import (
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
|
||||
)
|
||||
|
||||
// nodeOptions defines all the options exposed via flags by kubeadm upgrade node.
|
||||
@ -140,7 +139,7 @@ func newNodeData(cmd *cobra.Command, args []string, options *nodeOptions) (*node
|
||||
// Fetches the cluster configuration
|
||||
// NB in case of control-plane node, we are reading all the info for the node; in case of NOT control-plane node
|
||||
// (worker node), we are not reading local API address and the CRI socket from the node object
|
||||
cfg, err := configutil.FetchInitConfigurationFromCluster(client, &output.TextPrinter{}, "upgrade", !isControlPlaneNode, false)
|
||||
cfg, err := configutil.FetchInitConfigurationFromCluster(client, nil, "upgrade", !isControlPlaneNode, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap")
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
outputapischeme "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/scheme"
|
||||
outputapiv1alpha2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha2"
|
||||
@ -62,7 +63,7 @@ func newCmdPlan(apf *applyPlanFlags) *cobra.Command {
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
printer, err := outputFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "could not construct output printer")
|
||||
}
|
||||
|
||||
return runPlan(flags, args, printer)
|
||||
@ -77,21 +78,21 @@ func newCmdPlan(apf *applyPlanFlags) *cobra.Command {
|
||||
}
|
||||
|
||||
// newComponentUpgradePlan helper creates outputapiv1alpha2.ComponentUpgradePlan object
|
||||
func newComponentUpgradePlan(name, currentVersion, newVersion string) *outputapiv1alpha2.ComponentUpgradePlan {
|
||||
return &outputapiv1alpha2.ComponentUpgradePlan{
|
||||
func newComponentUpgradePlan(name, currentVersion, newVersion string) outputapiv1alpha2.ComponentUpgradePlan {
|
||||
return outputapiv1alpha2.ComponentUpgradePlan{
|
||||
Name: name,
|
||||
CurrentVersion: currentVersion,
|
||||
NewVersion: newVersion,
|
||||
}
|
||||
}
|
||||
|
||||
// upgradePlanPrintFlags defines printer flag structure for the
|
||||
// upgradePlanPrintFlags defines a printer flag structure for the
|
||||
// upgrade plan kubeadm command and provides a method
|
||||
// of retrieving a known printer based on flag values provided.
|
||||
type upgradePlanPrintFlags struct {
|
||||
// JSONYamlPrintFlags provides default flags necessary for json/yaml printing.
|
||||
// JSONYamlPrintFlags provides default flags necessary for json/yaml printing
|
||||
JSONYamlPrintFlags *upgradePlanJSONYamlPrintFlags
|
||||
// TextPrintFlags provides default flags necessary for text printing.
|
||||
// TextPrintFlags provides default flags necessary for text printing
|
||||
TextPrintFlags *upgradePlanTextPrintFlags
|
||||
// TypeSetterPrinter is an implementation of ResourcePrinter that wraps another printer with types set on the objects
|
||||
TypeSetterPrinter *printers.TypeSetterPrinter
|
||||
@ -108,7 +109,7 @@ func newUpgradePlanPrintFlags(outputFormat string) *upgradePlanPrintFlags {
|
||||
}
|
||||
}
|
||||
|
||||
// AllowedFormats returns list of allowed output formats
|
||||
// AllowedFormats returns a list of allowed output formats
|
||||
func (pf *upgradePlanPrintFlags) AllowedFormats() []string {
|
||||
ret := pf.TextPrintFlags.AllowedFormats()
|
||||
return append(ret, pf.JSONYamlPrintFlags.AllowedFormats()...)
|
||||
@ -119,7 +120,9 @@ func (pf *upgradePlanPrintFlags) AllowedFormats() []string {
|
||||
func (pf *upgradePlanPrintFlags) AddFlags(cmd *cobra.Command) {
|
||||
pf.TextPrintFlags.AddFlags(cmd)
|
||||
pf.JSONYamlPrintFlags.AddFlags(cmd)
|
||||
cmd.Flags().StringVarP(&pf.OutputFormat, "experimental-output", "o", pf.OutputFormat, fmt.Sprintf("Output format. One of: %s.", strings.Join(pf.AllowedFormats(), "|")))
|
||||
// TODO: once we are confident the feature is graduated we should remove the EXPERIMENTAL text below:
|
||||
// https://github.com/kubernetes/kubeadm/issues/494
|
||||
cmd.Flags().StringVarP(&pf.OutputFormat, "output", "o", pf.OutputFormat, fmt.Sprintf("EXPERIMENTAL: Output format. One of: %s.", strings.Join(pf.AllowedFormats(), "|")))
|
||||
}
|
||||
|
||||
// ToPrinter receives an outputFormat and returns a printer capable of
|
||||
@ -142,7 +145,7 @@ type upgradePlanJSONYamlPrintFlags struct {
|
||||
genericclioptions.JSONYamlPrintFlags
|
||||
}
|
||||
|
||||
// AllowedFormats returns list of allowed output formats
|
||||
// AllowedFormats returns a list of allowed output formats
|
||||
func (pf *upgradePlanJSONYamlPrintFlags) AllowedFormats() []string {
|
||||
return []string{output.JSONOutput, output.YAMLOutput}
|
||||
}
|
||||
@ -150,10 +153,10 @@ func (pf *upgradePlanJSONYamlPrintFlags) AllowedFormats() []string {
|
||||
// upgradePlanJSONYAMLPrinter prints upgrade plan in a JSON or YAML format
|
||||
type upgradePlanJSONYAMLPrinter struct {
|
||||
output.ResourcePrinterWrapper
|
||||
Buffer []*outputapiv1alpha2.ComponentUpgradePlan
|
||||
Buffer []outputapiv1alpha2.ComponentUpgradePlan
|
||||
}
|
||||
|
||||
// newUpgradePlanJSONYAMLPrinter creates new upgradePlanJSONYAMLPrinter object
|
||||
// newUpgradePlanJSONYAMLPrinter creates a new upgradePlanJSONYAMLPrinter object
|
||||
func newUpgradePlanJSONYAMLPrinter(resourcePrinter printers.ResourcePrinter, err error) (output.Printer, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -165,18 +168,29 @@ func newUpgradePlanJSONYAMLPrinter(resourcePrinter printers.ResourcePrinter, err
|
||||
func (p *upgradePlanJSONYAMLPrinter) PrintObj(obj runtime.Object, writer io.Writer) error {
|
||||
item, ok := obj.(*outputapiv1alpha2.ComponentUpgradePlan)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected ComponentUpgradePlan, but got %+v", obj)
|
||||
return errors.Errorf("expected ComponentUpgradePlan, but got %+v", obj)
|
||||
}
|
||||
p.Buffer = append(p.Buffer, item)
|
||||
p.Buffer = append(p.Buffer, *item)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close writes any buffered data and empties list of buffered components
|
||||
func (p *upgradePlanJSONYAMLPrinter) Close(writer io.Writer) {
|
||||
// Flush writes any buffered data once last object is added
|
||||
func (p *upgradePlanJSONYAMLPrinter) Flush(writer io.Writer, last bool) {
|
||||
if !last {
|
||||
return
|
||||
}
|
||||
if len(p.Buffer) == 0 {
|
||||
return
|
||||
}
|
||||
plan := &outputapiv1alpha2.UpgradePlan{Components: p.Buffer}
|
||||
// p.ResourcePrinterWrapper.Printer.PrintObj(plan, writer)
|
||||
p.Printer.PrintObj(plan, writer)
|
||||
p.Buffer = []*outputapiv1alpha2.ComponentUpgradePlan{}
|
||||
if err := p.Printer.PrintObj(plan, writer); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not flush output buffer: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Close empties the list of buffered components
|
||||
func (p *upgradePlanJSONYAMLPrinter) Close(writer io.Writer) {
|
||||
p.Buffer = p.Buffer[:0]
|
||||
}
|
||||
|
||||
// upgradePlanTextPrinter prints upgrade plan in a text form
|
||||
@ -187,10 +201,11 @@ type upgradePlanTextPrinter struct {
|
||||
}
|
||||
|
||||
// Flush writes any buffered data
|
||||
func (p *upgradePlanTextPrinter) Flush(writer io.Writer) {
|
||||
func (p *upgradePlanTextPrinter) Flush(writer io.Writer, last bool) {
|
||||
if p.tabwriter != nil {
|
||||
p.tabwriter.Flush()
|
||||
p.tabwriter = nil
|
||||
p.Fprintln(writer, "")
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,26 +219,25 @@ func (p *upgradePlanTextPrinter) PrintObj(obj runtime.Object, writer io.Writer)
|
||||
|
||||
item, ok := obj.(*outputapiv1alpha2.ComponentUpgradePlan)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected ComponentUpgradePlan, but got %+v", obj)
|
||||
return errors.Errorf("expected ComponentUpgradePlan, but got %+v", obj)
|
||||
}
|
||||
|
||||
// Print item
|
||||
fmt.Fprintf(p.tabwriter, "%s\t%s\t%s\n", item.Name, item.CurrentVersion, item.NewVersion)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// upgradePlanTextPrintFlags provides flags necessary for printing upgrade plan in a text form.
|
||||
// upgradePlanTextPrintFlags provides flags necessary for printing upgrade plan in a text form
|
||||
type upgradePlanTextPrintFlags struct{}
|
||||
|
||||
func (pf *upgradePlanTextPrintFlags) AddFlags(cmd *cobra.Command) {}
|
||||
|
||||
// AllowedFormats returns list of allowed output formats
|
||||
// AllowedFormats returns a list of allowed output formats
|
||||
func (pf *upgradePlanTextPrintFlags) AllowedFormats() []string {
|
||||
return []string{output.TextOutput}
|
||||
}
|
||||
|
||||
// ToPrinter returns kubeadm printer for the text output format
|
||||
// ToPrinter returns a kubeadm printer for the text output format
|
||||
func (pf *upgradePlanTextPrintFlags) ToPrinter(outputFormat string) (output.Printer, error) {
|
||||
if outputFormat == output.TextOutput {
|
||||
return &upgradePlanTextPrinter{columns: []string{"COMPONENT", "CURRENT", "TARGET"}}, nil
|
||||
@ -282,15 +296,12 @@ func runPlan(flags *planFlags, args []string, printer output.Printer) error {
|
||||
|
||||
// Finally, print the component config state table
|
||||
printComponentConfigVersionStates(configVersionStates, os.Stdout, printer)
|
||||
|
||||
// Add a newline in the end of this output to leave some space to the next output section
|
||||
klog.V(1).Infoln()
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO There is currently no way to cleanly output upgrades that involve adding, removing, or changing components
|
||||
// https://github.com/kubernetes/kubeadm/issues/810 was created to track addressing this.
|
||||
func appendDNSComponent(components []*outputapiv1alpha2.ComponentUpgradePlan, up *upgrade.Upgrade, name string) []*outputapiv1alpha2.ComponentUpgradePlan {
|
||||
func appendDNSComponent(components []outputapiv1alpha2.ComponentUpgradePlan, up *upgrade.Upgrade, name string) []outputapiv1alpha2.ComponentUpgradePlan {
|
||||
beforeVersion := up.Before.DNSVersion
|
||||
afterVersion := up.After.DNSVersion
|
||||
|
||||
@ -316,7 +327,7 @@ func genUpgradePlan(up *upgrade.Upgrade, isExternalEtcd bool) (*outputapiv1alpha
|
||||
}
|
||||
}
|
||||
|
||||
components := []*outputapiv1alpha2.ComponentUpgradePlan{}
|
||||
components := []outputapiv1alpha2.ComponentUpgradePlan{}
|
||||
|
||||
if up.CanUpgradeKubelets() {
|
||||
// The map is of the form <old-version>:<node-count>. Here all the keys are put into a slice and sorted
|
||||
@ -370,26 +381,26 @@ func printUpgradePlan(up *upgrade.Upgrade, plan *outputapiv1alpha2.UpgradePlan,
|
||||
} else if component.Name == constants.Kubelet {
|
||||
if printManualUpgradeHeader {
|
||||
printer.Fprintln(writer, "Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':")
|
||||
printer.PrintObj(newComponentUpgradePlan(component.Name, component.CurrentVersion, component.NewVersion), writer)
|
||||
plan := newComponentUpgradePlan(component.Name, component.CurrentVersion, component.NewVersion)
|
||||
printer.PrintObj(&plan, writer)
|
||||
printManualUpgradeHeader = false
|
||||
} else {
|
||||
printer.PrintObj(newComponentUpgradePlan("", component.CurrentVersion, component.NewVersion), writer)
|
||||
plan := newComponentUpgradePlan("", component.CurrentVersion, component.NewVersion)
|
||||
printer.PrintObj(&plan, writer)
|
||||
}
|
||||
} else {
|
||||
if printHeader {
|
||||
// End of manual upgrades table
|
||||
printer.Flush(writer)
|
||||
|
||||
printer.Fprintln(writer, "")
|
||||
printer.Flush(writer, false)
|
||||
printer.Fprintf(writer, "Upgrade to the latest %s:\n", up.Description)
|
||||
printer.Fprintln(writer, "")
|
||||
printHeader = false
|
||||
}
|
||||
printer.PrintObj(newComponentUpgradePlan(component.Name, component.CurrentVersion, component.NewVersion), writer)
|
||||
plan := newComponentUpgradePlan(component.Name, component.CurrentVersion, component.NewVersion)
|
||||
printer.PrintObj(&plan, writer)
|
||||
}
|
||||
}
|
||||
printer.Flush(writer)
|
||||
printer.Fprintln(writer, "")
|
||||
printer.Flush(writer, true)
|
||||
|
||||
printer.Fprintln(writer, "You can now apply the upgrade by executing the following command:")
|
||||
printer.Fprintln(writer, "")
|
||||
@ -430,8 +441,7 @@ func yesOrNo(b bool) string {
|
||||
}
|
||||
|
||||
func printLineSeparator(w io.Writer, printer output.Printer) {
|
||||
printer.Fprintln(w, "_____________________________________________________________________")
|
||||
printer.Fprintln(w, "")
|
||||
printer.Fprintf(w, "_____________________________________________________________________\n\n")
|
||||
}
|
||||
|
||||
func printComponentConfigVersionStates(versionStates []outputapiv1alpha2.ComponentConfigVersionState, w io.Writer, printer output.Printer) {
|
||||
|
@ -26,9 +26,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog/v2"
|
||||
outputapiv1alpha2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha2"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
outputapiv1alpha2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha2"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/config/strict"
|
||||
|
@ -268,7 +268,7 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
|
||||
}
|
||||
|
||||
// Add a newline in the end of this output to leave some space to the next output section
|
||||
printer.Printf("\n")
|
||||
printer.Println()
|
||||
|
||||
return upgrades, nil
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ import (
|
||||
|
||||
// FetchInitConfigurationFromCluster fetches configuration from a ConfigMap in the cluster
|
||||
func FetchInitConfigurationFromCluster(client clientset.Interface, printer output.Printer, logPrefix string, newControlPlane, skipComponentConfigs bool) (*kubeadmapi.InitConfiguration, error) {
|
||||
if printer == nil {
|
||||
printer = &output.TextPrinter{}
|
||||
}
|
||||
printer.Printf("[%s] Reading configuration from the cluster...\n", logPrefix)
|
||||
printer.Printf("[%s] FYI: You can look at this config file with 'kubectl -n %s get cm %s -o yaml'\n", logPrefix, metav1.NamespaceSystem, constants.KubeadmConfigConfigMap)
|
||||
|
||||
|
@ -28,14 +28,16 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
)
|
||||
|
||||
// TextOutput describes the plain text output
|
||||
const TextOutput = "text"
|
||||
const (
|
||||
// TextOutput describes the plain text output
|
||||
TextOutput = "text"
|
||||
|
||||
// JSONOutput describes the JSON output
|
||||
const JSONOutput = "json"
|
||||
// JSONOutput describes the JSON output
|
||||
JSONOutput = "json"
|
||||
|
||||
// YAMLOutput describes the YAML output
|
||||
const YAMLOutput = "yaml"
|
||||
// YAMLOutput describes the YAML output
|
||||
YAMLOutput = "yaml"
|
||||
)
|
||||
|
||||
// TextPrintFlags is an interface to handle custom text output
|
||||
type TextPrintFlags interface {
|
||||
@ -58,7 +60,7 @@ type PrintFlags struct {
|
||||
OutputFormat *string
|
||||
}
|
||||
|
||||
// AllowedFormats returns list of allowed output formats
|
||||
// AllowedFormats returns a list of allowed output formats
|
||||
func (pf *PrintFlags) AllowedFormats() []string {
|
||||
ret := []string{TextOutput}
|
||||
ret = append(ret, pf.JSONYamlPrintFlags.AllowedFormats()...)
|
||||
@ -141,8 +143,9 @@ type Printer interface {
|
||||
Fprintf(writer io.Writer, format string, args ...interface{}) (n int, err error)
|
||||
Fprintln(writer io.Writer, args ...interface{}) (n int, err error)
|
||||
Printf(format string, args ...interface{}) (n int, err error)
|
||||
Println(args ...interface{}) (n int, err error)
|
||||
|
||||
Flush(writer io.Writer)
|
||||
Flush(writer io.Writer, last bool)
|
||||
Close(writer io.Writer)
|
||||
}
|
||||
|
||||
@ -150,16 +153,6 @@ type Printer interface {
|
||||
type TextPrinter struct {
|
||||
}
|
||||
|
||||
// Flush writes any buffered data
|
||||
func (tp *TextPrinter) Flush(writer io.Writer) {
|
||||
return
|
||||
}
|
||||
|
||||
// Close flushes any buffered data and closes the printer
|
||||
func (tp *TextPrinter) Close(writer io.Writer) {
|
||||
return
|
||||
}
|
||||
|
||||
// PrintObj is an implementation of ResourcePrinter.PrintObj that prints object
|
||||
func (tp *TextPrinter) PrintObj(obj runtime.Object, writer io.Writer) error {
|
||||
_, err := fmt.Fprintf(writer, "%+v\n", obj)
|
||||
@ -181,6 +174,19 @@ func (tp *TextPrinter) Printf(format string, args ...interface{}) (n int, err er
|
||||
return fmt.Printf(format, args...)
|
||||
}
|
||||
|
||||
// Println is a wrapper around fmt.Printf
|
||||
func (tp *TextPrinter) Println(args ...interface{}) (n int, err error) {
|
||||
return fmt.Println(args...)
|
||||
}
|
||||
|
||||
// Flush writes any buffered data
|
||||
func (tp *TextPrinter) Flush(writer io.Writer, last bool) {
|
||||
}
|
||||
|
||||
// Close flushes any buffered data and closes the printer
|
||||
func (tp *TextPrinter) Close(writer io.Writer) {
|
||||
}
|
||||
|
||||
// ResourcePrinterWrapper wraps ResourcePrinter and implements Printer interface
|
||||
type ResourcePrinterWrapper struct {
|
||||
Printer printers.ResourcePrinter
|
||||
@ -195,13 +201,11 @@ func NewResourcePrinterWrapper(resourcePrinter printers.ResourcePrinter, err err
|
||||
}
|
||||
|
||||
// Flush writes any buffered data
|
||||
func (rpw *ResourcePrinterWrapper) Flush(writer io.Writer) {
|
||||
return
|
||||
func (rpw *ResourcePrinterWrapper) Flush(writer io.Writer, last bool) {
|
||||
}
|
||||
|
||||
// Close flushes any buffered data and closes the printer
|
||||
func (rpw *ResourcePrinterWrapper) Close(writer io.Writer) {
|
||||
return
|
||||
}
|
||||
|
||||
// PrintObj is an implementation of ResourcePrinter.PrintObj that calls underlying printer API
|
||||
@ -216,7 +220,7 @@ func (rpw *ResourcePrinterWrapper) Fprintf(writer io.Writer, format string, args
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Fprintln is an empty method to satisfy Printer interface
|
||||
// Fprintln is an empty method to satisfy the Printer interface
|
||||
// and silent info printing for structured output
|
||||
// This method is usually redefined for the text output
|
||||
func (rpw *ResourcePrinterWrapper) Fprintln(writer io.Writer, args ...interface{}) (n int, err error) {
|
||||
@ -229,3 +233,10 @@ func (rpw *ResourcePrinterWrapper) Fprintln(writer io.Writer, args ...interface{
|
||||
func (rpw *ResourcePrinterWrapper) Printf(format string, args ...interface{}) (n int, err error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Println is an empty method to satisfy Printer interface
|
||||
// and silent info printing for structured output
|
||||
// This method is usually redefined for the text output
|
||||
func (rpw *ResourcePrinterWrapper) Println(args ...interface{}) (n int, err error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user