Session log: GuruRMM audit, installer system, infrastructure fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,9 @@
|
||||
**Status:** [OK] Complete - Production Ready
|
||||
**Author:** Coding Agent (Claude Sonnet 4.5)
|
||||
|
||||
**Source Repo:** `azcomputerguru/gururmm` on git.azcomputerguru.com (active development, 53+ commits).
|
||||
Note: A `guru-rmm` repo also exists but is a restructured copy with only 2 commits -- use `gururmm` as the primary reference.
|
||||
|
||||
---
|
||||
|
||||
## What Was Built
|
||||
@@ -187,6 +190,10 @@ once_cell = "1.19"
|
||||
|
||||
Follow instructions in `commands_modifications.rs`:
|
||||
|
||||
> **Note:** `claude_task` is a NEW command type added by this integration. The existing
|
||||
> GuruRMM command types are: `shell`, `powershell`, `python`, `script`. This step adds
|
||||
> `claude_task` as an additional type in the command dispatcher.
|
||||
|
||||
1. Add module declaration: `mod claude;`
|
||||
2. Add imports: `use crate::claude::{ClaudeExecutor, ClaudeTaskCommand};`
|
||||
3. Create global executor: `static CLAUDE_EXECUTOR: Lazy<ClaudeExecutor> = ...`
|
||||
@@ -243,7 +250,9 @@ Follow deployment process in `TESTING_AND_DEPLOYMENT.md`:
|
||||
|
||||
## Usage Example
|
||||
|
||||
Once deployed, Main Claude can invoke tasks on AD2:
|
||||
Once deployed, Main Claude can invoke tasks on AD2. The curl command below creates the
|
||||
command on the server via REST; the server then delivers it to the agent over WebSocket
|
||||
(ServerMessage::Command):
|
||||
|
||||
```bash
|
||||
curl -X POST "http://172.16.3.30:3001/api/agents/{AD2_AGENT_ID}/command" \
|
||||
@@ -394,7 +403,7 @@ A: Check agent logs at `C:\Program Files\GuruRMM\logs\agent.log` for detailed er
|
||||
1. **TESTING_AND_DEPLOYMENT.md** - Complete testing and troubleshooting guide
|
||||
2. **README.md** - Full project documentation with examples
|
||||
3. **Agent logs** - `C:\Program Files\GuruRMM\logs\agent.log`
|
||||
4. **GuruRMM server logs** - `http://172.16.3.30:3001/logs`
|
||||
4. **GuruRMM server logs** - Check server-side logs on disk (no `/logs` HTTP endpoint exists)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -70,6 +70,10 @@ Open your `agent/src/commands.rs` and make these changes:
|
||||
```
|
||||
|
||||
### 3E: Update Command Dispatcher
|
||||
|
||||
> **Note:** `claude_task` is a NEW command type being added by this integration.
|
||||
> The existing GuruRMM command types are: `shell`, `powershell`, `python`, `script`.
|
||||
|
||||
- [ ] Find your `match command_type` block
|
||||
- [ ] Add new arm (before the `_` default case):
|
||||
```rust
|
||||
@@ -158,6 +162,10 @@ Open your `agent/src/commands.rs` and make these changes:
|
||||
|
||||
**Replace `{AD2_AGENT_ID}` with actual agent ID in all commands**
|
||||
|
||||
> The curl commands below create the command on the server via REST. The server then
|
||||
> delivers the command to the agent over WebSocket (ServerMessage::Command) -- the agent
|
||||
> does NOT poll for commands.
|
||||
|
||||
### Test 1: Simple Task
|
||||
- [ ] Run:
|
||||
```bash
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
Production-ready enhancement for GuruRMM agent that enables Main Claude to remotely invoke Claude Code CLI on AD2 (Windows Server 2022) for automated task execution.
|
||||
|
||||
**Source Repo:** `azcomputerguru/gururmm` on git.azcomputerguru.com (active development, 53+ commits).
|
||||
Note: A `guru-rmm` repo also exists but is a restructured copy with only 2 commits -- use `gururmm` as the primary reference.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
@@ -90,6 +93,8 @@ use once_cell::sync::Lazy;
|
||||
static CLAUDE_EXECUTOR: Lazy<ClaudeExecutor> = Lazy::new(|| ClaudeExecutor::new());
|
||||
|
||||
// In your command dispatcher
|
||||
// Existing types: shell, powershell, python, script
|
||||
// claude_task is a NEW type added by this integration
|
||||
match command_type {
|
||||
"shell" => execute_shell_command(&command).await,
|
||||
"claude_task" => execute_claude_task(&command).await, // NEW
|
||||
@@ -127,6 +132,11 @@ See `TESTING_AND_DEPLOYMENT.md` for complete deployment guide.
|
||||
|
||||
## Usage Examples
|
||||
|
||||
> **How commands work:** The curl examples below create the command on the server via
|
||||
> the REST API (`POST /api/agents/:id/command`). The server then delivers the command
|
||||
> to the agent over WebSocket (ServerMessage::Command). The agent does NOT poll for
|
||||
> commands via REST.
|
||||
|
||||
### Example 1: Simple Task
|
||||
|
||||
```bash
|
||||
|
||||
@@ -8,6 +8,9 @@ This guide covers testing and deployment of the Claude Code integration for the
|
||||
|
||||
## Prerequisites
|
||||
|
||||
**Source Repo:** `azcomputerguru/gururmm` on git.azcomputerguru.com (active development, 53+ commits).
|
||||
Note: A `guru-rmm` repo also exists but is a restructured copy with only 2 commits -- use `gururmm` as the primary reference.
|
||||
|
||||
### On Development Machine
|
||||
- Rust toolchain (1.70+)
|
||||
- cargo installed
|
||||
@@ -69,6 +72,14 @@ cargo fmt -- --check
|
||||
|
||||
## Integration Testing (On AD2 Server)
|
||||
|
||||
> **Note:** `claude_task` is a NEW command type added by this integration. The existing
|
||||
> GuruRMM command types are: `shell`, `powershell`, `python`, `script`.
|
||||
>
|
||||
> **How commands reach the agent:** The curl commands below create the command on the
|
||||
> server via the REST API (`POST /api/agents/:id/command`). The server then delivers the
|
||||
> command to the connected agent over WebSocket (ServerMessage::Command). The agent does
|
||||
> NOT poll for commands via REST.
|
||||
|
||||
### Test 1: Simple Task Execution
|
||||
|
||||
**Test Command via GuruRMM API:**
|
||||
@@ -476,7 +487,7 @@ Monitor Claude task execution metrics:
|
||||
|
||||
```powershell
|
||||
# Query GuruRMM API for task statistics
|
||||
curl "http://172.16.3.30:3001/api/agents/{AD2_AGENT_ID}/stats"
|
||||
curl "http://172.16.3.30:3001/api/agents/stats"
|
||||
```
|
||||
|
||||
**Key metrics to watch:**
|
||||
@@ -558,7 +569,7 @@ Prevents abuse:
|
||||
|
||||
For issues or questions:
|
||||
1. Check agent logs: `C:\Program Files\GuruRMM\logs\agent.log`
|
||||
2. Check GuruRMM server logs: `http://172.16.3.30:3001/logs`
|
||||
2. Check GuruRMM server logs on disk (no `/logs` HTTP endpoint exists)
|
||||
3. Review this documentation
|
||||
4. Contact GuruRMM support team
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ Check record counts in all ClaudeTools database tables
|
||||
"""
|
||||
import sys
|
||||
from sqlalchemy import create_engine, text, inspect
|
||||
from vault_utils import vault_get
|
||||
|
||||
# Database connection
|
||||
DATABASE_URL = "mysql+pymysql://claudetools:CT_e8fcd5a3952030a79ed6debae6c954ed@172.16.3.30:3306/claudetools?charset=utf8mb4"
|
||||
# Database connection - credentials from SOPS vault
|
||||
_db_password = vault_get("projects/claudetools/database.sops.yaml", "credentials.password")
|
||||
DATABASE_URL = f"mysql+pymysql://claudetools:{_db_password}@172.16.3.30:3306/claudetools?charset=utf8mb4"
|
||||
|
||||
def get_table_counts():
|
||||
"""Get row counts for all tables"""
|
||||
|
||||
@@ -4,10 +4,10 @@ Create a JWT token for ClaudeTools API access
|
||||
"""
|
||||
import jwt
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from vault_utils import vault_get
|
||||
|
||||
# Get the JWT secret from the RMM server's .env file
|
||||
# This should match what's in /opt/claudetools/.env on 172.16.3.30
|
||||
JWT_SECRET = "NdwgH6jsGR1WfPdUwR3u9i1NwNx3QthhLHBsRCfFxcg="
|
||||
# Get the JWT secret from the SOPS vault
|
||||
JWT_SECRET = vault_get("projects/claudetools/api-auth.sops.yaml", "credentials.credential")
|
||||
|
||||
# Create token data
|
||||
data = {
|
||||
|
||||
@@ -8,11 +8,12 @@ Tests the newly created admin user credentials and verifies API access.
|
||||
import requests
|
||||
import json
|
||||
from datetime import datetime
|
||||
from vault_utils import vault_get
|
||||
|
||||
# Configuration
|
||||
# Configuration - credentials from SOPS vault
|
||||
API_BASE_URL = "http://172.16.3.30:3001"
|
||||
EMAIL = "claude-api@azcomputerguru.com"
|
||||
PASSWORD = "ClaudeAPI2026!@#"
|
||||
EMAIL = vault_get("infrastructure/gururmm-server.sops.yaml", "credentials.gururmm-api.admin-email")
|
||||
PASSWORD = vault_get("infrastructure/gururmm-server.sops.yaml", "credentials.gururmm-api.admin-password")
|
||||
|
||||
def print_header(title):
|
||||
"""Print a formatted header."""
|
||||
@@ -133,7 +134,7 @@ def main():
|
||||
print_header("All Tests Passed!")
|
||||
print("API Credentials:")
|
||||
print(f" Email: {EMAIL}")
|
||||
print(f" Password: {PASSWORD}")
|
||||
print(f" Password: ********** (from vault)")
|
||||
print(f" Base URL: {API_BASE_URL}")
|
||||
print(f" Production URL: https://rmm-api.azcomputerguru.com")
|
||||
print("\nStatus: READY FOR INTEGRATION")
|
||||
|
||||
34
projects/gururmm-agent/scripts/vault_utils.py
Normal file
34
projects/gururmm-agent/scripts/vault_utils.py
Normal file
@@ -0,0 +1,34 @@
|
||||
"""
|
||||
Shared SOPS vault credential retrieval utility.
|
||||
|
||||
Usage:
|
||||
from vault_utils import vault_get
|
||||
|
||||
password = vault_get("projects/claudetools/database.sops.yaml", "credentials.password")
|
||||
"""
|
||||
import subprocess
|
||||
|
||||
|
||||
VAULT_SCRIPT = "D:/vault/scripts/vault.sh"
|
||||
|
||||
|
||||
def vault_get(path, field):
|
||||
"""Get a credential from the SOPS vault.
|
||||
|
||||
Args:
|
||||
path: Vault entry path (e.g. "projects/claudetools/database.sops.yaml")
|
||||
field: Dot-separated field path (e.g. "credentials.password")
|
||||
|
||||
Returns:
|
||||
The decrypted field value as a string.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If the vault command fails.
|
||||
"""
|
||||
result = subprocess.run(
|
||||
["bash", VAULT_SCRIPT, "get-field", path, field],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(f"Failed to get {field} from vault: {result.stderr.strip()}")
|
||||
return result.stdout.strip()
|
||||
Reference in New Issue
Block a user