packages/config-loader: more docs!
This commit is contained in:
@@ -21,6 +21,24 @@ const ENV_PREFIX = 'APP_CONFIG_';
|
||||
// Update the same pattern in config package if this is changed
|
||||
const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i;
|
||||
|
||||
/**
|
||||
* Read runtime configuration from the environment.
|
||||
*
|
||||
* Only environment variables prefixed with APP_CONFIG_ will be considered.
|
||||
*
|
||||
* For each variable, the prefix will be removed, and rest of the key will
|
||||
* be split by '_'. Each part will then be used as keys to build up a nested
|
||||
* config object structure. The treatment of the entire environment variable
|
||||
* is case-sensitive.
|
||||
*
|
||||
* The value of the variable should be JSON serialized, as it will be parsed
|
||||
* and the type will be kept intact. For example "true" and true are treated
|
||||
* differently, as well as "42" and 42.
|
||||
*
|
||||
* For example, to set the config app.title to "My Title", use the following:
|
||||
*
|
||||
* APP_CONFIG_app_title='"My Title"'
|
||||
*/
|
||||
export function readEnv(env: {
|
||||
[name: string]: string | undefined;
|
||||
}): AppConfig[] {
|
||||
|
||||
@@ -19,6 +19,10 @@ import { isObject } from './utils';
|
||||
import { JsonValue, JsonObject } from '@backstage/config';
|
||||
import { ReaderContext } from './types';
|
||||
|
||||
/**
|
||||
* Reads and parses, and validates, and transforms a single config file.
|
||||
* The transformation rewrites any special values, like the $secret key.
|
||||
*/
|
||||
export async function readConfigFile(filePath: string, ctx: ReaderContext) {
|
||||
const configYaml = await ctx.readFile(filePath);
|
||||
const config = yaml.parse(configYaml);
|
||||
|
||||
@@ -24,7 +24,7 @@ type ResolveOptions = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolves all configuration files that should be loaded.
|
||||
* Resolves all configuration files that should be loaded in the given environment.
|
||||
*/
|
||||
export async function resolveStaticConfig(
|
||||
options: ResolveOptions,
|
||||
|
||||
@@ -21,21 +21,31 @@ import { JsonObject, JsonValue } from '@backstage/config';
|
||||
import { isObject, isNever } from './utils';
|
||||
import { ReaderContext } from './types';
|
||||
|
||||
// Reads a file and forwards the contents as is, assuming ut8 encoding
|
||||
type FileSecret = {
|
||||
// Path to the secret file, relative to the config file.
|
||||
file: string;
|
||||
};
|
||||
|
||||
// Reads the secret from an environment variable.
|
||||
type EnvSecret = {
|
||||
// The name of the environment file.
|
||||
env: string;
|
||||
};
|
||||
|
||||
// Reads a secret from a json-like file and extracts a value at a path.
|
||||
// The supported extensions are define in dataSecretParser below.
|
||||
type DataSecret = {
|
||||
// Path to the data secret file, relative to the config file.
|
||||
data: string;
|
||||
// The path to the value inside the data file.
|
||||
// Either a '.' separated list, or an array of path segments.
|
||||
path: string | string[];
|
||||
};
|
||||
|
||||
type Secret = FileSecret | EnvSecret | DataSecret;
|
||||
|
||||
// Schema for each type of secret description
|
||||
const secretLoaderSchemas = {
|
||||
file: yup.object({
|
||||
file: yup.string().required(),
|
||||
@@ -54,6 +64,7 @@ const secretLoaderSchemas = {
|
||||
}),
|
||||
};
|
||||
|
||||
// The top-level secret schema, which figures out what type of secret it is.
|
||||
const secretSchema = yup.lazy<object>(value => {
|
||||
if (typeof value !== 'object' || value === null) {
|
||||
return yup.object().required().label('secret');
|
||||
@@ -75,6 +86,7 @@ const secretSchema = yup.lazy<object>(value => {
|
||||
);
|
||||
});
|
||||
|
||||
// Parsers for each type of data secret file.
|
||||
const dataSecretParser: {
|
||||
[ext in string]: (content: string) => Promise<JsonObject>;
|
||||
} = {
|
||||
@@ -83,6 +95,9 @@ const dataSecretParser: {
|
||||
'.yml': async content => yaml.parse(content),
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms a secret description into the actual secret value.
|
||||
*/
|
||||
export async function readSecret(
|
||||
data: JsonObject,
|
||||
ctx: ReaderContext,
|
||||
|
||||
@@ -19,6 +19,9 @@ import { JsonObject } from '@backstage/config';
|
||||
export type ReadFileFunc = (path: string) => Promise<string>;
|
||||
export type ReadSecretFunc = (desc: JsonObject) => Promise<string | undefined>;
|
||||
|
||||
/**
|
||||
* Common context that provides all the necessary hooks for reading configuration files.
|
||||
*/
|
||||
export type ReaderContext = {
|
||||
env: { [name in string]?: string };
|
||||
readFile: ReadFileFunc;
|
||||
|
||||
Reference in New Issue
Block a user