blob: d9e56839c7309c0f7fcf119630938157663568d6 [file] [log] [blame]
Serge Bazanskicaa12082023-02-16 14:54:04 +01001package manager
2
3import (
4 "context"
5 "net/http"
6 "sync"
7
8 "github.com/google/uuid"
9 "github.com/packethost/packngo"
10)
11
12// fakequinix implements a wrapngo.Client for testing. It starts out with a
13// number of made up hardware reservations, and allows for creating devices and
14// SSH keys.
15type fakequinix struct {
16 mu sync.Mutex
17
18 pid string
19 devices map[string]*packngo.Device
20 reservations map[string]*packngo.HardwareReservation
21 sshKeys map[string]*packngo.SSHKey
Serge Bazanskiae004682023-04-18 13:28:48 +020022 reboots map[string]int
Serge Bazanskicaa12082023-02-16 14:54:04 +010023}
24
25// newFakequinix makes a fakequinix with a given fake project ID and number of
26// hardware reservations to create.
27func newFakequinix(pid string, numReservations int) *fakequinix {
28 f := fakequinix{
29 pid: pid,
30 devices: make(map[string]*packngo.Device),
31 reservations: make(map[string]*packngo.HardwareReservation),
32 sshKeys: make(map[string]*packngo.SSHKey),
Serge Bazanskiae004682023-04-18 13:28:48 +020033 reboots: make(map[string]int),
Serge Bazanskicaa12082023-02-16 14:54:04 +010034 }
35
36 for i := 0; i < numReservations; i++ {
37 uid := uuid.New()
38 f.reservations[uid.String()] = &packngo.HardwareReservation{
39 ID: uid.String(),
40 ShortID: uid.String(),
41 Provisionable: true,
42 }
43 }
44
45 return &f
46}
47
48func (f *fakequinix) notFound() error {
49 return &packngo.ErrorResponse{
50 Response: &http.Response{
51 StatusCode: http.StatusNotFound,
52 },
53 }
54}
55
56func (f *fakequinix) GetDevice(_ context.Context, pid, did string) (*packngo.Device, error) {
57 f.mu.Lock()
58 defer f.mu.Unlock()
59
60 if pid != f.pid {
61 return nil, f.notFound()
62 }
63 val := f.devices[did]
64 if val == nil {
65 return nil, f.notFound()
66 }
67 return val, nil
68}
69
70func (f *fakequinix) ListDevices(_ context.Context, pid string) ([]packngo.Device, error) {
71 f.mu.Lock()
72 defer f.mu.Unlock()
73
74 if pid != f.pid {
75 return nil, nil
76 }
77 var res []packngo.Device
78 for _, dev := range f.devices {
79 res = append(res, *dev)
80 }
81 return res, nil
82}
83
84func (f *fakequinix) CreateDevice(_ context.Context, request *packngo.DeviceCreateRequest) (*packngo.Device, error) {
85 f.mu.Lock()
86 defer f.mu.Unlock()
87
88 rid := request.HardwareReservationID
89 res := f.reservations[rid]
90 if res == nil {
91 return nil, f.notFound()
92 }
93 if res.Device != nil {
94 return nil, f.notFound()
95 }
96
97 dev := &packngo.Device{
98 ID: uuid.New().String(),
99 State: "very fake",
100 Hostname: request.Hostname,
101 OS: &packngo.OS{
102 Name: request.OS,
103 Slug: request.OS,
104 },
105 }
106 res.Device = dev
107 res.Provisionable = false
108
109 f.devices[dev.ID] = dev
110 return dev, nil
111}
112
113func (f *fakequinix) ListReservations(_ context.Context, pid string) ([]packngo.HardwareReservation, error) {
114 f.mu.Lock()
115 defer f.mu.Unlock()
116
117 var res []packngo.HardwareReservation
118 for _, r := range f.reservations {
119 res = append(res, *r)
120 }
121
122 return res, nil
123}
124
125func (f *fakequinix) ListSSHKeys(_ context.Context) ([]packngo.SSHKey, error) {
126 f.mu.Lock()
127 defer f.mu.Unlock()
128
129 var res []packngo.SSHKey
130 for _, key := range f.sshKeys {
131 res = append(res, *key)
132 }
133
134 return res, nil
135}
136
137func (f *fakequinix) CreateSSHKey(_ context.Context, req *packngo.SSHKeyCreateRequest) (*packngo.SSHKey, error) {
138 f.mu.Lock()
139 defer f.mu.Unlock()
140
141 for _, k := range f.sshKeys {
142 if k.Key == req.Key {
143 return nil, f.notFound()
144 }
145 if k.Label == req.Label {
146 return nil, f.notFound()
147 }
148 }
149
150 uid := uuid.New().String()
151 f.sshKeys[uid] = &packngo.SSHKey{
152 ID: uid,
153 Label: req.Label,
154 Key: req.Key,
155 }
156
157 return f.sshKeys[uid], nil
158}
159
160func (f *fakequinix) UpdateSSHKey(_ context.Context, kid string, req *packngo.SSHKeyUpdateRequest) (*packngo.SSHKey, error) {
161 f.mu.Lock()
162 defer f.mu.Unlock()
163
164 key := f.sshKeys[kid]
165 if key == nil {
166 return nil, f.notFound()
167 }
168 key.Key = *req.Key
169
170 return key, nil
171}
172
Serge Bazanskiae004682023-04-18 13:28:48 +0200173func (f *fakequinix) RebootDevice(_ context.Context, did string) error {
174 f.mu.Lock()
175 defer f.mu.Unlock()
176
177 f.reboots[did]++
178
179 return nil
180}
181
Serge Bazanskicaa12082023-02-16 14:54:04 +0100182func (f *fakequinix) Close() {
183}