simple_deploy 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/README.md +8 -26
- data/lib/simple_deploy/artifact.rb +1 -5
- data/lib/simple_deploy/cli/deploy.rb +7 -2
- data/lib/simple_deploy/logger.rb +11 -4
- data/lib/simple_deploy/stack/deployment/status.rb +58 -0
- data/lib/simple_deploy/stack/deployment.rb +71 -42
- data/lib/simple_deploy/stack/stack_attribute_formater.rb +4 -2
- data/lib/simple_deploy/stack.rb +15 -49
- data/lib/simple_deploy/version.rb +1 -1
- data/spec/artifact_spec.rb +25 -0
- data/spec/cli_spec.rb +15 -0
- data/spec/config_spec.rb +68 -4
- data/spec/logger_spec.rb +34 -0
- data/spec/stack/deployment/status_spec.rb +7 -0
- data/spec/stack/deployment_spec.rb +33 -0
- data/spec/stack/stack_attribute_formater_spec.rb +38 -0
- data/spec/stack_spec.rb +66 -0
- metadata +29 -16
- data/lib/simple_deploy/stack/stack_lister.rb +0 -13
- data/lib/simple_deploy/stack/stack_reader.rb +0 -40
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## v0.4.6:
|
2
|
+
|
3
|
+
* Added spec tests
|
4
|
+
* Passing logger object into Capistrano deploy
|
5
|
+
* Updated logger to accept puts from Capistrano
|
6
|
+
* Refactored deployment
|
7
|
+
* Added support for both classic & vpc deployments
|
8
|
+
* Removed unused stack_reader & stack_lister classes
|
9
|
+
|
1
10
|
## v0.4.5:
|
2
11
|
|
3
12
|
* Corrected SSL verification options
|
data/README.md
CHANGED
@@ -33,8 +33,13 @@ notifications:
|
|
33
33
|
token: XXX
|
34
34
|
```
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
Notifications
|
37
|
+
-------------
|
38
|
+
|
39
|
+
Currently Simple Deploy only supports Campfire for notifications. To enable them, add your token, which can be obtained on the 'My Info' screen of Campfire in the notifications yaml above. If you don't want notificaitons, omit this section.
|
40
|
+
|
41
|
+
Advaned Configurations
|
42
|
+
----------------------
|
38
43
|
|
39
44
|
The configuration file supports additional optional deployment parameters. Artifacts can have an **endpoint** specified to be passed in (by default they pass in the s3 url).
|
40
45
|
|
@@ -43,30 +48,7 @@ Deploy can have a ssh **user** and **key** set. These will be used to connect t
|
|
43
48
|
Commands
|
44
49
|
--------
|
45
50
|
|
46
|
-
|
47
|
-
|
48
|
-
```
|
49
|
-
simple_deploy environments
|
50
|
-
simple_deploy list -e ENVIRONMENT
|
51
|
-
simple_deploy create -n STACK_NAME -e ENVIRONMENT -a ATTRIBUTES -t TEMPLATE_PATH
|
52
|
-
simple_deploy update -n STACK_NAME -e ENVIRONMENT -a ATTRIBUTES
|
53
|
-
simple_deploy deploy -n STACK_NAME -e ENVIRONMENT
|
54
|
-
simple_deploy ssh -n STACK_NAME -e ENVIRONMENT
|
55
|
-
simple_deploy destroy -n STACK_NAME -e ENVIRONMENT
|
56
|
-
simple_deploy instances -n STACK_NAME -e ENVIRONMENT
|
57
|
-
simple_deploy status -n STACK_NAME -e ENVIRONMENT
|
58
|
-
simple_deploy attributes -n STACK_NAME -e ENVIRONMENT
|
59
|
-
simple_deploy events -n STACK_NAME -e ENVIRONMENT
|
60
|
-
simple_deploy resources -n STACK_NAME -e ENVIRONMENT
|
61
|
-
simple_deploy outputs -n STACK_NAME -e ENVIRONMENT
|
62
|
-
simple_deploy template -n STACK_NAME -e ENVIRONMENT
|
63
|
-
|
64
|
-
Attribute pairs are = seperated key value pairs. Multiple can be specified. For example:
|
65
|
-
|
66
|
-
simple_deploy create -t ~/my-template.json -e my-env -n test-stack -a arg1=val1 -a arg2=vol2
|
67
|
-
```
|
68
|
-
|
69
|
-
For more information, run simple_deploy -h.
|
51
|
+
For a list of commands, run simple_deploy -h. To get more information about each subcommand, append a -h after the subcomand. For example: **simple_deploy deploy -h**.
|
70
52
|
|
71
53
|
Deploying
|
72
54
|
---------
|
@@ -42,9 +42,14 @@ EOS
|
|
42
42
|
:logger => logger
|
43
43
|
|
44
44
|
stack.update(:attributes => new_attributes) if new_attributes.any?
|
45
|
-
stack.deploy opts[:force]
|
46
45
|
|
47
|
-
|
46
|
+
if stack.deploy opts[:force]
|
47
|
+
notifier.send_deployment_complete_message unless opts[:quiet]
|
48
|
+
else
|
49
|
+
logger.error "Deployment to #{name} did not complete succesfully."
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
|
48
53
|
end
|
49
54
|
end
|
50
55
|
end
|
data/lib/simple_deploy/logger.rb
CHANGED
@@ -7,12 +7,23 @@ module SimpleDeploy
|
|
7
7
|
|
8
8
|
def_delegators :@logger, :debug, :error, :info, :warn
|
9
9
|
|
10
|
+
# For capistrano output
|
11
|
+
# Only output Cap commands in debug mode
|
12
|
+
def puts(msg, line_prefix=nil)
|
13
|
+
@logger.debug msg.chomp
|
14
|
+
end
|
15
|
+
|
10
16
|
def initialize(args = {})
|
11
17
|
@log_level = args[:log_level] ||= 'info'
|
12
18
|
@logger = args[:logger] ||= new_logger(args)
|
13
19
|
end
|
14
20
|
|
21
|
+
def logger_level
|
22
|
+
Logger.const_get @log_level.upcase
|
23
|
+
end
|
24
|
+
|
15
25
|
private
|
26
|
+
|
16
27
|
def new_logger(args)
|
17
28
|
Logger.new(STDOUT).tap do |l|
|
18
29
|
l.datetime_format = '%Y-%m-%dT%H:%M:%S%z'
|
@@ -23,9 +34,5 @@ module SimpleDeploy
|
|
23
34
|
end
|
24
35
|
end
|
25
36
|
|
26
|
-
def logger_level
|
27
|
-
Logger.const_get @log_level.upcase
|
28
|
-
end
|
29
|
-
|
30
37
|
end
|
31
38
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module SimpleDeploy
|
2
|
+
class Stack
|
3
|
+
class Deployment
|
4
|
+
class Status
|
5
|
+
|
6
|
+
def initialize(args)
|
7
|
+
@config = args[:config]
|
8
|
+
@stack = args[:stack]
|
9
|
+
@ssh_user = args[:ssh_user]
|
10
|
+
@name = args[:name]
|
11
|
+
@logger = @config.logger
|
12
|
+
end
|
13
|
+
|
14
|
+
def cleared_to_deploy?(force=false)
|
15
|
+
return true unless deployment_in_progress?
|
16
|
+
|
17
|
+
if force
|
18
|
+
@logger.info "Forcing. Clearing deployment status."
|
19
|
+
unset_deployment_in_progress
|
20
|
+
else
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def deployment_in_progress?
|
26
|
+
@logger.debug "Checking deployment status for #{@name}."
|
27
|
+
if attributes['deployment_in_progress'] == 'true'
|
28
|
+
@logger.info "Deployment in progress for #{@name}."
|
29
|
+
@logger.info "Started by #{attributes['deployment_user']}@#{attributes['deployment_datetime']}."
|
30
|
+
true
|
31
|
+
else
|
32
|
+
@logger.debug "No other deployments in progress for #{@name}."
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_deployment_in_progress
|
38
|
+
@logger.debug "Setting deployment in progress by #{@ssh_user} for #{@name}."
|
39
|
+
@stack.update :attributes => [ { 'deployment_in_progress' => 'true',
|
40
|
+
'deployment_user' => @ssh_user,
|
41
|
+
'deployment_datetime' => Time.now.to_s } ]
|
42
|
+
end
|
43
|
+
|
44
|
+
def unset_deployment_in_progress
|
45
|
+
@logger.debug "Clearing deployment in progress for #{@name}."
|
46
|
+
@stack.update :attributes => [ { 'deployment_in_progress' => 'false' } ]
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def attributes
|
52
|
+
@stack.attributes
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,30 +1,48 @@
|
|
1
1
|
require 'capistrano'
|
2
2
|
require 'capistrano/cli'
|
3
3
|
|
4
|
+
require 'simple_deploy/stack/deployment/status'
|
5
|
+
|
4
6
|
module SimpleDeploy
|
5
7
|
class Stack
|
6
8
|
class Deployment
|
7
9
|
def initialize(args)
|
8
10
|
@config = args[:config]
|
9
|
-
@logger = @config.logger
|
10
11
|
@instances = args[:instances]
|
11
|
-
@attributes = args[:attributes]
|
12
12
|
@environment = args[:environment]
|
13
|
-
@ssh_gateway = @attributes['ssh_gateway']
|
14
13
|
@ssh_user = args[:ssh_user]
|
15
14
|
@ssh_key = args[:ssh_key]
|
16
|
-
|
17
|
-
@
|
18
|
-
@
|
19
|
-
|
20
|
-
|
15
|
+
@stack = args[:stack]
|
16
|
+
@name = args[:name]
|
17
|
+
@attributes = @stack.attributes
|
18
|
+
@logger = @config.logger
|
19
|
+
@region = @config.region @environment
|
21
20
|
end
|
22
21
|
|
23
|
-
def
|
22
|
+
def create_deployment
|
23
|
+
@deployment = Capistrano::Configuration.new :output => @logger
|
24
|
+
@deployment.logger.level = 3
|
25
|
+
@logger.info "Creating deployment to #{@name}."
|
26
|
+
|
27
|
+
set_ssh_gateway
|
28
|
+
set_ssh_user
|
29
|
+
set_ssh_options
|
30
|
+
set_instances
|
24
31
|
set_deploy_command
|
25
|
-
|
26
|
-
|
27
|
-
|
32
|
+
end
|
33
|
+
|
34
|
+
def execute(force=false)
|
35
|
+
if status.cleared_to_deploy?(force)
|
36
|
+
status.set_deployment_in_progress
|
37
|
+
@logger.info 'Starting deployment.'
|
38
|
+
@deployment.simpledeploy
|
39
|
+
@logger.info 'Deployment complete.'
|
40
|
+
status.unset_deployment_in_progress
|
41
|
+
true
|
42
|
+
else
|
43
|
+
@logger.error "Not clear to deploy."
|
44
|
+
false
|
45
|
+
end
|
28
46
|
end
|
29
47
|
|
30
48
|
def ssh
|
@@ -37,22 +55,17 @@ module SimpleDeploy
|
|
37
55
|
|
38
56
|
def set_deploy_command
|
39
57
|
cmd = get_artifact_endpoints.any? ? "env " : ""
|
40
|
-
get_artifact_endpoints.each_pair do |
|
41
|
-
cmd += "#{
|
58
|
+
get_artifact_endpoints.each_pair do |key,value|
|
59
|
+
cmd += "#{key}=#{value} "
|
42
60
|
end
|
43
|
-
cmd += "PRIMARY_HOST=#{primary_instance} "
|
44
|
-
cmd += @deploy_script
|
61
|
+
cmd += "PRIMARY_HOST=#{primary_instance} #{deploy_script}"
|
45
62
|
|
46
|
-
@logger.info "
|
63
|
+
@logger.info "Deploy command: '#{cmd}'."
|
47
64
|
@deployment.load :string => "task :simpledeploy do
|
48
65
|
sudo '#{cmd}'
|
49
66
|
end"
|
50
67
|
end
|
51
68
|
|
52
|
-
def primary_instance
|
53
|
-
@instances.first
|
54
|
-
end
|
55
|
-
|
56
69
|
def get_artifact_endpoints
|
57
70
|
h = {}
|
58
71
|
@config.artifacts.each do |artifact|
|
@@ -64,39 +77,55 @@ module SimpleDeploy
|
|
64
77
|
:region => @region,
|
65
78
|
:config => @config,
|
66
79
|
:bucket_prefix => bucket_prefix
|
80
|
+
|
67
81
|
h[variable] = artifact.endpoints['s3']
|
68
82
|
end
|
69
83
|
h
|
70
84
|
end
|
71
85
|
|
72
|
-
def
|
73
|
-
@
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
}
|
86
|
+
def set_instances
|
87
|
+
@instances.each do |instance|
|
88
|
+
@logger.debug "Deploying to instance #{instance}."
|
89
|
+
@deployment.server instance, :instances
|
90
|
+
end
|
78
91
|
end
|
79
92
|
|
80
|
-
def
|
81
|
-
@
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
93
|
+
def set_ssh_options
|
94
|
+
@logger.debug "Setting key to #{@ssh_key}."
|
95
|
+
@deployment.variables[:ssh_options] = { :keys => @ssh_key,
|
96
|
+
:paranoid => false }
|
97
|
+
end
|
86
98
|
|
87
|
-
|
88
|
-
|
89
|
-
|
99
|
+
def set_ssh_gateway
|
100
|
+
ssh_gateway = @attributes['ssh_gateway']
|
101
|
+
if ssh_gateway && !ssh_gateway.empty?
|
102
|
+
@deployment.set :gateway, ssh_gateway
|
103
|
+
@logger.info "Proxying via gateway #{ssh_gateway}."
|
90
104
|
else
|
91
105
|
@logger.info "Not using an ssh gateway."
|
92
106
|
end
|
107
|
+
end
|
93
108
|
|
94
|
-
|
95
|
-
|
96
|
-
@
|
97
|
-
|
98
|
-
|
99
|
-
|
109
|
+
def set_ssh_user
|
110
|
+
@logger.debug "Setting user to #{@ssh_user}."
|
111
|
+
@deployment.set :user, @ssh_user
|
112
|
+
end
|
113
|
+
|
114
|
+
def primary_instance
|
115
|
+
@instances.first
|
116
|
+
end
|
117
|
+
|
118
|
+
def deploy_script
|
119
|
+
@config.deploy_script
|
120
|
+
end
|
121
|
+
|
122
|
+
def status
|
123
|
+
options = { :name => @name,
|
124
|
+
:environment => @environment,
|
125
|
+
:ssh_user => @ssh_user,
|
126
|
+
:config => @config,
|
127
|
+
:stack => @stack }
|
128
|
+
@status ||= SimpleDeploy::Stack::Deployment::Status.new options
|
100
129
|
end
|
101
130
|
|
102
131
|
end
|
@@ -20,6 +20,8 @@ module SimpleDeploy
|
|
20
20
|
attributes + updates
|
21
21
|
end
|
22
22
|
|
23
|
+
private
|
24
|
+
|
23
25
|
def artifact_names
|
24
26
|
@config.artifacts
|
25
27
|
end
|
@@ -30,7 +32,7 @@ module SimpleDeploy
|
|
30
32
|
a = @config.artifacts.select { |a| a['name'] == name }.first
|
31
33
|
|
32
34
|
bucket_prefix = @config.artifact_bucket_prefix name
|
33
|
-
|
35
|
+
url_parameter = @config.artifact_cloud_formation_url name
|
34
36
|
|
35
37
|
artifact = Artifact.new :name => name,
|
36
38
|
:id => id,
|
@@ -38,7 +40,7 @@ module SimpleDeploy
|
|
38
40
|
:config => @config,
|
39
41
|
:bucket_prefix => bucket_prefix
|
40
42
|
|
41
|
-
{
|
43
|
+
{ url_parameter => artifact.endpoints['s3'] }
|
42
44
|
end
|
43
45
|
|
44
46
|
end
|
data/lib/simple_deploy/stack.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'stackster'
|
2
2
|
require 'simple_deploy/stack/deployment'
|
3
|
-
require 'simple_deploy/stack/stack_reader'
|
4
|
-
require 'simple_deploy/stack/stack_lister'
|
5
3
|
require 'simple_deploy/stack/stack_attribute_formater'
|
6
4
|
|
7
5
|
module SimpleDeploy
|
@@ -15,62 +13,29 @@ module SimpleDeploy
|
|
15
13
|
end
|
16
14
|
|
17
15
|
def create(args)
|
18
|
-
|
19
|
-
|
16
|
+
attributes = stack_attribute_formater.updated_attributes args[:attributes]
|
17
|
+
stack.create :attributes => attributes,
|
18
|
+
:template => args[:template]
|
20
19
|
end
|
21
20
|
|
22
21
|
def update(args)
|
23
22
|
@logger.info "Updating #{@name}."
|
24
|
-
|
23
|
+
attributes = stack_attribute_formater.updated_attributes args[:attributes]
|
24
|
+
stack.update :attributes => attributes
|
25
25
|
@logger.info "Update complete for #{@name}."
|
26
26
|
end
|
27
27
|
|
28
|
-
# To Do: Abstract deployment into it's own class
|
29
|
-
# Pass in required stack objects for attribut mgmt
|
30
28
|
def deploy(force = false)
|
31
|
-
|
32
|
-
|
33
|
-
if deployment_in_progress?
|
34
|
-
@logger.info "Deployment in progress for #{@name}."
|
35
|
-
@logger.info "Started by #{attributes['deployment_user']}@#{attributes['deployment_datetime']}."
|
36
|
-
if force
|
37
|
-
@logger.info "Forcing. Clearing deployment status."
|
38
|
-
clear_deployment_status
|
39
|
-
else
|
40
|
-
@logger.error "Exiting due to existing deployment."
|
41
|
-
@logger.error "Use -f to override."
|
42
|
-
exit 1
|
43
|
-
end
|
44
|
-
else
|
45
|
-
@logger.debug "No other deployments in progress for #{@name}."
|
46
|
-
end
|
47
|
-
set_deployment_in_progress
|
48
|
-
deployment.execute
|
49
|
-
clear_deployment_status
|
50
|
-
@logger.info "Deploy completed succesfully for #{@name}."
|
29
|
+
deployment.create_deployment
|
30
|
+
deployment.execute force
|
51
31
|
end
|
52
32
|
|
53
33
|
def ssh
|
54
34
|
deployment.ssh
|
55
35
|
end
|
56
36
|
|
57
|
-
def deployment_in_progress?
|
58
|
-
attributes['deployment_in_progress'] == 'true'
|
59
|
-
end
|
60
|
-
|
61
|
-
def set_deployment_in_progress
|
62
|
-
@logger.debug "Setting deployment in progress by #{ssh_user} for #{@name}."
|
63
|
-
stack.update :attributes => [ { 'deployment_in_progress' => 'true',
|
64
|
-
'deployment_user' => ssh_user,
|
65
|
-
'deployment_datetime' => Time.now.to_s } ]
|
66
|
-
end
|
67
|
-
|
68
|
-
def clear_deployment_status
|
69
|
-
@logger.debug "Clearing deployment status for #{@name}."
|
70
|
-
stack.update :attributes => [ { 'deployment_in_progress' => '' } ]
|
71
|
-
end
|
72
|
-
|
73
37
|
def destroy
|
38
|
+
deployment.create_deployment
|
74
39
|
stack.destroy
|
75
40
|
@logger.info "#{@name} destroyed."
|
76
41
|
end
|
@@ -88,10 +53,9 @@ module SimpleDeploy
|
|
88
53
|
end
|
89
54
|
|
90
55
|
def instances
|
91
|
-
stack.instances.map do |
|
92
|
-
|
93
|
-
|
94
|
-
end
|
56
|
+
stack.instances.map do |instance|
|
57
|
+
info = instance['instancesSet'].first
|
58
|
+
info['vpcId'] ? info['privateIpAddress'] : info['ipAddress']
|
95
59
|
end
|
96
60
|
end
|
97
61
|
|
@@ -114,9 +78,10 @@ module SimpleDeploy
|
|
114
78
|
private
|
115
79
|
|
116
80
|
def stack
|
81
|
+
stackster_config = @config.environment @environment
|
117
82
|
@stack ||= Stackster::Stack.new :environment => @environment,
|
118
83
|
:name => @name,
|
119
|
-
:config =>
|
84
|
+
:config => stackster_config,
|
120
85
|
:logger => @logger
|
121
86
|
end
|
122
87
|
|
@@ -128,8 +93,9 @@ module SimpleDeploy
|
|
128
93
|
def deployment
|
129
94
|
@deployment ||= Stack::Deployment.new :config => @config,
|
130
95
|
:environment => @environment,
|
96
|
+
:name => @name,
|
97
|
+
:stack => stack,
|
131
98
|
:instances => instances,
|
132
|
-
:attributes => attributes,
|
133
99
|
:ssh_user => ssh_user,
|
134
100
|
:ssh_key => ssh_key
|
135
101
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy do
|
4
|
+
|
5
|
+
describe "an artifact" do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@config_mock = mock 'config'
|
9
|
+
@config_mock.should_receive(:artifact_domain).and_return('us-west-1')
|
10
|
+
@artifact = SimpleDeploy::Artifact.new :bucket_prefix => 'test_prefix',
|
11
|
+
:config => @config_mock,
|
12
|
+
:id => 'abc123',
|
13
|
+
:name => 'myapp',
|
14
|
+
:region => 'us-west-1'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return the endpoints for the artifact" do
|
18
|
+
endpoints = { "s3" => "s3://test_prefix-us-west-1/us-west-1/abc123.tar.gz",
|
19
|
+
"http" => "http://s3-us-west-1.amazonaws.com/test_prefix-us-west-1/us-west-1/abc123.tar.gz",
|
20
|
+
"https" => "https://s3-us-west-1.amazonaws.com/test_prefix-us-west-1/us-west-1/abc123.tar.gz" }
|
21
|
+
@artifact.endpoints.should == endpoints
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simple_deploy/cli'
|
3
|
+
|
4
|
+
describe SimpleDeploy do
|
5
|
+
|
6
|
+
it "should call the given sub command" do
|
7
|
+
status_mock = mock 'status mock'
|
8
|
+
ARGV = ['status', '-h']
|
9
|
+
status_mock.should_receive(:show)
|
10
|
+
SimpleDeploy::CLI::Status.should_receive(:new).and_return status_mock
|
11
|
+
SimpleDeploy::CLI.start
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
data/spec/config_spec.rb
CHANGED
@@ -2,10 +2,74 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe SimpleDeploy do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
describe "after creating a configuration" do
|
6
|
+
before do
|
7
|
+
@config_data = { 'artifacts' => {
|
8
|
+
'test_repo' => {
|
9
|
+
'bucket_prefix' => 'test_prefix',
|
10
|
+
'domain' => 'test_domain'
|
11
|
+
},
|
12
|
+
'test_repo2' => { },
|
13
|
+
},
|
14
|
+
'environments' => {
|
15
|
+
'test_env' => {
|
16
|
+
'secret_key' => 'secret',
|
17
|
+
'access_key' => 'access',
|
18
|
+
'region' => 'us-west-1'
|
19
|
+
}
|
20
|
+
},
|
21
|
+
'notifications' => {
|
22
|
+
'campfire' => {
|
23
|
+
'token' => 'my_token'
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
File.should_receive(:open).with("#{ENV['HOME']}/.simple_deploy.yml").
|
29
|
+
and_return(@config_data.to_yaml)
|
30
|
+
@config = SimpleDeploy::Config.new
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return the default artifacts to deploy" do
|
34
|
+
@config.artifacts.should == ['chef_repo', 'cookbooks', 'app']
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return the APP_URL for app" do
|
38
|
+
@config.artifact_deploy_variable('app').should == 'APP_URL'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return the Cloud Formation camel case variables" do
|
42
|
+
@config.artifact_cloud_formation_url('app').should == 'AppArtifactURL'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return the domain (the folder in the s3 bucket) for an artifact" do
|
46
|
+
@config.artifact_domain('test_repo').should == 'test_domain'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return the name of an artifact for those without a set domain" do
|
50
|
+
@config.artifact_domain('test_repo2').should == 'test_repo2'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return the bucket prefix for the artifact" do
|
54
|
+
@config.artifact_bucket_prefix('test_repo').should == 'test_prefix'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return the environment requested" do
|
58
|
+
@config.environment('test_env').should == ({ 'secret_key' => 'secret', 'access_key' => 'access', 'region' => 'us-west-1' })
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return the notifications available" do
|
62
|
+
@config.notifications.should == ( { 'campfire' => { 'token' => 'my_token' } } )
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return the region for the environment" do
|
66
|
+
@config.region('test_env').should == 'us-west-1'
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should return the deploy script" do
|
70
|
+
@config.deploy_script.should == '/opt/intu/admin/bin/configure.sh'
|
71
|
+
end
|
72
|
+
|
8
73
|
end
|
9
74
|
|
10
75
|
end
|
11
|
-
|
data/spec/logger_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy do
|
4
|
+
|
5
|
+
it "should create a new logger object from the hash passed as :logger" do
|
6
|
+
logger_mock = mock 'logger'
|
7
|
+
logger_mock.should_receive(:info).with 'a message'
|
8
|
+
logger = SimpleDeploy::SimpleDeployLogger.new :logger => logger_mock
|
9
|
+
logger.info 'a message'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should create a new logger object when one is not passed" do
|
13
|
+
logger_mock = mock 'logger'
|
14
|
+
Logger.should_receive(:new).with(STDOUT).and_return logger_mock
|
15
|
+
logger_mock.should_receive(:info).with 'a message'
|
16
|
+
logger_mock.should_receive(:datetime_format=).with '%Y-%m-%dT%H:%M:%S%z'
|
17
|
+
logger_mock.should_receive(:formatter=)
|
18
|
+
logger_mock.should_receive(:level=).with 1
|
19
|
+
logger = SimpleDeploy::SimpleDeployLogger.new
|
20
|
+
logger.info 'a message'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "accept puts with msg and pass it to debug" do
|
24
|
+
logger_mock = mock 'logger'
|
25
|
+
Logger.should_receive(:new).with(STDOUT).and_return logger_mock
|
26
|
+
logger_mock.should_receive(:debug).with 'a message'
|
27
|
+
logger_mock.should_receive(:datetime_format=).with '%Y-%m-%dT%H:%M:%S%z'
|
28
|
+
logger_mock.should_receive(:formatter=)
|
29
|
+
logger_mock.should_receive(:level=).with 1
|
30
|
+
logger = SimpleDeploy::SimpleDeployLogger.new
|
31
|
+
logger.puts 'a message'
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@attributes = { 'key' => 'val' }
|
7
|
+
@config_mock = mock 'config mock'
|
8
|
+
@stack_mock = mock 'stack mock'
|
9
|
+
|
10
|
+
@stack_mock.should_receive(:attributes).and_return @attributes
|
11
|
+
@config_mock.should_receive(:logger).and_return @logger_mock
|
12
|
+
@config_mock.should_receive(:region).with('test-us-west-1').
|
13
|
+
and_return 'us-west-1'
|
14
|
+
|
15
|
+
options = { :config => @config_mock,
|
16
|
+
:instances => ['1.2.3.4', '4.3.2.1'],
|
17
|
+
:environment => 'test-us-west-1',
|
18
|
+
:ssh_user => 'user',
|
19
|
+
:ssh_key => 'key',
|
20
|
+
:stack => @stack_mock,
|
21
|
+
:name => 'stack-name' }
|
22
|
+
@stack = SimpleDeploy::Stack::Deployment.new options
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not blow up creating a new deployment" do
|
26
|
+
@stack.class.should == SimpleDeploy::Stack::Deployment
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should deploy if the stack is clear to deploy"
|
30
|
+
it "should deploy if the stack is not clear to deploy but forced"
|
31
|
+
it "should deploy if the stack is not clear to deploy but forced"
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
describe SimpleDeploy do
|
2
|
+
before do
|
3
|
+
@config_mock = mock 'config mock'
|
4
|
+
@logger_mock = mock 'logger mock'
|
5
|
+
@config_mock.should_receive(:region).with('preprod').
|
6
|
+
and_return 'us-west-1'
|
7
|
+
@config_mock.should_receive(:logger).and_return @logger_mock
|
8
|
+
|
9
|
+
options = { :config => @config_mock,
|
10
|
+
:environment => 'preprod' }
|
11
|
+
@formater = SimpleDeploy::StackAttributeFormater.new options
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return updated attributes including cloud formation url" do
|
15
|
+
artifact_mock = mock 'artifact'
|
16
|
+
SimpleDeploy::Artifact.should_receive(:new).exactly(2).times.
|
17
|
+
with(:name => 'chef_repo',
|
18
|
+
:id => 'test123',
|
19
|
+
:region => 'us-west-1',
|
20
|
+
:config => @config_mock,
|
21
|
+
:bucket_prefix => 'test-prefix').
|
22
|
+
and_return artifact_mock
|
23
|
+
@config_mock.should_receive(:artifact_bucket_prefix).with('chef_repo').
|
24
|
+
exactly(2).times.
|
25
|
+
and_return('test-prefix')
|
26
|
+
@config_mock.should_receive(:artifact_cloud_formation_url).with('chef_repo').
|
27
|
+
exactly(2).times.
|
28
|
+
and_return('CookBooksURL')
|
29
|
+
@config_mock.should_receive(:artifacts).exactly(3).times.
|
30
|
+
and_return ['chef_repo', 'cookbooks', 'app']
|
31
|
+
@logger_mock.should_receive(:info)
|
32
|
+
artifact_mock.should_receive(:endpoints).exactly(2).times.
|
33
|
+
and_return 's3' => 's3_url'
|
34
|
+
@formater.updated_attributes([ { 'chef_repo' => 'test123' } ]).
|
35
|
+
should == [ { "chef_repo" => "test123" },
|
36
|
+
{ "CookBooksURL" =>"s3_url" } ]
|
37
|
+
end
|
38
|
+
end
|
data/spec/stack_spec.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy do
|
4
|
+
|
5
|
+
describe "A stack" do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@config_mock = mock 'config mock'
|
9
|
+
@logger_mock = mock 'logger mock'
|
10
|
+
@config_mock.should_receive(:logger).and_return @logger_mock
|
11
|
+
SimpleDeploy::Config.should_receive(:new).
|
12
|
+
with(:logger => 'my-logger').
|
13
|
+
and_return @config_mock
|
14
|
+
@stack = SimpleDeploy::Stack.new :environment => 'test-env',
|
15
|
+
:name => 'test-stack',
|
16
|
+
:logger => 'my-logger',
|
17
|
+
:config => @config_mock
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should call create stack" do
|
21
|
+
saf_mock = mock 'stack attribute formater mock'
|
22
|
+
stack_mock = mock 'stackster stack mock'
|
23
|
+
environment_config_mock = mock 'environment config mock'
|
24
|
+
@config_mock.should_receive(:environment).with('test-env').
|
25
|
+
and_return environment_config_mock
|
26
|
+
SimpleDeploy::StackAttributeFormater.should_receive(:new).
|
27
|
+
with(:config => @config_mock,
|
28
|
+
:environment => 'test-env').
|
29
|
+
and_return saf_mock
|
30
|
+
Stackster::Stack.should_receive(:new).with(:environment => 'test-env',
|
31
|
+
:name => 'test-stack',
|
32
|
+
:config => environment_config_mock,
|
33
|
+
:logger => @logger_mock).
|
34
|
+
and_return stack_mock
|
35
|
+
saf_mock.should_receive(:updated_attributes).with({'arg1' => 'val'}).
|
36
|
+
and_return('arg1' => 'new_val')
|
37
|
+
stack_mock.should_receive(:create).with :attributes => { 'arg1' => 'new_val' },
|
38
|
+
:template => 'some_json'
|
39
|
+
@stack.create(:attributes => { 'arg1' => 'val' },
|
40
|
+
:template => 'some_json')
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should call update stack" do
|
44
|
+
saf_mock = mock 'stack attribute formater mock'
|
45
|
+
stack_mock = mock 'stackster stack mock'
|
46
|
+
environment_config_mock = mock 'environment config mock'
|
47
|
+
@logger_mock.should_receive(:info).exactly(2).times
|
48
|
+
@config_mock.should_receive(:environment).with('test-env').
|
49
|
+
and_return environment_config_mock
|
50
|
+
SimpleDeploy::StackAttributeFormater.should_receive(:new).
|
51
|
+
with(:config => @config_mock,
|
52
|
+
:environment => 'test-env').
|
53
|
+
and_return saf_mock
|
54
|
+
Stackster::Stack.should_receive(:new).with(:environment => 'test-env',
|
55
|
+
:name => 'test-stack',
|
56
|
+
:config => environment_config_mock,
|
57
|
+
:logger => @logger_mock).
|
58
|
+
and_return stack_mock
|
59
|
+
saf_mock.should_receive(:updated_attributes).with({'arg1' => 'val'}).
|
60
|
+
and_return('arg1' => 'new_val')
|
61
|
+
stack_mock.should_receive(:update).with :attributes => { 'arg1' => 'new_val' }
|
62
|
+
@stack.update :attributes => { 'arg1' => 'val' }
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
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.4.
|
4
|
+
version: 0.4.6
|
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-07-
|
12
|
+
date: 2012-07-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70150787913560 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70150787913560
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: capistrano
|
27
|
-
requirement: &
|
27
|
+
requirement: &70150787912240 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70150787912240
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: stackster
|
38
|
-
requirement: &
|
38
|
+
requirement: &70150787911000 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - =
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.2.9
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70150787911000
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: tinder
|
49
|
-
requirement: &
|
49
|
+
requirement: &70150787909440 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70150787909440
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: trollop
|
60
|
-
requirement: &
|
60
|
+
requirement: &70150787878560 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70150787878560
|
69
69
|
description: I am designed to deploy artifacts uploaded by Heirloom
|
70
70
|
email:
|
71
71
|
- brett@weav.net
|
@@ -106,16 +106,22 @@ files:
|
|
106
106
|
- lib/simple_deploy/notifier/campfire.rb
|
107
107
|
- lib/simple_deploy/stack.rb
|
108
108
|
- lib/simple_deploy/stack/deployment.rb
|
109
|
+
- lib/simple_deploy/stack/deployment/status.rb
|
109
110
|
- lib/simple_deploy/stack/stack_attribute_formater.rb
|
110
|
-
- lib/simple_deploy/stack/stack_lister.rb
|
111
|
-
- lib/simple_deploy/stack/stack_reader.rb
|
112
111
|
- lib/simple_deploy/version.rb
|
113
112
|
- script/ci_setup
|
114
113
|
- simple_deploy.gemspec
|
114
|
+
- spec/artifact_spec.rb
|
115
|
+
- spec/cli_spec.rb
|
115
116
|
- spec/config_spec.rb
|
117
|
+
- spec/logger_spec.rb
|
116
118
|
- spec/notifier/campfire_spec.rb
|
117
119
|
- spec/notifier_spec.rb
|
118
120
|
- spec/spec_helper.rb
|
121
|
+
- spec/stack/deployment/status_spec.rb
|
122
|
+
- spec/stack/deployment_spec.rb
|
123
|
+
- spec/stack/stack_attribute_formater_spec.rb
|
124
|
+
- spec/stack_spec.rb
|
119
125
|
homepage: ''
|
120
126
|
licenses: []
|
121
127
|
post_install_message:
|
@@ -130,7 +136,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
136
|
version: '0'
|
131
137
|
segments:
|
132
138
|
- 0
|
133
|
-
hash: -
|
139
|
+
hash: -5787533256512322
|
134
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
141
|
none: false
|
136
142
|
requirements:
|
@@ -139,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
145
|
version: '0'
|
140
146
|
segments:
|
141
147
|
- 0
|
142
|
-
hash: -
|
148
|
+
hash: -5787533256512322
|
143
149
|
requirements: []
|
144
150
|
rubyforge_project: simple_deploy
|
145
151
|
rubygems_version: 1.8.16
|
@@ -147,7 +153,14 @@ signing_key:
|
|
147
153
|
specification_version: 3
|
148
154
|
summary: I help with deployments
|
149
155
|
test_files:
|
156
|
+
- spec/artifact_spec.rb
|
157
|
+
- spec/cli_spec.rb
|
150
158
|
- spec/config_spec.rb
|
159
|
+
- spec/logger_spec.rb
|
151
160
|
- spec/notifier/campfire_spec.rb
|
152
161
|
- spec/notifier_spec.rb
|
153
162
|
- spec/spec_helper.rb
|
163
|
+
- spec/stack/deployment/status_spec.rb
|
164
|
+
- spec/stack/deployment_spec.rb
|
165
|
+
- spec/stack/stack_attribute_formater_spec.rb
|
166
|
+
- spec/stack_spec.rb
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
module SimpleDeploy
|
4
|
-
class StackReader
|
5
|
-
|
6
|
-
def initialize(args)
|
7
|
-
@sf = Stackster::StackFormater.new args
|
8
|
-
@sr = Stackster::StackReader.new args
|
9
|
-
end
|
10
|
-
|
11
|
-
def attributes
|
12
|
-
@sf.attributes
|
13
|
-
end
|
14
|
-
|
15
|
-
def instances
|
16
|
-
@sf.instances_public_ip_addresses
|
17
|
-
end
|
18
|
-
|
19
|
-
def status
|
20
|
-
@sr.status
|
21
|
-
end
|
22
|
-
|
23
|
-
def events
|
24
|
-
@sr.events
|
25
|
-
end
|
26
|
-
|
27
|
-
def outputs
|
28
|
-
@sr.outputs
|
29
|
-
end
|
30
|
-
|
31
|
-
def resources
|
32
|
-
@sr.resources
|
33
|
-
end
|
34
|
-
|
35
|
-
def template
|
36
|
-
@sr.template
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|