Files
cloudpods/pkg/monitor/tsdb/datasource.go
2020-03-27 01:20:30 +08:00

172 lines
4.2 KiB
Go

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tsdb
import (
"crypto/tls"
"net"
"net/http"
"sync"
"time"
"yunion.io/x/onecloud/pkg/monitor/options"
)
type DataSource struct {
Id string
Name string
Type string
Url string
User string
Password string
Database string
BasicAuth bool
BasicAuthUser string
BasicAuthPassword string
TimeInterval string
Updated time.Time
}
type proxyTransportCache struct {
cache map[string]cachedTransport
sync.Mutex
}
// dataSourceTransport implements http.RoundTripper (https://golang.org/pkg/net/http/#RoundTripper)
type dataSourceTransport struct {
headers map[string]string
transport *http.Transport
}
// RoundTrip executes a single HTTP transaction, returning a Response for the provided Request.
func (d *dataSourceTransport) RoundTrip(req *http.Request) (*http.Response, error) {
for key, value := range d.headers {
req.Header.Set(key, value)
}
return d.transport.RoundTrip(req)
}
type cachedTransport struct {
updated time.Time
*dataSourceTransport
}
var ptc = proxyTransportCache{
cache: make(map[string]cachedTransport),
}
func (ds *DataSource) GetHttpClient() (*http.Client, error) {
transport, err := ds.GetHttpTransport()
if err != nil {
return nil, err
}
return &http.Client{
Timeout: 30 * time.Second,
Transport: transport,
}, nil
}
// getCustomHeaders returns a map with all the to be set headers
// The map key represents the HeaderName and the value represetns this header's value
func (ds *DataSource) getCustomHeaders() map[string]string {
headers := make(map[string]string)
// TODO: datasource support config customize headers
return headers
}
func (ds *DataSource) GetHttpTransport() (*dataSourceTransport, error) {
ptc.Lock()
defer ptc.Unlock()
if t, present := ptc.cache[ds.Id]; present && ds.Updated.Equal(t.updated) {
return t.dataSourceTransport, nil
}
tlsConfig, err := ds.GetTLSConfig()
if err != nil {
return nil, err
}
tlsConfig.Renegotiation = tls.RenegotiateFreelyAsClient
// Create transport which adds all
// TODO: use httputils.HttpTransport instead -- qj
customHeaders := ds.getCustomHeaders()
transport := &http.Transport{
TLSClientConfig: tlsConfig,
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: time.Duration(options.Options.DataProxyTimeout) * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
}
dsTransport := &dataSourceTransport{
headers: customHeaders,
transport: transport,
}
ptc.cache[ds.Id] = cachedTransport{
dataSourceTransport: dsTransport,
updated: ds.Updated,
}
return dsTransport, nil
}
func (ds *DataSource) GetTLSConfig() (*tls.Config, error) {
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
}
return tlsConfig, nil
}
/*
func (ds *DataSource) DecryptedBasicAuthPassword() string {
return ds.decryptedValue("basicAuthPassword", ds.BasicAuthPassword)
}
func (ds *DataSource) DecryptedPassword() string {
return ds.decryptedValue("password", ds.Password)
}
func (ds *DataSource) decryptedValue(field string, fallback string) string {
if value, ok := ds.DecryptedValue(field); ok {
return value
}
return fallback
}
// DecryptedValue returns cached decrypted value from cached data
func (ds *DataSource) DecryptedValue(key string) (string, bool) {
value, exists := ds.DecryptedValues()[key]
return value, exists
}
var dsDescryptionCache =
func (ds *DataSource) DecryptedValues() map[string]string {
}*/