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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 84dbc231d29673da035d182bf6198848a4b0bbe1
4
- data.tar.gz: 504c80fb2ea79996efa2b155affc7f1fcced00a6
3
+ metadata.gz: 304f9d5d7f79de110215c48e59f5c3dc39bbe29c
4
+ data.tar.gz: 3fa3639b3f5058161d5fb1b318d217dcfa1c4a78
5
5
  SHA512:
6
- metadata.gz: 8d1d4eb41cf77fc668a7e785a4c6228f9f15ce64add9cc1c434a10311964fe789b21031ef9a09c4930b932878a6962897732f1f3f03d18746e361c155ac90fb2
7
- data.tar.gz: 102f3eb0359b547f595fc64e13cb3ba9db54b27a26101eef0eb27dc2113c75e15d1af101119f1affb0d797fc8f8ab8075bc5663c05307b9ead3e32c2f1c38cee
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
- > **Spoiler! Alpha project. Use it by your own risk**
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 configure your infraestructure and deployment from a
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 only works in Ruby >= `1.9.x`
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', '>= 0.0.3'
36
+ spec.add_dependency 'dployr', '~> 0.0.1'
37
37
  # Gemfile
38
- gem 'dployr', '>= 0.0.3'
38
+ gem 'dployr', '>= 0.0.1'
39
39
  ```
40
40
 
41
- ## Documentation
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
- - Built-in support for defailted instances configuration
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 attrbutes to apply to the current template
70
- - **scripts** `Array|Object`
71
- - **providers** `Object`
72
- - **authentication** `Object` (optional)
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 (YAML)
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
- name: 1
163
- web-server:
164
- attributes:
165
- prefix: zeus-dev
166
- authentication:
167
- private_key_path: ~/.ssh/id_rsa
168
- public_key_path: ~/.ssh/id_rsa.pub
169
- username: ubuntu
170
- providers:
171
- aws:
172
- regions:
173
- attributes:
174
- instance_type: m1.medium
175
- gce:
176
- attributes:
177
- instance_type: m1.large
178
- scripts:
179
- pre-start:
180
- -
181
- args:
182
- - "%{name}"
183
- - "%{type}"
184
- - "%{domain}"
185
- path: ./scripts/pre-start.sh
186
- start:
187
- -
188
- args:
189
- - "%{hydra}"
190
- path: ./scripts/configure.sh
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
 
@@ -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 Exception => e
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
- 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
11
+ puts "Connecting to #{@provider}...".yellow
12
+ @client = Dployr::Compute.const_get(@provider.to_sym).new @options, @p_attrs
21
13
 
22
- stages.each do |stage|
23
- Dployr::Scripts::Hook.new @ip, @config, stage
24
- end
25
- rescue Exception => e
26
- self.log.error e
27
- exit 1
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
 
@@ -7,17 +7,13 @@ module Dployr
7
7
 
8
8
  def initialize(options)
9
9
  super options
10
- begin
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"
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
- 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"
20
- end
11
+ puts "Connecting to #{@provider}...".yellow
12
+ @client = Dployr::Compute.const_get(@provider.to_sym).new(@options, @p_attrs)
21
13
 
22
- Dployr::Scripts::Default_Hooks.new @ip, @config, action, self
23
- rescue Exception => e
24
- @log.error e
25
- exit 1
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
@@ -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
- 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"
21
- end
12
+ puts "Connecting to #{@provider}...".yellow
13
+ @client = Dployr::Compute.const_get(@provider.to_sym).new @options, @p_attrs
22
14
 
23
- Dployr::Scripts::Ssh.new @ip, @config
24
-
25
- rescue Exception => e
26
- self.log.error e
27
- exit 1
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
- puts "Connecting to #{@provider}...".yellow
14
- @client = Dployr::Compute.const_get(@provider.to_sym).new(@options, @p_attrs)
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(@action.to_sym)
34
+ @client.send @action.to_sym
34
35
  puts "#{@p_attrs["name"]} #{@action}ed sucesfully".yellow
35
36
  @ip
36
37
  end
@@ -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(["running"]) # TODO: add starting states
22
+ def get_ip
23
+ instance = get_instance ["running"] # TODO: add starting states
24
24
  if instance
25
25
  if @options[:public_ip]
26
- return instance.public_ip_address
26
+ instance.public_ip_address
27
27
  else
28
- return instance.private_ip_address
28
+ instance.private_ip_address
29
29
  end
30
30
  end
31
31
  end
32
-
33
- def get_info()
34
- get_instance(["running", "stopped", "stopping"])
32
+
33
+ def get_info
34
+ get_instance ["running", "stopped", "stopping"]
35
35
  end
36
36
 
37
- def destroy()
38
- instance = get_instance(["running", "stopped", "stopping"])
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(["running"])
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(["stopped", "stopping"])
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(options)
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(server)
78
- wait_ssh(@attrs, server, @options[:public_ip])
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(server.vpc_id)
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(@attrs["public_ip"])
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(server.id,nil,nil,allocation_id)
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
- @ip = server.public_ip_address
12
- else
13
- @ip = server.private_ip_address
14
- end
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
@@ -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
- return instance.public_ip_address
26
+ instance.public_ip_address
27
27
  else
28
- return instance.private_ip_address
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
- return instance.destroy
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(["STOPPED"])
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(@attrs, server, @options[:public_ip])
100
- end
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
- puts "Looking for previous public_ip...".yellow
107
- ip = @compute.insert_address(@attrs["name"], @options[:region][0..-3])
108
- while true
109
- ip = @compute.get_address(@attrs["name"], @options[:region][0..-3])
110
- if ip[:body]["address"]
111
- @attrs["public_ip"].replace ip[:body]["address"]
112
- puts "Using public_ip #{@attrs["public_ip"]}".yellow
113
- break
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
- return disk
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
- return nil
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
@@ -49,7 +49,7 @@ module Dployr
49
49
  end
50
50
 
51
51
  def add_script(script)
52
- @scripts << script if script.is_a? Hash
52
+ @scripts.merge! script if script.is_a? Hash
53
53
  end
54
54
 
55
55
  def add_provider(name, provider)
@@ -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
- if arguments
21
- total_command = command + ' ' + arguments
22
- end
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}'".yellow
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
@@ -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 Exception => e
17
- raise Error.new "Cannot copy to remote: #{e}"
16
+ rescue => e
17
+ raise "Cannot copy to remote: #{e}"
18
18
  end
19
19
  end
20
20
 
@@ -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
@@ -15,7 +15,7 @@ module Dployr
15
15
 
16
16
  def run
17
17
  puts "ssh -i #{@private_key_path} #{@username}@#{@ip}"
18
- system("ssh -i #{@private_key_path} #{@username}@#{@ip}")
18
+ system "ssh -i #{@private_key_path} #{@username}@#{@ip}"
19
19
  end
20
20
 
21
21
  end
@@ -1,3 +1,3 @@
1
1
  module Dployr
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.8'
3
3
  end
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.7
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-06 00:00:00.000000000 Z
12
+ date: 2014-05-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog