Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,9 @@ EREPUTATION_MAPPING_DB_PATH="/path/to/erep/mapping/db"
VITE_EREPUTATION_BASE_URL=http://localhost:8765

LOAD_TEST_USER_COUNT=6

PUBLIC_EID_WALLET_TOKEN=obtained-from-post-registry-service-/platforms/certification

LOKI_URL=http://localhost:3100
LOKI_USERNAME=admin
LOKI_PASSWORD=admin
39 changes: 39 additions & 0 deletions db/init-multiple-databases.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
set -e

# Get the list of databases from environment variable
# Default to empty if not set
POSTGRES_MULTIPLE_DATABASES=${POSTGRES_MULTIPLE_DATABASES:-}

# If no databases specified, exit
if [ -z "$POSTGRES_MULTIPLE_DATABASES" ]; then
echo "No databases specified in POSTGRES_MULTIPLE_DATABASES"
exit 0
fi

echo "Creating multiple databases..."

# Split the comma-separated list and create each database
IFS=',' read -ra DATABASES <<< "$POSTGRES_MULTIPLE_DATABASES"
for db in "${DATABASES[@]}"; do
# Trim whitespace
db=$(echo "$db" | xargs)

if [ -n "$db" ]; then
# Check if database exists
DB_EXISTS=$(psql -v ON_ERROR_STOP=0 --username "$POSTGRES_USER" --dbname postgres -tAc "SELECT 1 FROM pg_database WHERE datname='$db'" 2>/dev/null || echo "")

if [ "$DB_EXISTS" = "1" ]; then
echo "Database $db already exists, skipping..."
else
echo "Creating database: $db"
# Create the database directly (not inside a function)
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname postgres <<-EOSQL
CREATE DATABASE "$db";
EOSQL
fi
fi
done

echo "Multiple databases created successfully!"

25 changes: 25 additions & 0 deletions dev-docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,19 @@ services:
networks:
- metastate-network
<<: *common-host-access
entrypoint: ["/bin/sh", "-c"]
command:
- |
# Remove any stale PID files before starting Neo4j
# Neo4j stores PID files in /var/lib/neo4j/run/neo4j.pid
rm -f /var/lib/neo4j/run/neo4j.pid 2>/dev/null || true
rm -f /var/lib/neo4j/data/run/neo4j.pid 2>/dev/null || true
rm -f /var/lib/neo4j/data/neo4j.pid 2>/dev/null || true
# Also clean up any other PID files
find /var/lib/neo4j -name "*.pid" -type f -delete 2>/dev/null || true
find /var/lib/neo4j/data -name "*.pid" -type f -delete 2>/dev/null || true
# Start Neo4j with the original entrypoint
exec /startup/docker-entrypoint.sh neo4j
healthcheck:
test: [ "CMD-SHELL", "cypher-shell -u neo4j -p ${NEO4J_PASSWORD:-neo4j} 'RETURN 1' || exit 1" ]
interval: 10s
Expand Down Expand Up @@ -557,6 +570,18 @@ services:
- metastate-network
<<: *common-host-access

# Loki for log aggregation
loki:
profiles:
- all
image: grafana/loki:latest
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
networks:
- metastate-network
<<: *common-host-access

