bora 0.1.0 → 0.2.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.
- 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
|