fog 0.2.20 → 0.2.21

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,13 +1,13 @@
1
1
  source 'http://gemcutter.org'
2
2
 
3
3
  gem 'rake'
4
- gem 'excon', '>= 0.1.4'
5
- gem 'formatador', ">= 0.0.10"
4
+ gem 'builder', '>= 0'
5
+ gem 'excon', '>= 0.2.0'
6
+ gem 'formatador', ">= 0.0.15"
6
7
  gem 'json', ">= 0"
7
8
  gem 'mime-types', ">= 0"
8
9
  gem 'net-ssh', ">= 0"
9
- gem 'nokogiri', ">= 0"
10
+ gem 'nokogiri', ">= 1.4.3.1"
10
11
  gem 'rspec', '>= 0'
11
12
  gem 'ruby-hmac', '>= 0'
12
13
  gem 'shindo', '>= 0.1.6'
13
- gem 'builder', '>= 0'
@@ -3,12 +3,12 @@ dependencies:
3
3
  formatador:
4
4
  group:
5
5
  - :default
6
- version: ">= 0.0.10"
6
+ version: ">= 0.0.15"
7
7
  rake:
8
8
  group:
9
9
  - :default
10
10
  version: ">= 0"
11
- ruby-hmac:
11
+ rspec:
12
12
  group:
13
13
  - :default
14
14
  version: ">= 0"
@@ -16,43 +16,43 @@ dependencies:
16
16
  group:
17
17
  - :default
18
18
  version: ">= 0"
19
- rspec:
19
+ ruby-hmac:
20
20
  group:
21
21
  - :default
22
22
  version: ">= 0"
23
- json:
23
+ net-ssh:
24
24
  group:
25
25
  - :default
26
26
  version: ">= 0"
27
- net-ssh:
27
+ json:
28
28
  group:
29
29
  - :default
30
30
  version: ">= 0"
31
31
  excon:
32
32
  group:
33
33
  - :default
34
- version: ">= 0.1.4"
35
- builder:
36
- group:
37
- - :default
38
- version: ">= 0"
34
+ version: ">= 0.2.0"
39
35
  shindo:
40
36
  group:
41
37
  - :default
42
38
  version: ">= 0.1.6"
43
- nokogiri:
39
+ builder:
44
40
  group:
45
41
  - :default
46
42
  version: ">= 0"
43
+ nokogiri:
44
+ group:
45
+ - :default
46
+ version: ">= 1.4.3.1"
47
47
  specs:
48
48
  - rake:
49
49
  version: 0.8.7
50
50
  - builder:
51
51
  version: 2.1.2
52
52
  - excon:
53
- version: 0.1.4
53
+ version: 0.2.0
54
54
  - formatador:
55
- version: 0.0.14
55
+ version: 0.0.15
56
56
  - gestalt:
57
57
  version: 0.0.11
58
58
  - json:
@@ -62,14 +62,14 @@ specs:
62
62
  - net-ssh:
63
63
  version: 2.0.23
64
64
  - nokogiri:
65
- version: 1.4.2
65
+ version: 1.4.3.1
66
66
  - rspec:
67
67
  version: 1.3.0
68
68
  - ruby-hmac:
69
69
  version: 0.4.0
70
70
  - shindo:
71
71
  version: 0.1.6
72
- hash: 8520ed00122d3f78644dafa479a1f96842291e8f
72
+ hash: b335ed8d32bece98ea7a84d858b85cbf21025c82
73
73
  sources:
74
74
  - Rubygems:
75
75
  uri: http://gemcutter.org
@@ -7,8 +7,8 @@ Gem::Specification.new do |s|
7
7
  ## If your rubyforge_project name is different, then edit it and comment out
8
8
  ## the sub! line in the Rakefile
9
9
  s.name = 'fog'
10
- s.version = '0.2.20'
11
- s.date = '2010-07-25'
10
+ s.version = '0.2.21'
11
+ s.date = '2010-07-29'
12
12
  s.rubyforge_project = 'fog'
13
13
 
14
14
  ## Make sure your summary is short. The description may be as long
