diff --git a/packages/backend-defaults/report-alpha.api.md b/packages/backend-defaults/report-alpha.api.md index 043072da87..7e7cccc007 100644 --- a/packages/backend-defaults/report-alpha.api.md +++ b/packages/backend-defaults/report-alpha.api.md @@ -38,7 +38,7 @@ export class DefaultSystemMetadataService implements SystemMetadataService { // @alpha export const systemMetadataServiceFactory: ServiceFactory< SystemMetadataService, - 'plugin', + 'root', 'singleton' >; diff --git a/packages/backend-defaults/src/entrypoints/systemMetadata/lib/DefaultSystemMetadataService.ts b/packages/backend-defaults/src/entrypoints/systemMetadata/lib/DefaultSystemMetadataService.ts index 96fa8b1820..0d1583a113 100644 --- a/packages/backend-defaults/src/entrypoints/systemMetadata/lib/DefaultSystemMetadataService.ts +++ b/packages/backend-defaults/src/entrypoints/systemMetadata/lib/DefaultSystemMetadataService.ts @@ -22,14 +22,49 @@ import { BackstageInstance, SystemMetadataService, } from '@backstage/backend-plugin-api/alpha'; +import z from 'zod'; + +const targetObjectSchema = z.object({ + internal: z.string(), + external: z.string(), +}); /** * @alpha */ export class DefaultSystemMetadataService implements SystemMetadataService { + private instances: BackstageInstance[]; constructor( private options: { logger: LoggerService; config: RootConfigService }, - ) {} + ) { + const getInstances = () => { + const endpoints = + options.config.getOptionalConfigArray('discovery.instances') ?? []; + const instances: BackstageInstance[] = []; + for (const endpoint of endpoints) { + const baseUrl = endpoint.getOptional('baseUrl'); + if (baseUrl) { + if (typeof baseUrl === 'string') { + instances.push({ internalUrl: baseUrl, externalUrl: baseUrl }); + } else { + const parseAttempt = targetObjectSchema.safeParse(baseUrl); + if (parseAttempt.success) { + const { internal, external } = parseAttempt.data; + instances.push({ + internalUrl: internal, + externalUrl: external, + }); + } + } + } + } + return instances; + }; + this.instances = getInstances(); + this.options.config.subscribe?.(() => { + this.instances = getInstances(); + }); + } public static create(pluginEnv: { logger: LoggerService; @@ -39,15 +74,6 @@ export class DefaultSystemMetadataService implements SystemMetadataService { } async listInstances() { - const endpoints = - this.options.config.getOptionalConfigArray('discovery.instances') ?? []; - const instances: BackstageInstance[] = []; - for (const endpoint of endpoints) { - const baseUrl = endpoint.getOptionalString('baseUrl'); - if (baseUrl) { - instances.push({ url: baseUrl }); - } - } - return instances; + return this.instances; } } diff --git a/packages/backend-defaults/src/entrypoints/systemMetadata/lib/createSystemMetadataRouter.ts b/packages/backend-defaults/src/entrypoints/systemMetadata/lib/createSystemMetadataRouter.ts index 4750ed07db..66e1759213 100644 --- a/packages/backend-defaults/src/entrypoints/systemMetadata/lib/createSystemMetadataRouter.ts +++ b/packages/backend-defaults/src/entrypoints/systemMetadata/lib/createSystemMetadataRouter.ts @@ -43,17 +43,20 @@ export async function createSystemMetadataRouter(options: { const featurePromises = await Promise.allSettled( instances.map(async instance => { const response = await fetch( - `${instance.url}/.backstage/instanceMetadata/v1/features/installed`, + `${instance.internalUrl}/.backstage/instanceMetadata/v1/features/installed`, ); if (response.ok) { return { instance, response: await response.json() }; } throw new Error( - `Failed to fetch installed features from ${instance.url}`, + `Failed to fetch installed features from ${instance.internalUrl}`, ); }), ); - const pluginByInstance: Record = {}; + const pluginByInstance: Record< + string, + { internalUrl: string; externalUrl: string }[] + > = {}; for (const result of featurePromises) { if (result.status !== 'fulfilled') { logger.error(`Failed to fetch installed features: ${result.reason}`); @@ -67,7 +70,7 @@ export async function createSystemMetadataRouter(options: { if (!pluginByInstance[feature.pluginId]) { pluginByInstance[feature.pluginId] = []; } - pluginByInstance[feature.pluginId].push(instance.url); + pluginByInstance[feature.pluginId].push(instance); } } } diff --git a/packages/backend-plugin-api/src/alpha/index.ts b/packages/backend-plugin-api/src/alpha/index.ts index 2262c5a3f1..be5cb882fc 100644 --- a/packages/backend-plugin-api/src/alpha/index.ts +++ b/packages/backend-plugin-api/src/alpha/index.ts @@ -40,5 +40,4 @@ export const systemMetadataServiceRef = createServiceRef< export type { BackstageInstance, SystemMetadataService, - Target, } from './services/definitions/SystemMetadataService'; diff --git a/packages/backend-plugin-api/src/services/definitions/SystemMetadataService.ts b/packages/backend-plugin-api/src/services/definitions/SystemMetadataService.ts index 58ab02b000..20ce759679 100644 --- a/packages/backend-plugin-api/src/services/definitions/SystemMetadataService.ts +++ b/packages/backend-plugin-api/src/services/definitions/SystemMetadataService.ts @@ -14,14 +14,12 @@ * limitations under the License. */ -/** @alpha */ -export type Target = string | { internal: string; external: string }; - /** * @alpha */ export interface BackstageInstance { - url: Target; + internalUrl: string; + externalUrl: string; } /** diff --git a/packages/backend/app-config.split.yaml b/packages/backend/app-config.split.yaml index d1a7cf76f1..0eadc9f091 100644 --- a/packages/backend/app-config.split.yaml +++ b/packages/backend/app-config.split.yaml @@ -6,4 +6,6 @@ discovery: plugins: [catalog] instances: - baseUrl: http://localhost:7007 - - baseUrl: http://localhost:7008 + - baseUrl: + internal: http://localhost:7008 + external: http://127.0.0.1:7008