This commit is contained in:
asteam
2024-10-01 11:15:36 +03:00
commit a25a3c2e5c
81 changed files with 5143 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
package constants
const (
API = "/api"
APIv0 = "/0"
APIv1 = "/v1.0.0"
)

View File

@@ -0,0 +1,41 @@
package multierror
func Join(errs ...error) error {
n := 0
for _, err := range errs {
if err != nil {
n++
}
}
if n == 0 {
return nil
}
e := &joinError{
errs: make([]error, 0, n),
}
for _, err := range errs {
if err != nil {
e.errs = append(e.errs, err)
}
}
return e
}
type joinError struct {
errs []error
}
func (e *joinError) Error() string {
var b []byte
for i, err := range e.errs {
if i > 0 {
b = append(b, '\n')
}
b = append(b, err.Error()...)
}
return string(b)
}
func (e *joinError) Unwrap() []error {
return e.errs
}

View File

@@ -0,0 +1,247 @@
package validators
import (
"net/url"
"reflect"
"github.com/go-playground/validator/v10"
)
// virtTypeValidator validates the virtualization type
func virtTypeValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, virtTypeValues)
}
// vmStatusValidator validates the VM status
func vmStatusValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, vmStatusValues)
}
// cpuUnitsValidator validates the CPU units (2-262144)
func cpuUnitsValidator(fl validator.FieldLevel) bool {
cpuUnits := fl.Field().Int()
return IsInRange(cpuUnits, cpuUnitsRange)
}
// cpuLimitValidator validates the CPU limit (0-100)
func cpuLimitValidator(fl validator.FieldLevel) bool {
cpuLimit := fl.Field().Int()
return IsInRange(cpuLimit, cpuLimitRange)
}
// ioPriorityValidator validates the IO priority (0-7)
func ioPriorityValidator(fl validator.FieldLevel) bool {
ioPriority := fl.Field().Int()
return IsInRange(ioPriority, ioPriorityRange)
}
// videoRamValidator validates the video RAM limit (1-1024)
func videoRamValidator(fl validator.FieldLevel) bool {
videoRam := fl.Field().Int()
return IsInRange(videoRam, videoRamRange)
}
// memGuaranteeSizeValidator validates the memory guarantee size (-1, 100)
func memGuaranteeSizeValidator(fl validator.FieldLevel) bool {
memGuarantee := fl.Field().Int()
return IsInRange(memGuarantee, memGuaranteeSizeRange)
}
// haStatusValidator validates the HA status
func haStatusValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, haStatusValues)
}
// visibilityValidator validates the visibility
func visibilityValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, visibilityValues)
}
// metricsPeriodValidator validates the metrics
func metricsPeriodValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, metricPeriodValues)
}
// networkTypeValidator validates the network type
func networkTypeValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, networkTypeValues)
}
// imageTypeValidator validates the image type
func imageTypeValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, imageTypeValues)
}
// imageStatusValidator validates the image status
func imageStatusValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, imageStatusValues)
}
// isBoolTypeValidator validates that field value == bool
func isBoolTypeValidator(fe validator.FieldLevel) bool {
return fe.Field().CanConvert(reflect.TypeOf(true))
}
// extStorageStatusValidator validates the external storage status
func extStorageStatusValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, extStorageStatusValues)
}
// extStorageTypeValidator validates the external storage type
func extStorageTypeValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, extStorageTypeValues)
}
// nodeMaintenanceStatusValidator validates the node maintenance status
func nodeMaintenanceStatusValidator(fl validator.FieldLevel) bool {
fieldSlice, ok := fl.Field().Interface().([]string)
if !ok {
return false
}
for _, value := range fieldSlice {
if !IsInSlice(value, nodeMaintenanceStatusValues) {
return false
}
}
return true
}
// nodeAgentStatusValidator validates the node agent status
func nodeAgentStatusValidator(fl validator.FieldLevel) bool {
fieldSlice, ok := fl.Field().Interface().([]string)
if !ok {
return false
}
for _, value := range fieldSlice {
if !IsInSlice(value, nodeAgentStatusValues) {
return false
}
}
return true
}
// haMultiStatusValidator validates the HA status
func haMultiStatusValidator(fl validator.FieldLevel) bool {
fieldSlice, ok := fl.Field().Interface().([]string)
if !ok {
return false
}
for _, value := range fieldSlice {
if !IsInSlice(value, haStatusValues) {
return false
}
}
return true
}
// nodeStatusInHaClusterValidator validates the metrics
func nodeStatusInHaClusterValidator(fl validator.FieldLevel) bool {
fieldSlice, ok := fl.Field().Interface().([]string)
if !ok {
return false
}
for _, value := range fieldSlice {
if !IsInSlice(value, nodeStatusInHaClusterValues) {
return false
}
}
return true
}
// affinityRuleValidator validates the affinity rule value
func affinityRuleValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, affinityRuleValues)
}
// guestOSValidator validates the guest os value
func guestOSValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, guestOSValues)
}
// guestOSVersionValidator validates the guest os version value
func guestOSVersionValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, guestOSVersionValues)
}
// autoStartValidator validates the virtual machine startup options value
func autoStartValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, autoStartValues)
}
// autoStopValidator validates the virtual machine shutdown mode value
func autoStopValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, autoStopValues)
}
// vncModeValidator validates the vnc mode value
func vncModeValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, vncModeValues)
}
// chipsetValidator validates the chipset value
func chipsetValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, chipsetValues)
}
// clockOffsetValidator validates the VM clock offset value
func clockOffsetValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, clockOffsetValues)
}
// templateStatusValidator validates the template status value
func templateStatusValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
return IsInSlice(fieldValue, templateStatusValues)
}
func urlValidartor(fl validator.FieldLevel) bool {
fieldValues := fl.Field().String()
_, err := url.ParseRequestURI(fieldValues)
return err == nil
}

