client.go 4.1 KB

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