Appearance
Schema: Data Generation
Konfigo's schema allows you to define generators
that create new data within your configuration. Generators construct values from existing configuration data and variables, enabling dynamic configuration composition.
Available Generators
Konfigo provides several built-in generators:
concat
: Combines configuration data, variables, and literal texttimestamp
: Generates current timestamp in various formatsrandom
: Generates random values (integers, floats, strings, UUIDs)id
: Generates various types of identifiers using alphanumeric characters
concat
Generator
The concat
generator creates string values by combining configuration data, variable substitutions, and literal text. It operates in two phases: first replacing {placeholder}
tokens with values from configuration paths, then resolving ${VARIABLE}
references.
Structure
yaml
generators:
- type: "concat"
targetPath: "path.to.new.key"
format: "template with {placeholders} and ${VARIABLES}"
sources:
placeholder_name: "config.path.to.value"
Fields
type
(Required): Must be"concat"
targetPath
(Required): Dot-separated path where the generated value will be placedformat
(Required): Template string with{placeholders}
and${VARIABLES}
sources
(Required): Map of placeholder names to configuration paths
Processing Order
- Replace
{placeholder}
tokens usingsources
mapping - Resolve
${VARIABLE}
references from vars and environment - Insert result at
targetPath
timestamp
Generator
The timestamp
generator creates timestamp values in various formats.
Structure
yaml
generators:
- type: "timestamp"
targetPath: "path.to.timestamp"
format: "rfc3339" # Optional, defaults to "rfc3339"
Fields
type
(Required): Must be"timestamp"
targetPath
(Required): Dot-separated path where the timestamp will be placedformat
(Optional): Timestamp format (defaults to "rfc3339")
Supported Formats
unix
: Unix timestamp (seconds since epoch) - e.g.,1640995200
unixmilli
: Unix timestamp in milliseconds - e.g.,1640995200000
rfc3339
: RFC3339 format - e.g.,2021-12-31T16:00:00Z
iso8601
: ISO8601 format - e.g.,2021-12-31T16:00:00Z
- Custom: Any Go time format string - e.g.,
2006-01-02 15:04:05
Example
yaml
generators:
- type: "timestamp"
targetPath: "metadata.createdAt"
format: "rfc3339"
- type: "timestamp"
targetPath: "metadata.buildTime"
format: "2006-01-02 15:04:05"
random
Generator
The random
generator creates random values in various formats.
Structure
yaml
generators:
- type: "random"
targetPath: "path.to.random.value"
format: "string:16" # Required
Fields
type
(Required): Must be"random"
targetPath
(Required): Dot-separated path where the random value will be placedformat
(Required): Random value format specification
Supported Formats
int:min:max
: Random integer between min and max (inclusive) - e.g.,int:1:100
float:min:max
: Random float between min and max - e.g.,float:0.0:1.0
string:length
: Random string using [a-zA-Z0-9] - e.g.,string:16
bytes:length
: Random bytes as hex string - e.g.,bytes:8
uuid
: UUID v4 format - e.g.,uuid
Examples
yaml
generators:
- type: "random"
targetPath: "service.port"
format: "int:8000:9000"
- type: "random"
targetPath: "session.id"
format: "string:32"
- type: "random"
targetPath: "request.uuid"
format: "uuid"
id
Generator
The id
generator creates various types of identifiers using alphanumeric characters.
Structure
yaml
generators:
- type: "id"
targetPath: "path.to.id"
format: "simple:8" # Optional, defaults to "simple:8"
Fields
type
(Required): Must be"id"
targetPath
(Required): Dot-separated path where the ID will be placedformat
(Optional): ID format specification (defaults to "simple:8")
Supported Formats
simple:length
: Random ID using [a-zA-Z0-9] - e.g.,simple:12
prefix:prefix:length
: ID with prefix + random chars - e.g.,prefix:user_:8
numeric:length
: Numeric ID using [0-9] - e.g.,numeric:6
alpha:length
: Alphabetic ID using [a-zA-Z] - e.g.,alpha:10
sequential
: Sequential counter-based ID (starts from 1)timestamp
: Timestamp + random suffix - e.g.,1640995200abcd
Examples
yaml
generators:
- type: "id"
targetPath: "user.id"
format: "prefix:usr_:8" # Results in: usr_A9Kx2mP1
- type: "id"
targetPath: "session.counter"
format: "sequential" # Results in: 1, 2, 3, ...
- type: "id"
targetPath: "trace.id"
format: "timestamp" # Results in: 1640995200A9Kx
Examples from Tests
Basic Generation
Input Configuration:
yaml
service:
name: "data-processor"
instanceId: "instance-007"
port: 8080
region: "us-west-2"
Schema:
yaml
vars:
- name: "APP_VERSION"
value: "1.2.3"
generators:
- type: "concat"
targetPath: "service.identifier"
format: "Service: {name} (ID: {id}) running in {region}"
sources:
name: "service.name"
id: "service.instanceId"
region: "region"
Result:
yaml
service:
identifier: "Service: data-processor (ID: instance-007) running in us-west-2"
# ... other fields preserved
Multiple Generators with Variables
Schema:
yaml
vars:
- name: "APP_VERSION"
value: "1.2.3"
- name: "DOMAIN"
value: "example.com"
generators:
- type: "concat"
targetPath: "service.url"
format: "https://{service}.${DOMAIN}:{port}"
sources:
service: "service.name"
port: "service.port"
- type: "concat"
targetPath: "database.connectionString"
format: "postgresql://{host}:{port}/{db}"
sources:
host: "database.host"
port: "database.port"
db: "database.name"
- type: "concat"
targetPath: "service.fullIdentifier"
format: "{name}-{version} - ${APP_VERSION} ({env})"
sources:
name: "service.name"
version: "service.version"
env: "environment"
Result:
yaml
service:
url: "https://data-processor.example.com:8080"
fullIdentifier: "data-processor-1.2.3 - 1.2.3 (production)"
database:
connectionString: "postgresql://db-server:5432/app_db"
Variables-Only Generation
Generators can use only variables without configuration sources:
Schema:
yaml
vars:
- name: "APP_VERSION"
value: "1.2.3"
- name: "DOMAIN"
value: "example.com"
generators:
- type: "concat"
targetPath: "metadata.buildInfo"
format: "Built version ${APP_VERSION} for ${DOMAIN}"
sources: {} # No configuration sources needed
Error Handling
Common errors and their solutions:
Missing Source Path
yaml
# ERROR: 'service.missing' not found in configuration
sources:
name: "service.missing" # This path doesn't exist
Empty Format
yaml
# ERROR: format cannot be empty
format: ""
No Sources When Needed
yaml
# ERROR: Missing sources for placeholder {name}
format: "Service: {name}"
sources: {} # Missing required source mapping
Advanced Patterns
Cascading Generation
Generators can reference previously generated values:
yaml
generators:
- type: "concat"
targetPath: "temp.namespace"
format: "{app}-{env}"
sources:
app: "metadata.appName"
env: "environment"
- type: "concat"
targetPath: "kubernetes.namespace"
format: "k8s-{namespace}"
sources:
namespace: "temp.namespace" # Reference previous generation
Deep Path Creation
Generators automatically create nested paths:
yaml
generators:
- type: "concat"
targetPath: "deeply.nested.generated.value"
format: "Generated at {path}"
sources:
path: "metadata.location"
Creates the entire path structure if it doesn't exist.
Best Practices
- Clear Naming: Use descriptive placeholder names in
sources
- Path Validation: Ensure source paths exist in your configuration
- Variable Order: Define variables before generators that use them
- Avoid Conflicts: Don't overwrite critical configuration paths
- Test Generation: Verify generated values match expectations
sources
(Required, map): A map where:- Keys are the
placeholder_name
strings used in theformat
string (without the curly braces). - Values are dot-separated paths to existing values within the current state of the configuration (after merges, but typically before most other schema processing for the current generator pass).
- Keys are the
How it Works:
- For each
placeholder
defined insources
: a. Konfigo retrieves the value from the configuration at the specifiedpath
. b. If a source path is not found, Konfigo will return an error. - The
format
string is processed: a. Each{placeholder_name}
is replaced with the corresponding value retrieved fromsources
. - The resulting string (after
sources
substitution) is then processed for standard Konfigo variable substitution (e.g.,${MY_VARIABLE}
). - The final, fully resolved string is set at the
targetPath
in the configuration.
Example:
Schema (schema.yml
):
yaml
vars:
- name: "APP_VERSION"
value: "1.2.3"
config: # Assume this is the state of the config before this generator runs
service:
name: "data-processor"
instanceId: "instance-007"
region: "us-west-2"
generators:
- type: "concat"
targetPath: "service.identifier"
format: "Service: {name} (ID: {id}) running in {region_val} - Version: ${APP_VERSION}"
sources:
name: "service.name"
id: "service.instanceId"
region_val: "region"
- type: "concat"
targetPath: "service.url"
format: "https://${FQDN_VAR}" # Using only a global variable
sources: {} # No local sources needed if format string only uses global vars
Variables (e.g., from -V vars.yml
or environment):
yaml
# vars.yml
FQDN_VAR: "myapp.example.com"
Processing Steps:
First Generator (
service.identifier
):sources
:name
->service.name
-> "data-processor"id
->service.instanceId
-> "instance-007"region_val
->region
-> "us-west-2"
format
aftersources
substitution:"Service: data-processor (ID: instance-007) running in us-west-2 - Version: ${APP_VERSION}"
format
after${APP_VERSION}
substitution:"Service: data-processor (ID: instance-007) running in us-west-2 - Version: 1.2.3"
config.service.identifier
becomes"Service: data-processor (ID: instance-007) running in us-west-2 - Version: 1.2.3"
Second Generator (
service.url
):sources
: (empty)format
aftersources
substitution (no change):"https://${FQDN_VAR}"
format
after${FQDN_VAR}
substitution:"https://myapp.example.com"
config.service.url
becomes"https://myapp.example.com"
Resulting Configuration (snippet):
yaml
service:
name: "data-processor"
instanceId: "instance-007"
identifier: "Service: data-processor (ID: instance-007) running in us-west-2 - Version: 1.2.3"
url: "https://myapp.example.com"
region: "us-west-2"
# ... other config ...
Generators are applied in the order they are defined in the generators
list. The output of one generator can potentially be used as a source for a subsequent generator if its targetPath
is referenced in the later generator's sources
.