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:
@@ -47,7 +47,7 @@ class Kamal::Configuration
|
|||||||
@destination = destination
|
@destination = destination
|
||||||
@declared_version = version
|
@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
|
# Eager load config to validate it, these are first as they have dependencies later on
|
||||||
@servers = Servers.new(config: self)
|
@servers = Servers.new(config: self)
|
||||||
|
|||||||
@@ -2,13 +2,24 @@
|
|||||||
#
|
#
|
||||||
# Configuration is read from the `config/deploy.yml`
|
# Configuration is read from the `config/deploy.yml`
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Destinations
|
||||||
|
#
|
||||||
# When running commands, you can specify a destination with the `-d` flag,
|
# When running commands, you can specify a destination with the `-d` flag,
|
||||||
# e.g. `kamal deploy -d staging`
|
# e.g. `kamal deploy -d staging`
|
||||||
#
|
#
|
||||||
# In this case the configuration will also be read from `config/deploy.staging.yml`
|
# In this case the configuration will also be read from `config/deploy.staging.yml`
|
||||||
# and merged with the base configuration.
|
# 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
|
# The service name
|
||||||
# This is a required value. It is used as the container name prefix.
|
# This is a required value. It is used as the container name prefix.
|
||||||
|
|||||||
@@ -15,11 +15,10 @@ class Kamal::Configuration::Validator
|
|||||||
def validate_against_example!(validation_config, example)
|
def validate_against_example!(validation_config, example)
|
||||||
validate_type! validation_config, Hash
|
validate_type! validation_config, Hash
|
||||||
|
|
||||||
if (unknown_keys = validation_config.keys - example.keys).any?
|
check_unknown_keys! validation_config, example
|
||||||
unknown_keys_error unknown_keys
|
|
||||||
end
|
|
||||||
|
|
||||||
validation_config.each do |key, value|
|
validation_config.each do |key, value|
|
||||||
|
next if extension?(key)
|
||||||
with_context(key) do
|
with_context(key) do
|
||||||
example_value = example[key]
|
example_value = example[key]
|
||||||
|
|
||||||
@@ -137,4 +136,18 @@ class Kamal::Configuration::Validator
|
|||||||
ensure
|
ensure
|
||||||
@context = old_context
|
@context = old_context
|
||||||
end
|
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
|
end
|
||||||
|
|||||||
6
lib/kamal/configuration/validator/configuration.rb
Normal file
6
lib/kamal/configuration/validator/configuration.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class Kamal::Configuration::Validator::Configuration < Kamal::Configuration::Validator
|
||||||
|
private
|
||||||
|
def allow_extensions?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -344,4 +344,12 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
assert_raises(Kamal::ConfigurationError) { Kamal::Configuration.new(@deploy_with_roles.merge(retain_containers: 0)) }
|
assert_raises(Kamal::ConfigurationError) { Kamal::Configuration.new(@deploy_with_roles.merge(retain_containers: 0)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "extensions" do
|
||||||
|
dest_config_file = Pathname.new(File.expand_path("fixtures/deploy_with_extensions.yml", __dir__))
|
||||||
|
|
||||||
|
config = Kamal::Configuration.create_from config_file: dest_config_file
|
||||||
|
assert_equal config.role(:web_tokyo).running_traefik?, true
|
||||||
|
assert_equal config.role(:web_chicago).running_traefik?, true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
24
test/fixtures/deploy_with_extensions.yml
vendored
Normal file
24
test/fixtures/deploy_with_extensions.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
x-web: &web
|
||||||
|
traefik: true
|
||||||
|
|
||||||
|
service: app
|
||||||
|
image: dhh/app
|
||||||
|
servers:
|
||||||
|
web_chicago:
|
||||||
|
<<: *web
|
||||||
|
hosts:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 1.1.1.2
|
||||||
|
web_tokyo:
|
||||||
|
<<: *web
|
||||||
|
hosts:
|
||||||
|
- 1.1.1.3
|
||||||
|
- 1.1.1.4
|
||||||
|
env:
|
||||||
|
REDIS_URL: redis://x/y
|
||||||
|
registry:
|
||||||
|
server: registry.digitalocean.com
|
||||||
|
username: user
|
||||||
|
password: pw
|
||||||
|
primary_role: web_tokyo
|
||||||
Reference in New Issue
Block a user