fog 1.11.0 → 1.11.1

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.
data/changelog.txt CHANGED
@@ -1,3 +1,21 @@
1
+ 1.11.1 05/05/2013 2cfeaf236e4ebcf883d0e17f586293d6cd66f379
2
+ ==========================================================
3
+
4
+ Stats! { 'collaborators' => 47, 'downloads' => 2177247, 'forks' => 783, 'open_issues' => 140, 'watchers' => 2494 }
5
+
6
+ [VSphere]
7
+ Added VMware customvalue and customfields to read the annotations for each VM. thanks Marc Grimme
8
+ Removed dependency to the Datacenters root path. So that now it should even work with other localizations. thanks Marc Grimme
9
+
10
+ [misc]
11
+ Load google/api_client late to avoid dep. thanks Dan Prince
12
+ Add a custom log warning on load error. thanks Dan Prince
13
+
14
+ [vSphere]
15
+ Refactor and extend network interface methods (similar to the ovirt implementation) * added methods to add, remove and update interfaces for vSphere * added missing method to retrieve the interface * added existing attribute key to interface (required for modifying, deleting interfaces) * alias interface's mac to id. thanks Marc Grimme
16
+ fixed bug that datastores in subfolders would not be found. thanks Marc Grimme
17
+
18
+
1
19
  1.11.0 05/04/2013 bbea0162df01317405bfbb4c427fdde40e5f0f2c
2
20
  ==========================================================
3
21
 
data/fog.gemspec CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new do |s|
6
6
  ## If your rubyforge_project name is different, then edit it and comment out
7
7
  ## the sub! line in the Rakefile
8
8
  s.name = 'fog'
9
- s.version = '1.11.0'
10
- s.date = '2013-05-04'
9
+ s.version = '1.11.1'
10
+ s.date = '2013-05-05'
11
11
  s.rubyforge_project = 'fog'
12
12
 
13
13
  ## Make sure your summary is short. The description may be as long
@@ -41,7 +41,6 @@ Gem::Specification.new do |s|
41
41
  ## List your runtime dependencies here. Runtime dependencies are those
42
42
  ## that are needed for an end user to actually USE your code.
43
43
  s.add_dependency('builder')
44
- s.add_dependency('google-api-client', '~>0.6.2')
45
44
  s.add_dependency('excon', '~>0.20')
46
45
  s.add_dependency('formatador', '~>0.2.0')
47
46
  s.add_dependency('json', '~>1.7')
@@ -63,6 +62,7 @@ Gem::Specification.new do |s|
63
62
  s.add_development_dependency('shindo', '~>0.3.4')
64
63
  s.add_development_dependency('fission')
65
64
  s.add_development_dependency('pry')
65
+ s.add_development_dependency('google-api-client', '~>0.6.2')
66
66
  # s.add_development_dependency('ruby-libvirt','~>0.4.0')
67
67
 
68
68
  s.files = `git ls-files`.split("\n")
@@ -1,6 +1,5 @@
1
1
  require 'fog/google'
2
2
  require 'fog/compute'
3
- require 'google/api_client'
4
3
 
5
4
  module Fog
6
5
  module Compute
@@ -67,6 +66,8 @@ module Fog
67
66
  attr_reader :project
68
67
 
69
68
  def initialize(options)
69
+
70
+
70
71
  base_url = 'https://www.googleapis.com/compute/'
71
72
  api_version = 'v1beta14'
72
73
  api_scope_url = 'https://www.googleapis.com/auth/compute'
@@ -74,6 +75,12 @@ module Fog
74
75
  @project = options[:google_project]
75
76
  google_client_email = options[:google_client_email]
76
77
  @api_url = base_url + api_version + '/projects/'
78
+ #NOTE: loaded here to avoid requiring this as a core Fog dependency
79
+ begin
80
+ require 'google/api_client'
81
+ rescue LoadError
82
+ Fog::Logger.warning("Please install the google-api-client gem before using this provider.")
83
+ end
77
84
  key = ::Google::APIClient::KeyUtils.load_from_pkcs12(File.expand_path(options[:google_key_location]), 'notasecret')
78
85
 
