Example #1
0
// NewClient initializes a new API client for the given host and API version.
// It uses the given http client as transport.
// It also initializes the custom http headers to add to each request.
//
// It won't send any version information if the version number is empty. It is
// highly recommended that you set a version or your client may break if the
// server is upgraded.
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
	proto, addr, basePath, err := ParseHost(host)
	if err != nil {
		return nil, err
	}

	if client == nil {
		client = &http.Client{}
	}

	if client.Transport == nil {
		// setup the transport, if not already present
		transport := new(http.Transport)
		sockets.ConfigureTransport(transport, proto, addr)
		client.Transport = transport
	}

	return &Client{
		host:              host,
		proto:             proto,
		addr:              addr,
		basePath:          basePath,
		client:            client,
		version:           version,
		customHTTPHeaders: httpHeaders,
	}, nil
}
Example #2
0
// NewClient creates a new plugin client (http).
func NewClient(addr string, tlsConfig tlsconfig.Options) (*Client, error) {
	tr := &http.Transport{}

	c, err := tlsconfig.Client(tlsConfig)
	if err != nil {
		return nil, err
	}
	tr.TLSClientConfig = c

	u, err := url.Parse(addr)
	if err != nil {
		return nil, err
	}
	socket := u.Host
	if socket == "" {
		// valid local socket addresses have the host empty.
		socket = u.Path
	}
	if err := sockets.ConfigureTransport(tr, u.Scheme, socket); err != nil {
		return nil, err
	}
	scheme := httpScheme(u)

	clientTransport := transport.NewHTTPTransport(tr, scheme, socket)
	return NewClientWithTransport(clientTransport), nil
}
Example #3
0
func (provider *Docker) createClient() (client.APIClient, error) {
	var httpClient *http.Client
	httpHeaders := map[string]string{
		// FIXME(vdemeester) use version here O:)
		"User-Agent": "Traefik",
	}
	if provider.TLS != nil {
		tlsOptions := tlsconfig.Options{
			CAFile:             provider.TLS.CA,
			CertFile:           provider.TLS.Cert,
			KeyFile:            provider.TLS.Key,
			InsecureSkipVerify: provider.TLS.InsecureSkipVerify,
		}
		config, err := tlsconfig.Client(tlsOptions)
		if err != nil {
			return nil, err
		}
		tr := &http.Transport{
			TLSClientConfig: config,
		}
		proto, addr, _, err := client.ParseHost(provider.Endpoint)
		if err != nil {
			return nil, err
		}

		sockets.ConfigureTransport(tr, proto, addr)

		httpClient = &http.Client{
			Transport: tr,
		}
	}
	return client.NewClient(provider.Endpoint, DockerAPIVersion, httpClient, httpHeaders)
}
Example #4
0
func (provider *Docker) createClient() (client.APIClient, error) {
	var httpClient *http.Client
	httpHeaders := map[string]string{
		"User-Agent": "Traefik " + version.Version,
	}
	if provider.TLS != nil {
		config, err := provider.TLS.CreateTLSConfig()
		if err != nil {
			return nil, err
		}
		tr := &http.Transport{
			TLSClientConfig: config,
		}
		proto, addr, _, err := client.ParseHost(provider.Endpoint)
		if err != nil {
			return nil, err
		}

		sockets.ConfigureTransport(tr, proto, addr)

		httpClient = &http.Client{
			Transport: tr,
		}

	}
	var version string
	if provider.SwarmMode {
		version = SwarmAPIVersion
	} else {
		version = DockerAPIVersion
	}
	return client.NewClient(provider.Endpoint, version, httpClient, httpHeaders)

}
Example #5
0
// NewClient initializes a new API client for the given host and API version.
// It uses the given http client as transport.
// It also initializes the custom http headers to add to each request.
//
// It won't send any version information if the version number is empty. It is
// highly recommended that you set a version or your client may break if the
// server is upgraded.
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
	proto, addr, basePath, err := ParseHost(host)
	if err != nil {
		return nil, err
	}

	if client != nil {
		if _, ok := client.Transport.(*http.Transport); !ok {
			return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport)
		}
	} else {
		transport := new(http.Transport)
		sockets.ConfigureTransport(transport, proto, addr)
		client = &http.Client{
			Transport: transport,
		}
	}

	return &Client{
		host:              host,
		proto:             proto,
		addr:              addr,
		basePath:          basePath,
		client:            client,
		version:           version,
		customHTTPHeaders: httpHeaders,
	}, nil
}
Example #6
0
func (d *Daemon) getClientConfig() (*clientConfig, error) {
	var (
		transport *http.Transport
		scheme    string
		addr      string
		proto     string
	)
	if d.UseDefaultTLSHost {
		option := &tlsconfig.Options{
			CAFile:   "fixtures/https/ca.pem",
			CertFile: "fixtures/https/client-cert.pem",
			KeyFile:  "fixtures/https/client-key.pem",
		}
		tlsConfig, err := tlsconfig.Client(*option)
		if err != nil {
			return nil, err
		}
		transport = &http.Transport{
			TLSClientConfig: tlsConfig,
		}
		addr = fmt.Sprintf("%s:%d", opts.DefaultHTTPHost, opts.DefaultTLSHTTPPort)
		scheme = "https"
		proto = "tcp"
	} else if d.UseDefaultHost {
		addr = opts.DefaultUnixSocket
		proto = "unix"
		scheme = "http"
		transport = &http.Transport{}
	} else {
		addr = d.sockPath()
		proto = "unix"
		scheme = "http"
		transport = &http.Transport{}
	}

	if err := sockets.ConfigureTransport(transport, proto, addr); err != nil {
		return nil, err
	}
	transport.DisableKeepAlives = true

	return &clientConfig{
		transport: transport,
		scheme:    scheme,
		addr:      addr,
	}, nil
}
Example #7
0
// NewClient creates a new plugin client (http).
func NewClient(addr string, tlsConfig tlsconfig.Options) (*Client, error) {
	tr := &http.Transport{}

	c, err := tlsconfig.Client(tlsConfig)
	if err != nil {
		return nil, err
	}
	tr.TLSClientConfig = c

	protoAndAddr := strings.Split(addr, "://")
	sockets.ConfigureTransport(tr, protoAndAddr[0], protoAndAddr[1])

	scheme := protoAndAddr[0]
	if scheme != "https" {
		scheme = "http"
	}
	return &Client{&http.Client{Transport: tr}, scheme, protoAndAddr[1]}, nil
}
Example #8
0
func (d *Daemon) getClientConfig() (*clientConfig, error) {
	var (
		transport *http.Transport
		scheme    string
		addr      string
		proto     string
	)
	if d.useDefaultTLSHost {
		option := &tlsconfig.Options{
			CAFile:   "fixtures/https/ca.pem",
			CertFile: "fixtures/https/client-cert.pem",
			KeyFile:  "fixtures/https/client-key.pem",
		}
		tlsConfig, err := tlsconfig.Client(*option)
		if err != nil {
			return nil, err
		}
		transport = &http.Transport{
			TLSClientConfig: tlsConfig,
		}
		addr = fmt.Sprintf("%s:%d", opts.DefaultHTTPHost, opts.DefaultTLSHTTPPort)
		scheme = "https"
		proto = "tcp"
	} else if d.useDefaultHost {
		addr = opts.DefaultUnixSocket
		proto = "unix"
		scheme = "http"
		transport = &http.Transport{}
	} else {
		addr = filepath.Join(d.folder, "docker.sock")
		proto = "unix"
		scheme = "http"
		transport = &http.Transport{}
	}

	d.c.Assert(sockets.ConfigureTransport(transport, proto, addr), check.IsNil)

	return &clientConfig{
		transport: transport,
		scheme:    scheme,
		addr:      addr,
	}, nil
}
Example #9
0
// NewClient creates an http client for the specific host
func NewClient(host string) (*http.Client, error) {
	// FIXME(vdemeester) 10*time.Second timeout of SockRequest… ?
	proto, addr, _, err := dclient.ParseHost(host)
	if err != nil {
		return nil, err
	}
	transport := new(http.Transport)
	if proto == "tcp" && os.Getenv("DOCKER_TLS_VERIFY") != "" {
		// Setup the socket TLS configuration.
		tlsConfig, err := getTLSConfig()
		if err != nil {
			return nil, err
		}
		transport = &http.Transport{TLSClientConfig: tlsConfig}
	}
	err = sockets.ConfigureTransport(transport, proto, addr)
	return &http.Client{
		Transport: transport,
	}, err
}
Example #10
0
// NewClient initializes a new API client for the given host and API version.
// It uses the given http client as transport.
// It also initializes the custom http headers to add to each request.
//
// It won't send any version information if the version number is empty. It is
// highly recommended that you set a version or your client may break if the
// server is upgraded.
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
	proto, addr, basePath, err := ParseHost(host)
	if err != nil {
		return nil, err
	}

	if client != nil {
		if _, ok := client.Transport.(*http.Transport); !ok {
			return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport)
		}
	} else {
		transport := new(http.Transport)
		sockets.ConfigureTransport(transport, proto, addr)
		client = &http.Client{
			Transport: transport,
		}
	}

	scheme := "http"
	tlsConfig := resolveTLSConfig(client.Transport)
	if tlsConfig != nil {
		// TODO(stevvooe): This isn't really the right way to write clients in Go.
		// `NewClient` should probably only take an `*http.Client` and work from there.
		// Unfortunately, the model of having a host-ish/url-thingy as the connection
		// string has us confusing protocol and transport layers. We continue doing
		// this to avoid breaking existing clients but this should be addressed.
		scheme = "https"
	}

	return &Client{
		scheme:            scheme,
		host:              host,
		proto:             proto,
		addr:              addr,
		basePath:          basePath,
		client:            client,
		version:           version,
		customHTTPHeaders: httpHeaders,
	}, nil
}
Example #11
0
func newHTTPClient(host string, tlsOptions *tlsconfig.Options) (*http.Client, error) {
	if tlsOptions == nil {
		// let the api client configure the default transport.
		return nil, nil
	}

	config, err := tlsconfig.Client(*tlsOptions)
	if err != nil {
		return nil, err
	}
	tr := &http.Transport{
		TLSClientConfig: config,
	}
	proto, addr, _, err := client.ParseHost(host)
	if err != nil {
		return nil, err
	}

	sockets.ConfigureTransport(tr, proto, addr)

	return &http.Client{
		Transport: tr,
	}, nil
}
Example #12
0
File: exec.go Project: yiduoyunQ/sm
func (s *Swarm) Exec(cmd []string, containName string) (types.HijackedResponse, error) {
	var err error
	defer func() {
		if err != nil {
			log.WithFields(log.Fields{
				"cmd":         cmd,
				"ContainName": containName,
				"err":         err.Error(),
			}).Error("swarm exec error")
		}
	}()
	timeEnd := time.Now().Add(s.config.SwarmRetryTimeoutAll)
	defaultHeaders := map[string]string{"User-Agent": s.config.SwarmUserAgent}

	// for set client.Timeout do what engine-api do start
	// transport = defaultTransport(proto, addr)
	transport := new(http.Transport)
	sockets.ConfigureTransport(transport, "tcp", s.host)
	// for set client.Timeout do what engine-api do end
	c := &http.Client{
		Timeout:   s.config.SwarmRetryTimeout,
		Transport: transport,
	}
	// get last swarm host when connect error and retry once
	bRegetSwarmHost := false
	for i := 1; i <= s.config.SwarmRetryTimes; i++ {
		if timeEnd.Before(time.Now()) {
			return types.HijackedResponse{}, errors.New(fmt.Sprintf("time out after %+v\n", s.config.SwarmRetryTimeoutAll))
		}

		cli, err := client.NewClient("tcp://"+s.host, s.ApiVersion, c, defaultHeaders)
		if err != nil {
			log.WithFields(log.Fields{
				"cmd":         cmd,
				"ContainName": containName,
				"RetryTimes":  i,
				"err":         err.Error(),
			}).Error("swarm NewClient error")
			if !bRegetSwarmHost && s.consul != nil {
				log.Info("try to get swarm host from consul once again")
				bRegetSwarmHost = true
				swarmHost, err := s.consul.GetVal(s.config.SwarmHostKey)
				if err != nil {
					log.WithFields(log.Fields{
						"err": err.Error(),
					}).Error("consul connect error")
					time.Sleep(s.config.SwarmRetryInterval)
				} else if swarmHost == "" {
					log.WithFields(log.Fields{
						"key": s.config.SwarmHostKey,
						"err": err.Error(),
					}).Error("get empty SwarmHost from consul")
					time.Sleep(s.config.SwarmRetryInterval)
				} else {
					log.WithFields(log.Fields{
						"OldSwarmHost": s.host,
						"NewSwarmHost": swarmHost,
					}).Info("swarm host updated from consul")
					s.host = swarmHost
					// retry once
					cli, err = client.NewClient("tcp://"+s.host, s.ApiVersion, c, defaultHeaders)
					if err != nil {
						log.WithFields(log.Fields{
							"err": err.Error(),
						}).Error("swarm reconnect error")
					}
				}
			} else {
				time.Sleep(s.config.SwarmRetryInterval)
				continue
			}
		}

		execConfig := types.ExecConfig{
			Tty:          true,
			Detach:       false,
			AttachStdin:  true,
			AttachStderr: true,
			AttachStdout: true,
		}
		//execConfig.Container = containName
		execConfig.Cmd = cmd

		creres, err := cli.ContainerExecCreate(context.Background(), containName, execConfig)
		if err != nil {
			log.WithFields(log.Fields{
				"cmd":         cmd,
				"ContainName": containName,
				"RetryTimes":  i,
				"err":         err.Error(),
			}).Error("swarm ContainerExecCreate error")
			time.Sleep(s.config.SwarmRetryInterval)
			continue
		}
		res, err := cli.ContainerExecAttach(context.Background(), creres.ID, execConfig)
		if err != nil {
			log.WithFields(log.Fields{
				"cmd":         cmd,
				"ContainName": containName,
				"RetryTimes":  i,
				"err":         err.Error(),
			}).Error("swarm ContainerExecAttach error")
			time.Sleep(s.config.SwarmRetryInterval)
			continue
		}
		return res, nil
	}
	return types.HijackedResponse{}, errors.New(fmt.Sprintf("swarm exec cmd:%+v, containName:%s, retry %d times fail\n", cmd, containName, s.config.SwarmRetryTimes))
}
Example #13
0
// defaultTransport creates a new http.Transport with Docker's
// default transport configuration.
func defaultTransport(proto, addr string) *http.Transport {
	tr := new(http.Transport)
	sockets.ConfigureTransport(tr, proto, addr)
	return tr
}
Example #14
0
// CreateClient creates a docker client based on the specified options.
func CreateClient(c ClientOpts) (client.APIClient, error) {
	if c.Host == "" {
		if os.Getenv("DOCKER_API_VERSION") == "" {
			os.Setenv("DOCKER_API_VERSION", DefaultAPIVersion)
		}
		client, err := client.NewEnvClient()
		if err != nil {
			return nil, err
		}
		return client, nil
	}

	apiVersion := c.APIVersion
	if apiVersion == "" {
		apiVersion = DefaultAPIVersion
	}

	if c.TLSOptions.CAFile == "" {
		c.TLSOptions.CAFile = filepath.Join(dockerCertPath, defaultCaFile)
	}
	if c.TLSOptions.CertFile == "" {
		c.TLSOptions.CertFile = filepath.Join(dockerCertPath, defaultCertFile)
	}
	if c.TLSOptions.KeyFile == "" {
		c.TLSOptions.KeyFile = filepath.Join(dockerCertPath, defaultKeyFile)
	}
	if c.TrustKey == "" {
		c.TrustKey = filepath.Join(homedir.Get(), ".docker", defaultTrustKeyFile)
	}
	if c.TLSVerify {
		c.TLS = true
	}
	if c.TLS {
		c.TLSOptions.InsecureSkipVerify = !c.TLSVerify
	}

	var httpClient *http.Client
	if c.TLS {
		config, err := tlsconfig.Client(c.TLSOptions)
		if err != nil {
			return nil, err
		}
		tr := &http.Transport{
			TLSClientConfig: config,
		}
		proto, addr, _, err := client.ParseHost(c.Host)
		if err != nil {
			return nil, err
		}

		sockets.ConfigureTransport(tr, proto, addr)

		httpClient = &http.Client{
			Transport: tr,
		}
	}

	customHeaders := map[string]string{}
	customHeaders["User-Agent"] = fmt.Sprintf("Libcompose-Client/%s (%s)", version.VERSION, runtime.GOOS)

	client, err := client.NewClient(c.Host, apiVersion, httpClient, customHeaders)
	if err != nil {
		return nil, err
	}
	return client, nil
}