deltacloud-core 1.0.5 → 1.1.0

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 (141) hide show
  1. data/Rakefile +10 -2
  2. data/bin/deltacloudd +10 -10
  3. data/config.ru +2 -1
  4. data/config/drivers/digitalocean.yaml +3 -0
  5. data/deltacloud-core.gemspec +13 -6
  6. data/lib/cimi/collections.rb +1 -1
  7. data/lib/cimi/collections/address_templates.rb +27 -3
  8. data/lib/cimi/collections/addresses.rb +1 -1
  9. data/lib/cimi/collections/base.rb +1 -0
  10. data/lib/cimi/collections/cloud_entry_point.rb +4 -0
  11. data/lib/cimi/collections/credentials.rb +2 -2
  12. data/lib/cimi/collections/machine_images.rb +20 -0
  13. data/lib/cimi/collections/machine_templates.rb +72 -0
  14. data/lib/cimi/collections/machines.rb +50 -41
  15. data/lib/cimi/collections/network_ports.rb +3 -3
  16. data/lib/cimi/collections/networks.rb +4 -4
  17. data/lib/cimi/collections/resource_metadata.rb +1 -1
  18. data/lib/cimi/collections/volume_configurations.rb +25 -0
  19. data/lib/cimi/collections/volume_images.rb +21 -1
  20. data/lib/cimi/collections/volume_templates.rb +69 -0
  21. data/lib/cimi/collections/volumes.rb +5 -10
  22. data/lib/cimi/dependencies.rb +0 -1
  23. data/lib/cimi/helpers.rb +4 -1
  24. data/lib/cimi/helpers/cimi_helper.rb +62 -0
  25. data/lib/cimi/helpers/database_helper.rb +95 -0
  26. data/lib/cimi/models.rb +15 -1
  27. data/lib/cimi/models/address.rb +10 -5
  28. data/lib/cimi/models/address_template.rb +67 -3
  29. data/lib/cimi/models/base.rb +8 -5
  30. data/lib/cimi/models/cloud_entry_point.rb +6 -1
  31. data/lib/cimi/models/collection.rb +9 -4
  32. data/lib/cimi/models/disk.rb +6 -1
  33. data/lib/cimi/models/errors.rb +8 -0
  34. data/lib/cimi/models/machine.rb +68 -42
  35. data/lib/cimi/models/machine_configuration.rb +2 -2
  36. data/lib/cimi/models/machine_image.rb +41 -6
  37. data/lib/cimi/models/machine_template.rb +58 -0
  38. data/lib/cimi/models/machine_volume.rb +51 -3
  39. data/lib/cimi/models/resource_metadata.rb +88 -25
  40. data/lib/cimi/models/schema.rb +19 -5
  41. data/lib/cimi/models/volume.rb +66 -30
  42. data/lib/cimi/models/volume_configuration.rb +53 -21
  43. data/lib/cimi/models/volume_image.rb +24 -9
  44. data/lib/cimi/models/volume_template.rb +61 -0
  45. data/lib/cimi/server.rb +0 -6
  46. data/lib/db.rb +82 -0
  47. data/lib/db/address_template.rb +15 -0
  48. data/lib/db/entity.rb +22 -0
  49. data/lib/db/machine_template.rb +10 -0
  50. data/lib/db/provider.rb +13 -0
  51. data/lib/db/volume_configuration.rb +10 -0
  52. data/lib/db/volume_template.rb +10 -0
  53. data/lib/deltacloud/collections/addresses.rb +1 -1
  54. data/lib/deltacloud/collections/base.rb +12 -1
  55. data/lib/deltacloud/collections/buckets.rb +41 -8
  56. data/lib/deltacloud/collections/drivers.rb +1 -1
  57. data/lib/deltacloud/collections/firewalls.rb +2 -2
  58. data/lib/deltacloud/collections/images.rb +1 -1
  59. data/lib/deltacloud/collections/instances.rb +7 -1
  60. data/lib/deltacloud/collections/keys.rb +1 -1
  61. data/lib/deltacloud/collections/load_balancers.rb +4 -4
  62. data/lib/deltacloud/collections/storage_snapshots.rb +5 -1
  63. data/lib/deltacloud/collections/storage_volumes.rb +7 -3
  64. data/lib/deltacloud/drivers/base_driver.rb +10 -9
  65. data/lib/deltacloud/drivers/cimi_features.rb +42 -0
  66. data/lib/deltacloud/drivers/digitalocean/digitalocean_driver.rb +307 -0
  67. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +40 -14
  68. data/lib/deltacloud/drivers/exceptions.rb +8 -0
  69. data/lib/deltacloud/drivers/features.rb +19 -2
  70. data/lib/deltacloud/drivers/fgcp/fgcp_client.rb +11 -0
  71. data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +83 -11
  72. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +1 -1
  73. data/lib/deltacloud/drivers/mock/mock_client.rb +2 -4
  74. data/lib/deltacloud/drivers/mock/mock_driver.rb +29 -0
  75. data/lib/deltacloud/drivers/openstack/openstack_driver.rb +153 -36
  76. data/lib/deltacloud/drivers/rackspace/anti_cache_monkey_patch.rb +20 -0
  77. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +1 -0
  78. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +30 -12
  79. data/lib/deltacloud/drivers/sbc/sbc_client.rb +0 -1
  80. data/lib/deltacloud/drivers/sbc/sbc_driver.rb +5 -1
  81. data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +1 -1
  82. data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +19 -9
  83. data/lib/deltacloud/helpers/blob_stream_helper.rb +42 -3
  84. data/lib/deltacloud/helpers/deltacloud_helper.rb +31 -14
  85. data/lib/deltacloud/models/address.rb +9 -0
  86. data/lib/deltacloud/models/base_model.rb +4 -0
  87. data/lib/deltacloud/models/blob.rb +12 -0
  88. data/lib/deltacloud/models/bucket.rb +9 -0
  89. data/lib/deltacloud/models/firewall.rb +13 -1
  90. data/lib/deltacloud/models/firewall_rule.rb +14 -0
  91. data/lib/deltacloud/models/hardware_profile.rb +14 -0
  92. data/lib/deltacloud/models/image.rb +15 -0
  93. data/lib/deltacloud/models/instance.rb +40 -1
  94. data/lib/deltacloud/models/instance_address.rb +9 -0
  95. data/lib/deltacloud/models/key.rb +15 -0
  96. data/lib/deltacloud/models/load_balancer.rb +20 -0
  97. data/lib/deltacloud/models/metric.rb +15 -0
  98. data/lib/deltacloud/models/provider.rb +8 -0
  99. data/lib/deltacloud/models/realm.rb +9 -0
  100. data/lib/deltacloud/models/state_machine.rb +8 -0
  101. data/lib/deltacloud/models/storage_snapshot.rb +11 -0
  102. data/lib/deltacloud/models/storage_volume.rb +24 -0
  103. data/lib/deltacloud/server.rb +1 -3
  104. data/lib/deltacloud/version.rb +2 -1
  105. data/lib/deltacloud_rack.rb +1 -1
  106. data/tests/cimi/db/database_helper_test.rb +190 -0
  107. data/tests/cimi/db/db_helper.rb +30 -0
  108. data/tests/cimi/db/schema_test.rb +94 -0
  109. data/tests/cimi/model/collection_spec.rb +0 -1
  110. data/tests/cimi/model/machine_spec.rb +17 -0
  111. data/tests/cimi/spec_helper.rb +3 -2
  112. data/tests/deltacloud/collections/buckets_collection_test.rb +3 -0
  113. data/tests/deltacloud/collections/drivers_collection_test.rb +10 -0
  114. data/tests/deltacloud/collections/hardware_profiles_collection_test.rb +4 -0
  115. data/tests/deltacloud/collections/images_collection_test.rb +4 -0
  116. data/tests/deltacloud/collections/instances_collection_test.rb +14 -1
  117. data/tests/deltacloud/collections/keys_collection_test.rb +4 -0
  118. data/tests/deltacloud/collections/realms_collection_test.rb +47 -0
  119. data/tests/deltacloud/collections/storage_snapshots_collection_test.rb +47 -0
  120. data/tests/deltacloud/collections/storage_volumes_collection_test.rb +47 -0
  121. data/tests/deltacloud/common.rb +15 -0
  122. data/tests/deltacloud/deltacloud_helper_test.rb +0 -4
  123. data/tests/deltacloud/launcher_test.rb +108 -0
  124. data/tests/drivers/ec2/buckets_test.rb +2 -1
  125. data/tests/drivers/mock/buckets_test.rb +27 -0
  126. data/tests/drivers/mock/instances_test.rb +6 -0
  127. data/tests/drivers/openstack/common.rb +1 -1
  128. data/tests/drivers/openstack/hardware_profiles_test.rb +2 -1
  129. data/tests/drivers/openstack/instances_test.rb +18 -17
  130. data/tests/drivers/rhevm/common.rb +1 -0
  131. data/tests/drivers/rhevm/images_test.rb +1 -1
  132. data/tests/drivers/rhevm/instance_test.rb +7 -7
  133. data/tests/helpers/rack/rack_matrix_params_test.rb +0 -2
  134. data/tests/test_helper.rb +2 -1
  135. data/views/errors/403.xml.haml +6 -0
  136. data/views/errors/409.html.haml +47 -0
  137. data/views/errors/409.xml.haml +11 -0
  138. data/views/errors/502.html.haml +6 -5
  139. data/views/images/show.xml.haml +3 -2
  140. data/views/instances/new.html.haml +1 -1
  141. metadata +77 -30
