v1.0.0
This commit is contained in:
@@ -9,20 +9,53 @@ import (
|
||||
"github.com/rudecs/decort-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// Request struct for create disk
|
||||
type CreateRequest struct {
|
||||
AccountID uint64 `url:"accountId"`
|
||||
GID uint64 `url:"gid"`
|
||||
Name string `url:"name"`
|
||||
// ID of the account
|
||||
// Required: true
|
||||
AccountID uint64 `url:"accountId"`
|
||||
|
||||
// ID of the grid (platform)
|
||||
// Required: true
|
||||
GID uint64 `url:"gid"`
|
||||
|
||||
// Name of disk
|
||||
// Required: true
|
||||
Name string `url:"name"`
|
||||
|
||||
// Description of disk
|
||||
// Required: false
|
||||
Description string `url:"description,omitempty"`
|
||||
Size uint64 `url:"size,omitempty"`
|
||||
Type string `url:"type"`
|
||||
SSDSize uint64 `url:"ssdSize,omitempty"`
|
||||
IOps uint64 `url:"iops"`
|
||||
SepID uint64 `url:"sep_id,omitempty"`
|
||||
Pool string `url:"pool,omitempty"`
|
||||
|
||||
// Size in GB, default is 0
|
||||
// Required: false
|
||||
Size uint64 `url:"size,omitempty"`
|
||||
|
||||
// Type of disk
|
||||
// - B=Boot
|
||||
// - D=Data
|
||||
// - T=Temp
|
||||
// Required: true
|
||||
Type string `url:"type"`
|
||||
|
||||
// Size in GB default is 0
|
||||
// Required: false
|
||||
SSDSize uint64 `url:"ssdSize,omitempty"`
|
||||
|
||||
// Max IOPS disk can perform defaults to 2000
|
||||
// Required: false
|
||||
IOPS uint64 `url:"iops,omitempty"`
|
||||
|
||||
// Storage endpoint provider ID to create disk
|
||||
// Required: false
|
||||
SEPID uint64 `url:"sep_id,omitempty"`
|
||||
|
||||
// Pool name to create disk
|
||||
// Required: false
|
||||
Pool string `url:"pool,omitempty"`
|
||||
}
|
||||
|
||||
func (drq CreateRequest) Validate() error {
|
||||
func (drq CreateRequest) validate() error {
|
||||
if drq.AccountID == 0 {
|
||||
return errors.New("validation-error: field AccountID can not be empty or equal to 0")
|
||||
}
|
||||
@@ -32,21 +65,17 @@ func (drq CreateRequest) Validate() error {
|
||||
if drq.Name == "" {
|
||||
return errors.New("validation-error: field Name can not be empty")
|
||||
}
|
||||
|
||||
validType := validators.StringInSlice(drq.Type, []string{"B", "D", "T"})
|
||||
if !validType {
|
||||
return errors.New("validation-error: field Type must be set as B, D or T")
|
||||
}
|
||||
|
||||
if drq.IOps == 0 {
|
||||
return errors.New("validation-error: field IOps must be set")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create creates a disk
|
||||
func (d Disks) Create(ctx context.Context, req CreateRequest) (uint64, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -62,6 +91,6 @@ func (d Disks) Create(ctx context.Context, req CreateRequest) (uint64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result, nil
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -7,23 +7,36 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Request for delete disk
|
||||
type DeleteRequest struct {
|
||||
DiskID uint64 `url:"diskId"`
|
||||
Detach bool `url:"detach,omitempty"`
|
||||
Permanently bool `url:"permanently,omitempty"`
|
||||
Reason string `url:"reason,omitempty"`
|
||||
// ID of disk to delete
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId"`
|
||||
|
||||
// Detach disk from machine first
|
||||
// Required: false
|
||||
Detach bool `url:"detach,omitempty"`
|
||||
|
||||
// Whether to completely delete the disk, works only with non attached disks
|
||||
// Required: false
|
||||
Permanently bool `url:"permanently,omitempty"`
|
||||
|
||||
// Reason to delete
|
||||
// Required: false
|
||||
Reason string `url:"reason,omitempty"`
|
||||
}
|
||||
|
||||
func (d DeleteRequest) Validate() error {
|
||||
|
||||
func (d DeleteRequest) validate() error {
|
||||
if d.DiskID == 0 {
|
||||
return errors.New("validation-error: field DiskID must be set")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes disk by ID
|
||||
func (d Disks) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -39,5 +52,6 @@ func (d Disks) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -7,22 +7,35 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Request struct for multiple disks
|
||||
type DisksDeleteRequest struct {
|
||||
DisksIDs []uint64 `url:"diskIds"`
|
||||
Reason string `url:"reason"`
|
||||
Permanently bool `url:"permanently"`
|
||||
// List of disk ids to delete
|
||||
// Required: true
|
||||
DisksIDs []uint64 `url:"diskIds"`
|
||||
|
||||
// Reason for deleting the disks
|
||||
// Required: true
|
||||
Reason string `url:"reason"`
|
||||
|
||||
// Whether to completely delete the disks, works only with non attached disks
|
||||
// Required: false
|
||||
Permanently bool `url:"permanently,omitempty"`
|
||||
}
|
||||
|
||||
func (drq DisksDeleteRequest) Validate() error {
|
||||
func (drq DisksDeleteRequest) validate() error {
|
||||
if len(drq.DisksIDs) == 0 {
|
||||
return errors.New("validation-error: field DisksIDs must include one or more disks ids")
|
||||
}
|
||||
if drq.Reason == "" {
|
||||
return errors.New("validation-error: field Reason must be set")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteDisks deletes multiple disks permanently
|
||||
func (d Disks) DeleteDisks(ctx context.Context, req DisksDeleteRequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -40,5 +53,4 @@ func (d Disks) DeleteDisks(ctx context.Context, req DisksDeleteRequest) (bool, e
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
// API Actor api, this actor is the final api a enduser uses to manage his resources
|
||||
package disks
|
||||
|
||||
import (
|
||||
"github.com/rudecs/decort-sdk/interfaces"
|
||||
)
|
||||
|
||||
// Structure for creating request to disks
|
||||
type Disks struct {
|
||||
client interfaces.Caller
|
||||
}
|
||||
|
||||
// Builder for disks endpoints
|
||||
func New(client interfaces.Caller) *Disks {
|
||||
return &Disks{
|
||||
client,
|
||||
|
||||
@@ -7,11 +7,14 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Request struct for get information about disk
|
||||
type GetRequest struct {
|
||||
// ID of the disk
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId"`
|
||||
}
|
||||
|
||||
func (drq GetRequest) Validate() error {
|
||||
func (drq GetRequest) validate() error {
|
||||
if drq.DiskID == 0 {
|
||||
return errors.New("validation-error: field DiskID can not be empty or equal to 0")
|
||||
}
|
||||
@@ -19,8 +22,10 @@ func (drq GetRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d Disks) Get(ctx context.Context, req GetRequest) (*DiskRecord, error) {
|
||||
err := req.Validate()
|
||||
// Get gets disk details
|
||||
// Notice: the devicename field is the name as it is passed to the kernel (kname in linux) for unattached disks this field has no relevant value
|
||||
func (d Disks) Get(ctx context.Context, req GetRequest) (*RecordDisk, error) {
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -32,13 +37,12 @@ func (d Disks) Get(ctx context.Context, req GetRequest) (*DiskRecord, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disk := &DiskRecord{}
|
||||
info := RecordDisk{}
|
||||
|
||||
err = json.Unmarshal(res, disk)
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return disk, nil
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
@@ -7,25 +7,70 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Request struct for limit IO
|
||||
type LimitIORequest struct {
|
||||
DiskID uint64 `url:"diskId"`
|
||||
IOps uint64 `url:"iops"`
|
||||
TotalBytesSec uint64 `url:"total_bytes_sec"`
|
||||
ReadBytesSec uint64 `url:"read_bytes_sec"`
|
||||
WriteBytesSec uint64 `url:"write_bytes_sec"`
|
||||
TotalIOpsSec uint64 `url:"total_iops_sec"`
|
||||
ReadIOpsSec uint64 `url:"read_iops_sec"`
|
||||
WriteIOpsSec uint64 `url:"write_iops_sec"`
|
||||
TotalBytesSecMax uint64 `url:"total_bytes_sec_max"`
|
||||
ReadBytesSecMax uint64 `url:"read_bytes_sec_max"`
|
||||
WriteBytesSecMax uint64 `url:"write_bytes_sec_max"`
|
||||
TotalIOpsSecMax uint64 `url:"total_iops_sec_max"`
|
||||
ReadIOpsSecMax uint64 `url:"read_iops_sec_max"`
|
||||
WriteIOpsSecMax uint64 `url:"write_iops_sec_max"`
|
||||
SizeIOpsSec uint64 `url:"size_iops_sec"`
|
||||
// ID of the disk to limit
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId"`
|
||||
|
||||
// Alias for total_iops_sec for backwards compatibility
|
||||
// Required: false
|
||||
IOPS uint64 `url:"iops,omitempty"`
|
||||
|
||||
// TotalBytesSec
|
||||
// Required: false
|
||||
TotalBytesSec uint64 `url:"total_bytes_sec,omitempty"`
|
||||
|
||||
// ReadBytesSec
|
||||
// Required: false
|
||||
ReadBytesSec uint64 `url:"read_bytes_sec,omitempty"`
|
||||
|
||||
// WriteBytesSec
|
||||
// Required: false
|
||||
WriteBytesSec uint64 `url:"write_bytes_sec,omitempty"`
|
||||
|
||||
// TotalIOPSSec
|
||||
// Required: false
|
||||
TotalIOPSSec uint64 `url:"total_iops_sec,omitempty"`
|
||||
|
||||
// ReadIOPSSec
|
||||
// Required: false
|
||||
ReadIOPSSec uint64 `url:"read_iops_sec,omitempty"`
|
||||
|
||||
// WriteIOPSSec
|
||||
// Required: false
|
||||
WriteIOPSSec uint64 `url:"write_iops_sec,omitempty"`
|
||||
|
||||
// TotalBytesSecMax
|
||||
// Required: false
|
||||
TotalBytesSecMax uint64 `url:"total_bytes_sec_max,omitempty"`
|
||||
|
||||
// ReadBytesSecMax
|
||||
// Required: false
|
||||
ReadBytesSecMax uint64 `url:"read_bytes_sec_max,omitempty"`
|
||||
|
||||
// WriteBytesSecMax
|
||||
// Required: false
|
||||
WriteBytesSecMax uint64 `url:"write_bytes_sec_max,omitempty"`
|
||||
|
||||
// TotalIOPSSecMax
|
||||
// Required: false
|
||||
TotalIOPSSecMax uint64 `url:"total_iops_sec_max,omitempty"`
|
||||
|
||||
// ReadIOPSSecMax
|
||||
// Required: false
|
||||
ReadIOPSSecMax uint64 `url:"read_iops_sec_max,omitempty"`
|
||||
|
||||
// WriteIOPSSecMax
|
||||
// Required: false
|
||||
WriteIOPSSecMax uint64 `url:"write_iops_sec_max,omitempty"`
|
||||
|
||||
// SizeIOPSSec
|
||||
// Required: false
|
||||
SizeIOPSSec uint64 `url:"size_iops_sec,omitempty"`
|
||||
}
|
||||
|
||||
func (drq LimitIORequest) Validate() error {
|
||||
func (drq LimitIORequest) validate() error {
|
||||
if drq.DiskID == 0 {
|
||||
return errors.New("validation-error: field DiskID can not be empty or equal to 0")
|
||||
}
|
||||
@@ -33,8 +78,11 @@ func (drq LimitIORequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// LimitIO limit IO for a certain disk
|
||||
// total and read/write options are not allowed to be combined
|
||||
// see http://libvirt.org/formatdomain.html#elementsDisks iotune section for more details
|
||||
func (d Disks) LimitIO(ctx context.Context, req LimitIORequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -52,5 +100,4 @@ func (d Disks) LimitIO(ctx context.Context, req LimitIORequest) (bool, error) {
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -6,14 +6,27 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Request struct for get list/list_deleted of disks
|
||||
type ListRequest struct {
|
||||
// ID of the account the disks belong to
|
||||
// Required: false
|
||||
AccountID uint64 `url:"accountId,omitempty"`
|
||||
Type string `url:"type,omitempty"`
|
||||
Page uint64 `url:"page,omitempty"`
|
||||
Size uint64 `url:"size,omitempty"`
|
||||
|
||||
// Type of the disks
|
||||
// Required: false
|
||||
Type string `url:"type,omitempty"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty"`
|
||||
|
||||
// Page size
|
||||
// Required: false
|
||||
Size uint64 `url:"size,omitempty"`
|
||||
}
|
||||
|
||||
func (d Disks) List(ctx context.Context, req ListRequest) (DiskList, error) {
|
||||
// List gets list the created disks belonging to an account
|
||||
func (d Disks) List(ctx context.Context, req ListRequest) (ListDisks, error) {
|
||||
url := "/cloudapi/disks/list"
|
||||
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
@@ -21,34 +34,31 @@ func (d Disks) List(ctx context.Context, req ListRequest) (DiskList, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
diskList := DiskList{}
|
||||
list := ListDisks{}
|
||||
|
||||
err = json.Unmarshal(res, &diskList)
|
||||
err = json.Unmarshal(res, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return diskList, nil
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (d Disks) ListDeleted(ctx context.Context, req ListRequest) (DiskList, error) {
|
||||
url := "/disks/listDeleted"
|
||||
prefix := "/cloudapi"
|
||||
// ListDeleted gets list the deleted disks belonging to an account
|
||||
func (d Disks) ListDeleted(ctx context.Context, req ListRequest) (ListDisks, error) {
|
||||
url := "/cloudapi/disks/listDeleted"
|
||||
|
||||
url = prefix + url
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
diskList := DiskList{}
|
||||
list := ListDisks{}
|
||||
|
||||
err = json.Unmarshal(res, &diskList)
|
||||
err = json.Unmarshal(res, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return diskList, nil
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
@@ -6,10 +6,14 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Request struct for get list types of disks
|
||||
type ListTypesRequest struct {
|
||||
// Show detailed disk types by seps
|
||||
// Required: false
|
||||
Detailed bool `url:"detailed"`
|
||||
}
|
||||
|
||||
// ListTypes gets list defined disk types
|
||||
func (d Disks) ListTypes(ctx context.Context, req ListTypesRequest) ([]interface{}, error) {
|
||||
url := "/cloudapi/disks/listTypes"
|
||||
|
||||
@@ -18,13 +22,12 @@ func (d Disks) ListTypes(ctx context.Context, req ListTypesRequest) ([]interface
|
||||
return nil, err
|
||||
}
|
||||
|
||||
typesList := make([]interface{}, 0)
|
||||
list := make([]interface{}, 0)
|
||||
|
||||
err = json.Unmarshal(res, &typesList)
|
||||
err = json.Unmarshal(res, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return typesList, nil
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
@@ -6,11 +6,15 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Request struct for get list unattached disk
|
||||
type ListUnattachedRequest struct {
|
||||
AccountID uint64 `url:"accountId"`
|
||||
// ID of the account
|
||||
// Required: false
|
||||
AccountID uint64 `url:"accountId,omitempty"`
|
||||
}
|
||||
|
||||
func (d Disks) ListUnattached(ctx context.Context, req ListUnattachedRequest) (DiskList, error) {
|
||||
// ListUnattached gets list of unattached disks
|
||||
func (d Disks) ListUnattached(ctx context.Context, req ListUnattachedRequest) (ListDisks, error) {
|
||||
url := "/cloudapi/disks/listUnattached"
|
||||
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
@@ -18,13 +22,12 @@ func (d Disks) ListUnattached(ctx context.Context, req ListUnattachedRequest) (D
|
||||
return nil, err
|
||||
}
|
||||
|
||||
diskList := DiskList{}
|
||||
list := ListDisks{}
|
||||
|
||||
err = json.Unmarshal(res, &diskList)
|
||||
err = json.Unmarshal(res, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return diskList, nil
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
@@ -1,116 +1,280 @@
|
||||
package disks
|
||||
|
||||
type Disk struct {
|
||||
ACL map[string]interface{} `json:"acl"`
|
||||
AccountID uint64 `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
BootPartition uint64 `json:"bootPartition"`
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
ComputeID uint64 `json:"computeId"`
|
||||
ComputeName string `json:"computeName"`
|
||||
DeletedTime uint64 `json:"deletedTime"`
|
||||
DeviceName string `json:"devicename"`
|
||||
Description string `json:"desc"`
|
||||
DestructionTime uint64 `json:"destructionTime"`
|
||||
GID uint64 `json:"gid"`
|
||||
ID uint64 `json:"id"`
|
||||
ImageID uint64 `json:"imageId"`
|
||||
Images []uint64 `json:"images"`
|
||||
IOTune IOTune `json:"iotune"`
|
||||
MachineID uint64 `json:"machineId"`
|
||||
MachineName string `json:"machineName"`
|
||||
Name string `json:"name"`
|
||||
Order uint64 `json:"order"`
|
||||
Params string `json:"params"`
|
||||
ParentID uint64 `json:"parentId"`
|
||||
PciSlot uint64 `json:"pciSlot"`
|
||||
Pool string `json:"pool"`
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
ResID string `json:"resId"`
|
||||
ResName string `json:"resName"`
|
||||
Role string `json:"role"`
|
||||
SepType string `json:"sepType"`
|
||||
SepID uint64 `json:"sepId"` // NOTE: absent from compute/get output
|
||||
SizeMax uint64 `json:"sizeMax"`
|
||||
Snapshots []Snapshot `json:"snapshots"`
|
||||
Status string `json:"status"`
|
||||
TechStatus string `json:"techStatus"`
|
||||
Type string `json:"type"`
|
||||
VMID uint64 `json:"vmid"`
|
||||
}
|
||||
// Main information about disk
|
||||
type ItemDisk struct {
|
||||
// Access Control List
|
||||
ACL map[string]interface{} `json:"acl"`
|
||||
|
||||
type Snapshot struct {
|
||||
Guid string `json:"guid"`
|
||||
Label string `json:"label"`
|
||||
ResID string `json:"resId"`
|
||||
SnapSetGuid string `json:"snapSetGuid"`
|
||||
SnapSetTime uint64 `json:"snapSetTime"`
|
||||
TimeStamp uint64 `json:"timestamp"`
|
||||
}
|
||||
// Account ID
|
||||
AccountID uint64 `json:"accountId"`
|
||||
|
||||
type SnapshotList []Snapshot
|
||||
// Account name
|
||||
AccountName string `json:"accountName"`
|
||||
|
||||
type IOTune struct {
|
||||
ReadBytesSec uint64 `json:"read_bytes_sec"`
|
||||
ReadBytesSecMax uint64 `json:"read_bytes_sec_max"`
|
||||
ReadIopsSec uint64 `json:"read_iops_sec"`
|
||||
ReadIopsSecMax uint64 `json:"read_iops_sec_max"`
|
||||
SizeIopsSec uint64 `json:"size_iops_sec"`
|
||||
TotalBytesSec uint64 `json:"total_bytes_sec"`
|
||||
TotalBytesSecMax uint64 `json:"total_bytes_sec_max"`
|
||||
TotalIopsSec uint64 `json:"total_iops_sec"`
|
||||
TotalIopsSecMax uint64 `json:"total_iops_sec_max"`
|
||||
WriteBytesSec uint64 `json:"write_bytes_sec"`
|
||||
WriteBytesSecMax uint64 `json:"write_bytes_sec_max"`
|
||||
WriteIopsSec uint64 `json:"write_iops_sec"`
|
||||
WriteIopsSecMax uint64 `json:"write_iops_sec_max"`
|
||||
}
|
||||
// Boot partition
|
||||
BootPartition uint64 `json:"bootPartition"`
|
||||
|
||||
type DiskList []Disk
|
||||
// Created time
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
|
||||
type DisksTypesListCoomon []string
|
||||
// Compute ID
|
||||
ComputeID uint64 `json:"computeId"`
|
||||
|
||||
type DisksTypesListDetailed struct {
|
||||
Pools []Pool `json:"pools"`
|
||||
// Compute name
|
||||
ComputeName string `json:"computeName"`
|
||||
|
||||
// Deleted time
|
||||
DeletedTime uint64 `json:"deletedTime"`
|
||||
|
||||
// Device name
|
||||
DeviceName string `json:"devicename"`
|
||||
|
||||
// Description
|
||||
Description string `json:"desc"`
|
||||
|
||||
// Destruction time
|
||||
DestructionTime uint64 `json:"destructionTime"`
|
||||
|
||||
// Grid ID
|
||||
GID uint64 `json:"gid"`
|
||||
|
||||
// ID
|
||||
ID uint64 `json:"id"`
|
||||
|
||||
// Image ID
|
||||
ImageID uint64 `json:"imageId"`
|
||||
|
||||
// List of image IDs
|
||||
Images []uint64 `json:"images"`
|
||||
|
||||
// IOTune
|
||||
IOTune IOTune `json:"iotune"`
|
||||
|
||||
// Machine ID
|
||||
MachineID uint64 `json:"machineId"`
|
||||
|
||||
// Machine name
|
||||
MachineName string `json:"machineName"`
|
||||
|
||||
// Name
|
||||
Name string `json:"name"`
|
||||
|
||||
// Order
|
||||
Order uint64 `json:"order"`
|
||||
|
||||
// Params
|
||||
Params string `json:"params"`
|
||||
|
||||
// Parent ID
|
||||
ParentID uint64 `json:"parentId"`
|
||||
|
||||
// PCI slot
|
||||
PCISlot uint64 `json:"pciSlot"`
|
||||
|
||||
// Pool
|
||||
Pool string `json:"pool"`
|
||||
|
||||
// Purge time
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
|
||||
// Resource ID
|
||||
ResID string `json:"resId"`
|
||||
|
||||
// Resource name
|
||||
ResName string `json:"resName"`
|
||||
|
||||
// Role
|
||||
Role string `json:"role"`
|
||||
|
||||
// SepType
|
||||
SepType string `json:"sepType"`
|
||||
|
||||
// SepID
|
||||
SepID uint64 `json:"sepId"`
|
||||
|
||||
// Size max
|
||||
SizeMax uint64 `json:"sizeMax"`
|
||||
|
||||
// List of snapshots
|
||||
Snapshots ListSnapshots `json:"snapshots"`
|
||||
|
||||
// Status
|
||||
Status string `json:"status"`
|
||||
|
||||
// Tech status
|
||||
TechStatus string `json:"techStatus"`
|
||||
|
||||
// Type
|
||||
Type string `json:"type"`
|
||||
|
||||
// Virtual machine ID
|
||||
VMID uint64 `json:"vmid"`
|
||||
}
|
||||
|
||||
type Pool struct {
|
||||
Name string `json:"name"`
|
||||
Types []string `json:"types"`
|
||||
// List of disks
|
||||
type ListDisks []ItemDisk
|
||||
|
||||
// Main information about snapshot
|
||||
type ItemSnapshot struct {
|
||||
// GUID
|
||||
GUID string `json:"guid"`
|
||||
|
||||
// Label
|
||||
Label string `json:"label"`
|
||||
|
||||
// Resource ID
|
||||
ResID string `json:"resId"`
|
||||
|
||||
// SnapSetGUID
|
||||
SnapSetGUID string `json:"snapSetGuid"`
|
||||
|
||||
// SnapSetTime
|
||||
SnapSetTime uint64 `json:"snapSetTime"`
|
||||
|
||||
// TimeStamp
|
||||
TimeStamp uint64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type DiskRecord struct {
|
||||
ACL map[string]interface{} `json:"acl"`
|
||||
AccountID uint64 `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
DeletedTime uint64 `json:"deletedTime"`
|
||||
DeviceName string `json:"devicename"`
|
||||
Description string `json:"desc"`
|
||||
DestructionTime uint64 `json:"destructionTime"`
|
||||
GID uint64 `json:"gid"`
|
||||
ID uint64 `json:"id"`
|
||||
ImageID uint64 `json:"imageId"`
|
||||
Images []uint64 `json:"images"`
|
||||
IOTune IOTune `json:"iotune"`
|
||||
Name string `json:"name"`
|
||||
Order uint64 `json:"order"`
|
||||
Params string `json:"params"`
|
||||
ParentID uint64 `json:"parentId"`
|
||||
PciSlot uint64 `json:"pciSlot"`
|
||||
Pool string `json:"pool"`
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
ResID string `json:"resId"`
|
||||
ResName string `json:"resName"`
|
||||
Role string `json:"role"`
|
||||
SepType string `json:"sepType"`
|
||||
SepID uint64 `json:"sepId"` // NOTE: absent from compute/get output
|
||||
SizeMax uint64 `json:"sizeMax"`
|
||||
SizeUsed uint64 `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space
|
||||
Snapshots []Snapshot `json:"snapshots"`
|
||||
Status string `json:"status"`
|
||||
TechStatus string `json:"techStatus"`
|
||||
Type string `json:"type"`
|
||||
VMID uint64 `json:"vmid"`
|
||||
// List of snapshots
|
||||
type ListSnapshots []ItemSnapshot
|
||||
|
||||
// Main information about IO tune
|
||||
type IOTune struct {
|
||||
// ReadBytesSec
|
||||
ReadBytesSec uint64 `json:"read_bytes_sec"`
|
||||
|
||||
// ReadBytesSecMax
|
||||
ReadBytesSecMax uint64 `json:"read_bytes_sec_max"`
|
||||
|
||||
// ReadIOPSSec
|
||||
ReadIOPSSec uint64 `json:"read_iops_sec"`
|
||||
|
||||
// ReadIOPSSecMax
|
||||
ReadIOPSSecMax uint64 `json:"read_iops_sec_max"`
|
||||
|
||||
// SizeIOPSSec
|
||||
SizeIOPSSec uint64 `json:"size_iops_sec"`
|
||||
|
||||
// TotalBytesSec
|
||||
TotalBytesSec uint64 `json:"total_bytes_sec"`
|
||||
|
||||
// TotalBytesSecMax
|
||||
TotalBytesSecMax uint64 `json:"total_bytes_sec_max"`
|
||||
|
||||
// TotalIOPSSec
|
||||
TotalIOPSSec uint64 `json:"total_iops_sec"`
|
||||
|
||||
// TotalIOPSSecMax
|
||||
TotalIOPSSecMax uint64 `json:"total_iops_sec_max"`
|
||||
|
||||
// WriteBytesSec
|
||||
WriteBytesSec uint64 `json:"write_bytes_sec"`
|
||||
|
||||
// WriteBytesSecMax
|
||||
WriteBytesSecMax uint64 `json:"write_bytes_sec_max"`
|
||||
|
||||
// WriteIOPSSec
|
||||
WriteIOPSSec uint64 `json:"write_iops_sec"`
|
||||
|
||||
// WriteIOPSSecMax
|
||||
WriteIOPSSecMax uint64 `json:"write_iops_sec_max"`
|
||||
}
|
||||
|
||||
// Detailed information about disk
|
||||
type RecordDisk struct {
|
||||
// Access Control List
|
||||
ACL map[string]interface{} `json:"acl"`
|
||||
|
||||
// Account ID
|
||||
AccountID uint64 `json:"accountId"`
|
||||
|
||||
// Account name
|
||||
AccountName string `json:"accountName"`
|
||||
|
||||
// Created time
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
|
||||
// Deleted time
|
||||
DeletedTime uint64 `json:"deletedTime"`
|
||||
|
||||
// Device name
|
||||
DeviceName string `json:"devicename"`
|
||||
|
||||
// Description
|
||||
Description string `json:"desc"`
|
||||
|
||||
// Destruction time
|
||||
DestructionTime uint64 `json:"destructionTime"`
|
||||
|
||||
// Grid ID
|
||||
GID uint64 `json:"gid"`
|
||||
|
||||
// ID
|
||||
ID uint64 `json:"id"`
|
||||
|
||||
// Image ID
|
||||
ImageID uint64 `json:"imageId"`
|
||||
|
||||
// List of image IDs
|
||||
Images []uint64 `json:"images"`
|
||||
|
||||
// IOTune
|
||||
IOTune IOTune `json:"iotune"`
|
||||
|
||||
// Name
|
||||
Name string `json:"name"`
|
||||
|
||||
// Order
|
||||
Order uint64 `json:"order"`
|
||||
|
||||
// Params
|
||||
Params string `json:"params"`
|
||||
|
||||
// Parent ID
|
||||
ParentID uint64 `json:"parentId"`
|
||||
|
||||
// PCI slot
|
||||
PCISlot uint64 `json:"pciSlot"`
|
||||
|
||||
// Pool
|
||||
Pool string `json:"pool"`
|
||||
|
||||
// Purge time
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
|
||||
// Resource ID
|
||||
ResID string `json:"resId"`
|
||||
|
||||
// Resource name
|
||||
ResName string `json:"resName"`
|
||||
|
||||
// Role
|
||||
Role string `json:"role"`
|
||||
|
||||
// SepType
|
||||
SepType string `json:"sepType"`
|
||||
|
||||
// SepID
|
||||
SepID uint64 `json:"sepId"`
|
||||
|
||||
// Size max
|
||||
SizeMax uint64 `json:"sizeMax"`
|
||||
|
||||
// Size used
|
||||
SizeUsed uint64 `json:"sizeUsed"`
|
||||
|
||||
// List of snapshots
|
||||
Snapshots ListSnapshots `json:"snapshots"`
|
||||
|
||||
// Status
|
||||
Status string `json:"status"`
|
||||
|
||||
// Tech status
|
||||
TechStatus string `json:"techStatus"`
|
||||
|
||||
// Type
|
||||
Type string `json:"type"`
|
||||
|
||||
// Virtual machine ID
|
||||
VMID uint64 `json:"vmid"`
|
||||
}
|
||||
|
||||
@@ -7,16 +7,21 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Request struct for rename disk
|
||||
type RenameRequest struct {
|
||||
// ID of the disk to rename
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId"`
|
||||
Name string `url:"name"`
|
||||
|
||||
// New name of disk
|
||||
// Required: true
|
||||
Name string `url:"name"`
|
||||
}
|
||||
|
||||
func (drq RenameRequest) Validate() error {
|
||||
func (drq RenameRequest) validate() error {
|
||||
if drq.DiskID == 0 {
|
||||
return errors.New("validation-error: field DiskID can not be empty or equal to 0")
|
||||
}
|
||||
|
||||
if drq.Name == "" {
|
||||
return errors.New("validation-error: field Name can not be empty")
|
||||
}
|
||||
@@ -24,8 +29,9 @@ func (drq RenameRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rename rename disk
|
||||
func (d Disks) Rename(ctx context.Context, req RenameRequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -43,5 +49,4 @@ func (d Disks) Rename(ctx context.Context, req RenameRequest) (bool, error) {
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -7,16 +7,21 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Request struct for resize disk
|
||||
type ResizeRequest struct {
|
||||
// ID of the disk to resize
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId"`
|
||||
Size uint64 `url:"size"`
|
||||
|
||||
// New size of the disk in GB
|
||||
// Required: true
|
||||
Size uint64 `url:"size"`
|
||||
}
|
||||
|
||||
func (drq ResizeRequest) Validate() error {
|
||||
func (drq ResizeRequest) validate() error {
|
||||
if drq.DiskID == 0 {
|
||||
return errors.New("validation-error: field DiskID can not be empty or equal to 0")
|
||||
}
|
||||
|
||||
if drq.Size == 0 {
|
||||
return errors.New("validation-error: field Size can not be empty or equal to 0")
|
||||
}
|
||||
@@ -24,8 +29,12 @@ func (drq ResizeRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resize resize disk
|
||||
// Returns 200 if disk is resized online, else will return 202,
|
||||
// in that case please stop and start your machine after changing the disk size, for your changes to be reflected.
|
||||
// This method will not be used for disks, assigned to computes. Only unassigned disks and disks, assigned with "old" virtual machines.
|
||||
func (d Disks) Resize(ctx context.Context, req ResizeRequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -43,19 +52,20 @@ func (d Disks) Resize(ctx context.Context, req ResizeRequest) (bool, error) {
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
// Resize2 resize disk
|
||||
// Returns 200 if disk is resized online, else will return 202,
|
||||
// in that case please stop and start your machine after changing the disk size, for your changes to be reflected.
|
||||
// This method will not be used for disks, assigned to "old" virtual machines. Only unassigned disks and disks, assigned with computes.
|
||||
func (d Disks) Resize2(ctx context.Context, req ResizeRequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
url := "/disks/resize2"
|
||||
prefix := "/cloudapi"
|
||||
url := "/cloudapi/disks/resize2"
|
||||
|
||||
url = prefix + url
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -67,5 +77,4 @@ func (d Disks) Resize2(ctx context.Context, req ResizeRequest) (bool, error) {
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -7,16 +7,21 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Request struct for restore a deleted unattached disk
|
||||
type RestoreRequest struct {
|
||||
// ID of the disk to restore
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId"`
|
||||
|
||||
// Reason for restoring the disk
|
||||
// Required: true
|
||||
Reason string `url:"reason"`
|
||||
}
|
||||
|
||||
func (drq RestoreRequest) Validate() error {
|
||||
func (drq RestoreRequest) validate() error {
|
||||
if drq.DiskID == 0 {
|
||||
return errors.New("validation-error: field DiskID can not be empty or equal to 0")
|
||||
}
|
||||
|
||||
if drq.Reason == "" {
|
||||
return errors.New("validation-error: field Reason can not be empty")
|
||||
}
|
||||
@@ -24,8 +29,9 @@ func (drq RestoreRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Restore restore a deleted unattached disk from recycle bin
|
||||
func (d Disks) Restore(ctx context.Context, req RestoreRequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -43,5 +49,4 @@ func (d Disks) Restore(ctx context.Context, req RestoreRequest) (bool, error) {
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -6,13 +6,22 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Request struct for search
|
||||
type SearchRequest struct {
|
||||
// ID of the account to search for the Disk
|
||||
// Required: false
|
||||
AccountID uint64 `url:"accountId,omitempty"`
|
||||
Name string `url:"name,omitempty"`
|
||||
ShowAll bool `url:"show_all,omitempty"`
|
||||
// Name of the Disk to search for
|
||||
// Required: false
|
||||
Name string `url:"name,omitempty"`
|
||||
|
||||
// If false, then disks having one of the statuses are not listed
|
||||
// Required: false
|
||||
ShowAll bool `url:"show_all,omitempty"`
|
||||
}
|
||||
|
||||
func (d Disks) Search(ctx context.Context, req SearchRequest) (DiskList, error) {
|
||||
// Search search disks
|
||||
func (d Disks) Search(ctx context.Context, req SearchRequest) (ListDisks, error) {
|
||||
url := "/cloudapi/disks/search"
|
||||
|
||||
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
@@ -20,13 +29,12 @@ func (d Disks) Search(ctx context.Context, req SearchRequest) (DiskList, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
diskList := DiskList{}
|
||||
list := ListDisks{}
|
||||
|
||||
err = json.Unmarshal(res, &diskList)
|
||||
err = json.Unmarshal(res, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return diskList, nil
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
@@ -7,12 +7,18 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Request struct for delete snapshot
|
||||
type SnapshotDeleteRequest struct {
|
||||
// ID of disk to delete
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId"`
|
||||
Label string `url:"label"`
|
||||
|
||||
// Label of the snapshot to delete
|
||||
// Required: false
|
||||
Label string `url:"label"`
|
||||
}
|
||||
|
||||
func (drq SnapshotDeleteRequest) Validate() error {
|
||||
func (drq SnapshotDeleteRequest) validate() error {
|
||||
if drq.DiskID == 0 {
|
||||
return errors.New("validation-error: field DiskID can not be empty or equal to 0")
|
||||
}
|
||||
@@ -24,8 +30,9 @@ func (drq SnapshotDeleteRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SnapshotDelete deletes a snapshot
|
||||
func (d Disks) SnapshotDelete(ctx context.Context, req SnapshotDeleteRequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -43,5 +50,4 @@ func (d Disks) SnapshotDelete(ctx context.Context, req SnapshotDeleteRequest) (b
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -7,17 +7,25 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Request struct for rollback snapshot
|
||||
type SnapshotRollbackRequest struct {
|
||||
DiskID uint64 `url:"diskId"`
|
||||
Label string `url:"label"`
|
||||
// ID of the disk
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId"`
|
||||
|
||||
// Label of the snapshot to rollback
|
||||
// Required: true
|
||||
Label string `url:"label"`
|
||||
|
||||
// Timestamp of the snapshot to rollback
|
||||
// Required: true
|
||||
TimeStamp uint64 `url:"timestamp"`
|
||||
}
|
||||
|
||||
func (drq SnapshotRollbackRequest) Validate() error {
|
||||
func (drq SnapshotRollbackRequest) validate() error {
|
||||
if drq.DiskID == 0 {
|
||||
return errors.New("validation-error: field DiskID can not be empty or equal to 0")
|
||||
}
|
||||
|
||||
if drq.Label == "" && drq.TimeStamp == 0 {
|
||||
return errors.New("validation-error: field Label or field TimeStamp can not be empty")
|
||||
}
|
||||
@@ -25,8 +33,9 @@ func (drq SnapshotRollbackRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SnapshotRollback rollback an individual disk snapshot
|
||||
func (d Disks) SnapshotRollback(ctx context.Context, req SnapshotRollbackRequest) (bool, error) {
|
||||
err := req.Validate()
|
||||
err := req.validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user