package apps import ( "regexp" "strings" "time" // This is line from GORM documentation that imports database dialect _ "github.com/jinzhu/gorm/dialects/sqlite" "github.com/rosti-cz/node-api/detector" ) // ValidationError is error that holds multiple validation error messages type ValidationError struct { // List of validation errors // Example: ["phone number is too short", "email address is wrongly formated"] Errors []string } func (v ValidationError) Error() string { return strings.Join(v.Errors, "\n") } // Label holds metadata about the application type Label struct { // Value of the label // Example: userid:1 // Required: true Value string `json:"value"` AppID uint `json:"-" gorm:"not null"` } // AppState contains info about runnint application, it's not saved in the database type AppState struct { State string `json:"state"` CPUUsage float64 `json:"cpu_usage"` // in percents MemoryUsage int `json:"memory_usage"` // in MB DiskUsageBytes int `json:"disk_usage_bytes"` DiskUsageInodes int `json:"disk_usage_inodes"` Flags detector.Flags `json:"flags"` } // Apps is list of applications type Apps []App // App keeps info about hosted application type App struct { // ID of the applicaton // Unique: true ID uint `gorm:"primary_key" json:"id"` // Datetime of creation CreatedAt time.Time `json:"created_at"` // Datetime of last update UpdatedAt time.Time `json:"updated_at"` // Datetime of deletion DeletedAt *time.Time `sql:"index" json:"deleted_at"` // Name of the application // Example: test_1234 Name string `json:"name" gorm:"unique,index,not_null"` // SSH port where the application will be available // Unique: true // Example: 10001 SSHPort int `json:"ssh_port"` // HTTP port where the application will be available // Unique: true // Example: 10002 HTTPPort int `json:"http_port"` // Runtime image Image string `json:"image"` // Number of CPUs ticks assigned, 100 means one CPU, 200 are two CPU int `json:"cpu"` // percentage, 200 means two CPU // Memory limit in MB Memory int `json:"memory"` // Limit in MB // Custom labels Labels []Label `json:"labels" gorm:"foreignkey:AppID"` // username:cx or user_id:1 // Current status of the application (underlaying container) State string `json:"state"` // CPU usage in percents CPUUsage float64 `json:"cpu_usage"` // in percents // Memory usage in bytes MemoryUsage int `json:"memory_usage"` // in B // Disk usage in bytes DiskUsageBytes int `json:"disk_usage_bytes"` // Disk usage in inodes DiskUsageInodes int `json:"disk_usage_inodes"` // Flags from detector of problems in the container Flags string `json:"flags"` // flags are separated by comma // this is gathered in docker package and has to be assembled externally Techs AppTechs `json:"techs,omitempty" gorm:"-"` // list of available technologies in the image PrimaryTech AppTech `json:"primary_tech,omitempty" gorm:"-"` // Technology that was selected as primary in the environment // This is not store in the database but used in create request when the app suppose to be created from an existing snapshot Snapshot string `json:"snapshot" gorm:"-"` } // Validate do basic checks of the struct values func (a *App) Validate() []string { var errors []string nameRegExp := regexp.MustCompile(`^[a-z0-9_\-]{3,48}$`) if !nameRegExp.MatchString(a.Name) { errors = append(errors, "name can contain only characters, numbers and underscores and has to be between 3 and 48 characters") } if a.SSHPort < 0 && a.SSHPort > 65536 { errors = append(errors, "SSH port has to be between 0 and 65536, where 0 means disabled") } if a.HTTPPort < 1 && a.HTTPPort > 65536 { errors = append(errors, "HTTP port has to be between 1 and 65536") } if a.Image == "" { errors = append(errors, "image cannot be empty") } if a.CPU < 10 && a.CPU > 800 { errors = append(errors, "CPU value has be between 10 and 800") } if a.Memory < 32 && a.Memory > 16384 { errors = append(errors, "Memory value has be between 32 and 16384") } return errors } // AppTechs is list of technologies available in the app type AppTechs []AppTech // AppTech holds info about one technology in the app type AppTech struct { Name string `json:"name"` Version string `json:"version"` }