func promptForInsecureTLS(reader io.Reader, out io.Writer) bool { var input bool if term.IsTerminal(reader) { fmt.Fprintln(out, "The server uses a certificate signed by an unknown authority.") fmt.Fprintln(out, "You can bypass the certificate check, but any data you send to the server could be intercepted by others.") input = cmdutil.PromptForBool(os.Stdin, out, "Use insecure connections? (y/n): ") fmt.Fprintln(out) } return input }
func promptForInsecureTLS(reader io.Reader, out io.Writer, reason error) bool { var insecureTLSRequestReason string if reason != nil { switch reason.(type) { case x509.UnknownAuthorityError: insecureTLSRequestReason = "The server uses a certificate signed by an unknown authority." case x509.HostnameError: insecureTLSRequestReason = fmt.Sprintf("The server is using a certificate that does not match its hostname: %s", reason.Error()) case x509.CertificateInvalidError: insecureTLSRequestReason = fmt.Sprintf("The server is using an invalid certificate: %s", reason.Error()) } } var input bool if term.IsTerminal(reader) { if len(insecureTLSRequestReason) > 0 { fmt.Fprintln(out, insecureTLSRequestReason) } fmt.Fprintln(out, "You can bypass the certificate check, but any data you send to the server could be intercepted by others.") input = cmdutil.PromptForBool(os.Stdin, out, "Use insecure connections? (y/n): ") fmt.Fprintln(out) } return input }
// getClientConfig returns back the current clientConfig as we know it. If there is no clientConfig, it builds one with enough information // to talk to a server. This may involve user prompts. This method is not threadsafe. func (o *LoginOptions) getClientConfig() (*kclient.Config, error) { if o.Config != nil { return o.Config, nil } clientConfig := &kclient.Config{} if len(o.Server) == 0 { // we need to have a server to talk to if cmdutil.IsTerminal(o.Reader) { for !o.serverProvided() { defaultServer := defaultClusterURL promptMsg := fmt.Sprintf("Server [%s]: ", defaultServer) o.Server = cmdutil.PromptForStringWithDefault(o.Reader, defaultServer, promptMsg) } } } // normalize the provided server to a format expected by config serverNormalized, err := config.NormalizeServerURL(o.Server) if err != nil { return nil, err } o.Server = serverNormalized clientConfig.Host = o.Server if len(o.CAFile) > 0 { clientConfig.CAFile = o.CAFile } else { // check all cluster stanzas to see if we already have one with this URL that contains a client cert for _, cluster := range o.StartingKubeConfig.Clusters { if cluster.Server == clientConfig.Host { if len(cluster.CertificateAuthority) > 0 { clientConfig.CAFile = cluster.CertificateAuthority break } if len(cluster.CertificateAuthorityData) > 0 { clientConfig.CAData = cluster.CertificateAuthorityData break } } } } // ping to check if server is reachable osClient, err := client.New(clientConfig) if err != nil { return nil, err } result := osClient.Get().AbsPath("/osapi").Do() if result.Error() != nil { switch { case o.InsecureTLS: clientConfig.Insecure = true // certificate issue, prompt user for insecure connection case clientcmd.IsCertificateAuthorityUnknown(result.Error()): // check to see if we already have a cluster stanza that tells us to use --insecure for this particular server. If we don't, then prompt clientConfigToTest := *clientConfig clientConfigToTest.Insecure = true matchingClusters := getMatchingClusters(clientConfigToTest, *o.StartingKubeConfig) if len(matchingClusters) > 0 { clientConfig.Insecure = true } else if cmdutil.IsTerminal(o.Reader) { fmt.Fprintln(o.Out, "The server uses a certificate signed by an unknown authority.") fmt.Fprintln(o.Out, "You can bypass the certificate check, but any data you send to the server could be intercepted by others.") clientConfig.Insecure = cmdutil.PromptForBool(os.Stdin, "Use insecure connections? (y/n): ") if !clientConfig.Insecure { return nil, fmt.Errorf(clientcmd.GetPrettyMessageFor(result.Error())) } fmt.Fprintln(o.Out) } default: return nil, result.Error() } } // check for matching api version if len(o.APIVersion) > 0 { clientConfig.Version = o.APIVersion } o.Config = clientConfig return o.Config, nil }