|
|
@ -18,7 +18,7 @@ import (
|
|
|
|
"github.com/segmentio/encoding/json"
|
|
|
|
"github.com/segmentio/encoding/json"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
var errUnsupportedEnvironmentType = errors.New("Environment not supported")
|
|
|
|
var errUnsupportedEnvironmentType = errors.New("environment not supported")
|
|
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
const (
|
|
|
|
defaultDockerRequestTimeout = 60 * time.Second
|
|
|
|
defaultDockerRequestTimeout = 60 * time.Second
|
|
|
@ -48,9 +48,16 @@ func (factory *ClientFactory) CreateClient(endpoint *portainer.Endpoint, nodeNam
|
|
|
|
case portainer.AzureEnvironment:
|
|
|
|
case portainer.AzureEnvironment:
|
|
|
|
return nil, errUnsupportedEnvironmentType
|
|
|
|
return nil, errUnsupportedEnvironmentType
|
|
|
|
case portainer.AgentOnDockerEnvironment:
|
|
|
|
case portainer.AgentOnDockerEnvironment:
|
|
|
|
return createAgentClient(endpoint, factory.signatureService, nodeName, timeout)
|
|
|
|
return createAgentClient(endpoint, endpoint.URL, factory.signatureService, nodeName, timeout)
|
|
|
|
case portainer.EdgeAgentOnDockerEnvironment:
|
|
|
|
case portainer.EdgeAgentOnDockerEnvironment:
|
|
|
|
return createEdgeClient(endpoint, factory.signatureService, factory.reverseTunnelService, nodeName, timeout)
|
|
|
|
tunnel, err := factory.reverseTunnelService.GetActiveTunnel(endpoint)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endpointURL := fmt.Sprintf("http://127.0.0.1:%d", tunnel.Port)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return createAgentClient(endpoint, endpointURL, factory.signatureService, nodeName, timeout)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if strings.HasPrefix(endpoint.URL, "unix://") || strings.HasPrefix(endpoint.URL, "npipe://") {
|
|
|
|
if strings.HasPrefix(endpoint.URL, "unix://") || strings.HasPrefix(endpoint.URL, "npipe://") {
|
|
|
@ -93,7 +100,7 @@ func createTCPClient(endpoint *portainer.Endpoint, timeout *time.Duration) (*cli
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func createEdgeClient(endpoint *portainer.Endpoint, signatureService portainer.DigitalSignatureService, reverseTunnelService portainer.ReverseTunnelService, nodeName string, timeout *time.Duration) (*client.Client, error) {
|
|
|
|
func createAgentClient(endpoint *portainer.Endpoint, endpointURL string, signatureService portainer.DigitalSignatureService, nodeName string, timeout *time.Duration) (*client.Client, error) {
|
|
|
|
httpCli, err := httpClient(endpoint, timeout)
|
|
|
|
httpCli, err := httpClient(endpoint, timeout)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
return nil, err
|
|
|
@ -113,47 +120,18 @@ func createEdgeClient(endpoint *portainer.Endpoint, signatureService portainer.D
|
|
|
|
headers[portainer.PortainerAgentTargetHeader] = nodeName
|
|
|
|
headers[portainer.PortainerAgentTargetHeader] = nodeName
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tunnel, err := reverseTunnelService.GetActiveTunnel(endpoint)
|
|
|
|
opts := []client.Opt{
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endpointURL := fmt.Sprintf("http://127.0.0.1:%d", tunnel.Port)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return client.NewClientWithOpts(
|
|
|
|
|
|
|
|
client.WithHost(endpointURL),
|
|
|
|
client.WithHost(endpointURL),
|
|
|
|
client.WithAPIVersionNegotiation(),
|
|
|
|
client.WithAPIVersionNegotiation(),
|
|
|
|
client.WithHTTPClient(httpCli),
|
|
|
|
client.WithHTTPClient(httpCli),
|
|
|
|
client.WithHTTPHeaders(headers),
|
|
|
|
client.WithHTTPHeaders(headers),
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func createAgentClient(endpoint *portainer.Endpoint, signatureService portainer.DigitalSignatureService, nodeName string, timeout *time.Duration) (*client.Client, error) {
|
|
|
|
if nnTransport, ok := httpCli.Transport.(*NodeNameTransport); ok && nnTransport.TLSClientConfig != nil {
|
|
|
|
httpCli, err := httpClient(endpoint, timeout)
|
|
|
|
opts = append(opts, client.WithScheme("https"))
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
signature, err := signatureService.CreateSignature(portainer.PortainerAgentSignatureMessage)
|
|
|
|
return client.NewClientWithOpts(opts...)
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
headers := map[string]string{
|
|
|
|
|
|
|
|
portainer.PortainerAgentPublicKeyHeader: signatureService.EncodedPublicKey(),
|
|
|
|
|
|
|
|
portainer.PortainerAgentSignatureHeader: signature,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if nodeName != "" {
|
|
|
|
|
|
|
|
headers[portainer.PortainerAgentTargetHeader] = nodeName
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return client.NewClientWithOpts(
|
|
|
|
|
|
|
|
client.WithHost(endpoint.URL),
|
|
|
|
|
|
|
|
client.WithAPIVersionNegotiation(),
|
|
|
|
|
|
|
|
client.WithHTTPClient(httpCli),
|
|
|
|
|
|
|
|
client.WithHTTPHeaders(headers),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type NodeNameTransport struct {
|
|
|
|
type NodeNameTransport struct {
|
|
|
|