datasource.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package tsdb
  15. import (
  16. "crypto/tls"
  17. "net"
  18. "net/http"
  19. "sync"
  20. "time"
  21. "yunion.io/x/onecloud/pkg/monitor/options"
  22. )
  23. type DataSource struct {
  24. Id string
  25. Name string
  26. Type string
  27. Url string
  28. User string
  29. Password string
  30. Database string
  31. BasicAuth bool
  32. BasicAuthUser string
  33. BasicAuthPassword string
  34. TimeInterval string
  35. Updated time.Time
  36. }
  37. type proxyTransportCache struct {
  38. cache map[string]cachedTransport
  39. sync.Mutex
  40. }
  41. // dataSourceTransport implements http.RoundTripper (https://golang.org/pkg/net/http/#RoundTripper)
  42. type dataSourceTransport struct {
  43. headers map[string]string
  44. transport *http.Transport
  45. }
  46. // RoundTrip executes a single HTTP transaction, returning a Response for the provided Request.
  47. func (d *dataSourceTransport) RoundTrip(req *http.Request) (*http.Response, error) {
  48. for key, value := range d.headers {
  49. req.Header.Set(key, value)
  50. }
  51. return d.transport.RoundTrip(req)
  52. }
  53. type cachedTransport struct {
  54. updated time.Time
  55. *dataSourceTransport
  56. }
  57. var ptc = proxyTransportCache{
  58. cache: make(map[string]cachedTransport),
  59. }
  60. func (ds *DataSource) GetHttpClient() (*http.Client, error) {
  61. transport, err := ds.GetHttpTransport()
  62. if err != nil {
  63. return nil, err
  64. }
  65. return &http.Client{
  66. //Timeout: 30 * time.Second,
  67. Transport: transport,
  68. }, nil
  69. }
  70. // getCustomHeaders returns a map with all the to be set headers
  71. // The map key represents the HeaderName and the value represetns this header's value
  72. func (ds *DataSource) getCustomHeaders() map[string]string {
  73. headers := make(map[string]string)
  74. // TODO: datasource support config customize headers
  75. return headers
  76. }
  77. func (ds *DataSource) GetHttpTransport() (*dataSourceTransport, error) {
  78. ptc.Lock()
  79. defer ptc.Unlock()
  80. if t, present := ptc.cache[ds.Id]; present && ds.Updated.Equal(t.updated) {
  81. return t.dataSourceTransport, nil
  82. }
  83. tlsConfig, err := ds.GetTLSConfig()
  84. if err != nil {
  85. return nil, err
  86. }
  87. tlsConfig.Renegotiation = tls.RenegotiateFreelyAsClient
  88. // Create transport which adds all
  89. // TODO: use httputils.HttpTransport instead -- qj
  90. customHeaders := ds.getCustomHeaders()
  91. transport := &http.Transport{
  92. TLSClientConfig: tlsConfig,
  93. Proxy: http.ProxyFromEnvironment,
  94. DialContext: (&net.Dialer{
  95. Timeout: time.Duration(options.Options.DataProxyTimeout) * time.Second,
  96. KeepAlive: 30 * time.Second,
  97. }).DialContext,
  98. TLSHandshakeTimeout: 10 * time.Second,
  99. ExpectContinueTimeout: 1 * time.Second,
  100. MaxIdleConns: 100,
  101. IdleConnTimeout: 90 * time.Second,
  102. }
  103. dsTransport := &dataSourceTransport{
  104. headers: customHeaders,
  105. transport: transport,
  106. }
  107. ptc.cache[ds.Id] = cachedTransport{
  108. dataSourceTransport: dsTransport,
  109. updated: ds.Updated,
  110. }
  111. return dsTransport, nil
  112. }
  113. func (ds *DataSource) GetTLSConfig() (*tls.Config, error) {
  114. tlsConfig := &tls.Config{
  115. InsecureSkipVerify: true,
  116. }
  117. return tlsConfig, nil
  118. }
  119. /*
  120. func (ds *DataSource) DecryptedBasicAuthPassword() string {
  121. return ds.decryptedValue("basicAuthPassword", ds.BasicAuthPassword)
  122. }
  123. func (ds *DataSource) DecryptedPassword() string {
  124. return ds.decryptedValue("password", ds.Password)
  125. }
  126. func (ds *DataSource) decryptedValue(field string, fallback string) string {
  127. if value, ok := ds.DecryptedValue(field); ok {
  128. return value
  129. }
  130. return fallback
  131. }
  132. // DecryptedValue returns cached decrypted value from cached data
  133. func (ds *DataSource) DecryptedValue(key string) (string, bool) {
  134. value, exists := ds.DecryptedValues()[key]
  135. return value, exists
  136. }
  137. var dsDescryptionCache =
  138. func (ds *DataSource) DecryptedValues() map[string]string {
  139. }*/