diff --git a/cmd/kubeadm/.import-restrictions b/cmd/kubeadm/.import-restrictions index 5380cfc5771..0cf66938fb2 100644 --- a/cmd/kubeadm/.import-restrictions +++ b/cmd/kubeadm/.import-restrictions @@ -83,7 +83,6 @@ "k8s.io/kubernetes/pkg/util/ipvs", "k8s.io/kubernetes/pkg/util/metrics", "k8s.io/kubernetes/pkg/util/node", - "k8s.io/kubernetes/pkg/util/normalizer", "k8s.io/kubernetes/pkg/util/parsers", "k8s.io/kubernetes/pkg/util/procfs", "k8s.io/kubernetes/pkg/util/sysctl", diff --git a/cmd/kubeadm/app/cmd/alpha/BUILD b/cmd/kubeadm/app/cmd/alpha/BUILD index df4eabaa81f..b38e32481f3 100644 --- a/cmd/kubeadm/app/cmd/alpha/BUILD +++ b/cmd/kubeadm/app/cmd/alpha/BUILD @@ -31,7 +31,6 @@ go_library( "//cmd/kubeadm/app/util/apiclient:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library", - "//pkg/util/normalizer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", "//vendor/github.com/lithammer/dedent:go_default_library", diff --git a/cmd/kubeadm/app/cmd/alpha/certs.go b/cmd/kubeadm/app/cmd/alpha/certs.go index d9cf923902c..52c6df940db 100644 --- a/cmd/kubeadm/app/cmd/alpha/certs.go +++ b/cmd/kubeadm/app/cmd/alpha/certs.go @@ -38,11 +38,10 @@ 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/pkg/util/normalizer" ) var ( - genericCertRenewLongDesc = normalizer.LongDesc(` + genericCertRenewLongDesc = cmdutil.LongDesc(` Renew the %s. Renewals run unconditionally, regardless of certificate expiration date; extra attributes such as SANs will @@ -55,12 +54,12 @@ var ( eventually re-distribute the renewed certificate in case the file is used elsewhere. `) - allLongDesc = normalizer.LongDesc(` + allLongDesc = cmdutil.LongDesc(` Renew all known certificates necessary to run the control plane. Renewals are run unconditionally, regardless of expiration date. Renewals can also be run individually for more control. `) - expirationLongDesc = normalizer.LongDesc(` + expirationLongDesc = cmdutil.LongDesc(` Checks expiration for the certificates in the local PKI managed by kubeadm. `) diff --git a/cmd/kubeadm/app/cmd/alpha/kubeconfig.go b/cmd/kubeadm/app/cmd/alpha/kubeconfig.go index 31a507e83b4..541d0e0f671 100644 --- a/cmd/kubeadm/app/cmd/alpha/kubeconfig.go +++ b/cmd/kubeadm/app/cmd/alpha/kubeconfig.go @@ -28,19 +28,18 @@ import ( kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - kubeconfigLongDesc = normalizer.LongDesc(` + kubeconfigLongDesc = cmdutil.LongDesc(` Kubeconfig file utilities. ` + cmdutil.AlphaDisclaimer) - userKubeconfigLongDesc = normalizer.LongDesc(` + userKubeconfigLongDesc = cmdutil.LongDesc(` Output a kubeconfig file for an additional user. ` + cmdutil.AlphaDisclaimer) - userKubeconfigExample = normalizer.Examples(` + userKubeconfigExample = cmdutil.Examples(` # Output a kubeconfig file for an additional user named foo kubeadm alpha kubeconfig user --client-name=foo `) diff --git a/cmd/kubeadm/app/cmd/alpha/kubelet.go b/cmd/kubeadm/app/cmd/alpha/kubelet.go index 9157a8e5a88..121adb95450 100644 --- a/cmd/kubeadm/app/cmd/alpha/kubelet.go +++ b/cmd/kubeadm/app/cmd/alpha/kubelet.go @@ -29,18 +29,17 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/preflight" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" - "k8s.io/kubernetes/pkg/util/normalizer" utilsexec "k8s.io/utils/exec" ) var ( - kubeletConfigDownloadLongDesc = normalizer.LongDesc(` + kubeletConfigDownloadLongDesc = cmdutil.LongDesc(` Download the kubelet configuration from a ConfigMap of the form "kubelet-config-1.X" in the cluster, where X is the minor version of the kubelet. Either kubeadm autodetects the kubelet version by exec-ing "kubelet --version" or respects the --kubelet-version parameter. ` + cmdutil.AlphaDisclaimer) - kubeletConfigDownloadExample = normalizer.Examples(fmt.Sprintf(` + kubeletConfigDownloadExample = cmdutil.Examples(fmt.Sprintf(` # Download the kubelet configuration from the ConfigMap in the cluster. Autodetect the kubelet version. kubeadm alpha phase kubelet config download @@ -48,7 +47,7 @@ var ( kubeadm alpha phase kubelet config download --kubelet-version %s `, constants.CurrentKubernetesVersion)) - kubeletConfigEnableDynamicLongDesc = normalizer.LongDesc(` + kubeletConfigEnableDynamicLongDesc = cmdutil.LongDesc(` Enable or update dynamic kubelet configuration for a Node, against the kubelet-config-1.X ConfigMap in the cluster, where X is the minor version of the desired kubelet version. @@ -57,7 +56,7 @@ var ( ` + cmdutil.AlphaDisclaimer) - kubeletConfigEnableDynamicExample = normalizer.Examples(fmt.Sprintf(` + kubeletConfigEnableDynamicExample = cmdutil.Examples(fmt.Sprintf(` # Enable dynamic kubelet configuration for a Node. kubeadm alpha phase kubelet enable-dynamic-config --node-name node-1 --kubelet-version %s diff --git a/cmd/kubeadm/app/cmd/alpha/selfhosting.go b/cmd/kubeadm/app/cmd/alpha/selfhosting.go index f80dabd370e..d7929caf927 100644 --- a/cmd/kubeadm/app/cmd/alpha/selfhosting.go +++ b/cmd/kubeadm/app/cmd/alpha/selfhosting.go @@ -20,7 +20,9 @@ import ( "bufio" "fmt" "io" + "os" "strings" + "time" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -38,21 +40,17 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" - "k8s.io/kubernetes/pkg/util/normalizer" - - "os" - "time" ) var ( - selfhostingLongDesc = normalizer.LongDesc(` + selfhostingLongDesc = cmdutil.LongDesc(` Convert static Pod files for control plane components into self-hosted DaemonSets configured via the Kubernetes API. See the documentation for self-hosting limitations. ` + cmdutil.AlphaDisclaimer) - selfhostingExample = normalizer.Examples(` + selfhostingExample = cmdutil.Examples(` # Convert a static Pod-hosted control plane into a self-hosted one. kubeadm alpha phase self-hosting convert-from-staticpods diff --git a/cmd/kubeadm/app/cmd/phases/init/BUILD b/cmd/kubeadm/app/cmd/phases/init/BUILD index 36fd36fccb4..3204aa0e78c 100644 --- a/cmd/kubeadm/app/cmd/phases/init/BUILD +++ b/cmd/kubeadm/app/cmd/phases/init/BUILD @@ -45,7 +45,6 @@ go_library( "//cmd/kubeadm/app/util/apiclient:go_default_library", "//cmd/kubeadm/app/util/dryrun:go_default_library", "//cmd/kubeadm/app/util/pkiutil:go_default_library", - "//pkg/util/normalizer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", diff --git a/cmd/kubeadm/app/cmd/phases/init/addons.go b/cmd/kubeadm/app/cmd/phases/init/addons.go index 7256ddc846f..4f1b1e7ec6f 100644 --- a/cmd/kubeadm/app/cmd/phases/init/addons.go +++ b/cmd/kubeadm/app/cmd/phases/init/addons.go @@ -26,16 +26,15 @@ import ( cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" dnsaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns" proxyaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - coreDNSAddonLongDesc = normalizer.LongDesc(` + coreDNSAddonLongDesc = cmdutil.LongDesc(` Install the CoreDNS addon components via the API server. Please note that although the DNS server is deployed, it will not be scheduled until CNI is installed. `) - kubeProxyAddonLongDesc = normalizer.LongDesc(` + kubeProxyAddonLongDesc = cmdutil.LongDesc(` Install the kube-proxy addon components via the API server. `) ) diff --git a/cmd/kubeadm/app/cmd/phases/init/bootstraptoken.go b/cmd/kubeadm/app/cmd/phases/init/bootstraptoken.go index 3de062365a4..f92ff70b2db 100644 --- a/cmd/kubeadm/app/cmd/phases/init/bootstraptoken.go +++ b/cmd/kubeadm/app/cmd/phases/init/bootstraptoken.go @@ -23,13 +23,13 @@ import ( "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" clusterinfophase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo" nodebootstraptokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - bootstrapTokenLongDesc = normalizer.LongDesc(` + bootstrapTokenLongDesc = cmdutil.LongDesc(` Bootstrap tokens are used for establishing bidirectional trust between a node joining the cluster and a the control-plane node. @@ -37,7 +37,7 @@ var ( and then creates an initial token. `) - bootstrapTokenExamples = normalizer.Examples(` + bootstrapTokenExamples = cmdutil.Examples(` # Make all the bootstrap token configurations and create an initial token, functionally # equivalent to what generated by kubeadm init. kubeadm init phase bootstrap-token diff --git a/cmd/kubeadm/app/cmd/phases/init/certs.go b/cmd/kubeadm/app/cmd/phases/init/certs.go index 7f2c0951d10..8688be33a1b 100644 --- a/cmd/kubeadm/app/cmd/phases/init/certs.go +++ b/cmd/kubeadm/app/cmd/phases/init/certs.go @@ -32,17 +32,16 @@ import ( certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - saKeyLongDesc = fmt.Sprintf(normalizer.LongDesc(` + saKeyLongDesc = fmt.Sprintf(cmdutil.LongDesc(` Generate the private key for signing service account tokens along with its public key, and save them into %s and %s files. If both files already exist, kubeadm skips the generation step and existing files will be used. `+cmdutil.AlphaDisclaimer), kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName) - genericLongDesc = normalizer.LongDesc(` + genericLongDesc = cmdutil.LongDesc(` Generate the %[1]s, and save them into %[2]s.cert and %[2]s.key files.%[3]s If both files already exist, kubeadm skips the generation step and existing files will be used. diff --git a/cmd/kubeadm/app/cmd/phases/init/controlplane.go b/cmd/kubeadm/app/cmd/phases/init/controlplane.go index 895e2d7ab10..ca2f5797cd4 100644 --- a/cmd/kubeadm/app/cmd/phases/init/controlplane.go +++ b/cmd/kubeadm/app/cmd/phases/init/controlplane.go @@ -26,11 +26,10 @@ import ( cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - controlPlaneExample = normalizer.Examples(` + controlPlaneExample = cmdutil.Examples(` # Generates all static Pod manifest files for control plane components, # functionally equivalent to what is generated by kubeadm init. kubeadm init phase control-plane all diff --git a/cmd/kubeadm/app/cmd/phases/init/etcd.go b/cmd/kubeadm/app/cmd/phases/init/etcd.go index 854354a2fb0..c7c2b963a90 100644 --- a/cmd/kubeadm/app/cmd/phases/init/etcd.go +++ b/cmd/kubeadm/app/cmd/phases/init/etcd.go @@ -26,11 +26,10 @@ import ( "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" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - etcdLocalExample = normalizer.Examples(` + etcdLocalExample = cmdutil.Examples(` # Generates the static Pod manifest file for etcd, functionally # equivalent to what is generated by kubeadm init. kubeadm init phase etcd local diff --git a/cmd/kubeadm/app/cmd/phases/init/kubeconfig.go b/cmd/kubeadm/app/cmd/phases/init/kubeconfig.go index 049becccaab..374f3b1d74a 100644 --- a/cmd/kubeadm/app/cmd/phases/init/kubeconfig.go +++ b/cmd/kubeadm/app/cmd/phases/init/kubeconfig.go @@ -25,7 +25,6 @@ import ( cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( @@ -42,7 +41,7 @@ var ( kubeadmconstants.KubeletKubeConfigFileName: { name: "kubelet", short: "Generate a kubeconfig file for the kubelet to use *only* for cluster bootstrapping purposes", - long: normalizer.LongDesc(` + long: cmdutil.LongDesc(` Generate the kubeconfig file for the kubelet to use and save it to %s file. Please note that this should *only* be used for cluster bootstrapping purposes. After your control plane is up, diff --git a/cmd/kubeadm/app/cmd/phases/init/kubelet.go b/cmd/kubeadm/app/cmd/phases/init/kubelet.go index a5a03008ccd..e7633f5c175 100644 --- a/cmd/kubeadm/app/cmd/phases/init/kubelet.go +++ b/cmd/kubeadm/app/cmd/phases/init/kubelet.go @@ -21,12 +21,12 @@ import ( "k8s.io/klog" "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" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - kubeletStartPhaseExample = normalizer.Examples(` + kubeletStartPhaseExample = cmdutil.Examples(` # Writes a dynamic environment file with kubelet flags from a InitConfiguration file. kubeadm init phase kubelet-start --config config.yaml `) diff --git a/cmd/kubeadm/app/cmd/phases/init/markcontrolplane.go b/cmd/kubeadm/app/cmd/phases/init/markcontrolplane.go index 3bf112f94d5..ba05cb7f938 100644 --- a/cmd/kubeadm/app/cmd/phases/init/markcontrolplane.go +++ b/cmd/kubeadm/app/cmd/phases/init/markcontrolplane.go @@ -20,12 +20,12 @@ import ( "github.com/pkg/errors" "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" markcontrolplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markcontrolplane" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - markControlPlaneExample = normalizer.Examples(` + markControlPlaneExample = cmdutil.Examples(` # Applies control-plane label and taint to the current node, functionally equivalent to what executed by kubeadm init. kubeadm init phase mark-control-plane --config config.yml diff --git a/cmd/kubeadm/app/cmd/phases/init/preflight.go b/cmd/kubeadm/app/cmd/phases/init/preflight.go index f61086c83a0..0aab506708f 100644 --- a/cmd/kubeadm/app/cmd/phases/init/preflight.go +++ b/cmd/kubeadm/app/cmd/phases/init/preflight.go @@ -22,13 +22,13 @@ import ( "github.com/pkg/errors" "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" "k8s.io/kubernetes/cmd/kubeadm/app/preflight" - "k8s.io/kubernetes/pkg/util/normalizer" utilsexec "k8s.io/utils/exec" ) var ( - preflightExample = normalizer.Examples(` + preflightExample = cmdutil.Examples(` # Run pre-flight checks for kubeadm init using a config file. kubeadm init phase preflight --config kubeadm-config.yml `) diff --git a/cmd/kubeadm/app/cmd/phases/init/uploadconfig.go b/cmd/kubeadm/app/cmd/phases/init/uploadconfig.go index 7845870a0eb..4f693f83e84 100644 --- a/cmd/kubeadm/app/cmd/phases/init/uploadconfig.go +++ b/cmd/kubeadm/app/cmd/phases/init/uploadconfig.go @@ -31,28 +31,27 @@ import ( kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode" "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - uploadKubeadmConfigLongDesc = fmt.Sprintf(normalizer.LongDesc(` + uploadKubeadmConfigLongDesc = fmt.Sprintf(cmdutil.LongDesc(` Upload the kubeadm ClusterConfiguration to a ConfigMap called %s in the %s namespace. This enables correct configuration of system components and a seamless user experience when upgrading. Alternatively, you can use kubeadm config. `), kubeadmconstants.KubeadmConfigConfigMap, metav1.NamespaceSystem) - uploadKubeadmConfigExample = normalizer.Examples(` + uploadKubeadmConfigExample = cmdutil.Examples(` # upload the configuration of your cluster kubeadm init phase upload-config --config=myConfig.yaml `) - uploadKubeletConfigLongDesc = normalizer.LongDesc(` + uploadKubeletConfigLongDesc = cmdutil.LongDesc(` Upload kubelet configuration extracted from the kubeadm InitConfiguration object to a ConfigMap of the form kubelet-config-1.X in the cluster, where X is the minor version of the current (API Server) Kubernetes version. `) - uploadKubeletConfigExample = normalizer.Examples(` + uploadKubeletConfigExample = cmdutil.Examples(` # Upload the kubelet configuration from the kubeadm Config file to a ConfigMap in the cluster. kubeadm init phase upload-config kubelet --config kubeadm.yaml `) diff --git a/cmd/kubeadm/app/cmd/phases/join/BUILD b/cmd/kubeadm/app/cmd/phases/join/BUILD index 6c36f764fe9..4da71bfd685 100644 --- a/cmd/kubeadm/app/cmd/phases/join/BUILD +++ b/cmd/kubeadm/app/cmd/phases/join/BUILD @@ -16,6 +16,7 @@ go_library( "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/cmd/options:go_default_library", "//cmd/kubeadm/app/cmd/phases/workflow:go_default_library", + "//cmd/kubeadm/app/cmd/util:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/phases/certs:go_default_library", "//cmd/kubeadm/app/phases/controlplane:go_default_library", @@ -29,7 +30,6 @@ go_library( "//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library", - "//pkg/util/normalizer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", diff --git a/cmd/kubeadm/app/cmd/phases/join/controlplanejoin.go b/cmd/kubeadm/app/cmd/phases/join/controlplanejoin.go index 57f5bed1f61..df95435ae71 100644 --- a/cmd/kubeadm/app/cmd/phases/join/controlplanejoin.go +++ b/cmd/kubeadm/app/cmd/phases/join/controlplanejoin.go @@ -24,14 +24,14 @@ import ( "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" etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" markcontrolplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markcontrolplane" uploadconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig" - "k8s.io/kubernetes/pkg/util/normalizer" ) -var controlPlaneJoinExample = normalizer.Examples(` +var controlPlaneJoinExample = cmdutil.Examples(` # Joins a machine as a control plane instance kubeadm join phase control-plane-join all `) diff --git a/cmd/kubeadm/app/cmd/phases/join/controlplaneprepare.go b/cmd/kubeadm/app/cmd/phases/join/controlplaneprepare.go index 674c55dfb1b..201c56bbe93 100644 --- a/cmd/kubeadm/app/cmd/phases/join/controlplaneprepare.go +++ b/cmd/kubeadm/app/cmd/phases/join/controlplaneprepare.go @@ -26,16 +26,16 @@ import ( "k8s.io/klog" "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" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" "k8s.io/kubernetes/cmd/kubeadm/app/phases/copycerts" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" - "k8s.io/kubernetes/pkg/util/normalizer" ) -var controlPlanePrepareExample = normalizer.Examples(` +var controlPlanePrepareExample = cmdutil.Examples(` # Prepares the machine for serving a control plane kubeadm join phase control-plane-prepare all `) diff --git a/cmd/kubeadm/app/cmd/phases/join/preflight.go b/cmd/kubeadm/app/cmd/phases/join/preflight.go index 9bf47b2f1e5..066c91b221d 100644 --- a/cmd/kubeadm/app/cmd/phases/join/preflight.go +++ b/cmd/kubeadm/app/cmd/phases/join/preflight.go @@ -27,14 +27,14 @@ import ( 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" "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" "k8s.io/kubernetes/cmd/kubeadm/app/preflight" - "k8s.io/kubernetes/pkg/util/normalizer" utilsexec "k8s.io/utils/exec" ) var ( - preflightExample = normalizer.Examples(` + preflightExample = cmdutil.Examples(` # Run join pre-flight checks using a config file. kubeadm join phase preflight --config kubeadm-config.yml `) diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/BUILD b/cmd/kubeadm/app/cmd/phases/upgrade/node/BUILD index 5744ffaf529..dfd82184355 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/BUILD +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/BUILD @@ -13,12 +13,12 @@ go_library( "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/cmd/options:go_default_library", "//cmd/kubeadm/app/cmd/phases/workflow:go_default_library", + "//cmd/kubeadm/app/cmd/util:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/phases/kubelet:go_default_library", "//cmd/kubeadm/app/phases/upgrade:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library", "//cmd/kubeadm/app/util/dryrun:go_default_library", - "//pkg/util/normalizer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go index 086804ced22..a64a02afaf3 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go @@ -26,15 +26,15 @@ import ( "k8s.io/apimachinery/pkg/util/version" "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" "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun" - "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - kubeletConfigLongDesc = normalizer.LongDesc(` + kubeletConfigLongDesc = cmdutil.LongDesc(` Download the kubelet configuration from a ConfigMap of the form "kubelet-config-1.X" in the cluster, where X is the minor version of the kubelet. kubeadm uses the KuberneteVersion field in the kubeadm-config ConfigMap to determine what the _desired_ kubelet version is, but the user can override this by using the diff --git a/cmd/kubeadm/app/cmd/util/BUILD b/cmd/kubeadm/app/cmd/util/BUILD index e8249cf8a63..3fb5c76e7a8 100644 --- a/cmd/kubeadm/app/cmd/util/BUILD +++ b/cmd/kubeadm/app/cmd/util/BUILD @@ -14,7 +14,6 @@ go_library( "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library", "//cmd/kubeadm/app/util/pubkeypin:go_default_library", - "//pkg/util/normalizer:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/util/cert:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", @@ -26,7 +25,10 @@ go_library( go_test( name = "go_default_test", - srcs = ["cmdutil_test.go"], + srcs = [ + "cmdutil_test.go", + "documentation_test.go", + ], embed = [":go_default_library"], ) diff --git a/cmd/kubeadm/app/cmd/util/documentation.go b/cmd/kubeadm/app/cmd/util/documentation.go index 4867bb4aee8..29c4c4b3f6e 100644 --- a/cmd/kubeadm/app/cmd/util/documentation.go +++ b/cmd/kubeadm/app/cmd/util/documentation.go @@ -17,7 +17,7 @@ limitations under the License. package util import ( - "k8s.io/kubernetes/pkg/util/normalizer" + "strings" ) var ( @@ -27,7 +27,79 @@ var ( ` // MacroCommandLongDescription provide a standard description for "macro" commands - MacroCommandLongDescription = normalizer.LongDesc(` + MacroCommandLongDescription = LongDesc(` This command is not meant to be run on its own. See list of available subcommands. `) ) + +// LongDesc is designed to help with producing better long command line descriptions in code. +// Its behavior is somewhat inspired by the same function of kubectl, which uses Markdown for the input message. +// This one is not Markdown compliant, but it covers the needs of kubeadm. In particular: +// - Beginning and trailing space characters (including empty lines), are stripped from the output. +// - Consecutive non-empty lines of text are joined with spaces to form paragraphs. +// - Paragraphs are blocks of text divided by one or more empty lines or lines consisting only of "space" characters. +// - Paragraphs are spaced by precisely one empty line in the output. +// - A line break can be forced by adding a couple of empty spaces at the end of a text line. +// - All indentation is removed. The resulting output is not indented. +func LongDesc(s string) string { + // Strip beginning and trailing space characters (including empty lines) and split the lines into a slice + lines := strings.Split(strings.TrimSpace(s), "\n") + + output := []string{} + paragraph := []string{} + + for _, line := range lines { + // Remove indentation and trailing spaces from the current line + trimmedLine := strings.TrimSpace(line) + if trimmedLine == "" { + if len(paragraph) > 0 { + // If the line is empty and the current paragraph is not, we have reached a paragraph end. + // (if the paragraph and the line are empty, then this is non-first empty line in between paragraphs and needs to be ignored) + // In that case we join all of the paragraph lines with a single space, + // add a trailing newline character (to ensure an empty line after the paragraph), + // append the paragraph text to the output and clear everything in the current paragraph slice. + output = append(output, strings.Join(paragraph, " ")+"\n") + paragraph = []string{} + } + } else { + // Non-empty text line, append it to the current paragraph + paragraph = append(paragraph, trimmedLine) + if strings.HasSuffix(line, " ") { + // If the original line has a suffix of couple of spaces, then we add a line break. + // This is achieved by flushing out the current paragraph and starting a new one. + // No trailing space is added to the flushed paragraph, + // so that no empty line is placed between the old and the new paragraphs (a simple line break) + output = append(output, strings.Join(paragraph, " ")) + paragraph = []string{} + } + } + } + + // The last paragraph is always unflushed, so flush it. + // We don't add a trailing newline character, so that we won't have to strip the output. + output = append(output, strings.Join(paragraph, " ")) + + // Join all the paragraphs together with new lines in between them. + return strings.Join(output, "\n") +} + +// Examples is designed to help with producing examples for command line usage. +// Its behavior is mimicking a similar kubectl function in the following ways: +// - Beginning and trailing space characters (including empty lines), are stripped from the output. +// - All lines of text are stripped of beginning and trailing spaces (thus loosing indentation) and are then double-space indented. +func Examples(s string) string { + trimmedText := strings.TrimSpace(s) + if trimmedText == "" { + return "" + } + + const indent = ` ` + inLines := strings.Split(trimmedText, "\n") + outLines := make([]string, 0, len(inLines)) + + for _, line := range inLines { + outLines = append(outLines, indent+strings.TrimSpace(line)) + } + + return strings.Join(outLines, "\n") +} diff --git a/cmd/kubeadm/app/cmd/util/documentation_test.go b/cmd/kubeadm/app/cmd/util/documentation_test.go new file mode 100644 index 00000000000..0e03e40cc12 --- /dev/null +++ b/cmd/kubeadm/app/cmd/util/documentation_test.go @@ -0,0 +1,117 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "testing" +) + +func TestLongDesc(t *testing.T) { + tests := []struct { + desc string + in string + out string + }{ + { + desc: "Empty input produces empty output", + in: "", + out: "", + }, + { + desc: "Single line text is preserved as is", + in: "Some text", + out: "Some text", + }, + { + desc: "Consecutive new lines are combined into a single paragraph", + in: "Line1\nLine2", + out: "Line1 Line2", + }, + { + desc: "Leading and trailing spaces are stripped (single line)", + in: "\t \nThe text line \n \t", + out: "The text line", + }, + { + desc: "Leading and trailing spaces are stripped (multi line)", + in: "\t \nLine1\nLine2 \n \t", + out: "Line1 Line2", + }, + { + desc: "Multiple paragraphs are separated by a single empty line", + in: "Paragraph1\n\nParagraph2\n\n\nParagraph3", + out: "Paragraph1\n\nParagraph2\n\nParagraph3", + }, + { + desc: "Indentation is not preserved", + in: "\tParagraph1Line1\n\tParagraph1Line2\n\n Paragraph2Line1\n Paragraph2Line2", + out: "Paragraph1Line1 Paragraph1Line2\n\nParagraph2Line1 Paragraph2Line2", + }, + { + desc: "Double spaced line breaks", + in: "Line1 \nLine2", + out: "Line1\nLine2", + }, + { + desc: "Double spaced line breaks don't preserve indentation", + in: "\tLine1 \n\tLine2", + out: "Line1\nLine2", + }, + } + + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + got := LongDesc(test.in) + if got != test.out { + t.Errorf("expected(%d):\n%s\n=====\ngot(%d):\n%s\n", len(test.out), test.out, len(got), got) + } + }) + } +} + +func TestExamples(t *testing.T) { + tests := []struct { + desc string + in string + out string + }{ + { + desc: "Empty input produces empty output", + in: "", + out: "", + }, + { + desc: "Text is indented with a couple of spaces", + in: "\tLine1\n\tLine2", + out: " Line1\n Line2", + }, + { + desc: "Text is stripped of leading and trailing spaces", + in: "\t\n\tLine1\t \n\tLine2\t \n\t\n\n", + out: " Line1\n Line2", + }, + } + + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + got := Examples(test.in) + if got != test.out { + t.Errorf("expected(%d):\n%s\n=====\ngot(%d):\n%s\n", len(test.out), test.out, len(got), got) + } + }) + } +}