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
47 changes: 43 additions & 4 deletions infrastructure/control-panel/src/lib/services/evaultService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ export class EVaultService {
*/
static async getEVaultLogs(evaultId: string, tail?: number): Promise<string[]> {
try {
const url = new URL(`/api/evaults/${encodeURIComponent(evaultId)}/logs`, window.location.origin);
const url = new URL(
`/api/evaults/${encodeURIComponent(evaultId)}/logs`,
window.location.origin
);
if (tail) {
url.searchParams.set('tail', tail.toString());
}
Expand All @@ -100,9 +103,7 @@ export class EVaultService {
*/
static async getEVaultDetails(evaultId: string): Promise<any> {
try {
const response = await fetch(
`/api/evaults/${encodeURIComponent(evaultId)}/details`
);
const response = await fetch(`/api/evaults/${encodeURIComponent(evaultId)}/details`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
Expand All @@ -113,4 +114,42 @@ export class EVaultService {
throw error;
}
}

/**
* Get logs for a specific eVault by namespace and podName
*/
static async getEVaultLogsByPod(namespace: string, podName: string): Promise<string[]> {
try {
const response = await fetch(
`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/logs`
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.logs || [];
} catch (error) {
console.error('Failed to fetch eVault logs by pod:', error);
throw error;
}
}

/**
* Get metrics for a specific eVault by namespace and podName
*/
static async getEVaultMetrics(namespace: string, podName: string): Promise<any> {
try {
const response = await fetch(
`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/metrics`
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.metrics || {};
} catch (error) {
console.error('Failed to fetch eVault metrics:', error);
throw error;
}
}
}
4 changes: 1 addition & 3 deletions infrastructure/control-panel/src/lib/services/loki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,7 @@ export class LokiService {
).sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());

// Extract log lines and limit to requested number
const logLines = uniqueLogs
.map((log) => log.line)
.slice(-limit); // Get last N lines
const logLines = uniqueLogs.map((log) => log.line).slice(-limit); // Get last N lines

return logLines;
}
Expand Down
278 changes: 129 additions & 149 deletions infrastructure/control-panel/src/lib/services/registry.ts
Original file line number Diff line number Diff line change
@@ -1,160 +1,140 @@
import { env } from "$env/dynamic/public";
import { env } from '$env/dynamic/public';

export interface Platform {
name: string;
url: string;
status: "Active" | "Inactive";
uptime: string;
name: string;
url: string;
status: 'Active' | 'Inactive';
uptime: string;
}

export interface RegistryVault {
ename: string;
uri: string;
evault: string;
originalUri?: string;
resolved?: boolean;
ename: string;
uri: string;
evault: string;
originalUri?: string;
resolved?: boolean;
}

export class RegistryService {
private baseUrl: string;

constructor() {
this.baseUrl =
env.PUBLIC_REGISTRY_URL ||
"https://registry.staging.metastate.foundation";
}

async getEVaults(): Promise<RegistryVault[]> {
try {
const response = await fetch(`${this.baseUrl}/list`);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const vaults: RegistryVault[] = await response.json();
return vaults;
} catch (error) {
console.error("Error fetching evaults from registry:", error);
return [];
}
}

async getPlatforms(): Promise<Platform[]> {
try {
const response = await fetch(`${this.baseUrl}/platforms`);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const platformUrls: (string | null | undefined)[] =
await response.json();

// Filter out null/undefined values and convert URLs to platform objects
const platforms = platformUrls
.filter(
(url): url is string => url != null && url.trim() !== "",
)
.map((url) => {
// Use the original URL from the registry (it already has the correct format)
let displayUrl = url.trim();

// Ensure URL has protocol if it doesn't
if (
!displayUrl.startsWith("http://") &&
!displayUrl.startsWith("https://")
) {
displayUrl = `http://${displayUrl}`;
}

// Parse URL to extract platform name
let name = "Unknown";
try {
const urlObj = new URL(displayUrl);
const hostname = urlObj.hostname;
// Extract platform name from hostname (remove port if present)
const hostnameWithoutPort = hostname.split(":")[0];
const namePart = hostnameWithoutPort.split(".")[0];

// Capitalize and format the name
if (namePart === "pictique") name = "Pictique";
else if (namePart === "blabsy") name = "Blabsy";
else if (namePart === "charter") name = "Group Charter";
else if (namePart === "cerberus") name = "Cerberus";
else if (namePart === "evoting") name = "eVoting";
else if (namePart === "dreamsync") name = "DreamSync";
else if (namePart === "ereputation")
name = "eReputation";
else
name =
namePart.charAt(0).toUpperCase() +
namePart.slice(1);
} catch {
// If URL parsing fails, try to extract name from the URL string
const match = displayUrl.match(
/(?:https?:\/\/)?([^:./]+)/,
);
if (match) {
const namePart = match[1].toLowerCase();
if (namePart === "pictique") name = "Pictique";
else if (namePart === "blabsy") name = "Blabsy";
else if (namePart === "charter")
name = "Group Charter";
else if (namePart === "cerberus") name = "Cerberus";
else if (namePart === "evoting") name = "eVoting";
else if (namePart === "dreamsync")
name = "DreamSync";
else if (namePart === "ereputation")
name = "eReputation";
else
name =
namePart.charAt(0).toUpperCase() +
namePart.slice(1);
}
}

return {
name,
url: displayUrl,
status: "Active" as const,
uptime: "24h",
};
});

return platforms;
} catch (error) {
console.error("Error fetching platforms from registry:", error);

// Return fallback platforms if registry is unavailable
return [
{
name: "Blabsy",
url: "http://192.168.0.235:4444",
status: "Active",
uptime: "24h",
},
{
name: "Pictique",
url: "http://192.168.0.235:1111",
status: "Active",
uptime: "24h",
},
{
name: "Group Charter",
url: "http://192.168.0.235:5555",
status: "Active",
uptime: "24h",
},
{
name: "Cerberus",
url: "http://192.168.0.235:6666",
status: "Active",
uptime: "24h",
},
];
}
}
private baseUrl: string;

constructor() {
this.baseUrl = env.PUBLIC_REGISTRY_URL || 'https://registry.staging.metastate.foundation';
}

async getEVaults(): Promise<RegistryVault[]> {
try {
const response = await fetch(`${this.baseUrl}/list`);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const vaults: RegistryVault[] = await response.json();
return vaults;
} catch (error) {
console.error('Error fetching evaults from registry:', error);
return [];
}
}

async getPlatforms(): Promise<Platform[]> {
try {
const response = await fetch(`${this.baseUrl}/platforms`);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const platformUrls: (string | null | undefined)[] = await response.json();

// Filter out null/undefined values and convert URLs to platform objects
const platforms = platformUrls
.filter((url): url is string => url != null && url.trim() !== '')
.map((url) => {
// Use the original URL from the registry (it already has the correct format)
let displayUrl = url.trim();

// Ensure URL has protocol if it doesn't
if (!displayUrl.startsWith('http://') && !displayUrl.startsWith('https://')) {
displayUrl = `http://${displayUrl}`;
}

// Parse URL to extract platform name
let name = 'Unknown';
try {
const urlObj = new URL(displayUrl);
const hostname = urlObj.hostname;
// Extract platform name from hostname (remove port if present)
const hostnameWithoutPort = hostname.split(':')[0];
const namePart = hostnameWithoutPort.split('.')[0];

// Capitalize and format the name
if (namePart === 'pictique') name = 'Pictique';
else if (namePart === 'blabsy') name = 'Blabsy';
else if (namePart === 'charter') name = 'Group Charter';
else if (namePart === 'cerberus') name = 'Cerberus';
else if (namePart === 'evoting') name = 'eVoting';
else if (namePart === 'dreamsync') name = 'DreamSync';
else if (namePart === 'ereputation') name = 'eReputation';
else name = namePart.charAt(0).toUpperCase() + namePart.slice(1);
} catch {
// If URL parsing fails, try to extract name from the URL string
const match = displayUrl.match(/(?:https?:\/\/)?([^:./]+)/);
if (match) {
const namePart = match[1].toLowerCase();
if (namePart === 'pictique') name = 'Pictique';
else if (namePart === 'blabsy') name = 'Blabsy';
else if (namePart === 'charter') name = 'Group Charter';
else if (namePart === 'cerberus') name = 'Cerberus';
else if (namePart === 'evoting') name = 'eVoting';
else if (namePart === 'dreamsync') name = 'DreamSync';
else if (namePart === 'ereputation') name = 'eReputation';
else name = namePart.charAt(0).toUpperCase() + namePart.slice(1);
}
}

return {
name,
url: displayUrl,
status: 'Active' as const,
uptime: '24h'
};
});

return platforms;
} catch (error) {
console.error('Error fetching platforms from registry:', error);

// Return fallback platforms if registry is unavailable
return [
{
name: 'Blabsy',
url: 'http://192.168.0.235:4444',
status: 'Active',
uptime: '24h'
},
{
name: 'Pictique',
url: 'http://192.168.0.235:1111',
status: 'Active',
uptime: '24h'
},
{
name: 'Group Charter',
url: 'http://192.168.0.235:5555',
status: 'Active',
uptime: '24h'
},
{
name: 'Cerberus',
url: 'http://192.168.0.235:6666',
status: 'Active',
uptime: '24h'
}
];
}
}
}

export const registryService = new RegistryService();
3 changes: 2 additions & 1 deletion infrastructure/control-panel/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@

// Navigate to monitoring
goto('/monitoring');
}}>Start Monitoring</ButtonAction
}}
>Start Monitoring</ButtonAction
>
</div>
{:else}
Expand Down
4 changes: 2 additions & 2 deletions infrastructure/control-panel/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,11 @@
},
Uptime: {
type: 'text',
value: evault.age
value: 'N/A'
},
IP: {
type: 'text',
value: evault.ip
value: 'N/A'
},
URI: {
type: 'link',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const GET: RequestHandler = async () => {
registryVaults.map(async (vault) => {
// Use evault identifier as the primary ID, fallback to ename
const evaultId = vault.evault || vault.ename;

// Determine display name (prefer ename, fallback to evault)
const displayName = vault.ename || vault.evault || 'Unknown';

Expand Down
Loading