elbas 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6d8f971b000e61faf36f0e9ab36c7232ff89221
4
- data.tar.gz: 9cd09cc94338f8113371a7dac1f86961b5c1f3f0
3
+ metadata.gz: 809a76ffd1ba7661372b03f0caf54e1ec35ba980
4
+ data.tar.gz: b3a525b53a4e13406585aa90e073ebeedf3e9111
5
5
  SHA512:
6
- metadata.gz: fc9c23c1a5c7c8d5f0a032c1ca93a7bb0f6f6848cfbf2e851ae8f788961ac9c7746b822356ebdbee957d03dc4c8efd54fb678e6b67fe88bb532a004811f8da2e
7
- data.tar.gz: 72fbceef214a4dc4703ec16d343bae24e37532eed5c130a75bff4b2cb223525552976e2c8f9338e3ce5b6357a2fb66253a3f0f31899bb9b59dd7419faf21d8b5
6
+ metadata.gz: 9da3a2d3d86aa9949492914666bed49165aeccc8c239d287245b8483e851dd2654615ded41ed826c2e1973fbde9273d72a3b564c0de91b27f5c36b7b5f9ec510
7
+ data.tar.gz: 039bf59b076fd2cb3f651afff972582a4136c0906ea2f649ddc717edf5a86694494d30dffb36fe0fdff5a487798243cabba21242d3678b8872047032c4b75404
data/.gitignore CHANGED
@@ -1,9 +1,9 @@
1
1
  *.gem
2
2
  *.rbc
3
+ /Gemfile.lock
3
4
  .bundle
4
5
  .config
5
6
  .yardoc
6
- Gemfile.lock
7
7
  InstalledFiles
8
8
  _yardoc
9
9
  coverage
@@ -11,7 +11,6 @@ doc/
11
11
  lib/bundler/man
12
12
  pkg
13
13
  rdoc
14
- spec/reports
15
14
  test/tmp
16
15
  test/version_tmp
17
16
  tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 2.0.0
5
+ deploy:
6
+ provider: rubygems
7
+ gem:
8
+ release: elbas
9
+ on:
10
+ repo: lserman/capistrano-elbas
11
+ branch: master
12
+ api_key:
13
+ secure: l7oX8UC0qhvbTQioFOaRy6sx3T1+JKr2MxdcEvgqZDg6hx2l2WhnZemmm0FtvjKBWC65Sk/ygT0PmeekTVzQIcK8E6Bz/mtTTbOfD/wxdOzbJfOXGYKy8amCNvPEQ+DLIkMY0hxx23t7YLj/MIu53vKCAOEwKMKMylUZrYizZWk=
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
- require 'rake/testtask'
3
2
 
4
- Rake::TestTask.new do |t|
5
- t.pattern = "test/**/*_test.rb"
6
- end
3
+ require 'rspec/core/rake_task'
4
+ task :default => :spec
5
+ RSpec::Core::RakeTask.new
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Elbas::VERSION
9
9
  spec.authors = ["Logan Serman"]
10
10
  spec.email = ["logan.serman@metova.com"]
11
- spec.summary = 'Capistrano plugin for deploying to AWS ASGroups.'
12
- spec.description = "#{spec.summary}. Deploys to all instances in a group, creates a fresh AMI post-deploy, and attaches the AMI to your ASGroup."
11
+ spec.summary = 'Capistrano plugin for deploying to AWS AutoScale Groups.'
12
+ spec.description = "#{spec.summary} Deploys to all instances in a group, creates a fresh AMI post-deploy, and attaches the AMI to your AutoScale Group."
13
13
  spec.homepage = "http://github.com/metova/elbas"
14
14
  spec.license = "MIT"
15
15
 
@@ -20,11 +20,11 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.6"
22
22
  spec.add_development_dependency "rake"
23
- spec.add_development_dependency "minitest"
24
- spec.add_development_dependency "minitest-reporters"
23
+ spec.add_development_dependency "rspec"
25
24
  spec.add_development_dependency "webmock"
26
25
 
27
26
  spec.add_dependency 'aws-sdk', '~> 1'
28
27
  spec.add_dependency 'capistrano', '> 3.0.0'
28
+ spec.add_dependency 'activesupport', '>= 4.0.0'
29
29
 
30
30
  end
@@ -1,4 +1,16 @@
1
- require "elbas/version"
1
+ require 'aws-sdk'
2
+ require 'active_support/concern'
3
+
4
+ require 'elbas/version'
5
+ require 'elbas/taggable'
6
+ require 'elbas/logger'
7
+ require 'elbas/aws/credentials'
8
+ require 'elbas/aws/autoscaling'
9
+ require 'elbas/aws/ec2'
10
+ require 'elbas/aws_resource'
11
+ require 'elbas/ami'
12
+ require 'elbas/launch_configuration'
13
+
2
14
 
3
15
  module Elbas
4
16
  end
@@ -1,39 +1,40 @@
1
1
  module Elbas