79
86
  @client = ::Google::APIClient.new({
data/lib/fog/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fog
2
- VERSION = '1.11.0'
2
+ VERSION = '1.11.1'
3
3
  end
@@ -29,6 +29,10 @@ module Fog
29
29
  collection :datastores
30
30
  model :folder
31
31
  collection :folders
32
+ model :customvalue
33
+ collection :customvalues
34
+ model :customfield
35
+ collection :customfields
32
36
 
33
37
  request_path 'fog/vsphere/requests/compute'
34
38
  request :current_time
@@ -55,6 +59,7 @@ module Fog
55
59
  request :list_folders
56
60
  request :create_vm
57
61
  request :list_vm_interfaces
62
+ request :modify_vm_interface
58
63
  request :list_vm_volumes
59
64
  request :get_virtual_machine
60
65
  request :vm_reconfig_hardware
@@ -62,6 +67,8 @@ module Fog
62
67
  request :vm_reconfig_cpus
63
68
  request :vm_config_vnc
64
69
  request :create_folder
70
+ request :list_vm_customvalues
71
+ request :list_customfields
65
72
 
66
73
  module Shared
67
74
 
@@ -0,0 +1,19 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+
5
+ class Customfield < Fog::Model
6
+
7
+ identity :key
8
+
9
+ attribute :name
10
+ attribute :type
11
+
12
+ def to_s
13
+ name
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/vsphere/models/compute/customfield'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Vsphere
7
+
8
+ class Customfields < Fog::Collection
9
+
10
+ model Fog::Compute::Vsphere::Customfield
11
+
12
+ attr_accessor :vm
13
+
14
+ def all(filters = {})
15
+ load service.list_customfields()
16
+ end
17
+
18
+ def get(key)
19
+ load(service.list_customfields()).find do | cv |
20
+ cv.key == ((key.is_a? String) ? key.to_i : key)
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+
5
+ class Customvalue < Fog::Model
6
+
7
+ attribute :value
8
+ attribute :key
9
+
10
+ def to_s
11
+ value
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/vsphere/models/compute/customvalue'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Vsphere
7
+
8
+ class Customvalues < Fog::Collection
9
+
10
+ model Fog::Compute::Vsphere::Customvalue
11
+
12
+ attr_accessor :vm
13
+
14
+ def all(filters = {})
15
+ requires :vm
16
+ case vm
17
+ when Fog::Compute::Vsphere::Server
18
+ load service.list_vm_customvalues(vm.id)
19
+ else
20
+ raise 'customvalues should have vm'
21
+ end
22
+ end
23
+
24
+ def get(key)
25
+ requires :vm
26
+ case vm
27
+ when Fog::Compute::Vsphere::Server
28
+ load service.list_vm_customvalues(vm.id)
29
+ else
30
+ raise 'customvalues should have vm'
31
+ end.find { | cv | cv.key == key }
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
@@ -27,6 +27,10 @@ module Fog
27
27
  def virtual_machines filters = {}
28
28
  service.servers({ :datacenter => name }.merge(filters))
29
29
  end
30
+
31
+ def customfields filters = {}
32
+ service.customfields({ :datacenter => name}.merge(filters))
33
+ end
30
34
 
31
35
  def to_s
32
36
  name
@@ -5,12 +5,14 @@ module Fog
5
5
  class Interface < Fog::Model
6
6
 
7
7
  identity :mac
8
+ alias :id :mac
8
9
 
9
10
  attribute :network
10
11
  attribute :name
11
12
  attribute :status
12
13
  attribute :summary
13
14
  attribute :type
15
+ attribute :key
14
16
 
15
17
  def initialize(attributes={} )
16
18
  super defaults.merge(attributes)
@@ -24,9 +24,21 @@ module Fog
24
24
  end
25
25
 
26
26
  def get(id)
27
- new service.get_interface(id)
27
+ requires :vm
28
+ case vm
29
+ when Fog::Compute::Vsphere::Server
30
+ interface=service.get_vm_interface(vm.id, :key => id, :mac=> id, :name => id)
31
+ when Fog::Compute::Vsphere::Template
32
+ interface=service.get_template_interfaces(vm.id, :key => id, :mac=> id, :name => id)
33
+ else
34
+ raise 'interfaces should have vm or template'
35
+ end
36
+ if interface
37
+ Fog::Compute::Vsphere::Interface.new(interface)
38
+ else
39
+ nil
40
+ end
28
41
  end
29
-
30
42
  end
31
43
  end
32
44
  end
@@ -38,6 +38,7 @@ module Fog
38
38
  attribute :cpus
39
39
  attribute :interfaces
40
40
  attribute :volumes
41
+ attribute :customvalues
41
42
  attribute :overall_status, :aliases => 'status'
42
43
  attribute :cluster
43
44
  attribute :datacenter
@@ -50,6 +51,7 @@ module Fog
50
51
  self.instance_uuid ||= id # TODO: remvoe instance_uuid as it can be replaced with simple id
51
52
  initialize_interfaces
52
53
  initialize_volumes
54
+ initialize_customvalues
53
55
  end
54
56
 
55
57
  # Lazy Loaded Attributes
@@ -72,8 +74,8 @@ module Fog
72
74
  service.vm_reconfig_cpus('instance_uuid' => instance_uuid, 'cpus' => cpus)
73
75
  end
74
76
 
75
- def vm_reconfig_hardware(options = {})
76
- requires :instance_uuid, :hardware_spec
77
+ def vm_reconfig_hardware(hardware_spec, options = {})
78
+ requires :instance_uuid
77
79
  service.vm_reconfig_hardware('instance_uuid' => instance_uuid, 'hardware_spec' => hardware_spec)
78
80
  end
79
81
 
@@ -163,10 +165,33 @@ module Fog
163
165
  def interfaces
164
166
  attributes[:interfaces] ||= id.nil? ? [] : service.interfaces( :vm => self )
165
167
  end
168
+
169
+ def interface_ready? attrs
170
+ (attrs.is_a? Hash and attrs[:blocking]) or attrs.is_a? Fog::Compute::Vsphere::Interface
171
+ end
172
+
173
+ def add_interface attrs
174
+ wait_for { not ready? } if interface_ready? attrs
175
+ service.add_vm_interface(id, attrs)
176
+ end
177
+
178
+ def update_interface attrs
179
+ wait_for { not ready? } if interface_ready? attrs
180
+ service.update_vm_interface(id, attrs)
181
+ end
182
+
183
+ def destroy_interface attrs
184
+ wait_for { not ready? } if interface_ready? attrs
185
+ service.destroy_vm_interface(id, attrs)
186
+ end
166
187
 
167
188
  def volumes
168
189
  attributes[:volumes] ||= id.nil? ? [] : service.volumes( :vm => self )
169
190
  end
191
+
192
+ def customvalues
193
+ attributes[:customvalues] ||= id.nil? ? [] : service.customvalues( :vm => self )
194
+ end
170
195
 
171
196
  def folder
172
197
  return nil unless datacenter and path
@@ -218,6 +243,12 @@ module Fog
218
243
  self.attributes[:volumes].map! { |vol| vol.is_a?(Hash) ? service.volumes.new(vol) : vol }
219
244
  end
220
245
  end
246
+
247
+ def initialize_customvalues
248
+ if attributes[:customvalues] and attributes[:customvalues].is_a?(Array)
249
+ self.attributes[:customvalues].map { |cfield| cfield.is_a?(Hash) ? service.customvalue.new(cfield) : cfield}
250
+ end
251
+ end
221
252
  end
222
253
 
223
254
  end
@@ -12,7 +12,12 @@ module Fog
12
12
 
13
13
  def get_raw_datastore(name, datacenter_name)
14
14
  dc = find_raw_datacenter(datacenter_name)
15
- dc.datastoreFolder.find(name)
15
+
16
+ @connection.serviceContent.viewManager.CreateContainerView({
17
+ :container => dc.datastoreFolder,
18
+ :type => ["Datastore"],
19
+ :recursive => true
20
+ }).view.select{|ds| ds.name == name}.first
16
21
  end
17
22
  end
18
23
 
@@ -27,9 +27,11 @@ module Fog
27
27
  # The required path syntax - 'topfolder/subfolder
28
28
 
29
29
  # Clean up path to be relative since we're providing datacenter name
30
- paths = path.sub(/^\/?Datacenters\/#{datacenter_name}\/vm\/?/, '').split('/')
31
30
  dc = find_raw_datacenter(datacenter_name)
32
31
  dc_root_folder = dc.vmFolder
32
+ # Filter the root path for this datacenter not to be used."
33
+ dc_root_folder_path=dc_root_folder.path.map { | id, name | name }.join("/")
34
+ paths = path.sub(/^\/?#{dc_root_folder_path}\/?/, '').split('/')
33
35
 
34
36
  return dc_root_folder if paths.empty?
35
37
  # Walk the tree resetting the folder pointer as we go
@@ -0,0 +1,22 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Real
5
+ def list_customfields()
6
+ @connection.serviceContent.customFieldsManager.field.map do |customfield|
7
+ {
8
+ :key => customfield.key.to_i,
9
+ :name => customfield.name,
10
+ :type => customfield.type
11
+ }
12
+ end
13
+ end
14
+
15
+ end
16
+ class Mock
17
+ def list_vm_customfields()
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Real
5
+ def list_vm_customvalues(vm_id)
6
+ get_vm_ref(vm_id).summary.customValue.map do |customvalue|
7
+ {
8
+ :key => customvalue.key.to_i,
9
+ :value => customvalue.value,
10
+ }
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ class Mock
17
+ def list_vm_customfields(vm_id)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -37,10 +37,23 @@ module Fog
37
37
  :status => nic.connectable.status,
38
38
  :summary => nic.deviceInfo.summary,
39
39
  :type => nic.class,
40
+ :key => nic.key,
40
41
  }
41
42
  end
42
43
 
43
44
  end
45
+
46
+ def get_vm_interface(vm_id, options={})
47
+ raise ArgumentError, "instance id is a required parameter" unless vm_id
48
+ if options.is_a? Fog::Compute::Vsphere::Interface
49
+ options
50
+ else
51
+ raise ArgumentError, "Either key or name is a required parameter. options: #{options}" unless options.has_key? :key or options.has_key? :mac or options.has_key? :name
52
+ list_vm_interfaces(vm_id).find do | nic |
53
+ (options.has_key? :key and nic[:key]==options[:key].to_i) or (options.has_key? :mac and nic[:mac]==options[:mac]) or (options.has_key? :name and nic[:name]==options[:name])
54
+ end
55
+ end
56
+ end
44
57
 
45
58
  end
46
59
  class Mock