roark 0.0.1 → 0.1.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.
- data/CHANGELOG.md +5 -0
- data/README.md +5 -1
- data/lib/roark/ami.rb +22 -1
- data/lib/roark/ami_create_workflow.rb +11 -6
- data/lib/roark/aws/connection.rb +8 -6
- data/lib/roark/aws/ec2/ami_authorizations.rb +26 -0
- data/lib/roark/aws/ec2.rb +1 -0
- data/lib/roark/cli/create.rb +11 -4
- data/lib/roark/cli/shared.rb +9 -0
- data/lib/roark/version.rb +1 -1
- data/spec/ami_create_workflow_spec.rb +6 -3
- data/spec/ami_spec.rb +17 -2
- data/spec/aws/connection_spec.rb +1 -0
- data/spec/aws/ec2/ami_authorizations_spec.rb +21 -0
- metadata +15 -12
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -6,6 +6,8 @@ Howard Roark, master architect and builder of AMIs.
|
|
6
6
|
|
7
7
|
## Overview
|
8
8
|
|
9
|
+
Roark was built to solve the challenge of automating AMI builds across multiple AWS accounts and regions.
|
10
|
+
|
9
11
|
* Roark builds AMIs from an Instance created by a Cloud Formation Stack.
|
10
12
|
* Roark expects to be provided with a Cloud Formation Template that can be used to create this stack.
|
11
13
|
* This template should create an Instance that is fully configured at bootstrap (via userdata, CloudInit, etc).
|
@@ -41,7 +43,9 @@ Create AMI
|
|
41
43
|
-r AWS_REGION \
|
42
44
|
-t PATH_TO_CLOUD_FORMATION_TEMPLATE \
|
43
45
|
-p 'Parameter1=value1' \
|
44
|
-
-p 'Parameter2=value2'
|
46
|
+
-p 'Parameter2=value2' \
|
47
|
+
-a '123456789012' \
|
48
|
+
-a '123456789013'
|
45
49
|
|
46
50
|
Destroy AMI
|
47
51
|
|
data/lib/roark/ami.rb
CHANGED
@@ -110,6 +110,15 @@ module Roark
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
+
def authorize_account_ids(account_ids)
|
114
|
+
begin
|
115
|
+
authorize account_ids
|
116
|
+
rescue AWS::Errors::Base => e
|
117
|
+
return Response.new :code => 1, :message => e.message
|
118
|
+
end
|
119
|
+
Response.new :code => 0, :message => 'Authorizations completed successfully.'
|
120
|
+
end
|
121
|
+
|
113
122
|
def available?
|
114
123
|
state == :available
|
115
124
|
end
|
@@ -132,14 +141,26 @@ module Roark
|
|
132
141
|
|
133
142
|
private
|
134
143
|
|
144
|
+
def instance_name
|
145
|
+
@name.downcase.gsub /[^a-zA-Z0-9\-]/, '-'
|
146
|
+
end
|
147
|
+
|
148
|
+
def authorize(account_ids)
|
149
|
+
ec2_ami_authorizations.add :ami_id => @ami_id, :account_ids => account_ids
|
150
|
+
end
|
151
|
+
|
135
152
|
def instance
|
136
|
-
@instance ||= Instance.new :aws => @aws, :name =>
|
153
|
+
@instance ||= Instance.new :aws => @aws, :name => instance_name
|
137
154
|
end
|
138
155
|
|
139
156
|
def ec2_ami_state
|
140
157
|
@ec2_ami_state ||= Roark::Aws::Ec2::AmiState.new @aws
|
141
158
|
end
|
142
159
|
|
160
|
+
def ec2_ami_authorizations
|
161
|
+
@ec2_ami_authorizations ||= Roark::Aws::Ec2::AmiAuthorizations.new @aws
|
162
|
+
end
|
163
|
+
|
143
164
|
def ec2_destroy_ami
|
144
165
|
@ec2_destroy_ami ||= Roark::Aws::Ec2::DestroyAmi.new @aws
|
145
166
|
end
|
@@ -2,15 +2,16 @@ module Roark
|
|
2
2
|
class AmiCreateWorkflow
|
3
3
|
|
4
4
|
def initialize(args)
|
5
|
-
@
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@
|
5
|
+
@account_ids = args[:account_ids]
|
6
|
+
@ami = args[:ami]
|
7
|
+
@parameters = args[:parameters]
|
8
|
+
@template = args[:template]
|
9
|
+
@logger = Roark.logger
|
9
10
|
end
|
10
11
|
|
11
12
|
def execute
|
12
13
|
%w(create_instance wait_for_instance stop_instance wait_for_instance_to_stop
|
13
|
-
create_ami wait_for_ami destroy_instance).each do |m|
|
14
|
+
create_ami wait_for_ami destroy_instance authorize_account_ids).each do |m|
|
14
15
|
response = self.send m.to_sym
|
15
16
|
return response unless response.success?
|
16
17
|
end
|
@@ -19,7 +20,7 @@ module Roark
|
|
19
20
|
|
20
21
|
def create_instance
|
21
22
|
@ami.create_instance :parameters => @parameters,
|
22
|
-
|
23
|
+
:template => @template
|
23
24
|
end
|
24
25
|
|
25
26
|
def wait_for_instance
|
@@ -46,5 +47,9 @@ module Roark
|
|
46
47
|
@ami.destroy_instance
|
47
48
|
end
|
48
49
|
|
50
|
+
def authorize_account_ids
|
51
|
+
@ami.authorize_account_ids @account_ids
|
52
|
+
end
|
53
|
+
|
49
54
|
end
|
50
55
|
end
|
data/lib/roark/aws/connection.rb
CHANGED
@@ -10,16 +10,18 @@ module Roark
|
|
10
10
|
@region = args[:region]
|
11
11
|
end
|
12
12
|
|
13
|
+
def config
|
14
|
+
{ :access_key_id => @access_key_id,
|
15
|
+
:secret_access_key => @secret_access_key,
|
16
|
+
:region => @region }
|
17
|
+
end
|
18
|
+
|
13
19
|
def cf
|
14
|
-
@cf ||= AWS::CloudFormation.new
|
15
|
-
:secret_access_key => @secret_access_key,
|
16
|
-
:region => @region
|
20
|
+
@cf ||= AWS::CloudFormation.new config
|
17
21
|
end
|
18
22
|
|
19
23
|
def ec2
|
20
|
-
@ec2 ||= AWS::EC2.new
|
21
|
-
:secret_access_key => @secret_access_key,
|
22
|
-
:region => @region
|
24
|
+
@ec2 ||= AWS::EC2.new config
|
23
25
|
end
|
24
26
|
|
25
27
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Roark
|
2
|
+
module Aws
|
3
|
+
module Ec2
|
4
|
+
class AmiAuthorizations
|
5
|
+
|
6
|
+
def initialize(connection)
|
7
|
+
@connection = connection
|
8
|
+
@logger = Roark.logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(args)
|
12
|
+
account_ids = args[:account_ids]
|
13
|
+
ami_id = args[:ami_id]
|
14
|
+
|
15
|
+
ami = @connection.ec2.images[ami_id]
|
16
|
+
|
17
|
+
account_ids.each do |a|
|
18
|
+
@logger.info "Authorizing account '#{a}'."
|
19
|
+
ami.permissions.add a
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/roark/aws/ec2.rb
CHANGED
data/lib/roark/cli/create.rb
CHANGED
@@ -5,7 +5,7 @@ module Roark
|
|
5
5
|
include Shared
|
6
6
|
|
7
7
|
def initialize
|
8
|
-
@options = { :parameters => {}, :region => 'us-east-1' }
|
8
|
+
@options = { :account_ids => [], :parameters => {}, :region => 'us-east-1' }
|
9
9
|
@logger = Roark.logger
|
10
10
|
end
|
11
11
|
|
@@ -14,6 +14,8 @@ module Roark
|
|
14
14
|
|
15
15
|
validate_required_options [:name, :template]
|
16
16
|
|
17
|
+
validate_account_ids_format
|
18
|
+
|
17
19
|
unless File.exists? @options[:template]
|
18
20
|
@logger.error "Template #{@options[:template]} does not exist."
|
19
21
|
exit 1
|
@@ -23,9 +25,10 @@ module Roark
|
|
23
25
|
|
24
26
|
ami = Roark::Ami.new :aws => aws, :name => @options[:name]
|
25
27
|
|
26
|
-
ami_create_workflow = Roark::AmiCreateWorkflow.new :
|
27
|
-
:
|
28
|
-
:
|
28
|
+
ami_create_workflow = Roark::AmiCreateWorkflow.new :account_ids => @options[:account_ids],
|
29
|
+
:ami => ami,
|
30
|
+
:template => template,
|
31
|
+
:parameters => @options[:parameters]
|
29
32
|
response = ami_create_workflow.execute
|
30
33
|
|
31
34
|
unless response.success?
|
@@ -40,6 +43,10 @@ module Roark
|
|
40
43
|
OptionParser.new do |opts|
|
41
44
|
opts.banner = "Usage: roark create [options]"
|
42
45
|
|
46
|
+
opts.on("-a", "--account_id [ACCOUNT_ID]", "AWS Account ID to Authorize. Can be specified multiple times.") do |o|
|
47
|
+
@options[:account_ids] << o
|
48
|
+
end
|
49
|
+
|
43
50
|
opts.on("-n", "--name [NAME]", "Name of AMI") do |o|
|
44
51
|
@options[:name] = o
|
45
52
|
end
|
data/lib/roark/cli/shared.rb
CHANGED
@@ -10,6 +10,15 @@ module Roark
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
def validate_account_ids_format
|
14
|
+
@options[:account_ids].each do |a|
|
15
|
+
unless a =~ /^[0-9]{12}$/
|
16
|
+
@logger.error "Account '#{a}' invalid. IDs must be 12 digits without dashes."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
13
22
|
def command_name
|
14
23
|
self.class.name.split('::').last.downcase
|
15
24
|
end
|
data/lib/roark/version.rb
CHANGED
@@ -7,9 +7,11 @@ describe Roark::AmiCreateWorkflow do
|
|
7
7
|
Roark.logger logger_stub
|
8
8
|
Roark.logger.stub :info => true
|
9
9
|
@ami_mock = mock 'ami mock'
|
10
|
-
@
|
11
|
-
|
12
|
-
:
|
10
|
+
@account_ids = ['123456789012', '123456789013']
|
11
|
+
@ami_create_workflow = Roark::AmiCreateWorkflow.new :account_ids => @account_ids,
|
12
|
+
:ami => @ami_mock,
|
13
|
+
:parameters => { 'key' => 'val' },
|
14
|
+
:template => 'template'
|
13
15
|
end
|
14
16
|
|
15
17
|
it "should create and execute a new workflow" do
|
@@ -22,6 +24,7 @@ describe Roark::AmiCreateWorkflow do
|
|
22
24
|
@ami_mock.should_receive(:create_ami).and_return @response_stub
|
23
25
|
@ami_mock.should_receive(:wait_for_ami).and_return @response_stub
|
24
26
|
@ami_mock.should_receive(:destroy_instance).and_return @response_stub
|
27
|
+
@ami_mock.should_receive(:authorize_account_ids).with(@account_ids).and_return @response_stub
|
25
28
|
expect(@ami_create_workflow.execute.success?).to be_true
|
26
29
|
end
|
27
30
|
|
data/spec/ami_spec.rb
CHANGED
@@ -8,7 +8,7 @@ describe Roark::Ami do
|
|
8
8
|
@aws_mock = mock "aws connection mock"
|
9
9
|
@aws_mock.stub :region => 'us-west-1'
|
10
10
|
init_args = { :aws => @aws_mock,
|
11
|
-
:name => '
|
11
|
+
:name => 'Intu_BaselineImage.1.2.3' }
|
12
12
|
|
13
13
|
@ami = Roark::Ami.new init_args
|
14
14
|
end
|
@@ -18,7 +18,7 @@ describe Roark::Ami do
|
|
18
18
|
@instance_mock = mock 'instance mock'
|
19
19
|
Roark::Instance.should_receive(:new).
|
20
20
|
with(:aws => @aws_mock,
|
21
|
-
:name => '
|
21
|
+
:name => 'intu-baselineimage-1-2-3').
|
22
22
|
and_return @instance_mock
|
23
23
|
@instance_mock.stub :instance_id => 'i-1234abcd'
|
24
24
|
end
|
@@ -212,6 +212,21 @@ describe Roark::Ami do
|
|
212
212
|
expect(@ami.destroy.success?).to be_true
|
213
213
|
end
|
214
214
|
end
|
215
|
+
|
216
|
+
describe "#authorize_account_ids" do
|
217
|
+
it "should call authorize with the given account ids" do
|
218
|
+
@ami.ami_id = 'ami-12345678'
|
219
|
+
account_ids = ['123456789012']
|
220
|
+
ec2_ami_authorizations_mock = mock 'ami authorizations'
|
221
|
+
Roark::Aws::Ec2::AmiAuthorizations.should_receive(:new).
|
222
|
+
with(@aws_mock).
|
223
|
+
and_return ec2_ami_authorizations_mock
|
224
|
+
ec2_ami_authorizations_mock.should_receive(:add).
|
225
|
+
with :ami_id => "ami-12345678",
|
226
|
+
:account_ids => account_ids
|
227
|
+
expect(@ami.authorize_account_ids(account_ids).success?).to be_true
|
228
|
+
end
|
229
|
+
end
|
215
230
|
end
|
216
231
|
|
217
232
|
end
|
data/spec/aws/connection_spec.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roark::Aws::Ec2::AmiAuthorizations do
|
4
|
+
|
5
|
+
describe "#add" do
|
6
|
+
it "should authorize an array of account ids to an ami" do
|
7
|
+
Roark.logger stub 'logger stub'
|
8
|
+
Roark.logger.stub :info => true, :warn => true
|
9
|
+
account_ids = ['123456789012', '123456789013']
|
10
|
+
permissions_mock = mock 'permissions'
|
11
|
+
image_stub = stub 'image', :permissions => permissions_mock
|
12
|
+
images_stub = stub :images => { 'ami-12345678' => image_stub }
|
13
|
+
connection_stub = stub 'connection', :ec2 => images_stub
|
14
|
+
account_ids.each { |account_id| permissions_mock.should_receive(:add).with(account_id) }
|
15
|
+
@authorize_ami = Roark::Aws::Ec2::AmiAuthorizations.new connection_stub
|
16
|
+
@authorize_ami.add :ami_id => 'ami-12345678',
|
17
|
+
:account_ids => account_ids
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roark
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
|
-
requirement: &
|
16
|
+
requirement: &70191115678740 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '1.3'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70191115678740
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70191115678320 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70191115678320
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70191115677860 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70191115677860
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: aws-sdk
|
49
|
-
requirement: &
|
49
|
+
requirement: &70191115677360 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - =
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: 1.11.2
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70191115677360
|
58
58
|
description: Library and CLI to build AMIs from Instances created via Cloud Formation.
|
59
59
|
email:
|
60
60
|
- brett@weav.net
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- lib/roark/aws/cloud_formation/stack_status.rb
|
84
84
|
- lib/roark/aws/connection.rb
|
85
85
|
- lib/roark/aws/ec2.rb
|
86
|
+
- lib/roark/aws/ec2/ami_authorizations.rb
|
86
87
|
- lib/roark/aws/ec2/ami_state.rb
|
87
88
|
- lib/roark/aws/ec2/create_ami.rb
|
88
89
|
- lib/roark/aws/ec2/destroy_ami.rb
|
@@ -101,6 +102,7 @@ files:
|
|
101
102
|
- spec/ami_spec.rb
|
102
103
|
- spec/aws/cloud_formation/create_stack_spec.rb
|
103
104
|
- spec/aws/connection_spec.rb
|
105
|
+
- spec/aws/ec2/ami_authorizations_spec.rb
|
104
106
|
- spec/aws/ec2/ami_state_spec.rb
|
105
107
|
- spec/aws/ec2/create_ami_spec.rb
|
106
108
|
- spec/aws/ec2/destroy_ami_spec.rb
|
@@ -124,7 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
124
126
|
version: '0'
|
125
127
|
segments:
|
126
128
|
- 0
|
127
|
-
hash:
|
129
|
+
hash: -2496970937823058822
|
128
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
131
|
none: false
|
130
132
|
requirements:
|
@@ -133,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
135
|
version: '0'
|
134
136
|
segments:
|
135
137
|
- 0
|
136
|
-
hash:
|
138
|
+
hash: -2496970937823058822
|
137
139
|
requirements: []
|
138
140
|
rubyforge_project:
|
139
141
|
rubygems_version: 1.8.16
|
@@ -145,6 +147,7 @@ test_files:
|
|
145
147
|
- spec/ami_spec.rb
|
146
148
|
- spec/aws/cloud_formation/create_stack_spec.rb
|
147
149
|
- spec/aws/connection_spec.rb
|
150
|
+
- spec/aws/ec2/ami_authorizations_spec.rb
|
148
151
|
- spec/aws/ec2/ami_state_spec.rb
|
149
152
|
- spec/aws/ec2/create_ami_spec.rb
|
150
153
|
- spec/aws/ec2/destroy_ami_spec.rb
|