...

Source file src/github.com/prometheus/common/model/silence.go

Documentation: github.com/prometheus/common/model

     1  // Copyright 2015 The Prometheus Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package model
    15  
    16  import (
    17  	"encoding/json"
    18  	"fmt"
    19  	"regexp"
    20  	"time"
    21  )
    22  
    23  // Matcher describes a matches the value of a given label.
    24  type Matcher struct {
    25  	Name    LabelName `json:"name"`
    26  	Value   string    `json:"value"`
    27  	IsRegex bool      `json:"isRegex"`
    28  }
    29  
    30  func (m *Matcher) UnmarshalJSON(b []byte) error {
    31  	type plain Matcher
    32  	if err := json.Unmarshal(b, (*plain)(m)); err != nil {
    33  		return err
    34  	}
    35  
    36  	if len(m.Name) == 0 {
    37  		return fmt.Errorf("label name in matcher must not be empty")
    38  	}
    39  	if m.IsRegex {
    40  		if _, err := regexp.Compile(m.Value); err != nil {
    41  			return err
    42  		}
    43  	}
    44  	return nil
    45  }
    46  
    47  // Validate returns true iff all fields of the matcher have valid values.
    48  func (m *Matcher) Validate() error {
    49  	if !m.Name.IsValid() {
    50  		return fmt.Errorf("invalid name %q", m.Name)
    51  	}
    52  	if m.IsRegex {
    53  		if _, err := regexp.Compile(m.Value); err != nil {
    54  			return fmt.Errorf("invalid regular expression %q", m.Value)
    55  		}
    56  	} else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 {
    57  		return fmt.Errorf("invalid value %q", m.Value)
    58  	}
    59  	return nil
    60  }
    61  
    62  // Silence defines the representation of a silence definition in the Prometheus
    63  // eco-system.
    64  type Silence struct {
    65  	ID uint64 `json:"id,omitempty"`
    66  
    67  	Matchers []*Matcher `json:"matchers"`
    68  
    69  	StartsAt time.Time `json:"startsAt"`
    70  	EndsAt   time.Time `json:"endsAt"`
    71  
    72  	CreatedAt time.Time `json:"createdAt,omitempty"`
    73  	CreatedBy string    `json:"createdBy"`
    74  	Comment   string    `json:"comment,omitempty"`
    75  }
    76  
    77  // Validate returns true iff all fields of the silence have valid values.
    78  func (s *Silence) Validate() error {
    79  	if len(s.Matchers) == 0 {
    80  		return fmt.Errorf("at least one matcher required")
    81  	}
    82  	for _, m := range s.Matchers {
    83  		if err := m.Validate(); err != nil {
    84  			return fmt.Errorf("invalid matcher: %w", err)
    85  		}
    86  	}
    87  	if s.StartsAt.IsZero() {
    88  		return fmt.Errorf("start time missing")
    89  	}
    90  	if s.EndsAt.IsZero() {
    91  		return fmt.Errorf("end time missing")
    92  	}
    93  	if s.EndsAt.Before(s.StartsAt) {
    94  		return fmt.Errorf("start time must be before end time")
    95  	}
    96  	if s.CreatedBy == "" {
    97  		return fmt.Errorf("creator information missing")
    98  	}
    99  	if s.Comment == "" {
   100  		return fmt.Errorf("comment missing")
   101  	}
   102  	if s.CreatedAt.IsZero() {
   103  		return fmt.Errorf("creation timestamp missing")
   104  	}
   105  	return nil
   106  }
   107  

View as plain text