data/Rakefile CHANGED
@@ -128,7 +128,14 @@ task :routes do
128
128
  Rake::Task['deltacloud:routes'].invoke
129
129
  end
130
130
 
131
- DRIVERS = [:mock, :ec2, :rhevm, :google, :gogrid, :openstack]
131
+ # TODO: The 'google' driver tests are failing under jRuby
132
+ # need to investigate in future.
133
+ #
134
+ if RUBY_PLATFORM == 'java'
135
+ DRIVERS = [:mock, :ec2, :rhevm, :gogrid, :openstack]
136
+ else
137
+ DRIVERS = [:mock, :ec2, :rhevm, :google, :gogrid, :openstack]
138
+ end
132
139
 
133
140
  desc 'Run all tests'
134
141
  task :test do
@@ -160,7 +167,7 @@ namespace :test do
160
167
 
161
168
  DRIVERS.each do |driver|
162
169
  Rake::TestTask.new(driver) do |t|
163
- t.ruby_opts << '-r./tests/test_helper.rb' # Load SimpleCov when COVERAGE=1 is set
170
+ #t.ruby_opts << '-r./tests/test_helper.rb' # Load SimpleCov when COVERAGE=1 is set
164
171
  unless RUBY_VERSION < '1.9.0'
165
172
  t.loader = :testrb