2
- class AMI < AWS
3
- include Capistrano::DSL
2
+ class AMI < AWSResource
3
+ include Taggable
4
4
 
5
5
  def self.create(&block)
6
6
  ami = new
7
7
  ami.cleanup do
8
8
  ami.save
9
+ ami.tag 'Deployed-with' => 'ELBAS'
9
10
  yield ami
10
11
  end
11
12
  end
12
13
 
13
14
  def save
14
- info "Creating EC2 AMI from #{base_ec2_instance.id}"
15
+ info "Creating EC2 AMI from EC2 Instance: #{base_ec2_instance.id}"
15
16
  @aws_counterpart = ec2.images.create \
16
- name: timestamp(name_prefix),
17
+ name: name,
17
18
  instance_id: base_ec2_instance.id,
18
19
  no_reboot: true
19
20
  end
20
21
 
21
22
  def destroy(images = [])
22
23
  images.each do |i|
23
- info "Deleting old image: #{i.id}"
24
+ info "Deleting old AMI: #{i.id}"
24
25
  i.delete
25
26
  end
26
27
  end
27
28
 
28
29
  private
29
30
 
30
- def name_prefix
31
- "elbas-ami-#{environment}"
31
+ def name
32
+ timestamp "#{environment}-AMI"
32
33
  end
33
34
 
34
- def garbage
35
- ec2.images.with_owner('self').to_a.select do |i|
36
- i.name =~ /#{name_prefix}/i
35
+ def trash
36
+ ec2.images.with_owner('self').to_a.select do |ami|
37
+ deployed_with_elbas? ami
37
38
  end
38
39
  end
39
40
 
@@ -0,0 +1,22 @@
1
+ module Elbas
2
+ module AWS
3
+ module AutoScaling
4
+ extend ActiveSupport::Concern
5
+ include Elbas::AWS::Credentials
6
+ include Capistrano::DSL
7
+
8
+ def autoscaling
9
+ @_autoscaling ||= ::AWS::AutoScaling.new(credentials)
10
+ end
11
+
12
+ def autoscale_group
13
+ @_autoscale_group ||= autoscaling.groups[autoscale_group_name]
14
+ end
15
+
16
+ def autoscale_group_name
17
+ fetch(:aws_autoscale_group)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Elbas
2
+ module AWS
3
+ module Credentials
4
+ extend ActiveSupport::Concern
5
+ include Capistrano::DSL
6
+
7
+ def credentials
8
+ @_credentials ||= begin
9
+ _credentials = {
10
+ access_key_id: fetch(:aws_access_key_id, ENV['AWS_ACCESS_KEY_ID']),
11
+ secret_access_key: fetch(:aws_secret_access_key, ENV['AWS_SECRET_ACCESS_KEY'])
12
+ }
13
+
14
+ _credentials.merge! region: fetch(:aws_region) if fetch(:aws_region)
15
+ _credentials
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ module Elbas
2
+ module AWS
3
+ module EC2
4
+ extend ActiveSupport::Concern
5
+ include Elbas::AWS::Credentials
6
+ include Capistrano::DSL
7
+
8
+ def ec2
9
+ @_ec2 ||= ::AWS::EC2.new(credentials)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ module Elbas
2
+ class AWSResource
3
+ include Capistrano::DSL
4
+ include Elbas::AWS::AutoScaling
5
+ include Elbas::AWS::EC2
6
+ include Logger
7
+
8
+ attr_reader :aws_counterpart
9
+
10
+ def cleanup(&block)
11
+ items = trash || []
12
+ yield
13
+ destroy items
14
+ self
15
+ end
16
+
17
+ protected
18
+
19
+ def base_ec2_instance
20
+ @_base_ec2_instance ||= autoscale_group.ec2_instances.filter('instance-state-name', 'running').first
21
+ end
22
+
23
+ def environment
24
+ fetch(:rails_env, 'production')
25
+ end
26
+
27
+ def timestamp(str)
28
+ "#{str}-#{Time.now.to_i}"
29
+ end
30
+
31
+ private
32
+
33
+ def deployed_with_elbas?(resource)
34
+ resource.tags['Deployed-with'] == 'ELBAS'
35
+ end
36
+
37
+ end
38
+ end
@@ -5,11 +5,12 @@ load File.expand_path("../tasks/elbas.rake", __FILE__)
5
5
 
6
6
  def autoscale(groupname, *args)
7
7
  include Capistrano::DSL
8
+ include Elbas::AWS::AutoScaling
8
9
 
9
- asgroup = autoscaling.groups[groupname]
10
+ autoscale_group = autoscaling.groups[groupname]
10
11
  set :aws_autoscale_group, groupname
11
12
 
12
- asgroup.ec2_instances.filter('instance-state-name', 'running').each do |instance|
13
+ autoscale_group.ec2_instances.filter('instance-state-name', 'running').each do |instance|
13
14
  hostname = instance.dns_name || instance.private_ip_address
