client.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package apiclient
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "crypto/x509"
  6. "encoding/json"
  7. "fmt"
  8. "io/ioutil"
  9. "net/http"
  10. "net/url"
  11. "github.com/crowdsecurity/crowdsec/pkg/models"
  12. "github.com/pkg/errors"
  13. )
  14. var (
  15. InsecureSkipVerify = false
  16. Cert *tls.Certificate
  17. CaCertPool *x509.CertPool
  18. )
  19. type ApiClient struct {
  20. /*The http client used to make requests*/
  21. client *http.Client
  22. /*Reuse a single struct instead of allocating one for each service on the heap.*/
  23. common service
  24. /*config stuff*/
  25. BaseURL *url.URL
  26. URLPrefix string
  27. UserAgent string
  28. /*exposed Services*/
  29. Decisions *DecisionsService
  30. Alerts *AlertsService
  31. Auth *AuthService
  32. Metrics *MetricsService
  33. Signal *SignalService
  34. HeartBeat *HeartBeatService
  35. }
  36. type service struct {
  37. client *ApiClient
  38. }
  39. func NewClient(config *Config) (*ApiClient, error) {
  40. t := &JWTTransport{
  41. MachineID: &config.MachineID,
  42. Password: &config.Password,
  43. Scenarios: config.Scenarios,
  44. URL: config.URL,
  45. UserAgent: config.UserAgent,
  46. VersionPrefix: config.VersionPrefix,
  47. UpdateScenario: config.UpdateScenario,
  48. }
  49. tlsconfig := tls.Config{InsecureSkipVerify: InsecureSkipVerify}
  50. if Cert != nil {
  51. tlsconfig.RootCAs = CaCertPool
  52. tlsconfig.Certificates = []tls.Certificate{*Cert}
  53. }
  54. http.DefaultTransport.(*http.Transport).TLSClientConfig = &tlsconfig
  55. c := &ApiClient{client: t.Client(), BaseURL: config.URL, UserAgent: config.UserAgent, URLPrefix: config.VersionPrefix}
  56. c.common.client = c
  57. c.Decisions = (*DecisionsService)(&c.common)
  58. c.Alerts = (*AlertsService)(&c.common)
  59. c.Auth = (*AuthService)(&c.common)
  60. c.Metrics = (*MetricsService)(&c.common)
  61. c.Signal = (*SignalService)(&c.common)
  62. c.HeartBeat = (*HeartBeatService)(&c.common)
  63. return c, nil
  64. }
  65. func NewDefaultClient(URL *url.URL, prefix string, userAgent string, client *http.Client) (*ApiClient, error) {
  66. if client == nil {
  67. client = &http.Client{}
  68. if ht, ok := http.DefaultTransport.(*http.Transport); ok {
  69. tlsconfig := tls.Config{InsecureSkipVerify: InsecureSkipVerify}
  70. if Cert != nil {
  71. tlsconfig.RootCAs = CaCertPool
  72. tlsconfig.Certificates = []tls.Certificate{*Cert}
  73. }
  74. ht.TLSClientConfig = &tlsconfig
  75. client.Transport = ht
  76. }
  77. }
  78. c := &ApiClient{client: client, BaseURL: URL, UserAgent: userAgent, URLPrefix: prefix}
  79. c.common.client = c
  80. c.Decisions = (*DecisionsService)(&c.common)
  81. c.Alerts = (*AlertsService)(&c.common)
  82. c.Auth = (*AuthService)(&c.common)
  83. c.Metrics = (*MetricsService)(&c.common)
  84. c.Signal = (*SignalService)(&c.common)
  85. c.HeartBeat = (*HeartBeatService)(&c.common)
  86. return c, nil
  87. }
  88. func RegisterClient(config *Config, client *http.Client) (*ApiClient, error) {
  89. if client == nil {
  90. client = &http.Client{}
  91. }
  92. tlsconfig := tls.Config{InsecureSkipVerify: InsecureSkipVerify}
  93. if Cert != nil {
  94. tlsconfig.RootCAs = CaCertPool
  95. tlsconfig.Certificates = []tls.Certificate{*Cert}
  96. }
  97. http.DefaultTransport.(*http.Transport).TLSClientConfig = &tlsconfig
  98. c := &ApiClient{client: client, BaseURL: config.URL, UserAgent: config.UserAgent, URLPrefix: config.VersionPrefix}
  99. c.common.client = c
  100. c.Decisions = (*DecisionsService)(&c.common)
  101. c.Alerts = (*AlertsService)(&c.common)
  102. c.Auth = (*AuthService)(&c.common)
  103. resp, err := c.Auth.RegisterWatcher(context.Background(), models.WatcherRegistrationRequest{MachineID: &config.MachineID, Password: &config.Password})
  104. /*if we have http status, return it*/
  105. if err != nil {
  106. if resp != nil && resp.Response != nil {
  107. return nil, errors.Wrapf(err, "api register (%s) http %s : %s", c.BaseURL, resp.Response.Status, err)
  108. }
  109. return nil, errors.Wrapf(err, "api register (%s) : %s", c.BaseURL, err)
  110. }
  111. return c, nil
  112. }
  113. type Response struct {
  114. Response *http.Response
  115. //add our pagination stuff
  116. //NextPage int
  117. //...
  118. }
  119. type ErrorResponse struct {
  120. models.ErrorResponse
  121. }
  122. func (e *ErrorResponse) Error() string {
  123. err := fmt.Sprintf("API error: %s", *e.Message)
  124. if len(e.Errors) > 0 {
  125. err += fmt.Sprintf(" (%s)", e.Errors)
  126. }
  127. return err
  128. }
  129. func newResponse(r *http.Response) *Response {
  130. response := &Response{Response: r}
  131. return response
  132. }
  133. func CheckResponse(r *http.Response) error {
  134. if c := r.StatusCode; 200 <= c && c <= 299 {
  135. return nil
  136. }
  137. errorResponse := &ErrorResponse{}
  138. data, err := ioutil.ReadAll(r.Body)
  139. if err == nil && data != nil {
  140. err := json.Unmarshal(data, errorResponse)
  141. if err != nil {
  142. return errors.Wrapf(err, "http code %d, invalid body", r.StatusCode)
  143. }
  144. } else {
  145. errorResponse.Message = new(string)
  146. *errorResponse.Message = fmt.Sprintf("http code %d, no error message", r.StatusCode)
  147. }
  148. return errorResponse
  149. }
  150. type ListOpts struct {
  151. //Page int
  152. //PerPage int
  153. }
  154. type DeleteOpts struct {
  155. //??
  156. }
  157. type AddOpts struct {
  158. //??
  159. }