simple_deploy 0.5.2 → 0.5.3

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/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm use ruby-1.9.3-p125@simple_deploy --create
1
+ rvm use ruby-1.9.3-p194@simple_deploy --create
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ ## v0.5.3
2
+
3
+ * Added a clone command that clones a stack
4
+ * Updated the protect command so it allows multiple stacks
5
+ * Updated the instances command so it tells the user when the stack does not exist
6
+ * Updated the outputs command to make the output values easier to read
7
+
1
8
  ## v0.5.2
2
9
 
3
10
  * Upgrade to stackster 0.3.0
@@ -0,0 +1,79 @@
1
+ require 'trollop'
2
+ require 'tempfile'
3
+
4
+ module SimpleDeploy
5
+ module CLI
6
+ class Clone
7
+ def clone
8
+ @opts = Trollop::options do
9
+ version SimpleDeploy::VERSION
10
+ banner <<-EOS
11
+
12
+ Clone a stack.
13
+
14
+ simple_deploy clone -s SOURCE_STACK_NAME -n NEW_STACK_NAME -e ENVIRONMENT -a ATTRIB1=VALUE -a ATTRIB2=VALUE
15
+
16
+ EOS
17
+ opt :help, "Display Help"
18
+ opt :environment, "Set the target environment", :type => :string
19
+ opt :source_name, "Stack name for the stack to clone", :type => :string
20
+ opt :new_name, "Stack name for the new stack", :type => :string
21
+ opt :attributes, "= separated attribute and it's value", :type => :string,
22
+ :multi => true
23
+ end
24
+
25
+ CLI::Shared.valid_options? :provided => @opts,
26
+ :required => [:environment, :source_name, :new_name]
27
+
28
+ override_attributes = CLI::Shared.parse_attributes :attributes => @opts[:attributes],
29
+ :logger => logger
30
+
31
+ cloned_attributes = filter_attributes source_stack.attributes
32
+ new_attributes = merge_attributes cloned_attributes, override_attributes
33
+
34
+ template_file = Tempfile.new("#{@opts[:new_name]}_template.json").path
35
+ File::open(template_file, 'w') { |f| f.write source_stack.template.to_json }
36
+
37
+ new_stack.create :attributes => new_attributes,
38
+ :template => template_file
39
+ end
40
+
41
+ private
42
+
43
+ def filter_attributes(source_attributes)
44
+ selected = source_attributes.select { |k| k !~ /^deployment/ }
45
+ selected.map { |k,v| { k => v } }
46
+ end
47
+
48
+ def merge_attributes(cloned_attributes, override_attributes)
49
+ cloned_attributes.map do |clone|
50
+ key = clone.keys.first
51
+ override = override_attributes.find { |o| o.has_key? key }
52
+ override ? override : clone
53
+ end
54
+ end
55
+
56
+ def config
57
+ @config ||= Config.new.environment @opts[:environment]
58
+ end
59
+
60
+ def logger
61
+ @logger ||= SimpleDeployLogger.new :log_level => @opts[:log_level]
62
+ end
63
+
64
+ def source_stack
65
+ @source_stack ||= Stack.new :environment => @opts[:environment],
66
+ :name => @opts[:source_name],
67
+ :config => config,
68
+ :logger => logger
69
+ end
70
+
71
+ def new_stack
72
+ @new_stack ||= Stack.new :environment => @opts[:environment],
73
+ :name => @opts[:new_name],
74
+ :config => config,
75
+ :logger => logger
76
+ end
77
+ end
78
+ end
79
+ end
@@ -30,7 +30,12 @@ EOS
30
30
  :config => config,
31
31
  :logger => logger
32
32
 
33
- jj stack.instances
33
+ instances = stack.instances
34
+ if instances.nil? || instances.empty?
35
+ puts "stack '#{opts[:name]}' does not exist"
36
+ else
37
+ jj stack.instances
38
+ end
34
39
  end
35
40
  end
36
41
  end
@@ -32,7 +32,10 @@ EOS
32
32
  :config => config,
33
33
  :logger => logger
34
34
 
35
- puts stack.outputs
35
+ outputs = stack.outputs
36
+ outputs.each do |hash|
37
+ puts "%30s: %s" % [hash['OutputKey'], hash['OutputValue']]
38
+ end
36
39
  end
37
40
  end
38
41
  end
