blob: f18b4359b5d6b20e1e9f01098d2e54c02edfd476 [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
Serge Bazanski4969fd72023-04-19 17:43:12 +020056func (f *fakequinix) GetDevice(_ context.Context, pid, did string, _ *packngo.ListOptions) (*packngo.Device, error) {
Serge Bazanskicaa12082023-02-16 14:54:04 +010057 f.mu.Lock()
58 defer f.mu.Unlock()
59
Serge Bazanskicaa12082023-02-16 14:54:04 +010060 val := f.devices[did]
61 if val == nil {
62 return nil, f.notFound()
63 }
64 return val, nil
65}
66
67func (f *fakequinix) ListDevices(_ context.Context, pid string) ([]packngo.Device, error) {
68 f.mu.Lock()
69 defer f.mu.Unlock()
70
71 if pid != f.pid {
72 return nil, nil
73 }
74 var res []packngo.Device
75 for _, dev := range f.devices {
76 res = append(res, *dev)
77 }
78 return res, nil
79}
80
81func (f *fakequinix) CreateDevice(_ context.Context, request *packngo.DeviceCreateRequest) (*packngo.Device, error) {
82 f.mu.Lock()
83 defer f.mu.Unlock()
84
85 rid := request.HardwareReservationID
86 res := f.reservations[rid]
87 if res == nil {
88 return nil, f.notFound()
89 }
90 if res.Device != nil {
91 return nil, f.notFound()
92 }
93
94 dev := &packngo.Device{
Serge Bazanskiafd3cf82023-04-19 17:43:46 +020095 ID: uuid.New().String(),
96 State: "active",
97 HardwareReservation: &packngo.HardwareReservation{
98 ID: rid,
99 },
100 Network: []*packngo.IPAddressAssignment{
101 {
102 IpAddressCommon: packngo.IpAddressCommon{
103 Public: true,
104 Address: "1.2.3.4",
105 },
106 },
107 },
108 Facility: &packngo.Facility{
109 Code: "wad",
110 },
Serge Bazanskicaa12082023-02-16 14:54:04 +0100111 Hostname: request.Hostname,
112 OS: &packngo.OS{
113 Name: request.OS,
114 Slug: request.OS,
115 },
116 }
117 res.Device = dev
118 res.Provisionable = false
119
120 f.devices[dev.ID] = dev
121 return dev, nil
122}
123
124func (f *fakequinix) ListReservations(_ context.Context, pid string) ([]packngo.HardwareReservation, error) {
125 f.mu.Lock()
126 defer f.mu.Unlock()
127
128 var res []packngo.HardwareReservation
129 for _, r := range f.reservations {
130 res = append(res, *r)
131 }
132
133 return res, nil
134}
135
136func (f *fakequinix) ListSSHKeys(_ context.Context) ([]packngo.SSHKey, error) {
137 f.mu.Lock()
138 defer f.mu.Unlock()
139
140 var res []packngo.SSHKey
141 for _, key := range f.sshKeys {
142 res = append(res, *key)
143 }
144
145 return res, nil
146}
147
148func (f *fakequinix) CreateSSHKey(_ context.Context, req *packngo.SSHKeyCreateRequest) (*packngo.SSHKey, error) {
149 f.mu.Lock()
150 defer f.mu.Unlock()
151
152 for _, k := range f.sshKeys {
153 if k.Key == req.Key {
154 return nil, f.notFound()
155 }
156 if k.Label == req.Label {
157 return nil, f.notFound()
158 }
159 }
160
161 uid := uuid.New().String()
162 f.sshKeys[uid] = &packngo.SSHKey{
163 ID: uid,
164 Label: req.Label,
165 Key: req.Key,
166 }
167
168 return f.sshKeys[uid], nil
169}
170
171func (f *fakequinix) UpdateSSHKey(_ context.Context, kid string, req *packngo.SSHKeyUpdateRequest) (*packngo.SSHKey, error) {
172 f.mu.Lock()
173 defer f.mu.Unlock()
174
175 key := f.sshKeys[kid]
176 if key == nil {
177 return nil, f.notFound()
178 }
179 key.Key = *req.Key
180
181 return key, nil
182}
183
Serge Bazanskiae004682023-04-18 13:28:48 +0200184func (f *fakequinix) RebootDevice(_ context.Context, did string) error {
185 f.mu.Lock()
186 defer f.mu.Unlock()
187
188 f.reboots[did]++
189
190 return nil
191}
192
Serge Bazanskicaa12082023-02-16 14:54:04 +0100193func (f *fakequinix) Close() {
194}