mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 20:42:26 +00:00
kubeadm: improve some grammar issues and add some unit test cases
This commit is contained in:
parent
595482d264
commit
a2f8d31c65
@ -18,32 +18,27 @@ limitations under the License.
|
||||
package apply
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||
"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"
|
||||
dnsaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
|
||||
proxyaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
||||
)
|
||||
|
||||
// NewAddonPhase returns the addon Cobra command
|
||||
// NewAddonPhase returns a new addon phase.
|
||||
func NewAddonPhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "addon",
|
||||
Short: "Install required addons for passing conformance tests",
|
||||
Short: "Install the default kubeadm addons",
|
||||
Long: cmdutil.MacroCommandLongDescription,
|
||||
Phases: []workflow.Phase{
|
||||
{
|
||||
@ -54,13 +49,13 @@ func NewAddonPhase() workflow.Phase {
|
||||
},
|
||||
{
|
||||
Name: "coredns",
|
||||
Short: "Install the CoreDNS addon to a Kubernetes cluster",
|
||||
Short: "Install the CoreDNS addon",
|
||||
InheritFlags: getAddonPhaseFlags("coredns"),
|
||||
Run: runCoreDNSAddon,
|
||||
},
|
||||
{
|
||||
Name: "kube-proxy",
|
||||
Short: "Install the kube-proxy addon to a Kubernetes cluster",
|
||||
Short: "Install the kube-proxy addon",
|
||||
InheritFlags: getAddonPhaseFlags("kube-proxy"),
|
||||
Run: runKubeProxyAddon,
|
||||
},
|
||||
@ -74,10 +69,9 @@ func shouldUpgradeAddons(client clientset.Interface, cfg *kubeadmapi.InitConfigu
|
||||
return false, errors.Wrapf(err, "failed to determine whether all the control plane instances have been upgraded")
|
||||
}
|
||||
if len(unupgradedControlPlanes) > 0 {
|
||||
fmt.Fprintf(out, "[upgrade/addons] skip upgrade addons because control plane instances %v have not been upgraded\n", unupgradedControlPlanes)
|
||||
fmt.Fprintf(out, "[upgrade/addons] Skipping upgrade of addons because control plane instances %v have not been upgraded\n", unupgradedControlPlanes)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@ -89,7 +83,7 @@ func getInitData(c workflow.RunData) (*kubeadmapi.InitConfiguration, clientset.I
|
||||
return data.InitCfg(), data.Client(), data.PatchesDir(), data.OutputWriter(), data.DryRun(), nil
|
||||
}
|
||||
|
||||
// runCoreDNSAddon installs CoreDNS addon to a Kubernetes cluster
|
||||
// runCoreDNSAddon installs the CoreDNS addon.
|
||||
func runCoreDNSAddon(c workflow.RunData) error {
|
||||
cfg, client, patchesDir, out, dryRun, err := getInitData(c)
|
||||
if err != nil {
|
||||
@ -104,25 +98,6 @@ func runCoreDNSAddon(c workflow.RunData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If the coredns ConfigMap is missing, show a warning and assume that the
|
||||
// DNS addon was skipped during "kubeadm init", and that its redeployment on upgrade is not desired.
|
||||
//
|
||||
// TODO: remove this once "kubeadm upgrade apply" phases are supported:
|
||||
// https://github.com/kubernetes/kubeadm/issues/1318
|
||||
if _, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(
|
||||
context.TODO(),
|
||||
kubeadmconstants.CoreDNSConfigMap,
|
||||
metav1.GetOptions{},
|
||||
); err != nil && apierrors.IsNotFound(err) {
|
||||
klog.Warningf("the ConfigMaps %q in the namespace %q were not found. "+
|
||||
"Assuming that a DNS server was not deployed for this cluster. "+
|
||||
"Note that once 'kubeadm upgrade apply' supports phases you "+
|
||||
"will have to skip the DNS upgrade manually",
|
||||
kubeadmconstants.CoreDNSConfigMap,
|
||||
metav1.NamespaceSystem)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Upgrade CoreDNS
|
||||
if err := dnsaddon.EnsureDNSAddon(&cfg.ClusterConfiguration, client, patchesDir, out, dryRun); err != nil {
|
||||
return err
|
||||
@ -131,7 +106,7 @@ func runCoreDNSAddon(c workflow.RunData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// runKubeProxyAddon installs KubeProxy addon to a Kubernetes cluster
|
||||
// runKubeProxyAddon installs the KubeProxy addon.
|
||||
func runKubeProxyAddon(c workflow.RunData) error {
|
||||
cfg, client, _, out, dryRun, err := getInitData(c)
|
||||
if err != nil {
|
||||
@ -146,25 +121,6 @@ func runKubeProxyAddon(c workflow.RunData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If the kube-proxy ConfigMap is missing, show a warning and assume that kube-proxy
|
||||
// was skipped during "kubeadm init", and that its redeployment on upgrade is not desired.
|
||||
//
|
||||
// TODO: remove this once "kubeadm upgrade apply" phases are supported:
|
||||
// https://github.com/kubernetes/kubeadm/issues/1318
|
||||
if _, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(
|
||||
context.TODO(),
|
||||
kubeadmconstants.KubeProxyConfigMap,
|
||||
metav1.GetOptions{},
|
||||
); err != nil && apierrors.IsNotFound(err) {
|
||||
klog.Warningf("the ConfigMap %q in the namespace %q was not found. "+
|
||||
"Assuming that kube-proxy was not deployed for this cluster. "+
|
||||
"Note that once 'kubeadm upgrade apply' supports phases you "+
|
||||
"will have to skip the kube-proxy upgrade manually",
|
||||
kubeadmconstants.KubeProxyConfigMap,
|
||||
metav1.NamespaceSystem)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Upgrade kube-proxy
|
||||
if err := proxyaddon.EnsureProxyAddon(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, client, out, dryRun); err != nil {
|
||||
return err
|
||||
|
@ -30,12 +30,11 @@ import (
|
||||
nodebootstraptoken "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||
)
|
||||
|
||||
// NewBootstrapTokenPhase returns the phase to bootstrapToken
|
||||
// NewBootstrapTokenPhase returns a new bootstrap-token phase.
|
||||
func NewBootstrapTokenPhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "bootstrap-token",
|
||||
Aliases: []string{"bootstraptoken"},
|
||||
Short: "Generates bootstrap tokens used to join a node to a cluster",
|
||||
Name: "bootstrap-token",
|
||||
Short: "Configures bootstrap token and cluster-info RBAC rules",
|
||||
InheritFlags: []string{
|
||||
options.CfgPath,
|
||||
options.KubeconfigPath,
|
||||
@ -56,7 +55,7 @@ func runBootstrapToken(c workflow.RunData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("[bootstrap-token] Configuring cluster-info ConfigMap, RBAC Roles")
|
||||
fmt.Println("[bootstrap-token] Configuring the cluster-info ConfigMap and RBAC roles")
|
||||
|
||||
client := data.Client()
|
||||
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
)
|
||||
|
||||
// NewControlPlanePhase creates a kubeadm workflow phase that implements handling of control-plane upgrade.
|
||||
// NewControlPlanePhase returns a new control-plane phase.
|
||||
func NewControlPlanePhase() workflow.Phase {
|
||||
phase := workflow.Phase{
|
||||
Name: "control-plane",
|
||||
|
@ -28,7 +28,7 @@ import (
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
||||
)
|
||||
|
||||
// NewKubeconfigPhase creates a kubeadm workflow phase that implements handling of kubeconfig upgrade.
|
||||
// NewKubeconfigPhase returns a new kubeconfig phase.
|
||||
func NewKubeconfigPhase() workflow.Phase {
|
||||
phase := workflow.Phase{
|
||||
Name: "kubeconfig",
|
||||
@ -59,7 +59,7 @@ func runKubeconfig() func(c workflow.RunData) error {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("[upgrade] The kubeconfig for this node was successfully updated!")
|
||||
fmt.Println("[upgrade] The kubeconfig files for this node were successfully updated!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ var (
|
||||
`)
|
||||
)
|
||||
|
||||
// NewKubeletConfigPhase creates a kubeadm workflow phase that implements handling of kubelet-config upgrade.
|
||||
// NewKubeletConfigPhase returns a new kubelet-config phase.
|
||||
func NewKubeletConfigPhase() workflow.Phase {
|
||||
phase := workflow.Phase{
|
||||
Name: "kubelet-config",
|
||||
@ -59,15 +59,14 @@ func runKubeletConfigPhase(c workflow.RunData) error {
|
||||
|
||||
initCfg, dryRun := data.InitCfg(), data.DryRun()
|
||||
|
||||
// Write the configuration for the kubelet down to disk and print the generated manifests instead if dry-running.
|
||||
// Write the configuration for the kubelet down to disk and print the generated manifests instead of dry-running.
|
||||
// If not dry-running, the kubelet config file will be backed up to /etc/kubernetes/tmp/ dir, so that it could be
|
||||
// recovered if there is anything goes wrong.
|
||||
// recovered if anything goes wrong.
|
||||
err := upgrade.WriteKubeletConfigFiles(initCfg, data.PatchesDir(), dryRun, data.OutputWriter())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("[upgrade] The configuration for this node was successfully updated!")
|
||||
fmt.Println("[upgrade] Now you should go ahead and upgrade the kubelet package using your package manager.")
|
||||
fmt.Println("[upgrade] The kubelet configuration for this node was successfully updated!")
|
||||
return nil
|
||||
}
|
||||
|
@ -38,12 +38,12 @@ import (
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
|
||||
)
|
||||
|
||||
// NewPreflightPhase creates a kubeadm workflow phase that implements preflight checks for kubeadm upgrade apply.
|
||||
// NewPreflightPhase returns a new prefight phase.
|
||||
func NewPreflightPhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "preflight",
|
||||
Short: "Run upgrade apply pre-flight checks",
|
||||
Long: "Run pre-flight checks for kubeadm upgrade apply.",
|
||||
Short: "Run upgrade apply preflight checks",
|
||||
Long: "Run preflight checks for kubeadm upgrade apply.",
|
||||
Run: runPreflight,
|
||||
InheritFlags: []string{
|
||||
options.CfgPath,
|
||||
@ -58,13 +58,12 @@ func NewPreflightPhase() workflow.Phase {
|
||||
}
|
||||
}
|
||||
|
||||
// runPreflight executes preflight checks logic.
|
||||
func runPreflight(c workflow.RunData) error {
|
||||
data, ok := c.(Data)
|
||||
if !ok {
|
||||
return errors.New("preflight phase invoked with an invalid data struct")
|
||||
}
|
||||
fmt.Println("[preflight] Running pre-flight checks")
|
||||
fmt.Println("[preflight] Running preflight checks")
|
||||
|
||||
printer := &output.TextPrinter{}
|
||||
|
||||
@ -81,7 +80,7 @@ func runPreflight(c workflow.RunData) error {
|
||||
}
|
||||
|
||||
// Run healthchecks against the cluster
|
||||
klog.V(1).Infoln("[upgrade/apply] verifying health of cluster")
|
||||
klog.V(1).Infoln("[upgrade/apply] Verifying the cluster health")
|
||||
if err := upgrade.CheckClusterHealth(client, &initCfg.ClusterConfiguration, ignorePreflightErrors, printer); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -94,7 +93,7 @@ func runPreflight(c workflow.RunData) error {
|
||||
}
|
||||
|
||||
// Validate requested and validate actual version
|
||||
klog.V(1).Infoln("[upgrade/apply] validating requested and actual version")
|
||||
klog.V(1).Infoln("[upgrade/apply] Validating requested and actual version")
|
||||
if err := configutil.NormalizeKubernetesVersion(&initCfg.ClusterConfiguration); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -110,7 +109,7 @@ func runPreflight(c workflow.RunData) error {
|
||||
}
|
||||
|
||||
versionGetter := upgrade.NewOfflineVersionGetter(upgrade.NewKubeVersionGetter(client), initCfg.KubernetesVersion)
|
||||
if err := EnforceVersionPolicies(initCfg.KubernetesVersion, upgradeVersion, data.AllowExperimentalUpgrades(), data.AllowRCUpgrades(), data.ForceUpgrade(), versionGetter); err != nil {
|
||||
if err := enforceVersionPolicies(initCfg.KubernetesVersion, upgradeVersion, data.AllowExperimentalUpgrades(), data.AllowRCUpgrades(), data.ForceUpgrade(), versionGetter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -134,23 +133,23 @@ func runPreflight(c workflow.RunData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnforceVersionPolicies makes sure that the version the user specified is valid to upgrade to
|
||||
// enforceVersionPolicies makes sure that the version the user specified is valid to upgrade to
|
||||
// There are both fatal and skippable (with --force) errors
|
||||
func EnforceVersionPolicies(newK8sVersionStr string, newK8sVersion *version.Version, allowExperimentalUpgrades, allowRCUpgrades, force bool, versionGetter upgrade.VersionGetter) error {
|
||||
fmt.Printf("[upgrade/version] You have chosen to change the cluster version to %q\n", newK8sVersionStr)
|
||||
func enforceVersionPolicies(newK8sVersionStr string, newK8sVersion *version.Version, allowExperimentalUpgrades, allowRCUpgrades, force bool, versionGetter upgrade.VersionGetter) error {
|
||||
fmt.Printf("[upgrade/version] You have chosen to upgrade the cluster version to %q\n", newK8sVersionStr)
|
||||
|
||||
versionSkewErrs := upgrade.EnforceVersionPolicies(versionGetter, newK8sVersionStr, newK8sVersion, allowExperimentalUpgrades, allowRCUpgrades)
|
||||
if versionSkewErrs != nil {
|
||||
|
||||
if len(versionSkewErrs.Mandatory) > 0 {
|
||||
return errors.Errorf("the --version argument is invalid due to these fatal errors:\n\n%v\nPlease fix the misalignments highlighted above and try upgrading again",
|
||||
return errors.Errorf("the version argument is invalid due to these fatal errors:\n\n%v\nPlease fix the misalignments highlighted above and try upgrading again",
|
||||
kubeadmutil.FormatErrMsg(versionSkewErrs.Mandatory))
|
||||
}
|
||||
|
||||
if len(versionSkewErrs.Skippable) > 0 {
|
||||
// Return the error if the user hasn't specified the --force flag
|
||||
if !force {
|
||||
return errors.Errorf("the --version argument is invalid due to these errors:\n\n%v\nCan be bypassed if you pass the --force flag",
|
||||
return errors.Errorf("the version argument is invalid due to these errors:\n\n%v\nCan be bypassed if you pass the --force flag",
|
||||
kubeadmutil.FormatErrMsg(versionSkewErrs.Skippable))
|
||||
}
|
||||
// Soft errors found, but --force was specified
|
||||
|
@ -39,12 +39,12 @@ func NewUploadConfigPhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "upload-config",
|
||||
Aliases: []string{"uploadconfig"},
|
||||
Short: "Upload the kubeadm and kubelet configuration to a ConfigMap",
|
||||
Short: "Upload the kubeadm and kubelet configurations to a ConfigMaps",
|
||||
Long: cmdutil.MacroCommandLongDescription,
|
||||
Phases: []workflow.Phase{
|
||||
{
|
||||
Name: "all",
|
||||
Short: "Upload all configuration to a config map",
|
||||
Short: "Upload all the configurations to ConfigMaps",
|
||||
RunAllSiblings: true,
|
||||
InheritFlags: getUploadConfigPhaseFlags(),
|
||||
},
|
||||
@ -56,7 +56,7 @@ func NewUploadConfigPhase() workflow.Phase {
|
||||
},
|
||||
{
|
||||
Name: "kubelet",
|
||||
Short: "Upload the kubelet component config to a ConfigMap",
|
||||
Short: "Upload the kubelet configuration config to a ConfigMap",
|
||||
Run: runUploadKubeletConfig,
|
||||
InheritFlags: getUploadConfigPhaseFlags(),
|
||||
},
|
||||
@ -99,19 +99,19 @@ func runUploadKubeletConfig(c workflow.RunData) error {
|
||||
}
|
||||
|
||||
if dryRun {
|
||||
fmt.Println("[dryrun] Would upload the kubelet component config to a ConfigMap")
|
||||
fmt.Println("[dryrun] Would upload the kubelet configuration to a ConfigMap")
|
||||
fmt.Println("[dryrun] Would write the CRISocket annotation for the control-plane node")
|
||||
return nil
|
||||
}
|
||||
|
||||
klog.V(1).Infoln("[upload-config] Uploading the kubelet component config to a ConfigMap")
|
||||
klog.V(1).Infoln("[upload-config] Uploading the kubelet configuration to a ConfigMap")
|
||||
if err = kubeletphase.CreateConfigMap(&cfg.ClusterConfiguration, client); err != nil {
|
||||
return errors.Wrap(err, "error creating kubelet configuration ConfigMap")
|
||||
}
|
||||
|
||||
klog.V(1).Infoln("[upload-config] Preserving the CRISocket information for the control-plane node")
|
||||
if err := patchnodephase.AnnotateCRISocket(client, cfg.NodeRegistration.Name, cfg.NodeRegistration.CRISocket); err != nil {
|
||||
return errors.Wrap(err, "Error writing Crisocket information for the control-plane node")
|
||||
return errors.Wrap(err, "error writing Crisocket information for the control-plane node")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -99,25 +99,21 @@ func newCmdApply(apf *applyPlanFlags) *cobra.Command {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
applyData, ok := data.(*applyData)
|
||||
if !ok {
|
||||
return errors.New("invalid data struct")
|
||||
}
|
||||
|
||||
if err := applyRunner.Run(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flags.dryRun {
|
||||
fmt.Println("[upgrade/successful] Finished dryrunning successfully!")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
fmt.Printf("[upgrade/successful] SUCCESS! Your cluster was upgraded to %q. Enjoy!\n", applyData.InitCfg().KubernetesVersion)
|
||||
fmt.Println("")
|
||||
fmt.Println("[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.")
|
||||
fmt.Printf("[upgrade/successful] SUCCESS! A control plane node of your cluster was upgraded to %q.\n\n", applyData.InitCfg().KubernetesVersion)
|
||||
fmt.Println("[upgrade/kubelet] Now please proceed with upgrading the rest of the nodes by following the right order.")
|
||||
|
||||
return nil
|
||||
},
|
||||
@ -133,7 +129,7 @@ func newCmdApply(apf *applyPlanFlags) *cobra.Command {
|
||||
cmd.Flags().BoolVar(&flags.renewCerts, options.CertificateRenewal, flags.renewCerts, "Perform the renewal of certificates used by component changed during upgrades.")
|
||||
options.AddPatchesFlag(cmd.Flags(), &flags.patchesDir)
|
||||
|
||||
// initialize the workflow runner with the list of phases
|
||||
// Initialize the workflow runner with the list of phases
|
||||
applyRunner.AppendPhase(phases.NewPreflightPhase())
|
||||
applyRunner.AppendPhase(phases.NewControlPlanePhase())
|
||||
applyRunner.AppendPhase(phases.NewUploadConfigPhase())
|
||||
@ -142,7 +138,7 @@ func newCmdApply(apf *applyPlanFlags) *cobra.Command {
|
||||
applyRunner.AppendPhase(phases.NewBootstrapTokenPhase())
|
||||
applyRunner.AppendPhase(phases.NewAddonPhase())
|
||||
|
||||
// sets the data builder function, that will be used by the runner
|
||||
// Sets the data builder function, that will be used by the runner
|
||||
// both when running the entire workflow or single phases
|
||||
applyRunner.SetDataInitializer(func(cmd *cobra.Command, args []string) (workflow.RunData, error) {
|
||||
data, err := newApplyData(cmd, args, flags)
|
||||
@ -156,7 +152,7 @@ func newCmdApply(apf *applyPlanFlags) *cobra.Command {
|
||||
return data, nil
|
||||
})
|
||||
|
||||
// binds the Runner to kubeadm upgrade apply command by altering
|
||||
// Binds the Runner to kubeadm upgrade apply command by altering
|
||||
// command help, adding --skip-phases flag and by adding phases subcommands
|
||||
applyRunner.BindToCommand(cmd)
|
||||
|
||||
@ -173,18 +169,23 @@ func newApplyData(cmd *cobra.Command, args []string, applyFlags *applyFlags) (*a
|
||||
}
|
||||
|
||||
upgradeVersion := upgradeCfg.Apply.KubernetesVersion
|
||||
// The version arg is mandatory, during upgrade apply, unless it's specified in the config file
|
||||
// The version arg is mandatory, unless it's specified in the config file
|
||||
if upgradeVersion == "" {
|
||||
if err := cmdutil.ValidateExactArgNumber(args, []string{"version"}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// If option was specified in both args and config file, args will overwrite the config file.
|
||||
// If the version was specified in both the arg and config file, the arg will overwrite the config file.
|
||||
if len(args) == 1 {
|
||||
upgradeVersion = args[0]
|
||||
}
|
||||
|
||||
ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(applyFlags.ignorePreflightErrors, upgradeCfg.Apply.IgnorePreflightErrors)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
force, ok := cmdutil.ValueFromFlagsOrConfig(cmd.Flags(), "force", upgradeCfg.Apply.ForceUpgrade, &applyFlags.force).(*bool)
|
||||
if !ok {
|
||||
return nil, cmdutil.TypeMismatchErr("forceUpgrade", "bool")
|
||||
@ -239,10 +240,6 @@ func newApplyData(cmd *cobra.Command, args []string, applyFlags *applyFlags) (*a
|
||||
return nil, errors.Wrap(err, "[upgrade/init config] FATAL")
|
||||
}
|
||||
|
||||
ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(applyFlags.ignorePreflightErrors, upgradeCfg.Apply.IgnorePreflightErrors)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Also set the union of pre-flight errors to InitConfiguration, to provide a consistent view of the runtime configuration:
|
||||
initCfg.NodeRegistration.IgnorePreflightErrors = sets.List(ignorePreflightErrorsSet)
|
||||
|
||||
@ -303,7 +300,7 @@ func (d *applyData) RenewCerts() bool {
|
||||
return d.renewCerts
|
||||
}
|
||||
|
||||
// Cfg returns upgradeConfiguration.
|
||||
// Cfg returns the UpgradeConfiguration.
|
||||
func (d *applyData) Cfg() *kubeadmapi.UpgradeConfiguration {
|
||||
return d.cfg
|
||||
}
|
||||
@ -338,17 +335,17 @@ func (d *applyData) SessionIsInteractive() bool {
|
||||
return !(d.nonInteractiveMode || d.dryRun || d.force)
|
||||
}
|
||||
|
||||
// AllowExperimentalUpgrades returns true if allow upgrading to an alpha/beta/release candidate version of Kubernetes.
|
||||
// AllowExperimentalUpgrades returns true if upgrading to an alpha/beta/release candidate version of Kubernetes is allowed.
|
||||
func (d *applyData) AllowExperimentalUpgrades() bool {
|
||||
return d.allowExperimentalUpgrades
|
||||
}
|
||||
|
||||
// AllowRCUpgrades returns true if allow upgrading to a release candidate version of Kubernetes.
|
||||
// AllowRCUpgrades returns true if upgrading to a release candidate version of Kubernetes is allowed.
|
||||
func (d *applyData) AllowRCUpgrades() bool {
|
||||
return d.allowRCUpgrades
|
||||
}
|
||||
|
||||
// ForceUpgrade returns true if force upgrading although some requirements might not be met.
|
||||
// ForceUpgrade returns true if force-upgrading is enabled.
|
||||
func (d *applyData) ForceUpgrade() bool {
|
||||
return d.force
|
||||
}
|
||||
|
@ -17,7 +17,15 @@ limitations under the License.
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta4"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
)
|
||||
|
||||
func TestSessionIsInteractive(t *testing.T) {
|
||||
@ -61,3 +69,128 @@ func TestSessionIsInteractive(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var testApplyConfig = fmt.Sprintf(`---
|
||||
apiVersion: %s
|
||||
apply:
|
||||
certificateRenewal: true
|
||||
etcdUpgrade: true
|
||||
imagePullPolicy: IfNotPresent
|
||||
imagePullSerial: true
|
||||
diff: {}
|
||||
kind: UpgradeConfiguration
|
||||
node:
|
||||
certificateRenewal: true
|
||||
etcdUpgrade: true
|
||||
imagePullPolicy: IfNotPresent
|
||||
imagePullSerial: true
|
||||
plan: {}
|
||||
timeouts:
|
||||
controlPlaneComponentHealthCheck: 4m0s
|
||||
discovery: 5m0s
|
||||
etcdAPICall: 2m0s
|
||||
kubeletHealthCheck: 4m0s
|
||||
kubernetesAPICall: 1m0s
|
||||
tlsBootstrap: 5m0s
|
||||
upgradeManifests: 5m0s
|
||||
`, kubeadmapiv1.SchemeGroupVersion.String())
|
||||
|
||||
func TestNewApplyData(t *testing.T) {
|
||||
// create temp directory
|
||||
tmpDir, err := os.MkdirTemp("", "kubeadm-upgrade-apply-test")
|
||||
if err != nil {
|
||||
t.Errorf("Unable to create temporary directory: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = os.RemoveAll(tmpDir)
|
||||
}()
|
||||
|
||||
// create config file
|
||||
configFilePath := filepath.Join(tmpDir, "test-config-file")
|
||||
cfgFile, err := os.Create(configFilePath)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to create file %q: %v", configFilePath, err)
|
||||
}
|
||||
defer func() {
|
||||
_ = cfgFile.Close()
|
||||
}()
|
||||
if _, err = cfgFile.WriteString(testApplyConfig); err != nil {
|
||||
t.Fatalf("Unable to write file %q: %v", configFilePath, err)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
flags map[string]string
|
||||
validate func(*testing.T, *applyData)
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "fails if no upgrade version set",
|
||||
flags: map[string]string{
|
||||
options.CfgPath: configFilePath,
|
||||
},
|
||||
expectedError: "missing one or more required arguments. Required arguments: [version]",
|
||||
},
|
||||
{
|
||||
name: "fails if invalid preflight checks are provided",
|
||||
args: []string{"v1.1.0"},
|
||||
flags: map[string]string{
|
||||
options.IgnorePreflightErrors: "all,something-else",
|
||||
},
|
||||
expectedError: "ignore-preflight-errors: Invalid value",
|
||||
},
|
||||
{
|
||||
name: "fails if kubeconfig file doesn't exists",
|
||||
args: []string{"v1.1.0"},
|
||||
flags: map[string]string{
|
||||
options.CfgPath: configFilePath,
|
||||
options.KubeconfigPath: "invalid-kubeconfig-path",
|
||||
},
|
||||
expectedError: "couldn't create a Kubernetes client from file",
|
||||
},
|
||||
|
||||
// TODO: add more test cases here when the fake client for `kubeadm upgrade apply` can be injected
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// initialize an external apply flags and inject it to the apply cmd
|
||||
apf := &applyPlanFlags{
|
||||
kubeConfigPath: kubeadmconstants.GetAdminKubeConfigPath(),
|
||||
cfgPath: "",
|
||||
featureGatesString: "",
|
||||
allowExperimentalUpgrades: false,
|
||||
allowRCUpgrades: false,
|
||||
printConfig: false,
|
||||
out: os.Stdout,
|
||||
}
|
||||
|
||||
cmd := newCmdApply(apf)
|
||||
|
||||
// sets cmd flags (that will be reflected on the init options)
|
||||
for f, v := range tc.flags {
|
||||
_ = cmd.Flags().Set(f, v)
|
||||
}
|
||||
|
||||
flags := &applyFlags{
|
||||
applyPlanFlags: apf,
|
||||
etcdUpgrade: true,
|
||||
renewCerts: true,
|
||||
}
|
||||
|
||||
// test newApplyData method
|
||||
data, err := newApplyData(cmd, tc.args, flags)
|
||||
if err == nil && len(tc.expectedError) != 0 {
|
||||
t.Error("Expected error, but got success")
|
||||
}
|
||||
if err != nil && (len(tc.expectedError) == 0 || !strings.Contains(err.Error(), tc.expectedError)) {
|
||||
t.Fatalf("newApplyData returned unexpected error, expected: %s, got %v", tc.expectedError, err)
|
||||
}
|
||||
|
||||
// exec additional validation on the returned value
|
||||
if tc.validate != nil {
|
||||
tc.validate(t, data)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user