@@ -9,9 +9,9 @@ module SimpleDeploy
9
9
  version SimpleDeploy::VERSION
10
10
  banner <<-EOS
11
11
 
12
- Protect a stack.
12
+ Protect/Unprotect one or more stacks.
13
13
 
14
- simple_deploy protect -n STACK_NAME -e ENVIRONMENT -p on_off
14
+ simple_deploy protect -n STACK_NAME1 -n STACK_NAME2 -e ENVIRONMENT -p on_off
15
15
 
16
16
  EOS
17
17
  opt :help, "Display Help"
@@ -19,7 +19,8 @@ EOS
19
19
  opt :protection, "Enable/Disable protection using on/off", :type => :string
20
20
  opt :log_level, "Log level: debug, info, warn, error", :type => :string,
21
21
  :default => 'info'
22
- opt :name, "Stack name of stack to protect", :type => :string
22
+ opt :name, "Stack name(s) of stacks to protect", :type => :string,
23
+ :multi => true
23
24
  end
24
25
 
25
26
  CLI::Shared.valid_options? :provided => opts,
@@ -29,11 +30,13 @@ EOS
29
30
 
30
31
  logger = SimpleDeployLogger.new :log_level => opts[:log_level]
31
32
 
32
- stack = Stack.new :environment => opts[:environment],
33
- :name => opts[:name],
34
- :config => config,
35
- :logger => logger
36
- stack.update :attributes => [{ 'protection' => opts[:protection] }]
33
+ opts[:name].each do |name|
34
+ stack = Stack.new :environment => opts[:environment],
35
+ :name => name,
36
+ :config => config,
37
+ :logger => logger
38
+ stack.update :attributes => [{ 'protection' => opts[:protection] }]
39
+ end
37
40
  end
38
41
  end
39
42
  end
@@ -3,6 +3,7 @@ require 'trollop'
3
3
  require 'simple_deploy/cli/shared'
4
4
 
5
5
  require 'simple_deploy/cli/attributes'
6
+ require 'simple_deploy/cli/clone'
6
7
  require 'simple_deploy/cli/create'
7
8
  require 'simple_deploy/cli/deploy'
8
9
  require 'simple_deploy/cli/destroy'
@@ -26,6 +27,8 @@ module SimpleDeploy
26
27
  case cmd
27
28
  when 'attributes'
28
29
  CLI::Attributes.new.show
30
+ when 'clone'
31
+ CLI::Clone.new.clone
29
32
  when 'create'
30
33
  CLI::Create.new.create
31
34
  when 'destroy', 'delete'
@@ -57,13 +60,13 @@ module SimpleDeploy
57
60
  when 'update'
58
61
  CLI::Update.new.update
59
62
  when '-h'
60
- puts "simple_deploy [attributes|create|destroy|environments|events|instances|list|template|outputs|parameters|protect|resources|ssh|status|update] [options]"
63
+ puts "simple_deploy [attributes|clone|create|destroy|environments|events|instances|list|template|outputs|parameters|protect|resources|ssh|status|update] [options]"
61
64
  puts "Append -h for help on specific subcommand."
62
65
  when '-v'
63
66
  puts SimpleDeploy::VERSION
64
67
  else
65
68
  puts "Unknown command: '#{cmd}'."
66
- puts "simple_deploy [attributes|create|destroy|environments|events|instances|list|template|outputs|parameters|protect|resources|ssh|status|update] [options]"
69
+ puts "simple_deploy [attributes|clone|create|destroy|environments|events|instances|list|template|outputs|parameters|protect|resources|ssh|status|update] [options]"
67
70
  puts "Append -h for help on specific subcommand."
68
71
  exit 1
69
72
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleDeploy
2
- VERSION = "0.5.2"
2
+ VERSION = "0.5.3"
3
3
  end
data/script/ci_setup CHANGED
@@ -3,11 +3,13 @@
3
3
  # Source RVM profile and set ruby / gemset
4
4
  . /etc/profile
5
5
 
6
+ # Use simple deploy gemset
7
+ rvm use "1.9.3-p194@simple_deploy" --create
8
+
6
9
  # Exit with error if any command returns non zero
7
10
  set -e
8
11
 
9
12
  # Bundle gems
10
- rvm use "1.9.3-p125@simple_deploy" --create
11
13
  bundle
12
14
 
