feat: 实现 Redfish API 标准接口;支持通过前端开关控制 Redfish 服务

This commit is contained in:
Fucheng Sha
2026-05-12 10:45:42 +08:00
parent 17cd74f64c
commit 4e8c342905
23 changed files with 2170 additions and 5 deletions

View File

@@ -392,6 +392,24 @@ export const webConfigApi = {
}),
}
export interface RedfishConfigResponse {
enabled: boolean
}
export interface RedfishConfigUpdate {
enabled?: boolean
}
export const redfishConfigApi = {
get: () => request<RedfishConfigResponse>('/config/redfish'),
update: (config: RedfishConfigUpdate) =>
request<RedfishConfigResponse>('/config/redfish', {
method: 'PATCH',
body: JSON.stringify(config),
}),
}
export const systemApi = {
/**
* 重启系统

View File

@@ -678,6 +678,7 @@ export {
atxConfigApi,
audioConfigApi,
extensionsApi,
redfishConfigApi,
rustdeskConfigApi,
rtspConfigApi,
webConfigApi,
@@ -686,6 +687,8 @@ export {
type RustDeskConfigUpdate,
type RustDeskPasswordResponse,
type RtspConfigResponse,
type RedfishConfigResponse,
type RedfishConfigUpdate,
type RtspConfigUpdate,
type RtspStatusResponse,
type WebConfig,

View File

@@ -569,6 +569,10 @@ export default {
httpsEnabledDesc: 'Serve over an encrypted connection. A self-signed certificate is generated automatically if none is provided.',
portConfig: 'Port & Protocol',
portConfigDesc: 'The service listens on a single port at a time, determined by the HTTPS toggle',
redfishTitle: 'Redfish API',
redfishDesc: 'DMTF Redfish standard management interface',
redfishEnabled: 'Enable Redfish API',
redfishEnabledDesc: 'When enabled, the standard Redfish management interface is available at /redfish/v1/',
httpPortReserved: 'HTTP port (reserved)',
httpsPortReserved: 'HTTPS port (reserved)',
portActive: 'Active',

View File

@@ -568,6 +568,10 @@ export default {
httpsEnabledDesc: '使用加密连接对外提供服务,未配置证书时自动生成自签名证书',
portConfig: '端口与协议',
portConfigDesc: '服务一次仅监听一个端口,由 HTTPS 开关决定生效端口',
redfishTitle: 'Redfish API',
redfishDesc: 'DMTF Redfish 标准管理接口',
redfishEnabled: '启用 Redfish API',
redfishEnabledDesc: '开启后可通过 /redfish/v1/ 访问标准 Redfish 管理接口',
httpPortReserved: 'HTTP 端口(备用)',
httpsPortReserved: 'HTTPS 端口(备用)',
portActive: '当前生效',

View File

@@ -12,6 +12,7 @@ import {
streamApi,
atxConfigApi,
extensionsApi,
redfishConfigApi,
systemApi,
updateApi,
usbApi,
@@ -295,6 +296,8 @@ const webServerConfig = ref<WebConfig>({
has_custom_cert: false,
})
const webServerLoading = ref(false)
const redfishEnabled = ref(false)
const redfishSaving = ref(false)
const sslCertPem = ref('')
const sslKeyPem = ref('')
const certSaving = ref(false)
@@ -1601,6 +1604,30 @@ async function loadWebServerConfig() {
}
}
async function loadRedfishConfig() {
try {
const data = await redfishConfigApi.get()
redfishEnabled.value = data.enabled
} catch (e) {
console.error('Failed to load redfish config:', e)
}
}
async function saveRedfishConfig() {
redfishSaving.value = true
try {
const data = await redfishConfigApi.update({
enabled: redfishEnabled.value,
})
redfishEnabled.value = data.enabled
await triggerAutoRestart()
} catch (e) {
console.error('Failed to save redfish config:', e)
} finally {
redfishSaving.value = false
}
}
async function saveWebServerConfig() {
if (bindAddressError.value) return
webServerLoading.value = true
@@ -2087,6 +2114,7 @@ onMounted(async () => {
loadRustdeskPassword(),
loadRtspConfig(),
loadWebServerConfig(),
loadRedfishConfig(),
loadUpdateOverview(),
refreshUpdateStatus(),
fetchUsbDevices(),
@@ -3237,9 +3265,35 @@ watch(() => route.query.tab, (tab) => {
</Button>
</CardFooter>
</Card>
</div>
<!-- MSD Section -->
<!-- Redfish API Card -->
<Card>
<CardHeader>
<CardTitle>{{ t('settings.redfishTitle') }}</CardTitle>
<CardDescription>{{ t('settings.redfishDesc') }}</CardDescription>
</CardHeader>
<CardContent class="space-y-5">
<div class="flex items-start justify-between gap-4">
<div class="space-y-0.5">
<Label>{{ t('settings.redfishEnabled') }}</Label>
<p class="text-xs text-muted-foreground">{{ t('settings.redfishEnabledDesc') }}</p>
</div>
<Switch v-model="redfishEnabled" />
</div>
</CardContent>
<CardFooter class="flex items-center justify-between gap-3 border-t pt-4">
<p class="text-xs text-muted-foreground flex items-center gap-1.5">
<AlertTriangle class="h-3.5 w-3.5 text-amber-500" />
{{ t('settings.restartRequiredHint') }}
</p>
<Button @click="saveRedfishConfig" :disabled="redfishSaving || autoRestarting">
<RefreshCw v-if="autoRestarting" class="h-4 w-4 mr-2 animate-spin" />
<Save v-else class="h-4 w-4 mr-2" />
{{ autoRestarting ? t('settings.restarting') : t('common.save') }}
</Button>
</CardFooter>
</Card>
</div>
<div v-show="activeSection === 'msd' && config.msd_enabled" class="space-y-6">
<Card>
<CardHeader>