import { Registry, Tenant } from "@kumori/aurora-interfaces"; import { decodeRegistryAuth } from "../utils/utils"; interface HandleRegistryEventParams { eventData: any; parentParts: { [entity: string]: string }; tenantsMap: Map; secretsMap: Map; } interface HandleRegistryEventResult { registry: Registry; tenantId: string; tenantFound: boolean; updatedTenant: Tenant | null; pendingRegistry: { tenant: string; registry: Registry } | null; } /** * Extract registry credentials from secrets map */ const extractRegistryCredentials = ( tenantId: string, secretName: string, secretsMap: Map ): { username: string; password: string } => { let username = ""; let password = ""; const secretKey = `${tenantId}/${secretName}`; const credentialsKey = `${secretKey}_credentials`; const savedCredentials = secretsMap.get(credentialsKey); if (savedCredentials) { username = savedCredentials.secretUsername; password = savedCredentials.secretPassword; } else { const secretData = secretsMap.get(secretKey); if (secretData) { try { const parsedSecret = JSON.parse(secretData); if (parsedSecret.auths) { const registryUrl = Object.keys(parsedSecret.auths)[0]; if (registryUrl && parsedSecret.auths[registryUrl].auth) { const credentials = decodeRegistryAuth( parsedSecret.auths[registryUrl].auth ); username = credentials.username; password = credentials.password; } } } catch (error) { console.error("Error parsing registry secret in dregistry:", error); } } else { console.warn("Secret not found for registry:", { registryName: secretName, secretKey, availableSecrets: Array.from(secretsMap.keys()), }); } } return { username, password }; }; /** * Handles the "dregistry" event from WebSocket messages * Processes registry data and credentials */ export const handleRegistryEvent = ({ eventData, parentParts, tenantsMap, secretsMap, }: HandleRegistryEventParams): HandleRegistryEventResult => { const tenantId = parentParts.tenant; const registryName = eventData.id?.name; let username = ""; let password = ""; if (eventData.status?.secret?.name) { const credentials = extractRegistryCredentials( tenantId, eventData.status.secret.name, secretsMap ); username = credentials.username; password = credentials.password; } const newRegistry: Registry = { name: registryName, domain: eventData.spec.registry || "", public: true, credentials: username, password: password, description: `Registry for ${registryName}`, extra: eventData.meta.labels.logo || "", }; const tenant = tenantsMap.get(tenantId); let tenantFound = false; let updatedTenant: Tenant | null = null; let pendingRegistry: { tenant: string; registry: Registry } | null = null; if (tenant) { tenantFound = true; const existingIndex = tenant.registry.findIndex( (reg) => reg.domain === registryName ); if (existingIndex !== -1) { tenant.registry[existingIndex] = newRegistry; } else { tenant.registry.push(newRegistry); } updatedTenant = tenant; } else { pendingRegistry = { tenant: tenantId, registry: newRegistry, }; console.warn( `Registry orphaned for tenant ${tenantId}, added to pending registries.` ); } return { registry: newRegistry, tenantId, tenantFound, updatedTenant, pendingRegistry, }; };