...

Source file src/edge-infra.dev/pkg/sds/interlock/topic/host/vnc_payloads.go

Documentation: edge-infra.dev/pkg/sds/interlock/topic/host

     1  package host
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"time"
     7  
     8  	"github.com/gin-gonic/gin/binding"
     9  	"github.com/go-playground/validator/v10"
    10  )
    11  
    12  type postVNCPayload struct {
    13  	// RequestID is the ID of the VNC request
    14  	//
    15  	// example: 11asd123a
    16  	RequestID string `json:"requestId" binding:"required"`
    17  	// VNC status of the node
    18  	//
    19  	// example: ACCEPTED
    20  	Status VNCStatus `json:"status" binding:"required,oneof=REQUESTED ACCEPTED SUSPENDED REJECTED DROPPED CONNECTED"`
    21  	// Number of active connections on the VNC request. Only expected alongside a CONNECTED status.
    22  	//
    23  	// example: 2
    24  	Connections int `json:"connections" binding:"gte=0,is_zero_xor_is_connected"`
    25  	// Timestamp of VNC state
    26  	//
    27  	// example: "2006-01-02T15:04:05Z07:00"
    28  	TimeStamp time.Time `json:"timestamp,omitempty" time_format:"2006-01-02T15:04:05Z07:00"`
    29  }
    30  
    31  type putVNCPayload struct {
    32  	// RequestID is the ID of the VNC request
    33  	//
    34  	// example: 11asd123a
    35  	RequestID string `json:"requestId" binding:"required"`
    36  	// VNC status of the node
    37  	// in: body
    38  	// enum: ["REQUESTED", "ACCEPTED", "SUSPENDED", "REJECTED", "CONNECTED"]
    39  	//
    40  	// example: ACCEPTED
    41  	Status VNCStatus `json:"status" binding:"required,oneof=REQUESTED ACCEPTED SUSPENDED REJECTED CONNECTED"`
    42  	// Number of active connections on the VNC request. Only expected alongside a CONNECTED status.
    43  	//
    44  	// example: 2
    45  	Connections int `json:"connections" binding:"gte=0,is_zero_xor_is_connected"`
    46  	// Timestamp of VNC state
    47  	//
    48  	// example: "2006-01-02T15:04:05Z07:00"
    49  	TimeStamp time.Time `json:"timestamp" binding:"required" time_format:"2006-01-02T15:04:05Z07:00"`
    50  }
    51  
    52  type putVNCPayloads []putVNCPayload
    53  
    54  // Validates the incoming payload for duplicate request IDs. Returns a [binding.SliceValidationError]
    55  // to indicate this error is a validation error and should be treated as such in HandleBindingError.
    56  func (payload putVNCPayloads) validateRequestIDs() binding.SliceValidationError {
    57  	var err binding.SliceValidationError
    58  	requestIDs := make(map[string]struct{})
    59  	for _, p := range payload {
    60  		if _, ok := requestIDs[p.RequestID]; ok {
    61  			err = append(err, fmt.Errorf("Key: 'putVNCPayload.RequestID' Error: Duplicate request id %q", p.RequestID))
    62  		}
    63  		requestIDs[p.RequestID] = struct{}{}
    64  	}
    65  	if len(err) != 0 {
    66  		return err
    67  	}
    68  	return nil
    69  }
    70  
    71  // Custom validator methods
    72  
    73  func getIsConnected(fl validator.FieldLevel) (isConnected bool, ok bool) {
    74  	status := fl.Parent().FieldByName("Status")
    75  	if !status.CanConvert(reflect.TypeOf(Connected)) {
    76  		return false, false
    77  	}
    78  	return status.Equal(reflect.ValueOf(Connected)), true
    79  }
    80  
    81  func validateFieldIsZeroXORStatusIsConnected(fl validator.FieldLevel) bool {
    82  	isConnected, ok := getIsConnected(fl)
    83  	if !ok {
    84  		return false
    85  	}
    86  	intField := fl.Field().Int()
    87  	// If status is not CONNECTED, there should not be any connections
    88  	if !isConnected {
    89  		return intField == 0
    90  	}
    91  	// And if status is CONNECTED, there must be at least one connection
    92  	return intField != 0
    93  }
    94  

View as plain text