stacker 0.0.1
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/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/README.md +10 -0
- data/Rakefile +1 -0
- data/bin/stacker +6 -0
- data/lib/stacker.rb +5 -0
- data/lib/stacker/aws.rb +39 -0
- data/lib/stacker/cli.rb +117 -0
- data/lib/stacker/repo.rb +19 -0
- data/lib/stacker/stack.rb +33 -0
- data/lib/stacker/template.rb +69 -0
- data/lib/stacker/version.rb +3 -0
- data/stacker.gemspec +26 -0
- metadata +118 -0
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use ruby-1.9.2-p180@stacker --create
|
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/stacker
ADDED
data/lib/stacker.rb
ADDED
data/lib/stacker/aws.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
module Stacker
|
4
|
+
module AWS
|
5
|
+
module CloudFormation
|
6
|
+
class Stack
|
7
|
+
def initialize
|
8
|
+
@connect = Stack.connect
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.list
|
12
|
+
Stack.connect.describe_stacks
|
13
|
+
end
|
14
|
+
|
15
|
+
def create(args)
|
16
|
+
@connect.create_stack(args[:name], 'TemplateBody' => args[:body] )
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(args)
|
20
|
+
@connect.delete_stack(args[:name])
|
21
|
+
end
|
22
|
+
|
23
|
+
def describe(args)
|
24
|
+
@connect.describe_stacks('StackName' => args[:name])
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.connect
|
30
|
+
Fog::AWS::CloudFormation.new(
|
31
|
+
:aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
|
32
|
+
:aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/stacker/cli.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Stacker
|
5
|
+
module CLI
|
6
|
+
def self.start
|
7
|
+
read_variables
|
8
|
+
|
9
|
+
@stack = Stack.new
|
10
|
+
|
11
|
+
explain if verbose?
|
12
|
+
|
13
|
+
create if @cmd == 'create'
|
14
|
+
describe if @cmd == 'describe'
|
15
|
+
delete if @cmd == 'delete'
|
16
|
+
list if @cmd == 'list'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.create
|
20
|
+
template
|
21
|
+
status "Creating Stack"
|
22
|
+
status "Name: #{@opts[:name]}"
|
23
|
+
@stack.create(:name => @opts[:name], :template => @opts[:output])
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.delete
|
27
|
+
status("Deleting stack: #{@opts[:name]}.")
|
28
|
+
@stack.delete(:name => @opts[:name])
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.describe
|
32
|
+
status(@stack.describe(:name => @opts[:name]).to_yaml)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.list
|
36
|
+
Stack.list.each do |stack|
|
37
|
+
status "#{stack.to_yaml}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.template
|
42
|
+
template = Template.new(:git_repo => @opts[:git_repo])
|
43
|
+
status "Building Template"
|
44
|
+
status "Attributes: #{@opts[:attributes]}"
|
45
|
+
status "Resources: #{@opts[:resources]}"
|
46
|
+
status "Output: #{@opts[:output]}"
|
47
|
+
|
48
|
+
template.build(:attributes => @opts[:attributes],
|
49
|
+
:output => @opts[:output],
|
50
|
+
:resources => @opts[:resources])
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.read_variables
|
54
|
+
@cmd = ARGV.shift
|
55
|
+
|
56
|
+
@opts = case @cmd.downcase
|
57
|
+
when "template"
|
58
|
+
Trollop::options do
|
59
|
+
opt :attributes, "Attributes definition file", :default => 'attributes.json.erb'
|
60
|
+
opt :git_repo, "Git repository to export.", :default => 'git@github.com:brettweavnet/stacker-repo.git'
|
61
|
+
opt :output, "Template output file.", :default => 'stack.json'
|
62
|
+
opt :resources, "Resource definition file", :default => 'resources.json.erb'
|
63
|
+
opt :silent, "Silent mode.", :default => false
|
64
|
+
opt :temp_dir, "Directory to export configuration git repo.", :default => File.join(Dir.home, "stack-repo")
|
65
|
+
opt :verbose, "Verbose mode.", :default => false
|
66
|
+
end
|
67
|
+
when "create"
|
68
|
+
Trollop::options do
|
69
|
+
opt :attributes, "Attributes definition file", :default => 'attributes.json.erb'
|
70
|
+
opt :git_repo, "Git repository to export.", :default => 'git@github.com:brettweavnet/stacker-repo.git'
|
71
|
+
opt :name, "Name of stack to create.", :type => String
|
72
|
+
opt :output, "Template output file.", :default => 'stack.json'
|
73
|
+
opt :resources, "Resource definition file", :default => 'resources.json.erb'
|
74
|
+
opt :silent, "Silent mode.", :default => false
|
75
|
+
opt :temp_dir, "Directory to export configuration git repo.", :default => File.join(Dir.home, "stack-repo")
|
76
|
+
opt :verbose, "Verbose mode.", :default => false
|
77
|
+
end
|
78
|
+
when "delete"
|
79
|
+
Trollop::options do
|
80
|
+
opt :name, "Name of stack to delete.", :type => String
|
81
|
+
opt :silent, "Silent mode.", :default => false
|
82
|
+
opt :verbose, "Verbose mode.", :default => false
|
83
|
+
end
|
84
|
+
when "describe"
|
85
|
+
Trollop::options do
|
86
|
+
opt :name, "Name of stack to describe.", :type => String
|
87
|
+
opt :verbose, "Verbose mode.", :default => false
|
88
|
+
end
|
89
|
+
when "list"
|
90
|
+
Trollop::options do
|
91
|
+
opt :verbose, "Verbose mode.", :default => false
|
92
|
+
end
|
93
|
+
else
|
94
|
+
status "\nUnknown command: '#{@cmd}'."
|
95
|
+
status "\nstacker [create|describe|delete|list] --help"
|
96
|
+
exit 1
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.explain
|
101
|
+
status "Executing #{@cmd} with following options:"
|
102
|
+
status "#{@opts.to_yaml}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.verbose?
|
106
|
+
@opts[:verbose] && !silent?
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.silent?
|
110
|
+
@opts[:silent] if @opts
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.status(msg)
|
114
|
+
printf("#{msg}\n") unless silent?
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/stacker/repo.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "git"
|
2
|
+
|
3
|
+
module Stacker
|
4
|
+
class Repo
|
5
|
+
def initialize(args)
|
6
|
+
@temp_repo_export_dir = args[:temp_repo_export_dir]
|
7
|
+
@git_repo = args[:git_repo]
|
8
|
+
end
|
9
|
+
|
10
|
+
def export
|
11
|
+
Dir.mkdir(@temp_repo_export_dir, 0700)
|
12
|
+
Git.export(@git_repo, @temp_repo_export_dir)
|
13
|
+
end
|
14
|
+
|
15
|
+
def remove
|
16
|
+
FileUtils.remove_dir(@temp_repo_export_dir)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Stacker
|
2
|
+
|
3
|
+
class Stack
|
4
|
+
def self.list
|
5
|
+
list = []
|
6
|
+
|
7
|
+
stacks = AWS::CloudFormation::Stack.list
|
8
|
+
stacks.body["Stacks"].each do |stack|
|
9
|
+
list << stack['StackName']
|
10
|
+
end
|
11
|
+
|
12
|
+
list
|
13
|
+
end
|
14
|
+
|
15
|
+
def create(args)
|
16
|
+
file = File.open(args[:template], "rb")
|
17
|
+
contents = file.read
|
18
|
+
stack = AWS::CloudFormation::Stack.new
|
19
|
+
stack.create(:name => args[:name], :body => contents)
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(args)
|
23
|
+
stack = AWS::CloudFormation::Stack.new
|
24
|
+
stack.delete(:name => args[:name])
|
25
|
+
end
|
26
|
+
|
27
|
+
def describe(args)
|
28
|
+
stack = AWS::CloudFormation::Stack.new
|
29
|
+
stack.describe(:name => args[:name]).body.first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Stacker
|
5
|
+
|
6
|
+
class Template
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
@temp_repo_export_dir = "/tmp/repo-#{(0...8).map{65.+(rand(25)).chr}.join}"
|
10
|
+
@git_repo = args[:git_repo]
|
11
|
+
@repo = Repo.new(:git_repo => @git_repo,
|
12
|
+
:temp_repo_export_dir => @temp_repo_export_dir)
|
13
|
+
end
|
14
|
+
|
15
|
+
def build(args)
|
16
|
+
begin
|
17
|
+
export_git_repo if @git_repo
|
18
|
+
load_attributes(args[:attributes])
|
19
|
+
load_data
|
20
|
+
load_resources(args[:resources])
|
21
|
+
create_template(args[:output])
|
22
|
+
ensure
|
23
|
+
remove_git_repo if @git_repo
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def load_attributes(attributes_file)
|
30
|
+
template = IO.read("#{@temp_repo_export_dir}/attributes/#{attributes_file}")
|
31
|
+
attributes_json = ERB.new(template).result(binding).to_s
|
32
|
+
attributes = JSON.parse(attributes_json)
|
33
|
+
@data = attributes['data']
|
34
|
+
@resources = attributes['resources']
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_data
|
38
|
+
data_dir = "#{@temp_repo_export_dir}/data"
|
39
|
+
|
40
|
+
Dir.entries(data_dir).each do |data_file|
|
41
|
+
if data_file =~ /.erb$/
|
42
|
+
template = IO.read("#{data_dir}/#{data_file}")
|
43
|
+
data = ERB.new(template).result(binding).to_s
|
44
|
+
instance_variable_set("@#{data_file.gsub(/.erb$/, '')}", data)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_resources(resource_template_file)
|
50
|
+
resource_template = IO.read("#{@temp_repo_export_dir}/resources/#{resource_template_file}")
|
51
|
+
@resources = ERB.new(resource_template).result(binding)
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_template(output)
|
55
|
+
output_file = File.new(output,'w')
|
56
|
+
output_file.puts @resources
|
57
|
+
output_file.close
|
58
|
+
end
|
59
|
+
|
60
|
+
def export_git_repo
|
61
|
+
@repo.export
|
62
|
+
end
|
63
|
+
|
64
|
+
def remove_git_repo
|
65
|
+
@repo.remove
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/stacker.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "stacker/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "stacker"
|
7
|
+
s.version = Stacker::VERSION
|
8
|
+
s.authors = ["Brett Weaver"]
|
9
|
+
s.email = ["brett@weaver.io"]
|
10
|
+
s.homepage = "http://brettweavnet.github.com/stacker"
|
11
|
+
s.summary = %q{stacker helps build cloud stacks}
|
12
|
+
s.description = %q{stacker integrates with git and AWS cloud formation to rapidley build full application stacks from dynamic templates}
|
13
|
+
|
14
|
+
s.rubyforge_project = "stacker"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "rspec"
|
22
|
+
s.add_runtime_dependency "fog"
|
23
|
+
s.add_runtime_dependency "git"
|
24
|
+
s.add_runtime_dependency "json"
|
25
|
+
s.add_runtime_dependency "trollop"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stacker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brett Weaver
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-09 00:00:00.000000000 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
requirement: &79634830 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *79634830
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: fog
|
28
|
+
requirement: &79634620 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *79634620
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: git
|
39
|
+
requirement: &79634410 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *79634410
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: json
|
50
|
+
requirement: &79634200 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *79634200
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: trollop
|
61
|
+
requirement: &79633990 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :runtime
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *79633990
|
70
|
+
description: stacker integrates with git and AWS cloud formation to rapidley build
|
71
|
+
full application stacks from dynamic templates
|
72
|
+
email:
|
73
|
+
- brett@weaver.io
|
74
|
+
executables:
|
75
|
+
- stacker
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- .gitignore
|
80
|
+
- .rvmrc
|
81
|
+
- Gemfile
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- bin/stacker
|
85
|
+
- lib/stacker.rb
|
86
|
+
- lib/stacker/aws.rb
|
87
|
+
- lib/stacker/cli.rb
|
88
|
+
- lib/stacker/repo.rb
|
89
|
+
- lib/stacker/stack.rb
|
90
|
+
- lib/stacker/template.rb
|
91
|
+
- lib/stacker/version.rb
|
92
|
+
- stacker.gemspec
|
93
|
+
has_rdoc: true
|
94
|
+
homepage: http://brettweavnet.github.com/stacker
|
95
|
+
licenses: []
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project: stacker
|
114
|
+
rubygems_version: 1.6.2
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: stacker helps build cloud stacks
|
118
|
+
test_files: []
|