volumes:
postgres_data:
neo4j_data:
Expand Down
36 changes: 14 additions & 22 deletions infrastructure/control-panel/src/lib/components/EVaultList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
<div class="py-8 text-center">
<p class="text-gray-500">No eVaults found</p>
<p class="mt-1 text-sm text-gray-400">
Try refreshing or check your Kubernetes connection
Try refreshing or check your registry connection
</p>
</div>
{:else}
Expand All @@ -155,7 +155,7 @@
<th
class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
>
Namespace
eName (w3id)
</th>
<th
class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
Expand All @@ -165,12 +165,7 @@
<th
class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
>
Age
</th>
<th
class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
>
Service URL
URI
</th>
</tr>
</thead>
Expand All @@ -180,38 +175,35 @@
<td
class="px-6 py-4 text-sm font-medium whitespace-nowrap text-gray-900"
>
{evault.name}
{evault.name || evault.ename || evault.evault}
</td>
<td class="px-6 py-4 text-sm whitespace-nowrap text-gray-500">
{evault.namespace}
{evault.ename || 'N/A'}
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span
class="inline-flex rounded-full px-2 py-1 text-xs font-semibold {evault.status ===
'Running'
'Active'
? 'bg-green-100 text-green-800'
: evault.status === 'Pending'
? 'bg-yellow-100 text-yellow-800'
: 'bg-red-100 text-red-800'}"
: evault.status === 'Inactive'
? 'bg-red-100 text-red-800'
: 'bg-gray-100 text-gray-800'}"
>
{evault.status}
{evault.status || 'Unknown'}
</span>
</td>
<td class="px-6 py-4 text-sm whitespace-nowrap text-gray-500">
{evault.age || 'Unknown'}
</td>
<td class="px-6 py-4 text-sm whitespace-nowrap text-gray-500">
{#if evault.serviceUrl}
{#if evault.uri || evault.serviceUrl}
<a
href={evault.serviceUrl}
href={evault.uri || evault.serviceUrl}
target="_blank"
rel="noopener noreferrer"
class="text-blue-600 underline hover:text-blue-800"
>
{evault.serviceUrl}
{evault.uri || evault.serviceUrl}
</a>
{:else}
<span class="text-gray-400">No external access</span>
<span class="text-gray-400">No URI available</span>
{/if}
</td>
</tr>
Expand Down
25 changes: 12 additions & 13 deletions infrastructure/control-panel/src/lib/services/evaultService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,15 @@ export class EVaultService {
}

/**
* Get logs for a specific eVault pod
* Get logs for a specific eVault by evaultId
*/
/**
* Get logs for a specific eVault pod
*/
static async getEVaultLogs(namespace: string, podName: string): Promise<string[]> {
static async getEVaultLogs(evaultId: string, tail?: number): Promise<string[]> {
try {
const response = await fetch(
`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/logs`
);
const url = new URL(`/api/evaults/${encodeURIComponent(evaultId)}/logs`, window.location.origin);
if (tail) {
url.searchParams.set('tail', tail.toString());
}
const response = await fetch(url.toString());
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
Expand All @@ -97,20 +96,20 @@ export class EVaultService {
}

/**
* Get metrics for a specific eVault pod
* Get details for a specific eVault by evaultId
*/
static async getEVaultMetrics(namespace: string, podName: string): Promise<any> {
static async getEVaultDetails(evaultId: string): Promise<any> {
try {
const response = await fetch(
`/api/evaults/${encodeURIComponent(namespace)}/${encodeURIComponent(podName)}/metrics`
`/api/evaults/${encodeURIComponent(evaultId)}/details`
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.metrics || {};
return data.evault || {};
} catch (error) {
console.error('Failed to fetch eVault metrics:', error);
console.error('Failed to fetch eVault details:', error);
throw error;
}
}
Expand Down
43 changes: 43 additions & 0 deletions infrastructure/control-panel/src/lib/services/loki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,49 @@ export class LokiService {
.filter((event): event is FlowEvent => event !== null);
}

/**
* Query logs for a specific evault by identifier
* Supports querying by evault field or ename (w3id) in log labels
*/
async getEVaultLogs(
evaultId: string,
ename?: string,
limit: number = 100,
start?: string,
end?: string
): Promise<string[]> {
// Try multiple query patterns to find logs for this evault
// First try by evault field, then by ename/w3id
const queries = [
`{evault="${evaultId}"}`,
...(ename ? [`{ename="${ename}"}`, `{w3id="${ename}"}`] : [])
];

const allLogs: LogEntry[] = [];

// Try each query pattern
for (const query of queries) {
try {
const logs = await this.queryLogs(query, start, end);
allLogs.push(...logs);
} catch (error) {
console.log(`Query ${query} failed, trying next pattern`);
}
}

// Remove duplicates and sort by timestamp
const uniqueLogs = Array.from(
new Map(allLogs.map((log) => [`${log.timestamp}-${log.line}`, log])).values()
).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

return logLines;
}

parseLogEntry(log: LogEntry): FlowEvent | null {
try {
// Parse the JSON log line
Expand Down
Loading
Loading