github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/aagent/watchers/watcherdef.go (about)

     1  // Copyright (c) 2019-2022, R.I. Pienaar and the Choria Project contributors
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package watchers
     6  
     7  import (
     8  	"fmt"
     9  	"time"
    10  
    11  	"github.com/choria-io/go-choria/internal/util"
    12  )
    13  
    14  // WatcherDef is the core definition of a watcher, watcher type specific
    15  // properties get stored in Properties and parsed by each watcher type
    16  type WatcherDef struct {
    17  	Name              string         `json:"name" yaml:"name"`
    18  	Type              string         `json:"type" yaml:"type"`
    19  	StateMatch        []string       `json:"state_match" yaml:"state_match"`
    20  	FailTransition    string         `json:"fail_transition" yaml:"fail_transition"`
    21  	SuccessTransition string         `json:"success_transition" yaml:"success_transition"`
    22  	Interval          string         `json:"interval" yaml:"interval"`
    23  	AnnounceInterval  string         `json:"announce_interval" yaml:"announce_interval"`
    24  	Properties        map[string]any `json:"properties" yaml:"properties"`
    25  	AnnounceDuration  time.Duration  `json:"-" yaml:"-"`
    26  }
    27  
    28  // ParseAnnounceInterval parses the announce interval and ensures its not too small
    29  func (w *WatcherDef) ParseAnnounceInterval() (err error) {
    30  	if w.AnnounceInterval != "" {
    31  		w.AnnounceDuration, err = util.ParseDuration(w.AnnounceInterval)
    32  		if err != nil {
    33  			return fmt.Errorf("unknown announce interval for watcher %s: %s", w.Name, err)
    34  		}
    35  
    36  		if w.AnnounceDuration < time.Minute {
    37  			return fmt.Errorf("announce interval %v is too small for watcher %s", w.AnnounceDuration, w.Name)
    38  		}
    39  	}
    40  
    41  	return nil
    42  }
    43  
    44  // ValidateStates makes sure that all the states mentioned are valid
    45  func (w *WatcherDef) ValidateStates(valid []string) (err error) {
    46  	hasf := func(state string) bool {
    47  		for _, s := range valid {
    48  			if s == state {
    49  				return true
    50  			}
    51  		}
    52  
    53  		return false
    54  	}
    55  
    56  	for _, s := range w.StateMatch {
    57  		if !hasf(s) {
    58  			return fmt.Errorf("invalid state %s in state match for watcher %s", s, w.Name)
    59  		}
    60  	}
    61  
    62  	return nil
    63  }
    64  
    65  // ValidateTransitions checks that all stated transitions are valid
    66  func (w *WatcherDef) ValidateTransitions(valid []string) (err error) {
    67  	hasf := func(transition string) bool {
    68  		for _, t := range valid {
    69  			if t == transition {
    70  				return true
    71  			}
    72  		}
    73  
    74  		return false
    75  	}
    76  
    77  	if w.FailTransition != "" && !hasf(w.FailTransition) {
    78  		return fmt.Errorf("invalid fail_transition %s specified in watcher %s", w.FailTransition, w.Name)
    79  	}
    80  
    81  	if w.SuccessTransition != "" && !hasf(w.SuccessTransition) {
    82  		return fmt.Errorf("invalid success_transition %s specified in watcher %s", w.SuccessTransition, w.Name)
    83  	}
    84  
    85  	return nil
    86  }