1package gsclient
2
3import (
4	"context"
5	"errors"
6	"net/http"
7	"path"
8)
9
10// ServerIsoImageRelationOperator provides an interface for operations on server-ISO image relations.
11type ServerIsoImageRelationOperator interface {
12	GetServerIsoImageList(ctx context.Context, id string) ([]ServerIsoImageRelationProperties, error)
13	GetServerIsoImage(ctx context.Context, serverID, isoImageID string) (ServerIsoImageRelationProperties, error)
14	CreateServerIsoImage(ctx context.Context, id string, body ServerIsoImageRelationCreateRequest) error
15	UpdateServerIsoImage(ctx context.Context, serverID, isoImageID string, body ServerIsoImageRelationUpdateRequest) error
16	DeleteServerIsoImage(ctx context.Context, serverID, isoImageID string) error
17	LinkIsoImage(ctx context.Context, serverID string, isoimageID string) error
18	UnlinkIsoImage(ctx context.Context, serverID string, isoimageID string) error
19}
20
21// ServerIsoImageRelationList holds a list of relations between a server and ISO images.
22type ServerIsoImageRelationList struct {
23	// Array of relations between a server and ISO images.
24	List []ServerIsoImageRelationProperties `json:"isoimage_relations"`
25}
26
27// ServerIsoImageRelation represents a single relation between a server and an ISO image.
28type ServerIsoImageRelation struct {
29	// Properties of a relation between a server and an ISO image.
30	Properties ServerIsoImageRelationProperties `json:"isoimage_relation"`
31}
32
33// ServerIsoImageRelationProperties holds properties of a relation between a server and an ISO image.
34type ServerIsoImageRelationProperties struct {
35	// The UUID of an object is always unique, and refers to a specific object.
36	ObjectUUID string `json:"object_uuid"`
37
38	// The human-readable name of the object. It supports the full UTF-8 character set, with a maximum of 64 characters.
39	ObjectName string `json:"object_name"`
40
41	// Whether the ISO image is private or not.
42	Private bool `json:"private"`
43
44	// Defines the date and time the object was initially created.
45	CreateTime GSTime `json:"create_time"`
46
47	// Whether the server boots from this iso image or not.
48	Bootdevice bool `json:"bootdevice"`
49}
50
51// ServerIsoImageRelationCreateRequest represents a request for creating a relation between a server and an ISO image.
52type ServerIsoImageRelationCreateRequest struct {
53	// The UUID of the ISO-image you are requesting.
54	ObjectUUID string `json:"object_uuid"`
55}
56
57// ServerIsoImageRelationUpdateRequest represents a request for updating a relation between a server and an ISO image.
58type ServerIsoImageRelationUpdateRequest struct {
59	// Whether the server boots from this ISO-image or not.
60	BootDevice bool   `json:"bootdevice"`
61	Name       string `json:"name"`
62}
63
64// GetServerIsoImageList gets a list of a specific server's ISO images.
65//
66// See: https://gridscale.io/en//api-documentation/index.html#operation/getServerLinkedIsoimages
67func (c *Client) GetServerIsoImageList(ctx context.Context, id string) ([]ServerIsoImageRelationProperties, error) {
68	if !isValidUUID(id) {
69		return nil, errors.New("'id' is invalid")
70	}
71	r := gsRequest{
72		uri:                 path.Join(apiServerBase, id, "isoimages"),
73		method:              http.MethodGet,
74		skipCheckingRequest: true,
75	}
76	var response ServerIsoImageRelationList
77	err := r.execute(ctx, *c, &response)
78	return response.List, err
79}
80
81// GetServerIsoImage gets an ISO image of a specific server.
82//
83// See: https://gridscale.io/en//api-documentation/index.html#operation/getServerLinkedIsoimage
84func (c *Client) GetServerIsoImage(ctx context.Context, serverID, isoImageID string) (ServerIsoImageRelationProperties, error) {
85	if !isValidUUID(serverID) || !isValidUUID(isoImageID) {
86		return ServerIsoImageRelationProperties{}, errors.New("'id' is invalid")
87	}
88	r := gsRequest{
89		uri:                 path.Join(apiServerBase, serverID, "isoimages", isoImageID),
90		method:              http.MethodGet,
91		skipCheckingRequest: true,
92	}
93	var response ServerIsoImageRelation
94	err := r.execute(ctx, *c, &response)
95	return response.Properties, err
96}
97
98// UpdateServerIsoImage updates a link between a storage and an ISO image.
99//
100// See: https://gridscale.io/en//api-documentation/index.html#operation/updateServerLinkedIsoimage
101func (c *Client) UpdateServerIsoImage(ctx context.Context, serverID, isoImageID string, body ServerIsoImageRelationUpdateRequest) error {
102	if !isValidUUID(serverID) || !isValidUUID(isoImageID) {
103		return errors.New("'serverID' or 'isoImageID' is invalid")
104	}
105	r := gsRequest{
106		uri:    path.Join(apiServerBase, serverID, "isoimages", isoImageID),
107		method: http.MethodPatch,
108		body:   body,
109	}
110	return r.execute(ctx, *c, nil)
111}
112
113// CreateServerIsoImage creates a link between a server and an ISO image.
114//
115// See: https://gridscale.io/en//api-documentation/index.html#operation/linkIsoimageToServer
116func (c *Client) CreateServerIsoImage(ctx context.Context, id string, body ServerIsoImageRelationCreateRequest) error {
117	if !isValidUUID(id) || !isValidUUID(body.ObjectUUID) {
118		return errors.New("'serverID' or 'isoImageID' is invalid")
119	}
120	r := gsRequest{
121		uri:    path.Join(apiServerBase, id, "isoimages"),
122		method: http.MethodPost,
123		body:   body,
124	}
125	return r.execute(ctx, *c, nil)
126}
127
128// DeleteServerIsoImage removes a link between an ISO image and a server.
129//
130// See: https://gridscale.io/en//api-documentation/index.html#operation/unlinkIsoimageFromServer
131func (c *Client) DeleteServerIsoImage(ctx context.Context, serverID, isoImageID string) error {
132	if !isValidUUID(serverID) || !isValidUUID(isoImageID) {
133		return errors.New("'serverID' or 'isoImageID' is invalid")
134	}
135	r := gsRequest{
136		uri:    path.Join(apiServerBase, serverID, "isoimages", isoImageID),
137		method: http.MethodDelete,
138	}
139	return r.execute(ctx, *c, nil)
140}
141
142// LinkIsoImage attaches an ISO image to a server.
143func (c *Client) LinkIsoImage(ctx context.Context, serverID string, isoimageID string) error {
144	body := ServerIsoImageRelationCreateRequest{
145		ObjectUUID: isoimageID,
146	}
147	return c.CreateServerIsoImage(ctx, serverID, body)
148}
149
150// UnlinkIsoImage detaches an ISO image from a server.
151func (c *Client) UnlinkIsoImage(ctx context.Context, serverID string, isoimageID string) error {
152	return c.DeleteServerIsoImage(ctx, serverID, isoimageID)
153}
154