Skip to content

Commit 7d5cfa3

Browse files
committed
Add Bedrock gateway debug script
Introduces scripts/debug_bedrock_connection.sh to test Bedrock gateway connectivity, including SSL certificate validation, environment variable checks, endpoint accessibility, and model availability. The script provides detailed output and troubleshooting steps for connection and authentication issues.
1 parent b810e33 commit 7d5cfa3

File tree

1 file changed

+336
-0
lines changed

1 file changed

+336
-0
lines changed
Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
#!/bin/bash
2+
# Debug script for testing Bedrock gateway connectivity
3+
# Tests SSL certificates, API key, and endpoint accessibility
4+
5+
set -e
6+
7+
# Colors for output
8+
RED='\033[0;31m'
9+
GREEN='\033[0;32m'
10+
YELLOW='\033[1;33m'
11+
BLUE='\033[0;34m'
12+
NC='\033[0m' # No Color
13+
14+
print_header() {
15+
echo ""
16+
echo -e "${GREEN}========================================${NC}"
17+
echo -e "${GREEN}$1${NC}"
18+
echo -e "${GREEN}========================================${NC}"
19+
echo ""
20+
}
21+
22+
print_success() { echo -e "${GREEN}$1${NC}"; }
23+
print_warning() { echo -e "${YELLOW}$1${NC}"; }
24+
print_error() { echo -e "${RED}$1${NC}"; }
25+
print_info() { echo -e "${BLUE}$1${NC}"; }
26+
27+
# Helper function to list available models
28+
list_available_models() {
29+
local base_url=$1
30+
31+
echo ""
32+
print_info "Checking available models at: $base_url/v1/models"
33+
echo ""
34+
35+
response=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \
36+
--cacert "$SSL_CERT_FILE" \
37+
-X GET "$base_url/v1/models" \
38+
-H "Authorization: Bearer $OPENAI_API_KEY" \
39+
-H "Content-Type: application/json" \
40+
--max-time 30 2>&1)
41+
42+
http_status=$(echo "$response" | grep "HTTP_STATUS" | cut -d: -f2)
43+
body=$(echo "$response" | sed '/HTTP_STATUS/d')
44+
45+
if [ "$http_status" = "200" ]; then
46+
print_success "Successfully retrieved model list (HTTP $http_status)"
47+
echo ""
48+
print_info "Available models:"
49+
echo "$body" | python3 -c "
50+
import json
51+
import sys
52+
try:
53+
data = json.load(sys.stdin)
54+
models = data.get('data', [])
55+
if models:
56+
for model in models:
57+
model_id = model.get('id', 'N/A')
58+
owned_by = model.get('owned_by', 'N/A')
59+
print(f' • {model_id} (owned by: {owned_by})')
60+
else:
61+
print(' No models found in response')
62+
except Exception as e:
63+
print(f' Error parsing model list: {e}')
64+
" 2>/dev/null || echo "$body"
65+
else
66+
print_error "Failed to retrieve model list (HTTP $http_status)"
67+
echo "$body" | python3 -m json.tool 2>/dev/null || echo "$body"
68+
fi
69+
echo ""
70+
}
71+
72+
# Test 1: Check SSL Certificate
73+
print_header "Test 1: SSL Certificate Check"
74+
75+
if [ -f "$SSL_CERT_FILE" ]; then
76+
print_success "Certificate file exists: $SSL_CERT_FILE"
77+
78+
# Check if readable
79+
if [ -r "$SSL_CERT_FILE" ]; then
80+
print_success "Certificate file is readable"
81+
82+
# Count certificates in bundle
83+
cert_count=$(grep -c "BEGIN CERTIFICATE" "$SSL_CERT_FILE" || echo "0")
84+
print_info "Certificate bundle contains $cert_count certificate(s)"
85+
else
86+
print_error "Certificate file is not readable"
87+
exit 1
88+
fi
89+
else
90+
print_error "Certificate file not found: $SSL_CERT_FILE"
91+
exit 1
92+
fi
93+
94+
# Test 2: Check Environment Variables
95+
print_header "Test 2: Environment Variables"
96+
97+
echo "Checking SSL certificate variables:"
98+
if [ ! -z "$SSL_CERT_FILE" ]; then
99+
print_success "SSL_CERT_FILE: $SSL_CERT_FILE"
100+
else
101+
print_warning "SSL_CERT_FILE not set"
102+
export SSL_CERT_FILE="$SSL_CERT_FILE"
103+
print_info "Set SSL_CERT_FILE=$SSL_CERT_FILE"
104+
fi
105+
106+
if [ ! -z "$REQUESTS_CA_BUNDLE" ]; then
107+
print_success "REQUESTS_CA_BUNDLE: $REQUESTS_CA_BUNDLE"
108+
else
109+
print_warning "REQUESTS_CA_BUNDLE not set"
110+
export REQUESTS_CA_BUNDLE="$SSL_CERT_FILE"
111+
print_info "Set REQUESTS_CA_BUNDLE=$SSL_CERT_FILE"
112+
fi
113+
114+
if [ ! -z "$CURL_CA_BUNDLE" ]; then
115+
print_success "CURL_CA_BUNDLE: $CURL_CA_BUNDLE"
116+
else
117+
print_warning "CURL_CA_BUNDLE not set"
118+
export CURL_CA_BUNDLE="$SSL_CERT_FILE"
119+
print_info "Set CURL_CA_BUNDLE=$SSL_CERT_FILE"
120+
fi
121+
122+
echo ""
123+
echo "Checking API key:"
124+
if [ ! -z "$OPENAI_API_KEY" ]; then
125+
masked_key=$(echo $OPENAI_API_KEY | sed 's/\(.\{5\}\).*\(.\{4\}\)/\1*************\2/')
126+
print_success "OPENAI_API_KEY: $masked_key"
127+
else
128+
print_error "OPENAI_API_KEY not set"
129+
print_info "Please set: export OPENAI_API_KEY='your-key-here'"
130+
exit 1
131+
fi
132+
133+
# Test 3: Load Configuration
134+
print_header "Test 3: Configuration Check"
135+
136+
CONFIG_FILE="config/providers/openai.local.yml"
137+
if [ -f "$CONFIG_FILE" ]; then
138+
print_success "Found config file: $CONFIG_FILE"
139+
140+
# Extract base URLs
141+
llm_base_url=$(grep -A 5 "^llm:" "$CONFIG_FILE" | grep "base_url:" | head -1 | awk '{print $2}' | tr -d '"')
142+
embedder_base_url=$(grep -A 5 "^embedder:" "$CONFIG_FILE" | grep "base_url:" | head -1 | awk '{print $2}' | tr -d '"')
143+
llm_model=$(grep -A 5 "^llm:" "$CONFIG_FILE" | grep "model:" | head -1 | awk '{print $2}' | tr -d '"')
144+
embedder_model=$(grep -A 5 "^embedder:" "$CONFIG_FILE" | grep "model:" | head -1 | awk '{print $2}' | tr -d '"')
145+
146+
print_info "LLM Base URL: $llm_base_url"
147+
print_info "LLM Model: $llm_model"
148+
print_info "Embedder Base URL: $embedder_base_url"
149+
print_info "Embedder Model: $embedder_model"
150+
else
151+
print_error "Config file not found: $CONFIG_FILE"
152+
exit 1
153+
fi
154+
155+
# Test 4: Test SSL Connection with curl
156+
print_header "Test 4: SSL Connection Test (curl)"
157+
158+
GATEWAY_HOST="eng-ai-model-gateway.sfproxy.devx-preprod.aws-esvc1-useast2.aws.sfdc.cl"
159+
160+
print_info "Testing SSL connection to: $GATEWAY_HOST"
161+
echo ""
162+
163+
if curl --cacert "$SSL_CERT_FILE" -s -o /dev/null -w "%{http_code}" "https://$GATEWAY_HOST" > /tmp/curl_test.txt 2>&1; then
164+
status_code=$(cat /tmp/curl_test.txt)
165+
if [ "$status_code" != "000" ]; then
166+
print_success "SSL connection successful (HTTP $status_code)"
167+
else
168+
print_error "SSL connection failed"
169+
curl --cacert "$SSL_CERT_FILE" -v "https://$GATEWAY_HOST" 2>&1 | head -20
170+
exit 1
171+
fi
172+
else
173+
print_error "curl command failed"
174+
exit 1
175+
fi
176+
177+
# Test 5: Test LLM Endpoint with curl
178+
print_header "Test 5: LLM Endpoint Test"
179+
180+
print_info "Testing: $llm_base_url/v1/chat/completions"
181+
echo ""
182+
183+
response=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \
184+
--cacert "$SSL_CERT_FILE" \
185+
-X POST "$llm_base_url/v1/chat/completions" \
186+
-H "Authorization: Bearer $OPENAI_API_KEY" \
187+
-H "Content-Type: application/json" \
188+
--max-time 30 \
189+
-d '{
190+
"model": "'"$llm_model"'",
191+
"messages": [
192+
{"role": "user", "content": "Say: Connection test successful"}
193+
],
194+
"max_tokens": 50
195+
}' 2>&1)
196+
197+
http_status=$(echo "$response" | grep "HTTP_STATUS" | cut -d: -f2)
198+
body=$(echo "$response" | sed '/HTTP_STATUS/d')
199+
200+
if [ "$http_status" = "200" ]; then
201+
print_success "LLM endpoint works! (HTTP $http_status)"
202+
# Try to extract response content
203+
content=$(echo "$body" | python3 -c "import json,sys; data=json.load(sys.stdin); print(data.get('choices', [{}])[0].get('message', {}).get('content', 'N/A'))" 2>/dev/null || echo "")
204+
if [ ! -z "$content" ] && [ "$content" != "N/A" ]; then
205+
print_info "Response: $content"
206+
fi
207+
elif [ "$http_status" = "401" ]; then
208+
print_error "Authentication failed (HTTP 401)"
209+
print_info "Your API key may not be valid for this endpoint"
210+
error_msg=$(echo "$body" | python3 -c "import json,sys; data=json.load(sys.stdin); print(data.get('error', {}).get('message', 'Unknown error'))" 2>/dev/null || echo "")
211+
if [ ! -z "$error_msg" ]; then
212+
print_info "Error: $error_msg"
213+
fi
214+
elif [ "$http_status" = "404" ]; then
215+
print_error "Endpoint not found (HTTP 404)"
216+
print_warning "The /v1/chat/completions path may not exist"
217+
print_info "Try updating base_url to include the correct path"
218+
list_available_models "$llm_base_url"
219+
else
220+
print_error "Request failed (HTTP $http_status)"
221+
echo "$body" | python3 -m json.tool 2>/dev/null || echo "$body"
222+
223+
# Check if error message suggests checking available models
224+
if echo "$body" | grep -q "model"; then
225+
print_warning "Error mentions model - checking available models..."
226+
list_available_models "$llm_base_url"
227+
fi
228+
fi
229+
230+
# Test 6: Test Embedder Endpoint
231+
print_header "Test 6: Embedder Endpoint Test"
232+
233+
print_info "Testing: $embedder_base_url/embeddings"
234+
echo ""
235+
236+
response=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \
237+
--cacert "$SSL_CERT_FILE" \
238+
-X POST "$embedder_base_url/embeddings" \
239+
-H "Authorization: Bearer $OPENAI_API_KEY" \
240+
-H "Content-Type: application/json" \
241+
--max-time 30 \
242+
-d '{
243+
"model": "'"$embedder_model"'",
244+
"input": "Connection test"
245+
}' 2>&1)
246+
247+
http_status=$(echo "$response" | grep "HTTP_STATUS" | cut -d: -f2)
248+
body=$(echo "$response" | sed '/HTTP_STATUS/d')
249+
250+
if [ "$http_status" = "200" ]; then
251+
print_success "Embedder endpoint works! (HTTP $http_status)"
252+
dimension=$(echo "$body" | python3 -c "import json,sys; data=json.load(sys.stdin); print(len(data.get('data', [{}])[0].get('embedding', [])))" 2>/dev/null || echo "N/A")
253+
if [ "$dimension" != "N/A" ]; then
254+
print_info "Embedding dimension: $dimension"
255+
fi
256+
elif [ "$http_status" = "401" ]; then
257+
print_error "Authentication failed (HTTP 401)"
258+
print_info "Your API key may not be valid for this endpoint"
259+
list_available_models "$embedder_base_url"
260+
elif [ "$http_status" = "404" ]; then
261+
print_error "Endpoint not found (HTTP 404)"
262+
print_warning "The embeddings path may not exist at this base_url"
263+
print_info "Try: $llm_base_url/v1/embeddings"
264+
list_available_models "$embedder_base_url"
265+
else
266+
print_error "Request failed (HTTP $http_status)"
267+
echo "$body" | python3 -m json.tool 2>/dev/null || echo "$body"
268+
269+
# Check if error message suggests checking available models
270+
if echo "$body" | grep -q "model\|/v1/models"; then
271+
print_warning "Error mentions models - checking available models..."
272+
list_available_models "$embedder_base_url"
273+
fi
274+
fi
275+
276+
# Test 7: Python SSL Test
277+
print_header "Test 7: Python SSL Verification"
278+
279+
print_info "Testing Python SSL certificate handling..."
280+
echo ""
281+
282+
python3 << 'EOF'
283+
import os
284+
import sys
285+
import ssl
286+
import httpx
287+
288+
cert_path = os.path.expanduser("$SSL_CERT_FILE")
289+
gateway_host = "eng-ai-model-gateway.sfproxy.devx-preprod.aws-esvc1-useast2.aws.sfdc.cl"
290+
291+
print(f"Certificate path: {cert_path}")
292+
print(f"File exists: {os.path.exists(cert_path)}")
293+
print("")
294+
295+
# Test 1: SSL context
296+
try:
297+
ssl_context = ssl.create_default_context(cafile=cert_path)
298+
print("✓ SSL context created successfully")
299+
except Exception as e:
300+
print(f"✗ Failed to create SSL context: {e}")
301+
sys.exit(1)
302+
303+
# Test 2: httpx with certificate
304+
print("\nTesting httpx with certificate...")
305+
try:
306+
with httpx.Client(verify=cert_path, timeout=10.0) as client:
307+
response = client.get(f"https://{gateway_host}")
308+
print(f"✓ Connection successful (HTTP {response.status_code})")
309+
except httpx.ConnectError as e:
310+
print(f"✗ Connection failed: {e}")
311+
sys.exit(1)
312+
except Exception as e:
313+
print(f"⚠ Request completed but with error: {e}")
314+
315+
print("\n✓ Python SSL verification works!")
316+
EOF
317+
318+
if [ $? -eq 0 ]; then
319+
print_success "Python can use SSL certificates correctly"
320+
else
321+
print_error "Python SSL verification failed"
322+
exit 1
323+
fi
324+
325+
# Summary
326+
print_header "Debug Summary"
327+
328+
print_success "All connection tests completed!"
329+
echo ""
330+
print_info "Next steps:"
331+
echo " 1. If LLM endpoint failed: Check the base_url path in config"
332+
echo " 2. If embedder endpoint failed: Check the embedder base_url path"
333+
echo " 3. If authentication failed: Verify your OPENAI_API_KEY is correct"
334+
echo " 4. If model errors occurred: Check the available models list shown above"
335+
echo " 5. Run the actual tests: scripts/test_bedrock_endpoint.sh --connection-only"
336+
echo ""

0 commit comments

Comments
 (0)