13
15
  # Run spec tests
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+ require 'simple_deploy/cli'
3
+
4
+ describe SimpleDeploy::CLI::Clone do
5
+
6
+ describe 'clone' do
7
+ context 'filter_attributes' do
8
+ before do
9
+ @source_attributes = {
10
+ 'AmiId' => 'ami-7b6a4e3e',
11
+ 'AppEnv' => 'pod-2-cd-1',
12
+ 'MaximumAppInstances' => 1,
13
+ 'MinimumAppInstances' => 1,
14
+ 'chef_repo_bucket_prefix' => 'intu-lc',
15
+ 'chef_repo_domain' => 'live_community_chef_repo',
16
+ 'deployment_user' => 'rmendes'
17
+ }
18
+ end
19
+
20
+ it 'should filter out deployment attributes' do
21
+ new_attributes = subject.send(:filter_attributes, @source_attributes)
22
+
23
+ new_attributes.size.should == 6
24
+
25
+ new_attributes[0].has_key?('AmiId').should be_true
26
+ new_attributes[0]['AmiId'].should == 'ami-7b6a4e3e'
27
+ new_attributes[1].has_key?('AppEnv').should be_true
28
+ new_attributes[1]['AppEnv'].should == 'pod-2-cd-1'
29
+ new_attributes[2].has_key?('MaximumAppInstances').should be_true
30
+ new_attributes[2]['MaximumAppInstances'].should == 1
31
+ new_attributes[3].has_key?('MinimumAppInstances').should be_true
32
+ new_attributes[3]['MinimumAppInstances'].should == 1
33
+ new_attributes[4].has_key?('chef_repo_bucket_prefix').should be_true
34
+ new_attributes[4]['chef_repo_bucket_prefix'].should == 'intu-lc'
35
+ new_attributes[5].has_key?('chef_repo_domain').should be_true
36
+ new_attributes[5]['chef_repo_domain'].should == 'live_community_chef_repo'
37
+ end
38
+ end
39
+
40
+ context 'merge_attributes' do
41
+ before do
42
+ @cloned_attributes = [
43
+ { 'AmiId' => 'ami-7b6a4e3e' },
44
+ { 'AppEnv' => 'pod-2-cd-1' },
45
+ { 'MaximumAppInstances' => 1 },
46
+ { 'MinimumAppInstances' => 1 },
47
+ { 'chef_repo_bucket_prefix' => 'intu-lc' },
48
+ { 'chef_repo_domain' => 'live_community_chef_repo' },
49
+ { 'deployment_user' => 'rmendes' }
50
+ ]
51
+
52
+ @override_attributes = [
53
+ { 'chef_repo_bucket_prefix' => 'updated-intu-lc' },
54
+ { 'chef_repo_domain' => 'updated_community_chef_repo' }
55
+ ]
56
+ end
57
+
58
+ it 'should merge the override attributes' do
59
+ merged_attributes = subject.send(:merge_attributes, @cloned_attributes, @override_attributes)
60
+
61
+ merged_attributes.size.should == 7
62
+
63
+ merged_attributes[0].has_key?('AmiId').should be_true
64
+ merged_attributes[0]['AmiId'].should == 'ami-7b6a4e3e'
65
+ merged_attributes[1].has_key?('AppEnv').should be_true
66
+ merged_attributes[1]['AppEnv'].should == 'pod-2-cd-1'
67
+ merged_attributes[2].has_key?('MaximumAppInstances').should be_true
68
+ merged_attributes[2]['MaximumAppInstances'].should == 1
69
+ merged_attributes[3].has_key?('MinimumAppInstances').should be_true
70
+ merged_attributes[3]['MinimumAppInstances'].should == 1
71
+ merged_attributes[4].has_key?('chef_repo_bucket_prefix').should be_true
72
+ merged_attributes[4]['chef_repo_bucket_prefix'].should == 'updated-intu-lc'
73
+ merged_attributes[5].has_key?('chef_repo_domain').should be_true
74
+ merged_attributes[5]['chef_repo_domain'].should == 'updated_community_chef_repo'
75
+ merged_attributes[6].has_key?('deployment_user').should be_true
76
+ merged_attributes[6]['deployment_user'].should == 'rmendes'
77
+ end
78
+ end
79
+
80
+ context 'stack creation' do
81
+ before do
82
+ @config = mock 'config'
83
+ @logger = stub 'logger', :info => 'true'
84
+ @options = { :environment => 'my_env',
85
+ :log_level => 'debug',
86
+ :source_name => 'source_stack',
87
+ :new_name => 'new_stack',
88
+ :attributes => ['chef_repo_bucket_prefix=updated-intu-lc', 'chef_repo_domain=updated_community_chef_repo'] }
89
+
90
+ @source_stack = stub :attributes => {
91
+ 'AmiId' => 'ami-7b6a4e3e',
92
+ 'AppEnv' => 'pod-2-cd-1',
93
+ 'MaximumAppInstances' => 1,
94
+ 'MinimumAppInstances' => 1,
95
+ 'chef_repo_bucket_prefix' => 'intu-lc',
96
+ 'chef_repo_domain' => 'live_community_chef_repo',
97
+ 'deployment_user' => 'rmendes'
98
+ }, :template => { 'foo' => 'bah' }
99
+ @new_stack = stub :attributes => {}
100
+
101
+ SimpleDeploy::Config.stub(:new).and_return(@config)
102
+ @config.should_receive(:environment).with('my_env').and_return(@config)
103
+ SimpleDeploy::SimpleDeployLogger.should_receive(:new).
104
+ with(:log_level => 'debug').
105
+ and_return(@logger)
106
+
107
+ SimpleDeploy::Stack.should_receive(:new).
108
+ with(:config => @config,
109
+ :environment => 'my_env',
110
+ :logger => @logger,
111
+ :name => 'source_stack').
112
+ and_return(@source_stack)
113
+ SimpleDeploy::Stack.should_receive(:new).
114
+ with(:config => @config,
115
+ :environment => 'my_env',
116
+ :logger => @logger,
117
+ :name => 'new_stack').
118
+ and_return(@new_stack)
119
+ end
120
+
121
+ it 'should create the new stack using the filtered and merged attributes' do
122
+ SimpleDeploy::CLI::Shared.should_receive(:valid_options?).
123
+ with(:provided => @options,
124
+ :required => [:environment, :source_name, :new_name])
125
+ Trollop.stub(:options).and_return(@options)
126
+
127
+ @new_stack.should_receive(:create) do |options|
128
+ options[:attributes].should == [{ 'AmiId' => 'ami-7b6a4e3e' },
129
+ { 'AppEnv' => 'pod-2-cd-1' },
130
+ { 'MaximumAppInstances' => 1 },
131
+ { 'MinimumAppInstances' => 1 },
132
+ { 'chef_repo_bucket_prefix' => 'updated-intu-lc' },
133
+ { 'chef_repo_domain' => 'updated_community_chef_repo' }]
134
+ options[:template].should match /new_stack_template.json/
135
+ end
136
+
137
+ subject.clone
138
+ end
139
+ end
140
+ end
141
+ end
@@ -19,7 +19,7 @@ describe SimpleDeploy::CLI::Protect do
19
19
  it "should enable protection" do
