Skip to content

Commit bb88535

Browse files
committed
Hookup disk and nic creation on instance create
1 parent 679e9c3 commit bb88535

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

libs/api-mocks/msw/handlers.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
import {
3232
NotImplemented,
3333
errIfExists,
34+
errIfInvalidDiskSize,
3435
getStartAndEndTime,
3536
getTimestamps,
3637
paginated,
@@ -156,6 +157,7 @@ export const handlers = makeHandlers({
156157
const project = lookupProject(params.path)
157158

158159
errIfExists(db.disks, { name: body.name, project_id: project.id })
160+
errIfInvalidDiskSize(params.path, body)
159161

160162
const { name, description, size, disk_source } = body
161163
const newDisk: Json<Api.Disk> = {
@@ -243,8 +245,69 @@ export const handlers = makeHandlers({
243245

244246
errIfExists(db.instances, { name: body.name, project_id: project.id })
245247

248+
const instanceId = uuid()
249+
250+
for (const diskParams of body.disks || []) {
251+
if (diskParams.type === 'create') {
252+
errIfExists(db.disks, { name: diskParams.name, project_id: project.id })
253+
errIfInvalidDiskSize(params.path, diskParams)
254+
const { size, name, description, disk_source } = diskParams
255+
const newDisk: Json<Api.Disk> = {
256+
id: uuid(),
257+
name,
258+
description,
259+
size,
260+
project_id: project.id,
261+
state: { state: 'attached', instance: instanceId },
262+
device_path: '/mnt/disk',
263+
block_size: disk_source.type === 'blank' ? disk_source.block_size : 4096,
264+
...getTimestamps(),
265+
}
266+
db.disks.push(newDisk)
267+
} else {
268+
const disk = lookupDisk({ ...params.path, diskName: diskParams.name })
269+
disk.state = { state: 'attached', instance: instanceId }
270+
}
271+
}
272+
273+
if (body.network_interfaces?.type === 'default') {
274+
db.networkInterfaces.push({
275+
id: uuid(),
276+
description: 'The default network interface',
277+
instance_id: instanceId,
278+
primary: true,
279+
mac: '00:00:00:00:00:00',
280+
ip: '127.0.0.1',
281+
name: 'default',
282+
vpc_id: uuid(),
283+
subnet_id: uuid(),
284+
...getTimestamps(),
285+
})
286+
} else if (body.network_interfaces?.type === 'create') {
287+
body.network_interfaces.params.forEach(
288+
({ name, description, ip, subnet_name, vpc_name }, i) => {
289+
db.networkInterfaces.push({
290+
id: uuid(),
291+
name,
292+
description,
293+
instance_id: instanceId,
294+
primary: i === 0 ? true : false,
295+
mac: '00:00:00:00:00:00',
296+
ip: ip || '127.0.0.1',
297+
vpc_id: lookupVpc({ ...params.path, vpcName: vpc_name }).id,
298+
subnet_id: lookupVpcSubnet({
299+
...params.path,
300+
vpcName: vpc_name,
301+
subnetName: subnet_name,
302+
}).id,
303+
...getTimestamps(),
304+
})
305+
}
306+
)
307+
}
308+
246309
const newInstance: Json<Api.Instance> = {
247-
id: uuid(),
310+
id: instanceId,
248311
project_id: project.id,
249312
...pick(body, 'name', 'description', 'hostname', 'memory', 'ncpus'),
250313
...getTimestamps(),

libs/api-mocks/msw/util.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { subHours } from 'date-fns'
22

3+
import type { DiskCreate, DiskCreatePathParams } from '@oxide/gen/Api'
4+
import type { Json } from '@oxide/gen/msw-handlers'
35
import { json } from '@oxide/gen/msw-handlers'
6+
import { GiB } from '@oxide/util'
7+
8+
import { db } from './db'
49

510
export { json } from '@oxide/gen/msw-handlers'
611

@@ -86,3 +91,30 @@ export const errIfExists = <T extends Record<string, unknown>>(
8691
throw json({ error_code: 'ObjectAlreadyExists' }, { status: 400 })
8792
}
8893
}
94+
95+
export const errIfInvalidDiskSize = (
96+
params: DiskCreatePathParams,
97+
disk: Json<DiskCreate>
98+
) => {
99+
const source = disk.disk_source
100+
if (source.type === 'snapshot') {
101+
const snapshotSize = db.snapshots.find((s) => source.snapshot_id === s.id)?.size ?? 0
102+
if (disk.size >= snapshotSize) return
103+
throw 'Disk size must be greater than or equal to the snapshot size'
104+
}
105+
if (source.type === 'image') {
106+
const imageSize = db.images.find((i) => source.image_id === i.id)?.size ?? 0
107+
if (disk.size >= imageSize) return
108+
throw 'Disk size must be greater than or equal to the image size'
109+
}
110+
if (source.type === 'global_image') {
111+
const globalImageSize = db.globalImages.find((i) => source.image_id === i.id)?.size ?? 0
112+
if (disk.size >= globalImageSize) return
113+
throw 'Disk size must be greater than or equal to the global image size'
114+
}
115+
if (source.type === 'blank') {
116+
if (disk.size >= 1 * GiB) return
117+
// TODO: this is a bit arbitrary, should match whatever the API does
118+
throw 'Minimum disk size is 1 GiB'
119+
}
120+
}

0 commit comments

Comments
 (0)