1package linodego
2
3import (
4	"context"
5	"encoding/json"
6	"fmt"
7	"time"
8
9	"github.com/linode/linodego/internal/parseabletime"
10)
11
12// SSHKey represents a SSHKey object
13type SSHKey struct {
14	ID      int        `json:"id"`
15	Label   string     `json:"label"`
16	SSHKey  string     `json:"ssh_key"`
17	Created *time.Time `json:"-"`
18}
19
20// SSHKeyCreateOptions fields are those accepted by CreateSSHKey
21type SSHKeyCreateOptions struct {
22	Label  string `json:"label"`
23	SSHKey string `json:"ssh_key"`
24}
25
26// SSHKeyUpdateOptions fields are those accepted by UpdateSSHKey
27type SSHKeyUpdateOptions struct {
28	Label string `json:"label"`
29}
30
31// UnmarshalJSON implements the json.Unmarshaler interface
32func (i *SSHKey) UnmarshalJSON(b []byte) error {
33	type Mask SSHKey
34
35	p := struct {
36		*Mask
37		Created *parseabletime.ParseableTime `json:"created"`
38	}{
39		Mask: (*Mask)(i),
40	}
41
42	if err := json.Unmarshal(b, &p); err != nil {
43		return err
44	}
45
46	i.Created = (*time.Time)(p.Created)
47
48	return nil
49}
50
51// GetCreateOptions converts a SSHKey to SSHKeyCreateOptions for use in CreateSSHKey
52func (i SSHKey) GetCreateOptions() (o SSHKeyCreateOptions) {
53	o.Label = i.Label
54	o.SSHKey = i.SSHKey
55	return
56}
57
58// GetUpdateOptions converts a SSHKey to SSHKeyCreateOptions for use in UpdateSSHKey
59func (i SSHKey) GetUpdateOptions() (o SSHKeyUpdateOptions) {
60	o.Label = i.Label
61	return
62}
63
64// SSHKeysPagedResponse represents a paginated SSHKey API response
65type SSHKeysPagedResponse struct {
66	*PageOptions
67	Data []SSHKey `json:"data"`
68}
69
70// endpoint gets the endpoint URL for SSHKey
71func (SSHKeysPagedResponse) endpoint(c *Client) string {
72	endpoint, err := c.SSHKeys.Endpoint()
73	if err != nil {
74		panic(err)
75	}
76	return endpoint
77}
78
79// appendData appends SSHKeys when processing paginated SSHKey responses
80func (resp *SSHKeysPagedResponse) appendData(r *SSHKeysPagedResponse) {
81	resp.Data = append(resp.Data, r.Data...)
82}
83
84// ListSSHKeys lists SSHKeys
85func (c *Client) ListSSHKeys(ctx context.Context, opts *ListOptions) ([]SSHKey, error) {
86	response := SSHKeysPagedResponse{}
87	err := c.listHelper(ctx, &response, opts)
88	if err != nil {
89		return nil, err
90	}
91	return response.Data, nil
92}
93
94// GetSSHKey gets the sshkey with the provided ID
95func (c *Client) GetSSHKey(ctx context.Context, id int) (*SSHKey, error) {
96	e, err := c.SSHKeys.Endpoint()
97	if err != nil {
98		return nil, err
99	}
100	e = fmt.Sprintf("%s/%d", e, id)
101	r, err := coupleAPIErrors(c.R(ctx).SetResult(&SSHKey{}).Get(e))
102	if err != nil {
103		return nil, err
104	}
105	return r.Result().(*SSHKey), nil
106}
107
108// CreateSSHKey creates a SSHKey
109func (c *Client) CreateSSHKey(ctx context.Context, createOpts SSHKeyCreateOptions) (*SSHKey, error) {
110	var body string
111	e, err := c.SSHKeys.Endpoint()
112	if err != nil {
113		return nil, err
114	}
115
116	req := c.R(ctx).SetResult(&SSHKey{})
117
118	if bodyData, err := json.Marshal(createOpts); err == nil {
119		body = string(bodyData)
120	} else {
121		return nil, NewError(err)
122	}
123
124	r, err := coupleAPIErrors(req.
125		SetBody(body).
126		Post(e))
127	if err != nil {
128		return nil, err
129	}
130	return r.Result().(*SSHKey), nil
131}
132
133// UpdateSSHKey updates the SSHKey with the specified id
134func (c *Client) UpdateSSHKey(ctx context.Context, id int, updateOpts SSHKeyUpdateOptions) (*SSHKey, error) {
135	var body string
136	e, err := c.SSHKeys.Endpoint()
137	if err != nil {
138		return nil, err
139	}
140	e = fmt.Sprintf("%s/%d", e, id)
141
142	req := c.R(ctx).SetResult(&SSHKey{})
143
144	if bodyData, err := json.Marshal(updateOpts); err == nil {
145		body = string(bodyData)
146	} else {
147		return nil, NewError(err)
148	}
149
150	r, err := coupleAPIErrors(req.
151		SetBody(body).
152		Put(e))
153	if err != nil {
154		return nil, err
155	}
156	return r.Result().(*SSHKey), nil
157}
158
159// DeleteSSHKey deletes the SSHKey with the specified id
160func (c *Client) DeleteSSHKey(ctx context.Context, id int) error {
161	e, err := c.SSHKeys.Endpoint()
162	if err != nil {
163		return err
164	}
165	e = fmt.Sprintf("%s/%d", e, id)
166
167	_, err = coupleAPIErrors(c.R(ctx).Delete(e))
168	return err
169}
170