feat: implement Phase 6 — Software Deployment
Backend: - SoftwarePackage model (Name, Version, OsType, PackageManager, PackageName, InstallerUrl, Checksum, SilentArgs) - RmmDbContext: SoftwarePackages DbSet + unique index on (Name, Version, OsType) - SoftwarePackagesController: full CRUD with OsType filter - DeployController: POST /api/v1/deploy creates InstallSoftware/UninstallSoftware TaskItem - EF Migration: AddSoftwarePackages (20260319130448) Go Agent: - internal/deployer/deployer.go: Install() and Uninstall() with: - Chocolatey (Windows), apt/dnf (Linux), auto-detect - Direct installer fallback: HTTP download + SHA256 verify + silent install - Supports .msi, .exe (Windows) and .deb, .rpm (Linux) - main.go: COMMAND_TYPE_INSTALL_SOFTWARE and COMMAND_TYPE_UNINSTALL_SOFTWARE routed to deployer Frontend: - SoftwarePage: Katalog tab (CRUD, OS filter, smart package manager select) + Deploy tab - api/types.ts: SoftwarePackage, PackageManager, DeployRequest/Response types - api/client.ts: softwarePackagesApi and deployApi - App.tsx: Software nav item with Package icon Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,10 @@ import type {
|
||||
AlertItem,
|
||||
CreateAlertRuleRequest,
|
||||
UpdateAlertRuleRequest,
|
||||
SoftwarePackage,
|
||||
CreateSoftwarePackageRequest,
|
||||
DeployRequest,
|
||||
DeployResponse,
|
||||
} from './types'
|
||||
|
||||
const BASE_URL = '/api/v1'
|
||||
@@ -73,3 +77,23 @@ export const alertsApi = {
|
||||
acknowledge: (id: number) =>
|
||||
request<{ id: number; acknowledged: boolean }>(`/alerts/${id}/acknowledge`, { method: 'POST' }),
|
||||
}
|
||||
|
||||
// Software Packages
|
||||
export const softwarePackagesApi = {
|
||||
list: (osType?: string) => {
|
||||
const param = osType ? `?osType=${osType}` : ''
|
||||
return request<SoftwarePackage[]>(`/software-packages${param}`)
|
||||
},
|
||||
create: (data: CreateSoftwarePackageRequest) =>
|
||||
request<SoftwarePackage>('/software-packages', { method: 'POST', body: JSON.stringify(data) }),
|
||||
update: (id: number, data: CreateSoftwarePackageRequest) =>
|
||||
request<SoftwarePackage>(`/software-packages/${id}`, { method: 'PUT', body: JSON.stringify(data) }),
|
||||
delete: (id: number) =>
|
||||
request<void>(`/software-packages/${id}`, { method: 'DELETE' }),
|
||||
}
|
||||
|
||||
// Deploy
|
||||
export const deployApi = {
|
||||
deploy: (data: DeployRequest) =>
|
||||
request<DeployResponse>('/deploy', { method: 'POST', body: JSON.stringify(data) }),
|
||||
}
|
||||
|
||||
@@ -132,3 +132,44 @@ export interface UpdateAlertRuleRequest {
|
||||
severity?: AlertSeverity
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export type PackageManager = 'choco' | 'apt' | 'dnf' | 'direct'
|
||||
|
||||
export interface SoftwarePackage {
|
||||
id: number
|
||||
name: string
|
||||
version: string
|
||||
osType: OsType
|
||||
packageManager: PackageManager
|
||||
packageName: string
|
||||
installerUrl: string | null
|
||||
checksum: string | null
|
||||
silentArgs: string | null
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export interface CreateSoftwarePackageRequest {
|
||||
name: string
|
||||
version: string
|
||||
osType: OsType
|
||||
packageManager: PackageManager
|
||||
packageName: string
|
||||
installerUrl?: string
|
||||
checksum?: string
|
||||
silentArgs?: string
|
||||
}
|
||||
|
||||
export interface DeployRequest {
|
||||
agentId: string
|
||||
packageId: number
|
||||
action: 'install' | 'uninstall'
|
||||
}
|
||||
|
||||
export interface DeployResponse {
|
||||
id: string
|
||||
agentId: string
|
||||
type: string
|
||||
status: string
|
||||
packageName: string
|
||||
version: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user