224 lines
8.3 KiB
JavaScript
224 lines
8.3 KiB
JavaScript
import { useState } from 'react'
|
|
import { Copy, Check, Terminal, Monitor } from 'lucide-react'
|
|
import { copyToClipboard } from '../utils/clipboard'
|
|
import { useSettingsStore } from '../stores/settings'
|
|
|
|
export default function InstallGuide({ agentName, platform: initialPlatform }) {
|
|
const [platform, setPlatform] = useState(initialPlatform || 'freebsd')
|
|
const [copied, setCopied] = useState(null)
|
|
const { settings } = useSettingsStore()
|
|
const BACKEND_URL = settings.backend_url_external || settings.backend_url_internal || ''
|
|
const API_KEY = settings.api_key || ''
|
|
|
|
const copyText = (text, id) => {
|
|
copyToClipboard(text)
|
|
setCopied(id)
|
|
setTimeout(() => setCopied(null), 2000)
|
|
}
|
|
|
|
const CopyBtn = ({ text, id, className = '' }) => (
|
|
<button
|
|
onClick={(e) => { e.stopPropagation(); copyText(text, id) }}
|
|
className={`text-gray-500 hover:text-orange-400 transition-colors ${className}`}
|
|
title="Kopieren"
|
|
>
|
|
{copied === id ? <Check className="w-3.5 h-3.5 text-green-400" /> : <Copy className="w-3.5 h-3.5" />}
|
|
</button>
|
|
)
|
|
|
|
const CodeBlock = ({ text, id }) => (
|
|
<div className="relative group">
|
|
<pre className="bg-gray-950 rounded px-3 py-2 text-xs font-mono text-gray-300 whitespace-pre-wrap overflow-x-auto">
|
|
{text}
|
|
</pre>
|
|
<button
|
|
onClick={() => copyText(text, id)}
|
|
className="absolute top-1.5 right-1.5 text-gray-600 hover:text-orange-400 transition-colors"
|
|
>
|
|
{copied === id ? <Check className="w-4 h-4 text-green-400" /> : <Copy className="w-4 h-4" />}
|
|
</button>
|
|
</div>
|
|
)
|
|
|
|
const ConfigValue = ({ label, value, id, mono = false }) => (
|
|
<div className="flex items-center justify-between bg-gray-950 rounded px-3 py-2">
|
|
<div className="min-w-0">
|
|
<span className="text-xs text-gray-500">{label}</span>
|
|
<div className={`text-sm text-white truncate ${mono ? 'font-mono text-xs' : ''}`}>{value}</div>
|
|
</div>
|
|
<CopyBtn text={value} id={id} className="ml-2 flex-shrink-0" />
|
|
</div>
|
|
)
|
|
|
|
const opnInstallCmd = `fetch --no-verify-peer --no-verify-hostname -o /tmp/installer.zip \\
|
|
"${BACKEND_URL}/api/v1/installer/download?platform=freebsd&api_key=${API_KEY}" \\
|
|
&& cd /tmp && unzip -o installer.zip && sh /tmp/install.sh`
|
|
|
|
const linuxInstallCmd = `#!/bin/sh
|
|
# RMM Agent + Updater Installation
|
|
set -e
|
|
|
|
BACKEND="${BACKEND_URL}"
|
|
API_KEY="${API_KEY}"
|
|
NAME="${agentName || '<NAME>'}"
|
|
|
|
# Download
|
|
wget --no-check-certificate -O /tmp/rmm-bundle.zip \\
|
|
"$BACKEND/api/v1/firmware/download?platform=linux&api_key=$API_KEY"
|
|
cd /tmp && unzip -o rmm-bundle.zip
|
|
|
|
# Install binaries
|
|
install -m 755 /tmp/rmm-agent-linux /usr/local/bin/rmm-agent
|
|
install -m 755 /tmp/rmm-updater-linux /usr/local/bin/rmm-updater
|
|
mkdir -p /etc/rmm
|
|
|
|
# Config
|
|
cat > /etc/rmm/config.yaml << EOF
|
|
backend_url: "$BACKEND"
|
|
api_key: "$API_KEY"
|
|
agent_name: "$NAME"
|
|
interval_seconds: 60
|
|
insecure: true
|
|
EOF
|
|
|
|
# Systemd services
|
|
cat > /etc/systemd/system/rmm-agent.service << EOF
|
|
[Unit]
|
|
Description=RMM Agent
|
|
After=network.target
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=/usr/local/bin/rmm-agent
|
|
Restart=always
|
|
RestartSec=10
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
cat > /etc/systemd/system/rmm-updater.service << EOF
|
|
[Unit]
|
|
Description=RMM Updater
|
|
After=network.target
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=/usr/local/bin/rmm-updater
|
|
Restart=always
|
|
RestartSec=30
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable --now rmm-agent rmm-updater
|
|
echo "Fertig! Agent verbindet sich automatisch mit Backend."
|
|
`
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
{/* Platform Tabs */}
|
|
{!initialPlatform && (
|
|
<div className="flex gap-1 bg-gray-800 rounded-lg p-1">
|
|
<button
|
|
onClick={() => setPlatform('freebsd')}
|
|
className={`flex-1 flex items-center justify-center gap-2 px-3 py-2 rounded text-sm font-medium transition-colors ${
|
|
platform === 'freebsd'
|
|
? 'bg-orange-600 text-white'
|
|
: 'text-gray-400 hover:text-white'
|
|
}`}
|
|
>
|
|
<Monitor className="w-4 h-4" />
|
|
OPNsense
|
|
</button>
|
|
<button
|
|
onClick={() => setPlatform('linux')}
|
|
className={`flex-1 flex items-center justify-center gap-2 px-3 py-2 rounded text-sm font-medium transition-colors ${
|
|
platform === 'linux'
|
|
? 'bg-blue-600 text-white'
|
|
: 'text-gray-400 hover:text-white'
|
|
}`}
|
|
>
|
|
<Terminal className="w-4 h-4" />
|
|
Linux / Proxmox
|
|
</button>
|
|
</div>
|
|
)}
|
|
|
|
{platform === 'freebsd' ? (
|
|
<div className="space-y-4">
|
|
{/* Step 1: Install Plugin */}
|
|
<div className="space-y-2">
|
|
<h4 className="text-sm font-medium text-white flex items-center gap-2">
|
|
<span className="w-5 h-5 rounded-full bg-orange-600 text-white text-xs flex items-center justify-center font-bold">1</span>
|
|
Plugin installieren
|
|
</h4>
|
|
<p className="text-xs text-gray-400 ml-7">Per SSH oder WebGUI-Shell auf der Firewall ausfuehren:</p>
|
|
<div className="ml-7">
|
|
<CodeBlock text={opnInstallCmd} id="opn-install" />
|
|
</div>
|
|
</div>
|
|
|
|
{/* Step 2: Configure via WebGUI */}
|
|
<div className="space-y-2">
|
|
<h4 className="text-sm font-medium text-white flex items-center gap-2">
|
|
<span className="w-5 h-5 rounded-full bg-orange-600 text-white text-xs flex items-center justify-center font-bold">2</span>
|
|
Im WebGUI konfigurieren
|
|
</h4>
|
|
<p className="text-xs text-gray-400 ml-7">
|
|
Services > RMM Agent > folgende Werte eintragen:
|
|
</p>
|
|
<div className="ml-7 space-y-2">
|
|
<ConfigValue label="Backend URL" value={BACKEND_URL} id="opn-url" />
|
|
<ConfigValue label="API Key" value={API_KEY} id="opn-key" mono />
|
|
<ConfigValue label="Agent Name" value={agentName || '<NAME>'} id="opn-name" />
|
|
</div>
|
|
</div>
|
|
|
|
{/* Step 3: Enable + Start */}
|
|
<div className="space-y-2">
|
|
<h4 className="text-sm font-medium text-white flex items-center gap-2">
|
|
<span className="w-5 h-5 rounded-full bg-orange-600 text-white text-xs flex items-center justify-center font-bold">3</span>
|
|
Aktivieren und starten
|
|
</h4>
|
|
<p className="text-xs text-gray-400 ml-7">
|
|
"Enabled" aktivieren, "Save & Apply", dann "Restart Service".
|
|
Der Agent verbindet sich automatisch.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-4">
|
|
{/* Linux: Single script */}
|
|
<div className="space-y-2">
|
|
<h4 className="text-sm font-medium text-white flex items-center gap-2">
|
|
<span className="w-5 h-5 rounded-full bg-blue-600 text-white text-xs flex items-center justify-center font-bold">1</span>
|
|
Installscript ausfuehren
|
|
</h4>
|
|
<p className="text-xs text-gray-400 ml-7">Als root auf dem Server ausfuehren. Script kopieren, als Datei speichern und starten:</p>
|
|
<div className="ml-7">
|
|
<CodeBlock text={linuxInstallCmd} id="linux-install" />
|
|
</div>
|
|
</div>
|
|
|
|
{/* Config values for reference */}
|
|
<div className="space-y-2">
|
|
<h4 className="text-sm font-medium text-white flex items-center gap-2">
|
|
<span className="w-5 h-5 rounded-full bg-blue-600 text-white text-xs flex items-center justify-center font-bold">2</span>
|
|
Konfigurationswerte (Referenz)
|
|
</h4>
|
|
<div className="ml-7 space-y-2">
|
|
<ConfigValue label="Backend URL" value={BACKEND_URL} id="linux-url" />
|
|
<ConfigValue label="API Key" value={API_KEY} id="linux-key" mono />
|
|
<ConfigValue label="Agent Name" value={agentName || '<NAME>'} id="linux-name" />
|
|
<ConfigValue label="Config-Datei" value="/etc/rmm/config.yaml" id="linux-cfg" mono />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<p className="text-xs text-gray-500 border-t border-gray-800 pt-3">
|
|
Der Agent meldet sich nach Installation automatisch beim Backend. Name und IP werden beim ersten Heartbeat uebernommen.
|
|
</p>
|
|
</div>
|
|
)
|
|
}
|