@@ -42,19 +42,19 @@ Gem::Specification.new do |s|
42
42
 
43
43
  ## List your runtime dependencies here. Runtime dependencies are those
44
44
  ## that are needed for an end user to actually USE your code.
45
- s.add_dependency('excon', '>=0.1.4')
46
- s.add_dependency('formatador', '>=0.0.10')
45
+ s.add_dependency('builder')
46
+ s.add_dependency('excon', '>=0.2.0')
47
+ s.add_dependency('formatador', '>=0.0.15')
47
48
  s.add_dependency('json')
48
49
  s.add_dependency('mime-types')
49
50
  s.add_dependency('net-ssh')
50
- s.add_dependency('nokogiri')
51
+ s.add_dependency('nokogiri', '>=1.4.3.1')
51
52
  s.add_dependency('ruby-hmac')
52
- s.add_dependency('builder')
53
53
 
54
54
  ## List your development dependencies here. Development dependencies are
55
55
  ## those that are only needed during development
56
56
  s.add_development_dependency('rspec')
57
- s.add_development_dependency('shindo')
57
+ s.add_development_dependency('shindo', '0.1.6')
58
58
 
59
59
  ## Leave this section as-is. It will be automatically generated from the
60
60
  ## contents of your Git repository via the gemspec task. DO NOT REMOVE
@@ -248,7 +248,11 @@ Gem::Specification.new do |s|
248
248
  lib/fog/go_grid/requests/grid_image_list.rb
249
249
  lib/fog/go_grid/requests/grid_ip_list.rb
250
250
  lib/fog/go_grid/requests/grid_loadbalancer_list.rb
251
+ lib/fog/go_grid/requests/grid_server_add.rb
252
+ lib/fog/go_grid/requests/grid_server_delete.rb
253
+ lib/fog/go_grid/requests/grid_server_get.rb
251
254
  lib/fog/go_grid/requests/grid_server_list.rb
255
+ lib/fog/go_grid/requests/grid_server_power.rb
252
256
  lib/fog/hmac.rb
253
257
  lib/fog/linode.rb
254
258
  lib/fog/linode/bin.rb
data/lib/fog.rb CHANGED
@@ -41,7 +41,7 @@ require 'fog/vcloud'
41
41
  module Fog
42
42
 
43
43
  unless const_defined?(:VERSION)
44
- VERSION = '0.2.20'
44
+ VERSION = '0.2.21'
45
45
  end
46
46
 
47
47
  module Mock
@@ -12,7 +12,11 @@ module Fog
12
12
  request 'grid_image_list'
13
13
  request 'grid_ip_list'
14
14
  request 'grid_loadbalancer_list'
15
+ request 'grid_server_add'
16
+ request 'grid_server_delete'
17
+ request 'grid_server_get'
15
18
  request 'grid_server_list'
19
+ request 'grid_server_power'
16
20
 
17
21
  class Mock
18
22
  include Collections
@@ -55,6 +59,11 @@ module Fog
55
59
  end
56
60
 
57
61
  def request(params)
62
+ params = {
63
+ :expects => 200,
64
+ :method => 'GET'
65
+ }.merge!(params)
66
+
58
67
  params[:query] ||= {}
