dployr 0.0.7 → 0.0.8
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 +62 -58
- data/lib/dployr/cli.rb +5 -5
- data/lib/dployr/commands/base.rb +2 -2
- data/lib/dployr/commands/execute.rb +12 -16
- data/lib/dployr/commands/info.rb +7 -11
- data/lib/dployr/commands/provision_test.rb +10 -14
- data/lib/dployr/commands/ssh.rb +10 -15
- data/lib/dployr/commands/start.rb +7 -6
- data/lib/dployr/commands/stop_destroy.rb +9 -8
- data/lib/dployr/compute/aws.rb +26 -26
- data/lib/dployr/compute/common.rb +6 -6
- data/lib/dployr/compute/gce.rb +155 -41
- data/lib/dployr/config/instance.rb +1 -1
- data/lib/dployr/scripts/local_shell.rb +5 -5
- data/lib/dployr/scripts/scp.rb +2 -2
- data/lib/dployr/scripts/shell.rb +5 -6
- data/lib/dployr/scripts/ssh.rb +1 -1
- data/lib/dployr/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 304f9d5d7f79de110215c48e59f5c3dc39bbe29c
|
|
4
|
+
data.tar.gz: 3fa3639b3f5058161d5fb1b318d217dcfa1c4a78
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6eaaaf925b1c8e8ef30519a4c664577359cc33266cc8db708979f32f903ac5bd0bf58bcf13d624c6059ba0b0c19846914f65d0e07690036004b91d0b016ab79b
|
|
7
|
+
data.tar.gz: 51a0d39c49c4ce149003d5acd1807879f4a0878f5fb159f8c086d3b7d09a900076f2a153c3db348217a00acd5dfe388a49957505aa8c73e4fda3ee701e26d2ca
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Multicloud management and deployment made simple
|
|
4
4
|
|
|
5
|
-
> **
|
|
5
|
+
> **Alpha project, use it by your own risk**
|
|
6
6
|
|
|
7
7
|
<table>
|
|
8
8
|
<tr>
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
**Dployr** is a Ruby utility that simplifies cloud management
|
|
19
19
|
and deployment across different providers
|
|
20
20
|
|
|
21
|
-
You can
|
|
21
|
+
You can setup your project cloud infraestructure from a
|
|
22
22
|
simple configuration file which support built-in rich features
|
|
23
23
|
|
|
24
|
-
Dployr
|
|
24
|
+
Dployr provides a featured [command-line interface](#command-line-interface) and [programmatic API](#programmatic-api)
|
|
25
25
|
|
|
26
26
|
## Installation
|
|
27
27
|
|
|
@@ -33,20 +33,19 @@ If you need to use it from another Ruby package,
|
|
|
33
33
|
add it as dependency in your `Gemfile` or `.gemspec` file
|
|
34
34
|
```ruby
|
|
35
35
|
# gemspec
|
|
36
|
-
spec.add_dependency 'dployr', '
|
|
36
|
+
spec.add_dependency 'dployr', '~> 0.0.1'
|
|
37
37
|
# Gemfile
|
|
38
|
-
gem 'dployr', '>= 0.0.
|
|
38
|
+
gem 'dployr', '>= 0.0.1'
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Dployr documentation and API is available from [RubyDoc][rubydoc]
|
|
41
|
+
Requires Ruby 1.9.3+
|
|
44
42
|
|
|
45
43
|
## Features
|
|
46
44
|
|
|
47
45
|
- Fully configurable from Ruby or YAML file with rich features like templating
|
|
48
|
-
- Supports deployment to multiple providers
|
|
49
|
-
-
|
|
46
|
+
- Supports deployment to multiple cloud providers
|
|
47
|
+
- Supports default instances and inherited configuration values
|
|
48
|
+
- Full control of virtual instances (start, restart, stop, test, provision)
|
|
50
49
|
- Local and remote scripts execution per stage phase (start, test, provision, update, stop...)
|
|
51
50
|
- Featured command-line and programmatic API
|
|
52
51
|
|
|
@@ -56,6 +55,7 @@ Note that as Dployr is still in alpha stage, there are only a few providers supp
|
|
|
56
55
|
|
|
57
56
|
- Amazon Web Services (`aws`)
|
|
58
57
|
- Google Compute Engine (`gce`)
|
|
58
|
+
- Baremetal
|
|
59
59
|
|
|
60
60
|
## Configuration
|
|
61
61
|
|
|
@@ -66,11 +66,10 @@ or a YAML file (adding the `.yml` or `.yaml` extension)
|
|
|
66
66
|
|
|
67
67
|
Each configuration level supports the followings members:
|
|
68
68
|
|
|
69
|
-
- **attributes** `Object` Custom
|
|
70
|
-
- **scripts** `
|
|
71
|
-
- **providers** `Object`
|
|
72
|
-
- **
|
|
73
|
-
- **extends** `String|Array` Allows to inherits the current config object from others
|
|
69
|
+
- **attributes** `Object` Custom attributes to apply to the current template
|
|
70
|
+
- **scripts** `Object` Scripts hooks per phase to run (start, stop, test...)
|
|
71
|
+
- **providers** `Object` Nested configuration provider-specific (aws, gce...)
|
|
72
|
+
- **extends** `String|Array` Allows to inherits the current template from other templates
|
|
74
73
|
|
|
75
74
|
#### Templating
|
|
76
75
|
|
|
@@ -104,18 +103,15 @@ Notation: `${HOME}`
|
|
|
104
103
|
|
|
105
104
|
#### Example
|
|
106
105
|
|
|
107
|
-
Featured example configuration file
|
|
106
|
+
Featured example configuration file in YAML
|
|
108
107
|
```yml
|
|
109
108
|
---
|
|
109
|
+
# general configuration applied to templates
|
|
110
110
|
default:
|
|
111
111
|
attributes:
|
|
112
112
|
name: "default"
|
|
113
113
|
prefix: dev
|
|
114
114
|
private_key_path: ~/pems/private.pem
|
|
115
|
-
authentication:
|
|
116
|
-
private_key_path: ~/.ssh/id_rsa
|
|
117
|
-
public_key_path: ~/.ssh/id_rsa.pub
|
|
118
|
-
username: ubuntu
|
|
119
115
|
providers:
|
|
120
116
|
aws:
|
|
121
117
|
attributes:
|
|
@@ -159,43 +155,35 @@ default:
|
|
|
159
155
|
path: ./scripts/updatedns.sh
|
|
160
156
|
|
|
161
157
|
custom:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
provision:
|
|
192
|
-
-
|
|
193
|
-
args:
|
|
194
|
-
- "%{$provider}-%{region}"
|
|
195
|
-
- "%{type}"
|
|
196
|
-
path: ./scripts/provision.sh
|
|
197
|
-
test:
|
|
198
|
-
- path: ./scripts/serverspec.sh
|
|
158
|
+
attributes:
|
|
159
|
+
prefix: zeus-dev
|
|
160
|
+
providers:
|
|
161
|
+
aws:
|
|
162
|
+
regions:
|
|
163
|
+
attributes:
|
|
164
|
+
instance_type: m1.medium
|
|
165
|
+
public_ip: new # create a elastic IP
|
|
166
|
+
gce:
|
|
167
|
+
attributes:
|
|
168
|
+
instance_type: m1.large
|
|
169
|
+
scripts:
|
|
170
|
+
pre-start:
|
|
171
|
+
- args:
|
|
172
|
+
- "%{name}"
|
|
173
|
+
- "%{type}"
|
|
174
|
+
- "%{domain}"
|
|
175
|
+
path: ./scripts/pre-start.sh
|
|
176
|
+
start:
|
|
177
|
+
- args:
|
|
178
|
+
- "%{hydra}"
|
|
179
|
+
path: ./scripts/configure.sh
|
|
180
|
+
provision:
|
|
181
|
+
- args:
|
|
182
|
+
- "%{$provider}-%{region}"
|
|
183
|
+
- "%{type}"
|
|
184
|
+
path: ./scripts/provision.sh
|
|
185
|
+
test:
|
|
186
|
+
- path: ./scripts/serverspec.sh
|
|
199
187
|
```
|
|
200
188
|
|
|
201
189
|
## Command-line interface
|
|
@@ -209,6 +197,7 @@ Commands
|
|
|
209
197
|
halt stop instances
|
|
210
198
|
destroy destroy instances
|
|
211
199
|
status retrieve the instances status
|
|
200
|
+
info retrieve instance information and output it in YAML format
|
|
212
201
|
test run remote test in instances
|
|
213
202
|
deploy start, provision and test running instances
|
|
214
203
|
provision instance provisioning
|
|
@@ -221,9 +210,11 @@ Options
|
|
|
221
210
|
|
|
222
211
|
-n, --name NAME template name identifier to load
|
|
223
212
|
-f, --file PATH custom config file path to load
|
|
224
|
-
-a, --attributes ATTRS aditional attributes to pass to the configuration in matrix query
|
|
213
|
+
-a, --attributes ATTRS aditional attributes to pass to the configuration in matrix query format
|
|
225
214
|
-p, --provider VALUES provider to use (allow multiple values comma-separated)
|
|
226
215
|
-r, --region REGION region to use (allow multiple values comma-separated)
|
|
216
|
+
-i, --public-ip use public ip instead of private ip to when access instances
|
|
217
|
+
--debug enable debug mode
|
|
227
218
|
-v, -V, --version version
|
|
228
219
|
-h, --help help
|
|
229
220
|
```
|
|
@@ -245,8 +236,21 @@ Test a working instance
|
|
|
245
236
|
$ dployr test -n name -p aws -r eu-west-1 -a 'env=dev'
|
|
246
237
|
```
|
|
247
238
|
|
|
239
|
+
Generate config in YAML format
|
|
240
|
+
```bash
|
|
241
|
+
$ dployr config -n name -p aws -r eu-west-1 -a 'env=dev'
|
|
242
|
+
```
|
|
243
|
+
|
|
248
244
|
## Programmatic API
|
|
249
245
|
|
|
246
|
+
You can use the Ruby programmatic API to integrate it in your own implementation
|
|
247
|
+
|
|
248
|
+
### API
|
|
249
|
+
|
|
250
|
+
Dployr API documentation is available from [RubyDoc][rubydoc]
|
|
251
|
+
|
|
252
|
+
### Configuration
|
|
253
|
+
|
|
250
254
|
```ruby
|
|
251
255
|
Dployr::configure do |dployr|
|
|
252
256
|
|
data/lib/dployr/cli.rb
CHANGED
|
@@ -6,13 +6,13 @@ command = ARGV[0]
|
|
|
6
6
|
options = {}
|
|
7
7
|
|
|
8
8
|
opt_parser = OptionParser.new do |opt|
|
|
9
|
-
opt.banner = " Usage: dployr <command> [options]"
|
|
9
|
+
opt.banner = "\n Usage: dployr <command> [options]"
|
|
10
10
|
opt.separator ""
|
|
11
11
|
opt.separator " Commands"
|
|
12
12
|
opt.separator ""
|
|
13
|
-
opt.separator " start start instances"
|
|
13
|
+
opt.separator " start start instances or create networks"
|
|
14
14
|
opt.separator " halt stop instances"
|
|
15
|
-
opt.separator " destroy destroy instances"
|
|
15
|
+
opt.separator " destroy destroy instances or delete networks"
|
|
16
16
|
opt.separator " status retrieve the instances status"
|
|
17
17
|
opt.separator " info retrieve instance information and output it in YAML format"
|
|
18
18
|
opt.separator " test run remote test in instances"
|
|
@@ -20,7 +20,7 @@ opt_parser = OptionParser.new do |opt|
|
|
|
20
20
|
opt.separator " provision instance provisioning"
|
|
21
21
|
opt.separator " config generate configuration in YAML from Dployrfile"
|
|
22
22
|
opt.separator " execute run custom stages"
|
|
23
|
-
opt.separator " ssh ssh into machine"
|
|
23
|
+
opt.separator " ssh ssh into machine (only Unix-like OS)"
|
|
24
24
|
opt.separator " init create a sample Dployrfile"
|
|
25
25
|
opt.separator ""
|
|
26
26
|
opt.separator " Options"
|
|
@@ -46,7 +46,7 @@ opt_parser = OptionParser.new do |opt|
|
|
|
46
46
|
options[:region] = v
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
opt.on("-i", "--public-ip", "use public ip instead of private ip to when access instances") do |v|
|
|
49
|
+
opt.on("-i", "--public-ip", "use public ip instead of private ip to when access to instances") do |v|
|
|
50
50
|
options[:public_ip] = v
|
|
51
51
|
end
|
|
52
52
|
|
data/lib/dployr/commands/base.rb
CHANGED
|
@@ -17,7 +17,7 @@ module Dployr
|
|
|
17
17
|
@log = Logger.new STDOUT
|
|
18
18
|
@attrs = parse_attributes @options[:attributes]
|
|
19
19
|
@options[:public_ip] = false if !options[:public_ip]
|
|
20
|
-
@provider = options[:provider].upcase
|
|
20
|
+
@provider = options[:provider].upcase if options[:provider]
|
|
21
21
|
create
|
|
22
22
|
get_config
|
|
23
23
|
end
|
|
@@ -34,7 +34,7 @@ module Dployr
|
|
|
34
34
|
def create_compute_client
|
|
35
35
|
begin
|
|
36
36
|
Dployr::Compute.const_get(@provider.to_sym).new @regions
|
|
37
|
-
rescue
|
|
37
|
+
rescue => e
|
|
38
38
|
raise "Provider '#{@provider}' is not supported: #{e}"
|
|
39
39
|
end
|
|
40
40
|
end
|
|
@@ -7,24 +7,20 @@ module Dployr
|
|
|
7
7
|
|
|
8
8
|
def initialize(options, stages)
|
|
9
9
|
super options
|
|
10
|
-
begin
|
|
11
|
-
puts "Connecting to #{@provider}...".yellow
|
|
12
|
-
@client = Dployr::Compute.const_get(@provider.to_sym).new(@options, @p_attrs)
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if @ip
|
|
17
|
-
puts "#{@p_attrs["name"]} found with IP #{@ip}".yellow
|
|
18
|
-
else
|
|
19
|
-
raise "#{@p_attrs["name"]} not found"
|
|
20
|
-
end
|
|
11
|
+
puts "Connecting to #{@provider}...".yellow
|
|
12
|
+
@client = Dployr::Compute.const_get(@provider.to_sym).new @options, @p_attrs
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
puts "Looking for #{@name} in #{@region}...".yellow
|
|
15
|
+
@ip = @client.get_ip
|
|
16
|
+
if @ip
|
|
17
|
+
puts "#{@p_attrs["name"]} found with IP #{@ip}".yellow
|
|
18
|
+
else
|
|
19
|
+
raise "#{@p_attrs["name"]} not found"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
stages.each do |stage|
|
|
23
|
+
Dployr::Scripts::Hook.new @ip, @config, stage
|
|
28
24
|
end
|
|
29
25
|
end
|
|
30
26
|
|
data/lib/dployr/commands/info.rb
CHANGED
|
@@ -7,17 +7,13 @@ module Dployr
|
|
|
7
7
|
|
|
8
8
|
def initialize(options)
|
|
9
9
|
super options
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
end
|
|
18
|
-
rescue Exception => e
|
|
19
|
-
self.log.error e
|
|
20
|
-
exit 1
|
|
10
|
+
|
|
11
|
+
@client = Dployr::Compute.const_get(@provider.to_sym).new(@options, @p_attrs)
|
|
12
|
+
@info = @client.get_info
|
|
13
|
+
if @info
|
|
14
|
+
puts @info.attributes.to_yaml
|
|
15
|
+
else
|
|
16
|
+
raise "#{@p_attrs["name"]} not found"
|
|
21
17
|
end
|
|
22
18
|
end
|
|
23
19
|
|
|
@@ -7,23 +7,19 @@ module Dployr
|
|
|
7
7
|
|
|
8
8
|
def initialize(options, action)
|
|
9
9
|
super options
|
|
10
|
-
begin
|
|
11
|
-
puts "Connecting to #{@provider}...".yellow
|
|
12
|
-
@client = Dployr::Compute.const_get(@provider.to_sym).new(@options, @p_attrs)
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if @ip
|
|
17
|
-
puts "#{@p_attrs["name"]} found with IP #{@ip}".yellow
|
|
18
|
-
else
|
|
19
|
-
raise "#{@p_attrs["name"]} not found"
|
|
20
|
-
end
|
|
11
|
+
puts "Connecting to #{@provider}...".yellow
|
|
12
|
+
@client = Dployr::Compute.const_get(@provider.to_sym).new(@options, @p_attrs)
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
puts "Looking for #{@p_attrs["name"]} in #{@options[:region]}...".yellow
|
|
15
|
+
@ip = @client.get_ip
|
|
16
|
+
if @ip
|
|
17
|
+
puts "#{@p_attrs["name"]} found with IP #{@ip}".yellow
|
|
18
|
+
else
|
|
19
|
+
raise "#{@p_attrs["name"]} not found"
|
|
26
20
|
end
|
|
21
|
+
|
|
22
|
+
Dployr::Scripts::Default_Hooks.new @ip, @config, action, self
|
|
27
23
|
end
|
|
28
24
|
|
|
29
25
|
def action
|
data/lib/dployr/commands/ssh.rb
CHANGED
|
@@ -8,24 +8,19 @@ module Dployr
|
|
|
8
8
|
|
|
9
9
|
def initialize(options)
|
|
10
10
|
super options
|
|
11
|
-
begin
|
|
12
|
-
puts "Connecting to #{@provider}...".yellow
|
|
13
|
-
@client = Dployr::Compute.const_get(@provider.to_sym).new(@options, @p_attrs)
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if @ip
|
|
18
|
-
puts "#{@p_attrs["name"]} found with IP #{@ip}".yellow
|
|
19
|
-
else
|
|
20
|
-
raise "#{@p_attrs["name"]} not found"
|
|
21
|
-
end
|
|
12
|
+
puts "Connecting to #{@provider}...".yellow
|
|
13
|
+
@client = Dployr::Compute.const_get(@provider.to_sym).new @options, @p_attrs
|
|
22
14
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
puts "Looking for #{@p_attrs["name"]} in #{@options[:region]}...".yellow
|
|
16
|
+
@ip = @client.get_ip
|
|
17
|
+
if @ip
|
|
18
|
+
puts "#{@p_attrs["name"]} found with IP #{@ip}".yellow
|
|
19
|
+
else
|
|
20
|
+
raise "#{@p_attrs["name"]} not found"
|
|
28
21
|
end
|
|
22
|
+
|
|
23
|
+
Dployr::Scripts::Ssh.new @ip, @config
|
|
29
24
|
end
|
|
30
25
|
|
|
31
26
|
end
|
|
@@ -6,17 +6,18 @@ module Dployr
|
|
|
6
6
|
|
|
7
7
|
def initialize(options)
|
|
8
8
|
super options
|
|
9
|
-
begin
|
|
10
|
-
puts "Connecting to #{@provider}...".yellow
|
|
11
|
-
@client = Dployr::Compute.const_get(@provider.to_sym).new(@options, @p_attrs)
|
|
12
9
|
|
|
10
|
+
puts "Connecting to #{@provider}...".yellow
|
|
11
|
+
@client = Dployr::Compute.const_get(@provider.to_sym).new @options, @p_attrs
|
|
12
|
+
|
|
13
|
+
if @p_attrs["type"] == "network"
|
|
14
|
+
puts "Creating network in #{@options[:provider]}: #{@options[:region]}...".yellow
|
|
15
|
+
@network = @client.create_network(@p_attrs["name"], @p_attrs["private_net"], @p_attrs["firewalls"], [])
|
|
16
|
+
else
|
|
13
17
|
puts "Looking for #{@p_attrs["name"]} in #{@options[:region]}...".yellow
|
|
14
18
|
@ip = @client.get_ip
|
|
15
19
|
|
|
16
20
|
Dployr::Scripts::Default_Hooks.new @ip, @config, "start", self
|
|
17
|
-
rescue Exception => e
|
|
18
|
-
@log.error e
|
|
19
|
-
exit 1
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -7,12 +7,15 @@ module Dployr
|
|
|
7
7
|
|
|
8
8
|
def initialize(options, action)
|
|
9
9
|
super options
|
|
10
|
-
begin
|
|
11
|
-
@action = action
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
@action = action
|
|
12
|
+
puts "Connecting to #{@provider}...".yellow
|
|
13
|
+
@client = Dployr::Compute.const_get(@provider.to_sym).new @options, @p_attrs
|
|
15
14
|
|
|
15
|
+
if @p_attrs["type"] == "network"
|
|
16
|
+
puts "Destroying network in #{@options[:provider]}: #{@options[:region]}...".yellow
|
|
17
|
+
@network = @client.delete_network(@p_attrs["name"], @p_attrs["private_net"], @p_attrs["firewalls"], [])
|
|
18
|
+
else
|
|
16
19
|
puts "Looking for #{@p_attrs["name"]} in #{@options[:region]}...".yellow
|
|
17
20
|
@ip = @client.get_ip
|
|
18
21
|
if @ip
|
|
@@ -22,15 +25,13 @@ module Dployr
|
|
|
22
25
|
end
|
|
23
26
|
|
|
24
27
|
Dployr::Scripts::Default_Hooks.new @ip, @config, action, self
|
|
25
|
-
rescue Exception => e
|
|
26
|
-
@log.error e
|
|
27
|
-
exit 1
|
|
28
28
|
end
|
|
29
|
+
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
def action
|
|
32
33
|
puts "#{@action.capitalize}ing #{@p_attrs["name"]} in #{@options[:region]}...".yellow
|
|
33
|
-
@client.send
|
|
34
|
+
@client.send @action.to_sym
|
|
34
35
|
puts "#{@p_attrs["name"]} #{@action}ed sucesfully".yellow
|
|
35
36
|
@ip
|
|
36
37
|
end
|
data/lib/dployr/compute/aws.rb
CHANGED
|
@@ -4,38 +4,38 @@ require 'dployr/compute/common'
|
|
|
4
4
|
module Dployr
|
|
5
5
|
module Compute
|
|
6
6
|
class AWS
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
include Dployr::Compute::Common
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
def initialize(options, attrs)
|
|
11
11
|
@aws_options = {
|
|
12
12
|
region: options[:region][0..-2],
|
|
13
13
|
provider: 'AWS',
|
|
14
|
-
aws_access_key_id: ENV["AWS_ACCESS_KEY"],
|
|
15
|
-
aws_secret_access_key: ENV["AWS_SECRET_KEY"],
|
|
14
|
+
aws_access_key_id: (attrs["aws_access_key"] or ENV["AWS_ACCESS_KEY"]),
|
|
15
|
+
aws_secret_access_key: (attrs["aws_secret_key"] or ENV["AWS_SECRET_KEY"]),
|
|
16
16
|
}
|
|
17
17
|
@compute = Fog::Compute.new @aws_options
|
|
18
18
|
@attrs = attrs
|
|
19
19
|
@options = options
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def get_ip
|
|
23
|
-
instance = get_instance
|
|
22
|
+
def get_ip
|
|
23
|
+
instance = get_instance ["running"] # TODO: add starting states
|
|
24
24
|
if instance
|
|
25
25
|
if @options[:public_ip]
|
|
26
|
-
|
|
26
|
+
instance.public_ip_address
|
|
27
27
|
else
|
|
28
|
-
|
|
28
|
+
instance.private_ip_address
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
|
-
|
|
33
|
-
def get_info
|
|
34
|
-
get_instance
|
|
32
|
+
|
|
33
|
+
def get_info
|
|
34
|
+
get_instance ["running", "stopped", "stopping"]
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def destroy
|
|
38
|
-
instance = get_instance
|
|
37
|
+
def destroy
|
|
38
|
+
instance = get_instance ["running", "stopped", "stopping"]
|
|
39
39
|
if instance
|
|
40
40
|
instance.destroy
|
|
41
41
|
else
|
|
@@ -43,8 +43,8 @@ module Dployr
|
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
def halt
|
|
47
|
-
instance = get_instance
|
|
46
|
+
def halt
|
|
47
|
+
instance = get_instance ["running"]
|
|
48
48
|
if instance
|
|
49
49
|
instance.stop
|
|
50
50
|
else
|
|
@@ -52,8 +52,8 @@ module Dployr
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
def start
|
|
56
|
-
server = get_instance
|
|
55
|
+
def start
|
|
56
|
+
server = get_instance ["stopped", "stopping"]
|
|
57
57
|
if server
|
|
58
58
|
puts "Starting stopped instance for #{@attrs["name"]} in #{@options[:region]}...".yellow
|
|
59
59
|
server.start
|
|
@@ -69,17 +69,17 @@ module Dployr
|
|
|
69
69
|
tags: { Name: @attrs["name"] }
|
|
70
70
|
}
|
|
71
71
|
puts options.to_yaml
|
|
72
|
-
server = @compute.servers.create
|
|
72
|
+
server = @compute.servers.create options
|
|
73
73
|
end
|
|
74
74
|
print "Wait for instance to get online".yellow
|
|
75
75
|
server.wait_for { print ".".yellow; ready? }
|
|
76
76
|
print "\n"
|
|
77
|
-
elastic_ip
|
|
78
|
-
wait_ssh
|
|
77
|
+
elastic_ip server
|
|
78
|
+
wait_ssh @attrs, server, @options[:public_ip]
|
|
79
79
|
end
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
private
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
def get_instance(states)
|
|
84
84
|
servers = @compute.servers.all
|
|
85
85
|
servers.each do |instance|
|
|
@@ -89,21 +89,21 @@ module Dployr
|
|
|
89
89
|
end
|
|
90
90
|
nil
|
|
91
91
|
end
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
def elastic_ip(server)
|
|
94
94
|
if @attrs["public_ip"]
|
|
95
95
|
if @attrs["public_ip"] == "new"
|
|
96
96
|
puts "Creating new elastic ip...".yellow
|
|
97
|
-
response = @compute.allocate_address
|
|
97
|
+
response = @compute.allocate_address server.vpc_id
|
|
98
98
|
allocation_id = response[:body]["allocationId"]
|
|
99
99
|
@attrs["public_ip"] = response[:body]["publicIp"]
|
|
100
100
|
else
|
|
101
101
|
puts "Looking for elastic ip #{@attrs["public_ip"]}...".yellow
|
|
102
|
-
eip = @compute.addresses.get
|
|
102
|
+
eip = @compute.addresses.get @attrs["public_ip"]
|
|
103
103
|
allocation_id = eip.allocation_id
|
|
104
104
|
end
|
|
105
105
|
puts "Associating elastic ip #{@attrs["public_ip"]}...".yellow
|
|
106
|
-
@compute.associate_address
|
|
106
|
+
@compute.associate_address server.id, nil, nil, allocation_id
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
109
|
|
|
@@ -3,16 +3,17 @@ require 'net/ssh'
|
|
|
3
3
|
module Dployr
|
|
4
4
|
module Compute
|
|
5
5
|
module Common
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
module_function
|
|
8
8
|
|
|
9
9
|
def wait_ssh(attrs, server, use_public_ip)
|
|
10
10
|
if use_public_ip
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
@ip = server.public_ip_address
|
|
12
|
+
else
|
|
13
|
+
@ip = server.private_ip_address
|
|
14
|
+
end
|
|
15
15
|
print "Wait for ssh (#{@ip}) to get ready...".yellow
|
|
16
|
+
|
|
16
17
|
while true
|
|
17
18
|
begin
|
|
18
19
|
Net::SSH.start(@ip, attrs["username"], :keys => attrs["private_key_path"]) do |ssh|
|
|
@@ -26,7 +27,6 @@ module Dployr
|
|
|
26
27
|
end
|
|
27
28
|
print "\n"
|
|
28
29
|
end
|
|
29
|
-
|
|
30
30
|
|
|
31
31
|
end
|
|
32
32
|
end
|
data/lib/dployr/compute/gce.rb
CHANGED
|
@@ -6,35 +6,35 @@ module Dployr
|
|
|
6
6
|
class GCE
|
|
7
7
|
|
|
8
8
|
include Dployr::Compute::Common
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
def initialize(options, attrs)
|
|
11
11
|
@gce_options = {
|
|
12
12
|
provider: 'Google',
|
|
13
|
-
google_project: ENV["GOOGLE_PROJECT_ID"],
|
|
14
|
-
google_client_email: ENV["GOOGLE_CLIENT_EMAIL"],
|
|
15
|
-
google_key_location: ENV["GOOGLE_KEY_LOCATION"],
|
|
13
|
+
google_project: (attrs["google_project_id"] or ENV["GOOGLE_PROJECT_ID"]),
|
|
14
|
+
google_client_email: (attrs["google_client_email"] or ENV["GOOGLE_CLIENT_EMAIL"]),
|
|
15
|
+
google_key_location: (attrs["google_key_location"] or ENV["GOOGLE_KEY_LOCATION"]),
|
|
16
16
|
}
|
|
17
17
|
@compute = Fog::Compute.new @gce_options
|
|
18
18
|
@attrs = attrs
|
|
19
19
|
@options = options
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def get_ip
|
|
22
|
+
def get_ip
|
|
23
23
|
instance = get_instance(["PROVISIONING", "STAGING", "RUNNING"])
|
|
24
24
|
if instance
|
|
25
25
|
if @options[:public_ip]
|
|
26
|
-
|
|
26
|
+
instance.public_ip_address
|
|
27
27
|
else
|
|
28
|
-
|
|
28
|
+
instance.private_ip_address
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
|
-
|
|
33
|
-
def get_info
|
|
32
|
+
|
|
33
|
+
def get_info
|
|
34
34
|
get_instance(["RUNNING", "STOPPED"])
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def destroy
|
|
37
|
+
def destroy
|
|
38
38
|
instance = get_instance(["RUNNING", "STOPPED"])
|
|
39
39
|
if instance
|
|
40
40
|
puts "Destroying instance #{@attrs["name"]}...".yellow
|
|
@@ -47,12 +47,12 @@ module Dployr
|
|
|
47
47
|
# gdisk = @compute.disks.get(disk["deviceName"])
|
|
48
48
|
# gdisk.destroy
|
|
49
49
|
# end
|
|
50
|
-
return
|
|
50
|
+
return
|
|
51
51
|
end
|
|
52
52
|
raise "Instance #{@attrs["name"]} not found"
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
def halt
|
|
55
|
+
def halt
|
|
56
56
|
instance = get_instance(["RUNNING"])
|
|
57
57
|
if instance
|
|
58
58
|
instance.disks.each do |disk|
|
|
@@ -60,28 +60,29 @@ module Dployr
|
|
|
60
60
|
raise "Cannot halt instance with autoDelete disks"
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
|
-
|
|
63
|
+
instance.destroy
|
|
64
|
+
else
|
|
65
|
+
raise "Instance #{@attrs["name"]} not found"
|
|
64
66
|
end
|
|
65
|
-
raise "Instance #{@attrs["name"]} not found"
|
|
66
67
|
end
|
|
67
68
|
|
|
68
|
-
def start
|
|
69
|
-
external_ip
|
|
70
|
-
server = get_instance
|
|
69
|
+
def start
|
|
70
|
+
external_ip
|
|
71
|
+
server = get_instance ["STOPPED"]
|
|
71
72
|
if server
|
|
72
73
|
puts "Starting stopped instance for #{@attrs["name"]} in #{@options[:region]}...".yellow
|
|
73
74
|
server.start
|
|
74
75
|
else
|
|
75
76
|
puts "Creating boot disk...".yellow
|
|
76
|
-
disks = create_disk
|
|
77
|
+
disks = create_disk
|
|
77
78
|
if defined? @attrs["autodelete_disk"]
|
|
78
79
|
autodelete_disk = @attrs["autodelete_disk"]
|
|
79
80
|
else
|
|
80
81
|
autodelete_disk = false
|
|
81
82
|
end
|
|
82
|
-
|
|
83
|
+
|
|
83
84
|
puts "Creating new instance for #{@attrs["name"]} in #{@options[:region]}...".yellow
|
|
84
|
-
|
|
85
|
+
|
|
85
86
|
start_options = {
|
|
86
87
|
name: @attrs["name"],
|
|
87
88
|
zone_name: @options[:region],
|
|
@@ -93,32 +94,59 @@ module Dployr
|
|
|
93
94
|
puts start_options.to_yaml
|
|
94
95
|
server = @compute.servers.create(start_options)
|
|
95
96
|
end
|
|
97
|
+
|
|
96
98
|
print "Wait for instance to get online".yellow
|
|
97
99
|
server.wait_for { print ".".yellow; ready? }
|
|
98
100
|
print "\n"
|
|
99
|
-
wait_ssh
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
wait_ssh @attrs, server, @options[:public_ip]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def create_network(network_name, network_range, firewalls, routes)
|
|
105
|
+
create_subnet(network_name, network_range)
|
|
106
|
+
|
|
107
|
+
if firewalls.respond_to?("each")
|
|
108
|
+
firewalls.each do |key, value|
|
|
109
|
+
add_firewall(key , network_name, value["address"], value["protocol"], value["port"])
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def delete_network(network_name, network_range, firewalls, routes)
|
|
115
|
+
if exists("network", network_name)
|
|
116
|
+
delete_routes(routes)
|
|
117
|
+
|
|
118
|
+
if firewalls.respond_to?("each")
|
|
119
|
+
firewalls.each do |key, value|
|
|
120
|
+
delete_firewall(key)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
delete_subnet(network_name)
|
|
125
|
+
else
|
|
126
|
+
puts "\tNetwork #{network_name} not found. Nothing to delete!"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
102
130
|
private
|
|
103
|
-
|
|
104
|
-
def external_ip
|
|
131
|
+
|
|
132
|
+
def external_ip
|
|
105
133
|
if @attrs["public_ip"] == "new"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
end
|
|
115
|
-
puts "Waiting for ip to be ready...".yellow
|
|
116
|
-
sleep 1
|
|
134
|
+
puts "Looking for previous public_ip...".yellow
|
|
135
|
+
ip = @compute.insert_address(@attrs["name"], @options[:region][0..-3])
|
|
136
|
+
while true
|
|
137
|
+
ip = @compute.get_address(@attrs["name"], @options[:region][0..-3])
|
|
138
|
+
if ip[:body]["address"]
|
|
139
|
+
@attrs["public_ip"].replace ip[:body]["address"]
|
|
140
|
+
puts "Using public_ip #{@attrs["public_ip"]}".yellow
|
|
141
|
+
break
|
|
117
142
|
end
|
|
143
|
+
puts "Waiting for ip to be ready...".yellow
|
|
144
|
+
sleep 1
|
|
118
145
|
end
|
|
146
|
+
end
|
|
119
147
|
end
|
|
120
|
-
|
|
121
|
-
def create_disk
|
|
148
|
+
|
|
149
|
+
def create_disk
|
|
122
150
|
disk = @compute.disks.get(@attrs["name"])
|
|
123
151
|
if disk != nil
|
|
124
152
|
puts "Disk #{@attrs["name"]} already created. Reusing it.".yellow
|
|
@@ -131,9 +159,9 @@ module Dployr
|
|
|
131
159
|
zone_name: @options[:region],
|
|
132
160
|
source_image: @attrs["image_name"]
|
|
133
161
|
)
|
|
134
|
-
|
|
162
|
+
|
|
135
163
|
disk.wait_for { disk.ready? }
|
|
136
|
-
|
|
164
|
+
disk
|
|
137
165
|
end
|
|
138
166
|
end
|
|
139
167
|
|
|
@@ -145,7 +173,93 @@ module Dployr
|
|
|
145
173
|
return instance
|
|
146
174
|
end
|
|
147
175
|
end
|
|
148
|
-
|
|
176
|
+
nil
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def create_subnet(network_name, private_net)
|
|
180
|
+
if ! exists("network", network_name)
|
|
181
|
+
@compute.insert_network(network_name, private_net)
|
|
182
|
+
puts "\tNetwork #{network_name} created"
|
|
183
|
+
else
|
|
184
|
+
puts "\tNetwork #{network_name} already exists. Nothing to create!"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def add_firewall(fw_name, network_name, source_range, ip_protocol, allowed_ports)
|
|
189
|
+
allowed = [
|
|
190
|
+
{
|
|
191
|
+
IPProtocol: "#{ip_protocol}",
|
|
192
|
+
ports: ["#{allowed_ports}"]
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
options = {}
|
|
196
|
+
options[:source_ranges] = source_range
|
|
197
|
+
|
|
198
|
+
@compute.insert_firewall(fw_name, allowed, network_name, options)
|
|
199
|
+
puts "\tFirewall #{fw_name} created"
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def exists(type, name)
|
|
203
|
+
if type == "network"
|
|
204
|
+
list = @compute.list_networks.data[:body]
|
|
205
|
+
elsif type == "route"
|
|
206
|
+
list = @compute.list_routes.data[:body]
|
|
207
|
+
else
|
|
208
|
+
list = @compute.list_firewalls.data[:body]
|
|
209
|
+
puts "name #{name}"
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
items = list["items"]
|
|
213
|
+
if items.respond_to?("each")
|
|
214
|
+
items.each do |item|
|
|
215
|
+
if item["name"] == name
|
|
216
|
+
return true
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
return false
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def add_route(route_name, network_name, dest_range, priority, vm_name)
|
|
225
|
+
# Get VM url --> https://www.googleapis.com/compute/..../vm_name
|
|
226
|
+
server = @compute.get_server(vm_name,"europe-west1-a").data[:body]
|
|
227
|
+
url_next_hop = server["selfLink"]
|
|
228
|
+
|
|
229
|
+
network = @compute.get_network(network_name).data[:body]
|
|
230
|
+
network_url = network["selfLink"]
|
|
231
|
+
|
|
232
|
+
options = {}
|
|
233
|
+
options[:description] = ""
|
|
234
|
+
options[:next_hop_instance] = "#{url_next_hop}"
|
|
235
|
+
# options[:next_hop_gateway] = ""
|
|
236
|
+
# options[:next_hop_ip] = ""
|
|
237
|
+
|
|
238
|
+
@compute.insert_route(route_name, network_url, dest_range, priority, options)
|
|
239
|
+
puts "\tRoute #{route_name} created"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def delete_routes(routes)
|
|
243
|
+
if routes.respond_to?("each")
|
|
244
|
+
routes.each do |route|
|
|
245
|
+
if gce_exist("route", route)
|
|
246
|
+
@compute.delete_route(route)
|
|
247
|
+
puts "\tRoute #{route} deleted"
|
|
248
|
+
else
|
|
249
|
+
puts "\tRoute #{route} not found. Nothing to delete!"
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def delete_firewall(key)
|
|
256
|
+
@compute.delete_firewall(key)
|
|
257
|
+
puts "\tFirewall #{key} deleted"
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def delete_subnet(network_name)
|
|
261
|
+
@compute.delete_network(network_name)
|
|
262
|
+
puts "\tNetwork #{network_name} deleted"
|
|
149
263
|
end
|
|
150
264
|
|
|
151
265
|
end
|
|
@@ -14,15 +14,15 @@ module Dployr
|
|
|
14
14
|
def start
|
|
15
15
|
command = @script["local_path"]
|
|
16
16
|
arguments = @script["args"]
|
|
17
|
+
arguments = arguments.join ' ' if arguments.is_a? Array
|
|
17
18
|
|
|
18
19
|
puts "Running local script '#{command} #{arguments}'".yellow
|
|
19
20
|
total_command = command
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
result = system(total_command)
|
|
21
|
+
total_command = command + ' ' + arguments if arguments
|
|
22
|
+
|
|
23
|
+
result = system total_command
|
|
24
24
|
if result == false
|
|
25
|
-
raise "Exit code non zero when running local script '#{total_command}'"
|
|
25
|
+
raise "Exit code non zero when running local script '#{total_command}'"
|
|
26
26
|
else
|
|
27
27
|
puts "Local script '#{command} #{arguments}' finished succesfully".yellow
|
|
28
28
|
end
|
data/lib/dployr/scripts/scp.rb
CHANGED
|
@@ -13,8 +13,8 @@ module Dployr
|
|
|
13
13
|
puts "Copying #{source} -> #{target}".yellow
|
|
14
14
|
scp.upload(source, target, :recursive => true, :preserve => true)
|
|
15
15
|
end
|
|
16
|
-
rescue
|
|
17
|
-
raise
|
|
16
|
+
rescue => e
|
|
17
|
+
raise "Cannot copy to remote: #{e}"
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
data/lib/dployr/scripts/shell.rb
CHANGED
|
@@ -20,12 +20,11 @@ module Dployr
|
|
|
20
20
|
Net::SSH.start(@ip, @username, :keys => [@private_key_path]) do |ssh|
|
|
21
21
|
command = @script["remote_path"]
|
|
22
22
|
arguments = @script["args"]
|
|
23
|
+
arguments = arguments.join ' ' if arguments.is_a? Array
|
|
24
|
+
total_command = command
|
|
25
|
+
total_command = command + ' ' + arguments if arguments
|
|
23
26
|
|
|
24
27
|
puts "Running remote script '#{command} #{arguments}'".yellow
|
|
25
|
-
total_command = command
|
|
26
|
-
if arguments
|
|
27
|
-
total_command = command + ' ' + arguments
|
|
28
|
-
end
|
|
29
28
|
result = ssh_exec!(ssh, total_command)
|
|
30
29
|
if result[:exit_code] > 0
|
|
31
30
|
raise "Exit code #{result[:exit_code]} when running script '#{total_command}'".yellow
|
|
@@ -54,7 +53,7 @@ module Dployr
|
|
|
54
53
|
end
|
|
55
54
|
|
|
56
55
|
channel.on_extended_data do |ch,type,data|
|
|
57
|
-
stderr_data+=data
|
|
56
|
+
stderr_data += data
|
|
58
57
|
#print "[#{@host}] #{data}".red
|
|
59
58
|
print "#{data}".red
|
|
60
59
|
end
|
|
@@ -63,7 +62,7 @@ module Dployr
|
|
|
63
62
|
exit_code = data.read_long
|
|
64
63
|
@channel.close
|
|
65
64
|
end
|
|
66
|
-
|
|
65
|
+
|
|
67
66
|
end
|
|
68
67
|
end
|
|
69
68
|
ssh.loop
|
data/lib/dployr/scripts/ssh.rb
CHANGED
data/lib/dployr/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dployr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tomas Aparicio
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2014-05-
|
|
12
|
+
date: 2014-05-07 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: fog
|