github.com/vchain-us/vcn@v0.9.11-0.20210921212052-a2484d23c0b3/pkg/api/alert.go (about)

     1  /*
     2   * Copyright (c) 2018-2020 vChain, Inc. All Rights Reserved.
     3   * This software is released under GPL3.
     4   * The full license information can be found under:
     5   * https://www.gnu.org/licenses/gpl-3.0.en.html
     6   *
     7   */
     8  
     9  package api
    10  
    11  import (
    12  	"fmt"
    13  
    14  	"github.com/vchain-us/vcn/pkg/meta"
    15  )
    16  
    17  type alert struct {
    18  	ArtifactHash     string   `json:"artifactHash,omitempty"`
    19  	ArtifactMetaHash string   `json:"artifactMetaHash,omitempty"`
    20  	Email            string   `json:"email,omitempty"`
    21  	Enabled          bool     `json:"enabled"`
    22  	Metadata         Metadata `json:"metadata,omitempty"`
    23  	Name             string   `json:"name"`
    24  	UUID             string   `json:"uuid,omitempty"`
    25  }
    26  
    27  // AlertResponse holds alert values returned by the platform.
    28  type AlertResponse struct {
    29  	ArtifactHash     string   `json:"artifactHash,omitempty"`
    30  	ArtifactMetaHash string   `json:"artifactMetaHash,omitempty"`
    31  	Email            string   `json:"email,omitempty"`
    32  	Enabled          bool     `json:"enabled"`
    33  	Metadata         Metadata `json:"metadata,omitempty"`
    34  	Name             string   `json:"name"`
    35  	UnAcknowledged   bool     `json:"unAcknowledgedNotification"`
    36  	UUID             string   `json:"uuid,omitempty"`
    37  }
    38  
    39  // AlertConfig represents a platform alert configuration.
    40  type AlertConfig struct {
    41  	AlertUUID string   `json:"alertUuid" yaml:"alertUUID"`
    42  	Metadata  Metadata `json:"metadata,omitempty" yaml:"metadata"`
    43  }
    44  
    45  // CreateAlert creates a platform alert and returns its UUID.
    46  func (u *User) CreateAlert(name string, email string, a Artifact, v BlockchainVerification, m Metadata) (alertConfig *AlertConfig, err error) {
    47  
    48  	restError := new(Error)
    49  	alertResponse := &alert{}
    50  	r, err := newSling(u.token()).
    51  		Post(meta.APIEndpoint("alert")).
    52  		BodyJSON(alert{
    53  			ArtifactHash:     a.Hash,
    54  			ArtifactMetaHash: v.MetaHash(),
    55  			Email:            email,
    56  			Enabled:          true,
    57  			Metadata:         m,
    58  			Name:             name,
    59  		}).Receive(alertResponse, restError)
    60  
    61  	if err != nil {
    62  		return
    63  	}
    64  	switch r.StatusCode {
    65  	case 200:
    66  		alertConfig = &AlertConfig{
    67  			AlertUUID: alertResponse.UUID,
    68  			Metadata:  m,
    69  		}
    70  	case 400:
    71  		err = fmt.Errorf("%s", restError.Description)
    72  	case 413:
    73  		err = fmt.Errorf("%s is not allowed, only email addresses using the same domain are allowed", email)
    74  	default:
    75  		err = fmt.Errorf("alert API request failed: %s (%d)", restError.Message,
    76  			restError.Status)
    77  	}
    78  	return
    79  }
    80  
    81  // ModifyAlert modifies the settings of an already existing alert.
    82  // func (u *User) ModifyAlert(config *AlertConfig, enabled bool) error {
    83  
    84  // 	if config == nil {
    85  // 		return fmt.Errorf("alert config cannot be nil")
    86  // 	}
    87  
    88  // 	restError := new(Error)
    89  // 	alertResponse := &alert{}
    90  // 	alertRequest := alert{
    91  // 		Enabled:  enabled,
    92  // 		Metadata: config.Metadata,
    93  // 	}
    94  
    95  // 	r, err := newSling(u.token()).
    96  // 		Patch(meta.APIEndpoint("alert")+"?uuid="+config.AlertUUID).
    97  // 		BodyJSON(alertRequest).Receive(alertResponse, restError)
    98  
    99  // 	if err != nil {
   100  // 		return err
   101  // 	}
   102  
   103  // 	switch r.StatusCode {
   104  // 	case 200:
   105  // 		return nil
   106  // 	case 403:
   107  // 		return fmt.Errorf("illegal alert access: %s", restError.Message)
   108  // 	case 404:
   109  // 		return fmt.Errorf(`no such alert found matching "%s"`, config.AlertUUID)
   110  // 	default:
   111  // 		return fmt.Errorf("alert API request failed: %s (%d)", restError.Message,
   112  // 			restError.Status)
   113  // 	}
   114  // }
   115  
   116  // GetAlert returns an AlertResponse for a given alert uuid.
   117  func (u *User) GetAlert(uuid string) (*AlertResponse, error) {
   118  	restError := new(Error)
   119  	response := &AlertResponse{}
   120  	r, err := newSling(u.token()).
   121  		Get(meta.APIEndpoint("alert/"+uuid)).
   122  		Receive(&response, restError)
   123  
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  
   128  	switch r.StatusCode {
   129  	case 200:
   130  		return response, nil
   131  	case 403:
   132  		return nil, fmt.Errorf("illegal alert access: %s", restError.Message)
   133  	case 404:
   134  		return nil, fmt.Errorf(`no such alert found matching "%s"`, uuid)
   135  	default:
   136  		return nil, fmt.Errorf("alert API request failed: %s (%d)", restError.Message,
   137  			restError.Status)
   138  	}
   139  }
   140  
   141  func (u *User) alertMessage(config AlertConfig, what string) (err error) {
   142  	restError := new(Error)
   143  	r, err := newSling(u.token()).
   144  		Post(meta.APIEndpoint("alert/"+what)).
   145  		BodyJSON(config).Receive(nil, restError)
   146  
   147  	if err != nil {
   148  		return
   149  	}
   150  
   151  	switch r.StatusCode {
   152  	case 200:
   153  		return nil
   154  	case 403:
   155  		return fmt.Errorf("illegal alert access: %s", restError.Message)
   156  	case 404:
   157  		return fmt.Errorf(`no such alert found matching "%s"`, config.AlertUUID)
   158  	case 412:
   159  		return fmt.Errorf(`notification already triggered for alert "%s"`, config.AlertUUID)
   160  	default:
   161  		return fmt.Errorf("alert API request failed: %s (%d)", restError.Message,
   162  			restError.Status)
   163  	}
   164  }
   165  
   166  // PingAlert sends a ping for the given alert _config_.
   167  // Once the first ping goes through, the platform starts a server-side watcher and will trigger a notification
   168  // after some amount of time if no further pings for the alert are received.
   169  func (u *User) PingAlert(config AlertConfig) error {
   170  	return u.alertMessage(config, "ping")
   171  }
   172  
   173  // TriggerAlert triggers a notification immediately for the given alert _config_.
   174  func (u *User) TriggerAlert(config AlertConfig) error {
   175  	return u.alertMessage(config, "notify")
   176  }