// maybeWrapForConnectionUpgrades wraps the roundtripper for upgrades. The bool indicates if it was wrapped func (r *proxyHandler) maybeWrapForConnectionUpgrades(rt http.RoundTripper, req *http.Request) (http.RoundTripper, bool, error) { connectionHeader := req.Header.Get("Connection") if len(connectionHeader) == 0 { return rt, false, nil } cfg := r.getRESTConfig() tlsConfig, err := restclient.TLSConfigFor(cfg) if err != nil { return nil, true, err } upgradeRoundTripper := spdy.NewRoundTripper(tlsConfig) wrappedRT, err := restclient.HTTPWrappersForConfig(cfg, upgradeRoundTripper) if err != nil { return nil, true, err } return wrappedRT, true, nil }
// NewExecutor connects to the provided server and upgrades the connection to // multiplexed bidirectional streams. The current implementation uses SPDY, // but this could be replaced with HTTP/2 once it's available, or something else. // TODO: the common code between this and portforward could be abstracted. func NewExecutor(config *restclient.Config, method string, url *url.URL) (StreamExecutor, error) { tlsConfig, err := restclient.TLSConfigFor(config) if err != nil { return nil, err } upgradeRoundTripper := spdy.NewRoundTripper(tlsConfig) wrapper, err := restclient.HTTPWrappersForConfig(config, upgradeRoundTripper) if err != nil { return nil, err } return &streamExecutor{ upgrader: upgradeRoundTripper, transport: wrapper, method: method, url: url, }, nil }
// getClients returns a Kube client, OpenShift client, and registry client. func getClients(f *clientcmd.Factory, caBundle string) (*client.Client, *kclient.Client, *http.Client, error) { clientConfig, err := f.OpenShiftClientConfig.ClientConfig() if err != nil { return nil, nil, nil, err } var ( token string osClient *client.Client kClient *kclient.Client registryClient *http.Client ) switch { case len(clientConfig.BearerToken) > 0: osClient, kClient, err = f.Clients() if err != nil { return nil, nil, nil, err } token = clientConfig.BearerToken default: err = errors.New("You must use a client config with a token") return nil, nil, nil, err } // copy the config registryClientConfig := *clientConfig // zero out everything we don't want to use registryClientConfig.BearerToken = "" registryClientConfig.CertFile = "" registryClientConfig.CertData = []byte{} registryClientConfig.KeyFile = "" registryClientConfig.KeyData = []byte{} // we have to set a username to something for the Docker login // but it's not actually used registryClientConfig.Username = "******" // set the "password" to be the token registryClientConfig.Password = token tlsConfig, err := restclient.TLSConfigFor(®istryClientConfig) if err != nil { return nil, nil, nil, err } // if the user specified a CA on the command line, add it to the // client config's CA roots if len(caBundle) > 0 { data, err := ioutil.ReadFile(caBundle) if err != nil { return nil, nil, nil, err } if tlsConfig.RootCAs == nil { tlsConfig.RootCAs = x509.NewCertPool() } tlsConfig.RootCAs.AppendCertsFromPEM(data) } transport := knet.SetTransportDefaults(&http.Transport{ TLSClientConfig: tlsConfig, }) wrappedTransport, err := restclient.HTTPWrappersForConfig(®istryClientConfig, transport) if err != nil { return nil, nil, nil, err } registryClient = &http.Client{ Transport: wrappedTransport, } return osClient, kClient, registryClient, nil }