Skip to content

Commit e0efddf

Browse files
authored
IP pool utilization fixes (#2897)
* unbreak IP pool pages for IPv6 changes * fix e2e tests, stub out version radio on create form * remove version from list and create form * add column IDs for name-derived columns * recombine utilization columns into one * count IPs in pool by... counting IPs in pool * more explicit handling of bigints in mock server, other tweaks * type fix required by type-fest bump
1 parent 33c4c43 commit e0efddf

File tree

15 files changed

+164
-206
lines changed

15 files changed

+164
-206
lines changed

OMICRON_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9577096abb2801be1280c46b323a501ba819b006
1+
1ee118395ed95450274fdde79f322b84c00e252e

app/api/__generated__/Api.ts

Lines changed: 26 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/api/__generated__/OMICRON_VERSION

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/api/__generated__/validate.ts

Lines changed: 18 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/api/util.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import type {
1515
DiskState,
1616
Instance,
1717
InstanceState,
18-
IpPoolUtilization,
1918
Measurement,
2019
SiloUtilization,
2120
Sled,
@@ -281,16 +280,4 @@ export function synthesizeData(
281280
return result
282281
}
283282

284-
// do this by hand instead of getting elaborate in the client generator.
285-
// see https://github.com/oxidecomputer/oxide.ts/pull/231
286-
export function parseIpUtilization({ ipv4, ipv6 }: IpPoolUtilization) {
287-
return {
288-
ipv4,
289-
ipv6: {
290-
allocated: BigInt(ipv6.allocated),
291-
capacity: BigInt(ipv6.capacity),
292-
},
293-
}
294-
}
295-
296283
export const OXQL_GROUP_BY_ERROR = 'Input tables to a `group_by` must be aligned'

app/components/IpPoolUtilization.tsx

Lines changed: 0 additions & 50 deletions
This file was deleted.

app/forms/ip-pool-create.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ import { addToast } from '~/stores/toast'
1919
import { Message } from '~/ui/lib/Message'
2020
import { pb } from '~/util/path-builder'
2121

22+
// We are leaving the v4/v6 radio out for now because while you can
23+
// create a v6 pool, you can't actually add any ranges to it until
24+
// https://github.com/oxidecomputer/omicron/issues/8966
25+
2226
const defaultValues: IpPoolCreate = {
2327
name: '',
2428
description: '',
29+
ipVersion: 'v4',
2530
}
2631

2732
export const handle = titleCrumb('New IP pool')

app/pages/system/networking/IpPoolPage.tsx

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
apiq,
1616
apiQueryClient,
1717
getListQFn,
18-
parseIpUtilization,
1918
queryClient,
2019
useApiMutation,
2120
useApiQuery,
@@ -147,30 +146,24 @@ export default function IpPoolpage() {
147146
function UtilizationBars() {
148147
const { pool } = useIpPoolSelector()
149148
const { data } = usePrefetchedApiQuery('ipPoolUtilizationView', { path: { pool } })
150-
const { ipv4, ipv6 } = parseIpUtilization(data)
149+
const { capacity, remaining } = data
151150

152-
if (ipv4.capacity === 0 && ipv6.capacity === 0n) return null
151+
if (capacity === 0) return null
153152

154153
return (
155154
<div className="-mt-8 mb-8 flex min-w-min flex-col gap-3 lg+:flex-row">
156-
{ipv4.capacity > 0 && (
155+
{capacity > 0 && (
157156
<CapacityBar
158157
icon={<IpGlobal16Icon />}
159-
title="IPv4"
160-
provisioned={ipv4.allocated}
161-
capacity={ipv4.capacity}
162-
provisionedLabel="Allocated"
163-
capacityLabel="Capacity"
164-
unit="IPs"
165-
includeUnit={false}
166-
/>
167-
)}
168-
{ipv6.capacity > 0 && (
169-
<CapacityBar
170-
icon={<IpGlobal16Icon />}
171-
title="IPv6"
172-
provisioned={ipv6.allocated}
173-
capacity={ipv6.capacity}
158+
title="ALLOCATED"
159+
// TODO: this is potentially broken in the case of large IPv6 numbers
160+
// due to lack of full precision. This should be fine and useful
161+
// for IPv4 pools, but for IPv6 we should probably just show the two
162+
// numbers. For now there are no IPv6 pools.
163+
// https://github.com/oxidecomputer/omicron/issues/8966
164+
// https://github.com/oxidecomputer/omicron/issues/9004
165+
provisioned={Math.max(capacity - remaining, 0)}
166+
capacity={capacity}
174167
provisionedLabel="Allocated"
175168
capacityLabel="Capacity"
176169
unit="IPs"

app/pages/system/networking/IpPoolsPage.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { IpGlobal16Icon, IpGlobal24Icon } from '@oxide/design-system/icons/react
2222

2323
import { DocsPopover } from '~/components/DocsPopover'
2424
import { HL } from '~/components/HL'
25-
import { IpUtilCell } from '~/components/IpPoolUtilization'
2625
import { useQuickActions } from '~/hooks/use-quick-actions'
2726
import { confirmDelete } from '~/stores/confirm-delete'
2827
import { addToast } from '~/stores/toast'
@@ -31,6 +30,7 @@ import { makeLinkCell } from '~/table/cells/LinkCell'
3130
import { useColsWithActions, type MenuAction } from '~/table/columns/action-col'
3231
import { Columns } from '~/table/columns/common'
3332
import { useQueryTable } from '~/table/QueryTable'
33+
import { BigNum } from '~/ui/lib/BigNum'
3434
import { CreateLink } from '~/ui/lib/CreateButton'
3535
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
3636
import { PageHeader, PageTitle } from '~/ui/lib/PageHeader'
@@ -50,19 +50,24 @@ const EmptyState = () => (
5050

5151
function UtilizationCell({ pool }: { pool: string }) {
5252
const { data } = useApiQuery('ipPoolUtilizationView', { path: { pool } })
53-
5453
if (!data) return <SkeletonCell />
55-
return <IpUtilCell {...data} />
54+
return (
55+
<div>
56+
<BigNum className="text-raise" num={data.remaining} /> /{' '}
57+
<BigNum className="text-secondary" num={data.capacity} />
58+
</div>
59+
)
5660
}
5761

5862
const colHelper = createColumnHelper<IpPool>()
5963

6064
const staticColumns = [
6165
colHelper.accessor('name', { cell: makeLinkCell((pool) => pb.ipPool({ pool })) }),
6266
colHelper.accessor('description', Columns.description),
63-
colHelper.accessor('name', {
64-
header: 'Utilization',
65-
cell: (info) => <UtilizationCell pool={info.getValue()} />,
67+
// TODO: add version column when API supports v6 pools
68+
colHelper.display({
69+
header: 'IPs Remaining',
70+
cell: (info) => <UtilizationCell pool={info.row.original.id} />,
6671
}),
6772
colHelper.accessor('timeCreated', Columns.timeCreated),
6873
]

mock-api/ip-pool.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const ipPool1: Json<IpPool> = {
1717
description: 'public IPs',
1818
time_created: new Date().toISOString(),
1919
time_modified: new Date().toISOString(),
20+
ip_version: 'v4',
2021
}
2122

2223
export const ipPool2: Json<IpPool> = {
@@ -25,6 +26,7 @@ export const ipPool2: Json<IpPool> = {
2526
description: 'VPN IPs',
2627
time_created: new Date().toISOString(),
2728
time_modified: new Date().toISOString(),
29+
ip_version: 'v6',
2830
}
2931

3032
export const ipPool3: Json<IpPool> = {
@@ -33,6 +35,7 @@ export const ipPool3: Json<IpPool> = {
3335
description: '',
3436
time_created: new Date().toISOString(),
3537
time_modified: new Date().toISOString(),
38+
ip_version: 'v4',
3639
}
3740

3841
export const ipPool4: Json<IpPool> = {
@@ -41,6 +44,7 @@ export const ipPool4: Json<IpPool> = {
4144
description: '',
4245
time_created: new Date().toISOString(),
4346
time_modified: new Date().toISOString(),
47+
ip_version: 'v6',
4448
}
4549

4650
export const ipPools: Json<IpPool>[] = [ipPool1, ipPool2, ipPool3, ipPool4]
@@ -88,15 +92,6 @@ export const ipPoolRanges: Json<IpPoolRange[]> = [
8892
time_created: new Date().toISOString(),
8993
},
9094
// pool 3 has no ranges
91-
{
92-
id: '4d85c502-52cc-47f9-b525-14b64cf5f1ea',
93-
ip_pool_id: ipPool4.id,
94-
range: {
95-
first: '10.0.0.50',
96-
last: '10.0.1.0',
97-
},
98-
time_created: new Date().toISOString(),
99-
},
10095
{
10196
id: '914b10e1-0452-4d87-bc9b-7b91cc7c7628',
10297
ip_pool_id: ipPool4.id,

0 commit comments

Comments
 (0)