docs(public): sanitize release materials

This commit is contained in:
igor04091968
2026-06-03 08:52:20 +03:00
parent 18653e1a2f
commit a1801fca5f
175 changed files with 1121 additions and 17893 deletions
+9 -9
View File
@@ -954,7 +954,7 @@ systemctl is-active tsj-guardian-bot tsj-guardian-watchdog gost-tg
- read-only SQLite audit показал, что `/var/lib/activitywatch/aw-server-rust/sqlite.db`
занимает около `6.8G`, `freelist_count=0`; VACUUM сам по себе не
освободит место, потому что размер занят live events;
- основной источник роста: `aw-session-events_SHARKON2025` - около
- основной источник роста: `aw-session-events_HOST-EXAMPLE` - около
`6.9M` строк и `~5GB` payload, с пиками `1.2M-2.4M` process-level
событий в сутки за 2026-05-29..2026-06-01;
- production live config на RDP был `pollSeconds=5` и
@@ -967,7 +967,7 @@ systemctl is-active tsj-guardian-bot tsj-guardian-watchdog gost-tg
`C:\ProgramData\AWatch-rus\switch-backups\deployment-config.before-disable-process-events-20260602T061836Z.json`;
- старый `worktime-session-collector.ps1` PID `8476` остановлен, collector
поднят заново штатными `ActivityWatch Launch [...]` tasks/guard;
- delta-gate: `metadata.end` bucket `aw-session-events_SHARKON2025`
- delta-gate: `metadata.end` bucket `aw-session-events_HOST-EXAMPLE`
остался `2026-06-02T06:27:11.197Z` через 75 секунд, постоянный поток
остановлен;
- базовый сбор не сломан: `detmir-check --json` OK,
@@ -982,10 +982,10 @@ systemctl is-active tsj-guardian-bot tsj-guardian-watchdog gost-tg
- на время операции остановлены AW-related timers/services и
`activitywatch-server.service`, чтобы не было writer'ов к SQLite;
- scoped delete удалил только события bucket
`aw-session-events_SHARKON2025` с `eventType=process_start` или
`aw-session-events_HOST-EXAMPLE` с `eventType=process_start` или
`eventType=process_stop`;
- удалено `6,906,190` шумных process-level событий;
- сохранены logon events: после trim в `aw-session-events_SHARKON2025`
- сохранены logon events: после trim в `aw-session-events_HOST-EXAMPLE`
осталось `174` события, recent samples имеют `eventType=logon`;
- `PRAGMA integrity_check` до и после `VACUUM`: `ok`;
- DB уменьшилась с `6.8G` до `350M`, rootfs AW server вернулся к
@@ -1108,10 +1108,10 @@ systemctl is-active tsj-guardian-bot tsj-guardian-watchdog gost-tg
- `hardening-recovery.ps1` выполнен по existing
`C:\ProgramData\AWatch-rus\deployment-config.json`; после recovery
config остался `processEventsEnabled=false`, `logonEnabled=true`,
`pollSeconds=5`, users включают `SHARKON2025\Администратор`;
- exact task check: `ActivityWatch Launch [SHARKON2025_Администратор]`
`pollSeconds=5`, users включают `HOST-EXAMPLE\Администратор`;
- exact task check: `ActivityWatch Launch [HOST-EXAMPLE_Администратор]`
существует, ошибочный
`ActivityWatch Launch [SHARKON2025_Administrator]` отсутствует,
`ActivityWatch Launch [HOST-EXAMPLE_Administrator]` отсутствует,
`ActivityWatch Recovery` существует;
- `AWatchRusCollectorGuard` running/automatic; Windows
`validate-deployment.ps1` вернул `overallOk=True`;
@@ -1308,7 +1308,7 @@ systemctl is-active tsj-guardian-bot tsj-guardian-watchdog gost-tg
`dlp_counts={ok:22,warn:0,fail:0}` and `ok_for_operator=true`.
46. `[done]` Перенести Proxmox DetMir contour smoke на Rust-first helper:
- добавлен crate `aw-contour-smoke`;
- `scripts/aw-contour-smoke-<GATEWAY_HOST>.sh` теперь Rust-first wrapper:
- `scripts/aw-contour-smoke-gateway.sh` теперь Rust-first wrapper:
ищет `AW_CONTOUR_SMOKE_RUST`,
`$CARGO_TARGET_DIR/release/aw-contour-smoke`,
`adk-rust/target/release/aw-contour-smoke`,
@@ -1575,7 +1575,7 @@ systemctl is-active tsj-guardian-bot tsj-guardian-watchdog gost-tg
`.playwright-cli/page-2026-06-02T17-34-04-725Z.png`.
- portal link repair after Grafana/gateway smoke: quick links now open in a
separate tab, `worktime_report` points to explicit HTML
`/reports/worktime/management?format=html&host=SHARKON2025`,
`/reports/worktime/management?format=html&host=HOST-EXAMPLE`,
`1С действия` is shown in the portal, and gateway `/r/aw-worktime` is
pinned to the same HTML report. Production smoke: AW UI, Worktime, 1C
brief, and 1C actions returned `200 text/html`; Grafana links correctly
+11 -11
View File
@@ -116,7 +116,7 @@ fn run_proxmox_remote() -> Result<i32> {
check_tcp(&mut counts, "nginx http", "127.0.0.1", 80);
check_tcp(&mut counts, "nginx https", "127.0.0.1", 443);
check_tcp(&mut counts, "proxmox web", "127.0.0.1", 8006);
check_tcp(&mut counts, "1C company API", "10.10.10.2", 8710);
check_tcp(&mut counts, "1C company API", "192.0.2.2", 8710);
check_tcp(&mut counts, "clickhouse native", "127.0.0.1", 9000);
check_tcp(&mut counts, "clickhouse http", "127.0.0.1", 8123);
if let Ok(out) = command_output("ss", &["-tulpn"]) {
@@ -141,7 +141,7 @@ fn run_proxmox_remote() -> Result<i32> {
"go proxmox gui",
"https://127.0.0.1/go/proxmox-gui",
&[301, 302, 307, 308],
Some("https://10.10.10.2:8006/"),
Some("https://192.0.2.2:8006/"),
);
check_http_redirect(
&mut counts,
@@ -149,7 +149,7 @@ fn run_proxmox_remote() -> Result<i32> {
"go file1c brief",
"https://127.0.0.1/go/file1c-brief",
&[301, 302, 307, 308],
Some("http://10.10.10.2:8710/manager/brief"),
Some("http://192.0.2.2:8710/manager/brief"),
);
check_http_redirect(
&mut counts,
@@ -157,7 +157,7 @@ fn run_proxmox_remote() -> Result<i32> {
"go file1c actions",
"https://127.0.0.1/go/file1c-actions",
&[301, 302, 307, 308],
Some("http://10.10.10.2:8710/manager/actions"),
Some("http://192.0.2.2:8710/manager/actions"),
);
section("1C Company API");
@@ -165,24 +165,24 @@ fn run_proxmox_remote() -> Result<i32> {
&mut counts,
&no_redirect_http,
"1C root redirect",
"http://10.10.10.2:8710/",
"http://192.0.2.2:8710/",
&[307],
);
for (name, url) in [
("1C /health", "http://10.10.10.2:8710/health"),
("1C /api/health", "http://10.10.10.2:8710/api/health"),
("1C manager brief", "http://10.10.10.2:8710/manager/brief"),
("1C /health", "http://192.0.2.2:8710/health"),
("1C /api/health", "http://192.0.2.2:8710/api/health"),
("1C manager brief", "http://192.0.2.2:8710/manager/brief"),
(
"1C manager actions",
"http://10.10.10.2:8710/manager/actions",
"http://192.0.2.2:8710/manager/actions",
),
(
"1C manager recovery",
"http://10.10.10.2:8710/manager/recovery",
"http://192.0.2.2:8710/manager/recovery",
),
(
"1C weekly digest",
"http://10.10.10.2:8710/manager/digest/weekly",
"http://192.0.2.2:8710/manager/digest/weekly",
),
] {
check_http_code(&mut counts, &http, name, url, &[200]);
+1 -1
View File
@@ -9,7 +9,7 @@ use serde::Serialize;
use serde_json::{Value, json};
const DEFAULT_DB_PATH: &str = "/var/lib/activitywatch/aw-server-rust/sqlite.db";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
#[derive(Debug, Parser)]
#[command(author, version, about = "Read-only ActivityWatch SQLite growth guard")]
@@ -11,7 +11,7 @@ use serde_json::Value;
const DEFAULT_DB_PATH: &str = "/var/lib/activitywatch/aw-server-rust/sqlite.db";
const DEFAULT_BACKUP_DIR: &str = "/var/lib/activitywatch/backups/db";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
const ALLOWED_EVENT_TYPES: &[&str] = &["process_start", "process_stop"];
#[derive(Debug, Parser)]
+2 -2
View File
@@ -472,14 +472,14 @@ mod tests {
r#"
# comment
AW_EXPECT_START_OF_DAY="00:00"
AW_EXPECT_LANDINGPAGE=/#/activity/SHARKON2025/view/
AW_EXPECT_LANDINGPAGE=/#/activity/HOST-EXAMPLE/view/
BAD KEY=value
"#,
);
assert_eq!(parsed.get("AW_EXPECT_START_OF_DAY").unwrap(), "00:00");
assert_eq!(
parsed.get("AW_EXPECT_LANDINGPAGE").unwrap(),
"/#/activity/SHARKON2025/view/"
"/#/activity/HOST-EXAMPLE/view/"
);
assert!(!parsed.contains_key("BAD KEY"));
}
+2 -2
View File
@@ -24,7 +24,7 @@ struct Cli {
#[arg(long)]
legacy_script: PathBuf,
#[arg(long, default_value = "10.10.10.13")]
#[arg(long, default_value = "192.0.2.13")]
server_host: String,
#[arg(long, default_value = "5600")]
@@ -249,7 +249,7 @@ mod tests {
let cli = Cli {
kind: InstallKind::Client,
legacy_script: script,
server_host: "10.10.10.13".to_string(),
server_host: "192.0.2.13".to_string(),
server_port: "5600".to_string(),
poll_interval: "5".to_string(),
version: "0.13.2".to_string(),
+2 -2
View File
@@ -25,10 +25,10 @@ struct Cli {
#[arg(long, default_value = "http://127.0.0.1:5610")]
worktime_api: String,
#[arg(long, default_value = "192.168.100.18")]
#[arg(long, default_value = "198.51.100.18")]
rdp_host: String,
#[arg(long, default_value = "SHARKON2025")]
#[arg(long, default_value = "HOST-EXAMPLE")]
rdp_hostname: String,
#[arg(long, default_value = "/var/lib/activitywatch/health")]
+1 -1
View File
@@ -53,7 +53,7 @@ struct Cli {
#[arg(long, default_value = "http://127.0.0.1:5610")]
worktime_base: String,
#[arg(long, default_value = "SHARKON2025")]
#[arg(long, default_value = "HOST-EXAMPLE")]
host: String,
#[arg(long, default_value_t = 99.97)]
+5 -5
View File
@@ -7,8 +7,8 @@ use clap::Parser;
use reqwest::blocking::Client;
use serde_json::Value;
const DEFAULT_SERVER: &str = "http://10.10.10.13:5600";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_SERVER: &str = "http://192.0.2.13:5600";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
const BUCKETS: &[&str] = &[
"aw-dlp-endpoint-signals",
"aw-dlp-incidents",
@@ -410,7 +410,7 @@ fn get_json(client: &Client, url: &str, _timeout_seconds: u64) -> Result<Value>
}
fn check_cors(_client: &Client, server: &str) -> u16 {
let origin = "http://10.10.10.13:5600";
let origin = "http://192.0.2.13:5600";
let first = curl_status(&format!("{server}/api/0/settings/"), origin);
if first == 200 {
return first;
@@ -532,7 +532,7 @@ mod tests {
#[test]
fn metadata_only_bucket_event_skips_missing_deep_event_read() {
let index = serde_json::json!({
"aw-watcher-window_SHARKON2025": {
"aw-watcher-window_HOST-EXAMPLE": {
"metadata": {
"end": "2026-06-02T00:00:00Z"
}
@@ -540,7 +540,7 @@ mod tests {
});
let event = bucket_event(
"http://127.0.0.1:1",
"aw-watcher-window_SHARKON2025",
"aw-watcher-window_HOST-EXAMPLE",
Some(&index),
false,
1,
+4 -4
View File
@@ -7,9 +7,9 @@ use clap::Parser;
use reqwest::blocking::Client;
use serde_json::Value;
const DEFAULT_SERVER: &str = "http://10.10.10.13:5600";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_RDP_HOST: &str = "192.168.100.18";
const DEFAULT_SERVER: &str = "http://192.0.2.13:5600";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
const DEFAULT_RDP_HOST: &str = "198.51.100.18";
const BUCKETS: &[(&str, &str)] = &[
("aw-watcher-afk", "AFK watcher"),
("aw-watcher-window", "Window watcher"),
@@ -423,7 +423,7 @@ fn check_cors(client: &Client, server: &str) -> u16 {
let url = format!("{server}/api/0/settings/");
client
.get(&url)
.header("Origin", "http://10.10.10.13:5600")
.header("Origin", "http://192.0.2.13:5600")
.send()
.map(|response| response.status().as_u16())
.unwrap_or(0)
@@ -270,9 +270,9 @@ mod tests {
let kit = root.join("install-kit-awindows-20260427-211240");
fs::create_dir_all(&kit).unwrap();
fs::write(kit.join("unexpected.txt"), "kit").unwrap();
fs::create_dir_all(kit.join("server-configs-192.168.100.18")).unwrap();
fs::create_dir_all(kit.join("server-configs-198.51.100.18")).unwrap();
fs::write(
kit.join("server-configs-192.168.100.18/config.deployment-config.json"),
kit.join("server-configs-198.51.100.18/config.deployment-config.json"),
"{}",
)
.unwrap();
+6 -6
View File
@@ -12,10 +12,10 @@ use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
use serde::Serialize;
use serde_json::Value;
const DEFAULT_AW_API: &str = "http://10.10.10.13:5600/api/0";
const DEFAULT_WORKTIME_URL: &str = "http://10.10.10.13:5610";
const DEFAULT_ONE_C_URL: &str = "http://10.10.10.2:8710";
const DEFAULT_HOSTNAME: &str = "SHARKON2025";
const DEFAULT_AW_API: &str = "http://192.0.2.13:5600/api/0";
const DEFAULT_WORKTIME_URL: &str = "http://192.0.2.13:5610";
const DEFAULT_ONE_C_URL: &str = "http://192.0.2.2:8710";
const DEFAULT_HOSTNAME: &str = "HOST-EXAMPLE";
const DEFAULT_GATEWAY_HOST: &str = "detmir.example.local";
#[derive(Debug, Parser)]
@@ -298,13 +298,13 @@ fn service_checks(args: &Cli) -> Vec<ServiceCheck> {
}
checks.push(tcp_check(
"192.168.100.18",
"198.51.100.18",
5985,
args.tcp_timeout_seconds,
true,
));
checks.push(tcp_check(
"192.168.100.18",
"198.51.100.18",
22,
args.tcp_timeout_seconds,
true,
+1 -1
View File
@@ -4,7 +4,7 @@ use std::process::Command;
use anyhow::{Context, Result};
use clap::Parser;
const DEFAULT_SSH_TARGET: &str = "igor@10.10.10.13";
const DEFAULT_SSH_TARGET: &str = "igor@192.0.2.13";
const DEFAULT_REMOTE_COMMAND: &str = "sudo -n /usr/local/bin/dlp-health-check --json";
#[derive(Debug, Parser)]
@@ -12,7 +12,7 @@ use serde_json::{Value, json};
const DEFAULT_GRAFANA_URL: &str = "http://127.0.0.1:3000";
const DEFAULT_DASHBOARD_UID: &str = "detmir-aw-main";
const DEFAULT_DASHBOARD_FILE: &str = "/etc/grafana/provisioning/dashboards/aw/detmir-aw-main.json";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
const OLD_MEASUREMENTS: &[&str] = &["aw_window_event", "aw_afk_event"];
const REQUIRED_MEASUREMENTS: &[&str] = &[
"aw_rdp_worktime_hourly",
@@ -670,9 +670,9 @@ mod tests {
assert_eq!(
render_query_vars(
"r.host == \"${host}\" or r.host == \"$host\"",
"SHARKON2025"
"HOST-EXAMPLE"
),
"r.host == \"SHARKON2025\" or r.host == \"SHARKON2025\""
"r.host == \"HOST-EXAMPLE\" or r.host == \"HOST-EXAMPLE\""
);
}
+1 -1
View File
@@ -6,7 +6,7 @@ use clap::Parser;
use detmir_core::{exit_codes, now_utc_rfc3339};
use serde::Serialize;
const DEFAULT_SSH_TARGET: &str = "igor@10.10.10.13";
const DEFAULT_SSH_TARGET: &str = "igor@192.0.2.13";
const REQUIRED_UNITS: &[&str] = &[
"activitywatch-server.service",
"aw-worktime-api.service",
+4 -4
View File
@@ -52,14 +52,14 @@ struct Cli {
#[arg(
long,
default_value = "http://10.10.10.13:5610",
default_value = "http://192.0.2.13:5610",
env = "DETMIR_PORTAL_WORKTIME_URL"
)]
worktime_url: String,
#[arg(
long,
default_value = "http://10.10.10.2:8710",
default_value = "http://192.0.2.2:8710",
env = "DETMIR_PORTAL_ONE_C_URL"
)]
one_c_url: String,
@@ -1836,7 +1836,7 @@ fn links() -> PortalLinks {
portal: "/portal/".to_string(),
grafana_dashboards: "/dashboards".to_string(),
detmir_activitywatch:
"/d/detmir-aw-main/detmir-activitywatch?orgId=1&from=now-48h&to=now&timezone=browser&var-host=SHARKON2025&refresh=5m"
"/d/detmir-aw-main/detmir-activitywatch?orgId=1&from=now-48h&to=now&timezone=browser&var-host=HOST-EXAMPLE&refresh=5m"
.to_string(),
dlp_security_dashboard:
"/d/detmir-dlp-security?orgId=1&from=now-30d&to=now&timezone=browser".to_string(),
@@ -1845,7 +1845,7 @@ fn links() -> PortalLinks {
dlp_overview_dashboard:
"/d/awatch-dlp-overview?orgId=1&from=now-30d&to=now&timezone=browser".to_string(),
aw_ui: "/r/aw/".to_string(),
worktime_report: "/reports/worktime/management?format=html&host=SHARKON2025".to_string(),
worktime_report: "/reports/worktime/management?format=html&host=HOST-EXAMPLE".to_string(),
file1c_brief: "/r/file1c/brief".to_string(),
file1c_actions: "/r/file1c/actions".to_string(),
}
@@ -136,20 +136,20 @@ fn seed_server_dlp_events(inventory: &str) -> Result<()> {
let ts = Utc::now().format("%Y-%m-%dT%H:%M:%SZ");
let script = format!(
r#"cat >/tmp/aw-endpoint-seed.json <<'JSON'
{{"timestamp":"{ts}","duration":0.0,"data":{{"hostname":"SHARKON2025","signalType":"self_test","source":"diag_and_manual_restart","username":"system","queueDepth":0,"eventsEnqueued":0,"eventsFlushed":0,"sendFailures":0}}}}
{{"timestamp":"{ts}","duration":0.0,"data":{{"hostname":"HOST-EXAMPLE","signalType":"self_test","source":"diag_and_manual_restart","username":"system","queueDepth":0,"eventsEnqueued":0,"eventsFlushed":0,"sendFailures":0}}}}
JSON
cat >/tmp/aw-fileops-seed-host.json <<'JSON'
{{"timestamp":"{ts}","duration":0.0,"data":{{"hostname":"SHARKON2025","operation":"self_test","source":"diag_and_manual_restart"}}}}
{{"timestamp":"{ts}","duration":0.0,"data":{{"hostname":"HOST-EXAMPLE","operation":"self_test","source":"diag_and_manual_restart"}}}}
JSON
cat >/tmp/aw-fileops-seed-server.json <<'JSON'
{{"timestamp":"{ts}","duration":0.0,"data":{{"hostname":"10.10.10.13","operation":"self_test","source":"diag_and_manual_restart"}}}}
{{"timestamp":"{ts}","duration":0.0,"data":{{"hostname":"192.0.2.13","operation":"self_test","source":"diag_and_manual_restart"}}}}
JSON
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-dlp-endpoint-signals_SHARKON2025' -H 'Content-Type: application/json' -d '{{"client":"aw-dlp-endpoint-signals","type":"aw.dlp.endpoint.signal","hostname":"SHARKON2025"}}' >/dev/null 2>&1 || true
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-file-operations_SHARKON2025' -H 'Content-Type: application/json' -d '{{"client":"aw-file-operations","type":"aw.file.operation","hostname":"SHARKON2025"}}' >/dev/null 2>&1 || true
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-file-operations_10.10.10.13' -H 'Content-Type: application/json' -d '{{"client":"aw-file-operations","type":"aw.file.operation","hostname":"10.10.10.13"}}' >/dev/null 2>&1 || true
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-dlp-endpoint-signals_SHARKON2025/heartbeat?pulsetime=30' -H 'Content-Type: application/json' --data-binary @/tmp/aw-endpoint-seed.json >/dev/null
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-file-operations_SHARKON2025/heartbeat?pulsetime=30' -H 'Content-Type: application/json' --data-binary @/tmp/aw-fileops-seed-host.json >/dev/null
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-file-operations_10.10.10.13/heartbeat?pulsetime=30' -H 'Content-Type: application/json' --data-binary @/tmp/aw-fileops-seed-server.json >/dev/null
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-dlp-endpoint-signals_HOST-EXAMPLE' -H 'Content-Type: application/json' -d '{{"client":"aw-dlp-endpoint-signals","type":"aw.dlp.endpoint.signal","hostname":"HOST-EXAMPLE"}}' >/dev/null 2>&1 || true
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-file-operations_HOST-EXAMPLE' -H 'Content-Type: application/json' -d '{{"client":"aw-file-operations","type":"aw.file.operation","hostname":"HOST-EXAMPLE"}}' >/dev/null 2>&1 || true
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-file-operations_192.0.2.13' -H 'Content-Type: application/json' -d '{{"client":"aw-file-operations","type":"aw.file.operation","hostname":"192.0.2.13"}}' >/dev/null 2>&1 || true
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-dlp-endpoint-signals_HOST-EXAMPLE/heartbeat?pulsetime=30' -H 'Content-Type: application/json' --data-binary @/tmp/aw-endpoint-seed.json >/dev/null
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-file-operations_HOST-EXAMPLE/heartbeat?pulsetime=30' -H 'Content-Type: application/json' --data-binary @/tmp/aw-fileops-seed-host.json >/dev/null
curl -sS -X POST 'http://127.0.0.1:5600/api/0/buckets/aw-file-operations_192.0.2.13/heartbeat?pulsetime=30' -H 'Content-Type: application/json' --data-binary @/tmp/aw-fileops-seed-server.json >/dev/null
"#
);
let _ = ansible_command(
@@ -170,7 +170,7 @@ fn restart_windows_collectors(inventory: &str) {
fn seed_windows_dlp_events(inventory: &str) {
log("Seeding endpoint/file-ops events from aw_windows...");
let script = r#"powershell -NoProfile -ExecutionPolicy Bypass -Command "$ErrorActionPreference = 'Stop'; $ts = (Get-Date).ToUniversalTime().ToString('o'); $api='http://10.10.10.13:5600/api/0'; $endpoint=@{timestamp=$ts;duration=0.0;data=@{hostname='SHARKON2025';signalType='self_test';source='diag_and_manual_restart';username=$env:USERNAME;queueDepth=0;eventsEnqueued=0;eventsFlushed=0;sendFailures=0}} | ConvertTo-Json -Depth 8 -Compress; $fileops=@{timestamp=$ts;duration=0.0;data=@{hostname='SHARKON2025';operation='self_test';source='diag_and_manual_restart';username=$env:USERNAME}} | ConvertTo-Json -Depth 8 -Compress; Invoke-RestMethod -Method Post -Uri $api'/buckets/aw-dlp-endpoint-signals_SHARKON2025' -ContentType 'application/json' -Body '{\"client\":\"aw-dlp-endpoint-signals\",\"type\":\"aw.dlp.endpoint.signal\",\"hostname\":\"SHARKON2025\"}' -TimeoutSec 15 -DisableKeepAlive -ErrorAction SilentlyContinue | Out-Null; Invoke-RestMethod -Method Post -Uri $api'/buckets/aw-file-operations_SHARKON2025' -ContentType 'application/json' -Body '{\"client\":\"aw-file-operations\",\"type\":\"aw.file.operation\",\"hostname\":\"SHARKON2025\"}' -TimeoutSec 15 -DisableKeepAlive -ErrorAction SilentlyContinue | Out-Null; Invoke-RestMethod -Method Post -Uri $api'/buckets/aw-dlp-endpoint-signals_SHARKON2025/heartbeat?pulsetime=30' -ContentType 'application/json' -Body $endpoint -TimeoutSec 15 -DisableKeepAlive | Out-Null; Invoke-RestMethod -Method Post -Uri $api'/buckets/aw-file-operations_SHARKON2025/heartbeat?pulsetime=30' -ContentType 'application/json' -Body $fileops -TimeoutSec 15 -DisableKeepAlive | Out-Null; Write-Output 'windows-dlp-seeded'""#;
let script = r#"powershell -NoProfile -ExecutionPolicy Bypass -Command "$ErrorActionPreference = 'Stop'; $ts = (Get-Date).ToUniversalTime().ToString('o'); $api='http://192.0.2.13:5600/api/0'; $endpoint=@{timestamp=$ts;duration=0.0;data=@{hostname='HOST-EXAMPLE';signalType='self_test';source='diag_and_manual_restart';username=$env:USERNAME;queueDepth=0;eventsEnqueued=0;eventsFlushed=0;sendFailures=0}} | ConvertTo-Json -Depth 8 -Compress; $fileops=@{timestamp=$ts;duration=0.0;data=@{hostname='HOST-EXAMPLE';operation='self_test';source='diag_and_manual_restart';username=$env:USERNAME}} | ConvertTo-Json -Depth 8 -Compress; Invoke-RestMethod -Method Post -Uri $api'/buckets/aw-dlp-endpoint-signals_HOST-EXAMPLE' -ContentType 'application/json' -Body '{\"client\":\"aw-dlp-endpoint-signals\",\"type\":\"aw.dlp.endpoint.signal\",\"hostname\":\"HOST-EXAMPLE\"}' -TimeoutSec 15 -DisableKeepAlive -ErrorAction SilentlyContinue | Out-Null; Invoke-RestMethod -Method Post -Uri $api'/buckets/aw-file-operations_HOST-EXAMPLE' -ContentType 'application/json' -Body '{\"client\":\"aw-file-operations\",\"type\":\"aw.file.operation\",\"hostname\":\"HOST-EXAMPLE\"}' -TimeoutSec 15 -DisableKeepAlive -ErrorAction SilentlyContinue | Out-Null; Invoke-RestMethod -Method Post -Uri $api'/buckets/aw-dlp-endpoint-signals_HOST-EXAMPLE/heartbeat?pulsetime=30' -ContentType 'application/json' -Body $endpoint -TimeoutSec 15 -DisableKeepAlive | Out-Null; Invoke-RestMethod -Method Post -Uri $api'/buckets/aw-file-operations_HOST-EXAMPLE/heartbeat?pulsetime=30' -ContentType 'application/json' -Body $fileops -TimeoutSec 15 -DisableKeepAlive | Out-Null; Write-Output 'windows-dlp-seeded'""#;
let _ = ansible_windows_shell(inventory, script);
}
+3 -3
View File
@@ -1513,18 +1513,18 @@ mod tests {
#[test]
fn transport_counter_key_separates_sessions() {
let data = json!({
"hostname": "SHARKON2025",
"hostname": "HOST-EXAMPLE",
"sessionId": 4,
"username": "USER4"
});
assert_eq!(
transport_counter_key(
"file-operations",
"aw-file-operations_SHARKON2025",
"aw-file-operations_HOST-EXAMPLE",
&data,
"sendFailures"
),
"file-operations:aw-file-operations_SHARKON2025:SHARKON2025:4:USER4:sendFailures"
"file-operations:aw-file-operations_HOST-EXAMPLE:HOST-EXAMPLE:4:USER4:sendFailures"
);
}
+10 -10
View File
@@ -11,7 +11,7 @@ const DEFAULT_AW_API_BASE: &str = "http://127.0.0.1:5600/api/0";
const DEFAULT_CASE_API_BASE: &str = "http://127.0.0.1:5602/api/0/dlp/cases";
const DEFAULT_INFLUX_ORG: &str = "proxmox";
const DEFAULT_INFLUX_BUCKET: &str = "aw_metrics";
const DEFAULT_HOSTS: &str = "SHARKON2025";
const DEFAULT_HOSTS: &str = "HOST-EXAMPLE";
#[derive(Debug, Parser)]
#[command(about = "AW DLP InfluxDB exporter")]
@@ -1009,7 +1009,7 @@ mod tests {
"id": 10,
"timestamp": "2026-05-15T10:00:00Z",
"data": {
"hostname": "SHARKON2025",
"hostname": "HOST-EXAMPLE",
"username": "Администратор",
"signalType": "self_test",
"policyMode": "server",
@@ -1025,7 +1025,7 @@ mod tests {
"id": 11,
"timestamp": "2026-05-15T10:01:00Z",
"data": {
"hostname": "SHARKON2025",
"hostname": "HOST-EXAMPLE",
"username": "Администратор",
"signalType": "print_job",
"source": "endpoint-signals-phase2",
@@ -1034,7 +1034,7 @@ mod tests {
}
}),
];
let lines = build_endpoint_lines("SHARKON2025", &events);
let lines = build_endpoint_lines("HOST-EXAMPLE", &events);
assert!(
lines
.iter()
@@ -1048,13 +1048,13 @@ mod tests {
let item = json!({
"timestamp": "2026-05-15T10:02:00Z",
"data": {
"host": "SHARKON2025",
"host": "HOST-EXAMPLE",
"incident": {"status": "open", "verdict": "incident"},
"sourceBucket": "aw-dlp-endpoint-signals_SHARKON2025",
"sourceBucket": "aw-dlp-endpoint-signals_HOST-EXAMPLE",
"sourceEvent": {
"data": {
"signalType": "print_job",
"hostname": "SHARKON2025",
"hostname": "HOST-EXAMPLE",
"username": "Администратор",
"documentName": "Письмо",
"printerName": "HP",
@@ -1063,7 +1063,7 @@ mod tests {
}
}
});
let normalized = normalize_incident(&item, "SHARKON2025");
let normalized = normalize_incident(&item, "HOST-EXAMPLE");
assert_eq!(normalized.signal_type, "print_job");
assert_eq!(normalized.username, "Администратор");
assert_eq!(normalized.action, "incident");
@@ -1074,7 +1074,7 @@ mod tests {
fn case_lines_emit_case_state() {
let cases = vec![json!({
"id": 28,
"host": "SHARKON2025",
"host": "HOST-EXAMPLE",
"status": "open",
"severity": "medium",
"assignee": null,
@@ -1084,7 +1084,7 @@ mod tests {
"forensics": null,
"updated_at": "2026-05-15T10:03:00+00:00"
})];
let lines = build_case_lines("SHARKON2025", &cases);
let lines = build_case_lines("HOST-EXAMPLE", &cases);
assert_eq!(lines.len(), 1);
assert!(lines[0].starts_with("aw_dlp_case,"));
}
@@ -8,9 +8,9 @@ use chrono::Local;
use clap::Parser;
use serde::Serialize;
const DEFAULT_SERVER_HOST: &str = "10.10.10.13";
const DEFAULT_SERVER_HOST: &str = "192.0.2.13";
const DEFAULT_SERVER_USER: &str = "igor";
const DEFAULT_LEGACY_DB: &str = "/root/.local/share/activitywatch/aw-server-rust/sqlite.db";
const DEFAULT_LEGACY_DB: &str = "/var/lib/activitywatch/aw-server-rust/sqlite.db";
const DEFAULT_TARGET_DB: &str =
"/var/lib/activitywatch/.local/share/activitywatch/aw-server-rust/sqlite.db";
const DEFAULT_REMOTE_MERGE_BIN: &str = "/tmp/merge-aw-server-dbs";
@@ -454,7 +454,7 @@ mod tests {
dir.path(),
&dir.path().join("private-config/runtime.env"),
&env,
"10.10.10.13",
"192.0.2.13",
"igor",
"20260602-000000",
"/var/lib/activitywatch/backups/prod-restore-20260602-000000",
@@ -10,8 +10,8 @@ use reqwest::blocking::Client;
use serde::{Deserialize, Serialize};
use serde_json::Value;
const DEFAULT_AW_BASE_URL: &str = "http://10.10.10.13:5600/api/0";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_AW_BASE_URL: &str = "http://192.0.2.13:5600/api/0";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
const DEFAULT_SAMPLE_SECONDS: f64 = 30.0;
const DEFAULT_MAX_SAMPLE_SECONDS: f64 = 300.0;
const DEFAULT_OUT_DIR: &str = "reports";
@@ -550,7 +550,7 @@ mod tests {
];
let rows = build_rows(
events,
"SHARKON2025",
"HOST-EXAMPLE",
NaiveDate::from_ymd_opt(2026, 6, 1).unwrap(),
NaiveDate::from_ymd_opt(2026, 6, 1).unwrap(),
30.0,
@@ -563,7 +563,7 @@ mod tests {
assert_eq!(rows[0].sessions_count, 2);
assert_eq!(rows[0].samples_count, 3);
assert_eq!(rows[0].active_samples, 2);
assert_eq!(rows[0].user_id, "SHARKON2025\\user5");
assert_eq!(rows[0].user_id, "HOST-EXAMPLE\\user5");
}
#[test]
@@ -388,7 +388,7 @@ fn suggestions_from_failures(failures: &[String]) -> Vec<String> {
}
if text.contains("pfsense_web") {
suggestions
.push("Проверить доступность pfSense 10.10.10.1:8443, перезапустить WebGUI/nginx.");
.push("Проверить доступность pfSense 192.0.2.1:8443, перезапустить WebGUI/nginx.");
}
if text.contains("pfsense_mcp") {
suggestions.push("Проверить локальный pfsense-mcp-server.service, bearer token и endpoint 127.0.0.1:3010/mcp.");
@@ -397,18 +397,18 @@ fn suggestions_from_failures(failures: &[String]) -> Vec<String> {
suggestions.push("Проверить контейнер InfluxDB и restart сервиса influxdb.");
}
if text.contains("grafana") {
suggestions.push("Проверить grafana-server и NO_PROXY для 10.10.10.0/24.");
suggestions.push("Проверить grafana-server и NO_PROXY для 192.0.2.0/24.");
}
if text.contains("loki") || text.contains("alloy") {
suggestions.push("Проверить LXC логов и restart сервисов loki/alloy.");
}
if text.contains("aw-rus:watcher-") || text.contains("aw-rus:worktime:") {
suggestions.push("Проверить Windows collector recovery: worktime-session-collector, ActivityWatch Recovery и Launch tasks на 192.168.100.18.");
suggestions.push("Проверить Windows collector recovery: worktime-session-collector, ActivityWatch Recovery и Launch tasks на 198.51.100.18.");
suggestions.push("После Windows recovery проверить server-side aw-worktime-autoheal/ui-bridge для пересборки afk/window bucket'ов.");
}
if text.contains("aw-rus:dlp-") {
suggestions.push(
"Проверить DLP endpoint/fileops collectors и server-side DLP transport на 10.10.10.13.",
"Проверить DLP endpoint/fileops collectors и server-side DLP transport на 192.0.2.13.",
);
}
if text.contains("filesystem_usage") {
@@ -11,7 +11,8 @@ use serde::Serialize;
const DEFAULT_HEARTBEAT_FILE: &str = "/opt/infra-admin/.state/tsj_guardian_heartbeat";
const DEFAULT_SERVICE_NAME: &str = "tsj-guardian-bot.service";
const DEFAULT_GOST_SERVICE_NAME: &str = "gost-tg.service";
const DEFAULT_GOST_PATTERN: &str = "/usr/local/bin/gost -L http+socks5://127.0.0.1:11090 -F socks5+wss://gw.example.local:4443";
const DEFAULT_GOST_PATTERN: &str =
"/usr/local/bin/gost -L http+socks5://127.0.0.1:11090 -F socks5+wss://gw.example.local:4443";
#[derive(Debug, Parser)]
#[command(about = "TSJ Guardian bot heartbeat watchdog and gost duplicate guard.")]
+2 -2
View File
@@ -22,7 +22,7 @@ use tiny_http::{Header, Method, Request, Response, Server, StatusCode};
use url::form_urlencoded;
const DEFAULT_AW_URL: &str = "http://127.0.0.1:5600";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
#[derive(Debug, Parser)]
#[command(about = "AW Worktime Report API")]
@@ -2536,7 +2536,7 @@ mod tests {
],
start,
end,
"SHARKON2025",
"HOST-EXAMPLE",
false,
);
assert_eq!(rows[0]["active_seconds"], 60);
@@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
const DEFAULT_AW_URL: &str = "http://127.0.0.1:5600";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
const AUTOHEAL_SOURCE: &str = "aw-worktime-autoheal";
#[derive(Debug, Parser)]
@@ -11,7 +11,7 @@ const DEFAULT_AW_BASE: &str = "http://127.0.0.1:5600";
const DEFAULT_WORKTIME_REPORT_BASE: &str = "http://127.0.0.1:5610";
const DEFAULT_INFLUX_ORG: &str = "proxmox";
const DEFAULT_INFLUX_BUCKET: &str = "aw_metrics";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
const DEFAULT_DAYS: &str = "today,yesterday";
#[derive(Debug, Parser)]
@@ -993,14 +993,14 @@ mod tests {
fn heartbeat_line_uses_current_exporter_timestamp() {
let out = line(
"aw_worktime_exporter_heartbeat",
vec![("host", "SHARKON2025".to_string())],
vec![("host", "HOST-EXAMPLE".to_string())],
vec![("run", FieldValue::Int(1))],
42,
)
.unwrap();
assert_eq!(
out,
"aw_worktime_exporter_heartbeat,host=SHARKON2025 run=1i 42"
"aw_worktime_exporter_heartbeat,host=HOST-EXAMPLE run=1i 42"
);
}
@@ -1023,11 +1023,11 @@ mod tests {
}
})];
let daily = aggregate_daily_rows(&events, start, end_exclusive, "SHARKON2025", &config);
let hourly = aggregate_hourly_rows(&events, end_exclusive, "SHARKON2025", &config);
let daily = aggregate_daily_rows(&events, start, end_exclusive, "HOST-EXAMPLE", &config);
let hourly = aggregate_hourly_rows(&events, end_exclusive, "HOST-EXAMPLE", &config);
assert_eq!(daily.len(), 1);
assert_eq!(daily[0].user_id, "SHARKON2025\\user5");
assert_eq!(daily[0].user_id, "HOST-EXAMPLE\\user5");
assert_eq!(daily[0].active_seconds, 300);
assert_eq!(daily[0].active_samples, 1);
assert_eq!(hourly.len(), 1);
+1 -1
View File
@@ -7,7 +7,7 @@ use reqwest::blocking::Client;
use serde::Serialize;
const DEFAULT_BASE_URL: &str = "http://127.0.0.1:5610";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
#[derive(Debug, Parser)]
#[command(about = "AW Worktime report cache prewarm")]
@@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
const DEFAULT_AW_URL: &str = "http://127.0.0.1:5600";
const DEFAULT_HOST: &str = "SHARKON2025";
const DEFAULT_HOST: &str = "HOST-EXAMPLE";
const DEFAULT_STATE_PATH: &str = "/var/lib/activitywatch/aw-worktime-ui-bridge-state.json";
const BRIDGE_SOURCE: &str = "aw-worktime-ui-bridge";