2018-05-14 16:26:38 +00:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
2019-12-08 04:10:22 +00:00
|
|
|
"crypto/tls"
|
|
|
|
"net"
|
2018-05-14 16:26:38 +00:00
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2019-12-08 04:10:22 +00:00
|
|
|
"time"
|
2019-04-11 02:28:21 +00:00
|
|
|
|
2020-04-20 16:55:23 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/dbrp"
|
2020-04-03 17:39:20 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/kit/tracing"
|
|
|
|
"github.com/influxdata/influxdb/v2/pkg/httpc"
|
2018-05-14 16:26:38 +00:00
|
|
|
)
|
|
|
|
|
2019-12-08 04:10:22 +00:00
|
|
|
// NewHTTPClient creates a new httpc.Client type. This call sets all
|
|
|
|
// the options that are important to the http pkg on the httpc client.
|
|
|
|
// The default status fn and so forth will all be set for the caller.
|
2020-02-26 10:37:57 +00:00
|
|
|
// In addition, some options can be specified. Those will be added to the defaults.
|
|
|
|
func NewHTTPClient(addr, token string, insecureSkipVerify bool, opts ...httpc.ClientOptFn) (*httpc.Client, error) {
|
2019-12-08 04:10:22 +00:00
|
|
|
u, err := url.Parse(addr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-02-26 10:37:57 +00:00
|
|
|
defaultOpts := []httpc.ClientOptFn{
|
2019-12-08 04:10:22 +00:00
|
|
|
httpc.WithAddr(addr),
|
|
|
|
httpc.WithContentType("application/json"),
|
|
|
|
httpc.WithHTTPClient(NewClient(u.Scheme, insecureSkipVerify)),
|
|
|
|
httpc.WithInsecureSkipVerify(insecureSkipVerify),
|
|
|
|
httpc.WithStatusFn(CheckError),
|
|
|
|
}
|
|
|
|
if token != "" {
|
2020-02-26 10:37:57 +00:00
|
|
|
defaultOpts = append(defaultOpts, httpc.WithAuthToken(token))
|
2019-12-08 04:10:22 +00:00
|
|
|
}
|
2020-02-26 10:37:57 +00:00
|
|
|
opts = append(defaultOpts, opts...)
|
2019-12-08 04:10:22 +00:00
|
|
|
return httpc.New(opts...)
|
|
|
|
}
|
|
|
|
|
2018-09-17 02:39:46 +00:00
|
|
|
// Service connects to an InfluxDB via HTTP.
|
|
|
|
type Service struct {
|
|
|
|
Addr string
|
|
|
|
Token string
|
|
|
|
InsecureSkipVerify bool
|
|
|
|
|
2020-01-21 22:22:45 +00:00
|
|
|
*BackupService
|
2020-02-24 19:41:21 +00:00
|
|
|
*TaskService
|
2020-03-05 00:32:33 +00:00
|
|
|
*NotificationRuleService
|
2019-02-14 20:32:54 +00:00
|
|
|
*VariableService
|
2019-12-07 18:54:03 +00:00
|
|
|
*WriteService
|
2020-02-26 16:34:10 +00:00
|
|
|
*CheckService
|
2020-02-26 10:37:57 +00:00
|
|
|
*NotificationEndpointService
|
|
|
|
*TelegrafService
|
|
|
|
*LabelService
|
2020-04-20 16:55:23 +00:00
|
|
|
DBRPMappingServiceV2 *dbrp.Client
|
2018-09-17 02:39:46 +00:00
|
|
|
}
|
|
|
|
|
2020-02-26 10:37:57 +00:00
|
|
|
// NewService returns a service that is an HTTP client to a remote.
|
|
|
|
// Address and token are needed for those services that do not use httpc.Client,
|
|
|
|
// but use those for configuring.
|
|
|
|
// Usually one would do:
|
|
|
|
//
|
|
|
|
// ```
|
|
|
|
// c := NewHTTPClient(addr, token, insecureSkipVerify)
|
|
|
|
// s := NewService(c, addr token)
|
|
|
|
// ```
|
|
|
|
//
|
|
|
|
// So one should provide the same `addr` and `token` to both calls to ensure consistency
|
|
|
|
// in the behavior of the returned service.
|
|
|
|
func NewService(httpClient *httpc.Client, addr, token string) (*Service, error) {
|
2018-09-17 02:39:46 +00:00
|
|
|
return &Service{
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
Addr: addr,
|
|
|
|
Token: token,
|
2020-01-21 22:22:45 +00:00
|
|
|
BackupService: &BackupService{
|
|
|
|
Addr: addr,
|
|
|
|
Token: token,
|
|
|
|
},
|
2020-03-05 00:32:33 +00:00
|
|
|
TaskService: &TaskService{Client: httpClient},
|
|
|
|
NotificationRuleService: &NotificationRuleService{Client: httpClient},
|
|
|
|
VariableService: &VariableService{Client: httpClient},
|
2019-12-07 18:54:03 +00:00
|
|
|
WriteService: &WriteService{
|
2018-09-17 02:39:46 +00:00
|
|
|
Addr: addr,
|
|
|
|
Token: token,
|
|
|
|
},
|
2020-02-26 10:37:57 +00:00
|
|
|
CheckService: &CheckService{Client: httpClient},
|
|
|
|
NotificationEndpointService: &NotificationEndpointService{Client: httpClient},
|
|
|
|
TelegrafService: NewTelegrafService(httpClient),
|
|
|
|
LabelService: &LabelService{Client: httpClient},
|
2020-04-20 16:55:23 +00:00
|
|
|
DBRPMappingServiceV2: dbrp.NewClient(httpClient),
|
2019-12-07 18:54:03 +00:00
|
|
|
}, nil
|
2018-09-17 02:39:46 +00:00
|
|
|
}
|
|
|
|
|
2019-06-26 05:48:15 +00:00
|
|
|
// NewURL concats addr and path.
|
2019-05-09 17:41:14 +00:00
|
|
|
func NewURL(addr, path string) (*url.URL, error) {
|
2018-05-14 16:26:38 +00:00
|
|
|
u, err := url.Parse(addr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
u.Path = path
|
|
|
|
return u, nil
|
|
|
|
}
|
|
|
|
|
2019-06-26 05:48:15 +00:00
|
|
|
// NewClient returns an http.Client that pools connections and injects a span.
|
2019-12-08 04:10:22 +00:00
|
|
|
func NewClient(scheme string, insecure bool) *http.Client {
|
|
|
|
return httpClient(scheme, insecure)
|
2018-05-14 16:26:38 +00:00
|
|
|
}
|
2018-08-15 20:14:51 +00:00
|
|
|
|
2019-12-08 04:10:22 +00:00
|
|
|
// SpanTransport injects the http.RoundTripper.RoundTrip() request
|
|
|
|
// with a span.
|
|
|
|
type SpanTransport struct {
|
|
|
|
base http.RoundTripper
|
2018-08-15 20:14:51 +00:00
|
|
|
}
|
|
|
|
|
2019-12-08 04:10:22 +00:00
|
|
|
// RoundTrip implements the http.RoundTripper, intercepting the base
|
|
|
|
// round trippers call and injecting a span.
|
|
|
|
func (s *SpanTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
2019-04-11 02:28:21 +00:00
|
|
|
span, _ := tracing.StartSpanFromContext(r.Context())
|
2019-06-26 05:48:15 +00:00
|
|
|
defer span.Finish()
|
2019-04-11 02:28:21 +00:00
|
|
|
tracing.InjectToHTTPRequest(span, r)
|
2019-12-08 04:10:22 +00:00
|
|
|
return s.base.RoundTrip(r)
|
|
|
|
}
|
|
|
|
|
2020-06-05 16:52:45 +00:00
|
|
|
// DefaultTransport wraps http.DefaultTransport in SpanTransport to inject
|
|
|
|
// tracing headers into all outgoing requests.
|
|
|
|
var DefaultTransport http.RoundTripper = &SpanTransport{base: http.DefaultTransport}
|
|
|
|
|
|
|
|
// DefaultTransportInsecure is identical to DefaultTransport, with
|
|
|
|
// the exception that tls.Config is configured with InsecureSkipVerify
|
|
|
|
// set to true.
|
|
|
|
var DefaultTransportInsecure http.RoundTripper = &SpanTransport{
|
|
|
|
base: &http.Transport{
|
2019-12-08 04:10:22 +00:00
|
|
|
Proxy: http.ProxyFromEnvironment,
|
|
|
|
DialContext: (&net.Dialer{
|
|
|
|
Timeout: 30 * time.Second,
|
|
|
|
KeepAlive: 30 * time.Second,
|
|
|
|
DualStack: true,
|
|
|
|
}).DialContext,
|
2020-06-05 16:52:45 +00:00
|
|
|
ForceAttemptHTTP2: true,
|
2019-12-08 04:10:22 +00:00
|
|
|
MaxIdleConns: 100,
|
|
|
|
IdleConnTimeout: 90 * time.Second,
|
|
|
|
TLSHandshakeTimeout: 10 * time.Second,
|
|
|
|
ExpectContinueTimeout: 1 * time.Second,
|
2020-06-05 16:52:45 +00:00
|
|
|
TLSClientConfig: &tls.Config{
|
|
|
|
InsecureSkipVerify: true,
|
2019-12-08 04:10:22 +00:00
|
|
|
},
|
2020-06-05 16:52:45 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func httpClient(scheme string, insecure bool) *http.Client {
|
|
|
|
if scheme == "https" && insecure {
|
|
|
|
return &http.Client{Transport: DefaultTransportInsecure}
|
2019-12-07 18:54:03 +00:00
|
|
|
}
|
2020-06-05 16:52:45 +00:00
|
|
|
return &http.Client{Transport: DefaultTransport}
|
2019-12-07 00:45:49 +00:00
|
|
|
}
|