14
15
  p "ELBAS: Adding server: #{hostname}"
15
16
  server(hostname, *args)
@@ -17,11 +18,3 @@ def autoscale(groupname, *args)
17
18
 
18
19
  after('deploy', 'elbas:scale')
19
20
  end
20
-
21
- private
22
-
23
- def autoscaling
24
- @_autoscaling ||= AWS::AutoScaling.new \
25
- access_key_id: fetch(:aws_access_key_id, ENV['AWS_ACCESS_KEY_ID']),
26
- secret_access_key: fetch(:aws_secret_access_key, ENV['AWS_SECRET_ACCESS_KEY'])
27
- end
@@ -1,5 +1,5 @@
1
1
  module Elbas
2
- class LaunchConfiguration < AWS
2
+ class LaunchConfiguration < AWSResource
3
3
 
4
4
  def self.create(ami, &block)
5
5
  lc = new
@@ -10,13 +10,13 @@ module Elbas
10
10
  end
11
11
 
12
12
  def save(ami)
13
- info "Creating an EC2 Launch Configuration for AMI: #{ami.id}"
14
- @aws_counterpart = autoscaling.launch_configurations.create(timestamp(name_prefix), ami.id, instance_size, create_options)
13
+ info "Creating an EC2 Launch Configuration for AMI: #{ami.aws_counterpart.id}"
14
+ @aws_counterpart = autoscaling.launch_configurations.create(name, ami.aws_counterpart.id, instance_size, create_options)
15
15
  end
16
16
 
17
- def attach_to_asgroup!
17
+ def attach_to_autoscale_group!
18
18
  info "Attaching Launch Configuration to AutoScale Group"
19
- asgroup.update(launch_configuration: aws_counterpart)
19
+ autoscale_group.update(launch_configuration: aws_counterpart)
20
20
  end
21
21
 
22
22
  def destroy(launch_configurations = [])
@@ -28,8 +28,12 @@ module Elbas
28
28
 
29
29
  private
30
30
 
31
- def name_prefix
32
- "elbas-lc-#{environment}"
31
+ def name
32
+ timestamp "ELBAS-#{environment}-LC"
33
+ end
34
+
35
+ def instance_size
36
+ fetch(:aws_autoscale_instance_size, 'm1.small')
33
37
  end
34
38
 
35
39
  def create_options
@@ -39,28 +43,20 @@ module Elbas
39
43
  associate_public_ip_address: true,
40
44
  }
41
45
 
42
- if asgroup_already_had_launch_configuration_attached?
43
- _options.merge user_data: old_launch_configuration.user_data
46
+ if user_data = fetch(:aws_launch_configuration_user_data, nil)
47
+ _options.merge user_data: user_data
44
48
  end
45
49
 
46
50
  _options
47
51
  end
48
52
 
49
- def asgroup_already_had_launch_configuration_attached?
50
- !!old_launch_configuration
51
- end
52
-
53
- def old_launch_configuration
54
- @_old_launch_configuration ||= asgroup.launch_configurations.first
55
- end
56
-
57
- def instance_size
58
- fetch(:aws_autoscale_instance_size, 'm1.small')
53
+ def deployed_with_elbas?(lc)
54
+ lc.name =~ /ELBAS/
59
55
  end
60
56
 
61
- def garbage
57
+ def trash
62
58
  autoscaling.launch_configurations.to_a.select do |lc|
63
- lc.name =~ /#{name_prefix}/i
59
+ deployed_with_elbas? lc
64
60
  end
65
61
  end
66
62
 
@@ -0,0 +1,9 @@
1
+ module Elbas
2
+ module Logger
3
+
4
+ def info(message)
5
+ p "ELBAS: #{message}"
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Elbas
2
+ module Taggable
3
+
4
+ def tag(tags = {})
5
+ tags.each do |k, v|
6
+ aws_counterpart.tags[k] = v
7
+ end
8
+ end
9
+
10
+ end
11
+ end
@@ -1,7 +1,4 @@
1
1
  require 'elbas'
2
- require 'elbas/aws'
3
- require 'elbas/ami'
4
- require 'elbas/launch_configuration'
5
2
 
6
3
  namespace :elbas do
7
4
  task :scale do
@@ -12,8 +9,9 @@ namespace :elbas do
12
9
  p "ELBAS: Created AMI: #{ami.id}"
13
10
  Elbas::LaunchConfiguration.create(ami) do |lc|
14
11
  p "ELBAS: Created Launch Configuration: #{lc.name}"
15
- lc.attach_to_asgroup!
12
+ lc.attach_to_autoscale_group!
16
13
  end
17
14
  end
15
+
18
16
  end
19
17
  end
@@ -1,3 +1,3 @@
1
1
  module Elbas
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.7'
3
3
  end
