upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/grasp-audit/src/bin/grasp-audit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'grasp-audit/src/bin/grasp-audit.rs')
-rw-r--r--grasp-audit/src/bin/grasp-audit.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/grasp-audit/src/bin/grasp-audit.rs b/grasp-audit/src/bin/grasp-audit.rs
index d192f04..e77a698 100644
--- a/grasp-audit/src/bin/grasp-audit.rs
+++ b/grasp-audit/src/bin/grasp-audit.rs
@@ -3,6 +3,7 @@
3use clap::{Parser, Subcommand}; 3use clap::{Parser, Subcommand};
4use grasp_audit::*; 4use grasp_audit::*;
5use std::path::PathBuf; 5use std::path::PathBuf;
6use std::time::Duration;
6 7
7#[derive(Parser)] 8#[derive(Parser)]
8#[command(name = "grasp-audit")] 9#[command(name = "grasp-audit")]
@@ -14,6 +15,33 @@ struct Cli {
14 15
15#[derive(Subcommand)] 16#[derive(Subcommand)]
16enum Commands { 17enum Commands {
18 /// Run a probe/smoke test against a server
19 Probe {
20 /// Relay URL (e.g., ws://localhost:7000)
21 #[arg(short, long)]
22 relay: String,
23
24 /// Output machine-readable JSON
25 #[arg(long, default_value_t = false)]
26 json: bool,
27
28 /// Per-step timeout in seconds
29 #[arg(long, default_value_t = 30)]
30 timeout: u64,
31
32 /// Re-run every N seconds (watch mode)
33 #[arg(long)]
34 watch: Option<u64>,
35
36 /// Secret key in nsec bech32 format (for whitelisted relays)
37 #[arg(long)]
38 nsec: Option<String>,
39
40 /// Read-only mode: skip write steps, only check existing repos
41 #[arg(long, default_value_t = false)]
42 read_only: bool,
43 },
44
17 /// Run audit tests against a server 45 /// Run audit tests against a server
18 Audit { 46 Audit {
19 /// Relay URL (e.g., ws://localhost:7000) 47 /// Relay URL (e.g., ws://localhost:7000)
@@ -50,6 +78,53 @@ async fn main() -> Result<()> {
50 let cli = Cli::parse(); 78 let cli = Cli::parse();
51 79
52 match cli.command { 80 match cli.command {
81 Commands::Probe {
82 relay,
83 json,
84 timeout,
85 watch,
86 nsec,
87 read_only,
88 } => {
89 // Parse nsec if provided
90 let keys = if let Some(nsec_str) = nsec {
91 use nostr_sdk::prelude::SecretKey;
92 let sk = SecretKey::from_bech32(&nsec_str)
93 .map_err(|e| anyhow!("Invalid nsec: {}", e))?;
94 Some(Keys::new(sk))
95 } else {
96 None
97 };
98
99 if let Some(interval) = watch {
100 let mut run = 1u64;
101 loop {
102 println!("\n[Run {}]", run);
103 let report =
104 grasp_audit::probe::run_probe(&relay, keys.clone(), read_only, timeout)
105 .await;
106 if json {
107 report.print_json();
108 } else {
109 report.print_human();
110 }
111 run += 1;
112 tokio::time::sleep(Duration::from_secs(interval)).await;
113 }
114 } else {
115 let report =
116 grasp_audit::probe::run_probe(&relay, keys, read_only, timeout).await;
117 if json {
118 report.print_json();
119 } else {
120 report.print_human();
121 }
122 if !report.all_passed {
123 std::process::exit(1);
124 }
125 }
126 }
127
53 Commands::Audit { 128 Commands::Audit {
54 relay, 129 relay,
55 mode, 130 mode,