Reorganize repo: compartmentalize scripts by client/project
Move 150+ scripts from root and scripts/ into client/project directories: - clients/dataforth/scripts/ (110 files: AD2, sync, SSH, DB, DOS scripts) - clients/bg-builders/scripts/ (14 files: Lesley mgmt, Exchange, termination) - clients/internal-infrastructure/scripts/ (10 files: GDAP, Gitea, backups) - projects/msp-tools/scripts/ (9 files: CIPP, MSP onboarding, Datto) - projects/gururmm-agent/scripts/ (3 files: API test, JWT, record counts) - clients/glaztech/scripts/ (1 file: CentraStage removal) Also reorganized: - VPN scripts → infrastructure/vpn-configs/ - Retrieved API/JS files → api/ - Forum posts → projects/community-forum/forum-posts/ - SSH docs → clients/internal-infrastructure/docs/ - NWTOC/CTONW docs → projects/wrightstown-smarthome/docs/ - ACG website files → projects/internal/acg-website-2025/ - Dataforth docs → clients/dataforth/docs/ - schema-retrieved.sql → docs/database/ Deleted 24 tmp_*.ps1 one-off debug scripts (preserved in git history). Root reduced from 220+ files to 62 items (docs + directories only). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
98
projects/gururmm-agent/scripts/check_record_counts.py
Normal file
98
projects/gururmm-agent/scripts/check_record_counts.py
Normal file
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Check record counts in all ClaudeTools database tables
|
||||
"""
|
||||
import sys
|
||||
from sqlalchemy import create_engine, text, inspect
|
||||
|
||||
# Database connection
|
||||
DATABASE_URL = "mysql+pymysql://claudetools:CT_e8fcd5a3952030a79ed6debae6c954ed@172.16.3.30:3306/claudetools?charset=utf8mb4"
|
||||
|
||||
def get_table_counts():
|
||||
"""Get row counts for all tables"""
|
||||
engine = create_engine(DATABASE_URL)
|
||||
|
||||
with engine.connect() as conn:
|
||||
# Get all table names
|
||||
inspector = inspect(engine)
|
||||
tables = inspector.get_table_names()
|
||||
|
||||
print("=" * 70)
|
||||
print("ClaudeTools Database Record Counts")
|
||||
print("=" * 70)
|
||||
print(f"Database: claudetools @ 172.16.3.30:3306")
|
||||
print(f"Total Tables: {len(tables)}")
|
||||
print("=" * 70)
|
||||
print()
|
||||
|
||||
# Count rows in each table
|
||||
counts = {}
|
||||
total_records = 0
|
||||
|
||||
for table in sorted(tables):
|
||||
result = conn.execute(text(f"SELECT COUNT(*) FROM `{table}`"))
|
||||
count = result.scalar()
|
||||
counts[table] = count
|
||||
total_records += count
|
||||
|
||||
# Group by category
|
||||
categories = {
|
||||
'Core': ['machines', 'clients', 'projects', 'sessions', 'tags'],
|
||||
'MSP Work': ['work_items', 'tasks', 'billable_time', 'work_item_files'],
|
||||
'Infrastructure': ['sites', 'infrastructure', 'services', 'networks', 'firewall_rules', 'm365_tenants', 'm365_licenses'],
|
||||
'Credentials': ['credentials', 'credential_audit_logs', 'security_incidents'],
|
||||
'Context Recall': ['conversation_contexts', 'context_snippets', 'project_states', 'decision_logs'],
|
||||
'Learning': ['command_runs', 'file_changes', 'problem_solutions', 'failure_patterns', 'environmental_insights'],
|
||||
'Integrations': ['msp_integrations', 'backup_jobs', 'backup_reports'],
|
||||
'Junction': ['session_tags', 'session_work_items', 'client_contacts', 'project_repositories']
|
||||
}
|
||||
|
||||
# Print by category
|
||||
for category, table_list in categories.items():
|
||||
category_tables = [t for t in table_list if t in counts]
|
||||
if not category_tables:
|
||||
continue
|
||||
|
||||
print(f"{category}:")
|
||||
print("-" * 70)
|
||||
category_total = 0
|
||||
for table in category_tables:
|
||||
count = counts[table]
|
||||
category_total += count
|
||||
status = "[OK]" if count > 0 else " "
|
||||
print(f" {status} {table:.<50} {count:>10,}")
|
||||
print(f" {'Subtotal':.<50} {category_total:>10,}")
|
||||
print()
|
||||
|
||||
# Print any uncategorized tables
|
||||
all_categorized = set()
|
||||
for table_list in categories.values():
|
||||
all_categorized.update(table_list)
|
||||
|
||||
uncategorized = [t for t in counts.keys() if t not in all_categorized]
|
||||
if uncategorized:
|
||||
print("Other Tables:")
|
||||
print("-" * 70)
|
||||
for table in uncategorized:
|
||||
count = counts[table]
|
||||
status = "[OK]" if count > 0 else " "
|
||||
print(f" {status} {table:.<50} {count:>10,}")
|
||||
print()
|
||||
|
||||
# Print summary
|
||||
print("=" * 70)
|
||||
print(f"TOTAL RECORDS: {total_records:,}")
|
||||
print(f"Tables with data: {sum(1 for c in counts.values() if c > 0)}/{len(tables)}")
|
||||
print("=" * 70)
|
||||
|
||||
return counts, total_records
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
counts, total = get_table_counts()
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print(f"ERROR: {e}", file=sys.stderr)
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
28
projects/gururmm-agent/scripts/create_jwt_token.py
Normal file
28
projects/gururmm-agent/scripts/create_jwt_token.py
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create a JWT token for ClaudeTools API access
|
||||
"""
|
||||
import jwt
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
# 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="
|
||||
|
||||
# Create token data
|
||||
data = {
|
||||
"sub": "import-script",
|
||||
"scopes": ["admin", "import"],
|
||||
"exp": datetime.now(timezone.utc) + timedelta(days=30)
|
||||
}
|
||||
|
||||
# Create token
|
||||
token = jwt.encode(data, JWT_SECRET, algorithm="HS256")
|
||||
|
||||
print(f"New JWT Token:")
|
||||
print(token)
|
||||
print()
|
||||
print(f"Expires: {data['exp']}")
|
||||
print()
|
||||
print("Add this to .claude/context-recall-config.env:")
|
||||
print(f"JWT_TOKEN={token}")
|
||||
145
projects/gururmm-agent/scripts/test_gururmm_api.py
Normal file
145
projects/gururmm-agent/scripts/test_gururmm_api.py
Normal file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GuruRMM API Access Test Script
|
||||
|
||||
Tests the newly created admin user credentials and verifies API access.
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# Configuration
|
||||
API_BASE_URL = "http://172.16.3.30:3001"
|
||||
EMAIL = "claude-api@azcomputerguru.com"
|
||||
PASSWORD = "ClaudeAPI2026!@#"
|
||||
|
||||
def print_header(title):
|
||||
"""Print a formatted header."""
|
||||
print("\n" + "=" * 60)
|
||||
print(f" {title}")
|
||||
print("=" * 60 + "\n")
|
||||
|
||||
def print_success(message):
|
||||
"""Print success message."""
|
||||
print(f"[OK] {message}")
|
||||
|
||||
def print_error(message):
|
||||
"""Print error message."""
|
||||
print(f"[ERROR] {message}")
|
||||
|
||||
def test_login():
|
||||
"""Test login and retrieve JWT token."""
|
||||
print_header("Test 1: Login and Authentication")
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{API_BASE_URL}/api/auth/login",
|
||||
json={"email": EMAIL, "password": PASSWORD},
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
print_error(f"Login failed with status {response.status_code}")
|
||||
print(f"Response: {response.text}")
|
||||
return None
|
||||
|
||||
data = response.json()
|
||||
token = data.get("token")
|
||||
user = data.get("user")
|
||||
|
||||
if not token:
|
||||
print_error("No token in response")
|
||||
return None
|
||||
|
||||
print_success("Login successful")
|
||||
print(f" User ID: {user.get('id')}")
|
||||
print(f" Email: {user.get('email')}")
|
||||
print(f" Name: {user.get('name')}")
|
||||
print(f" Role: {user.get('role')}")
|
||||
print(f" Token: {token[:50]}...")
|
||||
|
||||
return token
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print_error(f"Request failed: {e}")
|
||||
return None
|
||||
|
||||
def test_authenticated_request(token, endpoint, name):
|
||||
"""Test an authenticated API request."""
|
||||
print_header(f"Test: {name}")
|
||||
|
||||
try:
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
response = requests.get(
|
||||
f"{API_BASE_URL}{endpoint}",
|
||||
headers=headers,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
print_error(f"Request failed with status {response.status_code}")
|
||||
print(f"Response: {response.text}")
|
||||
return False
|
||||
|
||||
data = response.json()
|
||||
count = len(data) if isinstance(data, list) else 1
|
||||
|
||||
print_success(f"Retrieved {count} record(s)")
|
||||
|
||||
# Print first record as sample
|
||||
if isinstance(data, list) and data:
|
||||
print("\nSample record:")
|
||||
print(json.dumps(data[0], indent=2))
|
||||
elif isinstance(data, dict):
|
||||
print("\nResponse:")
|
||||
print(json.dumps(data, indent=2)[:500] + "...")
|
||||
|
||||
return True
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print_error(f"Request failed: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""Main test runner."""
|
||||
print_header("GuruRMM API Access Test")
|
||||
print(f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print(f"API Base URL: {API_BASE_URL}")
|
||||
print(f"Test User: {EMAIL}")
|
||||
|
||||
# Test 1: Login
|
||||
token = test_login()
|
||||
if not token:
|
||||
print_error("Login test failed. Aborting remaining tests.")
|
||||
return 1
|
||||
|
||||
# Test 2: Sites endpoint
|
||||
if not test_authenticated_request(token, "/api/sites", "List Sites"):
|
||||
print_error("Sites test failed")
|
||||
return 1
|
||||
|
||||
# Test 3: Agents endpoint
|
||||
if not test_authenticated_request(token, "/api/agents", "List Agents"):
|
||||
print_error("Agents test failed")
|
||||
return 1
|
||||
|
||||
# Test 4: Clients endpoint
|
||||
if not test_authenticated_request(token, "/api/clients", "List Clients"):
|
||||
print_error("Clients test failed")
|
||||
return 1
|
||||
|
||||
# Success summary
|
||||
print_header("All Tests Passed!")
|
||||
print("API Credentials:")
|
||||
print(f" Email: {EMAIL}")
|
||||
print(f" Password: {PASSWORD}")
|
||||
print(f" Base URL: {API_BASE_URL}")
|
||||
print(f" Production URL: https://rmm-api.azcomputerguru.com")
|
||||
print("\nStatus: READY FOR INTEGRATION")
|
||||
print()
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
||||
Reference in New Issue
Block a user