cf_deployer 1.6.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +29 -0
  3. data/.github/workflows/publish.yml +40 -0
  4. data/.rspec +4 -0
  5. data/ChangeLog.md +7 -0
  6. data/QUICKSTART.md +1 -1
  7. data/Rakefile +1 -1
  8. data/cf_deployer.gemspec +16 -10
  9. data/fixtures/vcr_cassettes/aws_call_count/driver/auto_scaling_group/healthy_instance_count.yml +2 -2
  10. data/lib/cf_deployer/cli.rb +1 -1
  11. data/lib/cf_deployer/config_loader.rb +2 -2
  12. data/lib/cf_deployer/config_validation.rb +1 -1
  13. data/lib/cf_deployer/driver/auto_scaling_group.rb +22 -26
  14. data/lib/cf_deployer/driver/cloud_formation_driver.rb +28 -18
  15. data/lib/cf_deployer/driver/elb_driver.rb +11 -4
  16. data/lib/cf_deployer/driver/instance.rb +4 -3
  17. data/lib/cf_deployer/driver/route53_driver.rb +17 -9
  18. data/lib/cf_deployer/logger.rb +10 -11
  19. data/lib/cf_deployer/stack.rb +18 -30
  20. data/lib/cf_deployer/status_presenter.rb +1 -1
  21. data/lib/cf_deployer/version.rb +1 -1
  22. data/lib/cf_deployer.rb +10 -7
  23. data/spec/aws_call_count_spec_helper.rb +14 -2
  24. data/spec/fakes/instance.rb +5 -4
  25. data/spec/fakes/route53_client.rb +4 -7
  26. data/spec/spec_helper.rb +11 -2
  27. data/spec/unit/application_spec.rb +9 -9
  28. data/spec/unit/component_spec.rb +3 -3
  29. data/spec/unit/config_loader_spec.rb +70 -69
  30. data/spec/unit/deployment_strategy/auto_scaling_group_swap_spec.rb +10 -10
  31. data/spec/unit/deployment_strategy/base_spec.rb +17 -18
  32. data/spec/unit/deployment_strategy/cname_swap_spec.rb +9 -9
  33. data/spec/unit/deployment_strategy/create_or_update_spec.rb +8 -8
  34. data/spec/unit/driver/auto_scaling_group_spec.rb +75 -65
  35. data/spec/unit/driver/aws_sdk_v3_spec.rb +163 -0
  36. data/spec/unit/driver/cloud_formation_spec.rb +19 -17
  37. data/spec/unit/driver/dry_run_spec.rb +8 -8
  38. data/spec/unit/driver/elb_spec.rb +10 -4
  39. data/spec/unit/driver/instance_spec.rb +1 -7
  40. data/spec/unit/driver/route53_spec.rb +34 -25
  41. data/spec/unit/hook_spec.rb +3 -3
  42. data/spec/unit/stack_spec.rb +22 -21
  43. metadata +134 -56
  44. data/.travis.yml +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b15fbdcf8f040017be2e4f7fd2fca49e99327164
4
- data.tar.gz: 6138254475f90d7983da1823754ace6134be9d85
2
+ SHA256:
3
+ metadata.gz: e1556ed67ab725b4ff0aea77a7c5ded196cc314f1654dd7724d2fe3f501604ef
4
+ data.tar.gz: 5e343a49b896d720227e69dbe85c6702456dfc0a95ce8d83b5b7c5b3686d4183
5
5
  SHA512:
6
- metadata.gz: 209ff6fd2211ae9b37ef0592aaec30066139ee37742cc36bdb45593ad0bc8f4476393ccc76be3d04204b9021bef07621b703bdd09b65b85580f18827ff5ceb9a
7
- data.tar.gz: 9d3a7676274ac56d77ef0d545f1dc2441bf9a84ce07bf50cae1aec809df349ff8a5f23202bfdabedf8064d08383ac191d879606c9a80b3586e91792f2819f91b
6
+ metadata.gz: 4048ce2d730fe916f6b895950af91023be72e7bae0bfbfbcb536fd86e20f5c78801575cb681d212ca9df8749bc595dadd1fcec56abb67576b047e555c8e18c8c
7
+ data.tar.gz: 7ef7a7ed4210aa1c46d57a0a1add255d84b8f921b798aedb58381dc3420476f670d5dea115d000ffc32d72ef0f4a8477a0757ffa9d7021b87f2cf0539a8d6409
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ${{ vars.GHA_ENTERPRISE_LABELS || 'cai-standard-x86-linux' }}
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ ruby-version: ['3.3', '3.4', '4.0']
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - name: Setup Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby-version }}
26
+ bundler-cache: true
27
+
28
+ - name: Run tests
29
+ run: bundle exec rake
@@ -0,0 +1,40 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ${{ vars.GHA_ENTERPRISE_LABELS || 'cai-standard-x86-linux' }}
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Setup Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: '3.3'
21
+ bundler-cache: true
22
+
23
+ - name: Run tests
24
+ run: bundle exec rake
25
+
26
+ - name: Verify tag matches gem version
27
+ run: |
28
+ version=$(ruby -r ./lib/cf_deployer/version -e 'puts CfDeployer::VERSION')
29
+ if [ "${GITHUB_REF_NAME}" != "v${version}" ]; then
30
+ echo "Tag ${GITHUB_REF_NAME} does not match CfDeployer::VERSION v${version}"
31
+ exit 1
32
+ fi
33
+
34
+ - name: Build gem
35
+ run: gem build cf_deployer.gemspec
36
+
37
+ - name: Push gem to RubyGems
38
+ env:
39
+ GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
40
+ run: gem push cf_deployer-*.gem
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --require spec_helper
3
+ --format d
4
+ --order defined
data/ChangeLog.md CHANGED
@@ -63,3 +63,10 @@ version 1.6.0
63
63
  - Automatically rollback on failures for AutoScalingGroup based deployments (See: https://github.com/manheim/cf_deployer/issues/39)
64
64
  - Improve error message when no stack is exists on ASG-based switch (See: https://github.com/manheim/cf_deployer/issues/50)
65
65
  - Reduce AWS calls during healthy_instance_count (See: https://github.com/manheim/cf_deployer/issues/48)
66
+
67
+ version 2.0.0
68
+ - Requires Ruby 3.3 or newer
69
+ - Replaced aws-sdk v1 with the modular AWS SDK v3 gems (aws-sdk-autoscaling, aws-sdk-cloudformation, aws-sdk-ec2, aws-sdk-elasticloadbalancing, aws-sdk-route53)
70
+ - Replaced log4r with the standard library Logger (log output format is unchanged)
71
+ - Removed the json runtime dependency (json ships with Ruby)
72
+ - Handle non-existent stacks gracefully
data/QUICKSTART.md CHANGED
@@ -36,7 +36,7 @@ Note that you can use ERB and settings/inputs from the cf_deployer.yml file whil
36
36
  ==================
37
37
  ### Setting up your project to use CFDeployer
38
38
 
39
- * **CFDeployer is a Ruby gem so you'll need a working version of Ruby.** CFDeployer should work with any 1.8.7 or 1.9.X Ruby interpreter. CFDeployer uses the official AWS-published Ruby SDK under the covers which, in turn, uses Nokogiri. We've heard that JRuby projects and Ruby 2.X projects have trouble getting Nokogiri installed so that might be an issue for your if you're using one of those Rubies.
39
+ * **CFDeployer is a Ruby gem so you'll need a working version of Ruby.** CFDeployer requires Ruby 3.3 or newer and uses the official AWS SDK for Ruby (v3) under the covers.
40
40
 
41
41
  * **The use of the [Bundler](http://bundler.io/) gem is strongly encouraged.** Put "gem 'cf_deployer'" into your Gemfile.
42
42
 
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'bundler/gem_tasks'
5
5
  require 'rspec/core/rake_task'
6
6
 
7
7
  namespace :spec do
8
- RSPEC_OPTS = ["--format", "nested", "--format", "html", "--out", "spec_result.html", "--colour"]
8
+ RSPEC_OPTS = ["--format", "documentation", "--format", "html", "--out", "spec_result.html", "--colour"]
9
9
 
10
10
  RSpec::Core::RakeTask.new(:file) do |t|
11
11
  t.rspec_opts = RSPEC_OPTS
data/cf_deployer.gemspec CHANGED
@@ -8,18 +8,24 @@ Gem::Specification.new do |gem|
8
8
  gem.summary = %q{Support multiple components deployment using CloudFormation templates with multiple blue green strategies.}
9
9
  gem.homepage = "http://github.com/manheim/cf_deployer"
10
10
  gem.license = 'MIT'
11
+ gem.required_ruby_version = '>= 3.3'
11
12
 
12
- gem.add_runtime_dependency 'aws-sdk','1.44.0'
13
- gem.add_runtime_dependency 'log4r'
14
- gem.add_runtime_dependency 'thor'
15
- gem.add_runtime_dependency 'rainbow'
13
+ gem.add_runtime_dependency 'aws-sdk-autoscaling', '~> 1.86'
14
+ gem.add_runtime_dependency 'aws-sdk-cloudformation', '~> 1.76'
15
+ gem.add_runtime_dependency 'aws-sdk-core', '~> 3.170'
16
+ gem.add_runtime_dependency 'aws-sdk-ec2', '~> 1.365'
17
+ gem.add_runtime_dependency 'aws-sdk-elasticloadbalancing', '~> 1.42'
18
+ gem.add_runtime_dependency 'aws-sdk-route53', '~> 1.71'
16
19
  gem.add_runtime_dependency 'diffy'
17
- gem.add_development_dependency 'yard', '~> 0.8.7.6'
18
- gem.add_development_dependency 'pry', '~> 0.10.1'
19
- gem.add_development_dependency 'rspec', '2.14.1'
20
- gem.add_development_dependency 'rake', '~> 10.3.0'
21
- gem.add_development_dependency 'webmock', '~> 2.1.0'
22
- gem.add_development_dependency 'vcr', '~> 2.9.3'
20
+ gem.add_runtime_dependency 'logger', '~> 1.6'
21
+ gem.add_runtime_dependency 'rainbow'
22
+ gem.add_runtime_dependency 'thor'
23
+ gem.add_development_dependency 'pry', '~> 0.13'
24
+ gem.add_development_dependency 'rake', '~> 13.0'
25
+ gem.add_development_dependency 'rspec', '~> 3.13'
26
+ gem.add_development_dependency 'vcr', '~> 6.0'
27
+ gem.add_development_dependency 'webmock', '~> 3.11'
28
+ gem.add_development_dependency 'yard', '~> 0.9', '>= 0.9.44'
23
29
 
24
30
  gem.files = `git ls-files`.split($\).reject {|f| f =~ /^samples\// }
25
31
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -45,7 +45,7 @@ http_interactions:
45
45
  \ </member>\n </AutoScalingGroups>\n </DescribeAutoScalingGroupsResult>\n
46
46
  \ <ResponseMetadata>\n <RequestId>12345</RequestId>\n
47
47
  \ </ResponseMetadata>\n</DescribeAutoScalingGroupsResponse>\n"
48
- http_version:
48
+ http_version:
49
49
  recorded_at: Tue, 27 Sep 2016 05:47:40 GMT
50
50
  - request:
51
51
  method: post
@@ -65,7 +65,7 @@ http_interactions:
65
65
  \ </member>\n </AutoScalingInstances>\n </DescribeAutoScalingInstancesResult>\n
66
66
  \ <ResponseMetadata>\n <RequestId>12346</RequestId>\n
67
67
  \ </ResponseMetadata>\n</DescribeAutoScalingInstancesResponse>\n"
68
- http_version:
68
+ http_version:
69
69
  recorded_at: Tue, 27 Sep 2016 05:47:40 GMT
70
70
  - request:
71
71
  method: post
@@ -94,7 +94,7 @@ module CfDeployer
94
94
  def set_log_level
95
95
  if options[:'log-level'] == 'aws-debug'
96
96
  CfDeployer::Log.level = 'debug'
97
- AWS.config :logger => Logger.new($stdout)
97
+ Aws.config.update(:logger => Logger.new($stdout))
98
98
  else
99
99
  CfDeployer::Log.level = options[:'log-level']
100
100
  end
@@ -3,7 +3,7 @@ module CfDeployer
3
3
 
4
4
  def self.erb_to_json filename, config
5
5
  json_file = File.join(config[:config_dir], "#{filename}.json")
6
- raise ApplicationError.new("#{json_file} is missing") unless File.exists?(json_file)
6
+ raise ApplicationError.new("#{json_file} is missing") unless File.exist?(json_file)
7
7
  CfDeployer::Log.info "ERBing JSON for #{filename}"
8
8
  ERB.new(File.read(json_file)).result(binding)
9
9
  rescue RuntimeError,TypeError,NoMethodError => e
@@ -39,7 +39,7 @@ module CfDeployer
39
39
 
40
40
  def load_yaml(text)
41
41
  YAML.load text
42
- rescue Psych::SyntaxError => e
42
+ rescue ::Psych::SyntaxError => e
43
43
  error_document text
44
44
  raise e
45
45
  rescue
@@ -79,7 +79,7 @@ module CfDeployer
79
79
  file_name = component[hook_name][:file]
80
80
  return unless file_name
81
81
  path = File.join(component[:config_dir], file_name)
82
- @errors << "File '#{path}' does not exist, which is required by hook '#{hook_name}'" unless File.exists?(path)
82
+ @errors << "File '#{path}' does not exist, which is required by hook '#{hook_name}'" unless File.exist?(path)
83
83
  end
84
84
 
85
85
  def check_environments
@@ -3,7 +3,7 @@ module CfDeployer
3
3
  class AutoScalingGroup
4
4
  extend Forwardable
5
5
 
6
- def_delegators :aws_group, :auto_scaling_instances, :ec2_instances, :load_balancers, :desired_capacity
6
+ def_delegators :aws_group, :instances, :desired_capacity, :load_balancer_names
7
7
 
8
8
  attr_reader :group_name, :group
9
9
 
@@ -22,7 +22,7 @@ module CfDeployer
22
22
  Log.info "warming up auto scaling group #{group_name} to #{desired}"
23
23
 
24
24
  CfDeployer::Driver::DryRun.guard "Skipping ASG warmup" do
25
- aws_group.set_desired_capacity desired
25
+ aws_group.set_desired_capacity({desired_capacity: desired})
26
26
  wait_for_desired_capacity
27
27
  end
28
28
  end
@@ -38,14 +38,14 @@ module CfDeployer
38
38
  Log.info "Cooling down #{group_name}"
39
39
  CfDeployer::Driver::DryRun.guard "Skipping ASG cooldown" do
40
40
  aws_group.update :min_size => 0, :max_size => 0
41
- aws_group.set_desired_capacity 0
41
+ aws_group.set_desired_capacity({desired_capacity: 0})
42
42
  end
43
43
  end
44
44
 
45
45
  def instance_statuses
46
46
  instance_info = {}
47
- ec2_instances.each do |instance|
48
- instance_info[instance.id] = CfDeployer::Driver::Instance.new(instance).status
47
+ instances.each do |instance|
48
+ instance_info[instance.id] = CfDeployer::Driver::Instance.new(instance.id).status
49
49
  end
50
50
  instance_info
51
51
  end
@@ -59,38 +59,30 @@ module CfDeployer
59
59
  end
60
60
 
61
61
  def desired_capacity_reached?
62
+ aws_group.reload
62
63
  healthy_instance_count >= desired_capacity
63
64
  end
64
65
 
65
66
  def healthy_instance_ids
66
- instances = auto_scaling_instances.select do |instance|
67
+ _instances = instances.select do |instance|
67
68
  'HEALTHY'.casecmp(instance.health_status) == 0
68
69
  end
69
- instances.map(&:id)
70
+ _instances.map(&:id)
70
71
  end
71
72
 
72
73
  def in_service_instance_ids
73
- elbs = load_balancers
74
- return [] if elbs.empty?
75
-
76
- ids = elbs.collect(&:instances)
77
- .collect(&:health)
78
- .to_a
79
- .collect { |elb_healths|
80
- elb_healths.select { |health| health[:state] == 'InService' }
81
- .map { |health| health[:instance].id }
82
- }
83
-
84
- ids.inject(:&)
74
+ elb_names = load_balancer_names
75
+
76
+ return [] if elb_names.empty?
77
+
78
+ elb_driver.in_service_instance_ids elb_names
85
79
  end
86
80
 
87
81
  def healthy_instance_count
88
- AWS.memoize do
89
- instances = healthy_instance_ids
90
- instances &= in_service_instance_ids unless load_balancers.empty?
91
- Log.info "Healthy instance count: #{instances.count}"
92
- instances.count
93
- end
82
+ instances = healthy_instance_ids
83
+ instances &= in_service_instance_ids unless load_balancer_names.empty?
84
+ Log.info "Healthy instance count: #{instances.count}"
85
+ instances.count
94
86
  rescue => e
95
87
  Log.error "Unable to determine healthy instance count due to error: #{e.message}"
96
88
  -1
@@ -99,7 +91,11 @@ module CfDeployer
99
91
  private
100
92
 
101
93
  def aws_group
102
- @my_group ||= AWS::AutoScaling.new.groups[group_name]
94
+ @my_group ||= Aws::AutoScaling::AutoScalingGroup.new(group_name)
95
+ end
96
+
97
+ def elb_driver
98
+ @elb_driver ||= Elb.new
103
99
  end
104
100
  end
105
101
  end
@@ -7,22 +7,22 @@ module CfDeployer
7
7
  end
8
8
 
9
9
  def stack_exists?
10
- aws_stack.exists?
10
+ !aws_stack.nil?
11
11
  end
12
12
 
13
13
  def create_stack template, opts
14
14
  CfDeployer::Driver::DryRun.guard "Skipping create_stack" do
15
- cloud_formation.stacks.create @stack_name, template, opts
15
+ cloud_formation.create_stack(opts.merge(stack_name: @stack_name, template_body: template))
16
16
  end
17
17
  end
18
18
 
19
19
  def update_stack template, opts
20
20
  begin
21
21
  CfDeployer::Driver::DryRun.guard "Skipping update_stack" do
22
- aws_stack.update opts.merge(:template => template)
22
+ cloud_formation.update_stack(opts.merge(stack_name: @stack_name, template_body: template))
23
23
  end
24
24
 
25
- rescue AWS::CloudFormation::Errors::ValidationError => e
25
+ rescue Aws::CloudFormation::Errors::ValidationError => e
26
26
  if e.message =~ /No updates are to be performed/
27
27
  Log.info e.message
28
28
  return false
@@ -35,29 +35,31 @@ module CfDeployer
35
35
  end
36
36
 
37
37
  def stack_status
38
- aws_stack.status.downcase.to_sym
38
+ aws_stack&.stack_status&.downcase&.to_sym
39
39
  end
40
40
 
41
41
  def outputs
42
- aws_stack.outputs.inject({}) do |memo, o|
43
- memo[o.key] = o.value
42
+ existing_stack.outputs.inject({}) do |memo, o|
43
+ memo[o.output_key] = o.output_value
44
44
  memo
45
45
  end
46
46
  end
47
47
 
48
48
  def parameters
49
- aws_stack.parameters
49
+ existing_stack.parameters.each_with_object({}) do |p, memo|
50
+ memo[p.parameter_key] = p.parameter_value
51
+ end
50
52
  end
51
53
 
52
54
  def query_output key
53
- output = aws_stack.outputs.find { |o| o.key == key }
54
- output && output.value
55
+ output = existing_stack.outputs.find { |o| o.output_key == key }
56
+ output && output.output_value
55
57
  end
56
58
 
57
59
  def delete_stack
58
60
  if stack_exists?
59
61
  CfDeployer::Driver::DryRun.guard "Skipping create_stack" do
60
- aws_stack.delete
62
+ cloud_formation.delete_stack(stack_name: @stack_name)
61
63
  end
62
64
  else
63
65
  Log.info "Stack #{@stack_name} does not exist!"
@@ -66,28 +68,36 @@ module CfDeployer
66
68
 
67
69
  def resource_statuses
68
70
  resources = {}
69
- aws_stack.resource_summaries.each do |rs|
70
- resources[rs[:resource_type]] ||= {}
71
- resources[rs[:resource_type]][rs[:physical_resource_id]] = rs[:resource_status]
71
+ cloud_formation.list_stack_resources(stack_name: @stack_name).each do |page|
72
+ page.stack_resource_summaries.each do |rs|
73
+ resources[rs[:resource_type]] ||= {}
74
+ resources[rs[:resource_type]][rs[:physical_resource_id]] = rs[:resource_status]
75
+ end
72
76
  end
73
77
  resources
74
78
  end
75
79
 
76
80
  def template
77
- aws_stack.template
81
+ cloud_formation.get_template(stack_name: @stack_name).template_body
78
82
  end
79
83
 
80
84
  private
81
85
 
82
86
  def cloud_formation
83
- AWS::CloudFormation.new
87
+ @cloud_formation ||= Aws::CloudFormation::Client.new
84
88
  end
85
89
 
86
90
  def aws_stack
87
- cloud_formation.stacks[@stack_name]
91
+ cloud_formation.describe_stacks(stack_name: @stack_name).stacks.first
92
+ rescue Aws::CloudFormation::Errors::ValidationError => e
93
+ raise unless e.message =~ /does not exist/
94
+ nil
88
95
  end
89
96
 
90
- end
97
+ def existing_stack
98
+ aws_stack || raise(Aws::CloudFormation::Errors::ValidationError.new(nil, "Stack with id #{@stack_name} does not exist"))
99
+ end
91
100
 
101
+ end
92
102
  end
93
103
  end
@@ -2,16 +2,23 @@ module CfDeployer
2
2
  module Driver
3
3
  class Elb
4
4
  def find_dns_and_zone_id elb_id
5
- elb = elb_driver.load_balancers[elb_id]
6
- { :canonical_hosted_zone_name_id => elb.canonical_hosted_zone_name_id, :dns_name => elb.dns_name }
5
+ elb = elb_driver.describe_load_balancers({:load_balancer_names => [elb_id]})&.load_balancer_descriptions&.first
6
+ { :canonical_hosted_zone_name_id => elb&.canonical_hosted_zone_name_id, :dns_name => elb&.dns_name }
7
+ end
8
+
9
+ def in_service_instance_ids elb_ids
10
+ elb_ids.collect do |elb_id|
11
+ elb_driver.describe_instance_health({:load_balancer_name => elb_id}).instance_states
12
+ .collect{|instance| instance.state == 'InService' ? instance.instance_id : nil }.compact
13
+ end.inject(:&)
7
14
  end
8
15
 
9
16
  private
10
17
 
11
18
  def elb_driver
12
- AWS::ELB.new
19
+ @elb_driver ||= Aws::ElasticLoadBalancing::Client.new
13
20
  end
14
21
 
15
22
  end
16
23
  end
17
- end
24
+ end
@@ -14,15 +14,16 @@ module CfDeployer
14
14
 
15
15
  def status
16
16
  instance_info = { }
17
- [:status, :public_ip_address, :private_ip_address, :image_id].each do |stat|
17
+ [:public_ip_address, :private_ip_address, :image_id].each do |stat|
18
18
  instance_info[stat] = aws_instance.send(stat)
19
19
  end
20
- instance_info[:key_pair] = aws_instance.key_pair.name
20
+ instance_info[:status] = aws_instance.state.name.tr('-', '_').to_sym
21
+ instance_info[:key_pair] = aws_instance.key_name
21
22
  instance_info
22
23
  end
23
24
 
24
25
  def aws_instance
25
- @instance_obj ||= AWS::EC2.new.instances[@id]
26
+ @instance_obj ||= Aws::EC2::Instance.new(@id)
26
27
  end
27
28
  end
28
29
  end
@@ -2,7 +2,7 @@ module CfDeployer
2
2
  module Driver
3
3
  class Route53
4
4
  def initialize(aws_route53 = nil)
5
- @aws_route53 = aws_route53 || AWS::Route53.new
5
+ @aws_route53 = aws_route53 || Aws::Route53::Client.new
6
6
  end
7
7
 
8
8
  def find_alias_target(hosted_zone_name, target_host_name)
@@ -15,9 +15,8 @@ module CfDeployer
15
15
 
16
16
  def set_alias_target(hosted_zone_name, target_host_name, elb_hosted_zone_id, elb_dnsname)
17
17
  Log.info "set alias target --Hosted Zone: #{hosted_zone_name} --Host Name: #{target_host_name} --ELB DNS Name: #{elb_dnsname} --ELB Zone ID: #{elb_hosted_zone_id}"
18
- hosted_zone_name = trailing_dot(hosted_zone_name)
19
18
  target_host_name = trailing_dot(target_host_name)
20
- hosted_zone = @aws_route53.hosted_zones.find { |z| z.name == hosted_zone_name }
19
+ hosted_zone = get_hosted_zone(hosted_zone_name)
21
20
  raise ApplicationError.new('Target zone not found!') if hosted_zone.nil?
22
21
 
23
22
  change = {
@@ -34,7 +33,7 @@ module CfDeployer
34
33
  }
35
34
 
36
35
  batch = {
37
- hosted_zone_id: hosted_zone.path,
36
+ hosted_zone_id: hosted_zone.id,
38
37
  change_batch: {
39
38
  changes: [change]
40
39
  }
@@ -49,10 +48,15 @@ module CfDeployer
49
48
  hosted_zone = get_hosted_zone(hosted_zone_name)
50
49
  return unless hosted_zone
51
50
  record_set = get_record_set(hosted_zone, target_host_name)
51
+ return unless record_set
52
52
  CfDeployer::Driver::DryRun.guard "Skipping Route53 DNS delete" do
53
- record_set.delete if record_set
53
+ @aws_route53.change_resource_record_sets(
54
+ hosted_zone_id: hosted_zone.id,
55
+ change_batch: { changes: [{ action: 'DELETE', resource_record_set: record_set.to_h }] }
56
+ )
54
57
  end
55
58
  end
59
+
56
60
  private
57
61
 
58
62
  def change_resource_record_sets_with_retry(batch)
@@ -60,7 +64,7 @@ module CfDeployer
60
64
  while attempts < 20
61
65
  begin
62
66
  attempts = attempts + 1
63
- @aws_route53.client.change_resource_record_sets(batch)
67
+ @aws_route53.change_resource_record_sets(batch)
64
68
  return
65
69
  rescue Exception => e
66
70
  Log.info "Failed to update alias target, trying again in 20 seconds."
@@ -72,11 +76,15 @@ module CfDeployer
72
76
  end
73
77
 
74
78
  def get_hosted_zone(zone_name)
75
- @aws_route53.hosted_zones.find { |z| z.name == trailing_dot(zone_name.downcase) }
79
+ zone_name = trailing_dot(zone_name.downcase)
80
+ @aws_route53.list_hosted_zones_by_name(dns_name: zone_name).hosted_zones.find { |z| z.name == zone_name }
76
81
  end
77
-
82
+
78
83
  def get_record_set(hosted_zone, target_host_name)
79
- hosted_zone.resource_record_sets.find { |r| r.name == trailing_dot(target_host_name.downcase) }
84
+ record_name = trailing_dot(target_host_name.downcase)
85
+ @aws_route53.list_resource_record_sets(hosted_zone_id: hosted_zone.id, start_record_name: record_name)
86
+ .resource_record_sets
87
+ .find { |r| r.name == record_name }
80
88
  end
81
89
 
82
90
  def trailing_dot(text)
@@ -1,7 +1,8 @@
1
1
  module CfDeployer
2
2
  class Log
3
- require 'log4r'
4
- include Log4r
3
+ FORMATTER = proc do |severity, time, progname, message|
4
+ "#{time.strftime('%y-%m-%d %H:%M:%S')} [#{severity}] (#{progname}) #{message}\n"
5
+ end
5
6
 
6
7
  def self.debug(message)
7
8
  log.debug message
@@ -16,22 +17,20 @@ module CfDeployer
16
17
  end
17
18
 
18
19
  def self.log
19
- return @log if @log
20
- @log = Logger.new('cf_deployer')
21
- outputter = Outputter.stdout
22
- outputter.formatter = PatternFormatter.new(:pattern => "%d [%l] (%c) %M", :date_pattern => "%y-%m-%d %H:%M:%S")
23
- @log.outputters = outputter
24
- @log.level = Log4r::INFO
25
- @log
20
+ @log ||= ::Logger.new($stdout, progname: 'cf_deployer', level: ::Logger::INFO, formatter: FORMATTER)
21
+ end
22
+
23
+ def self.log=(logger)
24
+ @log = logger
26
25
  end
27
26
 
28
27
  def self.level=(trace_level)
29
28
  trace_level ||= 'info'
30
29
  case trace_level.downcase
31
30
  when 'debug'
32
- log.level = Log4r::DEBUG
31
+ log.level = ::Logger::DEBUG
33
32
  else
34
- log.level = Log4r::INFO
33
+ log.level = ::Logger::INFO
35
34
  end
36
35
  end
37
36
  end