fog 0.0.84 → 0.0.85

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.
Files changed (89) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +47 -37
  3. data/bin/fog +9 -10
  4. data/fog.gemspec +23 -4
  5. data/lib/fog.rb +19 -1
  6. data/lib/fog/aws.rb +23 -0
  7. data/lib/fog/aws/bin.rb +4 -0
  8. data/lib/fog/aws/ec2.rb +20 -27
  9. data/lib/fog/aws/elb.rb +115 -0
  10. data/lib/fog/aws/models/ec2/server.rb +7 -1
  11. data/lib/fog/aws/models/s3/directories.rb +4 -4
  12. data/lib/fog/aws/models/s3/directory.rb +13 -11
  13. data/lib/fog/aws/parsers/elb/deregister_instances_from_load_balancer.rb +26 -0
  14. data/lib/fog/aws/parsers/elb/describe_instance_health.rb +30 -0
  15. data/lib/fog/aws/parsers/elb/describe_load_balancers.rb +101 -0
  16. data/lib/fog/aws/parsers/elb/disable_availability_zones_for_load_balancer.rb +26 -0
  17. data/lib/fog/aws/parsers/elb/enable_availability_zones_for_load_balancer.rb +26 -0
  18. data/lib/fog/aws/parsers/elb/register_instances_with_load_balancer.rb +26 -0
  19. data/lib/fog/aws/requests/ec2/detach_volume.rb +2 -2
  20. data/lib/fog/aws/requests/elb/deregister_instances_from_load_balancer.rb +45 -0
  21. data/lib/fog/aws/requests/elb/describe_instance_health.rb +44 -0
  22. data/lib/fog/aws/requests/elb/describe_load_balancers.rb +57 -0
  23. data/lib/fog/aws/requests/elb/disable_availability_zones_for_load_balancer.rb +44 -0
  24. data/lib/fog/aws/requests/elb/enable_availability_zones_for_load_balancer.rb +44 -0
  25. data/lib/fog/aws/requests/elb/register_instances_with_load_balancer.rb +45 -0
  26. data/lib/fog/aws/s3.rb +8 -1
  27. data/lib/fog/aws/simpledb.rb +9 -18
  28. data/lib/fog/bin.rb +11 -1
  29. data/lib/fog/credentials.rb +1 -0
  30. data/lib/fog/local.rb +72 -0
  31. data/lib/fog/local/bin.rb +34 -0
  32. data/lib/fog/local/models/directories.rb +43 -0
  33. data/lib/fog/local/models/directory.rb +47 -0
  34. data/lib/fog/local/models/file.rb +58 -0
  35. data/lib/fog/local/models/files.rb +74 -0
  36. data/lib/fog/model.rb +2 -8
  37. data/lib/fog/rackspace/models/files/directories.rb +3 -3
  38. data/lib/fog/rackspace/models/files/directory.rb +8 -5
  39. data/lib/fog/rackspace/models/servers/server.rb +7 -3
  40. data/lib/fog/rackspace/requests/servers/create_server.rb +1 -1
  41. data/lib/fog/ssh.rb +91 -25
  42. data/lib/fog/terremark/bin.rb +1 -8
  43. data/lib/fog/terremark/ecloud.rb +14 -5
  44. data/lib/fog/terremark/models/shared/server.rb +54 -3
  45. data/lib/fog/terremark/parsers/shared/vapp.rb +1 -1
  46. data/lib/fog/terremark/requests/shared/get_network.rb +39 -1
  47. data/lib/fog/terremark/requests/shared/get_organization.rb +45 -1
  48. data/lib/fog/terremark/requests/shared/get_organizations.rb +2 -1
  49. data/lib/fog/terremark/requests/shared/get_public_ips.rb +32 -1
  50. data/lib/fog/terremark/requests/shared/get_vdc.rb +83 -1
  51. data/lib/fog/terremark/requests/shared/{reset.rb → power_reset.rb} +1 -1
  52. data/lib/fog/terremark/requests/shared/power_shutdown.rb +32 -0
  53. data/lib/fog/terremark/shared.rb +139 -18
  54. data/lib/fog/terremark/vcloud.rb +14 -5
  55. data/spec/aws/models/ec2/address_spec.rb +1 -3
  56. data/spec/aws/models/ec2/snapshot_spec.rb +25 -49
  57. data/spec/aws/models/ec2/snapshots_spec.rb +25 -31
  58. data/spec/aws/models/ec2/volume_spec.rb +9 -3
  59. data/spec/aws/models/s3/directory_spec.rb +14 -14
  60. data/spec/aws/requests/ec2/associate_address_spec.rb +4 -5
  61. data/spec/aws/requests/ec2/attach_volume_spec.rb +14 -16
  62. data/spec/aws/requests/ec2/create_snapshot_spec.rb +2 -3
  63. data/spec/aws/requests/ec2/delete_snapshot_spec.rb +5 -6
  64. data/spec/aws/requests/ec2/describe_instances_spec.rb +3 -2
  65. data/spec/aws/requests/ec2/describe_snapshots_spec.rb +21 -25
  66. data/spec/aws/requests/ec2/detach_volume_spec.rb +14 -16
  67. data/spec/aws/requests/ec2/disassociate_address_spec.rb +3 -4
  68. data/spec/aws/requests/ec2/get_console_output_spec.rb +1 -0
  69. data/spec/aws/requests/s3/get_service_spec.rb +5 -6
  70. data/spec/spec_helper.rb +0 -20
  71. data/tests/helper.rb +0 -10
  72. data/tests/rackspace/requests/servers/create_image_tests.rb +2 -2
  73. data/tests/rackspace/requests/servers/create_server_tests.rb +3 -2
  74. data/tests/rackspace/requests/servers/delete_image_tests.rb +2 -2
  75. data/tests/rackspace/requests/servers/delete_server_tests.rb +1 -1
  76. data/tests/rackspace/requests/servers/get_server_details_tests.rb +1 -1
  77. data/tests/rackspace/requests/servers/list_addresses_tests.rb +1 -1
  78. data/tests/rackspace/requests/servers/list_private_addresses_tests.rb +1 -1
  79. data/tests/rackspace/requests/servers/list_public_addresses_tests.rb +1 -1
  80. data/tests/rackspace/requests/servers/list_servers_detail_tests.rb +1 -1
  81. data/tests/rackspace/requests/servers/list_servers_tests.rb +1 -1
  82. data/tests/rackspace/requests/servers/reboot_server_tests.rb +3 -3
  83. data/tests/rackspace/requests/servers/update_server_tests.rb +1 -1
  84. data/tests/slicehost/requests/create_slice_tests.rb +1 -1
  85. data/tests/slicehost/requests/delete_slice_tests.rb +1 -1
  86. data/tests/slicehost/requests/get_slice_tests.rb +1 -1
  87. data/tests/slicehost/requests/reboot_slice_tests.rb +2 -2
  88. metadata +24 -5
  89. data/lib/fog/terremark/requests/shared/shutdown.rb +0 -43
