github.com/helmwave/helmwave@v0.36.4-0.20240509190856-b35563eba4c6/pkg/release/monitors.go (about)

     1  package release
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/helmwave/helmwave/pkg/monitor"
     7  	"github.com/invopop/jsonschema"
     8  )
     9  
    10  // MonitorFailedAction is a type for enumerating actions for handling failed monitors.
    11  type MonitorFailedAction string
    12  
    13  const (
    14  	MonitorActionNone      MonitorFailedAction = ""
    15  	MonitorActionRollback  MonitorFailedAction = "rollback"
    16  	MonitorActionUninstall MonitorFailedAction = "uninstall"
    17  )
    18  
    19  func (MonitorFailedAction) JSONSchema() *jsonschema.Schema {
    20  	return &jsonschema.Schema{
    21  		Type:    "string",
    22  		Default: MonitorActionNone,
    23  		Enum: []any{
    24  			MonitorActionNone,
    25  			MonitorActionRollback,
    26  			MonitorActionUninstall,
    27  		},
    28  	}
    29  }
    30  
    31  type MonitorReference struct {
    32  	Name   string              `yaml:"name" json:"name" jsonschema:"required"`
    33  	Action MonitorFailedAction `yaml:"action" json:"action" jsonschema:"title=Action if monitor fails"`
    34  }
    35  
    36  func (rel *config) NotifyMonitorsFailed(ctx context.Context, mons ...monitor.Config) {
    37  	action := MonitorActionNone
    38  
    39  	allMons := rel.Monitors()
    40  	for _, mon := range mons {
    41  		for i := range allMons {
    42  			monRef := allMons[i]
    43  			if mon.Name() != monRef.Name {
    44  				continue
    45  			}
    46  
    47  			if action != monRef.Action {
    48  				if action != MonitorActionNone {
    49  					rel.Logger().Warn("multiple actions to perform found, will use latest one")
    50  				}
    51  				action = monRef.Action
    52  			}
    53  		}
    54  	}
    55  
    56  	if action == MonitorActionNone {
    57  		rel.Logger().Info("no actions will be performed for failed monitors")
    58  	} else {
    59  		rel.Logger().WithField("action", action).Info("chose action to perform for failed monitors")
    60  		rel.performMonitorAction(ctx, action)
    61  	}
    62  }
    63  
    64  func (rel *config) performMonitorAction(ctx context.Context, action MonitorFailedAction) {
    65  	switch action {
    66  	case MonitorActionRollback:
    67  		err := rel.Rollback(ctx, 0)
    68  		if err != nil {
    69  			rel.Logger().WithError(err).Error("caught error while handling failed monitors")
    70  		}
    71  	case MonitorActionUninstall:
    72  		_, err := rel.Uninstall(ctx)
    73  		if err != nil {
    74  			rel.Logger().WithError(err).Error("caught error while handling failed monitors")
    75  		}
    76  	default:
    77  		rel.Logger().WithField("action", action).Error("unknown action to perform, skipping")
    78  	}
    79  }