1package gsclient 2 3import ( 4 "context" 5 "errors" 6 "net/http" 7 "path" 8) 9 10//ServerStorageRelationList JSON struct of a list of relations between a server and storages 11type ServerStorageRelationList struct { 12 //Array of relations between a server and storages 13 List []ServerStorageRelationProperties `json:"storage_relations"` 14} 15 16//ServerStorageRelationSingle JSON struct of a single relation between a server and a storage 17type ServerStorageRelationSingle struct { 18 //Properties of a relation between a server and a storage 19 Properties ServerStorageRelationProperties `json:"storage_relation"` 20} 21 22//ServerStorageRelationProperties JSON struct of properties of a relation between a server and a storage 23type ServerStorageRelationProperties struct { 24 //The UUID of an object is always unique, and refers to a specific object. 25 ObjectUUID string `json:"object_uuid"` 26 27 //The human-readable name of the object. It supports the full UTF-8 charset, with a maximum of 64 characters. 28 ObjectName string `json:"object_name"` 29 30 //The capacity of a storage/ISO-Image/template/snapshot in GB. 31 Capacity int `json:"capacity"` 32 33 //Indicates the speed of the storage. This may be (storage, storage_high or storage_insane). 34 StorageType string `json:"storage_type"` 35 36 //Defines the SCSI target ID. The SCSI defines transmission routes like Serial Attached SCSI (SAS), Fibre Channel and iSCSI. 37 //The target ID is a device (e.g. disk). 38 Target int `json:"target"` 39 40 //Is the common SCSI abbreviation of the Logical Unit Number. A LUN is a unique identifier for a single disk or a composite of disks. 41 Lun int `json:"lun"` 42 43 //Defines the SCSI controller id. The SCSI defines transmission routes such as Serial Attached SCSI (SAS), Fibre Channel and iSCSI. 44 Controller int `json:"controller"` 45 46 //Defines the date and time the object was initially created. 47 CreateTime GSTime `json:"create_time"` 48 49 //Defines if this object is the bootdevice. Storages, Networks and ISO-Images can have a bootdevice configured, 50 //but only one bootdevice per Storage, Network or ISO-Image. 51 //The boot order is as follows => Network > ISO-Image > Storage. 52 BootDevice bool `json:"bootdevice"` 53 54 //The SCSI bus id. The SCSI defines transmission routes like Serial Attached SCSI (SAS), Fibre Channel and iSCSI. 55 //Each SCSI device is addressed via a specific number. Each SCSI bus can have multiple SCSI devices connected to it. 56 Bus int `json:"bus"` 57 58 //Indicates the UUID of the last used template on this storage (inherited from snapshots). 59 LastUsedTemplate string `json:"last_used_template"` 60 61 //If a template has been used that requires a license key (e.g. Windows Servers) 62 //this shows the product_no of the license (see the /prices endpoint for more details). 63 LicenseProductNo int `json:"license_product_no"` 64 65 //The same as the object_uuid. 66 ServerUUID string `json:"server_uuid"` 67} 68 69//ServerStorageRelationCreateRequest JSON struct of a request for creating a relation between a server and a storage 70type ServerStorageRelationCreateRequest struct { 71 //The UUID of the storage you are requesting. If server's hardware profile is default, nested, q35 or q35_nested, 72 //you are allowed to attached 8 servers. Only 2 storage are allowed to be attached to server with other hardware profile 73 ObjectUUID string `json:"object_uuid"` 74 75 //Whether the server will boot from this storage device or not. Optional. 76 BootDevice bool `json:"bootdevice,omitempty"` 77} 78 79//ServerStorageRelationUpdateRequest JSON struct of a request for updating a relation between a server and a storage 80type ServerStorageRelationUpdateRequest struct { 81 //The ordering of the network interfaces. Lower numbers have lower PCI-IDs. Optional. 82 Ordering int `json:"ordering,omitempty"` 83 84 //Whether the server boots from this network or not. Optional. 85 BootDevice bool `json:"bootdevice,omitempty"` 86 87 //Defines information about IP prefix spoof protection (it allows source traffic only from the IPv4/IPv4 network prefixes). 88 //If empty, it allow no IPv4/IPv6 source traffic. If set to null, l3security is disabled (default). Optional. 89 L3security []string `json:"l3security,omitempty"` 90} 91 92//GetServerStorageList gets a list of a specific server's storages 93// 94//See: https://gridscale.io/en//api-documentation/index.html#operation/getServerLinkedStorages 95func (c *Client) GetServerStorageList(ctx context.Context, id string) ([]ServerStorageRelationProperties, error) { 96 if !isValidUUID(id) { 97 return nil, errors.New("'id' is invalid") 98 } 99 r := gsRequest{ 100 uri: path.Join(apiServerBase, id, "storages"), 101 method: http.MethodGet, 102 skipCheckingRequest: true, 103 } 104 var response ServerStorageRelationList 105 err := r.execute(ctx, *c, &response) 106 return response.List, err 107} 108 109//GetServerStorage gets a storage of a specific server 110// 111//See: https://gridscale.io/en//api-documentation/index.html#operation/getServerLinkedStorage 112func (c *Client) GetServerStorage(ctx context.Context, serverID, storageID string) (ServerStorageRelationProperties, error) { 113 if !isValidUUID(serverID) || !isValidUUID(storageID) { 114 return ServerStorageRelationProperties{}, errors.New("'serverID' or 'storageID' is invalid") 115 } 116 r := gsRequest{ 117 uri: path.Join(apiServerBase, serverID, "storages", storageID), 118 method: http.MethodGet, 119 skipCheckingRequest: true, 120 } 121 var response ServerStorageRelationSingle 122 err := r.execute(ctx, *c, &response) 123 return response.Properties, err 124} 125 126//UpdateServerStorage updates a link between a storage and a server 127// 128//See: https://gridscale.io/en//api-documentation/index.html#operation/updateServerLinkedStorage 129func (c *Client) UpdateServerStorage(ctx context.Context, serverID, storageID string, body ServerStorageRelationUpdateRequest) error { 130 if !isValidUUID(serverID) || !isValidUUID(storageID) { 131 return errors.New("'serverID' or 'storageID' is invalid") 132 } 133 r := gsRequest{ 134 uri: path.Join(apiServerBase, serverID, "storages", storageID), 135 method: http.MethodPatch, 136 body: body, 137 } 138 return r.execute(ctx, *c, nil) 139} 140 141//CreateServerStorage create a link between a server and a storage 142// 143//See: https://gridscale.io/en//api-documentation/index.html#operation/linkStorageToServer 144func (c *Client) CreateServerStorage(ctx context.Context, id string, body ServerStorageRelationCreateRequest) error { 145 if !isValidUUID(id) || !isValidUUID(body.ObjectUUID) { 146 return errors.New("'server_id' or 'storage_id' is invalid") 147 } 148 r := gsRequest{ 149 uri: path.Join(apiServerBase, id, "storages"), 150 method: http.MethodPost, 151 body: body, 152 } 153 return r.execute(ctx, *c, nil) 154} 155 156//DeleteServerStorage delete a link between a storage and a server 157// 158//See: https://gridscale.io/en//api-documentation/index.html#operation/unlinkStorageFromServer 159func (c *Client) DeleteServerStorage(ctx context.Context, serverID, storageID string) error { 160 if !isValidUUID(serverID) || !isValidUUID(storageID) { 161 return errors.New("'serverID' or 'storageID' is invalid") 162 } 163 r := gsRequest{ 164 uri: path.Join(apiServerBase, serverID, "storages", storageID), 165 method: http.MethodDelete, 166 } 167 return r.execute(ctx, *c, nil) 168} 169 170//LinkStorage attaches a storage to a server 171func (c *Client) LinkStorage(ctx context.Context, serverID string, storageID string, bootdevice bool) error { 172 body := ServerStorageRelationCreateRequest{ 173 ObjectUUID: storageID, 174 BootDevice: bootdevice, 175 } 176 return c.CreateServerStorage(ctx, serverID, body) 177} 178 179//UnlinkStorage remove a storage from a server 180func (c *Client) UnlinkStorage(ctx context.Context, serverID string, storageID string) error { 181 return c.DeleteServerStorage(ctx, serverID, storageID) 182} 183