@@ -0,0 +1,58 @@
1
+ require 'fog/model'
2
+
3
+ module Fog
4
+ module Local
5
+
6
+ class File < Fog::Model
7
+
8
+ identity :key, 'Key'
9
+
10
+ attr_accessor :body
11
+ attribute :content_length, 'Content-Length'
12
+ # attribute :content_type, 'Content-Type'
13
+ attribute :last_modified, 'Last-Modified'
14
+
15
+ def body
16
+ @body ||= if last_modified
17
+ collection.get(identity).body
18
+ else
19
+ ''
20
+ end
21
+ end
22
+
23
+ def directory
24
+ @directory
25
+ end
26
+
27
+ def destroy
28
+ requires :directory, :key
29
+ ::File.delete(path)
30
+ true
31
+ end
32
+
33
+ def save(options = {})
34
+ requires :body, :directory, :key
35
+ file = ::File.new(path, 'w')
36
+ file.write(body)
37
+ file.close
38
+ merge_attributes(
39
+ :content_length => ::File.size(path),
40
+ :last_modified => ::File.mtime(path)
41
+ )
42
+ true
43
+ end
44
+
45
+ private
46
+
47
+ def directory=(new_directory)
48
+ @directory = new_directory
49
+ end
50
+
51
+ def path
52
+ connection.path_to(::File.join(directory.name, key))
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,74 @@
1
+ require 'fog/collection'
2
+ require 'fog/local/models/file'
3
+
4
+ module Fog
5
+ module Local
6
+
7
+ class Files < Fog::Collection
8
+
9
+ model Fog::Local::File
10
+
11
+ def all
12
+ if directory.collection.get(directory.name)
13
+ data = Dir.entries(connection.path_to(directory.name)).select do |key|
14
+ key[0...1] != '.' && !::File.directory?(connection.path_to(key))
15
+ end.map do |key|
16
+ path = file_path(key)
17
+ {
18
+ :content_length => ::File.size(path),
19
+ :key => key,
20
+ :last_modified => ::File.mtime(path)
21
+ }
22
+ end
23
+ load(data)
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ def directory
30
+ @directory
31
+ end
32
+
33
+ def get(key, &block)
34
+ path = file_path(key)
35
+ if ::File.exists?(path)
36
+ data = {
37
+ :content_length => ::File.size(path),
38
+ :key => key,
39
+ :last_modified => ::File.mtime(path)
40
+ }
41
+ if block_given?
42
+ file = ::File.open(path)
43
+ while (chunk = file.read(Excon::CHUNK_SIZE)) && yield(chunk); end
44
+ file.close
45
+ new(data)
46
+ else
47
+ body = nil
48
+ ::File.open(path) do |file|
49
+ body = file.read
50
+ end
51
+ new(data.merge!(:body => body))
52
+ end
53
+ else
54
+ nil
55
+ end
56
+ end
57
+
58
+ def new(attributes = {})
59
+ super({ :directory => directory }.merge!(attributes))
60
+ end
61
+
62
+ private
63
+
64
+ def directory=(new_directory)
65
+ @directory = new_directory
66
+ end
67
+
68
+ def file_path(key)
69
+ connection.path_to(::File.join(directory.name, key))
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -110,14 +110,8 @@ module Fog
110
110
  end
