Merge pull request #21632 from davidfestal/support-additional-config-schemas

Support external config schemas in the backend
This commit is contained in:
Patrik Oldsberg
2024-02-13 12:04:04 +01:00
committed by GitHub
23 changed files with 540 additions and 13 deletions
+2
View File
@@ -4,6 +4,7 @@
```ts
import { Config } from '@backstage/config';
import { ConfigSchema } from '@backstage/config-loader';
import express from 'express';
import { Logger } from 'winston';
import { PluginDatabaseManager } from '@backstage/backend-common';
@@ -20,6 +21,7 @@ export interface RouterOptions {
disableConfigInjection?: boolean;
// (undocumented)
logger: Logger;
schema?: ConfigSchema;
staticFallbackHandler?: express.Handler;
}
```
+11 -2
View File
@@ -19,7 +19,11 @@ import { resolve as resolvePath } from 'path';
import { Logger } from 'winston';
import { AppConfig, Config } from '@backstage/config';
import { JsonObject } from '@backstage/types';
import { loadConfigSchema, readEnvConfig } from '@backstage/config-loader';
import {
ConfigSchema,
loadConfigSchema,
readEnvConfig,
} from '@backstage/config-loader';
type InjectOptions = {
appConfigs: AppConfig[];
@@ -74,6 +78,7 @@ type ReadOptions = {
env: { [name: string]: string | undefined };
appDistDir: string;
config: Config;
schema?: ConfigSchema;
};
/**
@@ -90,7 +95,11 @@ export async function readConfigs(options: ReadOptions): Promise<AppConfig[]> {
const serializedSchema = await fs.readJson(schemaPath);
try {
const schema = await loadConfigSchema({ serialized: serializedSchema });
const schema =
options.schema ||
(await loadConfigSchema({
serialized: serializedSchema,
}));
const frontendConfigs = await schema.process(
[{ data: config.get() as JsonObject, context: 'app' }],
+19 -1
View File
@@ -21,7 +21,11 @@ import {
} from '@backstage/backend-plugin-api';
import { createRouter } from './router';
import { loggerToWinstonLogger } from '@backstage/backend-common';
import { staticFallbackHandlerExtensionPoint } from '@backstage/plugin-app-node';
import {
configSchemaExtensionPoint,
staticFallbackHandlerExtensionPoint,
} from '@backstage/plugin-app-node';
import { ConfigSchema } from '@backstage/config-loader';
/**
* The App plugin is responsible for serving the frontend app bundle and static assets.
@@ -31,6 +35,7 @@ export const appPlugin = createBackendPlugin({
pluginId: 'app',
register(env) {
let staticFallbackHandler: express.Handler | undefined;
let schema: ConfigSchema | undefined;
env.registerExtensionPoint(staticFallbackHandlerExtensionPoint, {
setStaticFallbackHandler(handler) {
@@ -43,6 +48,17 @@ export const appPlugin = createBackendPlugin({
},
});
env.registerExtensionPoint(configSchemaExtensionPoint, {
setConfigSchema(configSchema) {
if (schema) {
throw new Error(
'Attempted to set config schema for the app-backend twice',
);
}
schema = configSchema;
},
});
env.registerInit({
deps: {
logger: coreServices.logger,
@@ -53,6 +69,7 @@ export const appPlugin = createBackendPlugin({
async init({ logger, config, database, httpRouter }) {
const appPackageName =
config.getOptionalString('app.packageName') ?? 'app';
const winstonLogger = loggerToWinstonLogger(logger);
const router = await createRouter({
@@ -61,6 +78,7 @@ export const appPlugin = createBackendPlugin({
database,
appPackageName,
staticFallbackHandler,
schema,
});
httpRouter.use(router);
},
@@ -37,6 +37,7 @@ import {
CACHE_CONTROL_NO_CACHE,
CACHE_CONTROL_REVALIDATE_CACHE,
} from '../lib/headers';
import { ConfigSchema } from '@backstage/config-loader';
// express uses mime v1 while we only have types for mime v2
type Mime = { lookup(arg0: string): string };
@@ -85,6 +86,13 @@ export interface RouterOptions {
* This also disables configuration injection though `APP_CONFIG_` environment variables.
*/
disableConfigInjection?: boolean;
/**
*
* Provides a ConfigSchema.
*
*/
schema?: ConfigSchema;
}
/** @public */
@@ -121,6 +129,7 @@ export async function createRouter(
config,
appDistDir,
env: process.env,
schema: options.schema,
});
injectedConfigPath = await injectConfig({ appConfigs, logger, staticDir });