update
This commit is contained in:
@@ -83,6 +83,11 @@ export class OneboxHttpServer {
|
||||
return this.handleLogStreamUpgrade(req, serviceName);
|
||||
}
|
||||
|
||||
// Network access logs WebSocket
|
||||
if (path === '/api/network/logs/stream' && req.headers.get('upgrade') === 'websocket') {
|
||||
return this.handleNetworkLogStreamUpgrade(req, new URL(req.url));
|
||||
}
|
||||
|
||||
// Docker Registry v2 Token endpoint (for OCI authentication)
|
||||
if (path === '/v2/token') {
|
||||
return await this.handleRegistryTokenRequest(req, url);
|
||||
@@ -291,6 +296,11 @@ export class OneboxHttpServer {
|
||||
} else if (path.match(/^\/api\/services\/[^/]+\/platform-resources$/) && method === 'GET') {
|
||||
const serviceName = path.split('/')[3];
|
||||
return await this.handleGetServicePlatformResourcesRequest(serviceName);
|
||||
// Network endpoints
|
||||
} else if (path === '/api/network/targets' && method === 'GET') {
|
||||
return await this.handleGetNetworkTargetsRequest();
|
||||
} else if (path === '/api/network/stats' && method === 'GET') {
|
||||
return await this.handleGetNetworkStatsRequest();
|
||||
} else {
|
||||
return this.jsonResponse({ success: false, error: 'Not found' }, 404);
|
||||
}
|
||||
@@ -995,6 +1005,186 @@ export class OneboxHttpServer {
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle WebSocket upgrade for network access log streaming
|
||||
*/
|
||||
private handleNetworkLogStreamUpgrade(req: Request, url: URL): Response {
|
||||
const { socket, response } = Deno.upgradeWebSocket(req);
|
||||
|
||||
// Extract filter from query params
|
||||
const filterDomain = url.searchParams.get('domain');
|
||||
|
||||
// Generate unique client ID
|
||||
const clientId = crypto.randomUUID();
|
||||
|
||||
socket.onopen = () => {
|
||||
logger.info(`Network log stream WebSocket connected (client: ${clientId})`);
|
||||
|
||||
// Register with CaddyLogReceiver
|
||||
const filter = filterDomain ? { domain: filterDomain } : {};
|
||||
this.oneboxRef.caddyLogReceiver.addClient(clientId, socket, filter);
|
||||
|
||||
// Send initial connection message
|
||||
socket.send(JSON.stringify({
|
||||
type: 'connected',
|
||||
clientId,
|
||||
filter,
|
||||
}));
|
||||
};
|
||||
|
||||
socket.onmessage = (event) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
|
||||
// Handle filter updates from client
|
||||
if (message.type === 'set_filter') {
|
||||
const newFilter = {
|
||||
domain: message.domain || undefined,
|
||||
sampleRate: message.sampleRate || undefined,
|
||||
};
|
||||
this.oneboxRef.caddyLogReceiver.updateClientFilter(clientId, newFilter);
|
||||
|
||||
socket.send(JSON.stringify({
|
||||
type: 'filter_updated',
|
||||
filter: newFilter,
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
logger.debug(`Network log stream message parse error: ${getErrorMessage(error)}`);
|
||||
}
|
||||
};
|
||||
|
||||
socket.onclose = () => {
|
||||
logger.info(`Network log stream WebSocket closed (client: ${clientId})`);
|
||||
this.oneboxRef.caddyLogReceiver.removeClient(clientId);
|
||||
};
|
||||
|
||||
socket.onerror = (error) => {
|
||||
logger.error(`Network log stream WebSocket error: ${error}`);
|
||||
this.oneboxRef.caddyLogReceiver.removeClient(clientId);
|
||||
};
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// ============ Network Endpoints ============
|
||||
|
||||
/**
|
||||
* Get all traffic targets (services, registry, platform services)
|
||||
*/
|
||||
private async handleGetNetworkTargetsRequest(): Promise<Response> {
|
||||
try {
|
||||
const targets: Array<{
|
||||
type: 'service' | 'registry' | 'platform';
|
||||
name: string;
|
||||
domain: string | null;
|
||||
targetHost: string;
|
||||
targetPort: number;
|
||||
status: string;
|
||||
}> = [];
|
||||
|
||||
// Add services
|
||||
const services = this.oneboxRef.services.listServices();
|
||||
for (const service of services) {
|
||||
targets.push({
|
||||
type: 'service',
|
||||
name: service.name,
|
||||
domain: service.domain || null,
|
||||
targetHost: service.containerIP || 'unknown',
|
||||
targetPort: service.port || 80,
|
||||
status: service.status,
|
||||
});
|
||||
}
|
||||
|
||||
// Add registry if running
|
||||
const registryStatus = this.oneboxRef.registry.getStatus();
|
||||
if (registryStatus.running) {
|
||||
targets.push({
|
||||
type: 'registry',
|
||||
name: 'onebox-registry',
|
||||
domain: null, // Registry is internal
|
||||
targetHost: 'localhost',
|
||||
targetPort: registryStatus.port,
|
||||
status: 'running',
|
||||
});
|
||||
}
|
||||
|
||||
// Add platform services
|
||||
const platformServices = this.oneboxRef.platformServices.getAllPlatformServices();
|
||||
for (const ps of platformServices) {
|
||||
// Get provider info for display name
|
||||
const provider = this.oneboxRef.platformServices.getProvider(ps.type);
|
||||
targets.push({
|
||||
type: 'platform',
|
||||
name: provider?.displayName || ps.type,
|
||||
domain: null, // Platform services are internal
|
||||
targetHost: 'localhost',
|
||||
targetPort: this.getPlatformServicePort(ps.type),
|
||||
status: ps.status,
|
||||
});
|
||||
}
|
||||
|
||||
return this.jsonResponse({ success: true, data: targets });
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get network targets: ${getErrorMessage(error)}`);
|
||||
return this.jsonResponse({
|
||||
success: false,
|
||||
error: getErrorMessage(error) || 'Failed to get network targets',
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default port for a platform service type
|
||||
*/
|
||||
private getPlatformServicePort(type: TPlatformServiceType): number {
|
||||
const ports: Record<TPlatformServiceType, number> = {
|
||||
mongodb: 27017,
|
||||
minio: 9000,
|
||||
redis: 6379,
|
||||
postgresql: 5432,
|
||||
rabbitmq: 5672,
|
||||
};
|
||||
return ports[type] || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Caddy/network stats
|
||||
*/
|
||||
private async handleGetNetworkStatsRequest(): Promise<Response> {
|
||||
try {
|
||||
const proxyStatus = this.oneboxRef.reverseProxy.getStatus();
|
||||
const logReceiverStats = this.oneboxRef.caddyLogReceiver.getStats();
|
||||
|
||||
return this.jsonResponse({
|
||||
success: true,
|
||||
data: {
|
||||
proxy: {
|
||||
running: proxyStatus.running,
|
||||
httpPort: proxyStatus.httpPort,
|
||||
httpsPort: proxyStatus.httpsPort,
|
||||
routes: proxyStatus.routes,
|
||||
certificates: proxyStatus.certificates,
|
||||
},
|
||||
logReceiver: {
|
||||
running: logReceiverStats.running,
|
||||
port: logReceiverStats.port,
|
||||
clients: logReceiverStats.clients,
|
||||
connections: logReceiverStats.connections,
|
||||
sampleRate: logReceiverStats.sampleRate,
|
||||
recentLogsCount: logReceiverStats.recentLogsCount,
|
||||
},
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get network stats: ${getErrorMessage(error)}`);
|
||||
return this.jsonResponse({
|
||||
success: false,
|
||||
error: getErrorMessage(error) || 'Failed to get network stats',
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast message to all connected WebSocket clients
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user