111
111
 
112
112
  def wait_for(timeout = 600, &block)
113
- start = Time.now
114
- until instance_eval(&block)
115
- if Time.now - start > timeout
116
- break
117
- end
118
- reload
119
- sleep(1)
120
- end
113
+ reload
114
+ Fog.wait_for(timeout) { reload && instance_eval(&block) }
121
115
  end
122
116
 
123
117
  private
@@ -26,9 +26,9 @@ module Fog
26
26
  load(data)
27
27
  end
28
28
 
29
- def get(name, options = {})
30
- data = connection.get_container(name, options).body
31
- directory = new(:name => name)
29
+ def get(key, options = {})
30
+ data = connection.get_container(key, options).body
31
+ directory = new(:key => key)
32
32
  directory.files.merge_attributes(options)
33
33
  directory.files.instance_variable_set(:@loaded, true)
34
34
  data.each do |file|
@@ -1,19 +1,22 @@
1
1
  require 'fog/model'
2
+ require 'fog/rackspace/models/files/files'
2
3
 
3
4
  module Fog
4
5
  module Rackspace
5
6
  module Files
6
7
 
7
8
  class Directory < Fog::Model
9
+ extend Fog::Deprecation
10
+ deprecate(:name, :key)
8
11
 
9
- identity :name
12
+ identity :key, 'name'
10
13
 
11
14
  attribute :bytes
12
15
  attribute :count
13
16
 
14
17
  def destroy
15
- requires :name
16
- connection.delete_container(@name)
18
+ requires :key
19
+ connection.delete_container(key)
17
20
  true
18
21
  rescue Excon::Errors::NotFound
19
22
  false
@@ -29,8 +32,8 @@ module Fog
29
32
  end
30
33
 
31
34
  def save
32
- requires :name
33
- connection.put_container(@name)
35
+ requires :key
36
+ connection.put_container(key)
34
37
  true
35
38
  end
36
39
 
@@ -51,10 +51,14 @@ module Fog
51
51
  end
52
52
 
53
53
  def save
54
- requires :flavor_id, :image_id, :name
55
- options = { 'metadata' => @metadata, 'personality' => @personality }
54
+ requires :flavor_id, :image_id
55
+ options = {
56
+ 'metadata' => @metadata,
57
+ 'name' => @name,
58
+ 'personality' => @personality
59
+ }
56
60
  options = options.reject {|key, value| value.nil?}
57
- data = connection.create_server(@flavor_id, @image_id, @name, options)
61
+ data = connection.create_server(@flavor_id, @image_id, options)
58
62
  merge_attributes(data.body['server'])
59
63
  true
60
64
  end
@@ -33,7 +33,7 @@ module Fog
33
33
  # * 'name<~String> - Name of server
34
34
  # * 'progress'<~Integer> - Progress through current status
35
35
  # * 'status'<~String> - Current server status
