Add support for configuration extensions

Allow blocks prefixed with `x-` in the configuration as a place to
declare reusable blocks with YAML anchors and aliases.

Borrowed from the Docker Compose configuration file format -
https://github.com/compose-spec/compose-spec/blob/main/spec.md#extension

Thanks to @ruyrocha for the suggestion.
This commit is contained in:
Donal McBreen
2024-07-15 14:56:30 +01:00
parent fa73d722ea
commit 29c723f7ec
6 changed files with 67 additions and 5 deletions

View File

@@ -47,7 +47,7 @@ class Kamal::Configuration
@destination = destination
@declared_version = version
validate! raw_config, example: validation_yml.symbolize_keys, context: ""
validate! raw_config, example: validation_yml.symbolize_keys, context: "", with: Kamal::Configuration::Validator::Configuration
# Eager load config to validate it, these are first as they have dependencies later on
@servers = Servers.new(config: self)

View File

@@ -2,13 +2,24 @@
#
# Configuration is read from the `config/deploy.yml`
#
# Destinations
#
# When running commands, you can specify a destination with the `-d` flag,
# e.g. `kamal deploy -d staging`
#
# In this case the configuration will also be read from `config/deploy.staging.yml`
# and merged with the base configuration.
# Extensions
#
# The available configuration options are explained below.
# Kamal will not accept unrecognized keys in the configuration file.
#
# However, you might want to declare a configuration block using YAML anchors
# and aliases to avoid repetition.
#
# You can use prefix a configuration section with `x-` to indicate that it is an
# extension. Kamal will ignore the extension and not raise an error.
# The service name
# This is a required value. It is used as the container name prefix.

View File

@@ -15,11 +15,10 @@ class Kamal::Configuration::Validator
def validate_against_example!(validation_config, example)
validate_type! validation_config, Hash
if (unknown_keys = validation_config.keys - example.keys).any?
unknown_keys_error unknown_keys
end
check_unknown_keys! validation_config, example
validation_config.each do |key, value|
next if extension?(key)
with_context(key) do
example_value = example[key]
@@ -137,4 +136,18 @@ class Kamal::Configuration::Validator
ensure
@context = old_context
end
def allow_extensions?
false
end
def extension?(key)
key.to_s.start_with?("x-")
end
def check_unknown_keys!(config, example)
unknown_keys = config.keys - example.keys
unknown_keys.reject! { |key| extension?(key) } if allow_extensions?
unknown_keys_error unknown_keys if unknown_keys.present?
end
end

View File

@@ -0,0 +1,6 @@
class Kamal::Configuration::Validator::Configuration < Kamal::Configuration::Validator
private
def allow_extensions?
true
end
end