20
20
  options = { :environment => 'my_env',
21
21
  :log_level => 'debug',
22
- :name => 'my_stack',
22
+ :name => ['my_stack'],
23
23
  :protection => 'on' }
24
24
 
25
25
  SimpleDeploy::CLI::Shared.should_receive(:valid_options?).
@@ -40,10 +40,41 @@ describe SimpleDeploy::CLI::Protect do
40
40
  subject.protect
41
41
  end
42
42
 
43
+ it "should enable protection for multiple stacks" do
44
+ options = { :environment => 'my_env',
45
+ :log_level => 'debug',
46
+ :name => ['my_stack1', 'my_stack2'],
47
+ :protection => 'on' }
48
+
49
+ SimpleDeploy::CLI::Shared.should_receive(:valid_options?).
50
+ with(:provided => options,
51
+ :required => [:environment, :name])
52
+ Trollop.stub(:options).and_return(options)
53
+
54
+ stack = stub :attributes => { 'protection' => 'on' }
55
+ stack.should_receive(:update).twice.with(hash_including(:attributes => [{ 'protection' => 'on' }]))
56
+
57
+ SimpleDeploy::Stack.should_receive(:new).
58
+ with(:config => @config,
59
+ :environment => 'my_env',
60
+ :logger => @logger,
61
+ :name => 'my_stack1').
62
+ and_return(stack)
63
+
64
+ SimpleDeploy::Stack.should_receive(:new).
65
+ with(:config => @config,
66
+ :environment => 'my_env',
67
+ :logger => @logger,
68
+ :name => 'my_stack2').
69
+ and_return(stack)
70
+
71
+ subject.protect
72
+ end
73
+
43
74
  it "should disable protection" do