36
- def create_server(flavor_id, image_id, name, options = {})
36
+ def create_server(flavor_id, image_id, options = {})
37
37
  data = {
38
38
  'server' => {
39
39
  'flavorId' => flavor_id,
@@ -1,42 +1,108 @@
1
1
  module Fog
2
+ module SSH
2
3
 
3
- class SSH
4
-
5
- def initialize(address, username, options = {})
4
+ def self.new(address, username, options = {})
6
5
  unless options[:keys] || options[:password]
7
6
  raise ArgumentError.new(':keys or :password are required to initialize SSH')
8
7
  end
9
- @address = address
10
- @username = username
11
- @options = options.merge!(:paranoid => false)
8
+ if Fog.mocking?
9
+ Fog::SSH::Mock.new(address, username, options)
10
+ else
11
+ Fog::SSH::Real.new(address, username, options)
12
+ end
13
+ end
14
+
15
+ def self.reset_data(keys=Mock.data.keys)
16
+ Mock.reset_data(keys)
12
17
  end
13
18
 
14
- def run(commands)
15
- commands = [*commands]
16
- results = []
17
- Net::SSH.start(@address, @username, @options) do |ssh|
18
- commands.each do |command|
19
- ssh.open_channel do |channel|
20
- channel.request_pty
21
- result = { :command => command }
22
- channel.exec(command.sub(/^sudo/, %q{sudo -p 'fog sudo password:'})) do |channel, success|
23
- channel.on_data do |channel, data|
24
- if data.strip == 'fog sudo password:'
25
- channel.send_data("#{@options[:password]}\n")
26
- else
27
- result[:data] ||= ''
28
- result[:data] << data
19
+ class Mock
20
+
21
+ def self.data
22
+ @data ||= Hash.new do |hash, key|
23
+ hash[key] = {}
24
+ end
25
+ end
26
+
27
+ def initialize(address, username, options)
28
+ @address = address
29
+ @username = username
30
+ @options = options
31
+ end
32
+
33
+ def run(commands)
34
+ raise MockNotImplemented.new("Contributions welcome!")
35
+ end
36
+
37
+ end
38
+
39
+ class Real
40
+
41
+ def initialize(address, username, options)
42
+ @address = address
43
+ @username = username
44
+ @options = options.merge!(:paranoid => false)
45
+ end
46
+
47
+ def run(commands)
48
+ commands = [*commands]
49
+ results = []
50
+ begin
51
+ Net::SSH.start(@address, @username, @options) do |ssh|
52
+ commands.each do |command|
53
+ ssh.open_channel do |channel|
54
+ sudoable_command = command.sub(/^sudo/, %{sudo -p 'fog sudo password:'})
55
+ escaped_command = sudoable_command.sub(/'/, %{'"'"'})
56
+ channel.request_pty
57
+ result = Result.new(command)
58
+ channel.exec(%{bash -lc '#{escaped_command}'}) do |channel, success|
59
+ unless success
60
+ raise "Could not execute command: #{command.inspect}"
61
+ end
62
+
63
+ channel.on_data do |channel, data|
64
+ result.stdout << data
65
+ end
66
+
67
+ channel.on_extended_data do |channel, type, data|
68
+ next unless type == 1
69
+ result.stderr << data
70
+ end
71
+
72
+ channel.on_request('exit-status') do |channel, data|
73
+ result.status = data.read_long
74
+ end
75
+
76
+ channel.on_request('exit-signal') do |channel, data|
77
+ result.status = 255
78
+ end
29
79
  end
80
+ results << result
30
81
  end
82
+ ssh.loop
31
83
  end
32
- results << result
33
84
  end
34
- ssh.loop
85
+ rescue Net::SSH::HostKeyMismatch => exception
86
+ exception.remember_host!
87
+ sleep 0.2
88
+ retry
35
89
  end
90
+ results
91
+ end
92
+
93
+ end
94
+
95
+ class Result
96
+
97
+ attr_accessor :command, :stderr, :stdout, :status
98
+
99
+ def initialize(command)
100
+ @command = command
101
+ @stderr = ''
102
+ @stdout = ''
36
103
  end
37
- results
104
+
38
105
  end
39
106
 
40
107
  end
41
-
42
108
  end
@@ -28,14 +28,7 @@ module Terremark
28
28
  !Fog::Terremark::VCLOUD_OPTIONS.include?(k)
29
29
  end
30
30
  end
31
- case key
32
- when :ecloud
33
- hash[key] = Fog::Terremark::Ecloud.new(credentials)
34
- when :vcloud
35
- hash[key] = Fog::Terremark::Vcloud.new(credentials)
36
- else
37
- raise "Unsupported Terremark Service"
38
- end
31
+ hash[key] = terremark_service(key).new(credentials)
39
32
  end
40
33
  @@connections[service]
41
34
  end
@@ -5,6 +5,13 @@ module Fog
5
5
  module Bin
6
6
  end
7
7
 
8
+ module Defaults
9
+ HOST = 'services.enterprisecloud.terremark.com'
10
+ PATH = '/api/v0.8a-ext2.0'
11
+ PORT = 443
12
+ SCHEME = 'https'
13
+ end
14
+
8
15
  extend Fog::Terremark::Shared
9
16
 
10
17
  def self.new(options={})
@@ -31,11 +38,10 @@ module Fog
31
38
  def initialize(options={})
32
39
  @terremark_password = options[:terremark_ecloud_password]
33
40
  @terremark_username = options[:terremark_ecloud_username]
34
- @host = options[:host] || "services.enterprisecloud.terremark.com"
35
- @path = options[:path] || "/api/v0.8a-ext2.0"
36
- @port = options[:port] || 443
37
- @scheme = options[:scheme] || 'https'
38
- @cookie = get_organizations.headers['Set-Cookie']
41
+ @host = options[:host] || Fog::Terremark::Ecloud::Defaults::HOST
42
+ @path = options[:path] || Fog::Terremark::Ecloud::Defaults::PATH
43
+ @port = options[:port] || Fog::Terremark::Ecloud::Defaults::PORT
44
+ @scheme = options[:scheme] || Fog::Terremark::Ecloud::Defaults::SCHEME
39
45
  end
40
46
 
41
47
  end
@@ -46,6 +52,9 @@ module Fog
46
52
 
47
53
  def initialize(option = {})
48
54
  super
55
+ @base_url = Fog::Terremark::Ecloud::Defaults::SCHEME + "://" +
56
+ Fog::Terremark::Ecloud::Defaults::HOST +
57
+ Fog::Terremark::Ecloud::Defaults::PATH
49
58
  @data = self.class.data[:terremark_ecloud_username]
50
59
  end
51
60
  end
@@ -25,12 +25,60 @@ module Fog
25
25
  @status == '2'
26
26
  end
27
27
 
28
- def reboot
28
+ def on?
29
+ @status == '4'
30
+ end
31
+
32
+ def off?
33
+ @status == '2'
34
+ end
35
+
36
+ def power_on(options = {})
37
+ requires :id
38
+ begin
39
+ connection.power_on(@id)
40
+ rescue Excon::Errors::InternalServerError => e
41
+ #Frankly we shouldn't get here ...
42
+ raise e unless e.to_s =~ /because it is already powered on/
43
+ end
44
+ true
45
+ end
46
+
47
+ def power_off
48
+ requires :id
49
+ begin
50
+ connection.power_off(@id)
51
+ rescue Excon::Errors::InternalServerError => e
52
+ #Frankly we shouldn't get here ...
53
+ raise e unless e.to_s =~ /because it is already powered off/
54
+ end
55
+ true
56
+ end
57
+
58
+ def shutdown
59
+ requires :id
60
+ begin
61
+ connection.power_shutdown(@id)
62
+ rescue Excon::Errors::InternalServerError => e
63
+ #Frankly we shouldn't get here ...
64
+ raise e unless e.to_s =~ /because it is already powered off/
65
+ end
66
+ true
67
+ end
68
+
69
+ def power_reset
29
70
  requires :id
30
- connection.reset(@id)
71
+ connection.power_reset(@id)
31
72
  true
32
73
  end
33
74
 
75
+ def graceful_restart
76
+ requires :id
77
+ shutdown
78
+ wait_for { off? }
79
+ power_on
80
+ end
81
+
34
82
  def save
35
83
  requires :name
36
84
  data = connection.instantiate_vapp(@name)
@@ -48,7 +96,10 @@ module Fog
48
96
  @id = new_href.split('/').last.to_i
49
97
  end
50
98
 
51
- def type=(new_type); end
99
+ def type=(new_type); @type = new_type; end
100
+ def size=(new_size); @size = new_size; end
101
+ def IpAddress=(new_ipaddress); @IpAddress = new_ipaddress; end
102
+ def Links=(new_links); @Links = new_links; end
52
103
 
53
104
  end
54
105