feat(rdp): 新增 RDP 远程桌面/SMB/账单同步能力 + 清理编译产物

主要变更:
- RDP 远程桌面:新增 backend/pkg/rdp(RDP 引擎 + credssp/display/rle/trace)、
  backend/controller/rdp*(连接/凭证/文件/会话/实时)、frontend RDP 组件与 API
- Windows SMB 文件传输:backend/pkg/winsmb
- 云账单同步:backend/pkg/billingsync + billing_sync/aliyun_billing,前端账单详情
- Agent CLI Kubernetes 工具:kubernetes_action/get、pod_execute/logs
- 服务器导入助手:server_import_helpers、ImportCredentialSettings
- 国际化与组件重构(cloud/deploy/monitor/server/system 等多模块)
- 清理编译产物二进制:移除 backend/server、backend/agent/bin/aiops-agent-*
- .gitignore:新增 backend/agent/ 与 .cache/(避免 334MB go-build 缓存误入库)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
LoganandClaude committed 2026-07-04 01:50:36 +08:00
1 parent 777d9e4e71
commit 76ec9387f0
202 files changed
+16555 -2543

No files matched your search

@@ -37,6 +37,11 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
const [sshPassword, setSshPassword] = useState('');
const [sshPrivateKey, setSshPrivateKey] = useState('');
const [sshPublicKey, setSshPublicKey] = useState('');
// RDP 字段 // Logan.Li
const [rdpUsername, setRdpUsername] = useState('Administrator');
const [rdpPassword, setRdpPassword] = useState('');
const [rdpDomain, setRdpDomain] = useState('');
const [rdpSecurity, setRdpSecurity] = useState('nla');
// Docker 字段
const [dockerServer, setDockerServer] = useState('');
const [dockerUsername, setDockerUsername] = useState('');
@@ -75,6 +80,7 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
setIsActive(editData.is_active);
// 编辑时不预填类型字段,仅修改用户填写的项 // Logan.Li
setSshUser(''); setSshPort('22'); setSshPassword(''); setSshPrivateKey(''); setSshPublicKey('');
setRdpUsername(''); setRdpPassword(''); setRdpDomain(''); setRdpSecurity('nla');
setDockerServer(''); setDockerUsername(''); setDockerPassword('');
setTlsCert(''); setTlsKey(''); setTlsCa('');
setAkskProvider(''); setAkskAccessKey(''); setAkskSecretKey(''); setAkskRegion('');
@@ -84,6 +90,7 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
} else {
setName(''); setVarName(''); setSecretType('ssh'); setDescription(''); setTags(''); setIsActive(true);
setSshUser('root'); setSshPort('22'); setSshPassword(''); setSshPrivateKey(''); setSshPublicKey('');
setRdpUsername('Administrator'); setRdpPassword(''); setRdpDomain(''); setRdpSecurity('nla');
setDockerServer(''); setDockerUsername(''); setDockerPassword('');
setTlsCert(''); setTlsKey(''); setTlsCa('');
setAkskProvider(''); setAkskAccessKey(''); setAkskSecretKey(''); setAkskRegion('');
@@ -115,6 +122,13 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
if (sshPassword.trim()) payload.ssh_password = sshPassword.trim();
if (sshPrivateKey.trim()) payload.ssh_private_key = sshPrivateKey.trim();
if (sshPublicKey.trim()) payload.ssh_public_key = sshPublicKey.trim();
} else if (secretType === 'rdp') {
if (!rdpUsername.trim()) { toast.error('请填写 RDP 用户'); return; }
if (!isEdit && !rdpPassword.trim()) { toast.error('请填写 RDP 密码'); return; }
if (rdpUsername.trim()) payload.rdp_username = rdpUsername.trim();
if (rdpPassword.trim()) payload.rdp_password = rdpPassword.trim();
if (rdpDomain.trim()) payload.rdp_domain = rdpDomain.trim();
payload.rdp_security = rdpSecurity.trim() || 'nla';
} else if (secretType === 'docker') {
if (dockerServer.trim()) payload.docker_server = dockerServer.trim();
if (dockerUsername.trim()) payload.docker_username = dockerUsername.trim();
@@ -275,6 +289,36 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
</div>
)}
{secretType === 'rdp' && (
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1">
<Label className="text-[var(--dg-text-secondary)] text-xs">Windows 用户 <span className="dg-text-red">*</span></Label>
<Input value={rdpUsername} onChange={e => setRdpUsername(e.target.value)} placeholder="Administrator"
className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" />
</div>
<div className="space-y-1">
<Label className="text-[var(--dg-text-secondary)] text-xs">安全模式</Label>
<Select value={rdpSecurity} onValueChange={setRdpSecurity}>
<SelectTrigger className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="nla">NLA</SelectItem>
<SelectItem value="tls">TLS</SelectItem>
<SelectItem value="rdp">标准 RDP</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-1">
<Label className="text-[var(--dg-text-secondary)] text-xs">域</Label>
<Input value={rdpDomain} onChange={e => setRdpDomain(e.target.value)} placeholder="可选"
className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" />
</div>
<div><FieldWithToggle label="Windows 密码" value={rdpPassword} onChange={setRdpPassword}
placeholder="Windows 登录密码" fieldKey="rdp_pwd" required /></div>
</div>
)}
{secretType === 'docker' && (
<div className="grid grid-cols-2 gap-3">
<div className="col-span-2 space-y-1">
@@ -394,4 +438,4 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
</DialogContent>
</Dialog>
);
}
}
@@ -1,27 +1,28 @@
// 凭据类型配置常量 // Logan.Li
import {
Key, Server, Container, Shield, Cloud, Database, FileText, Globe,
Key, Server, Container, Shield, Cloud, Database, FileText, Globe, Monitor,
} from 'lucide-react';
import type { SecretType } from './types';
import i18n from '@/i18n';
export const TYPE_CONFIG: Record<SecretType, { label: string; icon: typeof Key; color: string; desc: string }> = {
ssh: { label: i18n.t('system.sshKeyLabel'), icon: Server, color: 'dg-text-yellow', desc: i18n.t('pipeline.constantsts.sedc7f9e9') },
docker: { label: i18n.t('system.dockerCredential'), icon: Container, color: 'dg-text-cyan', desc: i18n.t('pipeline.constantsts.sbd6cf171') },
tls: { label: i18n.t('pipeline.constantsts.sfa5a64de'), icon: Shield, color: 'dg-text-green', desc: i18n.t('pipeline.constantsts.s43f00c61') },
aksk: { label: i18n.t('pipeline.constantsts.sb82698a1'), icon: Cloud, color: 'dg-text-purple', desc: i18n.t('pipeline.constantsts.s564e98a9') },
database: { label: i18n.t('system.dbCredential'), icon: Database, color: 'dg-text-blue', desc: i18n.t('pipeline.constantsts.se47498d3') },
api: { label: i18n.t('system.apiKeys'), icon: Globe, color: 'dg-text-orange', desc: i18n.t('pipeline.constantsts.sb3edf0a4') },
generic: { label: i18n.t('pipeline.constantsts.s1d319bb7'), icon: FileText, color: 'dg-text-secondary', desc: i18n.t('pipeline.constantsts.s51b5b280') },
ssh: { label: 'SSH 密钥', icon: Server, color: 'dg-text-yellow', desc: 'SSH 私钥/公钥/密码' },
rdp: { label: 'Windows RDP 密码', icon: Monitor, color: 'dg-text-blue', desc: 'Windows 远程桌面用户名/密码' },
docker: { label: 'Docker 凭证', icon: Container, color: 'dg-text-cyan', desc: 'Docker Registry 登录凭据' },
tls: { label: 'TLS 证书', icon: Shield, color: 'dg-text-green', desc: 'TLS/SSL 证书与私钥' },
aksk: { label: 'AKSK 密钥', icon: Cloud, color: 'dg-text-purple', desc: '云服务 AccessKey/SecretKey' },
database: { label: '数据库凭证', icon: Database, color: 'dg-text-blue', desc: '数据库连接信息' },
api: { label: 'API 密钥', icon: Globe, color: 'dg-text-orange', desc: 'API Token/Key + 端点' },
generic: { label: '通用凭证', icon: FileText, color: 'dg-text-secondary', desc: '自定义 Key/Value 键值对' },
};
export const TYPE_BADGE_CLASS: Record<SecretType, string> = {
ssh: 'bg-amber-500/20 dg-text-yellow border-amber-500/30',
rdp: 'bg-blue-500/20 dg-text-blue border-blue-500/30',
docker: 'bg-cyan-500/20 dg-text-cyan border-cyan-500/30',
tls: 'bg-green-500/20 dg-text-green border-green-500/30',
aksk: 'bg-purple-500/20 dg-text-purple border-purple-500/30',
database: 'bg-blue-500/20 dg-text-blue border-blue-500/30',
api: 'bg-orange-500/20 dg-text-orange border-orange-500/30',
generic: 'dg-badge-muted',
};
};
@@ -15,4 +15,4 @@ export interface Credential {
updated_at: string;
}
export type SecretType = 'ssh' | 'docker' | 'tls' | 'aksk' | 'database' | 'api' | 'generic';
export type SecretType = 'ssh' | 'rdp' | 'docker' | 'tls' | 'aksk' | 'database' | 'api' | 'generic';