blob: 39703736b006acef422cc6dadc014af936ad49ce [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
22}
23
24// newFakequinix makes a fakequinix with a given fake project ID and number of
25// hardware reservations to create.
26func newFakequinix(pid string, numReservations int) *fakequinix {
27 f := fakequinix{
28 pid: pid,
29 devices: make(map[string]*packngo.Device),
30 reservations: make(map[string]*packngo.HardwareReservation),
31 sshKeys: make(map[string]*packngo.SSHKey),
32 }
33
34 for i := 0; i < numReservations; i++ {
35 uid := uuid.New()
36 f.reservations[uid.String()] = &packngo.HardwareReservation{
37 ID: uid.String(),
38 ShortID: uid.String(),
39 Provisionable: true,
40 }
41 }
42
43 return &f
44}
45
46func (f *fakequinix) notFound() error {
47 return &packngo.ErrorResponse{
48 Response: &http.Response{
49 StatusCode: http.StatusNotFound,
50 },
51 }
52}
53
54func (f *fakequinix) GetDevice(_ context.Context, pid, did string) (*packngo.Device, error) {
55 f.mu.Lock()
56 defer f.mu.Unlock()
57
58 if pid != f.pid {
59 return nil, f.notFound()
60 }
61 val := f.devices[did]
62 if val == nil {
63 return nil, f.notFound()
64 }
65 return val, nil
66}
67
68func (f *fakequinix) ListDevices(_ context.Context, pid string) ([]packngo.Device, error) {
69 f.mu.Lock()
70 defer f.mu.Unlock()
71
72 if pid != f.pid {
73 return nil, nil
74 }
75 var res []packngo.Device
76 for _, dev := range f.devices {
77 res = append(res, *dev)
78 }
79 return res, nil
80}
81
82func (f *fakequinix) CreateDevice(_ context.Context, request *packngo.DeviceCreateRequest) (*packngo.Device, error) {
83 f.mu.Lock()
84 defer f.mu.Unlock()
85
86 rid := request.HardwareReservationID
87 res := f.reservations[rid]
88 if res == nil {
89 return nil, f.notFound()
90 }
91 if res.Device != nil {
92 return nil, f.notFound()
93 }
94
95 dev := &packngo.Device{
96 ID: uuid.New().String(),
97 State: "very fake",
98 Hostname: request.Hostname,
99 OS: &packngo.OS{
100 Name: request.OS,
101 Slug: request.OS,
102 },
103 }
104 res.Device = dev
105 res.Provisionable = false
106
107 f.devices[dev.ID] = dev
108 return dev, nil
109}
110
111func (f *fakequinix) ListReservations(_ context.Context, pid string) ([]packngo.HardwareReservation, error) {
112 f.mu.Lock()
113 defer f.mu.Unlock()
114
115 var res []packngo.HardwareReservation
116 for _, r := range f.reservations {
117 res = append(res, *r)
118 }
119
120 return res, nil
121}
122
123func (f *fakequinix) ListSSHKeys(_ context.Context) ([]packngo.SSHKey, error) {
124 f.mu.Lock()
125 defer f.mu.Unlock()
126
127 var res []packngo.SSHKey
128 for _, key := range f.sshKeys {
129 res = append(res, *key)
130 }
131
132 return res, nil
133}
134
135func (f *fakequinix) CreateSSHKey(_ context.Context, req *packngo.SSHKeyCreateRequest) (*packngo.SSHKey, error) {
136 f.mu.Lock()
137 defer f.mu.Unlock()
138
139 for _, k := range f.sshKeys {
140 if k.Key == req.Key {
141 return nil, f.notFound()
142 }
143 if k.Label == req.Label {
144 return nil, f.notFound()
145 }
146 }
147
148 uid := uuid.New().String()
149 f.sshKeys[uid] = &packngo.SSHKey{
150 ID: uid,
151 Label: req.Label,
152 Key: req.Key,
153 }
154
155 return f.sshKeys[uid], nil
156}
157
158func (f *fakequinix) UpdateSSHKey(_ context.Context, kid string, req *packngo.SSHKeyUpdateRequest) (*packngo.SSHKey, error) {
159 f.mu.Lock()
160 defer f.mu.Unlock()
161
162 key := f.sshKeys[kid]
163 if key == nil {
164 return nil, f.notFound()
165 }
166 key.Key = *req.Key
167
168 return key, nil
169}
170
171func (f *fakequinix) Close() {
172}