View File

@@ -0,0 +1,47 @@
package validators
import (
"errors"
"github.com/go-playground/validator/v10"
"repository.basistech.ru/BASIS/dynamix-standart-go-sdk/internal/multierror"
)
func ValidateRequest(req interface{}) error {
validate := getVControlValidator()
return validate.Struct(req)
}
func ValidateConfig(cfg interface{}) error {
validate := getVControlValidator()
return validate.Struct(cfg)
}
func ValidationError(fe validator.FieldError) error {
return errors.New(errorMessage(fe))
}
func ValidationErrors(fes []validator.FieldError) error {
errs := make([]error, 0, len(fes))
for _, fe := range fes {
errs = append(errs, ValidationError(fe))
}
return multierror.Join(errs...)
}
func GetErrors(err error) validator.ValidationErrors {
return err.(validator.ValidationErrors)
}
func IsInSlice(str string, target []string) bool {
for _, v := range target {
if v == str {
return true
}
}
return false
}
func IsInRange(num int64, target []int64) bool {
return num >= target[0] && num <= target[1]
}

View File

@@ -0,0 +1,85 @@
package validators
import (
"fmt"
"strings"
"github.com/go-playground/validator/v10"
)
func errorMessage(fe validator.FieldError) string {
prefix := "validation-error:"
switch fe.Tag() {
case "required":
return fmt.Sprintf("%s %s is required", prefix, fe.Field())
case "virt_type":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(virtTypeValues))
case "vm_status":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(vmStatusValues))
case "cpu_units":
return fmt.Sprintf("%s %s must be between %s", prefix, fe.Field(), joinRange(cpuUnitsRange))
case "cpu_limit":
return fmt.Sprintf("%s %s must be between %s", prefix, fe.Field(), joinRange(cpuLimitRange))
case "video_ram":
return fmt.Sprintf("%s %s must be between %s", prefix, fe.Field(), joinRange(videoRamRange))
case "io_priority":
return fmt.Sprintf("%s %s must be between %s", prefix, fe.Field(), joinRange(ioPriorityRange))
case "mem_guarantee_size":
return fmt.Sprintf("%s %s must be between %s", prefix, fe.Field(), joinRange(memGuaranteeSizeRange))
case "ha_status":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(haStatusValues))
case "visibility":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(visibilityValues))
case "metrics_period":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(metricPeriodValues))
case "network_type":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(networkTypeValues))
case "image_type":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(imageTypeValues))
case "image_status":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(imageStatusValues))
case "extstorage_status":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(extStorageStatusValues))
case "extstorage_type":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(extStorageTypeValues))
case "maintenance_status":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(nodeMaintenanceStatusValues))
case "agent_update_status":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(nodeAgentStatusValues))
case "node_status_in_ha_cluster":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(nodeStatusInHaClusterValues))
case "affinity":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(affinityRuleValues))
case "guest_os":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(guestOSValues))
case "guest_os_version":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(guestOSVersionValues))
case "auto_start":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(autoStartValues))
case "auto_stop":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(autoStopValues))
case "vnc_mode":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(vncModeValues))
case "chipset":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(chipsetValues))
case "clock_offset":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(clockOffsetValues))
case "template_status":
return fmt.Sprintf("%s %s must be one of the following: %s", prefix, fe.Field(), joinValues(templateStatusValues))
case "is_bool":
return fmt.Sprintf("%s %s must be bool type", prefix, fe.Field())
case "url":
return fmt.Sprintf("%s %s: unexpected URL format", prefix, fe.Field())
}
return fe.Error()
}
func joinValues(values []string) string {
return strings.Join(values, ", ")
}
func joinRange(lim []int64) string {
return fmt.Sprintf("%d and %d", lim[0], lim[1])
}

