初始提交:OCI 面板前端(含 GenAI 网关一期)
This commit is contained in:
@@ -0,0 +1,380 @@
|
||||
import {
|
||||
mockAds,
|
||||
mockBvAttachments,
|
||||
mockConsoleConns,
|
||||
mockImages,
|
||||
mockInstances,
|
||||
mockShapes,
|
||||
mockVolAttachments,
|
||||
mockVolumes,
|
||||
} from './mock'
|
||||
import { mockOn, mocked, request } from './request'
|
||||
import type {
|
||||
AttachVnicRequest,
|
||||
BootVolumeAttachment,
|
||||
ComputeShape,
|
||||
ConsoleConnection,
|
||||
CreateInstanceRequest,
|
||||
CreateInstancesResponse,
|
||||
ImageInfo,
|
||||
Instance,
|
||||
PowerAction,
|
||||
UpdateInstanceRequest,
|
||||
Vnic,
|
||||
Volume,
|
||||
VolumeAttachment,
|
||||
} from '@/types/api'
|
||||
|
||||
// ---- 创建实例前置查询 ----
|
||||
export interface ImagesQuery {
|
||||
region?: string
|
||||
operatingSystem?: string
|
||||
shape?: string
|
||||
}
|
||||
|
||||
export function listImages(cfgId: number, query: ImagesQuery = {}): Promise<ImageInfo[]> {
|
||||
if (mockOn) return mocked(mockImages)
|
||||
return request(`/oci-configs/${cfgId}/images`, { query: { ...query } })
|
||||
}
|
||||
|
||||
export function getImage(cfgId: number, imageId: string, region?: string): Promise<ImageInfo> {
|
||||
if (mockOn) {
|
||||
const found = mockImages.find((i) => i.id === imageId) ?? {
|
||||
...mockImages[0],
|
||||
id: imageId,
|
||||
displayName: 'Canonical-Ubuntu-24.04-aarch64-2026.05.20-0',
|
||||
}
|
||||
return mocked(found)
|
||||
}
|
||||
return request(`/oci-configs/${cfgId}/images/${encodeURIComponent(imageId)}`, {
|
||||
query: { region },
|
||||
})
|
||||
}
|
||||
|
||||
export function listAvailabilityDomains(cfgId: number, region?: string): Promise<string[]> {
|
||||
if (mockOn) return mocked(mockAds)
|
||||
return request(`/oci-configs/${cfgId}/availability-domains`, { query: { region } })
|
||||
}
|
||||
|
||||
export function listShapes(
|
||||
cfgId: number,
|
||||
region?: string,
|
||||
availabilityDomain?: string,
|
||||
): Promise<ComputeShape[]> {
|
||||
if (mockOn) return mocked(mockShapes)
|
||||
return request(`/oci-configs/${cfgId}/shapes`, { query: { region, availabilityDomain } })
|
||||
}
|
||||
|
||||
export function listVolumes(
|
||||
cfgId: number,
|
||||
availabilityDomain?: string,
|
||||
compartmentId?: string,
|
||||
region?: string,
|
||||
): Promise<Volume[]> {
|
||||
if (mockOn) return mocked(mockVolumes[cfgId] ?? [])
|
||||
return request(`/oci-configs/${cfgId}/volumes`, {
|
||||
query: { availabilityDomain, compartmentId, region },
|
||||
})
|
||||
}
|
||||
|
||||
export function listInstances(
|
||||
cfgId: number,
|
||||
region?: string,
|
||||
compartmentId?: string,
|
||||
): Promise<Instance[]> {
|
||||
if (mockOn) return mocked(compartmentId ? [] : (mockInstances[cfgId] ?? []))
|
||||
return request(`/oci-configs/${cfgId}/instances`, { query: { region, compartmentId } })
|
||||
}
|
||||
|
||||
export function getInstance(cfgId: number, instanceId: string, region?: string): Promise<Instance> {
|
||||
if (mockOn) {
|
||||
const all = Object.values(mockInstances).flat()
|
||||
const found = all.find((i) => i.id === instanceId)
|
||||
return found ? mocked(found) : Promise.reject(new Error('实例不存在'))
|
||||
}
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}`, {
|
||||
query: { region },
|
||||
})
|
||||
}
|
||||
|
||||
export function createInstances(
|
||||
cfgId: number,
|
||||
body: CreateInstanceRequest,
|
||||
): Promise<CreateInstancesResponse> {
|
||||
if (mockOn) return mocked({ instances: [mockInstances[1][0]], errors: [] }, 1200)
|
||||
return request(`/oci-configs/${cfgId}/instances`, { method: 'POST', body })
|
||||
}
|
||||
|
||||
export function updateInstance(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
body: UpdateInstanceRequest,
|
||||
region?: string,
|
||||
): Promise<Instance> {
|
||||
if (mockOn) return mocked({ ...mockInstances[1][0], ...body })
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}`, {
|
||||
method: 'PUT',
|
||||
body: { region: region ?? '', ...body },
|
||||
})
|
||||
}
|
||||
|
||||
export function terminateInstance(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
preserveBootVolume: boolean,
|
||||
region?: string,
|
||||
): Promise<void> {
|
||||
if (mockOn) return mocked(undefined, 600)
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}`, {
|
||||
method: 'DELETE',
|
||||
query: { preserveBootVolume, region },
|
||||
})
|
||||
}
|
||||
|
||||
export function instanceAction(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
action: PowerAction,
|
||||
region?: string,
|
||||
): Promise<Instance> {
|
||||
if (mockOn) {
|
||||
const next = action === 'STOP' || action === 'SOFTSTOP' ? 'STOPPING' : 'STARTING'
|
||||
return mocked({ ...mockInstances[1][0], lifecycleState: next }, 600)
|
||||
}
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/action`, {
|
||||
method: 'POST',
|
||||
body: { region: region ?? '', action },
|
||||
})
|
||||
}
|
||||
|
||||
export function changePublicIp(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
region?: string,
|
||||
): Promise<{ publicIp: string }> {
|
||||
if (mockOn) return mocked({ publicIp: '130.61.99.201' }, 900)
|
||||
return request(
|
||||
`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/change-public-ip`,
|
||||
{ method: 'POST', body: { region: region ?? '' } },
|
||||
)
|
||||
}
|
||||
|
||||
export function addIpv6(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
address = '',
|
||||
region?: string,
|
||||
): Promise<{ ipv6Address: string }> {
|
||||
if (mockOn) return mocked({ ipv6Address: address || '2603:c020:400d:aa01::2' }, 700)
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/ipv6-addresses`, {
|
||||
method: 'POST',
|
||||
body: { region: region ?? '', address },
|
||||
})
|
||||
}
|
||||
|
||||
export function removeIpv6(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
address: string,
|
||||
region?: string,
|
||||
): Promise<void> {
|
||||
if (mockOn) return mocked(undefined)
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/ipv6-addresses`, {
|
||||
method: 'DELETE',
|
||||
query: { address, region },
|
||||
})
|
||||
}
|
||||
|
||||
// ---- VNIC 管理 ----
|
||||
export function listVnics(cfgId: number, instanceId: string, region?: string): Promise<Vnic[]> {
|
||||
if (mockOn) return mocked([])
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/vnics`, {
|
||||
query: { region },
|
||||
})
|
||||
}
|
||||
|
||||
export function attachVnic(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
body: AttachVnicRequest,
|
||||
): Promise<Vnic> {
|
||||
if (mockOn) return Promise.reject(new Error('mock 环境不支持附加 VNIC'))
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/vnics`, {
|
||||
method: 'POST',
|
||||
body: { ...body, region: body.region ?? '' },
|
||||
})
|
||||
}
|
||||
|
||||
export function detachVnic(cfgId: number, attachmentId: string, region?: string): Promise<void> {
|
||||
if (mockOn) return mocked(undefined)
|
||||
return request(`/oci-configs/${cfgId}/vnic-attachments/${encodeURIComponent(attachmentId)}`, {
|
||||
method: 'DELETE',
|
||||
query: { region },
|
||||
})
|
||||
}
|
||||
|
||||
/** 为指定 VNIC 添加 IPv6;address 留空自动分配。删除复用实例级 removeIpv6(按地址遍历全部网卡) */
|
||||
export function addVnicIpv6(
|
||||
cfgId: number,
|
||||
vnicId: string,
|
||||
address = '',
|
||||
region?: string,
|
||||
): Promise<{ address: string }> {
|
||||
if (mockOn) return mocked({ address: address || '2603:c020:400d:aa01::3' }, 700)
|
||||
return request(`/oci-configs/${cfgId}/vnics/${encodeURIComponent(vnicId)}/ipv6-addresses`, {
|
||||
method: 'POST',
|
||||
body: { region: region ?? '', address },
|
||||
})
|
||||
}
|
||||
|
||||
// ---- 网页控制台(串行 / VNC)----
|
||||
export type ConsoleSessionType = 'serial' | 'vnc'
|
||||
|
||||
export function createConsoleSession(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
type: ConsoleSessionType,
|
||||
region?: string,
|
||||
): Promise<{ sessionId: string; type: ConsoleSessionType }> {
|
||||
if (mockOn) return Promise.reject(new Error('mock 环境不支持网页控制台'))
|
||||
return request(
|
||||
`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/console-sessions`,
|
||||
{ method: 'POST', body: { type, region: region ?? '' } },
|
||||
)
|
||||
}
|
||||
|
||||
export function deleteConsoleSession(sessionId: string): Promise<void> {
|
||||
if (mockOn) return mocked(undefined)
|
||||
return request(`/console-sessions/${encodeURIComponent(sessionId)}`, { method: 'DELETE' })
|
||||
}
|
||||
|
||||
/** 控制台数据面 WS 地址:浏览器 WS 无法带自定义头,token 走 query */
|
||||
export function consoleSessionWsUrl(sessionId: string, token: string, extra?: string): string {
|
||||
const proto = location.protocol === 'https:' ? 'wss' : 'ws'
|
||||
const q = extra ? `&${extra}` : ''
|
||||
return `${proto}://${location.host}/api/v1/console-sessions/${encodeURIComponent(sessionId)}/ws?token=${encodeURIComponent(token)}${q}`
|
||||
}
|
||||
|
||||
// ---- 控制台连接 ----
|
||||
export function listConsoleConnections(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
region?: string,
|
||||
): Promise<ConsoleConnection[]> {
|
||||
if (mockOn) return mocked(mockConsoleConns)
|
||||
return request(
|
||||
`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/console-connections`,
|
||||
{ query: { region } },
|
||||
)
|
||||
}
|
||||
|
||||
export function createConsoleConnection(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
sshPublicKey: string,
|
||||
region?: string,
|
||||
): Promise<ConsoleConnection> {
|
||||
if (mockOn) return mocked(mockConsoleConns[0], 1500)
|
||||
return request(
|
||||
`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/console-connections`,
|
||||
{ method: 'POST', body: { region: region ?? '', sshPublicKey } },
|
||||
)
|
||||
}
|
||||
|
||||
export function deleteConsoleConnection(
|
||||
cfgId: number,
|
||||
connectionId: string,
|
||||
region?: string,
|
||||
): Promise<void> {
|
||||
if (mockOn) return mocked(undefined)
|
||||
return request(`/oci-configs/${cfgId}/console-connections/${encodeURIComponent(connectionId)}`, {
|
||||
method: 'DELETE',
|
||||
query: { region },
|
||||
})
|
||||
}
|
||||
|
||||
// ---- 引导卷挂载 ----
|
||||
export function listBootVolumeAttachments(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
region?: string,
|
||||
): Promise<BootVolumeAttachment[]> {
|
||||
if (mockOn) return mocked(mockBvAttachments)
|
||||
return request(
|
||||
`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/boot-volume-attachments`,
|
||||
{ query: { region } },
|
||||
)
|
||||
}
|
||||
|
||||
export function attachBootVolume(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
bootVolumeId: string,
|
||||
region?: string,
|
||||
): Promise<BootVolumeAttachment> {
|
||||
if (mockOn) return mocked(mockBvAttachments[0], 1200)
|
||||
return request(
|
||||
`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/boot-volume-attachments`,
|
||||
{ method: 'POST', body: { region: region ?? '', bootVolumeId } },
|
||||
)
|
||||
}
|
||||
|
||||
export function replaceBootVolume(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
bootVolumeId: string,
|
||||
region?: string,
|
||||
): Promise<BootVolumeAttachment> {
|
||||
if (mockOn) return mocked(mockBvAttachments[0], 1500)
|
||||
return request(
|
||||
`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/replace-boot-volume`,
|
||||
{ method: 'POST', body: { region: region ?? '', bootVolumeId } },
|
||||
)
|
||||
}
|
||||
|
||||
export function detachBootVolume(
|
||||
cfgId: number,
|
||||
attachmentId: string,
|
||||
region?: string,
|
||||
): Promise<void> {
|
||||
if (mockOn) return mocked(undefined)
|
||||
return request(`/oci-configs/${cfgId}/boot-volume-attachments/${encodeURIComponent(attachmentId)}`, {
|
||||
method: 'DELETE',
|
||||
query: { region },
|
||||
})
|
||||
}
|
||||
|
||||
// ---- 块卷挂载 ----
|
||||
export function listVolumeAttachments(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
region?: string,
|
||||
): Promise<VolumeAttachment[]> {
|
||||
if (mockOn) return mocked(mockVolAttachments)
|
||||
return request(
|
||||
`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/volume-attachments`,
|
||||
{ query: { region } },
|
||||
)
|
||||
}
|
||||
|
||||
export function attachVolume(
|
||||
cfgId: number,
|
||||
instanceId: string,
|
||||
volumeId: string,
|
||||
readOnly = false,
|
||||
region?: string,
|
||||
): Promise<VolumeAttachment> {
|
||||
if (mockOn) return mocked(mockVolAttachments[0], 1000)
|
||||
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}/volume-attachments`, {
|
||||
method: 'POST',
|
||||
body: { region: region ?? '', volumeId, readOnly },
|
||||
})
|
||||
}
|
||||
|
||||
export function detachVolume(cfgId: number, attachmentId: string, region?: string): Promise<void> {
|
||||
if (mockOn) return mocked(undefined)
|
||||
return request(`/oci-configs/${cfgId}/volume-attachments/${encodeURIComponent(attachmentId)}`, {
|
||||
method: 'DELETE',
|
||||
query: { region },
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user