packages/config-loader: more docs!

This commit is contained in:
Patrik Oldsberg
2020-06-13 13:15:22 +02:00
parent ee33cf6751
commit fbba694986
5 changed files with 41 additions and 1 deletions
+18
View File
@@ -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[] {
+4
View File
@@ -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);
+1 -1
View File
@@ -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,
+15
View File
@@ -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,
+3
View File
@@ -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;