1
0
mirror of https://github.com/containous/traefik.git synced 2024-12-24 21:34:39 +03:00
traefik/pkg/types/constraints.go
Ludovic Fernandez 8d7eccad5d New static configuration loading system.
Co-authored-by: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
2019-06-17 11:48:05 +02:00

89 lines
2.4 KiB
Go

package types
import (
"encoding"
"errors"
"fmt"
"strings"
"github.com/ryanuber/go-glob"
)
// Constraint holds a parsed constraint expression.
// FIXME replace by a string.
type Constraint struct {
Key string `description:"The provider label that will be matched against. In practice, it is always 'tag'." export:"true"`
// MustMatch is true if operator is "==" or false if operator is "!="
MustMatch bool `description:"Whether the matching operator is equals or not equals." export:"true"`
Value string `description:"The value that will be matched against." export:"true"` // TODO: support regex
}
// NewConstraint receives a string and return a *Constraint, after checking syntax and parsing the constraint expression.
func NewConstraint(exp string) (*Constraint, error) {
sep := ""
constraint := &Constraint{}
switch {
case strings.Contains(exp, "=="):
sep = "=="
constraint.MustMatch = true
case strings.Contains(exp, "!="):
sep = "!="
constraint.MustMatch = false
default:
return nil, errors.New("constraint expression missing valid operator: '==' or '!='")
}
kv := strings.SplitN(exp, sep, 2)
if len(kv) == 2 {
// At the moment, it only supports tags
if kv[0] != "tag" {
return nil, errors.New("constraint must be tag-based. Syntax: tag==us-*")
}
constraint.Key = kv[0]
constraint.Value = kv[1]
return constraint, nil
}
return nil, fmt.Errorf("incorrect constraint expression: %s", exp)
}
func (c *Constraint) String() string {
if c.MustMatch {
return c.Key + "==" + c.Value
}
return c.Key + "!=" + c.Value
}
var _ encoding.TextUnmarshaler = (*Constraint)(nil)
// UnmarshalText defines how unmarshal in TOML parsing
func (c *Constraint) UnmarshalText(text []byte) error {
constraint, err := NewConstraint(string(text))
if err != nil {
return err
}
c.Key = constraint.Key
c.MustMatch = constraint.MustMatch
c.Value = constraint.Value
return nil
}
var _ encoding.TextMarshaler = (*Constraint)(nil)
// MarshalText encodes the receiver into UTF-8-encoded text and returns the result.
func (c *Constraint) MarshalText() (text []byte, err error) {
return []byte(c.String()), nil
}
// MatchConstraintWithAtLeastOneTag tests a constraint for one single service.
func (c *Constraint) MatchConstraintWithAtLeastOneTag(tags []string) bool {
for _, tag := range tags {
if glob.Glob(c.Value, tag) {
return true
}
}
return false
}