From 86404ecfbcb9b8e7c7b053e4ab1bceb147be6857 Mon Sep 17 00:00:00 2001 From: David Eads Date: Tue, 6 Nov 2018 10:36:50 -0500 Subject: [PATCH 1/4] UPSTREAM: : inject version into kubectl --- .../kubernetes/pkg/kubectl/cmd/patch_version.go | 16 ++++++++++++++++ .../k8s.io/kubernetes/pkg/kubectl/cmd/version.go | 3 +-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 vendor/k8s.io/kubernetes/pkg/kubectl/cmd/patch_version.go diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/patch_version.go b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/patch_version.go new file mode 100644 index 000000000000..da67e4e8033e --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/patch_version.go @@ -0,0 +1,16 @@ +package cmd + +import ( + apimachineryversion "k8s.io/apimachinery/pkg/version" + "k8s.io/kubernetes/pkg/version" +) + +var OverrideGetVersionFn func() apimachineryversion.Info = nil + +func getKubectlVersion() apimachineryversion.Info { + if OverrideGetVersionFn != nil { + return OverrideGetVersionFn() + } + + return version.Get() +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go index 7e616cbf8d53..ef2e05059a1c 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go @@ -30,7 +30,6 @@ import ( "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/util/i18n" - "k8s.io/kubernetes/pkg/version" ) type Version struct { @@ -104,7 +103,7 @@ func (o *VersionOptions) Run() error { versionInfo Version ) - clientVersion := version.Get() + clientVersion := getKubectlVersion() versionInfo.ClientVersion = &clientVersion if !o.ClientOnly { From 1fb6a51bfeb5cc58fc10f65c42c6cbc771089fdc Mon Sep 17 00:00:00 2001 From: David Eads Date: Tue, 6 Nov 2018 16:29:33 -0500 Subject: [PATCH 2/4] UPSTREAM: 70713: kubectl version should print just client information in the absence of kubeconfig --- vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go index ef2e05059a1c..be737bac8caf 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/version.go @@ -27,6 +27,7 @@ import ( apimachineryversion "k8s.io/apimachinery/pkg/version" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/discovery" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/util/i18n" @@ -60,7 +61,7 @@ func NewVersionOptions(ioStreams genericclioptions.IOStreams) *VersionOptions { } -func NewCmdVersion(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { +func NewCmdVersion(f genericclioptions.RESTClientGetter, ioStreams genericclioptions.IOStreams) *cobra.Command { o := NewVersionOptions(ioStreams) cmd := &cobra.Command{ Use: "version", @@ -79,10 +80,12 @@ func NewCmdVersion(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *co return cmd } -func (o *VersionOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { +func (o *VersionOptions) Complete(f genericclioptions.RESTClientGetter, cmd *cobra.Command) error { var err error o.discoveryClient, err = f.ToDiscoveryClient() - if err != nil { + // if we had an empty rest.Config, continue and just print out client information. + // if we had an error other than being unable to build a rest.Config, fail. + if err != nil && !clientcmd.IsEmptyConfig(err) { return err } return nil @@ -106,7 +109,7 @@ func (o *VersionOptions) Run() error { clientVersion := getKubectlVersion() versionInfo.ClientVersion = &clientVersion - if !o.ClientOnly { + if !o.ClientOnly && o.discoveryClient != nil { // Always request fresh data from the server o.discoveryClient.Invalidate() serverVersion, serverErr = o.discoveryClient.ServerVersion() From ddee4573bdc503c77c2f34272104b5bc9cc64e84 Mon Sep 17 00:00:00 2001 From: David Eads Date: Wed, 20 Feb 2019 11:34:59 -0500 Subject: [PATCH 3/4] generated --- contrib/completions/bash/oc | 7 +++++++ contrib/completions/zsh/oc | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/contrib/completions/bash/oc b/contrib/completions/bash/oc index 2e070760613c..5a8aeb77efdb 100644 --- a/contrib/completions/bash/oc +++ b/contrib/completions/bash/oc @@ -15241,6 +15241,13 @@ _oc_version() flags_with_completion=() flags_completion=() + flags+=("--client") + local_nonpersistent_flags+=("--client") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--short") + local_nonpersistent_flags+=("--short") flags+=("--as=") flags+=("--as-group=") flags+=("--cache-dir=") diff --git a/contrib/completions/zsh/oc b/contrib/completions/zsh/oc index 319473fbb472..5fb0bb05f281 100644 --- a/contrib/completions/zsh/oc +++ b/contrib/completions/zsh/oc @@ -15383,6 +15383,13 @@ _oc_version() flags_with_completion=() flags_completion=() + flags+=("--client") + local_nonpersistent_flags+=("--client") + flags+=("--output=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--output=") + flags+=("--short") + local_nonpersistent_flags+=("--short") flags+=("--as=") flags+=("--as-group=") flags+=("--cache-dir=") From 8d0ae2a3bb99f768cf3ee18093d91e259439be11 Mon Sep 17 00:00:00 2001 From: David Eads Date: Wed, 20 Feb 2019 11:34:55 -0500 Subject: [PATCH 4/4] collapse onto upstream version function --- hack/import-restrictions.json | 2 - pkg/oc/cli/admin/admin.go | 5 - pkg/oc/cli/cli.go | 5 +- pkg/oc/cli/shim_kubectl.go | 3 + pkg/oc/cli/version/version.go | 214 ---------------------------------- test/cmd/basicresources.sh | 6 +- 6 files changed, 6 insertions(+), 229 deletions(-) delete mode 100644 pkg/oc/cli/version/version.go diff --git a/hack/import-restrictions.json b/hack/import-restrictions.json index 073ffd4d3f23..954deda31183 100644 --- a/hack/import-restrictions.json +++ b/hack/import-restrictions.json @@ -617,7 +617,6 @@ "vendor/github.com/coreos/etcd/clientv3", "vendor/github.com/coreos/etcd/pkg/transport", - "vendor/github.com/coreos/etcd/version", "vendor/github.com/ghodss/yaml", "vendor/k8s.io/kubernetes/pkg/api/legacyscheme", @@ -625,7 +624,6 @@ "vendor/k8s.io/kubernetes/pkg/controller/deployment/util", "vendor/k8s.io/kubernetes/pkg/credentialprovider", "vendor/k8s.io/kubernetes/pkg/serviceaccount", - "vendor/k8s.io/kubernetes/pkg/version", "vendor/github.com/openshift/library-go/pkg/git" ] diff --git a/pkg/oc/cli/admin/admin.go b/pkg/oc/cli/admin/admin.go index 40f06283f64b..30453e1181c4 100644 --- a/pkg/oc/cli/admin/admin.go +++ b/pkg/oc/cli/admin/admin.go @@ -37,7 +37,6 @@ import ( "github.com/openshift/origin/pkg/oc/cli/admin/verifyimagesignature" "github.com/openshift/origin/pkg/oc/cli/kubectlwrappers" "github.com/openshift/origin/pkg/oc/cli/options" - "github.com/openshift/origin/pkg/oc/cli/version" ) var adminLong = ktemplates.LongDesc(` @@ -143,10 +142,6 @@ func NewCommandAdmin(name, fullName string, f kcmdutil.Factory, streams genericc options.NewCmdOptions(streams), ) - if name == fullName { - cmds.AddCommand(version.NewCmdVersion(fullName, f, version.NewVersionOptions(false, streams))) - } - return cmds } diff --git a/pkg/oc/cli/cli.go b/pkg/oc/cli/cli.go index 02b5e20e7fe4..cd22b6e6d18e 100644 --- a/pkg/oc/cli/cli.go +++ b/pkg/oc/cli/cli.go @@ -56,7 +56,6 @@ import ( "github.com/openshift/origin/pkg/oc/cli/startbuild" "github.com/openshift/origin/pkg/oc/cli/status" "github.com/openshift/origin/pkg/oc/cli/tag" - "github.com/openshift/origin/pkg/oc/cli/version" "github.com/openshift/origin/pkg/oc/cli/whoami" ) @@ -259,9 +258,7 @@ func NewOcCommand(name, fullName string, in io.Reader, out, errout io.Writer) *c cmds.AddCommand(newExperimentalCommand("ex", name+" ex", f, ioStreams)) cmds.AddCommand(kubectlwrappers.NewCmdPlugin(fullName, f, ioStreams)) - if name == fullName { - cmds.AddCommand(version.NewCmdVersion(fullName, f, version.NewVersionOptions(true, ioStreams))) - } + cmds.AddCommand(kubecmd.NewCmdVersion(f, ioStreams)) cmds.AddCommand(options.NewCmdOptions(ioStreams)) if cmds.Flag("namespace") != nil { diff --git a/pkg/oc/cli/shim_kubectl.go b/pkg/oc/cli/shim_kubectl.go index 8c4fab1600c3..27c312c25335 100644 --- a/pkg/oc/cli/shim_kubectl.go +++ b/pkg/oc/cli/shim_kubectl.go @@ -4,6 +4,7 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions/openshiftpatch" kclientcmd "k8s.io/client-go/tools/clientcmd" + kcmd "k8s.io/kubernetes/pkg/kubectl/cmd" kcmdset "k8s.io/kubernetes/pkg/kubectl/cmd/set" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" @@ -11,6 +12,7 @@ import ( "github.com/openshift/origin/pkg/api/legacygroupification" "github.com/openshift/origin/pkg/oc/originpolymorphichelpers" "github.com/openshift/origin/pkg/oc/util/clientcmd" + "github.com/openshift/origin/pkg/version" ) func shimKubectlForOc() { @@ -41,4 +43,5 @@ func shimKubectlForOc() { // update some functions we inject kcmdutil.GeneratorFn = originpolymorphichelpers.NewGeneratorsFn(kcmdutil.GeneratorFn) kcmdutil.DescriberFn = originpolymorphichelpers.NewDescriberFn(kcmdutil.DescriberFn) + kcmd.OverrideGetVersionFn = version.Get } diff --git a/pkg/oc/cli/version/version.go b/pkg/oc/cli/version/version.go deleted file mode 100644 index 48acf8bfd354..000000000000 --- a/pkg/oc/cli/version/version.go +++ /dev/null @@ -1,214 +0,0 @@ -package version - -import ( - "encoding/json" - "fmt" - "strings" - "time" - - etcdversion "github.com/coreos/etcd/version" - "github.com/spf13/cobra" - - kapierrors "k8s.io/apimachinery/pkg/api/errors" - apimachineryversion "k8s.io/apimachinery/pkg/version" - kubeversiontypes "k8s.io/apimachinery/pkg/version" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/rest" - kclientcmd "k8s.io/client-go/tools/clientcmd" - kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/kubectl/cmd/templates" - kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" - kubeversion "k8s.io/kubernetes/pkg/version" - - "github.com/openshift/origin/pkg/oc/lib/tokencmd" - "github.com/openshift/origin/pkg/version" -) - -var ( - versionLong = templates.LongDesc(`Display client and server versions.`) -) - -type VersionOptions struct { - BaseName string - - ClientConfig *rest.Config - Clients func() (kclientset.Interface, error) - - Timeout time.Duration - - IsServer bool - PrintEtcdVersion bool - PrintClientFeatures bool - - genericclioptions.IOStreams -} - -func NewVersionOptions(printClientFeatures bool, streams genericclioptions.IOStreams) *VersionOptions { - return &VersionOptions{ - IOStreams: streams, - PrintClientFeatures: printClientFeatures, - } -} - -// NewCmdVersion creates a command for displaying the version of this binary -func NewCmdVersion(fullName string, f kcmdutil.Factory, options *VersionOptions) *cobra.Command { - cmd := &cobra.Command{ - Use: "version", - Short: "Display client and server versions", - Long: versionLong, - Run: func(cmd *cobra.Command, args []string) { - options.BaseName = fullName - - if err := options.Complete(cmd, f); err != nil { - kcmdutil.CheckErr(kcmdutil.UsageErrorf(cmd, err.Error())) - } - - if err := options.RunVersion(); err != nil { - kcmdutil.CheckErr(err) - } - }, - } - - return cmd -} - -func (o *VersionOptions) Complete(cmd *cobra.Command, f kcmdutil.Factory) error { - if f == nil { - return nil - } - - var err error - o.ClientConfig, err = f.ToRESTConfig() - if err != nil && !kclientcmd.IsEmptyConfig(err) { - return err - } - o.Clients = func() (kclientset.Interface, error) { - return kclientset.NewForConfig(o.ClientConfig) - } - - if !o.IsServer { - // retrieve config timeout and set cmd option - // use this instead of getting value from global - // flag, as flag value would have to be parsed - // from a string potentially not formatted as - // a valid time.Duration value - config, err := f.ToRESTConfig() - if err == nil { - o.Timeout = config.Timeout - } - } - if o.Timeout == 0 { - o.Timeout = time.Duration(10 * time.Second) - } - return nil -} - -// RunVersion attempts to display client and server versions for Kubernetes and OpenShift -func (o VersionOptions) RunVersion() error { - fmt.Fprintf(o.Out, "%s %v\n", o.BaseName, version.Get()) - fmt.Fprintf(o.Out, "kubernetes %v\n", kubeversion.Get()) - if o.PrintEtcdVersion { - fmt.Fprintf(o.Out, "etcd %v\n", etcdversion.Version) - } - - if o.PrintClientFeatures { - features := []string{} - if tokencmd.BasicEnabled() { - features = append(features, "Basic-Auth") - } - if tokencmd.GSSAPIEnabled() { - features = append(features, "GSSAPI") - } - if tokencmd.SSPIEnabled() { - features = append(features, "SSPI") - } - if tokencmd.GSSAPIEnabled() || tokencmd.SSPIEnabled() { - features = append(features, "Kerberos") - features = append(features, "SPNEGO") - } - fmt.Printf("features: %s\n", strings.Join(features, " ")) - } - - // do not attempt to print server info if already running cmd as the server - // or if no client config is present - if o.ClientConfig == nil || o.IsServer { - return nil - } - - done := make(chan error) - oVersion := "" - kVersion := "" - versionHost := "" - - // start goroutine to fetch openshift / kubernetes server version - go func() { - defer close(done) - - // confirm config exists before making request to server - var err error - versionHost = o.ClientConfig.Host - - kClient, err := o.Clients() - if err != nil { - done <- err - return - } - - kRESTClient := kClient.Core().RESTClient() - kubeVersionBody, err := kRESTClient.Get().AbsPath("/version").Do().Raw() - switch { - case err == nil: - var kubeServerInfo kubeversiontypes.Info - err = json.Unmarshal(kubeVersionBody, &kubeServerInfo) - if err != nil && len(kubeVersionBody) > 0 { - done <- err - return - } - kVersion = fmt.Sprintf("%v", kubeServerInfo) - case kapierrors.IsNotFound(err) || kapierrors.IsUnauthorized(err) || kapierrors.IsForbidden(err): - default: - done <- err - return - } - - ocVersionBody, err := kClient.Discovery().RESTClient().Get().AbsPath("/version/openshift").Do().Raw() - switch { - case err == nil: - var ocServerInfo apimachineryversion.Info - err = json.Unmarshal(ocVersionBody, &ocServerInfo) - if err != nil && len(ocVersionBody) > 0 { - done <- err - return - } - oVersion = fmt.Sprintf("%v", ocServerInfo) - case kapierrors.IsNotFound(err) || kapierrors.IsUnauthorized(err) || kapierrors.IsForbidden(err): - default: - done <- err - return - } - }() - - select { - case err, closed := <-done: - if strings.HasSuffix(fmt.Sprintf("%v", err), "connection refused") || kclientcmd.IsEmptyConfig(err) || kclientcmd.IsConfigurationInvalid(err) { - return nil - } - if closed && err != nil { - return err - } - case <-time.After(o.Timeout): - return fmt.Errorf("%s", "error: server took too long to respond with version information.") - } - - if oVersion != "" || kVersion != "" { - fmt.Fprintf(o.Out, "\n%s%s\n", "Server ", versionHost) - } - if oVersion != "" { - fmt.Fprintf(o.Out, "openshift %s\n", oVersion) - } - if kVersion != "" { - fmt.Fprintf(o.Out, "kubernetes %s\n", kVersion) - } - - return nil -} diff --git a/test/cmd/basicresources.sh b/test/cmd/basicresources.sh index 8bd3d1019cf6..3ebcc63d4a2c 100755 --- a/test/cmd/basicresources.sh +++ b/test/cmd/basicresources.sh @@ -29,10 +29,8 @@ os_git_regex="$( escape_regex "${OS_GIT_VERSION%%-*}" )" kube_git_regex="$( escape_regex "${KUBE_GIT_VERSION%%-*}" )" etcd_version="$(echo "${ETCD_GIT_VERSION}" | sed -E "s/\-.*//g" | sed -E "s/v//")" etcd_git_regex="$( escape_regex "${etcd_version%%-*}" )" -os::cmd::expect_success_and_text 'oc version' "oc ${os_git_regex}" -os::cmd::expect_success_and_text 'oc version' "kubernetes ${kube_git_regex}" -os::cmd::expect_success_and_text 'oc version' "features: Basic-Auth" -os::cmd::expect_success_and_text 'openshift version' "openshift ${os_git_regex}" +os::cmd::expect_success_and_text 'oc version' "Client Version: .*GitVersion:\"${os_git_regex}" +os::cmd::expect_success_and_text 'oc version' "Server Version: .*GitVersion:\"${kube_git_regex}" os::cmd::expect_success_and_text "curl -k '${API_SCHEME}://${API_HOST}:${API_PORT}/version'" "${kube_git_regex}" os::cmd::expect_success_and_text "curl -k '${API_SCHEME}://${API_HOST}:${API_PORT}/version'" "${OS_GIT_COMMIT}"