@@ -0,0 +1,60 @@
1
+ describe 'ELBAS' do
2
+
3
+ before do
4
+ allow_any_instance_of(Elbas::AWSResource).to receive(:autoscale_group_name) { 'production' }
5
+ webmock :get, /security-credentials/ => 'security-credentials.200.json'
6
+ webmock(:post, /ec2.(.*).amazonaws.com\/\z/ => 'DescribeImages.200.xml') { Hash[body: /Action=DescribeImages/] }
7
+ webmock(:post, /ec2.(.*).amazonaws.com\/\z/ => 'DescribeTags.200.xml') { Hash[body: /Action=DescribeTags/] }
8
+ webmock(:post, /ec2.(.*).amazonaws.com\/\z/ => 'DescribeInstances.200.xml') { Hash[body: /Action=DescribeInstances/] }
9
+ webmock(:post, /ec2.(.*).amazonaws.com\/\z/ => 'CreateImage.200.xml') { Hash[body: /Action=CreateImage/] }
10
+ webmock(:post, /ec2.(.*).amazonaws.com\/\z/ => 'DeregisterImage.200.xml') { Hash[body: /Action=DeregisterImage/] }
11
+ webmock(:post, /ec2.(.*).amazonaws.com\/\z/ => 'CreateTags.200.xml') { Hash[body: /Action=CreateTags/] }
12
+ webmock(:post, /autoscaling.(.*).amazonaws.com\/\z/ => 'DescribeLaunchConfigurations.200.xml') { Hash[body: /Action=DescribeLaunchConfigurations/] }
13
+ webmock(:post, /autoscaling.(.*).amazonaws.com\/\z/ => 'CreateLaunchConfiguration.200.xml') { Hash[body: /Action=CreateLaunchConfiguration/] }
14
+ webmock(:post, /autoscaling.(.*).amazonaws.com\/\z/ => 'DeleteLaunchConfiguration.200.xml') { Hash[body: /Action=DeleteLaunchConfiguration/] }
15
+ webmock(:post, /autoscaling.(.*).amazonaws.com\/\z/ => 'UpdateAutoScalingGroup.200.xml') { Hash[body: /Action=UpdateAutoScalingGroup/] }
16
+ end
17
+
18
+ let!(:ami) do
19
+ _ami = nil
20
+ Elbas::AMI.create { |ami| _ami = ami }
21
+ _ami
22
+ end
23
+
24
+ describe 'AMI creation & cleanup' do
25
+ it 'creates a new AMI on Amazon' do
26
+ expect(ami.aws_counterpart.id).to eq 'ami-4fa54026'
27
+ end
28
+
29
+ it 'deletes any AMIs tagged with Deployed-with=ELBAS' do
30
+ expect(WebMock).to have_requested(:post, /ec2.(.*).amazonaws.com\/\z/).with(body: /Action=DeregisterImage&ImageId=ami-1a2b3c4d/)
31
+ end
32
+
33
+ it 'tags the new AMI with Deployed-with=ELBAS' do
34
+ expect(WebMock).to have_requested(:post, /ec2.(.*).amazonaws.com\/\z/).with(body: /Action=CreateTags&ResourceId.1=ami-4fa54026&Tag.1.Key=Deployed-with&Tag.1.Value=ELBAS/)
35
+ end
36
+ end
37
+
38
+ describe 'Launch configuration creation & cleanup' do
39
+ let!(:launch_configuration) do
40
+ _lc = nil
41
+ Elbas::LaunchConfiguration.create(ami) { |lc| _lc = lc }
42
+ _lc
43
+ end
44
+
45
+ it 'creates a new Launch Configuration on AWS' do
46
+ expect(WebMock).to have_requested(:post, /autoscaling.(.*).amazonaws.com\/\z/).
47
+ with(body: /Action=CreateLaunchConfiguration&AssociatePublicIpAddress=true&ImageId=ami-4fa54026&InstanceMonitoring.Enabled=true&InstanceType=m1.small&LaunchConfigurationName=ELBAS-production/)
48
+ end
49
+
50
+ it 'deletes any LCs with name =~ ELBAS' do
51
+ expect(WebMock).to have_requested(:post, /autoscaling.(.*).amazonaws.com\/\z/).with(body: /Action=DeleteLaunchConfiguration&LaunchConfigurationName=ELBAS-production-LC-1234567890/)
52
+ end
53
+
54
+ it 'attaches the LC to the autoscale group' do
55
+ launch_configuration.attach_to_autoscale_group!
56
+ expect(WebMock).to have_requested(:post, /autoscaling.(.*).amazonaws.com\/\z/).with(body: /Action=UpdateAutoScalingGroup&AutoScalingGroupName=production&LaunchConfigurationName=ELBAS-production-LC-\d{10,}/)
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,32 @@
1
+ require 'webmock'
2
+ require 'capistrano/all'
3
+ require 'elbas'
4
+ require 'webmock/rspec'
5
+
6
+ WebMock.disable_net_connect!
7
+
8
+ Dir[File.join(File.expand_path('../..', __FILE__), 'spec', 'support', '**', '*.rb')].each { |f| require f }
9
+
10
+ module WebMock
11
+ module RSpec
12
+ module Helper
13
+
14
+ def webmock(method, mocks = {})
15
+ mocks.each do |regex, filename|
16
+ status = filename[/\.(\d+)\./, 1] || 200
17
+ body = File.read File.join(File.expand_path('../..', __FILE__), 'spec', 'support', 'stubs', filename)
18
+ if block_given? && with_options = yield
19
+ WebMock.stub_request(method, regex).with(with_options).to_return status: status.to_i, body: body
20
+ else
21
+ WebMock.stub_request(method, regex).to_return status: status.to_i, body: body
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+
30
+ RSpec.configure do |config|
31
+ config.include WebMock::RSpec::Helper
32
+ end
@@ -0,0 +1,4 @@
1
+ <CreateImageResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
2
+ <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
3
+ <imageId>ami-4fa54026</imageId>
4
+ </CreateImageResponse>
@@ -0,0 +1,5 @@
1
+ <CreateLaunchConfigurationResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
2
+ <ResponseMetadata>
3
+ <RequestId>7c6e177f-f082-11e1-ac58-3714bEXAMPLE</RequestId>
4
+ </ResponseMetadata>
5
+ </CreateLaunchConfigurationResponse>
@@ -0,0 +1,5 @@
1
+ <CreateTagsResponse
2
+ xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
3
+ <requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
4
+ <return>true</return>
5
+ </CreateTagsResponse>
@@ -0,0 +1,5 @@
1
+ <DeleteLaunchConfigurationResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
2
+ <ResponseMetadata>
3
+ <RequestId>7347261f-97df-11e2-8756-35eEXAMPLE</RequestId>
4
+ </ResponseMetadata>
5
+ </DeleteLaunchConfigurationResponse>
@@ -0,0 +1,4 @@
1
+ <DeregisterImageResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
2
+ <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
3
+ <return>true</return>
4
+ </DeregisterImageResponse>
@@ -0,0 +1,35 @@
1
+ <DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
2
+ <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
3
+ <imagesSet>
4
+ <item>
5
+ <imageId>ami-1a2b3c4d</imageId>
6
+ <imageLocation>amazon/getting-started</imageLocation>
7
+ <imageState>available</imageState>
8
+ <imageOwnerId>123456789012</imageOwnerId>
9
+ <isPublic>true</isPublic>
10
+ <architecture>i386</architecture>
11
+ <imageType>machine</imageType>
12
+ <kernelId>aki-1a2b3c4d</kernelId>
13
+ <ramdiskId>ari-1a2b3c4d</ramdiskId>
14
+ <imageOwnerAlias>amazon</imageOwnerAlias>
15
+ <name>getting-started</name>
16
+ <description>Image Description</description>
17
+ <rootDeviceType>ebs</rootDeviceType>
18
+ <rootDeviceName>/dev/sda</rootDeviceName>
19
+ <blockDeviceMapping>
20
+ <item>
21
+ <deviceName>/dev/sda1</deviceName>
22
+ <ebs>
23
+ <snapshotId>snap-1a2b3c4d</snapshotId>
24
+ <volumeSize>15</volumeSize>
25
+ <deleteOnTermination>false</deleteOnTermination>
26
+ <volumeType>standard</volumeType>
27
+ </ebs>
28
+ </item>
29
+ </blockDeviceMapping>
30
+ <virtualizationType>paravirtual</virtualizationType>
31
+ <tagSet/>
32
+ <hypervisor>xen</hypervisor>
33
+ </item>
34
+ </imagesSet>
35
+ </DescribeImagesResponse>
@@ -0,0 +1,124 @@
1
+ <DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
2
+ <requestId>fdcdcab1-ae5c-489e-9c33-4637c5dda355</requestId>
3
+ <reservationSet>
4
+ <item>
5
+ <reservationId>r-1a2b3c4d</reservationId>
6
+ <ownerId>123456789012</ownerId>
7
+ <groupSet>
8
+ <item>
9
+ <groupId>sg-1a2b3c4d</groupId>
10
+ <groupName>my-security-group</groupName>
11
+ </item>
12
+ </groupSet>
13
+ <instancesSet>
14
+ <item>
15
+ <instanceId>i-1a2b3c4d</instanceId>
16
+ <imageId>ami-1a2b3c4d</imageId>
17
+ <instanceState>
18
+ <code>16</code>
19
+ <name>running</name>
20
+ </instanceState>
21
+ <privateDnsName/>
22
+ <dnsName/>
23
+ <reason/>
24
+ <keyName>my-key-pair</keyName>
25
+ <amiLaunchIndex>0</amiLaunchIndex>
26
+ <productCodes/>
27
+ <instanceType>c1.medium</instanceType>
28
+ <launchTime>Y2035-02-09T23:17:13Z+0000</launchTime>
29
+ <placement>
30
+ <availabilityZone>us-west-2a</availabilityZone>
31
+ <groupName/>
32
+ <tenancy>default</tenancy>
33
+ </placement>
34
+ <platform>windows</platform>
35
+ <monitoring>
36
+ <state>disabled</state>
37
+ </monitoring>
38
+ <subnetId>subnet-1a2b3c4d</subnetId>
39
+ <vpcId>vpc-1a2b3c4d</vpcId>
40
+ <privateIpAddress>10.0.0.12</privateIpAddress>
41
+ <ipAddress>46.51.219.63</ipAddress>
42
+ <sourceDestCheck>true</sourceDestCheck>
43
+ <groupSet>
44
+ <item>
45
+ <groupId>sg-1a2b3c4d</groupId>
46
+ <groupName>my-security-group</groupName>
47
+ </item>
48
+ </groupSet>
49
+ <architecture>x86_64</architecture>
50
+ <rootDeviceType>ebs</rootDeviceType>
51
+ <rootDeviceName>/dev/sda1</rootDeviceName>
52
+ <blockDeviceMapping>
53
+ <item>
54
+ <deviceName>/dev/sda1</deviceName>
55
+ <ebs>
56
+ <volumeId>vol-1a2b3c4d</volumeId>
57
+ <status>attached</status>
58
+ <attachTime>2035-02-09T23:17:13Z</attachTime>
59
+ <deleteOnTermination>true</deleteOnTermination>
60
+ </ebs>
61
+ </item>
62
+ </blockDeviceMapping>
63
+ <virtualizationType>hvm</virtualizationType>
64
+ <clientToken>ABCDE1234567890123</clientToken>
65
+ <tagSet>
66
+ <item>
67
+ <key>Name</key>
68
+ <value>Windows Instance</value>
69
+ </item>
70
+ </tagSet>
71
+ <hypervisor>xen</hypervisor>
72
+ <networkInterfaceSet>
73
+ <item>
74
+ <networkInterfaceId>eni-1a2b3c4d</networkInterfaceId>
75
+ <subnetId>subnet-1a2b3c4d</subnetId>
76
+ <vpcId>vpc-1a2b3c4d</vpcId>
77
+ <description>Primary network interface</description>
78
+ <ownerId>123456789012</ownerId>
79
+ <status>in-use</status>
80
+ <macAddress>1b:2b:3c:4d:5e:6f</macAddress>
81
+ <privateIpAddress>10.0.0.12</privateIpAddress>
82
+ <sourceDestCheck>true</sourceDestCheck>
83
+ <groupSet>
84
+ <item>
85
+ <groupId>sg-1a2b3c4d</groupId>
86
+ <groupName>my-security-group</groupName>
87
+ </item>
88
+ </groupSet>
89
+ <attachment>
90
+ <attachmentId>eni-attach-1a2b3c4d</attachmentId>
91
+ <deviceIndex>0</deviceIndex>
92
+ <status>attached</status>
93
+ <attachTime>2035-02-09T23:17:13Z</attachTime>
94
+ <deleteOnTermination>true</deleteOnTermination>
95
+ </attachment>
96
+ <association>
97
+ <publicIp>198.51.100.63</publicIp>
98
+ <ipOwnerId>123456789012</ipOwnerId>
99
+ </association>
100
+ <privateIpAddressesSet>
101
+ <item>
102
+ <privateIpAddress>10.0.0.12</privateIpAddress>
103
+ <primary>true</primary>
104
+ <association>
105
+ <publicIp>198.51.100.63</publicIp>
106
+ <ipOwnerId>123456789012</ipOwnerId>
107
+ </association>
108
+ </item>
109
+ <item>
110
+ <privateIpAddress>10.0.0.14</privateIpAddress>
111
+ <primary>false</primary>
112
+ <association>
113
+ <publicIp>198.51.100.177</publicIp>
114
+ <ipOwnerId>123456789012</ipOwnerId>
115
+ </association>
116
+ </item>
117
+ </privateIpAddressesSet>
118
+ </item>
119
+ </networkInterfaceSet>
120
+ </item>
121
+ </instancesSet>
122
+ </item>
123
+ </reservationSet>
124
+ </DescribeInstancesResponse>
@@ -0,0 +1,29 @@
1
+ <DescribeLaunchConfigurationsResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
2
+ <DescribeLaunchConfigurationsResult>
3
+ <LaunchConfigurations>
4
+ <member>
5
+ <AssociatePublicIpAddress>true</AssociatePublicIpAddress>
6
+ <SecurityGroups/>
7
+ <PlacementTenancy>dedicated</PlacementTenancy>
8
+ <CreatedTime>2013-01-21T23:04:42.200Z</CreatedTime>
9
+ <KernelId/>
10
+ <LaunchConfigurationName>ELBAS-production-LC-1234567890</LaunchConfigurationName>
11
+ <UserData/>
12
+ <InstanceType>m1.small</InstanceType>
13
+ <LaunchConfigurationARN>arn:aws:autoscaling:us-east-1:803981987763:launchConfiguration:
14
+ 9dbbbf87-6141-428a-a409-0752edbe6cad:launchConfigurationName/my-test-lc</LaunchConfigurationARN>
15
+ <BlockDeviceMappings/>
16
+ <ImageId>ami-514ac838</ImageId>
17
+ <KeyName/>
18
+ <RamdiskId/>
19
+ <InstanceMonitoring>
20
+ <Enabled>true</Enabled>
21
+ </InstanceMonitoring>
22
+ <EbsOptimized>false</EbsOptimized>
23
+ </member>
24
+ </LaunchConfigurations>
25
+ </DescribeLaunchConfigurationsResult>
26
+ <ResponseMetadata>
27
+ <RequestId>d05a22f8-b690-11e2-bf8e-2113fEXAMPLE</RequestId>
28
+ </ResponseMetadata>
29
+ </DescribeLaunchConfigurationsResponse>
@@ -0,0 +1,11 @@
1
+ <DescribeTagsResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
2
+ <requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
3
+ <tagSet>
4
+ <item>
5
+ <resourceId>ami-1a2b3c4d</resourceId>
6
+ <resourceType>image</resourceType>
7
+ <key>Deployed-with</key>
8
+ <value>ELBAS</value>
9
+ </item>
10
+ </tagSet>
11
+ </DescribeTagsResponse>
@@ -0,0 +1,5 @@
1
+ <UpdateAutoScalingGroupResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
2
+ <ResponseMetadata>
3
+ <RequestId>adafead0-ab8a-11e2-ba13-ab0ccEXAMPLE</RequestId>
4
+ </ResponseMetadata>
5
+ </UpdateAutoScalingGroupResponse>
@@ -0,0 +1,9 @@
1
+ {
2
+ "Code" : "Success",
3
+ "LastUpdated" : "2013-11-22T20:03:48Z",
4
+ "Type" : "AWS-HMAC",
5
+ "AccessKeyId" : "akid",
6
+ "SecretAccessKey" : "secret",
7
+ "Token" : "token",
8
+ "Expiration" : "2035-02-09T21:53:57Z"
9
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elbas
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Logan Serman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-06 00:00:00.000000000 Z
11
+ date: 2015-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,21 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: minitest-reporters
42
+ name: rspec
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - ">="
@@ -108,8 +94,23 @@ dependencies:
108
94
  - - ">"
109
95
  - !ruby/object:Gem::Version
110
96
  version: 3.0.0
111
- description: Capistrano plugin for deploying to AWS ASGroups.. Deploys to all instances
112
- in a group, creates a fresh AMI post-deploy, and attaches the AMI to your ASGroup.
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 4.0.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 4.0.0
111
+ description: Capistrano plugin for deploying to AWS AutoScale Groups. Deploys to all
112
+ instances in a group, creates a fresh AMI post-deploy, and attaches the AMI to your
113
+ AutoScale Group.
113
114
  email:
114
115
  - logan.serman@metova.com
115
116
  executables: []
@@ -117,6 +118,8 @@ extensions: []
117
118
  extra_rdoc_files: []
118
119
  files:
119
120
  - ".gitignore"
121
+ - ".rspec"
122
+ - ".travis.yml"
120
123
  - Gemfile
121
124
  - LICENSE.txt
122
125
  - README.md
@@ -124,14 +127,29 @@ files:
124
127
  - elbas.gemspec
125
128
  - lib/elbas.rb
126
129
  - lib/elbas/ami.rb
127
- - lib/elbas/aws.rb
130
+ - lib/elbas/aws/autoscaling.rb
131
+ - lib/elbas/aws/credentials.rb
132
+ - lib/elbas/aws/ec2.rb
133
+ - lib/elbas/aws_resource.rb
128
134
  - lib/elbas/capistrano.rb
129
135
  - lib/elbas/launch_configuration.rb
136
+ - lib/elbas/logger.rb
137
+ - lib/elbas/taggable.rb
130
138
  - lib/elbas/tasks/elbas.rake
131
139
  - lib/elbas/version.rb
132
- - test/aws/ami_test.rb
133
- - test/stubs.rb
134
- - test/test_helper.rb
140
+ - spec/elbas_spec.rb
141
+ - spec/spec_helper.rb
142
+ - spec/support/stubs/CreateImage.200.xml
143
+ - spec/support/stubs/CreateLaunchConfiguration.200.xml
144
+ - spec/support/stubs/CreateTags.200.xml
145
+ - spec/support/stubs/DeleteLaunchConfiguration.200.xml
146
+ - spec/support/stubs/DeregisterImage.200.xml
147
+ - spec/support/stubs/DescribeImages.200.xml
148
+ - spec/support/stubs/DescribeInstances.200.xml
149
+ - spec/support/stubs/DescribeLaunchConfigurations.200.xml
150
+ - spec/support/stubs/DescribeTags.200.xml
151
+ - spec/support/stubs/UpdateAutoScalingGroup.200.xml
152
+ - spec/support/stubs/security-credentials.200.json
135
153
  homepage: http://github.com/metova/elbas
136
154
  licenses:
137
155
  - MIT
@@ -155,8 +173,18 @@ rubyforge_project:
155
173
  rubygems_version: 2.2.2
156
174
  signing_key:
157
175
  specification_version: 4
158
- summary: Capistrano plugin for deploying to AWS ASGroups.
176
+ summary: Capistrano plugin for deploying to AWS AutoScale Groups.
159
177
  test_files:
160
- - test/aws/ami_test.rb
161
- - test/stubs.rb
162
- - test/test_helper.rb
178
+ - spec/elbas_spec.rb
179
+ - spec/spec_helper.rb
180
+ - spec/support/stubs/CreateImage.200.xml
181
+ - spec/support/stubs/CreateLaunchConfiguration.200.xml
182
+ - spec/support/stubs/CreateTags.200.xml
183
+ - spec/support/stubs/DeleteLaunchConfiguration.200.xml
184
+ - spec/support/stubs/DeregisterImage.200.xml
185
+ - spec/support/stubs/DescribeImages.200.xml
186
+ - spec/support/stubs/DescribeInstances.200.xml
187
+ - spec/support/stubs/DescribeLaunchConfigurations.200.xml
188
+ - spec/support/stubs/DescribeTags.200.xml
189
+ - spec/support/stubs/UpdateAutoScalingGroup.200.xml
190
+ - spec/support/stubs/security-credentials.200.json
@@ -1,62 +0,0 @@
1
- require 'aws-sdk'
2
-
3
- module Elbas
4
- class AWS
5
- include Capistrano::DSL
6
-
7
- attr_reader :aws_counterpart
8
-
9
- def cleanup(&block)
10
- items = garbage || []
11
- yield
12
- destroy items
13
- self
14
- end
15
-
16
- def info(message)
17
- p "ELBAS: #{message}"
18
- end
19
-
20
- def method_missing(_method, *args, &block)
21
- aws_counterpart.send _method, *args
22
- end
23
-
24
- protected
25
-
26
- def autoscaling
27
- @_autoscaling ||= ::AWS::AutoScaling.new(credentials)
28
- end
29
-
30
- def ec2
31
- @_ec2 ||= ::AWS::EC2.new(credentials)
32
- end
33
-
34
- def asgroup
35
- @_asgroup ||= autoscaling.groups[fetch(:aws_autoscale_group)]
36
- end
37
-
38
- def base_ec2_instance
39
- @_base_ec2_instance ||= asgroup.ec2_instances.filter('instance-state-name', 'running').first
40
- end
41
-
42
- def environment
43
- fetch(:rails_env, 'production')
44
- end
45
-
46
- def timestamp(str)
47
- "#{str}-#{Time.now.to_i}"
48
- end
49
-
50
- private
51
-
52
- def credentials
53
- {
54
- access_key_id: fetch(:aws_access_key_id, ENV['AWS_ACCESS_KEY_ID']),
55
- secret_access_key: fetch(:aws_secret_access_key, ENV['AWS_SECRET_ACCESS_KEY']),
56
- }.tap do |_credentials|
57
- _credentials.merge! region: fetch(:aws_region) if fetch(:aws_region)
58
- end
59
- end
60
-
61
- end
62
- end
@@ -1,9 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- class AMITest < Minitest::Test
4
- def test_creates_ec2_instance
5
- Elbas::AMI.create do |ami|
6
- p ami
7
- end
8
- end
9
- end
@@ -1,26 +0,0 @@
1
- def stub(url, method = :get, with = {}, &block)
2
- body = yield
3
- WebMock.stub_request(method, %r[#{url}]).with(with).to_return body: body
4
- end
5
-
6
- stub %r[(.*)/meta-data/iam/security-credentials] do
7
- <<-BODY
8
- {
9
- "Code" : "Success",
10
- "LastUpdated" : "2012-04-26T16:39:16Z",
11
- "Type" : "AWS-HMAC",
12
- "AccessKeyId" : "FAKE_ACCESS_KEY_ID",
13
- "SecretAccessKey" : "FAKE_SECRET_ACCESS_KEY",
14
- "Token" : "token",
15
- "Expiration" : "2012-04-27T22:39:16Z"
16
- }
17
- BODY
18
- end
19
-
20
- stub %r[ec2.us-east-1.amazonaws.com], :post, body: /DescribeImages&Owner.1=self/ do
21
- <<-BODY
22
- {
23
- "ImageId": "ami-5731123e"
24
- }
25
- BODY
26
- end
@@ -1,15 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/reporters'
3
- require 'webmock'
4
-
5
- require 'capistrano/all'
6
-
7
- require 'elbas'
8
- require 'elbas/aws'
9
- require 'elbas/ami'
10
- require 'elbas/launch_configuration'
11
-
12
- Minitest::Reporters.use!
13
-
14
- WebMock.disable_net_connect!
15
- load File.expand_path("../stubs.rb", __FILE__)