233 lines
6.0 KiB
JavaScript
233 lines
6.0 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Test Different Pangolin Raw Resource Creation Configurations
|
|
*
|
|
* Goal: Determine correct payload format for HTTP resources
|
|
*
|
|
* Tests:
|
|
* 1. Current payload (fails with "Unrecognized keys: type, ssl, enabled")
|
|
* 2. Payload without `type` field
|
|
* 3. Payload with only name, domainId, subdomain, http: true
|
|
* 4. Payload with `protocol: "http"` instead of `type: "http"`
|
|
* 5. TCP resource to understand base payload format
|
|
* 6. Minimal HTTP resource payload
|
|
* 7. Check actual resource structure from listResources()
|
|
*/
|
|
|
|
import { pangolinClient, CreateResourcePayload, PangolinResource } from './src/services/pangolin.client';
|
|
import { logger } from './src/utils/logger';
|
|
|
|
const orgId = process.env.PANGOLIN_ORG_ID || '';
|
|
const apiUrl = process.env.PANGOLIN_API_URL || '';
|
|
const apiKey = process.env.PANGOLIN_API_KEY || '';
|
|
|
|
if (!orgId || !apiUrl || !apiKey) {
|
|
logger.error('Missing required env vars: PANGOLIN_ORG_URL, PANGOLIN_API_KEY, PANGOLIN_ORG_ID');
|
|
process.exit(1);
|
|
}
|
|
|
|
logger.info('=== Pangolin Resource Payload Test ===');
|
|
logger.info(`OrgId: ${orgId}`);
|
|
logger.info(`API URL: ${apiUrl}`);
|
|
logger.info('');
|
|
|
|
// Helper to make raw requests
|
|
async function rawRequest(method: string, path: string, body?: unknown): Promise<unknown> {
|
|
const url = `${apiUrl}${path}`;
|
|
logger.info(`[${method}] ${url}`);
|
|
if (body) {
|
|
logger.info(`Body: ${JSON.stringify(body, null, 2)}`);
|
|
}
|
|
|
|
try {
|
|
const res = await fetch(url, {
|
|
method,
|
|
headers: {
|
|
'Authorization': `Bearer ${apiKey}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: body ? JSON.stringify(body) : undefined,
|
|
});
|
|
|
|
const text = await res.text();
|
|
logger.info(`Response Status: ${res.status}`);
|
|
|
|
if (text) {
|
|
try {
|
|
const json = JSON.parse(text);
|
|
logger.info(`Response: ${JSON.stringify(json, null, 2)}`);
|
|
return json;
|
|
} catch (e) {
|
|
logger.info(`Response (text): ${text}`);
|
|
return text;
|
|
}
|
|
}
|
|
return undefined;
|
|
} catch (err) {
|
|
logger.error(`Request failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
async function testListExistingResources() {
|
|
logger.info('\n--- Test 0: List Existing Resources ---');
|
|
const resources = await pangolinClient.listResources();
|
|
logger.info(`Found ${resources.length} resources`);
|
|
if (resources.length > 0) {
|
|
logger.info('Sample resource structure:');
|
|
logger.info(JSON.stringify(resources[0], null, 2));
|
|
}
|
|
}
|
|
|
|
async function testPayload1() {
|
|
logger.info('\n--- Test 1: Current Payload (WITH type, ssl, enabled) ---');
|
|
logger.info('Expected error: "Unrecognized keys: type, ssl, enabled"');
|
|
|
|
const payload = {
|
|
name: 'Test HTTP 1',
|
|
type: 'http',
|
|
domainId: 'test-domain-id',
|
|
subdomain: 'test1',
|
|
http: true,
|
|
ssl: true,
|
|
enabled: true,
|
|
};
|
|
|
|
await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
|
|
}
|
|
|
|
async function testPayload2() {
|
|
logger.info('\n--- Test 2: Payload WITHOUT type field ---');
|
|
logger.info('Maybe endpoint determines type from other fields');
|
|
|
|
const payload = {
|
|
name: 'Test HTTP 2',
|
|
domainId: 'test-domain-id',
|
|
subdomain: 'test2',
|
|
http: true,
|
|
};
|
|
|
|
await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
|
|
}
|
|
|
|
async function testPayload3() {
|
|
logger.info('\n--- Test 3: Minimal Payload (name, domainId, subdomain, http) ---');
|
|
|
|
const payload = {
|
|
name: 'Test HTTP 3',
|
|
domainId: 'test-domain-id',
|
|
subdomain: 'test3',
|
|
http: true,
|
|
};
|
|
|
|
await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
|
|
}
|
|
|
|
async function testPayload4() {
|
|
logger.info('\n--- Test 4: Payload with protocol instead of type ---');
|
|
|
|
const payload = {
|
|
name: 'Test HTTP 4',
|
|
domainId: 'test-domain-id',
|
|
subdomain: 'test4',
|
|
protocol: 'http',
|
|
};
|
|
|
|
await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
|
|
}
|
|
|
|
async function testPayload5() {
|
|
logger.info('\n--- Test 5: TCP Resource on /resource endpoint ---');
|
|
logger.info('TCP uses `/org/{orgId}/resource` endpoint (different from /site-resource)');
|
|
|
|
const payload = {
|
|
name: 'Test TCP 1',
|
|
type: 'tcp',
|
|
proxyPort: 2222,
|
|
stickySession: false,
|
|
enabled: true,
|
|
};
|
|
|
|
await rawRequest('PUT', `/org/${orgId}/resource`, payload);
|
|
}
|
|
|
|
async function testPayload6() {
|
|
logger.info('\n--- Test 6: Only Name + Subdomain (simplest) ---');
|
|
|
|
const payload = {
|
|
name: 'Test HTTP 6',
|
|
subdomain: 'test6',
|
|
};
|
|
|
|
await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
|
|
}
|
|
|
|
async function testPayload7() {
|
|
logger.info('\n--- Test 7: Check if siteId is required ---');
|
|
|
|
// First get a valid siteId
|
|
const sites = await pangolinClient.listSites();
|
|
if (sites.length === 0) {
|
|
logger.warn('No sites found - skipping test');
|
|
return;
|
|
}
|
|
|
|
const siteId = sites[0].siteId;
|
|
logger.info(`Using siteId: ${siteId}`);
|
|
|
|
const payload = {
|
|
name: 'Test HTTP 7',
|
|
subdomain: 'test7',
|
|
siteId,
|
|
};
|
|
|
|
await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
|
|
}
|
|
|
|
async function testPayload8() {
|
|
logger.info('\n--- Test 8: Try on different endpoint (/org/{orgId}/resource) with http resource ---');
|
|
|
|
const payload = {
|
|
name: 'Test HTTP 8',
|
|
domainId: 'test-domain-id',
|
|
subdomain: 'test8',
|
|
http: true,
|
|
};
|
|
|
|
await rawRequest('PUT', `/org/${orgId}/resource`, payload);
|
|
}
|
|
|
|
async function main() {
|
|
try {
|
|
// Check health first
|
|
const healthy = await pangolinClient.healthCheck();
|
|
if (!healthy) {
|
|
logger.error('Pangolin API health check failed');
|
|
process.exit(1);
|
|
}
|
|
logger.info('Pangolin API health check: OK');
|
|
|
|
// Run tests
|
|
await testListExistingResources();
|
|
await testPayload1();
|
|
await testPayload2();
|
|
await testPayload3();
|
|
await testPayload4();
|
|
await testPayload5();
|
|
await testPayload6();
|
|
await testPayload7();
|
|
await testPayload8();
|
|
|
|
logger.info('\n=== Test Complete ===');
|
|
} catch (err) {
|
|
logger.error('Test failed:', err);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main().catch(err => {
|
|
logger.error('Uncaught error:', err);
|
|
process.exit(1);
|
|
});
|