import { eventHelper } from "../backend-handler"; import { initializeGlobalWebSocketClient, makeGlobalWebSocketRequest, } from "../websocket-manager.ts"; import { environment } from "../environment.ts"; import { Account, Container, Environment, errors, Instance, MarketplaceItem, Organization, Platform, Registry, Resource, Service, Tenant, User, UserData, } from "@kumori/aurora-interfaces"; import { Revision } from "@kumori/aurora-interfaces/interfaces/revision-interface.ts"; type Security = string; export const loadUser = async (token: string, previousData: UserData) => { try { await initializeGlobalWebSocketClient(token, "", "", previousData); } catch (error) { console.error("Error in loadUser:", { error, errorMessage: error instanceof Error ? error.message : "Unknown error", stack: error instanceof Error ? error.stack : undefined, }); throw error; } }; export const isUserLogged = async (security: Security) => { let userLogged = false; try { await initializeGlobalWebSocketClient(security); await makeGlobalWebSocketRequest( "user:user_info", {}, 30000, "GET", "USER_INFO", ); userLogged = true; } catch (error) { console.error("User not logged in:", error); userLogged = false; } return userLogged; }; export const createUser = async (user: User) => { const userBody = { name: user.name, surname: user.surname, discoveryMethod: user.discoveryMethod, companyName: user.companyName, companyRole: user.rol, }; const response = await fetch( `${environment.apiServer.baseUrl}/api/${environment.apiServer.apiVersion}/user`, { method: "POST", body: JSON.stringify(userBody), }, ); if (response.ok) { eventHelper.user.publish.created(user); } if (!response.ok) { const error = await response.json(); user.name = error.code; eventHelper.user.publish.creationError(user); throw new Error( `HTTP Error ${response.status}: ${error.message || "Unknown error"}`, ); } }; export const loadUserData = async () => { try { const response = await makeGlobalWebSocketRequest("user:user_info", {}); const userResponse = response.data; const provider = Object.keys(userResponse.profiles)[0]; const email = userResponse.profiles[provider]?.spec?.claims?.email; const userData: UserData = { id: userResponse.userRecord.id.name, name: userResponse.userRecord.spec.userinfo.name, surname: userResponse.userRecord.spec.userinfo.surname, provider: [{ name: provider, email: email || "", password: "" }], notificationsEnabled: "true", organizations: [], clusterTokens: [], tokens: [], tenants: [], axebowPlan: "freemium", companyName: userResponse.userRecord.spec.userinfo.companyName, rol: userResponse.userRecord.spec.userinfo.companyRole, }; try { const tenantsResponse = await makeGlobalWebSocketRequest( "tenant:list_tenants", { strict: true }, 30000, "GET", "ALL_TENANTS", ); const tenantsData = tenantsResponse.data; const userTenants: Tenant[] = []; const userOrganizations: Organization[] = []; for (const [_, value] of Object.entries(tenantsData)) { const parts = (value as any).toString().split(","); userTenants.push({ id: parts[0], name: parts[0], organizationsIds: [], services: [], accounts: [], environments: [], marketplaceItems: [], resources: [], role: parts[1], status: "healthy", users: [], registry: [{ name: "", public: false, credentials: "", domain: "" }], }); } for (const tenant of userTenants) { try { const tenantResponse = await makeGlobalWebSocketRequest( "tenant:tenant_info", { tenant: tenant.name }, 30000, "GET", tenant.name, ); const tenantData = tenantResponse.data; const registries = tenantData?.registries?.registries; if (registries && Object.keys(registries).length > 0) { const tenantRegistry = Object.keys(registries)[0]; const tenantOptions = registries[tenantRegistry]?.options; let registry: Registry = { name: "", domain: "", public: false, credentials: "", description: "", extra: {}, password: "", }; if (tenantOptions?.endpoint) registry.domain = tenantOptions.endpoint; if (tenantOptions?.credentials) registry.credentials = tenantOptions.credentials; if (typeof tenantOptions?.public === "boolean") registry.public = tenantOptions.public; if (tenantData?.domains && Object.keys(tenantData.domains)[0]) registry.name = Object.keys(tenantData.domains)[0]; tenant.registry.push(registry); } const tenantAccounts: Account[] = []; const tenantEnvironments: Environment[] = []; const userServices: Service[] = []; if (tenantData && Array.isArray(tenantData.accounts)) { for (const account of tenantData.accounts) { const environmentsIds: string[] = []; if (account.environments && Array.isArray(account.environments)) { for (const env of account.environments) { const envId = `${env.id.name}`; environmentsIds.push(envId); const newEnvironment: Environment = { id: envId, name: env.id.name, account: `${account.account.id.parent.name}-${account.account.id.name}`, tenant: account.account.id.parent.name.split("tenant/")[1], logo: `${env.logo || "https://kumori.systems/wp-content/uploads/2023/07/cropped-favicon-kumori.png"}`, services: [], domains: [], status: { code: env.status.state, message: env.status.message, timestamp: env.status.timestamp, }, usage: { current: { cpu: env.status.marks.vcpu.current / 1000, memory: env.status.marks.memory.current / 1000, storage: env.status.marks.storage.current / 1000, volatileStorage: env.status.marks.vstorage.current / 1000, nonReplicatedStorage: env.status.marks.nrstorage.current / 1000, persistentStorage: env.status.marks.rstorage.current / 1000, }, limit: { cpu: { max: env.spec.marks.vcpu.highmark / 1000, min: env.spec.marks.vcpu.lowmark / 1000, }, memory: { max: env.spec.marks.memory.highmark / 1000, min: env.spec.marks.memory.lowmark / 1000, }, storage: { max: env.spec.marks.storage.highmark / 1000, min: env.spec.marks.storage.lowmark / 1000, }, volatileStorage: { max: env.spec.marks.vstorage.highmark / 1000, min: env.spec.marks.vstorage.lowmark / 1000, }, nonReplicatedStorage: { max: env.spec.marks.nrstorage.highmark / 1000, min: env.spec.marks.nrstorage.lowmark / 1000, }, persistentStorage: { max: env.spec.marks.rstorage.highmark / 1000, min: env.spec.marks.rstorage.lowmark / 1000, }, }, cost: env.status.marks.cost.current, }, organization: "", cloudProvider: "", labels: [], type: "", cluster: { name: "" }, }; tenantEnvironments.push(newEnvironment); } } const cloudProviderInfo = extractCloudProviderInfo( account.account.spec, ); const newAccount: Account = { id: `${account.account.id.parent.name}-${account.account.id.name}`, name: account.account.id.name, tenant: account.account.id.parent.name.split("tenant/")[1], cloudProvider: { name: account.account.spec.api, ...cloudProviderInfo, }, logo: `${account.account.spec.api || "https://kumori.systems/wp-content/uploads/2023/07/cropped-favicon-kumori.png"}`, environments: environmentsIds, services: [], domains: [], status: account.account.status.validCredentials ? account.account.status.validCredentials?.status === "InvalidCredentials" ? "InvalidCredentials" : !account.account.status.validCredentials?.status && account.account.id !== "kumori" ? "pending" : "healthy" : "", usage: { current: { cpu: account.account.status.marks.vcpu.current / 1000, memory: account.account.status.marks.memory.current / 1000, storage: account.account.status.marks.storage.current / 1000, volatileStorage: account.account.status.marks.vstorage.current / 1000, nonReplicatedStorage: account.account.status.marks.nrstorage.current / 1000, persistentStorage: account.account.status.marks.rstorage.current / 1000, }, limit: { cpu: { max: account.account.spec.marks.vcpu.highmark / 1000, min: account.account.spec.marks.vcpu.lowmark / 1000, }, memory: { max: account.account.spec.marks.memory.highmark / 1000, min: account.account.spec.marks.memory.lowmark / 1000, }, storage: { max: account.account.spec.marks.storage.highmark / 1000, min: account.account.spec.marks.storage.lowmark / 1000, }, volatileStorage: { max: account.account.spec.marks.vstorage.highmark / 1000, min: account.account.spec.marks.vstorage.lowmark / 1000, }, nonReplicatedStorage: { max: account.account.spec.marks.nrstorage.highmark / 1000, min: account.account.spec.marks.nrstorage.lowmark / 1000, }, persistentStorage: { max: account.account.spec.marks.rstorage.highmark / 1000, min: account.account.spec.marks.rstorage.lowmark / 1000, }, }, cost: account.account.status.marks.cost.current, }, flavors: { small: account.account.spec.iaasconfig.smallVMFlavor, medium: account.account.spec.iaasconfig.mediumVMFlavor, large: account.account.spec.iaasconfig.largeVMFlavor, volatile: account.account.spec.iaasconfig.volatile, nonReplicated: account.account.spec.iaasconfig.nonreplicated, persistent: account.account.spec.iaasconfig.persistent, }, organization: account.organization, }; tenantAccounts.push(newAccount); } const kinds = [ "ca", "certificate", "domain", "port", "secret", "volume", ]; for (const kind of kinds) { try { const resourcesResponse = await makeGlobalWebSocketRequest( "resource:list_resources", { tenant: tenant.name, kind }, 30000, "GET", "ALL_RESOURCES", ); const resourcesData = resourcesResponse.data; if ( !resourcesData[kind] || !Array.isArray(resourcesData[kind]) ) { console.warn( `No se encontraron recursos de tipo ${kind} o no es un array`, ); continue; } for (const resource of resourcesData[kind]) { try { const resourceName = resource.id.name; const resourceResponse = await makeGlobalWebSocketRequest( "resource:resource_info", { tenant: tenant.name, kind, resource: resourceName }, 30000, "GET", resourceName, ); const resourceDataJson = resourceResponse.data; const resourceType = resourceDataJson.id.kind; let resourceStatus: "used" | "available" | "error" = "available"; if (resourceDataJson.status?.requested) { if ( Object.keys(resourceDataJson.status.requested).length > 0 ) { resourceStatus = "used"; } } if (resourceType === "volume") { tenant.resources.push({ type: kind, name: resourceName, value: resourceDataJson.spec[resourceType].size, kind: resourceDataJson.spec[resourceType].kind, maxItems: resourceDataJson.spec[resourceType].maxitems, status: resourceStatus, } as Resource); } else if (resourceType === "certificate") { tenant.resources.push({ type: kind, name: resourceName, value: resourceDataJson.spec[resourceType].cert, key: resourceDataJson.spec[resourceType].key, domain: resourceDataJson.spec[resourceType].domain, status: resourceStatus, } as Resource); } else if ( ["domain", "port", "ca", "secret"].includes(resourceType) ) { tenant.resources.push({ type: kind, name: resourceName, value: resourceDataJson.spec[resourceType], status: resourceStatus, } as Resource); } } catch (resourceError) { console.error( `Error procesando recurso individual de tipo ${kind}:`, resourceError, ); } } } catch (error) { console.error( `Error procesando recursos de tipo ${kind}:`, error, ); } } } const servicesResponse = await makeGlobalWebSocketRequest( "service:list_services", { tenant: tenant.name }, 30000, "GET", "ALL_SERVICES", ); const servicesData = servicesResponse.data; const serviceEntries = Object.entries(servicesData); for (const [, serviceValue] of serviceEntries) { try { let serviceStatus = { code: "", message: "", timestamp: "", args: [], }; const serviceResponse = await makeGlobalWebSocketRequest( "service:describe_service", { tenant: tenant.name, service: (serviceValue as any).name, summary: false, }, 30000, "GET", (serviceValue as any).name, ); const serviceData = serviceResponse.data; let revisionData: any; try { const revisionResponse = await makeGlobalWebSocketRequest( "revision:revision_info", { tenant: tenant.name, service: (serviceValue as any).name, revision: "latest", }, 30000, "GET_REVISION", (serviceValue as any).name, ); revisionData = revisionResponse.data; } catch (revisionError) { serviceStatus = { code: "PENDING", message: "", timestamp: "", args: [], }; console.warn( `No se pudo obtener la revisión para el servicio ${(serviceValue as any).name}:`, revisionError, ); continue; } const serviceName = revisionData.solution.top; // revisionData.revision is a string ID, revisionData.intensives has the resource limits const revisionId: string = revisionData.revision; const intensives = revisionData.intensives ?? {}; let rawHistoryData: any[] = []; try { const revisionsResponse = await makeGlobalWebSocketRequest( "service:report_history_service", { tenant: tenant.name, service: serviceName }, 30000, "GET_HISTORY", serviceName, ); rawHistoryData = revisionsResponse.data ?? []; } catch (historyError) { serviceStatus = { code: "PENDING", message: "", timestamp: "", args: [], }; console.warn( `No se pudo obtener el historial para el servicio ${serviceName}:`, historyError, ); continue; } const revisions: Revision[] = (rawHistoryData as any[]).map( (entry: any) => ({ id: String(entry.revision ?? entry.id ?? ""), schema: entry.spec ?? {}, usage: { current: { cpu: 0, memory: 0, storage: 0, volatileStorage: 0, nonReplicatedStorage: 0, persistentStorage: 0, }, limit: { cpu: { max: 0, min: 0 }, memory: { max: 0, min: 0 }, storage: { max: 0, min: 0 }, volatileStorage: { max: 0, min: 0 }, nonReplicatedStorage: { max: 0, min: 0 }, persistentStorage: { max: 0, min: 0 }, }, cost: 0, }, status: entry.status ?? { code: "", message: "", timestamp: "", args: [], }, createdAt: entry.createdAt ?? "", }), ); const serviceRoles: { name: string; instances: Instance[] }[] = []; let serviceUsedVCPU = 0; let serviceUsedRAM = 0; const roles = revisionData.solution.deployments[serviceName].artifact .description.role; for (const roleName of Object.keys(roles)) { try { const instancesResponse = await makeGlobalWebSocketRequest( "service:describe_role_service", { tenant: tenant.name, service: serviceName, role: roleName, }, 30000, "GET_ROLE", `${serviceName}_${roleName}`, ); const instancesData = instancesResponse.data; const instances: Instance[] = []; for (const [instanceName, instanceValue] of Object.entries( instancesData.instances, )) { const containers: Container[] = []; for (const [ containerName, containerValue, ] of Object.entries((instanceValue as any).containers)) { containers.push({ name: containerName, ready: (containerValue as any).ready, reestartCount: (containerValue as any).restarts, metrics: { cpu: (containerValue as any).metrics.usage.cpu, memory: (containerValue as any).metrics.usage.memory, }, states: (containerValue as any).states, }); serviceUsedVCPU += (containerValue as any).metrics.usage .cpu; serviceUsedRAM += (containerValue as any).metrics.usage .memory; } instances.push({ id: instanceName, name: instanceName, status: (instanceValue as any).status, usage: { current: { cpu: (instanceValue as any).metrics.usage.cpu, memory: (instanceValue as any).metrics.usage.memory, storage: 0, volatileStorage: 0, nonReplicatedStorage: 0, persistentStorage: 0, }, limit: { cpu: { max: serviceData.artifact.description.role[roleName] .artifact.description.code[roleName]?.size?.cpu ?.min / 1000, min: serviceData.artifact.description.role[roleName] .artifact.description.code[roleName]?.size?.cpu ?.min / 1000, }, memory: { max: serviceData.artifact.description.role[roleName] .artifact.description.code[roleName]?.size ?.memory?.size / 1000, min: serviceData.artifact.description.role[roleName] .artifact.description.code[roleName]?.size ?.memory?.size / 1000, }, storage: { max: 0, min: 0 }, volatileStorage: { max: 0, min: 0 }, nonReplicatedStorage: { max: 0, min: 0 }, persistentStorage: { max: 0, min: 0 }, }, cost: 0, }, logs: [], containers, }); } serviceRoles.push({ name: roleName, instances }); } catch (instanceError) { serviceStatus = { code: "PENDING", message: "", timestamp: "", args: [], }; console.warn( `Error obteniendo instancias para el rol ${roleName}:`, instanceError, ); } } let containerName = ""; const firstRoleName = Object.keys(roles)[0]; const code = roles[firstRoleName].artifact.description.code; for (const key of Object.keys(code)) { if (!key.includes("INIT")) { containerName = key; break; } } const newService: Service = { id: (serviceValue as any).name, tenant: tenant.name, account: (serviceValue as any).environment.split("/")[4], environment: (serviceValue as any).environment.split("/")[6], name: (serviceValue as any).name, logo: "", description: "", revisions, status: serviceStatus, role: serviceRoles, links: [], resources: [], parameters: [], usage: { current: { cpu: serviceUsedVCPU, memory: serviceUsedRAM / 1000000000, storage: 0, volatileStorage: 0, nonReplicatedStorage: 0, persistentStorage: 0, }, limit: { cpu: { max: intensives.vcpu / 1000, min: intensives.vcpu / 1000, }, memory: { max: intensives.ram / 1000, min: intensives.ram / 1000, }, storage: { max: intensives.shared_disk, min: intensives.shared_disk, }, volatileStorage: { max: intensives.volatile_disk, min: intensives.volatile_disk, }, nonReplicatedStorage: { max: intensives.nrpersistent_disk, min: intensives.nrpersistent_disk, }, persistentStorage: { max: intensives.persistent_disk, min: intensives.persistent_disk, }, }, cost: 0, }, minReplicas: 0, maxReplicas: 0, lastDeployed: `${revisionData.tstamp ?? ""}`, project: "", registry: roles[firstRoleName].artifact.description.code[containerName] ?.image?.hub?.name ?? "", imageName: roles[firstRoleName].artifact.description.code[containerName] ?.image?.tag ?? "", entrypoint: roles[firstRoleName].artifact.description.code[containerName] ?.entrypoint ?? "", cmd: roles[firstRoleName].artifact.description.code[containerName] ?.cmd ?? "", serverChannels: [], clientChannels: [], duplexChannels: [], cloudProvider: "", currentRevision: revisionId, }; userServices.push(newService); } catch (error) { console.error("Error al obtener los datos del servicio:", error); } } for (const account of tenantAccounts) { account.services = userServices .filter((service) => service.account === account.name) .map((service) => service.name); } for (const env of tenantEnvironments) { env.services = userServices .filter((service) => service.environment === env.name) .map((service) => service.name); } try { const marketplaceResponse = await makeGlobalWebSocketRequest( "marketplace:search_marketplace", { tenant: tenant.name, name: "" }, 30000, "GET", "MARKETPLACE", ); const marketplaceData = marketplaceResponse.data; const tenantItems: MarketplaceItem[] = []; Object.entries(marketplaceData.items).forEach(([_, value]) => { let cpu = 0; let memory = 0; (value as any).tags.forEach((tag: string) => { if (tag.includes("cpu")) cpu = Number(tag.split("::")[1].split("vCPU")[0]); else if (tag.includes("memory")) memory = Number(tag.split("::")[1].split("MB")[0]); }); tenantItems.push({ tenant: tenant.toString(), name: (value as any).name, logo: (value as any).icon, description: (value as any).name, version: (value as any).version, requirements: { cpu, memory }, status: "", instances: [], links: [], resources: [], domain: (value as any).domain, type: (value as any).artifactTypes[0], }); }); tenant.marketplaceItems = tenantItems; } catch (marketplaceError) { console.error( `Error obteniendo marketplace para tenant ${tenant.name}:`, marketplaceError, ); tenant.marketplaceItems = []; } tenant.accounts = tenantAccounts; tenant.environments = tenantEnvironments; tenant.services = userServices; } catch (tenantError) { console.error(`Error procesando tenant ${tenant.name}:`, tenantError); } } try { const organizationsResponse = await makeGlobalWebSocketRequest( "organization:list_organizations", { strict: true }, 30000, "GET", "ORGANIZATIONS", ); const organizationsData = organizationsResponse.data; for (const [, organizationValue] of Object.entries(organizationsData)) { userOrganizations.push({ id: (organizationValue as any).spec.companyName, name: (organizationValue as any).id.name, usersIds: Object.keys((organizationValue as any).spec.users), tenantsIds: Object.keys((organizationValue as any).spec.tenants), billingInformation: { legalName: (organizationValue as any).spec.billing.companyname, CIFNIF: (organizationValue as any).id.name, email: (organizationValue as any).spec.billing.email, language: (organizationValue as any).spec.billing.language, country: (organizationValue as any).spec.billing.country, region: (organizationValue as any).spec.billing.region, city: (organizationValue as any).spec.billing.city, address: (organizationValue as any).spec.billing.address, zipcode: (organizationValue as any).spec.billing.zip, }, invoices: [], }); } } catch (organizationError) { console.error("Error obteniendo organizaciones:", organizationError); } try { const platformResponse = await makeGlobalWebSocketRequest( "misc:info", {}, 30000, "GET", "PLATFORM", ); const platformData: Platform = { instanceName: String(platformResponse.instanceName), platformVersion: String(platformResponse.platformVersion), referenceDomain: String(platformResponse.referenceDomain), apiVersions: Array.isArray(platformResponse.apiVersions) ? platformResponse.apiVersions.map(String) : [], oidProviders: Array.isArray(platformResponse.oidProviders) ? platformResponse.oidProviders.map(String) : [], iaasProviders: typeof platformResponse.iaasProviders === "object" && platformResponse.iaasProviders !== null ? platformResponse.iaasProviders : {}, freemiumAdvancedLimits: { vcpu: { lowmark: Number( platformResponse.freemiumAdvancedLimits.vcpu.lowmark, ), highmark: Number( platformResponse.freemiumAdvancedLimits.vcpu.highmark, ), unit: String(platformResponse.freemiumAdvancedLimits.vcpu.unit), }, memory: { lowmark: Number( platformResponse.freemiumAdvancedLimits.memory.lowmark, ), highmark: Number( platformResponse.freemiumAdvancedLimits.memory.highmark, ), unit: String(platformResponse.freemiumAdvancedLimits.memory.unit), }, vstorage: { lowmark: Number( platformResponse.freemiumAdvancedLimits.vstorage.lowmark, ), highmark: Number( platformResponse.freemiumAdvancedLimits.vstorage.highmark, ), unit: String( platformResponse.freemiumAdvancedLimits.vstorage.unit, ), }, nrstorage: { lowmark: Number( platformResponse.freemiumAdvancedLimits.nrstorage.lowmark, ), highmark: Number( platformResponse.freemiumAdvancedLimits.nrstorage.highmark, ), unit: String( platformResponse.freemiumAdvancedLimits.nrstorage.unit, ), }, rstorage: { lowmark: Number( platformResponse.freemiumAdvancedLimits.rstorage.lowmark, ), highmark: Number( platformResponse.freemiumAdvancedLimits.rstorage.highmark, ), unit: String( platformResponse.freemiumAdvancedLimits.rstorage.unit, ), }, storage: { lowmark: Number( platformResponse.freemiumAdvancedLimits.storage.lowmark, ), highmark: Number( platformResponse.freemiumAdvancedLimits.storage.highmark, ), unit: String( platformResponse.freemiumAdvancedLimits.storage.unit, ), }, cost: { lowmark: Number( platformResponse.freemiumAdvancedLimits.cost.lowmark, ), highmark: Number( platformResponse.freemiumAdvancedLimits.cost.highmark, ), unit: String(platformResponse.freemiumAdvancedLimits.cost.unit), }, }, freemiumLimits: { vcpu: { lowmark: Number(platformResponse.freemiumLimits.vcpu.lowmark), highmark: Number(platformResponse.freemiumLimits.vcpu.highmark), unit: String(platformResponse.freemiumLimits.vcpu.unit), }, memory: { lowmark: Number(platformResponse.freemiumLimits.memory.lowmark), highmark: Number(platformResponse.freemiumLimits.memory.highmark), unit: String(platformResponse.freemiumLimits.memory.unit), }, vstorage: { lowmark: Number(platformResponse.freemiumLimits.vstorage.lowmark), highmark: Number( platformResponse.freemiumLimits.vstorage.highmark, ), unit: String(platformResponse.freemiumLimits.vstorage.unit), }, nrstorage: { lowmark: Number( platformResponse.freemiumLimits.nrstorage.lowmark, ), highmark: Number( platformResponse.freemiumLimits.nrstorage.highmark, ), unit: String(platformResponse.freemiumLimits.nrstorage.unit), }, rstorage: { lowmark: Number(platformResponse.freemiumLimits.rstorage.lowmark), highmark: Number( platformResponse.freemiumLimits.rstorage.highmark, ), unit: String(platformResponse.freemiumLimits.rstorage.unit), }, storage: { lowmark: Number(platformResponse.freemiumLimits.storage.lowmark), highmark: Number( platformResponse.freemiumLimits.storage.highmark, ), unit: String(platformResponse.freemiumLimits.storage.unit), }, cost: { lowmark: Number(platformResponse.freemiumLimits.cost.lowmark), highmark: Number(platformResponse.freemiumLimits.cost.highmark), unit: String(platformResponse.freemiumLimits.cost.unit), }, }, portrange: Array.isArray(platformResponse.portrange) ? platformResponse.portrange.map(Number) : [], }; if (eventHelper.user) { eventHelper.user.publish.loaded( new User(userData, userTenants, userOrganizations, platformData), ); } } catch (error) { console.error("Error al obtener los datos del tenant:", error); throw error; } } catch (error) { console.error("Error al obtener los datos del usuario:", error); } } catch (err) { console.error(err); } }; const extractCloudProviderInfo = (accountSpec: any) => { const credentials = accountSpec.credentials; if (!credentials) { return { region: "", interface: "", apiVersion: "", authType: "", authUrl: "", credentialId: "", credentialSecret: "", }; } if (credentials.openstack) { return { region: credentials.openstack.region_name ?? "", interface: credentials.openstack.interface ?? "", apiVersion: credentials.openstack.identity_api_version ?? "", authType: credentials.openstack.auth_type ?? "", authUrl: credentials.openstack.auth?.auth_url ?? "", credentialId: credentials.openstack.auth?.credential_id ?? credentials.openstack.auth?.application_credential_id ?? "", credentialSecret: credentials.openstack.auth?.credential_secret ?? credentials.openstack.auth?.application_credential_secret ?? "", }; } return { region: "", interface: "", apiVersion: "", authType: credentials.method ?? "", authUrl: credentials.apiuri ?? "", credentialId: "", credentialSecret: "", }; }; export const updateUser = async (user: User) => { try { const userBody = { spec: { name: user.name, surname: user.surname, discoveryMethod: "work", companyName: user.companyName, companyRole: user.rol, }, }; await makeGlobalWebSocketRequest( "user:modify_user_info", userBody, 30000, "PUT", "UPDATE_USER", ); eventHelper.user.publish.updated(user); eventHelper.notification.publish.creation({ type: "success", subtype: errors.user.updated.subtype, date: Date.now().toString(), status: "unread", callToAction: false, data: { user: user.name }, }); } catch (error) { console.error("Error updating user:", { error, errorMessage: error instanceof Error ? error.message : "Unknown error", stack: error instanceof Error ? error.stack : undefined, }); eventHelper.user.publish.updateError(user); eventHelper.notification.publish.creation({ type: "error", subtype: errors.user.updateError.subtype, date: Date.now().toString(), status: "unread", callToAction: false, info_content: { code: (error as any).error.code, message: (error as any).error.content, }, data: { user: user.name }, userError: true, }); throw error; } }; export const deleteUSer = async (user: User, security: string) => { try { await initializeGlobalWebSocketClient(security); const response = await makeGlobalWebSocketRequest( "user:delete_user", {}, 30000, "DELETE", "DELETE_USER", "user", ); eventHelper.notification.publish.creation({ type: "success", subtype: errors.user.deleted.subtype, date: Date.now().toString(), status: "unread", callToAction: false, data: { user: user.name }, }); return response; } catch (error) { console.error("Error deleting user:", error); eventHelper.notification.publish.creation({ type: "error", subtype: errors.user.deleteError.subtype, date: Date.now().toString(), status: "unread", callToAction: false, info_content: { code: (error as any).error.code, message: (error as any).error.content, }, data: { user: user.name }, userError: true, }); throw error; } }; export const getUserHTTP = async () => { try { const url = new URL( `${environment.apiServer.baseUrl}/api/${environment.apiServer.apiVersion}/user/info`, ); const response = await fetch(url.toString(), { method: "GET", headers: { }, credentials: "include", }); const userData = await response.json(); return userData; } catch (error) { console.error("Error fetching user data:", error); throw error; } };