enhance globalrulegroups (#5134)
Signed-off-by: junot <junotxiang@kubesphere.io> Signed-off-by: junot <junotxiang@kubesphere.io>
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/prometheus/pkg/labels"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
@@ -33,6 +34,8 @@ type Comparator string
|
||||
|
||||
type Severity string
|
||||
|
||||
type MatchType string
|
||||
|
||||
const (
|
||||
ComparatorLT Comparator = "<"
|
||||
ComparatorLE Comparator = "<="
|
||||
@@ -42,6 +45,11 @@ const (
|
||||
SeverityWarning Severity = "warning"
|
||||
SeverityError Severity = "error"
|
||||
SeverityCritical Severity = "critical"
|
||||
|
||||
MatchEqual = "="
|
||||
MatchNotEqual = "!="
|
||||
MatchRegexp = "=~"
|
||||
MatchNotRegexp = "!~"
|
||||
)
|
||||
|
||||
type Rule struct {
|
||||
@@ -71,7 +79,91 @@ type ClusterRule struct {
|
||||
}
|
||||
|
||||
type GlobalRule struct {
|
||||
Rule `json:",inline"`
|
||||
ClusterSelector *MetricLabelSelector `json:"clusterSelector,omitempty"`
|
||||
NamespaceSelector *MetricLabelSelector `json:"namespaceSelector,omitempty"`
|
||||
Rule `json:",inline"`
|
||||
// If ExprBuilder is not nil, the configured Expr will be ignored
|
||||
ExprBuilder *GlobalRuleExprBuilder `json:"exprBuilder,omitempty"`
|
||||
}
|
||||
|
||||
// Only one of its members may be specified.
|
||||
type MetricLabelSelector struct {
|
||||
InValues []string `json:"inValues,omitempty"`
|
||||
Matcher *Matcher `json:"matcher,omitempty"`
|
||||
}
|
||||
|
||||
func (s *MetricLabelSelector) ParseToMatcher(labelName string) *labels.Matcher {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
if len(s.InValues) == 1 {
|
||||
return &labels.Matcher{
|
||||
Type: labels.MatchEqual,
|
||||
Name: labelName,
|
||||
Value: s.InValues[0],
|
||||
}
|
||||
}
|
||||
if len(s.InValues) > 1 {
|
||||
return &labels.Matcher{
|
||||
Type: labels.MatchRegexp,
|
||||
Name: labelName,
|
||||
Value: fmt.Sprintf("(%s)", strings.Join(s.InValues, "|")),
|
||||
}
|
||||
}
|
||||
if s.Matcher != nil {
|
||||
var mtype labels.MatchType
|
||||
switch s.Matcher.Type {
|
||||
case MatchEqual:
|
||||
mtype = labels.MatchEqual
|
||||
case MatchNotEqual:
|
||||
mtype = labels.MatchNotEqual
|
||||
case MatchRegexp:
|
||||
mtype = labels.MatchRegexp
|
||||
case MatchNotRegexp:
|
||||
mtype = labels.MatchNotRegexp
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
return &labels.Matcher{
|
||||
Type: mtype,
|
||||
Name: labelName,
|
||||
Value: s.Matcher.Value,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MetricLabelSelector) Validate() error {
|
||||
if s.Matcher != nil {
|
||||
return s.Matcher.Validate()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Matcher struct {
|
||||
Type MatchType `json:"type"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Matcher) Validate() error {
|
||||
var mtype labels.MatchType
|
||||
switch m.Type {
|
||||
case MatchEqual:
|
||||
mtype = labels.MatchEqual
|
||||
case MatchNotEqual:
|
||||
mtype = labels.MatchNotEqual
|
||||
case MatchRegexp:
|
||||
mtype = labels.MatchRegexp
|
||||
case MatchNotRegexp:
|
||||
mtype = labels.MatchNotRegexp
|
||||
default:
|
||||
return fmt.Errorf("unsupported match type [%s]", m.Type)
|
||||
}
|
||||
_, err := labels.NewMatcher(mtype, "name", m.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid matcher: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NamespaceRuleExprBuilder struct {
|
||||
@@ -82,6 +174,12 @@ type ClusterRuleExprBuilder struct {
|
||||
Node *NodeExprBuilder `json:"node,omitempty"`
|
||||
}
|
||||
|
||||
// Only one of its members may be specified.
|
||||
type GlobalRuleExprBuilder struct {
|
||||
Workload *WorkloadExprBuilder `json:"workload,omitempty"`
|
||||
Node *NodeExprBuilder `json:"node,omitempty"`
|
||||
}
|
||||
|
||||
type WorkloadKind string
|
||||
|
||||
const (
|
||||
|
||||
@@ -212,6 +212,20 @@ func (r *GlobalRuleGroup) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||
var _ webhook.Defaulter = &GlobalRuleGroup{}
|
||||
|
||||
func (r *GlobalRuleGroup) Default() {
|
||||
log := globalrulegrouplog.WithValues("name", r.Name)
|
||||
log.Info("default")
|
||||
|
||||
for i := range r.Spec.Rules {
|
||||
rule := r.Spec.Rules[i]
|
||||
if rule.ExprBuilder != nil {
|
||||
if rule.ExprBuilder.Node != nil {
|
||||
rule.Expr = intstr.FromString(rule.ExprBuilder.Node.Build())
|
||||
} else if rule.ExprBuilder.Workload != nil {
|
||||
rule.Expr = intstr.FromString(rule.ExprBuilder.Workload.Build())
|
||||
}
|
||||
}
|
||||
r.Spec.Rules[i] = rule
|
||||
}
|
||||
}
|
||||
|
||||
var _ webhook.Validator = &GlobalRuleGroup{}
|
||||
@@ -231,6 +245,16 @@ func (r *GlobalRuleGroup) Validate() error {
|
||||
|
||||
var rules []Rule
|
||||
for _, r := range r.Spec.Rules {
|
||||
if r.ClusterSelector != nil {
|
||||
if err := r.ClusterSelector.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if r.NamespaceSelector != nil {
|
||||
if err := r.NamespaceSelector.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
rules = append(rules, r.Rule)
|
||||
}
|
||||
var err = validateRules(log, r.Name, r.Spec.Interval, rules)
|
||||
|
||||
@@ -171,7 +171,22 @@ func (in *ClusterRuleGroupStatus) DeepCopy() *ClusterRuleGroupStatus {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GlobalRule) DeepCopyInto(out *GlobalRule) {
|
||||
*out = *in
|
||||
if in.ClusterSelector != nil {
|
||||
in, out := &in.ClusterSelector, &out.ClusterSelector
|
||||
*out = new(MetricLabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.NamespaceSelector != nil {
|
||||
in, out := &in.NamespaceSelector, &out.NamespaceSelector
|
||||
*out = new(MetricLabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Rule.DeepCopyInto(&out.Rule)
|
||||
if in.ExprBuilder != nil {
|
||||
in, out := &in.ExprBuilder, &out.ExprBuilder
|
||||
*out = new(GlobalRuleExprBuilder)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -185,6 +200,32 @@ func (in *GlobalRule) DeepCopy() *GlobalRule {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GlobalRuleExprBuilder) DeepCopyInto(out *GlobalRuleExprBuilder) {
|
||||
*out = *in
|
||||
if in.Workload != nil {
|
||||
in, out := &in.Workload, &out.Workload
|
||||
*out = new(WorkloadExprBuilder)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Node != nil {
|
||||
in, out := &in.Node, &out.Node
|
||||
*out = new(NodeExprBuilder)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRuleExprBuilder.
|
||||
func (in *GlobalRuleExprBuilder) DeepCopy() *GlobalRuleExprBuilder {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(GlobalRuleExprBuilder)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GlobalRuleGroup) DeepCopyInto(out *GlobalRuleGroup) {
|
||||
*out = *in
|
||||
@@ -285,6 +326,48 @@ func (in *GlobalRuleGroupStatus) DeepCopy() *GlobalRuleGroupStatus {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Matcher) DeepCopyInto(out *Matcher) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Matcher.
|
||||
func (in *Matcher) DeepCopy() *Matcher {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Matcher)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MetricLabelSelector) DeepCopyInto(out *MetricLabelSelector) {
|
||||
*out = *in
|
||||
if in.InValues != nil {
|
||||
in, out := &in.InValues, &out.InValues
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Matcher != nil {
|
||||
in, out := &in.Matcher, &out.Matcher
|
||||
*out = new(Matcher)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricLabelSelector.
|
||||
func (in *MetricLabelSelector) DeepCopy() *MetricLabelSelector {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MetricLabelSelector)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NamespaceRule) DeepCopyInto(out *NamespaceRule) {
|
||||
*out = *in
|
||||
|
||||
Reference in New Issue
Block a user