166
173
  end
@@ -199,6 +206,7 @@ namespace :test do
199
206
  t.loader = :testrb
200
207
  end
201
208
  t.test_files = FileList[
209
+ 'tests/cimi/db/*test.rb', # CIMI frontend database tests
202
210
  'tests/cimi/model/*spec.rb', # CIMI frontend serialization API tests
203
211
  'tests/cimi/collections/*test.rb', # CIMI frontend API tests
204
212
  ]
@@ -85,7 +85,7 @@ BANNER
85
85
  opts.on( '-V', '--verbose', 'Set verbose logging on') do |verbose|
86
86
  ENV["API_VERBOSE"] ||= 'true'
87
87
  end
88
- opts.on( nil, '--webrick', 'Force the use of WEBRick as a server') do |opt|
88
+ opts.on( '-w', '--webrick', 'Force the use of WEBRick as a server') do |opt|
89
89
  options[:webrick] = true
90
90
  end
91
91
  opts.on('--logdir LOGDIR', "Directory for log files, defaults to #{options[:logdir]}") do |opt|
@@ -165,7 +165,10 @@ end
165
165
  ENV["API_HOST"] = "localhost" unless ENV["API_HOST"]
166
166
  ENV["API_PORT"] = "3001" unless ENV["API_PORT"]
