automan 2.1.2

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 (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +29 -0
  8. data/Rakefile +6 -0
  9. data/automan.gemspec +30 -0
  10. data/bin/baker +4 -0
  11. data/bin/mover +4 -0
  12. data/bin/scanner +4 -0
  13. data/bin/snapper +4 -0
  14. data/bin/stacker +4 -0
  15. data/bin/stalker +4 -0
  16. data/lib/automan.rb +27 -0
  17. data/lib/automan/base.rb +64 -0
  18. data/lib/automan/beanstalk/application.rb +74 -0
  19. data/lib/automan/beanstalk/configuration.rb +137 -0
  20. data/lib/automan/beanstalk/deployer.rb +193 -0
  21. data/lib/automan/beanstalk/errors.rb +22 -0
  22. data/lib/automan/beanstalk/package.rb +39 -0
  23. data/lib/automan/beanstalk/router.rb +102 -0
  24. data/lib/automan/beanstalk/terminator.rb +60 -0
  25. data/lib/automan/beanstalk/uploader.rb +58 -0
  26. data/lib/automan/beanstalk/version.rb +100 -0
  27. data/lib/automan/chef/uploader.rb +30 -0
  28. data/lib/automan/cli/baker.rb +63 -0
  29. data/lib/automan/cli/base.rb +14 -0
  30. data/lib/automan/cli/mover.rb +47 -0
  31. data/lib/automan/cli/scanner.rb +24 -0
  32. data/lib/automan/cli/snapper.rb +78 -0
  33. data/lib/automan/cli/stacker.rb +106 -0
  34. data/lib/automan/cli/stalker.rb +279 -0
  35. data/lib/automan/cloudformation/errors.rb +40 -0
  36. data/lib/automan/cloudformation/launcher.rb +196 -0
  37. data/lib/automan/cloudformation/replacer.rb +102 -0
  38. data/lib/automan/cloudformation/terminator.rb +61 -0
  39. data/lib/automan/cloudformation/uploader.rb +57 -0
  40. data/lib/automan/ec2/errors.rb +4 -0
  41. data/lib/automan/ec2/image.rb +137 -0
  42. data/lib/automan/ec2/instance.rb +83 -0
  43. data/lib/automan/mixins/aws_caller.rb +115 -0
  44. data/lib/automan/mixins/utils.rb +18 -0
  45. data/lib/automan/rds/errors.rb +7 -0
  46. data/lib/automan/rds/snapshot.rb +244 -0
  47. data/lib/automan/s3/downloader.rb +25 -0
  48. data/lib/automan/s3/uploader.rb +20 -0
  49. data/lib/automan/version.rb +3 -0
  50. data/lib/automan/wait_rescuer.rb +17 -0
  51. data/spec/beanstalk/application_spec.rb +49 -0
  52. data/spec/beanstalk/configuration_spec.rb +98 -0
  53. data/spec/beanstalk/deployer_spec.rb +162 -0
  54. data/spec/beanstalk/package_spec.rb +9 -0
  55. data/spec/beanstalk/router_spec.rb +65 -0
  56. data/spec/beanstalk/terminator_spec.rb +67 -0
  57. data/spec/beanstalk/uploader_spec.rb +53 -0
  58. data/spec/beanstalk/version_spec.rb +60 -0
  59. data/spec/chef/uploader_spec.rb +9 -0
  60. data/spec/cloudformation/launcher_spec.rb +240 -0
  61. data/spec/cloudformation/replacer_spec.rb +58 -0
  62. data/spec/cloudformation/templates/worker_role.json +337 -0
  63. data/spec/cloudformation/terminator_spec.rb +63 -0
  64. data/spec/cloudformation/uploader_spec.rb +50 -0
  65. data/spec/ec2/image_spec.rb +158 -0
  66. data/spec/ec2/instance_spec.rb +57 -0
  67. data/spec/mixins/aws_caller_spec.rb +39 -0
  68. data/spec/mixins/utils_spec.rb +44 -0
  69. data/spec/rds/snapshot_spec.rb +152 -0
  70. metadata +278 -0
@@ -0,0 +1,49 @@
1
+ require "automan"
2
+
3
+ describe Automan::Beanstalk::Application do
4
+ it { should respond_to :name }
5
+ it { should respond_to :create }
6
+ it { should respond_to :delete }
7
+
8
+ describe '#create' do
9
+ subject(:a) do
10
+ AWS.stub!
11
+ a = Automan::Beanstalk::Application.new
12
+ a.logger = Logger.new('/dev/null')
13
+ a
14
+ end
15
+
16
+ it "does not create if the application already exists" do
17
+ a.stub(:application_exists?).and_return(true)
18
+ a.should_not_receive(:create_application)
19
+ a.create
20
+ end
21
+
22
+ it "does create if the application doesn't exist" do
23
+ a.stub(:application_exists?).and_return(false)
24
+ a.should_receive(:create_application)
25
+ a.create
26
+ end
27
+ end
28
+
29
+ describe '#delete' do
30
+ subject(:a) do
31
+ AWS.stub!
32
+ a = Automan::Beanstalk::Application.new
33
+ a.logger = Logger.new('/dev/null')
34
+ a
35
+ end
36
+
37
+ it "does delete if the application already exists" do
38
+ a.stub(:application_exists?).and_return(true)
39
+ a.should_receive(:delete_application)
40
+ a.delete
41
+ end
42
+
43
+ it "does not delete if the application doesn't exist" do
44
+ a.stub(:application_exists?).and_return(false)
45
+ a.should_not_receive(:delete_application)
46
+ a.delete
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,98 @@
1
+ require "automan"
2
+
3
+ describe Automan::Beanstalk::Configuration do
4
+ subject(:c) do
5
+ AWS.stub!
6
+ c = Automan::Beanstalk::Configuration.new
7
+ c.logger = Logger.new('/dev/null')
8
+ c
9
+ end
10
+
11
+ it { should respond_to :name }
12
+ it { should respond_to :application }
13
+ it { should respond_to :template }
14
+ it { should respond_to :platform }
15
+ it { should respond_to :config_template_exists? }
16
+ it { should respond_to :create_config_template }
17
+ it { should respond_to :delete_config_template }
18
+ it { should respond_to :fix_config_keys }
19
+ it { should respond_to :create }
20
+ it { should respond_to :delete }
21
+ it { should respond_to :update }
22
+
23
+ describe '#config_template_exists?' do
24
+
25
+ it 'returns false if raises InvalidParameterValue with missing config template message' do
26
+ c.eb = double(:eb)
27
+ error = AWS::ElasticBeanstalk::Errors::InvalidParameterValue.new('No Configuration Template named')
28
+ c.eb.stub(:describe_configuration_settings).and_raise(error)
29
+ c.config_template_exists?.should be_false
30
+ end
31
+ end
32
+
33
+ describe '#fix_config_keys' do
34
+ it 'snake-cases the keys' do
35
+ config_before = [
36
+ {
37
+ "Namespace" => "aws:elasticbeanstalk:application:environment",
38
+ "OptionName" => "Environment",
39
+ "Value" => "dev1"
40
+ }
41
+ ]
42
+
43
+ config_after = [
44
+ {
45
+ "namespace" => "aws:elasticbeanstalk:application:environment",
46
+ "option_name" => "Environment",
47
+ "value" => "dev1"
48
+ }
49
+ ]
50
+
51
+ c.fix_config_keys(config_before).should eq(config_after)
52
+ end
53
+ end
54
+
55
+ describe '#create' do
56
+ it 'does not create if configuration exists' do
57
+ c.stub(:config_template_exists?).and_return(true)
58
+ c.should_not_receive(:create_config_template)
59
+ c.create
60
+ end
61
+
62
+ it 'does create if configuration does not exist' do
63
+ c.stub(:config_template_exists?).and_return(false)
64
+ c.should_receive(:create_config_template)
65
+ c.create
66
+ end
67
+ end
68
+
69
+ describe '#delete' do
70
+ it 'does delete if configuration exists' do
71
+ c.stub(:config_template_exists?).and_return(true)
72
+ c.should_receive(:delete_config_template)
73
+ c.delete
74
+ end
75
+
76
+ it 'does not delete if configuration does not exist' do
77
+ c.stub(:config_template_exists?).and_return(false)
78
+ c.should_not_receive(:delete_config_template)
79
+ c.delete
80
+ end
81
+ end
82
+
83
+ describe '#update' do
84
+ it 'deletes configuration and recreates it if it exists' do
85
+ c.stub(:config_template_exists?).and_return(true)
86
+ c.should_receive(:delete_config_template)
87
+ c.should_receive(:create_config_template)
88
+ c.update
89
+ end
90
+
91
+ it 'does not try to delete configuration if it does not exist' do
92
+ c.stub(:config_template_exists?).and_return(false)
93
+ c.should_not_receive(:delete_config_template)
94
+ c.should_receive(:create_config_template)
95
+ c.update
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,162 @@
1
+ require "automan"
2
+
3
+ describe Automan::Beanstalk::Deployer do
4
+
5
+ it { should respond_to :name }
6
+ it { should respond_to :version_label }
7
+ it { should respond_to :package }
8
+ it { should respond_to :environment }
9
+ it { should respond_to :manifest }
10
+ it { should respond_to :read_manifest }
11
+ it { should respond_to :manifest_exists? }
12
+ it { should respond_to :package_exists? }
13
+ it { should respond_to :environment_status }
14
+ it { should respond_to :configuration_template }
15
+ it { should respond_to :deploy }
16
+ it { should respond_to :update_environment }
17
+ it { should respond_to :create_environment }
18
+
19
+ # Constraint: Must be from 4 to 23 characters in length.
20
+ # The name can contain only letters, numbers, and hyphens.
21
+ # It cannot start or end with a hyphen.
22
+ describe '#eb_environment_name' do
23
+ subject(:bd) { Automan::Beanstalk::Deployer.new }
24
+
25
+ it "is at least 4 characters" do
26
+ bd.name = "a"
27
+ bd.environment = "a"
28
+ bd.eb_environment_name.length.should be >= 4
29
+ end
30
+
31
+ it "is no more than 23 characters" do
32
+ bd.name = "a" * 23
33
+ bd.environment = "dev"
34
+ bd.eb_environment_name.length.should be <= 23
35
+ end
36
+
37
+ it "contains only letters, numbers, and hyphens" do
38
+ bd.name = '@#$%^foo_bar!$%&&E.'
39
+ bd.environment = 'prod.baz'
40
+ bd.eb_environment_name.should match(/[a-z0-9-]+/)
41
+ end
42
+
43
+ it "cannot start or end with a hyphen" do
44
+ bd.name = '--foo'
45
+ bd.environment = 'bar--'
46
+ bd.eb_environment_name.should match(/^[^-].*[^-]$/)
47
+ end
48
+
49
+ it "is still at least 4 characters even after removing restricted strings" do
50
+ bd.name = '--f'
51
+ bd.environment = '-'
52
+ bd.eb_environment_name.length.should be >= 4
53
+ end
54
+ end
55
+
56
+ describe '#read_manifest' do
57
+ subject(:d) do
58
+ AWS.stub!
59
+ d = Automan::Beanstalk::Deployer.new
60
+ d.logger = Logger.new('/dev/null')
61
+ d
62
+ end
63
+
64
+ it 'raises MissingManifestError if the manifest is missing' do
65
+ d.stub(:manifest_exists?).and_return(false)
66
+ expect {
67
+ d.read_manifest
68
+ }.to raise_error(Automan::Beanstalk::MissingManifestError)
69
+ end
70
+
71
+ it 'sets version_label and package properly' do
72
+ d.stub(:manifest_exists?).and_return(true)
73
+ d.stub(:s3_read).and_return('{"version_label": "foo", "package": "bar"}')
74
+ d.read_manifest
75
+ d.version_label.should eq('foo')
76
+ d.package.should eq('bar')
77
+ end
78
+ end
79
+
80
+ describe '#deploy' do
81
+ subject(:d) do
82
+ AWS.stub!
83
+ d = Automan::Beanstalk::Deployer.new
84
+ d.logger = Logger.new('/dev/null')
85
+ d
86
+ end
87
+
88
+ it 'raises MissingPackageError if the package does not exist' do
89
+ d.stub(:package_exists?).and_return(false)
90
+ expect {
91
+ d.deploy
92
+ }.to raise_error(Automan::Beanstalk::MissingPackageFileError)
93
+ end
94
+
95
+ it 'makes sure the application version and environment exists' do
96
+ d.stub(:package_exists?).and_return(true)
97
+ d.should_receive(:ensure_version_exists)
98
+ d.should_receive(:create_or_update_environment)
99
+ d.deploy
100
+ end
101
+ end
102
+
103
+ describe '#ensure_version_exists' do
104
+ subject(:d) do
105
+ AWS.stub!
106
+ d = Automan::Beanstalk::Deployer.new
107
+ d.logger = Logger.new('/dev/null')
108
+ d
109
+ end
110
+
111
+ it 'creates version if it does not exist' do
112
+ version = double(:version)
113
+ version.stub(:exists?).and_return(false)
114
+ version.should_receive(:create)
115
+ d.stub(:get_version).and_return(version)
116
+ d.ensure_version_exists
117
+ end
118
+
119
+ it 'does not create version if it exists' do
120
+ version = double(:version)
121
+ version.stub(:exists?).and_return(true)
122
+ version.should_not_receive(:create)
123
+ d.stub(:get_version).and_return(version)
124
+ d.ensure_version_exists
125
+ end
126
+ end
127
+
128
+ describe '#create_or_update_environment' do
129
+ subject(:d) do
130
+ AWS.stub!
131
+ d = Automan::Beanstalk::Deployer.new
132
+ d.logger = Logger.new('/dev/null')
133
+ d.stub(:ensure_version_exists)
134
+ d
135
+ end
136
+
137
+ [nil, 'Terminated'].each do |state|
138
+ it "creates environment if state is #{state.nil? ? 'nil' : state}" do
139
+ d.stub(:environment_status).and_return(state)
140
+ d.should_receive(:create_environment)
141
+ d.create_or_update_environment
142
+ end
143
+ end
144
+
145
+ ['Ready'].each do |state|
146
+ it "updates environment if state is #{state.nil? ? 'nil' : state}" do
147
+ d.stub(:environment_status).and_return(state)
148
+ d.should_receive(:update_environment)
149
+ d.create_or_update_environment
150
+ end
151
+ end
152
+
153
+ it 'raises error if environment state is anything else' do
154
+ d.stub(:environment_status).and_return('foo')
155
+ expect {
156
+ d.create_or_update_environment
157
+ }.to raise_error(Automan::Beanstalk::InvalidEnvironmentStatusError)
158
+ end
159
+ end
160
+
161
+ end
162
+
@@ -0,0 +1,9 @@
1
+ require "automan"
2
+
3
+ describe Automan::Beanstalk::Package do
4
+ it { should respond_to :upload_package }
5
+ it { should respond_to :source }
6
+ it { should respond_to :destination }
7
+ it { should respond_to :manifest }
8
+ it { should respond_to :version_label }
9
+ end
@@ -0,0 +1,65 @@
1
+ require 'automan'
2
+ require 'wait'
3
+
4
+ describe Automan::Beanstalk::Router do
5
+ it { should respond_to :run }
6
+ it { should respond_to :environment_name }
7
+ it { should respond_to :hosted_zone_name }
8
+ it { should respond_to :hostname }
9
+
10
+ describe '#run' do
11
+ context 'waiting' do
12
+ subject(:r) do
13
+ AWS.stub!
14
+ r = Automan::Beanstalk::Router.new
15
+ r.eb = AWS::ElasticBeanstalk::Client.new
16
+ r.elb = AWS::ELB.new
17
+ r.environment_name = 'foo'
18
+ r.hosted_zone_name = 'foo.com'
19
+ r.hostname = 'www.foo.com'
20
+ r.log_aws_calls = false
21
+ r.logger = Logger.new('/dev/null')
22
+ r.wait = Wait.new(delay: 0.01, rescuer: WaitRescuer.new(AWS::Route53::Errors::InvalidChangeBatch))
23
+ r
24
+ end
25
+
26
+ it "raises error if it never finds a name" do
27
+ r.stub(:elb_cname_from_beanstalk_environment).and_return(nil)
28
+ expect {
29
+ r.run
30
+ }.to raise_error Wait::ResultInvalid
31
+ end
32
+
33
+ it "calls #update_dns_alias if it finds a name" do
34
+ r.stub(:elb_cname_from_beanstalk_environment).and_return('foo')
35
+ r.should_receive(:update_dns_alias)
36
+ r.run
37
+ end
38
+
39
+ it "ignores InvalidChangeBatch until last attempt" do
40
+ r.stub(:elb_cname_from_beanstalk_environment).and_return('foo')
41
+ r.stub(:update_dns_alias).and_raise AWS::Route53::Errors::InvalidChangeBatch
42
+ expect {
43
+ r.run
44
+ }.to raise_error AWS::Route53::Errors::InvalidChangeBatch
45
+ r.attempts_made.should eq 5
46
+ end
47
+
48
+ it "ignores InvalidChangeBatch until it succeeds" do
49
+ r.stub(:elb_cname_from_beanstalk_environment).and_return('foo')
50
+
51
+ @attempts = 0
52
+ r.stub(:update_dns_alias) do
53
+ @attempts += 1
54
+ raise AWS::Route53::Errors::InvalidChangeBatch if @attempts < 3
55
+ end
56
+
57
+ expect {
58
+ r.run
59
+ }.not_to raise_error
60
+
61
+ r.attempts_made.should eq 3
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,67 @@
1
+ require 'automan'
2
+
3
+ describe Automan::Beanstalk::Terminator do
4
+ it { should respond_to :name }
5
+ it { should respond_to :terminate }
6
+ it { should respond_to :environment_exists? }
7
+
8
+ describe '#environment_exists?' do
9
+ subject(:t) do
10
+ AWS.stub!
11
+ t = Automan::Beanstalk::Terminator.new
12
+ t.logger = Logger.new('/dev/null')
13
+ t
14
+ end
15
+
16
+ it "returns false if environment does not exist" do
17
+ resp = t.eb.stub_for :describe_environments
18
+ resp.data[:environments] = [{}]
19
+ t.environment_exists?('foo').should be_false
20
+ end
21
+
22
+ it "returns false if environment is in Terminated state" do
23
+ resp = t.eb.stub_for :describe_environments
24
+ resp.data[:environments] = [{environment_name: 'foo', status: 'Terminated'}]
25
+ t.environment_exists?('foo').should be_false
26
+ end
27
+
28
+ it "returns false if environment is in Terminating state" do
29
+ resp = t.eb.stub_for :describe_environments
30
+ resp.data[:environments] = [{environment_name: 'foo', status: 'Terminating'}]
31
+ t.environment_exists?('foo').should be_false
32
+ end
33
+
34
+ it "returns true if environment does exist" do
35
+ resp = t.eb.stub_for :describe_environments
36
+ resp.data[:environments] = [{environment_name: 'foo'}]
37
+ t.environment_exists?('foo').should be_true
38
+ end
39
+
40
+ it "returns true if environment is in Ready state" do
41
+ resp = t.eb.stub_for :describe_environments
42
+ resp.data[:environments] = [{environment_name: 'foo', status: 'Ready'}]
43
+ t.environment_exists?('foo').should be_true
44
+ end
45
+ end
46
+
47
+ describe '#terminate' do
48
+ subject(:t) do
49
+ AWS.stub!
50
+ t = Automan::Beanstalk::Terminator.new
51
+ t.logger = Logger.new('/dev/null')
52
+ t
53
+ end
54
+
55
+ it 'should call #terminate_environment if the environment exists' do
56
+ t.stub(:environment_exists?).and_return(true)
57
+ t.should_receive :terminate_environment
58
+ t.terminate
59
+ end
60
+
61
+ it 'should not call #terminate_environment if the environment does not exist' do
62
+ t.stub(:environment_exists?).and_return(false)
63
+ t.should_not_receive :terminate_environment
64
+ t.terminate
65
+ end
66
+ end
67
+ end