Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions infrastructure/control-panel/src/lib/services/evaultService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ export class EVaultService {
}
}

static async getEVaultLogs(namespace: string, podName: string, tail: number = 100): Promise<string[]> {
static async getEVaultLogs(
namespace: string,
podName: string,
tail: number = 100
): Promise<string[]> {
try {
const response = await fetch(`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/logs?tail=${tail}`);
const response = await fetch(
`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/logs?tail=${tail}`
);
if (!response.ok) {
throw new Error('Failed to fetch logs');
}
Expand All @@ -31,7 +37,9 @@ export class EVaultService {

static async getEVaultDetails(namespace: string, podName: string): Promise<any> {
try {
const response = await fetch(`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/details`);
const response = await fetch(
`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/details`
);
if (!response.ok) {
throw new Error('Failed to fetch eVault details');
}
Expand All @@ -44,7 +52,9 @@ export class EVaultService {

static async getEVaultMetrics(namespace: string, podName: string): Promise<any> {
try {
const response = await fetch(`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/metrics`);
const response = await fetch(
`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/metrics`
);
if (!response.ok) {
throw new Error('Failed to fetch metrics');
}
Expand All @@ -54,4 +64,4 @@ export class EVaultService {
return null;
}
}
}
}
79 changes: 48 additions & 31 deletions infrastructure/control-panel/src/routes/api/evaults/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,54 +26,60 @@ export const GET: RequestHandler = async () => {
// Get minikube IP for NodePort services
let minikubeIP = 'localhost';
try {
const { stdout: minikubeIPOutput } = await execAsync('minikube ip 2>/dev/null || echo "localhost"');
const { stdout: minikubeIPOutput } = await execAsync(
'minikube ip 2>/dev/null || echo "localhost"'
);
if (minikubeIPOutput.trim()) {
minikubeIP = minikubeIPOutput.trim();
}
} catch (ipError) {
console.log('Could not get minikube IP, using localhost');
}

console.log('Using IP:', minikubeIP);

// Get all namespaces
const { stdout: namespacesOutput } = await execAsync('kubectl get namespaces -o json');
const namespaces = JSON.parse(namespacesOutput);

// Filter for eVault namespaces
const evaultNamespaces = namespaces.items
.filter((ns: any) => ns.metadata.name.startsWith('evault-'))
.map((ns: any) => ns.metadata.name);

console.log('Found eVault namespaces:', evaultNamespaces);

let allEVaults: EVault[] = [];

// Get services and pods from each eVault namespace
for (const namespace of evaultNamespaces) {
try {
// Get services in this namespace as JSON
const { stdout: servicesOutput } = await execAsync(`kubectl get services -n ${namespace} -o json`);
const { stdout: servicesOutput } = await execAsync(
`kubectl get services -n ${namespace} -o json`
);
const services = JSON.parse(servicesOutput);

// Get pods in this namespace as JSON
const { stdout: podsOutput } = await execAsync(`kubectl get pods -n ${namespace} -o json`);
const { stdout: podsOutput } = await execAsync(
`kubectl get pods -n ${namespace} -o json`
);
const pods = JSON.parse(podsOutput);

console.log(`=== SERVICES FOR ${namespace} ===`);
console.log(JSON.stringify(services, null, 2));
console.log(`=== PODS FOR ${namespace} ===`);
console.log(JSON.stringify(pods, null, 2));
console.log(`=== END DATA ===`);

if (services.items && services.items.length > 0) {
for (const service of services.items) {
const serviceName = service.metadata.name;
const serviceType = service.spec.type;
const ports = service.spec.ports;

console.log(`Service: ${serviceName}, Type: ${serviceType}, Ports:`, ports);

// Find NodePort for NodePort services
let nodePort = null;
if (serviceType === 'NodePort' && ports) {
Expand All @@ -84,9 +90,9 @@ export const GET: RequestHandler = async () => {
}
}
}

console.log(`NodePort: ${nodePort}`);

// Get pod data for this service
let podData = {
status: 'Unknown',
Expand All @@ -98,28 +104,39 @@ export const GET: RequestHandler = async () => {
node: 'N/A',
podName: 'N/A'
};

if (pods.items && pods.items.length > 0) {
// Find pod that matches this service (usually same name or has service label)
const matchingPod = pods.items.find((pod: any) =>
pod.metadata.name.includes(serviceName.replace('-service', '')) ||
pod.metadata.labels?.app === 'evault'
const matchingPod = pods.items.find(
(pod: any) =>
pod.metadata.name.includes(
serviceName.replace('-service', '')
) || pod.metadata.labels?.app === 'evault'
);

if (matchingPod) {
const pod = matchingPod;
const readyCount = pod.status.containerStatuses?.filter((cs: any) => cs.ready).length || 0;
const readyCount =
pod.status.containerStatuses?.filter((cs: any) => cs.ready)
.length || 0;
const totalCount = pod.status.containerStatuses?.length || 0;
const restarts = pod.status.containerStatuses?.reduce((sum: number, cs: any) => sum + (cs.restartCount || 0), 0) || 0;

const restarts =
pod.status.containerStatuses?.reduce(
(sum: number, cs: any) => sum + (cs.restartCount || 0),
0
) || 0;

// Calculate age
const creationTime = new Date(pod.metadata.creationTimestamp);
const now = new Date();
const ageMs = now.getTime() - creationTime.getTime();
const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24));
const ageHours = Math.floor((ageMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const age = ageDays > 0 ? `${ageDays}d${ageHours}h` : `${ageHours}h`;

const ageHours = Math.floor(
(ageMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
);
const age =
ageDays > 0 ? `${ageDays}d${ageHours}h` : `${ageHours}h`;

podData = {
status: pod.status.phase || 'Unknown',
age: age,
Expand All @@ -132,18 +149,18 @@ export const GET: RequestHandler = async () => {
};
}
}

// Extract the eVault ID from the namespace
const evaultId = namespace.replace('evault-', '');

// Generate service URL
let serviceUrl = '';
if (nodePort) {
serviceUrl = `http://${minikubeIP}:${nodePort}`;
}

console.log(`Service URL: ${serviceUrl}`);

allEVaults.push({
id: serviceName,
name: serviceName,
Expand Down Expand Up @@ -172,4 +189,4 @@ export const GET: RequestHandler = async () => {
console.error('Error fetching eVaults:', error);
return json({ error: 'Failed to fetch eVaults', evaults: [] }, { status: 500 });
}
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ export const GET: RequestHandler = async ({ params }) => {
try {
// Get detailed pod information
const { stdout: podInfo } = await execAsync(`kubectl describe pod -n ${namespace} ${pod}`);

// Get pod YAML
const { stdout: podYaml } = await execAsync(`kubectl get pod -n ${namespace} ${pod} -o yaml`);

const { stdout: podYaml } = await execAsync(
`kubectl get pod -n ${namespace} ${pod} -o yaml`
);

// Get pod metrics if available
let metrics = null;
try {
const { stdout: metricsOutput } = await execAsync(`kubectl top pod -n ${namespace} ${pod}`);
const { stdout: metricsOutput } = await execAsync(
`kubectl top pod -n ${namespace} ${pod}`
);
metrics = metricsOutput.trim();
} catch (metricsError) {
// Metrics might not be available
Expand All @@ -34,4 +38,4 @@ export const GET: RequestHandler = async ({ params }) => {
console.error('Error fetching pod details:', error);
return json({ error: 'Failed to fetch pod details' }, { status: 500 });
}
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ export const GET: RequestHandler = async ({ params, url }) => {
const tail = url.searchParams.get('tail') || '100';

try {
const { stdout } = await execAsync(`kubectl logs -n ${namespace} ${pod} -c evault --tail=${tail}`);
const logs = stdout.trim().split('\n').filter(line => line.trim());

const { stdout } = await execAsync(
`kubectl logs -n ${namespace} ${pod} -c evault --tail=${tail}`
);
const logs = stdout
.trim()
.split('\n')
.filter((line) => line.trim());

return json({ logs });
} catch (error) {
console.error('Error fetching logs:', error);
return json({ error: 'Failed to fetch logs', logs: [] }, { status: 500 });
}
};
};
Loading
Loading