167
167
 
168
- unless options[:daemon]
168
+ have_thin = options[:webrick].nil? && library_present?('thin')
169
+ have_rerun = library_present?('rerun')
170
+
171
+ if !options[:daemon] || options[:daemon] && !have_thin
169
172
  msg = "Starting Deltacloud API :: #{ENV["API_DRIVER"]} "
170
173
  msg << ":: #{ENV['API_PROVIDER']} " if ENV['API_PROVIDER']
171
174
  api_uri = ENV['API_FRONTEND'] == 'cimi' ? 'cimi/cloudEntryPoint' : 'api'
@@ -184,12 +187,11 @@ if ENV['API_USER'] && ENV['API_PASSWORD']
184
187
  puts
185
188
  end
186
189
 
187
- have_thin = options[:webrick].nil? && library_present?('thin')
188
- have_rerun = library_present?('rerun')
189
-
190
190
  unless have_thin
191
191
  require 'rack'
192
192
 
193
+ puts "To start Deltacloud as a daemon, install 'thin' (gem install thin)\n\n" if options[:daemon]
194
+
193
195
  # Read in config.ru and convert it to an instance of Rack::Builder
194
196
  cfgfile = File.read(File.join($top_srcdir, 'config.ru'))
195
197
  inner_app = eval("Rack::Builder.new {(" + cfgfile + "\n )}.to_app",
@@ -197,19 +199,17 @@ unless have_thin
197
199
 
198
200
  app = Rack::Builder.new {
199
201
  use Rack::CommonLogger # apache-like logging
200
- use Rack::Reloader if options[:env] == "development"
201
- unless RUBY_PLATFORM == 'java'
202
- set :root, $top_srcdir # Set Sinatra root since we can't chdir to ../
203
- end
202
+ use Rack::Reloader #if options[:env] == "development"
204
203
  run inner_app
205
204
  }.to_app
206
205
 
207
206
  # There's a bug with string ports on JRuby so convert to int
208
207
  # http://jira.codehaus.org/browse/JRUBY-4868
209
208
  port = ENV["API_PORT"].to_i
210
-
211
209
  puts "=> Ctrl-C to shutdown server"
210
+ Dir::chdir($top_srcdir)
212
211
  Rack::Server::start(:app => app,
212
+ :server => :webrick,
213
213
  :Host => ENV["API_HOST"],
214
214
  :Port => port,
215
215
  :AccessLog => [])
data/config.ru CHANGED
@@ -30,7 +30,7 @@ end
30
30
 
31
31
  Deltacloud::configure(:cimi) do |server|
32
32
  server.root_url '/cimi'
33
- server.version Deltacloud::API_VERSION
33
+ server.version Deltacloud::CIMI_API_VERSION
34
34
  server.klass 'CIMI::API'
35
35
  end
36
36
 
@@ -54,6 +54,7 @@ end
54
54
  # different root_url's
55
55
  #
56
56
  frontends.each do |frontend|
57
+ frontend = frontend.strip
57
58
  if Deltacloud[frontend.to_sym].nil?
58
59
  puts "ERROR: Unknown frontend (#{frontend}). Valid values are 'deltacloud,cimi,ec2'"
59
60
  exit(1)
@@ -0,0 +1,3 @@
1
+ ---
2
+ :digitalocean:
3
+ :name: Digitalocean
@@ -14,7 +14,7 @@
14
14
  # License for the specific language governing permissions and limitations
15
15
  # under the License.
16
16
 
17
- Kernel::load File::join(File::dirname(__FILE__), './lib/deltacloud/version.rb')
17
+ require File::expand_path(File::join(File::dirname(__FILE__), './lib/deltacloud/version.rb'))
18
18
 
19
19
  Gem::Specification.new do |s|
20
20
  s.author = 'The Apache Software Foundation'
@@ -70,22 +70,29 @@ Gem::Specification.new do |s|
70
70
  s.add_dependency('haml', '>= 2.2.17')
71
71
  s.add_dependency('sinatra', '>= 1.3.0')
72
72
  s.add_dependency('sinatra-rabbit', '>= 1.0.11')
73
- s.add_dependency('crack')
74
73
  s.add_dependency('rack', '>= 1.0.0')
75
74
  s.add_dependency('rack-accept')
76
75
  s.add_dependency('json', '>= 1.1.9')
77
76
  s.add_dependency('net-ssh', '>= 2.0.0')
78
- s.add_dependency('thin', '>= 1.2.5') unless RUBY_PLATFORM == 'java'
79
77
  s.add_dependency('nokogiri', '>= 1.4.3')
80
78
  s.add_dependency('require_relative') if RUBY_VERSION < '1.9'
81
79
 
80
+ s.add_dependency('sequel', '<= 3.42.0')
81
+
82
+ if RUBY_PLATFORM == 'java'
83
+ s.add_dependency('jdbc-sqlite3')
84
+ else
85
+ s.add_dependency('sqlite3')
86
+ s.add_dependency('thin', '>= 1.2.5')
87
+ end
88
+
82
89
  # dependencies for various cloud providers:
83
90
 
84
91
  # RHEV-M and oVirt
85
- s.add_dependency('rbovirt', '>=0.0.13')
92
+ s.add_dependency('rbovirt', '>=0.0.16')
86
93
 
87
94
  # Amazon EC2 S3
88
- s.add_dependency('aws', '>=2.5.4')
95
+ s.add_dependency('aws', '>=2.6.0')
89
96
  # Microsoft Azure
90
97
  s.add_dependency('waz-storage', '>=1.1.0')
91
98
 
@@ -104,7 +111,7 @@ Gem::Specification.new do |s|
104
111
  s.add_dependency('uuidtools', '>= 2.1.1')
105
112
 
106
113
  # Openstack Compute and Object-Storage
107
- s.add_dependency('openstack', '>= 1.0.6')
114
+ s.add_dependency('openstack', '>= 1.0.7')
108
115
 
109
116
  # Aruba Cloud
110
117
  s.add_dependency('savon', '>= 1.0.0')
@@ -39,7 +39,7 @@ module CIMI
39
39
  Dir[File.join(File::dirname(__FILE__), "collections", "*.rb")].each do |collection|
40
40
  base_collection_name = File.basename(collection).gsub('.rb', '')
41
41
  next if base_collection_name == 'base'
42
- require_relative collection
42
+ require collection
43
43
  cimi_module_class = CIMI::Collections.const_get(base_collection_name.camelize)
44
44
  cimi_modules << cimi_module_class
45
45
  unless cimi_module_class.collections.nil?
@@ -16,11 +16,11 @@
16
16
  module CIMI::Collections
17
17
  class AddressTemplates < Base
18
18
 
19
- set :capability, lambda { |m| driver.respond_to? m }
19
+ set :capability, lambda { |t| true }
20
20
 
21
21
  collection :address_templates do
22
22
 
23
- operation :index, :with_capability => :address_templates do
23
+ operation :index do
24
24
  description 'List all AddressTemplates in the AddressTemplateCollection'
25
25
  control do
26
26
  address_templates = AddressTemplate.list(self).filter_by(params['$select'])
@@ -31,7 +31,7 @@ module CIMI::Collections
31
31
  end
32
32
  end
33
33
 
34
- operation :show, :with_capability => :address_templates do
34
+ operation :show do
35
35
  description 'Show a specific AddressTemplate'
36
36
  control do
37
37
  address_template = CIMI::Model::AddressTemplate.find(params[:id], self)
@@ -42,6 +42,30 @@ module CIMI::Collections
42
42
  end
43
43
  end
44
44
 
45
+ operation :create do
46
+ description "Create new AddressTemplate"
47
+ control do
48
+ if grab_content_type(request.content_type, request.body) == :json
49
+ new_address_template = CIMI::Model::AddressTemplate.create_from_json(request.body.read, self)
50
+ else
51
+ new_address_template = CIMI::Model::AddressTemplate.create_from_xml(request.body.read, self)
52
+ end
53
+ headers_for_create new_address_template
54
+ respond_to do |format|
55
+ format.json { new_address_template.to_json }
56
+ format.xml { new_address_template.to_xml }
57
+ end
58
+ end
59
+ end
60
+
61
+ operation :destroy do
62
+ description "Delete a specified AddressTemplate"
63
+ control do
64
+ CIMI::Model::AddressTemplate.delete!(params[:id], self)
65
+ no_content_with_status(200)
66
+ end
67
+ end
68
+
45
69
  end
46
70
 
47
71
  end
@@ -47,7 +47,7 @@ module CIMI::Collections
47
47
  operation :create, :with_capability => :create_address do
48
48
  description "Create a new Address"
49
49
  control do
50
- if request.content_type.end_with?("json")
50
+ if grab_content_type(request.content_type, request.body) == :json
51
51
  address = CIMI::Model::Address.create(request.body.read, self, :json)
52
52
  else
53
53
  address = CIMI::Model::Address.create(request.body.read, self, :xml)
@@ -23,6 +23,7 @@ module CIMI::Collections
23
23
  include CIMI::Model
24
24
 
25
25
  helpers Deltacloud::Helpers::Drivers
26
+ helpers Deltacloud::Helpers::Database
26
27
  helpers Sinatra::AuthHelper
27
28
  helpers Sinatra::Rabbit::URLHelper
28
29
  helpers Deltacloud::Helpers::Application
@@ -16,6 +16,10 @@
16
16
  module CIMI::Collections
17
17
  class CloudEntryPoint < Base
18
18
 
19
+ get '/' do
20
+ redirect url('/cloudEntryPoint'), 301
21
+ end
22
+
19
23
  collection :cloudEntryPoint do
20
24
  description 'Cloud entry point'
21
25
  operation :index do
@@ -46,12 +46,12 @@ module CIMI::Collections
46
46
  operation :create, :with_capability => :create_key do
47
47
  description "Show specific machine admin"
48
48
  control do
49
- if request.content_type.end_with?("json")
49
+ if grab_content_type(request.content_type, request.body) == :json
50
50
  new_admin = Credential.create_from_json(request.body.read, self)
51
51
  else
52
52
  new_admin = Credential.create_from_xml(request.body.read, self)
53
53
  end
54
- status 201 # Created
54
+ headers_for_create new_admin
55
55
  respond_to do |format|
56
56
  format.json { new_admin.to_json }
57
57
  format.xml { new_admin.to_xml }
@@ -43,6 +43,26 @@ module CIMI::Collections
43
43
  end
44
44
  end
45
45
 
46
+ operation :create, :with_capability => :create_image do
47
+ description "Create a new machine image."
48
+ control do
49
+ machine_image = CIMI::Model::MachineImage.create(request.body, self)
50
+ headers_for_create machine_image
51
+ respond_to do |format|
52
+ format.xml { machine_image.to_xml }
53
+ format.json { machine_image.to_json }
54
+ end
55
+ end
56
+ end
57
+
58
+ operation :destroy, :with_capability => :destroy_image do
59
+ description "Delete a specified MachineImage"
60
+ control do
61
+ CIMI::Model::MachineImage.delete!(params[:id], self)
62
+ no_content_with_status 200
63
+ end
64
+ end
65
+
46
66
  end
47
67
 
48
68
  end
@@ -0,0 +1,72 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ module CIMI::Collections
17
+ class MachineTemplates < Base
18
+
19
+ set :capability, lambda { |t| true }
20
+
21
+ collection :machine_templates do
22
+
23
+ operation :index do
24
+ description "List all machine templates"
25
+ control do
26
+ machine_templates = CIMI::Model::MachineTemplate.list(self).filter_by(params['$select'])
27
+ respond_to do |format|
28
+ format.xml { machine_templates.to_xml }
29
+ format.json { machine_templates.to_json }
30
+ end
31
+ end
32
+ end
33
+
34
+ operation :show do
35
+ description "Show specific machine template"
36
+ control do
37
+ machine_template = CIMI::Model::MachineTemplate.find(params[:id], self)
38
+ respond_to do |format|
39
+ format.xml { machine_template.to_xml }
40
+ format.json { machine_template.to_json }
41
+ end
42
+ end
43
+ end
44
+
45
+ operation :create do
46
+ description "Create new machine template"
47
+ control do
48
+ if grab_content_type(request.content_type, request.body) == :json
49
+ new_machine_template = CIMI::Model::MachineTemplate.create_from_json(request.body.read, self)
50
+ else
51
+ new_machine_template = CIMI::Model::MachineTemplate.create_from_xml(request.body.read, self)
52
+ end
53
+ headers_for_create new_machine_template
54
+ respond_to do |format|
55
+ format.json { new_machine_template.to_json }
56
+ format.xml { new_machine_template.to_xml }
57
+ end
58
+ end
59
+ end
60
+
61
+ operation :destroy do
62
+ description "Delete a specified machine template"
63
+ control do
64
+ CIMI::Model::MachineTemplate.delete!(params[:id], self)
65
+ no_content_with_status(200)
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+ end
@@ -46,13 +46,12 @@ module CIMI::Collections
46
46
  operation :create, :with_capability => :create_instance do
47
47
  description "Create a new Machine entity."
48
48
  control do
49
- if request.content_type.end_with?("json")
49
+ if grab_content_type(request.content_type, request.body) == :json
50
50
  new_machine = Machine.create_from_json(request.body.read, self)
51
51
  else
52
52
  new_machine = Machine.create_from_xml(request.body.read, self)
53
53
  end
54
- status 201 # Created
55
- headers 'Location' => new_machine.id
54
+ headers_for_create new_machine
56
55
  respond_to do |format|
57
56
  format.json { new_machine.to_json }
58
57
  format.xml { new_machine.to_xml }
@@ -73,7 +72,7 @@ module CIMI::Collections
73
72
  param :id, :string, :required
74
73
  control do
75
74
  machine = Machine.find(params[:id], self)
76
- if request.content_type.end_with?("json")
75
+ if grab_content_type(request.content_type, request.body) == :json
77
76
  action = Action.from_json(request.body.read)
78
77
  else
79
78
  action = Action.from_xml(request.body.read)
@@ -85,15 +84,15 @@ module CIMI::Collections
85
84
  end
86
85
  end
87
86
 
88
- action :restart, :with_capability => :restart_instance do
87
+ action :restart, :with_capability => :reboot_instance do
89
88
  description "Start specific machine."
90
89
  param :id, :string, :required
91
90
  control do
92
91
  machine = Machine.find(params[:id], self)
93
- if request.content_type.end_with?("json")
94
- action = Action.from_json(request.body.read)
92
+ if grab_content_type(request.content_type, request.body) == :json
93
+ action = Action.from_json(request.body.read.gsub("restart", "reboot"))
95
94
  else
96
- action = Action.from_xml(request.body.read)
95
+ action = Action.from_xml(request.body.read.gsub("restart", "reboot"))
97
96
  end
98
97
  machine.perform(action, self) do |operation|
99
98
  no_content_with_status(202) if operation.success?
@@ -107,7 +106,7 @@ module CIMI::Collections
107
106
  param :id, :string, :required
108
107
  control do
109
108
  machine = Machine.find(params[:id], self)
110
- if request.content_type.end_with?("json")
109
+ if grab_content_type(request.content_type, request.body) == :json
111
110
  action = Action.from_json(request.body.read)
112
111
  else
113
112
  action = Action.from_xml(request.body.read)
@@ -131,54 +130,64 @@ module CIMI::Collections
131
130
  end
132
131
  end
133
132
 
134
- operation :volumes, :with_capability => :storage_volumes do
135
- description "Retrieve the Machine's MachineVolumeCollection"
136
- param :id, :string, :required
137
- control do
138
- volumes = MachineVolumeCollection.default(params[:id], self)
139
- respond_to do |format|
140
- format.json {volumes.to_json}
141
- format.xml {volumes.to_xml}
133
+ #use rabbit subcollections for volumes index/show:
134
+ collection :volumes, :with_id => :vol_id do
135
+
136
+ operation :index, :with_capability => :storage_volumes do
137
+ description "Retrieve the Machine's MachineVolumeCollection"
138
+ control do
139
+ volumes = CIMI::Model::MachineVolume.collection_for_instance(params[:id], self)
140
+ respond_to do |format|
141
+ format.json {volumes.to_json}
142
+ format.xml {volumes.to_xml}
143
+ end
142
144
  end
143
145
  end
144
- end
145
146
 
146
- #NOTE: The routes for attach/detach used here are NOT as specified by CIMI
147
- #will likely move later. CIMI specifies PUT of the whole Machine description
148
- #with inclusion/ommission of the volumes you want [att|det]ached
149
- action :attach_volume, :http_method => :put, :with_capability => :attach_storage_volume do
150
- description "Attach CIMI Volume(s) to a machine."
151
- param :id, :string, :required
152
- control do
153
- if request.content_type.end_with?("json")
154
- volumes_to_attach = Volume.find_to_attach_from_json(request.body.read, self)
155
- else
156
- volumes_to_attach = Volume.find_to_attach_from_xml(request.body.read, self)
147
+ operation :show, :with_capability => :storage_volumes do
148
+ description "Retrieve a Machine's specific MachineVolume"
149
+ control do
150
+ volume = CIMI::Model::MachineVolume.find(params[:id], self, params[:vol_id])
151
+ respond_to do |format|
152
+ format.json {volume.to_json}
153
+ format.xml {volume.to_xml}
154
+ end
157
155
  end
158
- machine = Machine.attach_volumes(volumes_to_attach, self)
159
- respond_to do |format|
160
- format.json{ machine.to_json}
161
- format.xml{machine.to_xml}
156
+ end
157
+
158
+ operation :destroy, :with_capability => :detach_storage_volume do
159
+ description "Remove/detach a volume from the Machine's MachineVolumeCollection"
160
+ control do
161
+ machine_volume = CIMI::Model::MachineVolume.find(params[:id], self, params[:vol_id])
162
+ location = machine_volume.initial_location
163
+ machine_volumes = Machine.detach_volume(params[:vol_id], location, self)
164
+ respond_to do |format|
165
+ format.json{ machine_volumes.to_json}
166
+ format.xml{ machine_volumes.to_xml}
167
+ end
162
168
  end
163
169
  end
170
+
164
171
  end
165
172
 
166
- action :detach_volume, :http_method => :put, :with_capability => :detach_storage_volume do
167
- description "Detach CIMI Volume(s) from a machine."
173
+ operation :volume_attach, :http_method => :post, :with_capability => :attach_storage_volume do
174
+ description "Attach CIMI Volume(s) to a machine."
168
175
  param :id, :string, :required
169
176
  control do
170
- if request.content_type.end_with?("json")
171
- volumes_to_detach = Volume.find_to_attach_from_json(request.body.read, self)
177
+ if grab_content_type(request.content_type, request.body) == :json
178
+ volume_to_attach, location = MachineVolume.find_to_attach_from_json(request.body.read, self)
172
179
  else
173
- volumes_to_detach = Volume.find_to_attach_from_xml(request.body.read, self)
180
+ volume_to_attach, location = MachineVolume.find_to_attach_from_xml(request.body.read, self)
174
181
  end
175
- machine = Machine.detach_volumes(volumes_to_detach, self)
182
+ machine_volume = Machine.attach_volume(volume_to_attach,location, self)
183
+ headers_for_create machine_volume
176
184
  respond_to do |format|
177
- format.json{ machine.to_json}
178
- format.xml{machine.to_xml}
185
+ format.json{ machine_volume.to_json}
186
+ format.xml{machine_volume.to_xml}
179
187
  end
180
188
  end
181
189
  end
190
+
182
191
  end
183
192
 
184
193
  end