44
75
  options = { :environment => 'my_env',
45
76
  :log_level => 'debug',
46
- :name => 'my_stack',
77
+ :name => ['my_stack'],
47
78
  :protection => 'off' }
48
79
 
49
80
  SimpleDeploy::CLI::Shared.should_receive(:valid_options?).
@@ -63,5 +94,36 @@ describe SimpleDeploy::CLI::Protect do
63
94
 
64
95
  subject.protect
65
96
  end
97
+
98
+ it "should disable protection for multiple stacks" do
99
+ options = { :environment => 'my_env',
100
+ :log_level => 'debug',
101
+ :name => ['my_stack1', 'my_stack2'],
102
+ :protection => 'off' }
103
+
104
+ SimpleDeploy::CLI::Shared.should_receive(:valid_options?).
105
+ with(:provided => options,
106
+ :required => [:environment, :name])
107
+ Trollop.stub(:options).and_return(options)
108
+
109
+ stack = stub :attributes => { 'protection' => 'off' }
110
+ stack.should_receive(:update).twice.with(hash_including(:attributes => [{ 'protection' => 'off' }]))
111
+
112
+ SimpleDeploy::Stack.should_receive(:new).
113
+ with(:config => @config,
114
+ :environment => 'my_env',
115
+ :logger => @logger,
116
+ :name => 'my_stack1').
117
+ and_return(stack)
118
+
119
+ SimpleDeploy::Stack.should_receive(:new).
120
+ with(:config => @config,
121
+ :environment => 'my_env',
122
+ :logger => @logger,
123
+ :name => 'my_stack2').
124
+ and_return(stack)
125
+
126
+ subject.protect
127
+ end
66
128
  end
67
129
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-02 00:00:00.000000000 Z
12
+ date: 2012-10-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2164719400 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2164719400
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: capistrano
27
- requirement: &2164718320 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,21 +37,31 @@ dependencies:
32
37
  version: '0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *2164718320
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: stackster
38
- requirement: &2164716240 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
- - - =
51
+ - - '='
42
52
  - !ruby/object:Gem::Version
43
53
  version: 0.3.0
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *2164716240
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.3.0
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: tinder
49
- requirement: &2164728520 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: '0'
55
70
  type: :runtime
56
71
  prerelease: false
57
- version_requirements: *2164728520
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: trollop
60
- requirement: &2164727880 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ! '>='
@@ -65,7 +85,12 @@ dependencies:
65
85
  version: '0'
66
86
  type: :runtime
67
87
  prerelease: false
68
- version_requirements: *2164727880
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
69
94
  description: I am designed to deploy artifacts uploaded by Heirloom
70
95
  email:
71
96
  - brett@weav.net
@@ -86,6 +111,7 @@ files:
86
111
  - lib/simple_deploy/artifact.rb
87
112
  - lib/simple_deploy/cli.rb
88
113
  - lib/simple_deploy/cli/attributes.rb
114
+ - lib/simple_deploy/cli/clone.rb
89
115
  - lib/simple_deploy/cli/create.rb
90
116
  - lib/simple_deploy/cli/deploy.rb
91
117
  - lib/simple_deploy/cli/destroy.rb
@@ -114,6 +140,7 @@ files:
114
140
  - simple_deploy.gemspec
115
141
  - spec/artifact_spec.rb
116
142
  - spec/cli/attributes_spec.rb
143
+ - spec/cli/clone_spec.rb
117
144
  - spec/cli/deploy_spec.rb
118
145
  - spec/cli/destroy_spec.rb
119
146
  - spec/cli/protect_spec.rb
@@ -148,13 +175,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
175
  version: '0'
149
176
  requirements: []
150
177
  rubyforge_project: simple_deploy
151
- rubygems_version: 1.8.10
178
+ rubygems_version: 1.8.24
152
179
  signing_key:
153
180
  specification_version: 3
154
181
  summary: I help with deployments
155
182
  test_files:
156
183
  - spec/artifact_spec.rb
157
184
  - spec/cli/attributes_spec.rb
185
+ - spec/cli/clone_spec.rb
158
186
  - spec/cli/deploy_spec.rb
159
187
  - spec/cli/destroy_spec.rb
160
188
  - spec/cli/protect_spec.rb