59
68
  params[:query].merge!({
60
69
  'api_key' => @go_grid_api_key,
@@ -16,8 +16,6 @@ module Fog
16
16
  # TODO: docs
17
17
  def common_lookup_list(lookup, options={})
18
18
  request(
19
- :expects => 200,
20
- :method => 'GET',
21
19
  :path => 'common/lookup/list',
22
20
  :query => {'lookup' => lookup}.merge!(options)
23
21
  )
@@ -19,8 +19,6 @@ module Fog
19
19
  # TODO: docs
20
20
  def grid_image_list(options={})
21
21
  request(
22
- :expects => 200,
23
- :method => 'GET',
24
22
  :path => 'grid/image/list',
25
23
  :query => options
26
24
  )
@@ -18,8 +18,6 @@ module Fog
18
18
  # TODO: docs
19
19
  def grid_ip_list(options={})
20
20
  request(
21
- :expects => 200,
22
- :method => 'GET',
23
21
  :path => 'grid/ip/list',
24
22
  :query => options
25
23
  )
@@ -16,8 +16,6 @@ module Fog
16
16
  # TODO: docs
17
17
  def grid_loadbalancer_list(options={})
18
18
  request(
19
- :expects => 200,
20
- :method => 'GET',
21
19
  :path => 'grid/loadbalancer/list',
22
20
  :query => options
23
21
  )
@@ -0,0 +1,42 @@
1
+ module Fog
2
+ module GoGrid
3
+ class Real
4
+
5
+ # Create a new server
6
+ #
7
+ # ==== Parameters
8
+ # * 'image'<~String> - image to use, in grid_image_list
9
+ # * 'ip'<~String> - initial public ip for this server
10
+ # * 'name'<~String> - name of the server, 20 or fewer characters
11
+ # * 'server_ram'<~String> - flavor to use, in common_lookup_list('server.ram')
12
+ # * 'options'<~Hash>:
13
+ # * 'description'<~String> - description of this server
14
+ # * 'isSandbox'<~String> - treat this server as image sandbox? in ['true', 'false']
15
+ #
16
+ # ==== Returns
17
+ # * response<~Excon::Response>:
18
+ # * body<~Array>:
19
+ # TODO: docs
20
+ def grid_server_add(image, ip, name, server_ram, options={})
21
+ request(
22
+ :path => 'grid/server/add',
23
+ :query => {
24
+ 'image' => image,
25
+ 'ip' => ip,
26
+ 'name' => name,
27
+ 'server.ram' => server_ram
28
+ }.merge!(options)
29
+ )
30
+ end
31
+
32
+ end
33
+
34
+ class Mock
35
+
36
+ def grid_server_add(image, ip, name, server_ram, options={})
37
+ Fog::Mock.not_implemented
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ module Fog
2
+ module GoGrid
3
+ class Real
4
+
5
+ # Delete a server
6
+ #
7
+ # ==== Parameters
8
+ # * 'server'<~String> - id or name of server to delete
9
+ #
10
+ # ==== Returns
11
+ # * response<~Excon::Response>:
12
+ # * body<~Array>:
13
+ # TODO: docs
14
+ def grid_server_delete(server)
15
+ request(
16
+ :path => 'grid/server/delete',
17
+ :query => {'server' => server}
18
+ )
19
+ end
20
+
21
+ end
22
+
23
+ class Mock
24
+
25
+ def grid_server_delete(server)
26
+ Fog::Mock.not_implemented
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ module Fog
2
+ module GoGrid
3
+ class Real
4
+
5
+ # Get one or more servers by name
6
+ #
7
+ # ==== Parameters
8
+ # * 'server'<~String> - id or name of server(s) to lookup
9
+ #
10
+ # ==== Returns
11
+ # * response<~Excon::Response>:
12
+ # * body<~Array>:
13
+ # TODO: docs
14
+ def grid_server_get(servers)
15
+ request(
16
+ :path => 'grid/server/get',
17
+ :query => {'server' => [*servers]}
18
+ )
19
+ end
20
+
21
+ end
22
+
23
+ class Mock
24
+
25
+ def grid_server_get(servers)
26
+ Fog::Mock.not_implemented
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -18,8 +18,6 @@ module Fog
18
18
  # TODO: docs
19
19
  def grid_server_list(options={})
20
20
  request(
21
- :expects => 200,
22
- :method => 'GET',
23
21
  :path => 'grid/server/list',
24
22
  :query => options
25
23
  )
@@ -0,0 +1,32 @@
1
+ module Fog
2
+ module GoGrid
3
+ class Real
4
+
5
+ # Start, Stop or Restart a server
6
+ #
7
+ # ==== Parameters
8
+ # * 'server'<~String> - id or name of server to power
9
+ # * 'power'<~String> - power operation, in ['restart', 'start', 'stop']
10
+ #
11
+ # ==== Returns
12
+ # * response<~Excon::Response>:
13
+ # * body<~Array>:
14
+ # TODO: docs
15
+ def grid_server_delete(server, power)
16
+ request(
17
+ :path => 'grid/server/power',
18
+ :query => {'server' => server}
19
+ )
20
+ end
21
+
22
+ end
23
+
24
+ class Mock
25
+
26
+ def grid_server_delete(server)
27
+ Fog::Mock.not_implemented
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -34,6 +34,26 @@ module Fog
34
34
  end
35
35
  end
36
36
 
37
+ def monitor=(new_monitor = {})
38
+ if new_monitor.nil?
39
+ @monitor = nil
40
+ elsif new_monitor.is_a?(Hash)
41
+ @monitor = {}
42
+ @monitor[:type] = new_monitor[:MonitorType] || new_monitor[:type]
43
+ @monitor[:url_send_string] = new_monitor[:UrlSendString] || new_monitor[:url_send_string]
44
+ @monitor[:http_headers] = new_monitor[:HttpHeader] || new_monitor[:http_headers]
45
+ @monitor[:http_headers] = @monitor[:http_headers].split("\n") unless @monitor[:http_headers].is_a?(Array)
46
+ @monitor[:receive_string] = new_monitor[:ReceiveString] || new_monitor[:receive_string]
47
+ @monitor[:interval] = new_monitor[:Interval] || new_monitor[:interval]
48
+ @monitor[:response_timeout] = new_monitor[:ResponseTimeOut] || new_monitor[:response_timeout]
49
+ @monitor[:downtime] = new_monitor[:DownTime] || new_monitor[:downtime]
50
+ @monitor[:retries] = new_monitor[:Retries] || new_monitor[:retries]
51
+ @monitor[:is_enabled] = new_monitor[:IsEnabled] || new_monitor[:is_enabled]
52
+ else
53
+ raise RuntimeError.new("monitor needs to either be nil or a Hash")
54
+ end
55
+ end
56
+
37
57
  def nodes
38
58
  @nodes ||= Fog::Vcloud::Terremark::Ecloud::Nodes.new( :connection => connection, :href => href + "/nodeServices" )
39
59
  end
@@ -41,8 +61,9 @@ module Fog
41
61
  private
42
62
 
43
63
  def _compose_service_data
64
+ #For some reason inject didn't work
44
65
  service_data = {}
45
- self.class.attributes.select{ |attribute| !send(attribute).nil? }.each { |attribute| service_data[attribute] = send(attribute).to_s }
66
+ self.class.attributes.select{ |attribute| !send(attribute).nil? }.each { |attribute| service_data[attribute] = send(attribute) }
46
67
  service_data
47
68
  end
48
69
 
@@ -15,17 +15,23 @@ module Fog
15
15
  builder.Enabled(service_data[:enabled])
16
16
  builder.Description(service_data[:description])
17
17
  builder.RedirectURL(service_data[:redirect_url])
18
- #builder.Monitor {
19
- # builder.MonitorType {}
20
- # builder.UrlSendString {}
21
- # builder.HttpHeader {}
22
- # builder.ReceiveString {}
23
- # builder.Interval {}
24
- # builder.ResponseTimeOut {}
25
- # builder.DownTime {}
26
- # builder.Retries {}
27
- # builder.IsEnabled {}
28
- #}
18
+ if monitor = service_data[:monitor]
19
+ generate_monitor_section(builder,monitor)
20
+ end
21
+ }
22
+ end
23
+
24
+ def generate_monitor_section(builder, monitor)
25
+ builder.Monitor {
26
+ builder.MonitorType(monitor[:type])
27
+ builder.UrlSendString(monitor[:url_send_string])
28
+ builder.HttpHeader(monitor[:http_headers].join("\n"))
29
+ builder.ReceiveString(monitor[:receive_string])
30
+ builder.Interval(monitor[:interval])
31
+ builder.ResponseTimeOut(monitor[:response_timeout])
32
+ builder.DownTime(monitor[:downtime])
33
+ builder.Retries(monitor[:retries])
34
+ builder.IsEnabled(monitor[:is_enabled])
29
35
  }
30
36
  end
31
37
 
@@ -39,8 +45,55 @@ module Fog
39
45
  end
40
46
  end
41
47
 
48
+ def validate_internet_service_monitor(monitor)
49
+ #FIXME: Refactor this type of function into something generic
50
+ required_opts = [:type, :url_send_string, :http_headers, :receive_string, :is_enabled]
51
+
52
+ unless required_opts.all? { |opt| monitor.keys.include?(opt) && monitor[opt] }
53
+ raise ArgumentError.new("Required Monitor data missing: #{(required_opts - monitor.keys).map(&:inspect).join(", ")}")
54
+ end
55
+
56
+ unless ['HTTP','ECV'].include?(monitor[:type])
57
+ raise ArgumentError.new("Supported monitor types are: ECV & HTTP")
58
+ end
59
+
60
+ unless monitor[:http_headers].is_a?(Array) || monitor[:http_headers].is_a?(String)
61
+ raise ArgumentError.new("Monitor :http_headers must be a String or Array")
62
+ end
63
+
64
+ unless [true, false, "true", "false"].include?(monitor[:is_enabled])
65
+ raise ArgumentError.new("Monitor :is_enabled must be true or false")
66
+ end
67
+ end
68
+
69
+ def ensure_monitor_defaults!(monitor)
70
+ if monitor[:http_headers].is_a?(String)
71
+ monitor[:http_headers] = [ monitor[:http_headers] ]
72
+ end
73
+
74
+ unless monitor[:retries]
75
+ monitor[:retries] = 3
76
+ end
77
+
78
+ unless monitor[:response_timeout]
79
+ monitor[:response_timeout] = 2
80
+ end
81
+
82
+ unless monitor[:down_time]
83
+ monitor[:down_time] = 30
84
+ end
85
+
86
+ unless monitor[:interval]
87
+ monitor[:interval] = 5
88
+ end
89
+ end
90
+
42
91
  def add_internet_service(internet_services_uri, service_data)
43
92
  validate_internet_service_data(service_data)
93
+ if monitor = service_data[:monitor]
94
+ validate_internet_service_monitor(monitor)
95
+ ensure_monitor_defaults!(monitor)
96
+ end
44
97
 
45
98
  request(
46
99
  :body => generate_internet_service_request(service_data),
@@ -64,7 +117,7 @@ module Fog
64
117
  validate_internet_service_data(service_data)
65
118
 
66
119
  internet_services_uri = ensure_unparsed(internet_services_uri)
67
-
120
+
68
121
  if ip = ip_from_uri(internet_services_uri)
69
122
  id = rand(1000)
70
123
  new_service = service_data.merge!( { :href => Fog::Vcloud::Terremark::Ecloud::Mock.internet_service_href( { :id => id } ),
@@ -22,6 +22,9 @@ module Fog
22
22
  builder.Href(ip_address_data[:href].to_s)
23
23
  builder.Name(ip_address_data[:name])
24
24
  }
25
+ if monitor = service_data[:monitor]
26
+ generate_monitor_section(builder,monitor)
27
+ end
25
28
  }
26
29
  end
27
30
 
@@ -37,6 +40,11 @@ module Fog
37
40
 
38
41
  validate_public_ip_address_data(ip_address_data)
39
42
 
43
+ if monitor = service_data[:monitor]
44
+ validate_internet_service_monitor(monitor)
45
+ ensure_monitor_defaults!(monitor)
46
+ end
47
+
40
48
  request(
41
49
  :body => generate_internet_service_response(service_data, ip_address_data),
42
50
  :expects => 200,
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 20
9
- version: 0.2.20
8
+ - 21
9
+ version: 0.2.21
10
10
  platform: ruby
11
11
  authors:
12
12
  - geemus (Wesley Beary)
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-25 00:00:00 -07:00
17
+ date: 2010-07-29 00:00:00 -07:00
18
18
  default_executable: fog
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: excon
21
+ name: builder
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
@@ -26,13 +26,11 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  segments:
28
28
  - 0
29
- - 1
30
- - 4
31
- version: 0.1.4
29
+ version: "0"
32
30
  type: :runtime
33
31
  version_requirements: *id001
34
32
  - !ruby/object:Gem::Dependency
35
- name: formatador
33
+ name: excon
36
34
  prerelease: false
37
35
  requirement: &id002 !ruby/object:Gem::Requirement
38
36
  requirements:
@@ -40,13 +38,13 @@ dependencies:
40
38
  - !ruby/object:Gem::Version
41
39
  segments:
42
40
  - 0
41
+ - 2
43
42
  - 0
44
- - 10
45
- version: 0.0.10
43
+ version: 0.2.0
46
44
  type: :runtime
47
45
  version_requirements: *id002
48
46
  - !ruby/object:Gem::Dependency
49
- name: json
47
+ name: formatador
50
48
  prerelease: false
51
49
  requirement: &id003 !ruby/object:Gem::Requirement
52
50
  requirements:
@@ -54,11 +52,13 @@ dependencies:
54
52
  - !ruby/object:Gem::Version
55
53
  segments:
56
54
  - 0
57
- version: "0"
55
+ - 0
56
+ - 15
57
+ version: 0.0.15
58
58
  type: :runtime
59
59
  version_requirements: *id003
60
60
  - !ruby/object:Gem::Dependency
61
- name: mime-types
61
+ name: json
62
62
  prerelease: false
63
63
  requirement: &id004 !ruby/object:Gem::Requirement
64
64
  requirements:
@@ -70,7 +70,7 @@ dependencies:
70
70
  type: :runtime
71
71
  version_requirements: *id004
72
72
  - !ruby/object:Gem::Dependency
73
- name: net-ssh
73
+ name: mime-types
74
74
  prerelease: false
75
75
  requirement: &id005 !ruby/object:Gem::Requirement
76
76
  requirements:
@@ -82,7 +82,7 @@ dependencies:
82
82
  type: :runtime
83
83
  version_requirements: *id005
84
84
  - !ruby/object:Gem::Dependency
85
- name: nokogiri
85
+ name: net-ssh
86
86
  prerelease: false
87
87
  requirement: &id006 !ruby/object:Gem::Requirement
88
88
  requirements:
@@ -94,19 +94,22 @@ dependencies:
94
94
  type: :runtime
95
95
  version_requirements: *id006
96
96
  - !ruby/object:Gem::Dependency
97
- name: ruby-hmac
97
+ name: nokogiri
98
98
  prerelease: false
99
99
  requirement: &id007 !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  segments:
104
- - 0
105
- version: "0"
104
+ - 1
105
+ - 4
106
+ - 3
107
+ - 1
108
+ version: 1.4.3.1
106
109
  type: :runtime
107
110
  version_requirements: *id007
108
111
  - !ruby/object:Gem::Dependency
109
- name: builder
112
+ name: ruby-hmac
110
113
  prerelease: false
111
114
  requirement: &id008 !ruby/object:Gem::Requirement
112
115
  requirements:
@@ -134,11 +137,13 @@ dependencies:
134
137
  prerelease: false
135
138
  requirement: &id010 !ruby/object:Gem::Requirement
136
139
  requirements:
137
- - - ">="
140
+ - - "="
138
141
  - !ruby/object:Gem::Version
139
142
  segments:
140
143
  - 0
141
- version: "0"
144
+ - 1
145
+ - 6
146
+ version: 0.1.6
142
147
  type: :development
143
148
  version_requirements: *id010
144
149
  description: The Ruby cloud computing library.
@@ -337,7 +342,11 @@ files:
337
342
  - lib/fog/go_grid/requests/grid_image_list.rb
338
343
  - lib/fog/go_grid/requests/grid_ip_list.rb
339
344
  - lib/fog/go_grid/requests/grid_loadbalancer_list.rb
345
+ - lib/fog/go_grid/requests/grid_server_add.rb
346
+ - lib/fog/go_grid/requests/grid_server_delete.rb
347
+ - lib/fog/go_grid/requests/grid_server_get.rb
340
348
  - lib/fog/go_grid/requests/grid_server_list.rb
349
+ - lib/fog/go_grid/requests/grid_server_power.rb
341
350
  - lib/fog/hmac.rb
342
351
  - lib/fog/linode.rb
343
352
  - lib/fog/linode/bin.rb