1package gsclient
2
3import (
4	"context"
5	"errors"
6	"net/http"
7	"path"
8)
9
10// SSHKeyOperator provides an interface for operations on SSH keys.
11type SSHKeyOperator interface {
12	GetSshkey(ctx context.Context, id string) (Sshkey, error)
13	GetSshkeyList(ctx context.Context) ([]Sshkey, error)
14	CreateSshkey(ctx context.Context, body SshkeyCreateRequest) (CreateResponse, error)
15	DeleteSshkey(ctx context.Context, id string) error
16	UpdateSshkey(ctx context.Context, id string, body SshkeyUpdateRequest) error
17	GetSshkeyEventList(ctx context.Context, id string) ([]Event, error)
18}
19
20// SshkeyList holds a list of SSH keys.
21type SshkeyList struct {
22	// Array of SSH keys.
23	List map[string]SshkeyProperties `json:"sshkeys"`
24}
25
26// Sshkey represents a single SSH key.
27type Sshkey struct {
28	// Properties of a SSH key.
29	Properties SshkeyProperties `json:"sshkey"`
30}
31
32// SshkeyProperties holds properties of a single SSH key.
33// A SSH key can be retrieved when creating new storages and attaching them to
34// servers.
35type SshkeyProperties struct {
36	// The human-readable name of the object. It supports the full UTF-8 character set, with a maximum of 64 characters.
37	Name string `json:"name"`
38
39	// The UUID of an object is always unique, and refers to a specific object.
40	ObjectUUID string `json:"object_uuid"`
41
42	// Status indicates the status of the object.
43	Status string `json:"status"`
44
45	// Defines the date and time the object was initially created.
46	CreateTime GSTime `json:"create_time"`
47
48	// Defines the date and time of the last object change.
49	ChangeTime GSTime `json:"change_time"`
50
51	// The OpenSSH public key string (all key types are supported => ed25519, ecdsa, dsa, rsa, rsa1).
52	Sshkey string `json:"sshkey"`
53
54	// List of labels.
55	Labels []string `json:"labels"`
56
57	// The User-UUID of the account which created this SSH Key.
58	UserUUID string `json:"user_uuid"`
59}
60
61// SshkeyCreateRequest represents a request for creating a SSH key.
62type SshkeyCreateRequest struct {
63	// The human-readable name of the object. It supports the full UTF-8 character set, with a maximum of 64 characters.
64	Name string `json:"name"`
65
66	// The OpenSSH public key string (all key types are supported => ed25519, ecdsa, dsa, rsa, rsa1).
67	Sshkey string `json:"sshkey"`
68
69	// List of labels. Optional.
70	Labels []string `json:"labels,omitempty"`
71}
72
73// SshkeyUpdateRequest represents a request for updating a SSH key.
74type SshkeyUpdateRequest struct {
75	// The human-readable name of the object. It supports the full UTF-8 character set, with a maximum of 64 characters.
76	// Optional.
77	Name string `json:"name,omitempty"`
78
79	// The OpenSSH public key string (all key types are supported => ed25519, ecdsa, dsa, rsa, rsa1). Optional.
80	Sshkey string `json:"sshkey,omitempty"`
81
82	// List of labels. Optional.
83	Labels *[]string `json:"labels,omitempty"`
84}
85
86// GetSshkey gets a single SSH key object.
87//
88// See: https://gridscale.io/en//api-documentation/index.html#operation/getSshKey
89func (c *Client) GetSshkey(ctx context.Context, id string) (Sshkey, error) {
90	if !isValidUUID(id) {
91		return Sshkey{}, errors.New("'id' is invalid")
92	}
93	r := gsRequest{
94		uri:                 path.Join(apiSshkeyBase, id),
95		method:              http.MethodGet,
96		skipCheckingRequest: true,
97	}
98	var response Sshkey
99	err := r.execute(ctx, *c, &response)
100	return response, err
101}
102
103// GetSshkeyList gets the list of SSH keys in the project.
104//
105// See: https://gridscale.io/en//api-documentation/index.html#operation/getSshKeys
106func (c *Client) GetSshkeyList(ctx context.Context) ([]Sshkey, error) {
107	r := gsRequest{
108		uri:                 apiSshkeyBase,
109		method:              http.MethodGet,
110		skipCheckingRequest: true,
111	}
112
113	var response SshkeyList
114	var sshKeys []Sshkey
115	err := r.execute(ctx, *c, &response)
116	for _, properties := range response.List {
117		sshKeys = append(sshKeys, Sshkey{Properties: properties})
118	}
119	return sshKeys, err
120}
121
122// CreateSshkey creates a new SSH key.
123//
124// See: https://gridscale.io/en//api-documentation/index.html#operation/createSshKey
125func (c *Client) CreateSshkey(ctx context.Context, body SshkeyCreateRequest) (CreateResponse, error) {
126	r := gsRequest{
127		uri:    apiSshkeyBase,
128		method: "POST",
129		body:   body,
130	}
131	var response CreateResponse
132	err := r.execute(ctx, *c, &response)
133	return response, err
134}
135
136// DeleteSshkey removes a single SSH key.
137//
138// See: https://gridscale.io/en//api-documentation/index.html#operation/deleteSshKey
139func (c *Client) DeleteSshkey(ctx context.Context, id string) error {
140	if !isValidUUID(id) {
141		return errors.New("'id' is invalid")
142	}
143	r := gsRequest{
144		uri:    path.Join(apiSshkeyBase, id),
145		method: http.MethodDelete,
146	}
147	return r.execute(ctx, *c, nil)
148}
149
150// UpdateSshkey updates a SSH key.
151//
152// See: https://gridscale.io/en//api-documentation/index.html#operation/updateSshKey
153func (c *Client) UpdateSshkey(ctx context.Context, id string, body SshkeyUpdateRequest) error {
154	if !isValidUUID(id) {
155		return errors.New("'id' is invalid")
156	}
157	r := gsRequest{
158		uri:    path.Join(apiSshkeyBase, id),
159		method: http.MethodPatch,
160		body:   body,
161	}
162	return r.execute(ctx, *c, nil)
163}
164
165// GetSshkeyEventList gets a SSH key's events.
166//
167// See: https://gridscale.io/en//api-documentation/index.html#operation/getSshKeyEvents
168func (c *Client) GetSshkeyEventList(ctx context.Context, id string) ([]Event, error) {
169	if !isValidUUID(id) {
170		return nil, errors.New("'id' is invalid")
171	}
172	r := gsRequest{
173		uri:                 path.Join(apiSshkeyBase, id, "events"),
174		method:              http.MethodGet,
175		skipCheckingRequest: true,
176	}
177	var response EventList
178	var sshEvents []Event
179	err := r.execute(ctx, *c, &response)
180	for _, properties := range response.List {
181		sshEvents = append(sshEvents, Event{Properties: properties})
182	}
183	return sshEvents, err
184}
185