feat: Linux SSH admin and remote ssh-monitor update (0.11.0)
This commit is contained in:
@@ -58,6 +58,26 @@
|
||||
</button>
|
||||
<p v-if="winRmTestMessage" :class="winRmTestOk ? 'success' : 'error'">{{ winRmTestMessage }}</p>
|
||||
</div>
|
||||
<div v-if="isLinuxHost" class="host-actions">
|
||||
<button
|
||||
type="button"
|
||||
class="secondary"
|
||||
:disabled="testingSsh"
|
||||
@click="runSshTest"
|
||||
>
|
||||
{{ testingSsh ? "Проверка…" : "Проверить SSH" }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="secondary"
|
||||
:disabled="updatingAgent"
|
||||
@click="runAgentUpdate"
|
||||
>
|
||||
{{ updatingAgent ? "Обновление…" : "Обновить ssh-monitor" }}
|
||||
</button>
|
||||
<p v-if="sshActionMessage" :class="sshActionOk ? 'success' : 'error'">{{ sshActionMessage }}</p>
|
||||
<pre v-if="sshActionOutput" class="host-ssh-output">{{ sshActionOutput }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section v-if="inventory" class="host-inventory card">
|
||||
@@ -177,6 +197,8 @@ import {
|
||||
fetchHost,
|
||||
fetchRecentEvents,
|
||||
testHostWinRm,
|
||||
testHostSsh,
|
||||
updateHostAgentViaSsh,
|
||||
type EventListResponse,
|
||||
type HostDetail,
|
||||
} from "../api";
|
||||
@@ -195,6 +217,11 @@ const eventsPageSize = 50;
|
||||
const testingWinRm = ref(false);
|
||||
const winRmTestMessage = ref("");
|
||||
const winRmTestOk = ref(false);
|
||||
const testingSsh = ref(false);
|
||||
const updatingAgent = ref(false);
|
||||
const sshActionMessage = ref("");
|
||||
const sshActionOk = ref(false);
|
||||
const sshActionOutput = ref("");
|
||||
let refreshingLive = false;
|
||||
|
||||
useSacLiveEventStream(() => {
|
||||
@@ -210,6 +237,13 @@ const isWindowsHost = computed(() => {
|
||||
return h.product === "rdp-login-monitor";
|
||||
});
|
||||
|
||||
const isLinuxHost = computed(() => {
|
||||
const h = host.value;
|
||||
if (!h) return false;
|
||||
if ((h.os_family || "").toLowerCase() === "linux") return true;
|
||||
return h.product === "ssh-monitor";
|
||||
});
|
||||
|
||||
const inventory = computed(() => host.value?.inventory ?? null);
|
||||
|
||||
const windowsFields = computed(() => {
|
||||
@@ -289,6 +323,8 @@ async function loadHost() {
|
||||
loading.value = true;
|
||||
error.value = "";
|
||||
winRmTestMessage.value = "";
|
||||
sshActionMessage.value = "";
|
||||
sshActionOutput.value = "";
|
||||
try {
|
||||
host.value = await fetchHost(hostId.value);
|
||||
} catch (e) {
|
||||
@@ -313,6 +349,57 @@ async function runWinRmTest() {
|
||||
}
|
||||
}
|
||||
|
||||
function formatSshOutput(result: { stdout: string | null; stderr: string | null; exit_code: number | null }) {
|
||||
const parts: string[] = [];
|
||||
if (result.stdout?.trim()) {
|
||||
parts.push(result.stdout.trim());
|
||||
}
|
||||
if (result.stderr?.trim()) {
|
||||
parts.push(result.stderr.trim());
|
||||
}
|
||||
if (result.exit_code != null) {
|
||||
parts.push(`exit code: ${result.exit_code}`);
|
||||
}
|
||||
return parts.join("\n\n");
|
||||
}
|
||||
|
||||
async function runSshTest() {
|
||||
testingSsh.value = true;
|
||||
sshActionMessage.value = "";
|
||||
sshActionOutput.value = "";
|
||||
try {
|
||||
const result = await testHostSsh(hostId.value);
|
||||
sshActionOk.value = result.ok;
|
||||
sshActionMessage.value = result.message;
|
||||
sshActionOutput.value = formatSshOutput(result);
|
||||
} catch (e) {
|
||||
sshActionOk.value = false;
|
||||
sshActionMessage.value = e instanceof Error ? e.message : "Ошибка проверки SSH";
|
||||
} finally {
|
||||
testingSsh.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function runAgentUpdate() {
|
||||
updatingAgent.value = true;
|
||||
sshActionMessage.value = "";
|
||||
sshActionOutput.value = "";
|
||||
try {
|
||||
const result = await updateHostAgentViaSsh(hostId.value);
|
||||
sshActionOk.value = result.ok;
|
||||
sshActionMessage.value = result.message;
|
||||
sshActionOutput.value = formatSshOutput(result);
|
||||
if (result.ok) {
|
||||
host.value = await fetchHost(hostId.value);
|
||||
}
|
||||
} catch (e) {
|
||||
sshActionOk.value = false;
|
||||
sshActionMessage.value = e instanceof Error ? e.message : "Ошибка обновления агента";
|
||||
} finally {
|
||||
updatingAgent.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshFromLatestEvent() {
|
||||
if (refreshingLive) return;
|
||||
refreshingLive = true;
|
||||
@@ -380,4 +467,23 @@ watch(
|
||||
.muted {
|
||||
color: #9aa4b2;
|
||||
}
|
||||
|
||||
.host-actions {
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.75rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.host-ssh-output {
|
||||
margin-top: 0.75rem;
|
||||
max-height: 16rem;
|
||||
overflow: auto;
|
||||
padding: 0.75rem;
|
||||
background: #0d1117;
|
||||
border-radius: 6px;
|
||||
font-size: 0.85rem;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user