Skip to content

Commit

Permalink
Merge pull request #884 from basecamp/x-config
Browse files Browse the repository at this point in the history
Add support for configuration extensions
  • Loading branch information
djmb authored Jul 16, 2024
2 parents fa73d72 + 29c723f commit 27fede3
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 5 deletions.
2 changes: 1 addition & 1 deletion lib/kamal/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def initialize(raw_config, destination: nil, version: nil, validate: true)
@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)
Expand Down
13 changes: 12 additions & 1 deletion lib/kamal/configuration/docs/configuration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
# 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.
#
# The available configuration options are explained below.
# 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.
Expand Down
19 changes: 16 additions & 3 deletions lib/kamal/configuration/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ def validate!
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]

Expand Down Expand Up @@ -137,4 +136,18 @@ def with_context(context)
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
6 changes: 6 additions & 0 deletions lib/kamal/configuration/validator/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Kamal::Configuration::Validator::Configuration < Kamal::Configuration::Validator
private
def allow_extensions?
true
end
end
8 changes: 8 additions & 0 deletions test/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,12 @@ class ConfigurationTest < ActiveSupport::TestCase

assert_raises(Kamal::ConfigurationError) { Kamal::Configuration.new(@deploy_with_roles.merge(retain_containers: 0)) }
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
24 changes: 24 additions & 0 deletions test/fixtures/deploy_with_extensions.yml
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 27fede3

Please sign in to comment.