package host import ( "fmt" "reflect" "time" "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" ) type postVNCPayload struct { // RequestID is the ID of the VNC request // // example: 11asd123a RequestID string `json:"requestId" binding:"required"` // VNC status of the node // // example: ACCEPTED Status VNCStatus `json:"status" binding:"required,oneof=REQUESTED ACCEPTED SUSPENDED REJECTED DROPPED CONNECTED"` // Number of active connections on the VNC request. Only expected alongside a CONNECTED status. // // example: 2 Connections int `json:"connections" binding:"gte=0,is_zero_xor_is_connected"` // Timestamp of VNC state // // example: "2006-01-02T15:04:05Z07:00" TimeStamp time.Time `json:"timestamp,omitempty" time_format:"2006-01-02T15:04:05Z07:00"` } type putVNCPayload struct { // RequestID is the ID of the VNC request // // example: 11asd123a RequestID string `json:"requestId" binding:"required"` // VNC status of the node // in: body // enum: ["REQUESTED", "ACCEPTED", "SUSPENDED", "REJECTED", "CONNECTED"] // // example: ACCEPTED Status VNCStatus `json:"status" binding:"required,oneof=REQUESTED ACCEPTED SUSPENDED REJECTED CONNECTED"` // Number of active connections on the VNC request. Only expected alongside a CONNECTED status. // // example: 2 Connections int `json:"connections" binding:"gte=0,is_zero_xor_is_connected"` // Timestamp of VNC state // // example: "2006-01-02T15:04:05Z07:00" TimeStamp time.Time `json:"timestamp" binding:"required" time_format:"2006-01-02T15:04:05Z07:00"` } type putVNCPayloads []putVNCPayload // Validates the incoming payload for duplicate request IDs. Returns a [binding.SliceValidationError] // to indicate this error is a validation error and should be treated as such in HandleBindingError. func (payload putVNCPayloads) validateRequestIDs() binding.SliceValidationError { var err binding.SliceValidationError requestIDs := make(map[string]struct{}) for _, p := range payload { if _, ok := requestIDs[p.RequestID]; ok { err = append(err, fmt.Errorf("Key: 'putVNCPayload.RequestID' Error: Duplicate request id %q", p.RequestID)) } requestIDs[p.RequestID] = struct{}{} } if len(err) != 0 { return err } return nil } // Custom validator methods func getIsConnected(fl validator.FieldLevel) (isConnected bool, ok bool) { status := fl.Parent().FieldByName("Status") if !status.CanConvert(reflect.TypeOf(Connected)) { return false, false } return status.Equal(reflect.ValueOf(Connected)), true } func validateFieldIsZeroXORStatusIsConnected(fl validator.FieldLevel) bool { isConnected, ok := getIsConnected(fl) if !ok { return false } intField := fl.Field().Int() // If status is not CONNECTED, there should not be any connections if !isConnected { return intField == 0 } // And if status is CONNECTED, there must be at least one connection return intField != 0 }