func checkErr(err error, handleErr func(string)) { if err == nil { return } if errors.IsInvalid(err) { details := err.(*errors.StatusError).Status().Details prefix := fmt.Sprintf("The %s %q is invalid.\n", details.Kind, details.Name) errs := statusCausesToAggrError(details.Causes) handleErr(MultilineError(prefix, errs)) } // handle multiline errors if clientcmd.IsConfigurationInvalid(err) { handleErr(MultilineError("Error in configuration: ", err)) } if agg, ok := err.(utilerrors.Aggregate); ok && len(agg.Errors()) > 0 { handleErr(MultipleErrors("", agg.Errors())) } msg, ok := StandardErrorMessage(err) if !ok { msg = fmt.Sprintf("error: %s", err.Error()) } handleErr(msg) }
// checkErr formats a given error as a string and calls the passed handleErr // func with that string and an kubectl exit code. func checkErr(prefix string, err error, handleErr func(string, int)) { // unwrap aggregates of 1 if agg, ok := err.(utilerrors.Aggregate); ok && len(agg.Errors()) == 1 { err = agg.Errors()[0] } switch { case err == nil: return case err == ErrExit: handleErr("", DefaultErrorExitCode) return case kerrors.IsInvalid(err): details := err.(*kerrors.StatusError).Status().Details s := fmt.Sprintf("%sThe %s %q is invalid", prefix, details.Kind, details.Name) if len(details.Causes) > 0 { errs := statusCausesToAggrError(details.Causes) handleErr(MultilineError(s+": ", errs), DefaultErrorExitCode) } else { handleErr(s, DefaultErrorExitCode) } case clientcmd.IsConfigurationInvalid(err): handleErr(MultilineError(fmt.Sprintf("%sError in configuration: ", prefix), err), DefaultErrorExitCode) default: switch err := err.(type) { case *meta.NoResourceMatchError: switch { case len(err.PartialResource.Group) > 0 && len(err.PartialResource.Version) > 0: handleErr(fmt.Sprintf("%sthe server doesn't have a resource type %q in group %q and version %q", prefix, err.PartialResource.Resource, err.PartialResource.Group, err.PartialResource.Version), DefaultErrorExitCode) case len(err.PartialResource.Group) > 0: handleErr(fmt.Sprintf("%sthe server doesn't have a resource type %q in group %q", prefix, err.PartialResource.Resource, err.PartialResource.Group), DefaultErrorExitCode) case len(err.PartialResource.Version) > 0: handleErr(fmt.Sprintf("%sthe server doesn't have a resource type %q in version %q", prefix, err.PartialResource.Resource, err.PartialResource.Version), DefaultErrorExitCode) default: handleErr(fmt.Sprintf("%sthe server doesn't have a resource type %q", prefix, err.PartialResource.Resource), DefaultErrorExitCode) } case utilerrors.Aggregate: handleErr(MultipleErrors(prefix, err.Errors()), DefaultErrorExitCode) case utilexec.ExitError: // do not print anything, only terminate with given error handleErr("", err.ExitStatus()) default: // for any other error type msg, ok := StandardErrorMessage(err) if !ok { msg = err.Error() if !strings.HasPrefix(msg, "error: ") { msg = fmt.Sprintf("error: %s", msg) } } handleErr(msg, DefaultErrorExitCode) } } }
func detectReason(err error) int { if err != nil { switch { case strings.Contains(err.Error(), "certificate signed by unknown authority"): return certificateAuthorityUnknownReason case strings.Contains(err.Error(), "no server defined"): return noServerFoundReason case clientcmd.IsConfigurationInvalid(err): return configurationInvalidReason } } return unknownReason }
func checkErr(err error, handleErr func(string)) { if err == nil { return } if kerrors.IsInvalid(err) { details := err.(*kerrors.StatusError).Status().Details prefix := fmt.Sprintf("The %s %q is invalid.\n", details.Kind, details.Name) errs := statusCausesToAggrError(details.Causes) handleErr(MultilineError(prefix, errs)) return } if noMatch, ok := err.(*meta.NoResourceMatchError); ok { switch { case len(noMatch.PartialResource.Group) > 0 && len(noMatch.PartialResource.Version) > 0: handleErr(fmt.Sprintf("the server doesn't have a resource type %q in group %q and version %q", noMatch.PartialResource.Resource, noMatch.PartialResource.Group, noMatch.PartialResource.Version)) case len(noMatch.PartialResource.Group) > 0: handleErr(fmt.Sprintf("the server doesn't have a resource type %q in group %q", noMatch.PartialResource.Resource, noMatch.PartialResource.Group)) case len(noMatch.PartialResource.Version) > 0: handleErr(fmt.Sprintf("the server doesn't have a resource type %q in version %q", noMatch.PartialResource.Resource, noMatch.PartialResource.Version)) default: handleErr(fmt.Sprintf("the server doesn't have a resource type %q", noMatch.PartialResource.Resource)) } return } // handle multiline errors if clientcmd.IsConfigurationInvalid(err) { handleErr(MultilineError("Error in configuration: ", err)) return } if agg, ok := err.(utilerrors.Aggregate); ok && len(agg.Errors()) > 0 { handleErr(MultipleErrors("", agg.Errors())) return } msg, ok := StandardErrorMessage(err) if !ok { msg = err.Error() if !strings.HasPrefix(msg, "error: ") { msg = fmt.Sprintf("error: %s", msg) } } handleErr(msg) }
func detectReason(err error) int { if err != nil { switch { case strings.Contains(err.Error(), "certificate signed by unknown authority"): return certificateAuthorityUnknownReason case strings.Contains(err.Error(), "no server defined"): return noServerFoundReason case clientcmd.IsConfigurationInvalid(err): return configurationInvalidReason case strings.Contains(err.Error(), "tls: oversized record received"): return tlsOversizedRecordReason } switch err.(type) { case x509.UnknownAuthorityError: return certificateAuthorityUnknownReason case x509.HostnameError: return certificateHostnameErrorReason case x509.CertificateInvalidError: return certificateInvalidReason } } return unknownReason }
// 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") features = append(features, "Kerberos") // GSSAPI or SSPI features = append(features, "SPNEGO") // GSSAPI or SSPI } 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 } // max amount of time we want to wait for server to respond timeout := 10 * time.Second done := make(chan error) oVersion := "" kVersion := "" versionHost := "" // start goroutine to fetch openshift / kubernetes server version go func() { defer close(done) // confirm config exists before makig request to server var err error clientConfig, err := o.ClientConfig.ClientConfig() if err != nil { done <- err return } versionHost = clientConfig.Host oClient, kClient, err := o.Clients() if err != nil { done <- err return } ocVersionBody, err := oClient.Get().AbsPath("/version/openshift").Do().Raw() if kapierrors.IsNotFound(err) || kapierrors.IsUnauthorized(err) || kapierrors.IsForbidden(err) { return } if err != nil { done <- err return } var ocServerInfo version.Info err = json.Unmarshal(ocVersionBody, &ocServerInfo) if err != nil && len(ocVersionBody) > 0 { done <- err return } oVersion = fmt.Sprintf("%v", ocServerInfo) kubeVersionBody, err := kClient.Get().AbsPath("/version").Do().Raw() if kapierrors.IsNotFound(err) || kapierrors.IsUnauthorized(err) || kapierrors.IsForbidden(err) { return } if err != nil { done <- err return } var kubeServerInfo kubeversion.Info err = json.Unmarshal(kubeVersionBody, &kubeServerInfo) if err != nil && len(kubeVersionBody) > 0 { done <- err return } kVersion = fmt.Sprintf("%v", kubeServerInfo) }() select { case err, closed := <-done: if strings.HasSuffix(fmt.Sprintf("%v", err), "connection refused") || clientcmd.IsConfigurationMissing(err) || kclientcmd.IsConfigurationInvalid(err) { return nil } if closed && err != nil { return err } case <-time.After(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 }