Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands - CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround - CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check - NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere - MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates - LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference Co-authored-by: Cursor <cursoragent@cursor.com>
261 lines
8.9 KiB
Bash
Executable File
261 lines
8.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Export NPMplus configuration (proxy hosts and certificates)
|
|
# Verifies configuration matches documentation
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
EVIDENCE_DIR="$PROJECT_ROOT/docs/04-configuration/verification-evidence"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[✗]${NC} $1"; }
|
|
|
|
cd "$PROJECT_ROOT"
|
|
|
|
# Source .env
|
|
if [ -f .env ]; then
|
|
set +euo pipefail
|
|
source .env 2>/dev/null || true
|
|
set -euo pipefail
|
|
fi
|
|
|
|
NPM_URL="${NPM_URL:-https://192.168.11.167:81}"
|
|
NPM_EMAIL="${NPM_EMAIL:-nsatoshi2007@hotmail.com}"
|
|
NPM_PASSWORD="${NPM_PASSWORD:-}"
|
|
NPMPLUS_VMID="${NPMPLUS_VMID:-${NPM_VMID:-10233}}"
|
|
NPMPLUS_HOST="${NPMPLUS_HOST:-${NPM_PROXMOX_HOST:-${PROXMOX_HOST:-192.168.11.11}}}"
|
|
|
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
OUTPUT_DIR="$EVIDENCE_DIR/npmplus-verification-$TIMESTAMP"
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "🔍 NPMplus Configuration Verification & Export"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
# Authenticate to NPMplus
|
|
log_info "Authenticating to NPMplus..."
|
|
|
|
if [ -z "$NPM_PASSWORD" ]; then
|
|
log_error "NPM_PASSWORD not found in .env"
|
|
exit 1
|
|
fi
|
|
|
|
TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD\"}")
|
|
|
|
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token // empty' 2>/dev/null || echo "")
|
|
|
|
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
|
|
ERROR_MSG=$(echo "$TOKEN_RESPONSE" | jq -r '.error.message // "Unknown error"' 2>/dev/null || echo "$TOKEN_RESPONSE")
|
|
log_error "Authentication failed: $ERROR_MSG"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "Authentication successful"
|
|
echo ""
|
|
|
|
# Verify container status
|
|
log_info "Verifying NPMplus container status..."
|
|
|
|
CONTAINER_STATUS=$(ssh -o StrictHostKeyChecking=no root@"$NPMPLUS_HOST" "pct status $NPMPLUS_VMID 2>/dev/null || echo 'not-found'" 2>/dev/null || echo "unknown")
|
|
|
|
if echo "$CONTAINER_STATUS" | grep -q "running"; then
|
|
log_success "Container VMID $NPMPLUS_VMID is running"
|
|
elif echo "$CONTAINER_STATUS" | grep -q "stopped"; then
|
|
log_warn "Container VMID $NPMPLUS_VMID is stopped"
|
|
else
|
|
log_warn "Could not determine container status"
|
|
fi
|
|
|
|
# Get container IP
|
|
CONTAINER_IP=$(ssh -o StrictHostKeyChecking=no root@"$NPMPLUS_HOST" "pct config $NPMPLUS_VMID 2>/dev/null | grep -E '^ip[0-9]+' | head -1 | awk -F'=' '{print \$2}' | awk '{print \$1}'" 2>/dev/null || echo "")
|
|
if [ -n "$CONTAINER_IP" ]; then
|
|
log_info "Container IP: $CONTAINER_IP"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# Export proxy hosts
|
|
log_info "Exporting proxy hosts..."
|
|
|
|
PROXY_HOSTS_RESPONSE=$(curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts" \
|
|
-H "Authorization: Bearer $TOKEN")
|
|
|
|
if [ $? -ne 0 ]; then
|
|
log_error "Failed to fetch proxy hosts"
|
|
exit 1
|
|
fi
|
|
|
|
PROXY_HOSTS=$(echo "$PROXY_HOSTS_RESPONSE" | jq '.' 2>/dev/null || echo "[]")
|
|
echo "$PROXY_HOSTS" > "$OUTPUT_DIR/proxy_hosts.json"
|
|
|
|
PROXY_HOST_COUNT=$(echo "$PROXY_HOSTS" | jq '. | length' 2>/dev/null || echo "0")
|
|
log_success "Exported $PROXY_HOST_COUNT proxy hosts"
|
|
|
|
# Export certificates
|
|
log_info "Exporting SSL certificates..."
|
|
|
|
CERTIFICATES_RESPONSE=$(curl -s -k -X GET "$NPM_URL/api/nginx/certificates" \
|
|
-H "Authorization: Bearer $TOKEN")
|
|
|
|
if [ $? -ne 0 ]; then
|
|
log_error "Failed to fetch certificates"
|
|
exit 1
|
|
fi
|
|
|
|
CERTIFICATES=$(echo "$CERTIFICATES_RESPONSE" | jq '.' 2>/dev/null || echo "[]")
|
|
echo "$CERTIFICATES" > "$OUTPUT_DIR/certificates.json"
|
|
|
|
CERT_COUNT=$(echo "$CERTIFICATES" | jq '. | length' 2>/dev/null || echo "0")
|
|
log_success "Exported $CERT_COUNT certificates"
|
|
|
|
# Verify certificate files on disk
|
|
log_info ""
|
|
log_info "Verifying certificate files on disk..."
|
|
|
|
VERIFIED_CERTS=0
|
|
MISSING_CERTS=0
|
|
|
|
CERT_VERIFICATION=()
|
|
|
|
while IFS= read -r cert; do
|
|
cert_id=$(echo "$cert" | jq -r '.id' 2>/dev/null || echo "")
|
|
cert_name=$(echo "$cert" | jq -r '.nice_name // "cert-'$cert_id'"' 2>/dev/null || echo "")
|
|
domains=$(echo "$cert" | jq -r '.domain_names | join(", ")' 2>/dev/null || echo "")
|
|
|
|
if [ -z "$cert_id" ] || [ "$cert_id" = "null" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Check certificate files in container
|
|
CERT_DIR="/data/tls/certbot/live/npm-$cert_id"
|
|
|
|
fullchain_exists=$(ssh -o StrictHostKeyChecking=no root@"$NPMPLUS_HOST" \
|
|
"pct exec $NPMPLUS_VMID -- test -f $CERT_DIR/fullchain.pem && echo 'yes' || echo 'no'" 2>/dev/null || echo "unknown")
|
|
|
|
privkey_exists=$(ssh -o StrictHostKeyChecking=no root@"$NPMPLUS_HOST" \
|
|
"pct exec $NPMPLUS_VMID -- test -f $CERT_DIR/privkey.pem && echo 'yes' || echo 'no'" 2>/dev/null || echo "unknown")
|
|
|
|
# Get certificate expiration from file if it exists
|
|
expires_from_file=""
|
|
if [ "$fullchain_exists" = "yes" ]; then
|
|
expires_from_file=$(ssh -o StrictHostKeyChecking=no root@"$NPMPLUS_HOST" \
|
|
"pct exec $NPMPLUS_VMID -- openssl x509 -in $CERT_DIR/fullchain.pem -noout -enddate 2>/dev/null | cut -d= -f2" 2>/dev/null || echo "")
|
|
fi
|
|
|
|
if [ "$fullchain_exists" = "yes" ] && [ "$privkey_exists" = "yes" ]; then
|
|
VERIFIED_CERTS=$((VERIFIED_CERTS + 1))
|
|
log_success "Cert ID $cert_id ($cert_name): Files exist"
|
|
if [ -n "$expires_from_file" ]; then
|
|
log_info " Expires: $expires_from_file"
|
|
fi
|
|
else
|
|
MISSING_CERTS=$((MISSING_CERTS + 1))
|
|
log_warn "Cert ID $cert_id ($cert_name): Files missing"
|
|
fi
|
|
|
|
CERT_VERIFICATION+=("{\"cert_id\":$cert_id,\"cert_name\":\"$cert_name\",\"domains\":\"$domains\",\"fullchain_exists\":\"$fullchain_exists\",\"privkey_exists\":\"$privkey_exists\",\"expires_from_file\":\"$expires_from_file\"}")
|
|
done < <(echo "$CERTIFICATES" | jq -c '.[]' 2>/dev/null || true)
|
|
|
|
# Write certificate verification results
|
|
echo "${CERT_VERIFICATION[@]}" | jq -s '.' > "$OUTPUT_DIR/certificate_verification.json"
|
|
|
|
# Generate report
|
|
REPORT_FILE="$OUTPUT_DIR/verification_report.md"
|
|
cat > "$REPORT_FILE" <<EOF
|
|
# NPMplus Configuration Verification Report
|
|
|
|
**Date**: $(date -Iseconds)
|
|
**NPMplus URL**: $NPM_URL
|
|
**Container VMID**: $NPMPLUS_VMID
|
|
**Container Host**: $NPMPLUS_HOST
|
|
**Verifier**: $(whoami)
|
|
|
|
## Summary
|
|
|
|
| Component | Count |
|
|
|-----------|-------|
|
|
| Proxy Hosts | $PROXY_HOST_COUNT |
|
|
| SSL Certificates | $CERT_COUNT |
|
|
| Verified Certificate Files | $VERIFIED_CERTS |
|
|
| Missing Certificate Files | $MISSING_CERTS |
|
|
|
|
## Container Status
|
|
|
|
- **VMID**: $NPMPLUS_VMID
|
|
- **Host**: $NPMPLUS_HOST
|
|
- **Status**: $CONTAINER_STATUS
|
|
- **Container IP**: ${CONTAINER_IP:-unknown}
|
|
|
|
## Proxy Hosts
|
|
|
|
Exported $PROXY_HOST_COUNT proxy hosts. See \`proxy_hosts.json\` for complete details.
|
|
|
|
## SSL Certificates
|
|
|
|
Exported $CERT_COUNT certificates. Certificate file verification:
|
|
|
|
EOF
|
|
|
|
for cert_ver in "${CERT_VERIFICATION[@]}"; do
|
|
cert_id=$(echo "$cert_ver" | jq -r '.cert_id' 2>/dev/null || echo "")
|
|
cert_name=$(echo "$cert_ver" | jq -r '.cert_name' 2>/dev/null || echo "")
|
|
domains=$(echo "$cert_ver" | jq -r '.domains' 2>/dev/null || echo "")
|
|
fullchain_exists=$(echo "$cert_ver" | jq -r '.fullchain_exists' 2>/dev/null || echo "")
|
|
privkey_exists=$(echo "$cert_ver" | jq -r '.privkey_exists' 2>/dev/null || echo "")
|
|
expires=$(echo "$cert_ver" | jq -r '.expires_from_file' 2>/dev/null || echo "")
|
|
|
|
status_icon="❌"
|
|
if [ "$fullchain_exists" = "yes" ] && [ "$privkey_exists" = "yes" ]; then
|
|
status_icon="✅"
|
|
fi
|
|
|
|
echo "" >> "$REPORT_FILE"
|
|
echo "### Cert ID $cert_id: $cert_name" >> "$REPORT_FILE"
|
|
echo "- Domains: $domains" >> "$REPORT_FILE"
|
|
echo "- Fullchain: $fullchain_exists $status_icon" >> "$REPORT_FILE"
|
|
echo "- Privkey: $privkey_exists $status_icon" >> "$REPORT_FILE"
|
|
if [ -n "$expires" ]; then
|
|
echo "- Expires: $expires" >> "$REPORT_FILE"
|
|
fi
|
|
done
|
|
|
|
cat >> "$REPORT_FILE" <<EOF
|
|
|
|
## Files Generated
|
|
|
|
- \`proxy_hosts.json\` - Complete proxy hosts export
|
|
- \`certificates.json\` - Complete certificates export
|
|
- \`certificate_verification.json\` - Certificate file verification results
|
|
- \`verification_report.md\` - This report
|
|
|
|
## Next Steps
|
|
|
|
1. Review proxy hosts configuration
|
|
2. Verify certificate files match API data
|
|
3. Check for any missing certificate files
|
|
4. Update source-of-truth JSON after verification
|
|
EOF
|
|
|
|
log_info ""
|
|
log_info "Verification complete!"
|
|
log_success "Proxy hosts export: $OUTPUT_DIR/proxy_hosts.json"
|
|
log_success "Certificates export: $OUTPUT_DIR/certificates.json"
|
|
log_success "Report: $REPORT_FILE"
|
|
log_info "Summary: $PROXY_HOST_COUNT proxy hosts, $CERT_COUNT certificates, $VERIFIED_CERTS verified cert files"
|