diff --git a/README.md b/README.md index c47d56c..e83267e 100644 --- a/README.md +++ b/README.md @@ -167,9 +167,29 @@ For more information: $ figaro help heroku:set ``` +#### AWS Elastic Beanstalk + +Elastic Beanstalk makes setting application configuration easy too: + +```bash +$ eb setenv google_analytics_key=UA-35722661-5 +``` + +Using the `figaro` command, you can set values from your configuration file all at once: + +```bash +$ figaro eb:set -e production +``` + +For more information: + +```bash +$ figaro help eb:set +``` + #### Other Hosts -If you're not deploying to Heroku, you have two options: +If you're not deploying to Heroku or Elastic Beanstalk, you have two options: * Generate a remote configuration file * Set `ENV` variables directly diff --git a/lib/figaro/cli.rb b/lib/figaro/cli.rb index a3a5f54..52ba331 100644 --- a/lib/figaro/cli.rb +++ b/lib/figaro/cli.rb @@ -37,5 +37,36 @@ def install require "figaro/cli/heroku_set" HerokuSet.run(options) end + + # figaro eb:set + + desc "eb:set", "Send Figaro configuration to Elastic Beanstalk" + + method_option "eb-env", + desc: "Specify the Elastic Beanstalk environment to target" + method_option "environment", + aliases: ["-e"], + desc: "Specify an application environment" + method_option "path", + aliases: ["-p"], + default: "config/application.yml", + desc: "Specify a configuration file path" + method_option "profile", + desc: "Use a specific profile from your credential file" + method_option "verify-ssl", + type: :boolean, + desc: "Whether to verify AWS SSL certificates", + default: true + + method_option "region", + aliases: ["-r"], + desc: "Use a specific region" + method_option "timeout", + desc: "The number of minutes before the command times out" + + define_method "eb:set" do + require "figaro/cli/eb_set" + EBSet.run(options) + end end end diff --git a/lib/figaro/cli/eb_set.rb b/lib/figaro/cli/eb_set.rb new file mode 100644 index 0000000..3890ec3 --- /dev/null +++ b/lib/figaro/cli/eb_set.rb @@ -0,0 +1,46 @@ +require "figaro/cli/task" + +module Figaro + class CLI < Thor + class EBSet < Task + def run + system(configuration, command) + end + + private + + def command + "eb setenv #{vars} #{for_eb_environment} #{for_profile} #{for_region} " \ + "#{for_timeout} #{for_verify_ssl}" + end + + def for_eb_environment + options[:'eb-env'] ? "--environment=#{options[:'eb-env']}" : nil + end + + def for_profile + options[:profile] ? "--profile=#{options[:profile]}" : nil + end + + def for_region + options[:region] ? "--region=#{options[:region]}" : nil + end + + def for_timeout + options[:timeout] ? "--timeout=#{options[:timeout]}" : nil + end + + def for_verify_ssl + !options[:'verify-ssl'] ? "--no-verify-ssl" : nil + end + + def vars + configuration.keys.map { |k| var(k) }.join(" ") + end + + def var(key) + Gem.win_platform? ? %(#{key}="%#{key}%") : %(#{key}="$#{key}") + end + end + end +end diff --git a/spec/figaro/cli/eb_set_spec.rb b/spec/figaro/cli/eb_set_spec.rb new file mode 100644 index 0000000..7b182e4 --- /dev/null +++ b/spec/figaro/cli/eb_set_spec.rb @@ -0,0 +1,65 @@ +describe "figaro eb:set" do + before do + create_dir("example") + cd("example") + write_file("config/application.yml", "foo: bar") + end + + it "sends Figaro configuration to Elastic Beanstalk" do + run_simple("figaro eb:set") + expect_ran("eb", "setenv", "foo=bar") + end + + it "respects path" do + write_file("env.yml", "foo: bar") + + run_simple("figaro eb:set -p env.yml") + expect_ran("eb", "setenv", "foo=bar") + end + + it "respects environment" do + overwrite_file("config/application.yml", <<-EOF) +foo: bar +test: + foo: baz +EOF + + run_simple("figaro eb:set -e test") + expect_ran("eb", "setenv", "foo=baz") + end + + it "handles values with special characters" do + overwrite_file("config/application.yml", "foo: bar baz") + + run_simple("figaro eb:set") + expect_ran("eb", "setenv", "foo=bar baz") + end + + it "targets a Elastic Beanstalk environment" do + run_simple("figaro eb:set --eb-env=beanstalk-env") + expect_ran("eb", "setenv", "foo=bar", "--environment=beanstalk-env") + end + + it "targets a specific region" do + run_simple("figaro eb:set --region=us-east-1") + expect_ran("eb", "setenv", "foo=bar", "--region=us-east-1") + + run_simple("figaro eb:set -r us-east-1") + expect_ran("eb", "setenv", "foo=bar", "--region=us-east-1") + end + + it "targets a specific profile" do + run_simple("figaro eb:set --profile=awesomecreds") + expect_ran("eb", "setenv", "foo=bar", "--profile=awesomecreds") + end + + it "respects a given timeout" do + run_simple("figaro eb:set --timeout=1") + expect_ran("eb", "setenv", "foo=bar", "--timeout=1") + end + + it "respects a no-verify-ssl" do + run_simple("figaro eb:set --no-verify-ssl") + expect_ran("eb", "setenv", "foo=bar", "--no-verify-ssl") + end +end diff --git a/spec/figaro/cli/heroku_set_spec.rb b/spec/figaro/cli/heroku_set_spec.rb index 839ae97..2b8b2ff 100644 --- a/spec/figaro/cli/heroku_set_spec.rb +++ b/spec/figaro/cli/heroku_set_spec.rb @@ -7,20 +7,14 @@ it "sends Figaro configuration to Heroku" do run_simple("figaro heroku:set") - - command = commands.last - expect(command.name).to eq("heroku") - expect(command.args).to eq(["config:set", "foo=bar"]) + expect_ran("heroku", "config:set", "foo=bar") end it "respects path" do write_file("env.yml", "foo: bar") run_simple("figaro heroku:set -p env.yml") - - command = commands.last - expect(command.name).to eq("heroku") - expect(command.args).to eq(["config:set", "foo=bar"]) + expect_ran("heroku", "config:set", "foo=bar") end it "respects environment" do @@ -31,37 +25,23 @@ EOF run_simple("figaro heroku:set -e test") - - command = commands.last - expect(command.name).to eq("heroku") - expect(command.args).to eq(["config:set", "foo=baz"]) + expect_ran("heroku", "config:set", "foo=baz") end it "targets a specific Heroku app" do run_simple("figaro heroku:set -a foo-bar-app") - - command = commands.last - expect(command.name).to eq("heroku") - expect(command.args.shift).to eq("config:set") - expect(command.args).to match_array(["foo=bar", "--app=foo-bar-app"]) + expect_ran("heroku", "config:set", "foo=bar", "--app=foo-bar-app") end it "targets a specific Heroku git remote" do run_simple("figaro heroku:set --remote production") - - command = commands.last - expect(command.name).to eq("heroku") - expect(command.args.shift).to eq("config:set") - expect(command.args).to match_array(["foo=bar", "--remote=production"]) + expect_ran("heroku", "config:set", "foo=bar", "--remote=production") end it "handles values with special characters" do overwrite_file("config/application.yml", "foo: bar baz") run_simple("figaro heroku:set") - - command = commands.last - expect(command.name).to eq("heroku") - expect(command.args).to eq(["config:set", "foo=bar baz"]) + expect_ran("heroku", "config:set", "foo=bar baz") end end diff --git a/spec/support/bin/eb b/spec/support/bin/eb new file mode 100755 index 0000000..b2674c7 --- /dev/null +++ b/spec/support/bin/eb @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby + +require File.expand_path("../../command_interceptor", __FILE__) + +CommandInterceptor.intercept("eb") diff --git a/spec/support/command_helpers.rb b/spec/support/command_helpers.rb index 57f74f1..5c1e2d4 100644 --- a/spec/support/command_helpers.rb +++ b/spec/support/command_helpers.rb @@ -2,6 +2,13 @@ module CommandHelpers def commands CommandInterceptor.commands end + + def expect_ran(*args) + expected_name, *expected_args = args + command = commands.last + expect(command.name).to eq(expected_name) + expect(command.args).to eq(expected_args) if expected_args.any? + end end RSpec.configure do |config|