blob: 62892cc0e78a1e273a57ba1a3f2ae85cd8e238ac [file] [log] [blame]
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +02001package main
Serge Bazanskicaa12082023-02-16 14:54:04 +01002
3import (
4 "context"
Tim Windelschmidt72a903f2023-06-27 15:49:36 +02005 "fmt"
Serge Bazanskicaa12082023-02-16 14:54:04 +01006 "net/http"
7 "sync"
8
9 "github.com/google/uuid"
10 "github.com/packethost/packngo"
11)
12
13// fakequinix implements a wrapngo.Client for testing. It starts out with a
14// number of made up hardware reservations, and allows for creating devices and
15// SSH keys.
16type fakequinix struct {
17 mu sync.Mutex
18
19 pid string
20 devices map[string]*packngo.Device
21 reservations map[string]*packngo.HardwareReservation
22 sshKeys map[string]*packngo.SSHKey
Serge Bazanskiae004682023-04-18 13:28:48 +020023 reboots map[string]int
Serge Bazanskicaa12082023-02-16 14:54:04 +010024}
25
Tim Windelschmidtde12c7e2024-04-25 18:00:40 +020026func (f *fakequinix) ListOrganizationReservations(ctx context.Context, oid string) ([]packngo.HardwareReservation, error) {
27 return nil, fmt.Errorf("not implemented")
28}
29
Serge Bazanskicaa12082023-02-16 14:54:04 +010030// newFakequinix makes a fakequinix with a given fake project ID and number of
31// hardware reservations to create.
32func newFakequinix(pid string, numReservations int) *fakequinix {
33 f := fakequinix{
34 pid: pid,
35 devices: make(map[string]*packngo.Device),
36 reservations: make(map[string]*packngo.HardwareReservation),
37 sshKeys: make(map[string]*packngo.SSHKey),
Serge Bazanskiae004682023-04-18 13:28:48 +020038 reboots: make(map[string]int),
Serge Bazanskicaa12082023-02-16 14:54:04 +010039 }
40
41 for i := 0; i < numReservations; i++ {
42 uid := uuid.New()
43 f.reservations[uid.String()] = &packngo.HardwareReservation{
44 ID: uid.String(),
45 ShortID: uid.String(),
46 Provisionable: true,
47 }
48 }
49
50 return &f
51}
52
53func (f *fakequinix) notFound() error {
54 return &packngo.ErrorResponse{
55 Response: &http.Response{
56 StatusCode: http.StatusNotFound,
57 },
58 }
59}
60
Serge Bazanski4969fd72023-04-19 17:43:12 +020061func (f *fakequinix) GetDevice(_ context.Context, pid, did string, _ *packngo.ListOptions) (*packngo.Device, error) {
Serge Bazanskicaa12082023-02-16 14:54:04 +010062 f.mu.Lock()
63 defer f.mu.Unlock()
64
Serge Bazanskicaa12082023-02-16 14:54:04 +010065 val := f.devices[did]
66 if val == nil {
67 return nil, f.notFound()
68 }
69 return val, nil
70}
71
72func (f *fakequinix) ListDevices(_ context.Context, pid string) ([]packngo.Device, error) {
73 f.mu.Lock()
74 defer f.mu.Unlock()
75
76 if pid != f.pid {
77 return nil, nil
78 }
79 var res []packngo.Device
80 for _, dev := range f.devices {
81 res = append(res, *dev)
82 }
83 return res, nil
84}
85
Tim Windelschmidt72a903f2023-06-27 15:49:36 +020086func (f *fakequinix) UpdateDevice(ctx context.Context, id string, r *packngo.DeviceUpdateRequest) (*packngo.Device, error) {
87 return nil, fmt.Errorf("not implemented")
88}
89
Tim Windelschmidt8180de92023-05-11 19:45:37 +020090// MoveReservation is not implemented in fakequinix
91func (f *fakequinix) MoveReservation(_ context.Context, hardwareReservationDID, projectID string) (*packngo.HardwareReservation, error) {
92 return nil, &packngo.ErrorResponse{
93 Response: &http.Response{
94 StatusCode: http.StatusNotImplemented,
95 },
96 }
97}
98
99func (f *fakequinix) DeleteDevice(_ context.Context, id string) error {
100 f.mu.Lock()
101 defer f.mu.Unlock()
102
103 if _, ok := f.devices[id]; !ok {
104 return f.notFound()
105 }
106
107 delete(f.devices, id)
108
109 return nil
110}
111
Serge Bazanskicaa12082023-02-16 14:54:04 +0100112func (f *fakequinix) CreateDevice(_ context.Context, request *packngo.DeviceCreateRequest) (*packngo.Device, error) {
113 f.mu.Lock()
114 defer f.mu.Unlock()
115
116 rid := request.HardwareReservationID
117 res := f.reservations[rid]
118 if res == nil {
119 return nil, f.notFound()
120 }
121 if res.Device != nil {
122 return nil, f.notFound()
123 }
124
125 dev := &packngo.Device{
Serge Bazanskiafd3cf82023-04-19 17:43:46 +0200126 ID: uuid.New().String(),
127 State: "active",
128 HardwareReservation: &packngo.HardwareReservation{
129 ID: rid,
130 },
131 Network: []*packngo.IPAddressAssignment{
132 {
133 IpAddressCommon: packngo.IpAddressCommon{
134 Public: true,
135 Address: "1.2.3.4",
136 },
137 },
138 },
139 Facility: &packngo.Facility{
140 Code: "wad",
141 },
Serge Bazanskicaa12082023-02-16 14:54:04 +0100142 Hostname: request.Hostname,
143 OS: &packngo.OS{
144 Name: request.OS,
145 Slug: request.OS,
146 },
147 }
148 res.Device = dev
149 res.Provisionable = false
150
151 f.devices[dev.ID] = dev
152 return dev, nil
153}
154
155func (f *fakequinix) ListReservations(_ context.Context, pid string) ([]packngo.HardwareReservation, error) {
156 f.mu.Lock()
157 defer f.mu.Unlock()
158
159 var res []packngo.HardwareReservation
160 for _, r := range f.reservations {
161 res = append(res, *r)
162 }
163
164 return res, nil
165}
166
167func (f *fakequinix) ListSSHKeys(_ context.Context) ([]packngo.SSHKey, error) {
168 f.mu.Lock()
169 defer f.mu.Unlock()
170
171 var res []packngo.SSHKey
172 for _, key := range f.sshKeys {
173 res = append(res, *key)
174 }
175
176 return res, nil
177}
178
179func (f *fakequinix) CreateSSHKey(_ context.Context, req *packngo.SSHKeyCreateRequest) (*packngo.SSHKey, error) {
180 f.mu.Lock()
181 defer f.mu.Unlock()
182
183 for _, k := range f.sshKeys {
184 if k.Key == req.Key {
185 return nil, f.notFound()
186 }
187 if k.Label == req.Label {
188 return nil, f.notFound()
189 }
190 }
191
192 uid := uuid.New().String()
193 f.sshKeys[uid] = &packngo.SSHKey{
194 ID: uid,
195 Label: req.Label,
196 Key: req.Key,
197 }
198
199 return f.sshKeys[uid], nil
200}
201
202func (f *fakequinix) UpdateSSHKey(_ context.Context, kid string, req *packngo.SSHKeyUpdateRequest) (*packngo.SSHKey, error) {
203 f.mu.Lock()
204 defer f.mu.Unlock()
205
206 key := f.sshKeys[kid]
207 if key == nil {
208 return nil, f.notFound()
209 }
210 key.Key = *req.Key
211
212 return key, nil
213}
214
Serge Bazanskiae004682023-04-18 13:28:48 +0200215func (f *fakequinix) RebootDevice(_ context.Context, did string) error {
216 f.mu.Lock()
217 defer f.mu.Unlock()
218
219 f.reboots[did]++
220
221 return nil
222}
223
Serge Bazanskicaa12082023-02-16 14:54:04 +0100224func (f *fakequinix) Close() {
225}