153 lines
3.6 KiB
Go
153 lines
3.6 KiB
Go
package endpoint
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/influxdata/influxdb/v2"
|
|
)
|
|
|
|
var _ influxdb.NotificationEndpoint = &HTTP{}
|
|
|
|
const (
|
|
httpTokenSuffix = "-token"
|
|
httpUsernameSuffix = "-username"
|
|
httpPasswordSuffix = "-password"
|
|
)
|
|
|
|
// HTTP is the notification endpoint config of http.
|
|
type HTTP struct {
|
|
Base
|
|
// Path is the API path of HTTP
|
|
URL string `json:"url"`
|
|
// Token is the bearer token for authorization
|
|
Headers map[string]string `json:"headers,omitempty"`
|
|
Token influxdb.SecretField `json:"token,omitempty"`
|
|
Username influxdb.SecretField `json:"username,omitempty"`
|
|
Password influxdb.SecretField `json:"password,omitempty"`
|
|
AuthMethod string `json:"authMethod"`
|
|
Method string `json:"method"`
|
|
ContentTemplate string `json:"contentTemplate"`
|
|
}
|
|
|
|
// BackfillSecretKeys fill back fill the secret field key during the unmarshalling
|
|
// if value of that secret field is not nil.
|
|
func (s *HTTP) BackfillSecretKeys() {
|
|
if s.Token.Key == "" && s.Token.Value != nil {
|
|
s.Token.Key = s.idStr() + httpTokenSuffix
|
|
}
|
|
if s.Username.Key == "" && s.Username.Value != nil {
|
|
s.Username.Key = s.idStr() + httpUsernameSuffix
|
|
}
|
|
if s.Password.Key == "" && s.Password.Value != nil {
|
|
s.Password.Key = s.idStr() + httpPasswordSuffix
|
|
}
|
|
}
|
|
|
|
// SecretFields return available secret fields.
|
|
func (s HTTP) SecretFields() []influxdb.SecretField {
|
|
arr := make([]influxdb.SecretField, 0)
|
|
if s.Token.Key != "" {
|
|
arr = append(arr, s.Token)
|
|
}
|
|
if s.Username.Key != "" {
|
|
arr = append(arr, s.Username)
|
|
}
|
|
if s.Password.Key != "" {
|
|
arr = append(arr, s.Password)
|
|
}
|
|
return arr
|
|
}
|
|
|
|
var goodHTTPAuthMethod = map[string]bool{
|
|
"none": true,
|
|
"basic": true,
|
|
"bearer": true,
|
|
}
|
|
|
|
var goodHTTPMethod = map[string]bool{
|
|
http.MethodGet: true,
|
|
http.MethodPost: true,
|
|
http.MethodPut: true,
|
|
}
|
|
|
|
// Valid returns error if some configuration is invalid
|
|
func (s HTTP) Valid() error {
|
|
if err := s.Base.valid(); err != nil {
|
|
return err
|
|
}
|
|
if s.URL == "" {
|
|
return &influxdb.Error{
|
|
Code: influxdb.EInvalid,
|
|
Msg: "http endpoint URL is empty",
|
|
}
|
|
}
|
|
if _, err := url.Parse(s.URL); err != nil {
|
|
return &influxdb.Error{
|
|
Code: influxdb.EInvalid,
|
|
Msg: fmt.Sprintf("http endpoint URL is invalid: %s", err.Error()),
|
|
}
|
|
}
|
|
if !goodHTTPMethod[s.Method] {
|
|
return &influxdb.Error{
|
|
Code: influxdb.EInvalid,
|
|
Msg: "invalid http http method",
|
|
}
|
|
}
|
|
if !goodHTTPAuthMethod[s.AuthMethod] {
|
|
return &influxdb.Error{
|
|
Code: influxdb.EInvalid,
|
|
Msg: "invalid http auth method",
|
|
}
|
|
}
|
|
if s.AuthMethod == "basic" && (s.Username.Key == "" || s.Password.Key == "") {
|
|
return &influxdb.Error{
|
|
Code: influxdb.EInvalid,
|
|
Msg: "invalid http username/password for basic auth",
|
|
}
|
|
}
|
|
if s.AuthMethod == "bearer" && s.Token.Key == "" {
|
|
return &influxdb.Error{
|
|
Code: influxdb.EInvalid,
|
|
Msg: "invalid http token for bearer auth",
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON implement json.Marshaler interface.
|
|
func (s HTTP) MarshalJSON() ([]byte, error) {
|
|
type httpAlias HTTP
|
|
return json.Marshal(
|
|
struct {
|
|
httpAlias
|
|
Type string `json:"type"`
|
|
}{
|
|
httpAlias: httpAlias(s),
|
|
Type: s.Type(),
|
|
})
|
|
}
|
|
|
|
// Type returns the type.
|
|
func (s HTTP) Type() string {
|
|
return HTTPType
|
|
}
|
|
|
|
// ParseResponse will parse the http response from http.
|
|
func (s HTTP) ParseResponse(resp *http.Response) error {
|
|
if resp.StatusCode != http.StatusOK {
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return &influxdb.Error{
|
|
Msg: string(body),
|
|
}
|
|
}
|
|
return nil
|
|
}
|