bora 0.9.4 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +144 -115
- data/bora.gemspec +1 -0
- data/exe/bora +5 -0
- data/lib/bora.rb +41 -4
- data/lib/bora/cfn/event.rb +35 -0
- data/lib/bora/cfn/output.rb +24 -0
- data/lib/bora/cfn/stack.rb +168 -0
- data/lib/bora/cfn/stack_status.rb +33 -0
- data/lib/bora/cfn/status.rb +43 -0
- data/lib/bora/cfn_param_resolver.rb +3 -3
- data/lib/bora/cli.rb +81 -0
- data/lib/bora/stack.rb +125 -118
- data/lib/bora/stack_tasks.rb +132 -0
- data/lib/bora/tasks.rb +8 -3
- data/lib/bora/template.rb +37 -0
- data/lib/bora/version.rb +2 -2
- metadata +29 -10
- data/lib/bora/event.rb +0 -31
- data/lib/bora/output.rb +0 -20
- data/lib/bora/rake_tasks.rb +0 -107
- data/lib/bora/stack_status.rb +0 -29
- data/lib/bora/status.rb +0 -41
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'rake/tasklib'
|
2
|
+
|
3
|
+
class Bora
|
4
|
+
class StackTasks < Rake::TaskLib
|
5
|
+
def initialize(stack)
|
6
|
+
@stack = stack
|
7
|
+
define_tasks
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def define_tasks
|
14
|
+
define_apply_task
|
15
|
+
define_delete_task
|
16
|
+
define_diff_task
|
17
|
+
define_events_task
|
18
|
+
define_outputs_task
|
19
|
+
define_recreate_task
|
20
|
+
define_show_task
|
21
|
+
define_show_current_task
|
22
|
+
define_status_task
|
23
|
+
define_validate_task
|
24
|
+
end
|
25
|
+
|
26
|
+
def define_apply_task
|
27
|
+
within_namespace do
|
28
|
+
desc "Creates (or updates) the '#{@stack.stack_name}' stack"
|
29
|
+
task :apply do |_, args|
|
30
|
+
@stack.apply(extract_params_from_args(args.extras))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def define_delete_task
|
36
|
+
within_namespace do
|
37
|
+
desc "Deletes the '#{@stack.stack_name}' stack"
|
38
|
+
task :delete do
|
39
|
+
@stack.delete
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def define_diff_task
|
45
|
+
within_namespace do
|
46
|
+
desc "Diffs the new template with the '#{@stack.stack_name}' stack's current template"
|
47
|
+
task :diff do |_, args|
|
48
|
+
@stack.diff(extract_params_from_args(args.extras))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def define_events_task
|
54
|
+
within_namespace do
|
55
|
+
desc "Outputs the latest events from the '#{@stack.stack_name}' stack"
|
56
|
+
task :events do
|
57
|
+
@stack.events
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def define_outputs_task
|
63
|
+
within_namespace do
|
64
|
+
desc "Shows the outputs from the '#{@stack.stack_name}' stack"
|
65
|
+
task :outputs do
|
66
|
+
@stack.outputs
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def define_recreate_task
|
72
|
+
within_namespace do
|
73
|
+
desc "Recreates (deletes then creates) the '#{@stack.stack_name}' stack"
|
74
|
+
task :recreate do |_, args|
|
75
|
+
@stack.recreate(extract_params_from_args(args.extras))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def define_show_task
|
81
|
+
within_namespace do
|
82
|
+
desc "Shows the new template for '#{@stack.stack_name}' stack"
|
83
|
+
task :show do |_, args|
|
84
|
+
@stack.show(self.extract_params_from_args(args.extras))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def define_show_current_task
|
90
|
+
within_namespace do
|
91
|
+
desc "Shows the current template for '#{@stack.stack_name}' stack"
|
92
|
+
task :show_current do
|
93
|
+
@stack.show_current
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def define_status_task
|
99
|
+
within_namespace do
|
100
|
+
desc "Displays the current status of the '#{@stack.stack_name}' stack"
|
101
|
+
task :status do
|
102
|
+
@stack.status
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def define_validate_task
|
108
|
+
within_namespace do
|
109
|
+
desc "Checks the '#{@stack.stack_name}' stack's template for validity"
|
110
|
+
task :validate do |_, args|
|
111
|
+
@stack.validate(extract_params_from_args(args.extras))
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def within_namespace
|
117
|
+
namespace :stack do
|
118
|
+
namespace @stack.stack_name do
|
119
|
+
yield
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
protected
|
126
|
+
|
127
|
+
def extract_params_from_args(args)
|
128
|
+
args ? Hash[args.map { |arg| arg.split("=", 2) }] : {}
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
data/lib/bora/tasks.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
require 'colorize'
|
2
2
|
require 'rake/tasklib'
|
3
|
-
require 'bora/stack'
|
3
|
+
require 'bora/cfn/stack'
|
4
4
|
|
5
|
-
|
5
|
+
class Bora
|
6
6
|
class Tasks < Rake::TaskLib
|
7
7
|
def initialize(stack_name, template_uri = nil)
|
8
|
+
puts "--------------------------------------------------------------------------------"
|
9
|
+
puts "Bora::Tasks is deprecated. Please use YAML based configuration instead."
|
10
|
+
puts "See http://ampedandwired.com/bora for more information."
|
11
|
+
puts "--------------------------------------------------------------------------------"
|
12
|
+
|
8
13
|
@stack_name = stack_name
|
9
|
-
@stack = Stack.new(stack_name)
|
14
|
+
@stack = Cfn::Stack.new(stack_name)
|
10
15
|
@colorize = true
|
11
16
|
@stack_options = {}
|
12
17
|
within_namespace { yield self } if block_given?
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'bora/stack'
|
2
|
+
|
3
|
+
class Bora
|
4
|
+
class Template
|
5
|
+
def initialize(template_name, template_config)
|
6
|
+
@template_name = template_name
|
7
|
+
@template_config = template_config
|
8
|
+
@stacks = {}
|
9
|
+
template_config['stacks'].each do |stack_name, stack_config|
|
10
|
+
stack_name = "#{template_name}-#{stack_name}"
|
11
|
+
stack_config = resolve_stack_config(template_config, stack_config)
|
12
|
+
@stacks[stack_name] = Stack.new(stack_name, template_config['template_file'], stack_config)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def stack(name)
|
17
|
+
@stacks[name]
|
18
|
+
end
|
19
|
+
|
20
|
+
def rake_tasks
|
21
|
+
@stacks.each { |_, s| s.rake_tasks }
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def resolve_stack_config(template_config, stack_config)
|
28
|
+
extract_cfn_options(template_config).merge(stack_config)
|
29
|
+
end
|
30
|
+
|
31
|
+
def extract_cfn_options(config)
|
32
|
+
valid_options = ["capabilities"]
|
33
|
+
config.select { |k| valid_options.include?(k) }
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/lib/bora/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.
|
1
|
+
class Bora
|
2
|
+
VERSION = "1.0.0.beta1"
|
3
3
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bora
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Blaxland
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: thor
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.19'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.19'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: bundler
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -111,7 +125,8 @@ dependencies:
|
|
111
125
|
description:
|
112
126
|
email:
|
113
127
|
- charles.blaxland@gmail.com
|
114
|
-
executables:
|
128
|
+
executables:
|
129
|
+
- bora
|
115
130
|
extensions: []
|
116
131
|
extra_rdoc_files: []
|
117
132
|
files:
|
@@ -124,15 +139,19 @@ files:
|
|
124
139
|
- bin/console
|
125
140
|
- bin/setup
|
126
141
|
- bora.gemspec
|
142
|
+
- exe/bora
|
127
143
|
- lib/bora.rb
|
144
|
+
- lib/bora/cfn/event.rb
|
145
|
+
- lib/bora/cfn/output.rb
|
146
|
+
- lib/bora/cfn/stack.rb
|
147
|
+
- lib/bora/cfn/stack_status.rb
|
148
|
+
- lib/bora/cfn/status.rb
|
128
149
|
- lib/bora/cfn_param_resolver.rb
|
129
|
-
- lib/bora/
|
130
|
-
- lib/bora/output.rb
|
131
|
-
- lib/bora/rake_tasks.rb
|
150
|
+
- lib/bora/cli.rb
|
132
151
|
- lib/bora/stack.rb
|
133
|
-
- lib/bora/
|
134
|
-
- lib/bora/status.rb
|
152
|
+
- lib/bora/stack_tasks.rb
|
135
153
|
- lib/bora/tasks.rb
|
154
|
+
- lib/bora/template.rb
|
136
155
|
- lib/bora/version.rb
|
137
156
|
homepage: https://github.com/ampedandwired/bora
|
138
157
|
licenses: []
|
@@ -148,9 +167,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
167
|
version: '0'
|
149
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
169
|
requirements:
|
151
|
-
- - "
|
170
|
+
- - ">"
|
152
171
|
- !ruby/object:Gem::Version
|
153
|
-
version:
|
172
|
+
version: 1.3.1
|
154
173
|
requirements: []
|
155
174
|
rubyforge_project:
|
156
175
|
rubygems_version: 2.4.5.1
|
data/lib/bora/event.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'bora/status'
|
2
|
-
|
3
|
-
module Bora
|
4
|
-
class Event
|
5
|
-
def initialize(event)
|
6
|
-
@event = event
|
7
|
-
@status = Status.new(@event.resource_status)
|
8
|
-
end
|
9
|
-
|
10
|
-
def method_missing(sym, *args, &block)
|
11
|
-
@event.send(sym, *args, &block)
|
12
|
-
end
|
13
|
-
|
14
|
-
def status_success?
|
15
|
-
@status.success?
|
16
|
-
end
|
17
|
-
|
18
|
-
def status_failure?
|
19
|
-
@status.failure?
|
20
|
-
end
|
21
|
-
|
22
|
-
def status_complete?
|
23
|
-
status_success? || status_failure?
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_s
|
27
|
-
status_reason = @event.resource_status_reason ? " - #{@event.resource_status_reason}" : ""
|
28
|
-
"#{@event.timestamp.getlocal} - #{@event.resource_type} - #{@event.logical_resource_id} - #{@status}#{status_reason}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/lib/bora/output.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
module Bora
|
2
|
-
class Output
|
3
|
-
def initialize(output)
|
4
|
-
@output = output
|
5
|
-
end
|
6
|
-
|
7
|
-
def key
|
8
|
-
@output.output_key
|
9
|
-
end
|
10
|
-
|
11
|
-
def value
|
12
|
-
@output.output_value
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_s
|
16
|
-
desc = @output.description ? " (#{@output.description})" : ""
|
17
|
-
"#{@output.output_key} - #{@output.output_value} #{desc}"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/lib/bora/rake_tasks.rb
DELETED
@@ -1,107 +0,0 @@
|
|
1
|
-
require 'tempfile'
|
2
|
-
require 'yaml'
|
3
|
-
require 'colorize'
|
4
|
-
require 'rake/tasklib'
|
5
|
-
require 'cfndsl'
|
6
|
-
require 'bora/tasks'
|
7
|
-
require 'bora/cfn_param_resolver'
|
8
|
-
|
9
|
-
module Bora
|
10
|
-
class RakeTasks < Rake::TaskLib
|
11
|
-
def initialize(config_file_or_hash)
|
12
|
-
define_templates(load_config(config_file_or_hash))
|
13
|
-
end
|
14
|
-
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def define_templates(config)
|
19
|
-
config['templates'].each do |template_name, template_config|
|
20
|
-
define_stacks(template_name, template_config)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def define_stacks(template_name, template_config)
|
25
|
-
template_file = template_config['template_file']
|
26
|
-
template_config['stacks'].each do |stack_name, stack_config|
|
27
|
-
stack_name = stack_config['stack_name'] || "#{template_name}-#{stack_name}"
|
28
|
-
stack_options = extract_stack_options(template_config)
|
29
|
-
define_tasks(template_file, stack_name, stack_config, stack_options)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def define_tasks(template_file, stack_name, stack_config, stack_options)
|
34
|
-
Bora::Tasks.new(stack_name) do |t|
|
35
|
-
t.stack_options = stack_options
|
36
|
-
|
37
|
-
task :generate do |_, args|
|
38
|
-
params = extract_params(stack_config, args)
|
39
|
-
|
40
|
-
if File.extname(template_file) == ".rb"
|
41
|
-
template_body = run_cfndsl(template_file, params)
|
42
|
-
template_json = JSON.parse(template_body)
|
43
|
-
if template_json["Parameters"]
|
44
|
-
cfn_param_keys = template_json["Parameters"].keys
|
45
|
-
cfn_params = params.select { |k, v| cfn_param_keys.include?(k) }.map do |k, v|
|
46
|
-
{ parameter_key: k, parameter_value: v }
|
47
|
-
end
|
48
|
-
t.stack_options[:parameters] = cfn_params if !cfn_params.empty?
|
49
|
-
end
|
50
|
-
t.stack_options[:template_body] = template_body
|
51
|
-
else
|
52
|
-
t.stack_options[:template_url] = template_file
|
53
|
-
if !params.empty?
|
54
|
-
t.stack_options[:parameters] = params.map do |k, v|
|
55
|
-
{ parameter_key: k, parameter_value: v }
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def run_cfndsl(template_file, params)
|
64
|
-
temp_extras = Tempfile.new("bora")
|
65
|
-
temp_extras.write(params.to_yaml)
|
66
|
-
temp_extras.close
|
67
|
-
template_body = CfnDsl.eval_file_with_extras(template_file, [[:yaml, temp_extras.path]]).to_json
|
68
|
-
temp_extras.unlink
|
69
|
-
template_body
|
70
|
-
end
|
71
|
-
|
72
|
-
def extract_stack_options(config)
|
73
|
-
valid_options = ["capabilities"]
|
74
|
-
config.select { |k| valid_options.include?(k) }
|
75
|
-
end
|
76
|
-
|
77
|
-
def extract_params(stack_config, args)
|
78
|
-
params = stack_config['params'] || {}
|
79
|
-
params.merge!(extract_params_from_args(args.extras))
|
80
|
-
params.map { |k, v| [k, process_param_substitutions(v)] }.to_h
|
81
|
-
end
|
82
|
-
|
83
|
-
def process_param_substitutions(val)
|
84
|
-
old_val = nil
|
85
|
-
while old_val != val
|
86
|
-
old_val = val
|
87
|
-
val = val.sub(/\${[^}]+}/) do |m|
|
88
|
-
token = m[2..-2]
|
89
|
-
CfnParamResolver.new(token).resolve
|
90
|
-
end
|
91
|
-
end
|
92
|
-
val
|
93
|
-
end
|
94
|
-
|
95
|
-
def extract_params_from_args(args)
|
96
|
-
args ? Hash[args.map { |arg| arg.split("=", 2) }] : {}
|
97
|
-
end
|
98
|
-
|
99
|
-
def load_config(config)
|
100
|
-
if config.class == String
|
101
|
-
return YAML.load_file(config)
|
102
|
-
elsif config.class == Hash
|
103
|
-
return config
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
data/lib/bora/stack_status.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'bora/status'
|
2
|
-
|
3
|
-
module Bora
|
4
|
-
class StackStatus
|
5
|
-
def initialize(underlying_stack)
|
6
|
-
@stack = underlying_stack
|
7
|
-
if @stack
|
8
|
-
@status = Status.new(@stack.stack_status)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def exists?
|
13
|
-
@status && !@status.deleted?
|
14
|
-
end
|
15
|
-
|
16
|
-
def success?
|
17
|
-
@status && @status.success?
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_s
|
21
|
-
if @stack
|
22
|
-
status_reason = @stack.stack_status_reason ? " - #{@stack.stack_status_reason}" : ""
|
23
|
-
"#{@stack.stack_name} - #{@status}#{status_reason}"
|
24
|
-
else
|
25
|
-
"Stack does not exist"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|