View File

@@ -0,0 +1,210 @@
package validators
import (
"sync"
"github.com/go-playground/validator/v10"
)
var (
once sync.Once
VControlValidator = validator.New()
)
// getVControlValidator returns singleton instance of VControlValidator.
func getVControlValidator() *validator.Validate {
once.Do(func() {
err := registerAllValidators(VControlValidator)
if err != nil {
panic(err)
}
})
return VControlValidator
}
// registerAllValidators registers all custom validators in VControlValidator.
func registerAllValidators(validate *validator.Validate) error {
// Register virt_type validator
err := validate.RegisterValidation("virt_type", virtTypeValidator)
if err != nil {
return err
}
// Register vm status validator
err = validate.RegisterValidation("vm_status", vmStatusValidator)
if err != nil {
return err
}
// Register cpu_units validator
err = validate.RegisterValidation("cpu_units", cpuUnitsValidator)
if err != nil {
return err
}
// Register cpu_limit validator
err = validate.RegisterValidation("cpu_limit", cpuLimitValidator)
if err != nil {
return err
}
// Register mem_guarantee_size validator
err = validate.RegisterValidation("mem_guarantee_size", memGuaranteeSizeValidator)
if err != nil {
return err
}
// Register video_ram validator
err = validate.RegisterValidation("video_ram", videoRamValidator)
if err != nil {
return err
}
// Register mem_guarantee_size validator
err = validate.RegisterValidation("metrics_period", metricsPeriodValidator)
if err != nil {
return err
}
// Register ha_status validator
err = validate.RegisterValidation("ha_status", haStatusValidator)
if err != nil {
return err
}
// Register visibility validator
err = validate.RegisterValidation("visibility", visibilityValidator)
if err != nil {
return err
}
// Register visibility validator
err = validate.RegisterValidation("image_type", imageTypeValidator)
if err != nil {
return err
}
// Register visibility validator
err = validate.RegisterValidation("image_status", imageStatusValidator)
if err != nil {
return err
}
// Register bool validator
err = validate.RegisterValidation("is_bool", isBoolTypeValidator)
if err != nil {
return err
}
// Register network_type validator
err = validate.RegisterValidation("network_type", networkTypeValidator)
if err != nil {
return err
}
// Register external storage status validator
err = validate.RegisterValidation("extstorage_status", extStorageStatusValidator)
if err != nil {
return err
}
// Register external storage type validator
err = validate.RegisterValidation("extstorage_type", extStorageTypeValidator)
if err != nil {
return err
}
// Register node maintenance status validator
err = validate.RegisterValidation("maintenance_status", nodeMaintenanceStatusValidator)
if err != nil {
return err
}
// Register node maintenance status validator
err = validate.RegisterValidation("agent_update_status", nodeAgentStatusValidator)
if err != nil {
return err
}
// Register multi choose ha status validator
err = validate.RegisterValidation("ha_multi_status", haMultiStatusValidator)
if err != nil {
return err
}
// Register node status on ha cluster validator
err = validate.RegisterValidation("node_status_in_ha_cluster", nodeStatusInHaClusterValidator)
if err != nil {
return err
}
// Register affinity rule validator
err = validate.RegisterValidation("affinity", affinityRuleValidator)
if err != nil {
return err
}
// Register guest os validator
err = validate.RegisterValidation("guest_os", guestOSValidator)
if err != nil {
return err
}
// Register guest os version validator
err = validate.RegisterValidation("guest_os_version", guestOSVersionValidator)
if err != nil {
return err
}
// Register io priority validator
err = validate.RegisterValidation("io_priority", ioPriorityValidator)
if err != nil {
return err
}
// Register auto start validator
err = validate.RegisterValidation("auto_start", autoStartValidator)
if err != nil {
return err
}
// Register auto stop validator
err = validate.RegisterValidation("auto_stop", autoStopValidator)
if err != nil {
return err
}
// Register vnc mode validator
err = validate.RegisterValidation("vnc_mode", vncModeValidator)
if err != nil {
return err
}
// Register chipset validator
err = validate.RegisterValidation("chipset", chipsetValidator)
if err != nil {
return err
}
// Register clock offset validator
err = validate.RegisterValidation("clock_offset", clockOffsetValidator)
if err != nil {
return err
}
// Register template status validator
err = validate.RegisterValidation("template_status", templateStatusValidator)
if err != nil {
return err
}
// Register url validator
err = validate.RegisterValidation("url", urlValidartor)
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,35 @@
package validators
var (
metricPeriodValues = []string{"latest", "hour", "day", "week"}
imageTypeValues = []string{"OPTICAL", "HDD"}
imageStatusValues = []string{"CREATING", "UPLOADING", "READY", "DELETING", "FAILED_TO_CREATE"}
visibilityValues = []string{"visible", "deleted", "all"}
networkTypeValues = []string{"HOST_ONLY", "CLUSTER_NETWORK", "BRIDGED_ETHERNET"}
virtTypeValues = []string{"VM", "CT"}
vmStatusValues = []string{
"RUNNING", "PAUSED", "STOPPED", "SUSPENDED",
"ERROR", "DELETED", "CREATING", "FAILED_TO_CREATE",
"NODE_OFFLINE",
}
haStatusValues = []string{"ACTIVE", "INACTIVE", "ERROR", "UNKNOWN", "NO LICENSE"}
extStorageStatusValues = []string{"READY", "UNMOUNTED", "UNAVAILABLE", "PARTIALLY_AVAILABLE", "UNKNOWN"}
extStorageTypeValues = []string{"NFSv3", "iSCSI", "blockdev"}
nodeMaintenanceStatusValues = []string{"PREPARING", "INTERRUPTED", "ON_MAINTENANCE"}
nodeAgentStatusValues = []string{"UPDATED", "UPDATE_IN_PROGRESS", "MISMATCH_VERSION", "UPDATE_ERROR"}
nodeStatusInHaClusterValues = []string{"IDLE", "ATTACHING", "MEMBER", "CANDIDATE", "MASTER", "EXISTING", "NET_ISOLATED", "DISK_ISOLATED", "FAILED", "UNKNOWN"}
affinityRuleValues = []string{"SHOULD", "MUST"}
guestOSValues = []string{"ANDROID", "CHROMEOS", "FREEBSD", "LINUX", "MACOS", "MSDOS", "NETWARE", "OS2", "OTHER", "SOLARIS", "WINDOWS"}
guestOSVersionValues = []string{"ANDROID_2_x", "ANDROID_3_x", "ANDROID_4_0", "ANDROID_LAST", "ANDROID_OTHER", "ASTRA_LINUX", "BSD_4X", "BSD_5X", "BSD_6X", "BSD_7X", "BSD_8X", "BSD_LAST", "BSD_OTHER", "CHROMEOS_1x", "CHROMEOS_LAST", "CHROMEOS_OTHER", "DOS_LAST", "DOS_MS622", "DOS_OTHER", "LIN_CENTOS", "LIN_CENTOS_7", "LIN_CENTOS_8", "LIN_DEBIAN", "LIN_FEDORA", "LIN_FEDORA_5", "LIN_KRNL_24", "LIN_KRNL_26", "LIN_LAST", "LIN_MAGEIA", "LIN_MANDRAKE", "LIN_MINT", "LIN_OPENSUSE", "LIN_OTHER", "LIN_PSBM", "LIN_REDHAT", "LIN_REDHAT_7", "LIN_REDHAT_8", "LIN_RHLES3", "LIN_RH_LEGACY", "LIN_SLES11", "LIN_SLES12", "LIN_SLES9", "LIN_SUSE", "LIN_UBUNTU", "LIN_VZLINUX", "LIN_VZLINUX_7", "LIN_VZLINUX_8", "LIN_XANDROS", "LIN_CLOUDLINUX", "LIN_CLOUDLINUX_7", "MACOS_LAST", "MACOS_LEOPARD", "MACOS_SNOW_LEOPARD", "MACOS_TIGER", "MACOS_UNIVERSAL", "NET_4X", "NET_5X", "NET_6X", "NET_LAST", "NET_OTHER", "OS2_ECS11", "OS2_ECS12", "OS2_LAST", "OS2_OTHER", "OS2_WARP3", "OS2_WARP4", "OS2_WARP45", "OTH_LAST", "OTH_OPENSTEP", "OTH_OTHER", "OTH_QNX", "SOL_10", "SOL_11", "SOL_9", "SOL_LAST", "SOL_OPEN", "SOL_OTHER", "WIN_2003", "WIN_2008", "WIN_2012", "WIN_2016", "WIN_2019", "WIN_2K", "WIN_311", "WIN_95", "WIN_98", "WIN_LAST", "WIN_ME", "WIN_NT", "WIN_OTHER", "WIN_VISTA", "WIN_WINDOWS10", "WIN_WINDOWS7", "WIN_WINDOWS8", "WIN_WINDOWS8_1", "WIN_XP"}
autoStartValues = []string{"OFF", "ON", "AUTO", "START_APP", "OPEN_WINDOW"}
autoStopValues = []string{"STOP", "SUSPEND", "SHUTDOWN"}
vncModeValues = []string{"disabled", "auto", "manual"}
chipsetValues = []string{"I440FX", "Q35"}
clockOffsetValues = []string{"UTS", "LOCALTIME"}
templateStatusValues = []string{"unknown", "creating", "error", "deleted", "failed_to_create", "ready"}
cpuUnitsRange = []int64{2, 262144}
cpuLimitRange = []int64{0, 100}
ioPriorityRange = []int64{0, 7}
videoRamRange = []int64{1, 1024}
memGuaranteeSizeRange = []int64{-1, 100}
)