2019-09-23 16:00:03 +00:00
|
|
|
package influxdb
|
|
|
|
|
|
|
|
import (
|
2019-10-14 21:33:50 +00:00
|
|
|
"encoding/json"
|
2019-09-23 16:00:03 +00:00
|
|
|
"regexp"
|
|
|
|
"strings"
|
2021-03-30 18:10:02 +00:00
|
|
|
|
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform/errors"
|
2019-09-23 16:00:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Operator is an Enum value of operators.
|
2019-10-14 21:33:50 +00:00
|
|
|
type Operator int
|
2019-09-23 16:00:03 +00:00
|
|
|
|
|
|
|
// Valid returns invalid error if the operator is invalid.
|
|
|
|
func (op Operator) Valid() error {
|
2019-10-14 21:33:50 +00:00
|
|
|
if op < Equal || op > NotRegexEqual {
|
2021-03-30 18:10:02 +00:00
|
|
|
return &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-10-14 21:33:50 +00:00
|
|
|
Msg: "Operator is invalid",
|
2019-09-23 16:00:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// operators
|
|
|
|
const (
|
2019-10-14 21:33:50 +00:00
|
|
|
Equal Operator = iota
|
|
|
|
NotEqual
|
|
|
|
RegexEqual
|
|
|
|
NotRegexEqual
|
2019-09-23 16:00:03 +00:00
|
|
|
)
|
|
|
|
|
2019-10-14 21:33:50 +00:00
|
|
|
var opStr = []string{
|
|
|
|
"equal",
|
|
|
|
"notequal",
|
|
|
|
"equalregex",
|
|
|
|
"notequalregex",
|
|
|
|
}
|
|
|
|
|
|
|
|
var opStrMap = map[string]Operator{
|
|
|
|
"equal": Equal,
|
|
|
|
"notequal": NotEqual,
|
|
|
|
"equalregex": RegexEqual,
|
|
|
|
"notequalregex": NotRegexEqual,
|
|
|
|
}
|
|
|
|
|
2019-12-20 17:10:10 +00:00
|
|
|
// ToOperator converts a string into its equivalent Operator.
|
|
|
|
func ToOperator(s string) (Operator, bool) {
|
|
|
|
s = strings.ToLower(s)
|
|
|
|
if op, ok := opStrMap[s]; ok {
|
|
|
|
return op, true
|
|
|
|
}
|
|
|
|
return -1, false
|
|
|
|
}
|
|
|
|
|
2019-10-14 21:33:50 +00:00
|
|
|
// String returns the string value of the operator.
|
|
|
|
func (op Operator) String() string {
|
|
|
|
if err := op.Valid(); err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return opStr[op]
|
|
|
|
}
|
|
|
|
|
|
|
|
// MarshalJSON implements json.Marshal interface.
|
|
|
|
func (op Operator) MarshalJSON() ([]byte, error) {
|
|
|
|
return json.Marshal(op.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalJSON implements json.Unmarshaler interface.
|
|
|
|
func (op *Operator) UnmarshalJSON(b []byte) error {
|
|
|
|
var s string
|
|
|
|
if err := json.Unmarshal(b, &s); err != nil {
|
2021-03-30 18:10:02 +00:00
|
|
|
return &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-10-14 21:33:50 +00:00
|
|
|
Err: err,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var ok bool
|
|
|
|
if *op, ok = opStrMap[s]; !ok {
|
2021-03-30 18:10:02 +00:00
|
|
|
return &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-10-14 21:33:50 +00:00
|
|
|
Msg: "unrecognized operator",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
2019-09-23 16:00:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Tag is a tag key-value pair.
|
|
|
|
type Tag struct {
|
|
|
|
Key string `json:"key"`
|
|
|
|
Value string `json:"value"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewTag generates a tag pair from a string in the format key:value.
|
|
|
|
func NewTag(s string) (Tag, error) {
|
|
|
|
var tagPair Tag
|
|
|
|
|
|
|
|
matched, err := regexp.MatchString(`^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+$`, s)
|
|
|
|
if !matched || err != nil {
|
2021-03-30 18:10:02 +00:00
|
|
|
return tagPair, &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-09-23 16:00:03 +00:00
|
|
|
Msg: `tag must be in form key:value`,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 20:24:27 +00:00
|
|
|
tagPair.Key, tagPair.Value, _ = strings.Cut(s, ":")
|
2019-09-23 16:00:03 +00:00
|
|
|
return tagPair, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Valid returns an error if the tagpair is missing fields
|
|
|
|
func (t Tag) Valid() error {
|
|
|
|
if t.Key == "" || t.Value == "" {
|
2021-03-30 18:10:02 +00:00
|
|
|
return &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-09-23 16:00:03 +00:00
|
|
|
Msg: "tag must contain a key and a value",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// QueryParam converts a Tag to a string query parameter
|
2019-10-14 21:33:50 +00:00
|
|
|
func (t *Tag) QueryParam() string {
|
|
|
|
return strings.Join([]string{t.Key, t.Value}, ":")
|
2019-09-23 16:00:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TagRule is the struct of tag rule.
|
|
|
|
type TagRule struct {
|
|
|
|
Tag
|
2019-10-14 21:33:50 +00:00
|
|
|
Operator Operator `json:"operator"`
|
2019-09-23 16:00:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Valid returns error for invalid operators.
|
|
|
|
func (tr TagRule) Valid() error {
|
|
|
|
if err := tr.Tag.Valid(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return tr.Operator.Valid()
|
|
|
|
}
|