From c6ef553ca0070a09cda602183ecd48f8e6b247b4 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Thu, 1 Sep 2016 11:25:56 -0700 Subject: [PATCH 01/13] Minor doc update --- README.md | 6 +++--- docs/02-RESTACKER_YML.md | 6 +++--- source/restacker-sample.yml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2ee9599..87b59f3 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,9 @@ $ cat ~/.restacker/restacker.yml :role_name: ctrl-ctrl-DeployAdmin :role_prefix: "/dso/ctrl/ctrl/" :bucket: - :name: kaos-installers - :prefix: cloudformation - :ami_key: latest_amis + :name: my-bucket + :prefix: "s3/bucket/prefix/" + :ami_key: ami_object_key :ctrlAcct: :region: us-west-2 diff --git a/docs/02-RESTACKER_YML.md b/docs/02-RESTACKER_YML.md index e00c19f..39da3c8 100644 --- a/docs/02-RESTACKER_YML.md +++ b/docs/02-RESTACKER_YML.md @@ -35,9 +35,9 @@ In order for Restacker to work as expected, the following key:value pairs are re :role_name: ctrl-ctrl-DeployAdmin :role_prefix: "/dso/ctrl/ctrl/" :bucket: - :name: kaos-installers - :prefix: cloudformation - :ami_key: latest_amis + :name: my-bucket + :prefix: "s3/bucket/prefix/" + :ami_key: ami_object_key :ctrlAcct: :region: us-west-2 diff --git a/source/restacker-sample.yml b/source/restacker-sample.yml index a02791a..8624b6c 100644 --- a/source/restacker-sample.yml +++ b/source/restacker-sample.yml @@ -7,9 +7,9 @@ :role_name: ctrl-ctrl-DeployAdmin :role_prefix: "/dso/ctrl/ctrl/" :bucket: - :name: kaos-installers - :prefix: cloudformation - :ami_key: latest_amis + :name: my-bucket + :prefix: "s3/bucket/prefix/" + :ami_key: ami_object_key :ctrlAcct: :region: us-west-2 From e641b5bce1d7d5909fa0f0345f00c7dcc11da475 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Thu, 1 Sep 2016 11:31:18 -0700 Subject: [PATCH 02/13] Renamed restacker-sample.yml to restacker-example.yml --- README.md | 2 +- docs/02-RESTACKER_YML.md | 2 +- source/lib/base_stacker.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 87b59f3..f03f208 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Notes: ## Configure it - `restacker configure -l ` -- Or copy the `restacker-sample.yml` to `~/.restacker/restacker.yml` & update the configurations +- Or copy the `restacker-example.yml` to `~/.restacker/restacker.yml` & update the configurations The below configuration is an example of MyApp1 and MyApp2 as target accounts and CTRL as master. ``` diff --git a/docs/02-RESTACKER_YML.md b/docs/02-RESTACKER_YML.md index 39da3c8..4130f39 100644 --- a/docs/02-RESTACKER_YML.md +++ b/docs/02-RESTACKER_YML.md @@ -1,6 +1,6 @@ # RESTACKER.YML This is the configuration file for Restacker CLI. -See the sample [here](../source/restacker-sample.yml). +See the sample [here](../source/restacker-example.yml). ## STRUCTURE In order for Restacker to work as expected, the following key:value pairs are required: diff --git a/source/lib/base_stacker.rb b/source/lib/base_stacker.rb index 144b847..1a68aa7 100644 --- a/source/lib/base_stacker.rb +++ b/source/lib/base_stacker.rb @@ -6,7 +6,7 @@ VERSION = '1.0.0' CONFIG_DIR="#{ENV['HOME']}/.restacker" CONFIG_FILE="#{CONFIG_DIR}/restacker.yml" -SAMPLE_FILE = "#{__dir__}/../restacker-sample.yml" +SAMPLE_FILE = "#{__dir__}/../restacker-example.yml" # needed here (after config_dir and defaults_file) require_relative 'auth' From 47bc700faf6c6eb61d51bcd7192f7f7f8d7061bb Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Thu, 1 Sep 2016 16:02:37 -0700 Subject: [PATCH 03/13] Refactor auth.rb to support non-ctrl plane accounts --- source/lib/auth.rb | 154 ++++++++++++++++++++++++++++++++------------- 1 file changed, 109 insertions(+), 45 deletions(-) diff --git a/source/lib/auth.rb b/source/lib/auth.rb index cb72e6c..1790523 100644 --- a/source/lib/auth.rb +++ b/source/lib/auth.rb @@ -4,69 +4,133 @@ class Auth + # TODO use keychain to save creds + def self.login(options, config, location) + auth_file = "#{CREDS_FILE}.#{location}" + region = default_region(config) + profile_name = options[:profile] + username = options.fetch(:username) + + # if no ctrl plane specified, authenticate directly + return target_plane_auth(region, profile_name) if config[:ctrl].nil? + + if File.exists?(auth_file) + session = YAML.load_file(auth_file) + if valid_session?(region, session) + return cloudformation_client(region, session) + else # if session expired + session = get_auth_session(profile_name, username, config) + return cloudformation_client(region, session) + end + else # if file does not exist + session = get_auth_session(profile_name, username, config) + create_auth_file(auth_file, session) + return cloudformation_client(region, session) + end + + end + + private + def self.get_mfa_code print Rainbow("Enter MFA: ").yellow STDOUT.flush STDIN.gets(7).chomp end - def self.get_creds(username, defaults) - region = defaults.fetch(:region) - ctrl = defaults.fetch(:ctrl) - ctrl_account_number = ctrl.fetch(:account_number) - ctrl_role_prefix = ctrl.fetch(:role_prefix) - ctrl_role_name = ctrl.fetch(:role_name) - - target = defaults.fetch(:target) - target_account_number = target.fetch(:account_number) - target_role_prefix = target.fetch(:role_prefix) - target_role_name = target.fetch(:role_name) - target_label = target.fetch(:label) - serial_number = "arn:aws:iam::#{ctrl_account_number}:mfa/#{username}" - puts "Logging into #{Rainbow(target_label.upcase).yellow} using MFA: #{serial_number} (#{region})" - role_arn = "arn:aws:iam::#{ctrl_account_number}:role#{ctrl_role_prefix}#{ctrl_role_name}" + def self.target_config(config) + target_config = config.fetch(:target) + target = {} + target[:label] = target_config.fetch(:account_number) + target[:account_number] = target_config.fetch(:account_number) + target[:role_prefix] = target_config.fetch(:role_prefix, nil) + target[:role_name] = target_config.fetch(:role_name, nil) + target + end + + def self.ctrl_config(config) + ctrl_config = config.fetch(:ctrl) + ctrl = {} + ctrl[:account_number] = ctrl_config.fetch(:account_number) + ctrl[:role_prefix] = ctrl_config.fetch(:role_prefix) + ctrl[:role_name] = ctrl_config.fetch(:role_name) + ctrl + end + + def self.default_region(config) + config.fetch(:region) + end + + def self.get_creds(username, config) + region = default_region(config) + target = target_config(config) # target account will always exist in restacker.yml + + if config[:ctrl].nil? + target_plane_auth(target) + else + ctrl = ctrl_config(config) + control_plane_auth(ctrl, target, username, region) + end + end + + def self.control_plane_auth(ctrl, target, username, region) + serial_number = "arn:aws:iam::#{ctrl[:account_number]}:mfa/#{username}" + puts "Logging into #{Rainbow(target[:label].upcase).yellow} using MFA: #{serial_number} (#{region})" + role_arn = "arn:aws:iam::#{ctrl[:account_number]}:role#{ctrl[:role_prefix]}#{ctrl[:role_name]}" session_name = username[0..31] sts_client = Aws::STS::Client.new(region: region) - sts_role = sts_client.assume_role(role_arn: role_arn, role_session_name: session_name, serial_number: serial_number, token_code: get_mfa_code) + sts_role = sts_client.assume_role(role_arn: role_arn, + role_session_name: session_name, + serial_number: serial_number, + token_code: get_mfa_code) creds = sts_role[:credentials] - creds_obj = Aws::Credentials.new(creds.access_key_id, creds.secret_access_key, creds.session_token) + creds_obj = Aws::Credentials.new( creds.access_key_id, + creds.secret_access_key, + creds.session_token ) - role_arn = "arn:aws:iam::#{target_account_number}:role#{target_role_prefix}#{target_role_name}" + role_arn = "arn:aws:iam::#{target[:account_number]}:role#{target[:role_prefix]}#{target[:role_name]}" session_name = username[0..31] sts_client = Aws::STS::Client.new(region: region, credentials: creds_obj) - sts_role = sts_client.assume_role(role_arn: role_arn, role_session_name: session_name) + sts_role = sts_client.assume_role(role_arn: role_arn, + role_session_name: session_name) creds = sts_role[:credentials] - Aws::Credentials.new(creds.access_key_id, creds.secret_access_key, creds.session_token) + Aws::Credentials.new( creds.access_key_id, + creds.secret_access_key, + creds.session_token) end - # TODO use keychain to save creds - def self.login(options, defaults, plane) - auth_file = "#{CREDS_FILE}.#{plane}" + def self.target_plane_auth(region, profile_name) + Aws.config[:credentials] = Aws::SharedCredentials.new(profile_name: profile_name) + return Aws::CloudFormation::Client.new(region: region), nil + end + + def self.valid_session?(region, creds) + puts "inside valid_session?" begin - creds = YAML.load(File.read(auth_file)) - cf = Aws::CloudFormation::Client.new(region: defaults[:region], credentials: creds) - cf.list_stacks # testing that creds are still good - rescue => e - begin - profile_name = options[:profile] - Aws.config[:credentials] = Aws::SharedCredentials.new(profile_name: profile_name) - creds = get_creds(options.fetch(:username), defaults) - rescue KeyError => e - error = Rainbow("Error parsing #{CONFIG_FILE}, (#{e.message}), please ensure it is properly formatted").red - raise error - rescue => err - error = Rainbow(err.message).red - raise error - exit - end - # now save to yaml - File.open(auth_file, 'w') do |f| - f.write YAML.dump(creds) - end + Aws::CloudFormation::Client.new(region: region, credentials: creds).list_stacks + puts "valid" + return true + rescue Aws::CloudFormation::Errors::ExpiredToken + puts "invalid" + return false + end + end + + def self.get_auth_session(profile_name, username, config) + Aws.config[:credentials] = Aws::SharedCredentials.new(profile_name: profile_name) + + get_creds(username, config) + end + + def self.cloudformation_client(region, session) + cf = Aws::CloudFormation::Client.new(region: region, credentials: session) + return cf, session + end - cf = Aws::CloudFormation::Client.new(region: defaults[:region], credentials: creds) + def self.create_auth_file(file_name, session) + File.open(auth_file, 'w') do |f| + f.write YAML.dump(creds) end - return cf, creds end end From 9d86401919f0045999ecc12afc3e44f14cb10517 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 13:32:26 -0700 Subject: [PATCH 04/13] Get default user from RestackerConfig if not supplied as flag --- source/bin/restacker | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/bin/restacker b/source/bin/restacker index a9f70cc..4be41b9 100755 --- a/source/bin/restacker +++ b/source/bin/restacker @@ -111,16 +111,16 @@ end options, unparsed = Parser.parse(ARGV) # set the username to $USER if not specified -options[:username] = ENV['USER'] if options[:username].nil? +options[:username] = options[:username] || RestackerConfig.default_user || ENV['USER'] begin action = unparsed.pop puts(VERSION) || exit(0) if options[:version] usage("Please specify an ACTION") && exit(0) if action.nil? - plane = RestackerConfig.get_plane(options) + plane = RestackerConfig.load_config(options) if action == 'configure' - printf "%-30s : %s\n", Rainbow("CONFIGURING PLANE").white.bright.underline, plane + printf "%-s (%s)\n", Rainbow("CONFIGURING PLANE").white.bright.underline, plane RestackerConfig.configure(plane) exit(0) end @@ -129,7 +129,7 @@ begin restacker = Restacker.new(options.to_h) unless ['dump', 'amis'].include?(action) case action when 'list' - printf "%-30s : %s\n", Rainbow("LISTING STACKS").white.bright.underline, plane + printf "%-s (%s)\n", Rainbow("LISTING STACKS").white.bright.underline, plane restacker.list_stacks when 'desc', 'describe' if options[:name] @@ -140,7 +140,7 @@ begin end when 'restack' if options[:name] - printf "%-30s : %s\n", Rainbow("RESTACKING").white.bright.underline, options[:name] + printf "%-s (%s)\n", Rainbow("RESTACKING").white.bright.underline, options[:name] restacker.restack_by_name(options[:name]) puts Rainbow("Now run migrate followed by remove").white.bright else @@ -162,7 +162,7 @@ begin end when 'remove' if options[:name] - printf "%-30s : %s\n", Rainbow("REMOVING STACK").white.bright.underline, options[:name] + printf "%-s (%s)\n", Rainbow("REMOVING STACK").white.bright.underline, options[:name] restacker.delete_stack(options[:name]) else usage "Please specify a stack name (-n) to remove" @@ -182,7 +182,7 @@ begin AwsCli.new(options).cmd(options[:params], options[:debug]) end else - usage "Unknown ACTION: #{action}" + usage Rainbow("Unknown ACTION: #{action}").red end rescue => e puts options[:debug] From e1f91946c8544888ff64c8d6fc7761eaaf04f5ef Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 13:32:45 -0700 Subject: [PATCH 05/13] Fix auth bug --- source/lib/auth.rb | 52 ++++++++++++++-------------------------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/source/lib/auth.rb b/source/lib/auth.rb index 1790523..86995c5 100644 --- a/source/lib/auth.rb +++ b/source/lib/auth.rb @@ -1,4 +1,5 @@ require 'yaml' +require_relative 'restacker_config' CREDS_FILE="#{CONFIG_DIR}/auth" @@ -7,8 +8,8 @@ class Auth # TODO use keychain to save creds def self.login(options, config, location) auth_file = "#{CREDS_FILE}.#{location}" - region = default_region(config) - profile_name = options[:profile] + region = RestackerConfig.default_region + profile_name = options[:profile] || RestackerConfig.default_profile username = options.fetch(:username) # if no ctrl plane specified, authenticate directly @@ -16,10 +17,12 @@ def self.login(options, config, location) if File.exists?(auth_file) session = YAML.load_file(auth_file) - if valid_session?(region, session) + if session && valid_session?(region, session) + create_auth_file(auth_file, session) return cloudformation_client(region, session) else # if session expired session = get_auth_session(profile_name, username, config) + create_auth_file(auth_file, session) return cloudformation_client(region, session) end else # if file does not exist @@ -38,37 +41,14 @@ def self.get_mfa_code STDIN.gets(7).chomp end - def self.target_config(config) - target_config = config.fetch(:target) - target = {} - target[:label] = target_config.fetch(:account_number) - target[:account_number] = target_config.fetch(:account_number) - target[:role_prefix] = target_config.fetch(:role_prefix, nil) - target[:role_name] = target_config.fetch(:role_name, nil) - target - end - - def self.ctrl_config(config) - ctrl_config = config.fetch(:ctrl) - ctrl = {} - ctrl[:account_number] = ctrl_config.fetch(:account_number) - ctrl[:role_prefix] = ctrl_config.fetch(:role_prefix) - ctrl[:role_name] = ctrl_config.fetch(:role_name) - ctrl - end - - def self.default_region(config) - config.fetch(:region) - end - def self.get_creds(username, config) - region = default_region(config) - target = target_config(config) # target account will always exist in restacker.yml + region = RestackerConfig.default_region(config) + target = RestackerConfig.target_config(config) # target account will always exist in restacker.yml if config[:ctrl].nil? target_plane_auth(target) else - ctrl = ctrl_config(config) + ctrl = RestackerConfig.ctrl_config(config) control_plane_auth(ctrl, target, username, region) end end @@ -106,15 +86,15 @@ def self.target_plane_auth(region, profile_name) end def self.valid_session?(region, creds) - puts "inside valid_session?" begin Aws::CloudFormation::Client.new(region: region, credentials: creds).list_stacks - puts "valid" return true - rescue Aws::CloudFormation::Errors::ExpiredToken - puts "invalid" - return false + rescue Aws::CloudFormation::Errors::ExpiredToken => expired + raise expired.message + rescue => e + raise e.message end + return false end def self.get_auth_session(profile_name, username, config) @@ -129,8 +109,8 @@ def self.cloudformation_client(region, session) end def self.create_auth_file(file_name, session) - File.open(auth_file, 'w') do |f| - f.write YAML.dump(creds) + File.open(file_name, 'w') do |f| + f.write YAML.dump(session) end end end From 054e84ade779e1a74fdbb637dc13538769168ed9 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 13:33:36 -0700 Subject: [PATCH 06/13] Abstract methods from auth.rb to restacker_config.rb --- source/lib/restacker_config.rb | 39 +++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/source/lib/restacker_config.rb b/source/lib/restacker_config.rb index 6fe1109..4ba19a8 100644 --- a/source/lib/restacker_config.rb +++ b/source/lib/restacker_config.rb @@ -13,7 +13,7 @@ def self.get_plane(options) if options[:location] plane = options[:location] else - plane = find_default_plane() + plane = default_plane end plane.to_sym end @@ -66,15 +66,44 @@ def self.latest_amis(rhel=nil) latest_amis end - private + def self.target_config(config) + target_config = config.fetch(:target) + target = {} + target[:label] = target_config.fetch(:account_number) + target[:account_number] = target_config.fetch(:account_number) + target[:role_prefix] = target_config.fetch(:role_prefix, nil) + target[:role_name] = target_config.fetch(:role_name, nil) + target + end + + def self.ctrl_config(config) + ctrl_config = config.fetch(:ctrl) + ctrl = {} + ctrl[:account_number] = ctrl_config.fetch(:account_number) + ctrl[:role_prefix] = ctrl_config.fetch(:role_prefix) + ctrl[:role_name] = ctrl_config.fetch(:role_name) + ctrl + end + + def self.default_region + find_config.fetch(:region, nil) + end + + def self.default_profile + find_config.fetch(:profile, nil) + end + + def self.default_user + find_config.fetch(:username, nil) + end + def self.find_config Dir.mkdir(CONFIG_DIR) unless Dir.exist?(CONFIG_DIR) begin if File.exist?(CONFIG_FILE) config = YAML.load_file(CONFIG_FILE) else - config = YAML.load_file(SAMPLE_FILE) - File.open(CONFIG_FILE, 'w') { |f| f.write config.to_yaml } + File.open(CONFIG_FILE, 'w') { |f| f.write SAMPLE_FILE.to_yaml } end rescue Psych::SyntaxError raise "Improperly formatted YAML file: #{CONFIG_FILE}." @@ -84,7 +113,7 @@ def self.find_config config end - def self.find_default_plane + def self.default_plane find_config[:default][:label] || raise(Rainbow("Location was not provided and no default location was found in #{CONFIG_FILE}.").red) end From a4018d9d9814808397fbc6f67854049fbf2c3cb2 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 14:37:30 -0700 Subject: [PATCH 07/13] Find configuration values gracefully --- source/bin/restacker | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/bin/restacker b/source/bin/restacker index 4be41b9..69df8ce 100755 --- a/source/bin/restacker +++ b/source/bin/restacker @@ -111,13 +111,13 @@ end options, unparsed = Parser.parse(ARGV) # set the username to $USER if not specified -options[:username] = options[:username] || RestackerConfig.default_user || ENV['USER'] +options[:username] = RestackerConfig.find_user(options) begin action = unparsed.pop puts(VERSION) || exit(0) if options[:version] usage("Please specify an ACTION") && exit(0) if action.nil? - plane = RestackerConfig.load_config(options) + plane = RestackerConfig.get_plane(options) if action == 'configure' printf "%-s (%s)\n", Rainbow("CONFIGURING PLANE").white.bright.underline, plane From 8d5305cd91d41bf8c1e2267e846be2a14fe98a74 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 14:41:24 -0700 Subject: [PATCH 08/13] Replace get_plane with find_plane --- source/bin/restacker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/bin/restacker b/source/bin/restacker index 69df8ce..376ba78 100755 --- a/source/bin/restacker +++ b/source/bin/restacker @@ -117,7 +117,7 @@ begin action = unparsed.pop puts(VERSION) || exit(0) if options[:version] usage("Please specify an ACTION") && exit(0) if action.nil? - plane = RestackerConfig.get_plane(options) + plane = RestackerConfig.find_plane(options) if action == 'configure' printf "%-s (%s)\n", Rainbow("CONFIGURING PLANE").white.bright.underline, plane From 85b6e042a8934f4b97ffb48a7e012dc9cf4c7cd7 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 14:41:42 -0700 Subject: [PATCH 09/13] Replace get_plane with find_plane --- source/lib/base_stacker.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/lib/base_stacker.rb b/source/lib/base_stacker.rb index 1a68aa7..2cf77b5 100644 --- a/source/lib/base_stacker.rb +++ b/source/lib/base_stacker.rb @@ -27,9 +27,8 @@ class BaseStacker def initialize(options) - location = RestackerConfig.get_plane(options) + location = RestackerConfig.find_plane(options) config = RestackerConfig.load_config(location) - # use default region if not passed in from cli config[:region] = options[:region] if options[:region] options[:region] = config[:region] unless options[:region] From a1410125ccf307fed78a2e37aaab83e3f298f7db Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 14:42:28 -0700 Subject: [PATCH 10/13] Refactor restacker_config --- source/lib/restacker_config.rb | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/source/lib/restacker_config.rb b/source/lib/restacker_config.rb index 4ba19a8..8decb1e 100644 --- a/source/lib/restacker_config.rb +++ b/source/lib/restacker_config.rb @@ -1,6 +1,6 @@ class RestackerConfig def self.load_config(plane) - plane = get_plane if plane.nil? + plane = find_plane if plane.nil? config = find_config if config[plane].nil? puts "Plane not found (#{plane}). Please see #{CONFIG_FILE}." @@ -9,15 +9,6 @@ def self.load_config(plane) config[plane] end - def self.get_plane(options) - if options[:location] - plane = options[:location] - else - plane = default_plane - end - plane.to_sym - end - def self.configure(location) config = find_config() puts Rainbow("Configuration file location:").white.bright + " #{CONFIG_FILE}" @@ -85,16 +76,18 @@ def self.ctrl_config(config) ctrl end - def self.default_region - find_config.fetch(:region, nil) + def self.find_profile(options) + plane = find_plane(options) + options[:profile] || find_config[plane][:profile] || find_config[:default][:profile] end - def self.default_profile - find_config.fetch(:profile, nil) + def self.find_user(options) + plane = find_plane(options) + options[:username] || find_config[plane].fetch(:username, nil) || ENV['USER'] end - def self.default_user - find_config.fetch(:username, nil) + def self.find_plane(options) + (options[:location] || find_config[:default][:label]).to_sym || raise(Rainbow("Location was not provided and no default location was found in #{CONFIG_FILE}.").red) end def self.find_config @@ -113,11 +106,7 @@ def self.find_config config end - def self.default_plane - find_config[:default][:label] || raise(Rainbow("Location was not provided and no default location was found in #{CONFIG_FILE}.").red) - end - - def self.bucket + def self.bucket(options) find_config[:ctrl][:bucket][:name] end From 5803b1dd649af64d4bbfa70414ae75360e3fe1e8 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 14:43:22 -0700 Subject: [PATCH 11/13] Fix auth bug --- source/lib/auth.rb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source/lib/auth.rb b/source/lib/auth.rb index 86995c5..1a8cc83 100644 --- a/source/lib/auth.rb +++ b/source/lib/auth.rb @@ -8,9 +8,9 @@ class Auth # TODO use keychain to save creds def self.login(options, config, location) auth_file = "#{CREDS_FILE}.#{location}" - region = RestackerConfig.default_region - profile_name = options[:profile] || RestackerConfig.default_profile - username = options.fetch(:username) + region = config.fetch(:region) + profile_name = RestackerConfig.find_profile(options) + username = RestackerConfig.find_user(options) # if no ctrl plane specified, authenticate directly return target_plane_auth(region, profile_name) if config[:ctrl].nil? @@ -42,7 +42,7 @@ def self.get_mfa_code end def self.get_creds(username, config) - region = RestackerConfig.default_region(config) + region = config.fetch(:region) target = RestackerConfig.target_config(config) # target account will always exist in restacker.yml if config[:ctrl].nil? @@ -90,11 +90,9 @@ def self.valid_session?(region, creds) Aws::CloudFormation::Client.new(region: region, credentials: creds).list_stacks return true rescue Aws::CloudFormation::Errors::ExpiredToken => expired - raise expired.message - rescue => e - raise e.message + puts expired.message + return false end - return false end def self.get_auth_session(profile_name, username, config) From b6c441771b4fdc37c29ff21c08cf5d8106c0d2a4 Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 15:10:38 -0700 Subject: [PATCH 12/13] Fix bucket bug --- source/lib/restacker_config.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source/lib/restacker_config.rb b/source/lib/restacker_config.rb index 8decb1e..e63b33b 100644 --- a/source/lib/restacker_config.rb +++ b/source/lib/restacker_config.rb @@ -51,10 +51,7 @@ def self.configure(location) def self.latest_amis(rhel=nil) latest_amis = YAML.load(get_object(find_config[:ctrl][:bucket][:ami_key])) - if rhel - return latest_amis[rhel] - end - latest_amis + return latest_amis[rhel] || latest_amis end def self.target_config(config) @@ -106,7 +103,7 @@ def self.find_config config end - def self.bucket(options) + def self.bucket find_config[:ctrl][:bucket][:name] end From ca9d1b836167f0376859d52edee320bc61f1dffa Mon Sep 17 00:00:00 2001 From: Peter Benjamin Date: Fri, 2 Sep 2016 19:11:24 -0700 Subject: [PATCH 13/13] Return cloudformation client and credentials when authenticating directly to target account --- source/lib/auth.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lib/auth.rb b/source/lib/auth.rb index 1a8cc83..f9d6d0b 100644 --- a/source/lib/auth.rb +++ b/source/lib/auth.rb @@ -82,7 +82,7 @@ def self.control_plane_auth(ctrl, target, username, region) def self.target_plane_auth(region, profile_name) Aws.config[:credentials] = Aws::SharedCredentials.new(profile_name: profile_name) - return Aws::CloudFormation::Client.new(region: region), nil + return Aws::CloudFormation::Client.new(region: region), Aws.config[:credentials].credentials end def self.valid_session?(region, creds)