stack_master 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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +208 -0
- data/Rakefile +11 -0
- data/apply_demo.gif +0 -0
- data/bin/stack_master +16 -0
- data/example/simple/Gemfile +3 -0
- data/example/simple/parameters/myapp_vpc.yml +1 -0
- data/example/simple/parameters/myapp_web.yml +2 -0
- data/example/simple/stack_master.yml +13 -0
- data/example/simple/templates/myapp_vpc.rb +39 -0
- data/example/simple/templates/myapp_web.rb +16 -0
- data/features/apply.feature +241 -0
- data/features/delete.feature +43 -0
- data/features/diff.feature +191 -0
- data/features/events.feature +38 -0
- data/features/init.feature +6 -0
- data/features/outputs.feature +49 -0
- data/features/region_aliases.feature +66 -0
- data/features/resources.feature +45 -0
- data/features/stack_defaults.feature +88 -0
- data/features/status.feature +124 -0
- data/features/step_definitions/stack_steps.rb +50 -0
- data/features/support/env.rb +14 -0
- data/lib/stack_master.rb +81 -0
- data/lib/stack_master/aws_driver/cloud_formation.rb +56 -0
- data/lib/stack_master/cli.rb +164 -0
- data/lib/stack_master/command.rb +13 -0
- data/lib/stack_master/commands/apply.rb +104 -0
- data/lib/stack_master/commands/delete.rb +53 -0
- data/lib/stack_master/commands/diff.rb +31 -0
- data/lib/stack_master/commands/events.rb +39 -0
- data/lib/stack_master/commands/init.rb +109 -0
- data/lib/stack_master/commands/list_stacks.rb +16 -0
- data/lib/stack_master/commands/outputs.rb +27 -0
- data/lib/stack_master/commands/resources.rb +33 -0
- data/lib/stack_master/commands/status.rb +47 -0
- data/lib/stack_master/commands/validate.rb +17 -0
- data/lib/stack_master/config.rb +86 -0
- data/lib/stack_master/ctrl_c.rb +4 -0
- data/lib/stack_master/parameter_loader.rb +17 -0
- data/lib/stack_master/parameter_resolver.rb +45 -0
- data/lib/stack_master/parameter_resolvers/secret.rb +42 -0
- data/lib/stack_master/parameter_resolvers/security_group.rb +20 -0
- data/lib/stack_master/parameter_resolvers/sns_topic_name.rb +29 -0
- data/lib/stack_master/parameter_resolvers/stack_output.rb +53 -0
- data/lib/stack_master/prompter.rb +14 -0
- data/lib/stack_master/security_group_finder.rb +29 -0
- data/lib/stack_master/sns_topic_finder.rb +27 -0
- data/lib/stack_master/stack.rb +96 -0
- data/lib/stack_master/stack_definition.rb +49 -0
- data/lib/stack_master/stack_differ.rb +80 -0
- data/lib/stack_master/stack_events/fetcher.rb +45 -0
- data/lib/stack_master/stack_events/presenter.rb +27 -0
- data/lib/stack_master/stack_events/streamer.rb +55 -0
- data/lib/stack_master/stack_states.rb +34 -0
- data/lib/stack_master/template_compiler.rb +21 -0
- data/lib/stack_master/test_driver/cloud_formation.rb +139 -0
- data/lib/stack_master/testing.rb +7 -0
- data/lib/stack_master/utils.rb +31 -0
- data/lib/stack_master/validator.rb +25 -0
- data/lib/stack_master/version.rb +3 -0
- data/logo.png +0 -0
- data/script/buildkite/bundle.sh +5 -0
- data/script/buildkite/clean.sh +3 -0
- data/script/buildkite_rspec.sh +27 -0
- data/spec/fixtures/parameters/myapp_vpc.yml +1 -0
- data/spec/fixtures/stack_master.yml +35 -0
- data/spec/fixtures/templates/myapp_vpc.json +1 -0
- data/spec/spec_helper.rb +99 -0
- data/spec/stack_master/commands/apply_spec.rb +92 -0
- data/spec/stack_master/commands/delete_spec.rb +40 -0
- data/spec/stack_master/commands/init_spec.rb +17 -0
- data/spec/stack_master/commands/status_spec.rb +38 -0
- data/spec/stack_master/commands/validate_spec.rb +26 -0
- data/spec/stack_master/config_spec.rb +81 -0
- data/spec/stack_master/parameter_loader_spec.rb +81 -0
- data/spec/stack_master/parameter_resolver_spec.rb +58 -0
- data/spec/stack_master/parameter_resolvers/secret_spec.rb +66 -0
- data/spec/stack_master/parameter_resolvers/security_group_spec.rb +17 -0
- data/spec/stack_master/parameter_resolvers/sns_topic_name_spec.rb +43 -0
- data/spec/stack_master/parameter_resolvers/stack_output_spec.rb +77 -0
- data/spec/stack_master/security_group_finder_spec.rb +49 -0
- data/spec/stack_master/sns_topic_finder_spec.rb +25 -0
- data/spec/stack_master/stack_definition_spec.rb +37 -0
- data/spec/stack_master/stack_differ_spec.rb +34 -0
- data/spec/stack_master/stack_events/fetcher_spec.rb +65 -0
- data/spec/stack_master/stack_events/presenter_spec.rb +18 -0
- data/spec/stack_master/stack_events/streamer_spec.rb +33 -0
- data/spec/stack_master/stack_spec.rb +157 -0
- data/spec/stack_master/template_compiler_spec.rb +48 -0
- data/spec/stack_master/test_driver/cloud_formation_spec.rb +24 -0
- data/spec/stack_master/utils_spec.rb +30 -0
- data/spec/stack_master/validator_spec.rb +38 -0
- data/stack_master.gemspec +38 -0
- data/stacktemplates/parameter_region.yml +3 -0
- data/stacktemplates/parameter_stack_name.yml +3 -0
- data/stacktemplates/stack.json.erb +20 -0
- data/stacktemplates/stack_master.yml.erb +6 -0
- metadata +427 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
Feature: Status command
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given a file named "stack_master.yml" with:
|
|
5
|
+
"""
|
|
6
|
+
stacks:
|
|
7
|
+
us_east_1:
|
|
8
|
+
stack1:
|
|
9
|
+
template: stack1.json
|
|
10
|
+
stack2:
|
|
11
|
+
template: stack2.json
|
|
12
|
+
stack3:
|
|
13
|
+
template: stack3.json
|
|
14
|
+
"""
|
|
15
|
+
And a directory named "parameters"
|
|
16
|
+
And a file named "parameters/stack1.yml" with:
|
|
17
|
+
"""
|
|
18
|
+
KeyName: my-key
|
|
19
|
+
"""
|
|
20
|
+
And a directory named "templates"
|
|
21
|
+
And a file named "templates/stack1.json" with:
|
|
22
|
+
"""
|
|
23
|
+
{
|
|
24
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
|
25
|
+
"Description": "Test template",
|
|
26
|
+
"Parameters": {
|
|
27
|
+
"InstanceTypeParameter" : { "Type" : "String" }
|
|
28
|
+
},
|
|
29
|
+
"Mappings": {},
|
|
30
|
+
"Resources": {
|
|
31
|
+
"MyAwesomeQueue" : {
|
|
32
|
+
"Type" : "AWS::SQS::Queue",
|
|
33
|
+
"Properties" : {
|
|
34
|
+
"VisibilityTimeout" : "1"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"Outputs": {}
|
|
39
|
+
}
|
|
40
|
+
"""
|
|
41
|
+
And a file named "templates/stack2.json" with:
|
|
42
|
+
"""
|
|
43
|
+
{
|
|
44
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
|
45
|
+
"Description": "Test template",
|
|
46
|
+
"Parameters": {},
|
|
47
|
+
"Mappings": {},
|
|
48
|
+
"Resources": {
|
|
49
|
+
"MoarQueue" : {
|
|
50
|
+
"Type" : "AWS::SQS::Queue",
|
|
51
|
+
"Properties" : {
|
|
52
|
+
"VisibilityTimeout" : "1"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"Outputs": {}
|
|
57
|
+
}
|
|
58
|
+
"""
|
|
59
|
+
And a file named "templates/stack3.json" with:
|
|
60
|
+
"""
|
|
61
|
+
{
|
|
62
|
+
}
|
|
63
|
+
"""
|
|
64
|
+
And I set the environment variables to:
|
|
65
|
+
| variable | value |
|
|
66
|
+
| STUB_AWS | true |
|
|
67
|
+
|
|
68
|
+
Scenario: Run status command and get a list of stack statuii
|
|
69
|
+
Given I set the environment variables to:
|
|
70
|
+
| variable | value |
|
|
71
|
+
| ANSWER | y |
|
|
72
|
+
And I stub the following stacks:
|
|
73
|
+
| stack_id | stack_name | parameters | region | stack_status |
|
|
74
|
+
| 1 | stack1 | KeyName=my-key | us-east-1 | CREATE_COMPLETE |
|
|
75
|
+
| 2 | stack2 | | us-east-1 | UPDATE_COMPLETE |
|
|
76
|
+
And I stub a template for the stack "stack1":
|
|
77
|
+
"""
|
|
78
|
+
{
|
|
79
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
|
80
|
+
"Description": "Test template",
|
|
81
|
+
"Parameters": {
|
|
82
|
+
"InstanceTypeParameter" : { "Type" : "String" }
|
|
83
|
+
},
|
|
84
|
+
"Mappings": {},
|
|
85
|
+
"Resources": {
|
|
86
|
+
"MyAwesomeQueue" : {
|
|
87
|
+
"Type" : "AWS::SQS::Queue",
|
|
88
|
+
"Properties" : {
|
|
89
|
+
"VisibilityTimeout" : "7"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"Outputs": {}
|
|
94
|
+
}
|
|
95
|
+
"""
|
|
96
|
+
And I stub a template for the stack "stack2":
|
|
97
|
+
"""
|
|
98
|
+
{
|
|
99
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
|
100
|
+
"Description": "Test template",
|
|
101
|
+
"Parameters": {},
|
|
102
|
+
"Mappings": {},
|
|
103
|
+
"Resources": {
|
|
104
|
+
"MoarQueue" : {
|
|
105
|
+
"Type" : "AWS::SQS::Queue",
|
|
106
|
+
"Properties" : {
|
|
107
|
+
"VisibilityTimeout" : "1"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"Outputs": {}
|
|
112
|
+
}
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
When I run `stack_master status --trace` interactively
|
|
116
|
+
And the output should contain all of these lines:
|
|
117
|
+
| REGION \| STACK_NAME \| STACK_STATUS \| DIFFERENT |
|
|
118
|
+
| ----------\|------------\|-----------------\|---------- |
|
|
119
|
+
| us-east-1 \| stack1 \| CREATE_COMPLETE \| Yes |
|
|
120
|
+
| us-east-1 \| stack2 \| UPDATE_COMPLETE \| No |
|
|
121
|
+
| us-east-1 \| stack3 \| \| Yes |
|
|
122
|
+
|
|
123
|
+
Then the exit status should be 0
|
|
124
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
Given(/^I stub the following stack events:$/) do |table|
|
|
2
|
+
table.hashes.each do |row|
|
|
3
|
+
row.symbolize_keys!
|
|
4
|
+
StackMaster.cloud_formation_driver.add_stack_event(row)
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
Given(/^I stub the following stack resources:$/) do |table|
|
|
9
|
+
table.hashes.each do |row|
|
|
10
|
+
row.symbolize_keys!
|
|
11
|
+
StackMaster.cloud_formation_driver.add_stack_resource(row)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def extract_hash_from_kv_string(string)
|
|
16
|
+
string.to_s.split(',').inject({}) do |hash, kv|
|
|
17
|
+
key, value = kv.split('=')
|
|
18
|
+
hash[key] = value
|
|
19
|
+
hash
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
Given(/^I stub the following stacks:$/) do |table|
|
|
25
|
+
table.hashes.each do |row|
|
|
26
|
+
row.symbolize_keys!
|
|
27
|
+
row[:parameters] = StackMaster::Utils.hash_to_aws_parameters(extract_hash_from_kv_string(row[:parameters]))
|
|
28
|
+
outputs = extract_hash_from_kv_string(row[:outputs]).inject([]) do |array, (k, v)|
|
|
29
|
+
array << OpenStruct.new(output_key: k, output_value: v)
|
|
30
|
+
array
|
|
31
|
+
end
|
|
32
|
+
row[:outputs] = outputs
|
|
33
|
+
StackMaster.cloud_formation_driver.add_stack(row)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Given(/^I stub a template for the stack "([^"]*)":$/) do |stack_name, template_body|
|
|
38
|
+
StackMaster.cloud_formation_driver.set_template(stack_name, template_body)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
Then(/^the stack "([^"]*)" should have a policy with the following:$/) do |stack_name, policy|
|
|
42
|
+
stack_policy_body = StackMaster.cloud_formation_driver.get_stack_policy(stack_name: stack_name).stack_policy_body
|
|
43
|
+
expect(stack_policy_body).to eq policy
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Then(/^the stack "([^"]*)" should contain this notification ARN "([^"]*)"$/) do |stack_name, notification_arn|
|
|
47
|
+
stack = StackMaster.cloud_formation_driver.describe_stacks(stack_name: stack_name).stacks.first
|
|
48
|
+
expect(stack).to be
|
|
49
|
+
expect(stack.notification_arns).to include notification_arn
|
|
50
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'aruba/cucumber'
|
|
2
|
+
require 'stack_master'
|
|
3
|
+
require 'stack_master/testing'
|
|
4
|
+
require 'aruba/in_process'
|
|
5
|
+
require 'pry'
|
|
6
|
+
|
|
7
|
+
Aruba.configure do |config|
|
|
8
|
+
config.command_launcher = :in_process
|
|
9
|
+
config.main_class = StackMaster::CLI
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
Before do
|
|
13
|
+
StackMaster.cloud_formation_driver.reset
|
|
14
|
+
end
|
data/lib/stack_master.rb
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require "commander"
|
|
2
|
+
require "yaml"
|
|
3
|
+
require "virtus"
|
|
4
|
+
require "aws-sdk"
|
|
5
|
+
require "diffy"
|
|
6
|
+
require "colorize"
|
|
7
|
+
require "table_print"
|
|
8
|
+
require 'active_support/core_ext/string'
|
|
9
|
+
require "erb"
|
|
10
|
+
require 'sparkle_formation'
|
|
11
|
+
require 'dotgpg'
|
|
12
|
+
|
|
13
|
+
require "stack_master/ctrl_c"
|
|
14
|
+
require "stack_master/command"
|
|
15
|
+
require "stack_master/version"
|
|
16
|
+
require "stack_master/stack"
|
|
17
|
+
require "stack_master/prompter"
|
|
18
|
+
require "stack_master/aws_driver/cloud_formation"
|
|
19
|
+
require "stack_master/test_driver/cloud_formation"
|
|
20
|
+
require "stack_master/stack_events/fetcher"
|
|
21
|
+
require "stack_master/stack_events/presenter"
|
|
22
|
+
require "stack_master/stack_events/streamer"
|
|
23
|
+
require "stack_master/stack_states"
|
|
24
|
+
require "stack_master/sns_topic_finder"
|
|
25
|
+
require "stack_master/security_group_finder"
|
|
26
|
+
require "stack_master/parameter_loader"
|
|
27
|
+
require "stack_master/parameter_resolver"
|
|
28
|
+
require "stack_master/parameter_resolvers/stack_output"
|
|
29
|
+
require "stack_master/parameter_resolvers/secret"
|
|
30
|
+
require "stack_master/parameter_resolvers/sns_topic_name"
|
|
31
|
+
require "stack_master/parameter_resolvers/security_group"
|
|
32
|
+
require "stack_master/utils"
|
|
33
|
+
require "stack_master/config"
|
|
34
|
+
require "stack_master/stack_definition"
|
|
35
|
+
require "stack_master/template_compiler"
|
|
36
|
+
require "stack_master/commands/apply"
|
|
37
|
+
require "stack_master/commands/events"
|
|
38
|
+
require "stack_master/commands/outputs"
|
|
39
|
+
require "stack_master/commands/init"
|
|
40
|
+
require "stack_master/commands/diff"
|
|
41
|
+
require "stack_master/commands/list_stacks"
|
|
42
|
+
require "stack_master/commands/validate"
|
|
43
|
+
require "stack_master/commands/resources"
|
|
44
|
+
require "stack_master/commands/delete"
|
|
45
|
+
require "stack_master/commands/status"
|
|
46
|
+
require "stack_master/stack_differ"
|
|
47
|
+
require "stack_master/validator"
|
|
48
|
+
require "stack_master/cli"
|
|
49
|
+
|
|
50
|
+
module StackMaster
|
|
51
|
+
extend self
|
|
52
|
+
|
|
53
|
+
def base_dir
|
|
54
|
+
File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def cloud_formation_driver
|
|
58
|
+
@cloud_formation_driver ||= AwsDriver::CloudFormation.new
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def cloud_formation_driver=(value)
|
|
62
|
+
@cloud_formation_driver = value
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def stdout
|
|
66
|
+
@stdout || $stdout
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def stdout=(io)
|
|
70
|
+
@stdout = io
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def stderr
|
|
74
|
+
@stderr || $stderr
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def stderr=(io)
|
|
78
|
+
@stderr = io
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module StackMaster
|
|
2
|
+
module AwsDriver
|
|
3
|
+
class CloudFormation
|
|
4
|
+
def set_region(region)
|
|
5
|
+
@region = region
|
|
6
|
+
@cf = nil
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def delete_stack(options)
|
|
10
|
+
cf.delete_stack(options)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def describe_stacks(options)
|
|
14
|
+
cf.describe_stacks(options)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def cancel_update_stack(options)
|
|
18
|
+
cf.cancel_update_stack(options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def describe_stack_resources(options)
|
|
22
|
+
cf.describe_stack_resources(options)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_template(options)
|
|
26
|
+
cf.get_template(options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get_stack_policy(options)
|
|
30
|
+
cf.get_stack_policy(options)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def describe_stack_events(options)
|
|
34
|
+
cf.describe_stack_events(options)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def update_stack(options)
|
|
38
|
+
cf.update_stack(options)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def create_stack(options)
|
|
42
|
+
cf.create_stack(options)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def validate_template(options)
|
|
46
|
+
cf.validate_template(options)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def cf
|
|
52
|
+
@cf ||= Aws::CloudFormation::Client.new(region: @region)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
require 'commander'
|
|
2
|
+
|
|
3
|
+
module StackMaster
|
|
4
|
+
class CLI
|
|
5
|
+
include Commander::Methods
|
|
6
|
+
|
|
7
|
+
def initialize(argv, stdin=STDIN, stdout=STDOUT, stderr=STDERR, kernel=Kernel)
|
|
8
|
+
@argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
|
|
9
|
+
Commander::Runner.instance_variable_set('@singleton', Commander::Runner.new(argv))
|
|
10
|
+
StackMaster.stdout = @stdout
|
|
11
|
+
StackMaster.stderr = @stderr
|
|
12
|
+
TablePrint::Config.io = StackMaster.stdout
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def execute!
|
|
16
|
+
program :name, 'StackMaster'
|
|
17
|
+
program :version, '0.0.1'
|
|
18
|
+
program :description, 'AWS Stack Management'
|
|
19
|
+
|
|
20
|
+
global_option '-c', '--config FILE', 'Config file to use'
|
|
21
|
+
|
|
22
|
+
command :apply do |c|
|
|
23
|
+
c.syntax = 'stack_master apply [region_or_alias] [stack_name]'
|
|
24
|
+
c.summary = 'Creates or updates a stack'
|
|
25
|
+
c.description = "Creates or updates a stack. Shows a diff of the proposed stack's template and parameters. Tails stack events until CloudFormation has completed."
|
|
26
|
+
c.example 'update a stack named myapp-vpc in us-east-1', 'stack_master apply us-east-1 myapp-vpc'
|
|
27
|
+
c.action do |args, options|
|
|
28
|
+
execute_stack_command(StackMaster::Commands::Apply, args, options)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
command :outputs do |c|
|
|
33
|
+
c.syntax = 'stack_master outputs [region_or_alias] [stack_name]'
|
|
34
|
+
c.summary = 'Displays outputs for a stack'
|
|
35
|
+
c.description = "Displays outputs for a stack"
|
|
36
|
+
c.action do |args, options|
|
|
37
|
+
execute_stack_command(StackMaster::Commands::Outputs, args, options)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
command :init do |c|
|
|
42
|
+
c.syntax = 'stack_master init [region_or_alias] [stack_name]'
|
|
43
|
+
c.summary = 'Initialises the expected directory structure and stack_master.yml file'
|
|
44
|
+
c.description = 'Initialises the expected directory structure and stack_master.yml file'
|
|
45
|
+
c.option('--overwrite', 'Overwrite existing files')
|
|
46
|
+
c.action do |args, options|
|
|
47
|
+
unless args.size == 2
|
|
48
|
+
say "Invalid arguments. stack_master init [region] [stack_name]"
|
|
49
|
+
else
|
|
50
|
+
StackMaster::Commands::Init.perform(options.overwrite, *args)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
command :diff do |c|
|
|
56
|
+
c.syntax = 'stack_master diff [region_or_alias] [stack_name]'
|
|
57
|
+
c.summary = "Shows a diff of the proposed stack's template and parameters"
|
|
58
|
+
c.description = "Shows a diff of the proposed stack's template and parameters"
|
|
59
|
+
c.example 'diff a stack named myapp-vpc in us-east-1', 'stack_master diff us-east-1 myapp-vpc'
|
|
60
|
+
c.action do |args, options|
|
|
61
|
+
execute_stack_command(StackMaster::Commands::Diff, args, options)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
command :events do |c|
|
|
66
|
+
c.syntax = 'stack_master events [region_or_alias] [stack_name]'
|
|
67
|
+
c.summary = "Shows events for a stack"
|
|
68
|
+
c.description = "Shows events for a stack"
|
|
69
|
+
c.example 'show events for myapp-vpc in us-east-1', 'stack_master events us-east-1 myapp-vpc'
|
|
70
|
+
c.option '--number Integer', Integer, 'Number of recent events to show'
|
|
71
|
+
c.option '--all', 'Show all events'
|
|
72
|
+
c.option '--tail', 'Tail events'
|
|
73
|
+
c.action do |args, options|
|
|
74
|
+
execute_stack_command(StackMaster::Commands::Events, args, options)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
command :resources do |c|
|
|
79
|
+
c.syntax = 'stack_master resources [region] [stack_name]'
|
|
80
|
+
c.summary = "Shows stack resources"
|
|
81
|
+
c.description = "Shows stack resources"
|
|
82
|
+
c.action do |args, options|
|
|
83
|
+
execute_stack_command(StackMaster::Commands::Resources, args, options)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
command :list do |c|
|
|
88
|
+
c.syntax = 'stack_master list'
|
|
89
|
+
c.summary = 'List stack definitions'
|
|
90
|
+
c.description = 'List stack definitions'
|
|
91
|
+
c.action do |args, options|
|
|
92
|
+
say "Invalid arguments." if args.size > 0
|
|
93
|
+
config = load_config(options.config)
|
|
94
|
+
StackMaster::Commands::ListStacks.perform(config)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
command :validate do |c|
|
|
99
|
+
c.syntax = 'stack_master validate [region_or_alias] [stack_name]'
|
|
100
|
+
c.summary = 'Validate a template'
|
|
101
|
+
c.description = 'Validate a template'
|
|
102
|
+
c.example 'validate a stack named myapp-vpc in us-east-1', 'stack_master validate us-east-1 myapp-vpc'
|
|
103
|
+
c.action do |args, options|
|
|
104
|
+
execute_stack_command(StackMaster::Commands::Validate, args, options)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
command :status do |c|
|
|
109
|
+
c.syntax = 'stack_master status'
|
|
110
|
+
c.summary = 'Check the current status stacks.'
|
|
111
|
+
c.description = 'Checks the status of all stacks defined in the stack_master.yml file. Warning this operation can be somewhat slow.'
|
|
112
|
+
c.example 'description', 'Check the status of all stack definitions'
|
|
113
|
+
c.action do |args, options|
|
|
114
|
+
say "Invalid arguments. stack_master status" and return unless args.size == 0
|
|
115
|
+
config = load_config(options.config)
|
|
116
|
+
StackMaster::Commands::Status.perform(config)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
command :delete do |c|
|
|
121
|
+
c.syntax = 'stack_master delete [region] [stack_name]'
|
|
122
|
+
c.summary = 'Delete an existing stack'
|
|
123
|
+
c.description = 'Deletes a stack. The stack does not necessarily have to appear in the stack_master.yml file.'
|
|
124
|
+
c.example 'description', 'Delete a stack'
|
|
125
|
+
c.action do |args, options|
|
|
126
|
+
unless args.size == 2
|
|
127
|
+
say "Invalid arguments. stack_master delete [region] [stack_name]"
|
|
128
|
+
return
|
|
129
|
+
end
|
|
130
|
+
StackMaster.cloud_formation_driver.set_region(args[0])
|
|
131
|
+
StackMaster::Commands::Delete.perform(*args)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
run!
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def load_config(file)
|
|
139
|
+
stack_file = file || 'stack_master.yml'
|
|
140
|
+
StackMaster::Config.load!(stack_file)
|
|
141
|
+
rescue Errno::ENOENT => e
|
|
142
|
+
say "Failed to load config file #{stack_file}"
|
|
143
|
+
exit 1
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def execute_stack_command(command, args, options)
|
|
147
|
+
unless args.size == 2
|
|
148
|
+
say "Invalid arguments. stack_master #{command.name.split('::').last.downcase} [region] [stack_name]"
|
|
149
|
+
return
|
|
150
|
+
end
|
|
151
|
+
config = load_config(options.config)
|
|
152
|
+
aliased_region, stack_name = args
|
|
153
|
+
region = Utils.underscore_to_hyphen(config.unalias_region(aliased_region))
|
|
154
|
+
stack_name = Utils.underscore_to_hyphen(stack_name)
|
|
155
|
+
StackMaster.cloud_formation_driver.set_region(region)
|
|
156
|
+
stack_definition ||= config.find_stack(region, stack_name)
|
|
157
|
+
if stack_definition.nil?
|
|
158
|
+
say "Could not find stack definition #{stack_name} in region #{region}"
|
|
159
|
+
return
|
|
160
|
+
end
|
|
161
|
+
command.perform(config, stack_definition, options)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|