bora 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +65 -7
- data/bora.gemspec +1 -0
- data/lib/bora/stack.rb +37 -9
- data/lib/bora/tasks.rb +48 -2
- data/lib/bora/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3bef88ac6bd7773175b02930da53efe7de03ec7
|
4
|
+
data.tar.gz: 450388c3e3ffc40c353ed09af8a79b8bf2223c13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b7cc4b0e82bf2eb5c9ba59e95600f890296b7dcb1409177dccff2373a7b99b74c5664b95bacc96a3d597ff1cdfa477164489b623a05d8a20972f9e9e9abe142
|
7
|
+
data.tar.gz: 770f772c1df360fc90dfe7bb1efa031e537aa110a11638fb3bda947dc3c08a45b48810e28f4598bcd7ea7efc169ed35a395530c6545fbfd0a0925706af01a285
|
data/README.md
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# Bora
|
2
2
|
|
3
|
-
|
3
|
+
> 1. A cold and often gusty katabatic wind in the Adriatic
|
4
|
+
> 2. A tool for pushing around your cloud formations
|
5
|
+
|
6
|
+
This gem contains Ruby [rake](https://github.com/ruby/rake) tasks that help you work with [CloudFormation](https://aws.amazon.com/cloudformation/) stacks.
|
7
|
+
You don't need to use it with rake though - you can use the underlaying classes
|
8
|
+
in any Ruby app.
|
4
9
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
10
|
|
7
11
|
## Installation
|
8
12
|
|
@@ -22,15 +26,69 @@ Or install it yourself as:
|
|
22
26
|
|
23
27
|
## Usage
|
24
28
|
|
25
|
-
|
29
|
+
### Quick Start
|
30
|
+
|
31
|
+
Add this to your `Rakefile`
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'bora'
|
35
|
+
|
36
|
+
Bora::Tasks.new("example") do |t|
|
37
|
+
t.stack_options = {
|
38
|
+
template_body: File.read("example.json")
|
39
|
+
}
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
This will give you the following rake tasks
|
44
|
+
|
45
|
+
```shell
|
46
|
+
rake stack:example:apply # Creates (or updates) the example stack
|
47
|
+
rake stack:example:current_template # Shows the current template for example stack
|
48
|
+
rake stack:example:delete # Deletes the example stack
|
49
|
+
rake stack:example:diff # Diffs the new template with the example stack's current template
|
50
|
+
rake stack:example:events # Outputs the latest events from the example stack
|
51
|
+
rake stack:example:new_template # Shows the new template for example stack
|
52
|
+
```
|
53
|
+
|
54
|
+
You can add as many templates as you like into your Rakefile, simply define an instance of `Bora::Tasks` for each one.
|
55
|
+
|
56
|
+
### Task Options
|
57
|
+
|
58
|
+
When you define the Bora tasks, you can pass in a number of options that control how Bora works and what gets passed to CloudFormation.
|
59
|
+
The available options are shown below with their default values.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
Bora::Tasks.new("example") do |t|
|
63
|
+
t.colorize = true
|
64
|
+
t.stack_options = {}
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
* `colorize` - A boolean that controls whether console output is colored or not
|
69
|
+
* `stack_options` - A hash of options that are passed directly to the CloudFormation [create_stack](http://docs.aws.amazon.com/sdkforruby/api/Aws/CloudFormation/Client.html#create_stack-instance_method) and [update_stack](http://docs.aws.amazon.com/sdkforruby/api/Aws/CloudFormation/Client.html#update_stack-instance_method) APIs.
|
70
|
+
You must at a minimum specify either the `template_body` or `template_url` option.
|
71
|
+
|
72
|
+
|
73
|
+
### API
|
74
|
+
|
75
|
+
You can use this gem without using Rake. Most of the logic is implemented in [stack.rb](https://github.com/ampedandwired/bora/blob/master/lib/bora/stack.rb) and is fairly self-explanatory.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
require 'bora'
|
79
|
+
|
80
|
+
stack = Bora::Stack.new("my-stack")
|
81
|
+
result = stack.update({template_body: File.read("example.json")}) do |event|
|
82
|
+
puts event
|
83
|
+
end
|
84
|
+
|
85
|
+
puts "Update #{result ? "succeeded" : "failed"}"
|
86
|
+
```
|
26
87
|
|
27
88
|
## Development
|
28
89
|
|
29
90
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
91
|
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
-
|
33
92
|
## Contributing
|
34
93
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
36
|
-
|
94
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ampedandwired/bora.
|
data/bora.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_dependency "aws-sdk", "~> 2.0"
|
21
21
|
spec.add_dependency "colorize", "~> 0.7"
|
22
|
+
spec.add_dependency "diffy", "~> 3.0"
|
22
23
|
spec.add_dependency "rake", "~> 10.0"
|
23
24
|
|
24
25
|
spec.add_development_dependency "bundler", "~> 1.11"
|
data/lib/bora/stack.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'set'
|
2
2
|
require 'aws-sdk'
|
3
|
+
require 'diffy'
|
3
4
|
|
4
5
|
module Bora
|
5
6
|
class Stack
|
@@ -9,22 +10,49 @@ module Bora
|
|
9
10
|
@processed_events = Set.new
|
10
11
|
end
|
11
12
|
|
12
|
-
def create(
|
13
|
-
call_cfn_action(:create,
|
13
|
+
def create(options, &block)
|
14
|
+
call_cfn_action(:create, options, &block)
|
14
15
|
end
|
15
16
|
|
16
|
-
def update(
|
17
|
-
call_cfn_action(:update,
|
17
|
+
def update(options, &block)
|
18
|
+
call_cfn_action(:update, options, &block)
|
18
19
|
end
|
19
20
|
|
20
|
-
def create_or_update(
|
21
|
-
exists? ? update(
|
21
|
+
def create_or_update(options, &block)
|
22
|
+
exists? ? update(options, &block) : create(options, &block)
|
22
23
|
end
|
23
24
|
|
24
25
|
def delete(&block)
|
25
26
|
call_cfn_action(:delete, &block)
|
26
27
|
end
|
27
28
|
|
29
|
+
def events
|
30
|
+
return [] if !underlying_stack
|
31
|
+
events = @cfn.describe_stack_events({stack_name: underlying_stack.stack_id}).stack_events
|
32
|
+
events.reverse.map { |e| Event.new(e) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def template(pretty = true)
|
36
|
+
return if !exists?
|
37
|
+
template = @cfn.get_template({stack_name: @stack_name}).template_body
|
38
|
+
template = JSON.pretty_generate(JSON.parse(template)) if pretty
|
39
|
+
template
|
40
|
+
end
|
41
|
+
|
42
|
+
def new_template(options, pretty = true)
|
43
|
+
if options[:template_body]
|
44
|
+
template = options[:template_body]
|
45
|
+
template = JSON.pretty_generate(JSON.parse(template)) if pretty
|
46
|
+
template
|
47
|
+
else
|
48
|
+
raise Exception("new_template not yet implemented for template_url stack option")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def diff(options)
|
53
|
+
Diffy::Diff.new(template, new_template(options))
|
54
|
+
end
|
55
|
+
|
28
56
|
def exists?
|
29
57
|
underlying_stack && underlying_stack.stack_status != 'DELETE_COMPLETE'
|
30
58
|
end
|
@@ -32,13 +60,13 @@ module Bora
|
|
32
60
|
|
33
61
|
private
|
34
62
|
|
35
|
-
def call_cfn_action(action,
|
63
|
+
def call_cfn_action(action, options = {}, &block)
|
36
64
|
underlying_stack(refresh: true)
|
37
65
|
return true if action == :delete && !exists?
|
38
66
|
@previous_event_time = last_event_time
|
39
|
-
|
67
|
+
options[:stack_name] = @stack_name
|
40
68
|
begin
|
41
|
-
@cfn.method("#{action.to_s.downcase}_stack").call(
|
69
|
+
@cfn.method("#{action.to_s.downcase}_stack").call(options)
|
42
70
|
wait_for_completion(&block)
|
43
71
|
rescue Aws::CloudFormation::Errors::ValidationError => e
|
44
72
|
raise e unless e.message.include?("No updates are to be performed")
|
data/lib/bora/tasks.rb
CHANGED
@@ -11,20 +11,34 @@ module Bora
|
|
11
11
|
define_tasks
|
12
12
|
end
|
13
13
|
|
14
|
-
attr_accessor :
|
14
|
+
attr_accessor :stack_options, :colorize
|
15
15
|
|
16
16
|
private
|
17
17
|
|
18
18
|
def define_tasks
|
19
19
|
define_apply_task
|
20
|
+
define_current_template_task
|
20
21
|
define_delete_task
|
22
|
+
define_diff_task
|
23
|
+
define_events_task
|
24
|
+
define_new_template_task
|
21
25
|
end
|
22
26
|
|
23
27
|
def define_apply_task
|
24
28
|
within_namespace do
|
25
29
|
desc "Creates (or updates) the #{@stack_name} stack"
|
26
30
|
task :apply do
|
27
|
-
invoke_action(@stack.exists? ? "update" : "create",
|
31
|
+
invoke_action(@stack.exists? ? "update" : "create", stack_options)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def define_current_template_task
|
37
|
+
within_namespace do
|
38
|
+
desc "Shows the current template for #{@stack_name} stack"
|
39
|
+
task :current_template do
|
40
|
+
template = @stack.template
|
41
|
+
puts template ? template : "Stack #{@stack_name} does not exist"
|
28
42
|
end
|
29
43
|
end
|
30
44
|
end
|
@@ -38,6 +52,38 @@ module Bora
|
|
38
52
|
end
|
39
53
|
end
|
40
54
|
|
55
|
+
def define_diff_task
|
56
|
+
within_namespace do
|
57
|
+
desc "Diffs the new template with the #{@stack_name} stack's current template"
|
58
|
+
task :diff do
|
59
|
+
puts @stack.diff(@stack_options).to_s(@colorize ? :color : :text)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def define_events_task
|
65
|
+
within_namespace do
|
66
|
+
desc "Outputs the latest events from the #{@stack_name} stack"
|
67
|
+
task :events do
|
68
|
+
events = @stack.events
|
69
|
+
if events.length > 0
|
70
|
+
@stack.events.each { |e| puts e }
|
71
|
+
else
|
72
|
+
puts "No events for stack #{@stack_name}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def define_new_template_task
|
79
|
+
within_namespace do
|
80
|
+
desc "Shows the new template for #{@stack_name} stack"
|
81
|
+
task :new_template do
|
82
|
+
puts @stack.new_template(@stack_options)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
41
87
|
def invoke_action(action, *args)
|
42
88
|
puts "#{action.capitalize} stack #{@stack_name}"
|
43
89
|
success = @stack.send(action, *args) { |event| puts event.to_s(colorize) }
|
data/lib/bora/version.rb
CHANGED
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: 0.2.0
|
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-01-
|
11
|
+
date: 2016-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: diffy
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|