bbrowning-deltacloud-core 0.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +502 -0
- data/Rakefile +85 -0
- data/bin/deltacloudd +88 -0
- data/config.ru +5 -0
- data/deltacloud.rb +14 -0
- data/lib/deltacloud/base_driver.rb +19 -0
- data/lib/deltacloud/base_driver/base_driver.rb +189 -0
- data/lib/deltacloud/base_driver/features.rb +159 -0
- data/lib/deltacloud/base_driver/mock_driver.rb +37 -0
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +340 -0
- data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +170 -0
- data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +45 -0
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +322 -0
- data/lib/deltacloud/drivers/mock/mock_driver.rb +275 -0
- data/lib/deltacloud/drivers/opennebula/cloud_client.rb +116 -0
- data/lib/deltacloud/drivers/opennebula/occi_client.rb +204 -0
- data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +241 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +129 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +150 -0
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +254 -0
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_client.rb +84 -0
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +144 -0
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +261 -0
- data/lib/deltacloud/hardware_profile.rb +153 -0
- data/lib/deltacloud/helpers.rb +5 -0
- data/lib/deltacloud/helpers/application_helper.rb +56 -0
- data/lib/deltacloud/helpers/conversion_helper.rb +38 -0
- data/lib/deltacloud/helpers/hardware_profiles_helper.rb +35 -0
- data/lib/deltacloud/method_serializer.rb +84 -0
- data/lib/deltacloud/models/base_model.rb +58 -0
- data/lib/deltacloud/models/image.rb +26 -0
- data/lib/deltacloud/models/instance.rb +37 -0
- data/lib/deltacloud/models/instance_profile.rb +47 -0
- data/lib/deltacloud/models/realm.rb +25 -0
- data/lib/deltacloud/models/storage_snapshot.rb +26 -0
- data/lib/deltacloud/models/storage_volume.rb +27 -0
- data/lib/deltacloud/state_machine.rb +84 -0
- data/lib/deltacloud/validation.rb +70 -0
- data/lib/drivers.rb +38 -0
- data/lib/sinatra/accept_media_types.rb +128 -0
- data/lib/sinatra/lazy_auth.rb +56 -0
- data/lib/sinatra/rabbit.rb +272 -0
- data/lib/sinatra/respond_to.rb +269 -0
- data/lib/sinatra/static_assets.rb +83 -0
- data/lib/sinatra/url_for.rb +51 -0
- data/public/favicon.ico +0 -0
- data/public/images/grid.png +0 -0
- data/public/images/logo-wide.png +0 -0
- data/public/images/rails.png +0 -0
- data/public/images/topbar-bg.png +0 -0
- data/public/javascripts/application.js +32 -0
- data/public/javascripts/jquery-1.4.2.min.js +154 -0
- data/public/stylesheets/compiled/application.css +613 -0
- data/public/stylesheets/compiled/ie.css +31 -0
- data/public/stylesheets/compiled/print.css +27 -0
- data/public/stylesheets/compiled/screen.css +456 -0
- data/server.rb +342 -0
- data/support/fedora/deltacloudd +68 -0
- data/support/fedora/rubygem-deltacloud-core.spec +91 -0
- data/tests/deltacloud_test.rb +60 -0
- data/tests/images_test.rb +94 -0
- data/tests/instances_test.rb +136 -0
- data/tests/realms_test.rb +56 -0
- data/tests/storage_snapshots_test.rb +48 -0
- data/tests/storage_volumes_test.rb +48 -0
- data/torquebox-ec2-config.ru +8 -0
- data/views/accounts/index.html.haml +11 -0
- data/views/accounts/show.html.haml +30 -0
- data/views/api/show.html.haml +15 -0
- data/views/api/show.xml.haml +5 -0
- data/views/docs/collection.html.haml +37 -0
- data/views/docs/collection.xml.haml +14 -0
- data/views/docs/index.html.haml +15 -0
- data/views/docs/index.xml.haml +5 -0
- data/views/docs/operation.html.haml +31 -0
- data/views/docs/operation.xml.haml +10 -0
- data/views/errors/auth_exception.html.haml +8 -0
- data/views/errors/auth_exception.xml.haml +2 -0
- data/views/errors/backend_error.html.haml +17 -0
- data/views/errors/backend_error.xml.haml +8 -0
- data/views/errors/validation_failure.html.haml +11 -0
- data/views/errors/validation_failure.xml.haml +7 -0
- data/views/hardware_profiles/index.html.haml +25 -0
- data/views/hardware_profiles/index.xml.haml +4 -0
- data/views/hardware_profiles/show.html.haml +19 -0
- data/views/hardware_profiles/show.xml.haml +17 -0
- data/views/images/index.html.haml +30 -0
- data/views/images/index.xml.haml +7 -0
- data/views/images/show.html.haml +21 -0
- data/views/images/show.xml.haml +5 -0
- data/views/instance_states/show.gv.erb +45 -0
- data/views/instance_states/show.html.haml +31 -0
- data/views/instance_states/show.xml.haml +8 -0
- data/views/instances/index.html.haml +30 -0
- data/views/instances/index.xml.haml +23 -0
- data/views/instances/new.html.haml +55 -0
- data/views/instances/show.html.haml +43 -0
- data/views/instances/show.xml.haml +41 -0
- data/views/layout.html.haml +26 -0
- data/views/realms/index.html.haml +29 -0
- data/views/realms/index.xml.haml +12 -0
- data/views/realms/show.html.haml +15 -0
- data/views/realms/show.xml.haml +10 -0
- data/views/root/index.html.haml +4 -0
- data/views/storage_snapshots/index.html.haml +20 -0
- data/views/storage_snapshots/index.xml.haml +11 -0
- data/views/storage_snapshots/show.html.haml +14 -0
- data/views/storage_snapshots/show.xml.haml +9 -0
- data/views/storage_volumes/index.html.haml +21 -0
- data/views/storage_volumes/index.xml.haml +13 -0
- data/views/storage_volumes/show.html.haml +20 -0
- data/views/storage_volumes/show.xml.haml +13 -0
- metadata +361 -0
data/Rakefile
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2009 Red Hat, Inc.
|
3
|
+
#
|
4
|
+
# This library is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU Lesser General Public
|
6
|
+
# License as published by the Free Software Foundation; either
|
7
|
+
# version 2.1 of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
+
# Lesser General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
15
|
+
# License along with this library; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
17
|
+
|
18
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
19
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
20
|
+
|
21
|
+
require 'rake'
|
22
|
+
require 'rake/testtask'
|
23
|
+
require 'rake/gempackagetask'
|
24
|
+
|
25
|
+
desc "Run basic unit tests"
|
26
|
+
Rake::TestTask.new("test") { |t|
|
27
|
+
t.test_files = FileList[
|
28
|
+
'tests/realms_test.rb',
|
29
|
+
'tests/images_test.rb',
|
30
|
+
'tests/instances_test.rb',
|
31
|
+
'tests/storage_volumes_test.rb',
|
32
|
+
'tests/storage_snapshots_test.rb',
|
33
|
+
]
|
34
|
+
t.verbose = false
|
35
|
+
t.warning = false
|
36
|
+
}
|
37
|
+
|
38
|
+
load 'deltacloud-core.gemspec'
|
39
|
+
|
40
|
+
Rake::GemPackageTask.new(@spec) do |pkg|
|
41
|
+
pkg.need_tar = true
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Install API"
|
45
|
+
task :install, [:install_dir, :bin_dir] do |t, args|
|
46
|
+
|
47
|
+
require 'fileutils'
|
48
|
+
require 'pp'
|
49
|
+
|
50
|
+
files = FileList[
|
51
|
+
Dir["config/**/**"],
|
52
|
+
Dir["features/**/**"],
|
53
|
+
Dir["lib/**/**"],
|
54
|
+
Dir["public/**/**"],
|
55
|
+
Dir["views/**/**"],
|
56
|
+
"config.ru",
|
57
|
+
"COPYING",
|
58
|
+
"README",
|
59
|
+
"*.rb"
|
60
|
+
]
|
61
|
+
|
62
|
+
INSTALL_DIR=args.install_dir || "/usr/local/share/deltacloud-core"
|
63
|
+
BIN_DIR=args.bin_dir || "/usr/local/bin"
|
64
|
+
|
65
|
+
exit(1) unless FileUtils.mkdir_p(INSTALL_DIR)
|
66
|
+
exit(1) unless FileUtils.mkdir_p(BIN_DIR)
|
67
|
+
|
68
|
+
files.each do |f|
|
69
|
+
install_path = "#{INSTALL_DIR}/#{File.dirname(f)}"
|
70
|
+
unless File.directory?(install_path)
|
71
|
+
FileUtils.mkdir_p(install_path, :mode => 0755, :verbose => true)
|
72
|
+
end
|
73
|
+
next if File.directory?(f)
|
74
|
+
FileUtils.install(f, "#{INSTALL_DIR}/#{File.dirname(f)}", :verbose => true)
|
75
|
+
end
|
76
|
+
|
77
|
+
FileUtils.install('bin/deltacloudd', BIN_DIR, :verbose => true, :mode => 0755)
|
78
|
+
end
|
79
|
+
|
80
|
+
desc "Uninstall API"
|
81
|
+
task :uninstall do
|
82
|
+
require 'fileutils'
|
83
|
+
INSTALL_DIR="/usr/share/deltacloud-core"
|
84
|
+
FileUtils.rm_rf(INSTALL_DIR)
|
85
|
+
end
|
data/bin/deltacloudd
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require 'thin'
|
6
|
+
|
7
|
+
options = {
|
8
|
+
:env => 'development'
|
9
|
+
}
|
10
|
+
optparse = OptionParser.new do |opts|
|
11
|
+
|
12
|
+
opts.banner = <<BANNER
|
13
|
+
Usage:
|
14
|
+
deltacloudd -i <driver> [options]
|
15
|
+
|
16
|
+
Options:
|
17
|
+
BANNER
|
18
|
+
opts.on( '-i', '--driver DRIVER', 'Driver to use') do |driver|
|
19
|
+
ENV["API_DRIVER"] = driver
|
20
|
+
end
|
21
|
+
opts.on( '-r', '--hostname HOSTNAME',
|
22
|
+
'Bind to HOST address (default: localhost)') do |host|
|
23
|
+
ENV["API_HOST"] = host
|
24
|
+
end
|
25
|
+
opts.on( '-p', '--port PORT', 'Use PORT (default: 3001)') do |port|
|
26
|
+
ENV["API_PORT"] = port
|
27
|
+
end
|
28
|
+
opts.on( '-e', '--env ENV', 'Environment (default: "development")') { |env| options[:env] = env }
|
29
|
+
opts.on( '-h', '--help', '') { options[:help] = true }
|
30
|
+
end
|
31
|
+
|
32
|
+
optparse.parse!
|
33
|
+
|
34
|
+
if options[:help]
|
35
|
+
puts optparse
|
36
|
+
exit(0)
|
37
|
+
end
|
38
|
+
|
39
|
+
unless ENV["API_DRIVER"]
|
40
|
+
puts "You need to specify a driver to use (-i <driver>)"
|
41
|
+
exit(1)
|
42
|
+
end
|
43
|
+
|
44
|
+
ENV["API_HOST"] = "localhost" unless ENV["API_HOST"]
|
45
|
+
ENV["API_PORT"] = "3001" unless ENV["API_PORT"]
|
46
|
+
|
47
|
+
dirname="#{File.dirname(__FILE__)}/.."
|
48
|
+
|
49
|
+
argv_opts = ARGV.clone
|
50
|
+
argv_opts << ['start'] unless Thin::Runner.commands.include?(options[0])
|
51
|
+
argv_opts << ['--address', ENV["API_HOST"] ]
|
52
|
+
argv_opts << ['--port', ENV["API_PORT"] ]
|
53
|
+
argv_opts << ['--rackup', 'config.ru' ]
|
54
|
+
argv_opts << ['--chdir', dirname ]
|
55
|
+
argv_opts << ['-e', options[:env] ]
|
56
|
+
argv_opts << ['--threaded', '-D', '--stats', '/stats']
|
57
|
+
|
58
|
+
argv_opts.flatten!
|
59
|
+
|
60
|
+
if options[:env] == "development"
|
61
|
+
use_rerun = false
|
62
|
+
begin
|
63
|
+
require "rerun"
|
64
|
+
use_rerun = true
|
65
|
+
rescue
|
66
|
+
# Do nothing
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
puts "Starting Deltacloud API :: #{ENV["API_DRIVER"]} :: http://#{ENV["API_HOST"]}:#{ENV["API_PORT"]}/api"
|
71
|
+
puts
|
72
|
+
|
73
|
+
if use_rerun
|
74
|
+
argv_opts.unshift "thin"
|
75
|
+
command = argv_opts.join(" ")
|
76
|
+
topdir = File::expand_path(File::join(File::dirname(__FILE__), ".."))
|
77
|
+
rerun = Rerun::Runner.new(command, :dir => topdir)
|
78
|
+
rerun.start
|
79
|
+
rerun.join
|
80
|
+
else
|
81
|
+
thin = Thin::Runner.new(argv_opts)
|
82
|
+
|
83
|
+
begin
|
84
|
+
thin.run!
|
85
|
+
rescue Exception => e
|
86
|
+
puts "ERROR: #{e.message}"
|
87
|
+
end
|
88
|
+
end
|
data/config.ru
ADDED
data/deltacloud.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Add ./lib into load path
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
3
|
+
|
4
|
+
require 'deltacloud/base_driver'
|
5
|
+
require 'deltacloud/hardware_profile'
|
6
|
+
require 'deltacloud/state_machine'
|
7
|
+
|
8
|
+
require 'deltacloud/models/base_model'
|
9
|
+
require 'deltacloud/models/realm'
|
10
|
+
require 'deltacloud/models/image'
|
11
|
+
require 'deltacloud/models/instance'
|
12
|
+
require 'deltacloud/models/instance_profile'
|
13
|
+
require 'deltacloud/models/storage_snapshot'
|
14
|
+
require 'deltacloud/models/storage_volume'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2009 Red Hat, Inc.
|
3
|
+
#
|
4
|
+
# This library is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU Lesser General Public
|
6
|
+
# License as published by the Free Software Foundation; either
|
7
|
+
# version 2.1 of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
+
# Lesser General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
15
|
+
# License along with this library; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
17
|
+
|
18
|
+
require 'deltacloud/base_driver/base_driver'
|
19
|
+
require 'deltacloud/base_driver/features'
|
@@ -0,0 +1,189 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2009 Red Hat, Inc.
|
3
|
+
#
|
4
|
+
# This library is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU Lesser General Public
|
6
|
+
# License as published by the Free Software Foundation; either
|
7
|
+
# version 2.1 of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
+
# Lesser General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
15
|
+
# License along with this library; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
17
|
+
|
18
|
+
module Deltacloud
|
19
|
+
|
20
|
+
class AuthException < Exception
|
21
|
+
end
|
22
|
+
|
23
|
+
class BackendError < StandardError
|
24
|
+
attr_reader :code, :cause, :details
|
25
|
+
def initialize(code, cause, message, details)
|
26
|
+
super(message)
|
27
|
+
@code = code
|
28
|
+
@cause = cause
|
29
|
+
@details = details
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class BaseDriver
|
34
|
+
|
35
|
+
def self.define_hardware_profile(name,&block)
|
36
|
+
@hardware_profiles ||= []
|
37
|
+
hw_profile = @hardware_profiles.find{|e| e.name == name}
|
38
|
+
return if hw_profile
|
39
|
+
hw_profile = ::Deltacloud::HardwareProfile.new( name, &block )
|
40
|
+
@hardware_profiles << hw_profile
|
41
|
+
hw_params = hw_profile.params
|
42
|
+
unless hw_params.empty?
|
43
|
+
feature :instances, :hardware_profiles do
|
44
|
+
decl.operation(:create) { add_params(hw_params) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.hardware_profiles
|
50
|
+
@hardware_profiles ||= []
|
51
|
+
@hardware_profiles
|
52
|
+
end
|
53
|
+
|
54
|
+
def hardware_profiles(credentials, opts = nil)
|
55
|
+
results = self.class.hardware_profiles
|
56
|
+
filter_hardware_profiles(results, opts)
|
57
|
+
end
|
58
|
+
|
59
|
+
def hardware_profile(credentials, name)
|
60
|
+
hardware_profiles(credentials, :name => name).first
|
61
|
+
end
|
62
|
+
|
63
|
+
def filter_hardware_profiles(profiles, opts)
|
64
|
+
if opts
|
65
|
+
if v = opts[:architecture]
|
66
|
+
profiles = profiles.select { |hwp| hwp.include?(:architecture, v) }
|
67
|
+
end
|
68
|
+
if v = opts[:name]
|
69
|
+
profiles = profiles.select { |hwp| hwp.name == v }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
profiles
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_hardware_profile(credentials, name, image_id)
|
76
|
+
hwp = nil
|
77
|
+
if name
|
78
|
+
unless hwp = hardware_profiles(credentials, :name => name).first
|
79
|
+
raise BackendError.new(400, "bad-hardware-profile-name",
|
80
|
+
"Hardware profile '#{name}' does not exist", nil)
|
81
|
+
end
|
82
|
+
else
|
83
|
+
unless image = image(credentials, :id=>image_id)
|
84
|
+
raise BackendError.new(400, "bad-image-id",
|
85
|
+
"Image with ID '#{image_id}' does not exist", nil)
|
86
|
+
end
|
87
|
+
hwp = hardware_profiles(credentials,
|
88
|
+
:architecture=>image.architecture).first
|
89
|
+
end
|
90
|
+
return hwp
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.define_instance_states(&block)
|
94
|
+
machine = ::Deltacloud::StateMachine.new(&block)
|
95
|
+
@instance_state_machine = machine
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.instance_state_machine
|
99
|
+
@instance_state_machine
|
100
|
+
end
|
101
|
+
|
102
|
+
def instance_state_machine
|
103
|
+
self.class.instance_state_machine
|
104
|
+
end
|
105
|
+
|
106
|
+
def instance_actions_for(state)
|
107
|
+
actions = []
|
108
|
+
state_key = state.downcase.to_sym
|
109
|
+
states = instance_state_machine.states()
|
110
|
+
current_state = states.find{|e| e.name == state.underscore.to_sym }
|
111
|
+
if ( current_state )
|
112
|
+
actions = current_state.transitions.collect{|e|e.action}
|
113
|
+
actions.reject!{|e| e.nil?}
|
114
|
+
end
|
115
|
+
actions
|
116
|
+
end
|
117
|
+
|
118
|
+
def realm(credentials, opts)
|
119
|
+
realms = realms(credentials, opts)
|
120
|
+
return realms.first unless realms.empty?
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
|
124
|
+
def realms(credentials, opts=nil)
|
125
|
+
[]
|
126
|
+
end
|
127
|
+
|
128
|
+
def image(credentials, opts)
|
129
|
+
images = images(credentials, opts)
|
130
|
+
return images.first unless images.empty?
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
134
|
+
def images(credentials, ops)
|
135
|
+
[]
|
136
|
+
end
|
137
|
+
|
138
|
+
def instance(credentials, opts)
|
139
|
+
instances = instances(credentials, opts)
|
140
|
+
return instances.first unless instances.empty?
|
141
|
+
nil
|
142
|
+
end
|
143
|
+
|
144
|
+
def instances(credentials, ops)
|
145
|
+
[]
|
146
|
+
end
|
147
|
+
|
148
|
+
def create_instance(credentials, image_id, opts)
|
149
|
+
end
|
150
|
+
def start_instance(credentials, id)
|
151
|
+
end
|
152
|
+
def stop_instance(credentials, id)
|
153
|
+
end
|
154
|
+
def reboot_instance(credentials, id)
|
155
|
+
end
|
156
|
+
|
157
|
+
def storage_volume(credentials, opts)
|
158
|
+
volumes = storage_volumes(credentials, opts)
|
159
|
+
return volumes.first unless volumes.empty?
|
160
|
+
nil
|
161
|
+
end
|
162
|
+
|
163
|
+
def storage_volumes(credentials, ops)
|
164
|
+
[]
|
165
|
+
end
|
166
|
+
|
167
|
+
def storage_snapshot(credentials, opts)
|
168
|
+
snapshots = storage_snapshots(credentials, opts)
|
169
|
+
return snapshots.first unless snapshots.empty?
|
170
|
+
nil
|
171
|
+
end
|
172
|
+
|
173
|
+
def storage_snapshots(credentials, ops)
|
174
|
+
[]
|
175
|
+
end
|
176
|
+
|
177
|
+
def filter_on(collection, attribute, opts)
|
178
|
+
return collection if opts.nil?
|
179
|
+
return collection if opts[attribute].nil?
|
180
|
+
filter = opts[attribute]
|
181
|
+
if ( filter.is_a?( Array ) )
|
182
|
+
return collection.select{|e| filter.include?( e.send(attribute) ) }
|
183
|
+
else
|
184
|
+
return collection.select{|e| filter == e.send(attribute) }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'deltacloud/validation'
|
2
|
+
|
3
|
+
# Add advertising of optional features to the base driver
|
4
|
+
module Deltacloud
|
5
|
+
|
6
|
+
class FeatureError < StandardError; end
|
7
|
+
class DuplicateFeatureDeclError < FeatureError; end
|
8
|
+
class UndeclaredFeatureError < FeatureError; end
|
9
|
+
|
10
|
+
class BaseDriver
|
11
|
+
|
12
|
+
# An operation on a collection like cretae or show. Features
|
13
|
+
# can add parameters to operations
|
14
|
+
class Operation
|
15
|
+
attr_reader :name
|
16
|
+
|
17
|
+
include Deltacloud::Validation
|
18
|
+
|
19
|
+
def initialize(name, &block)
|
20
|
+
@name = name
|
21
|
+
@params = {}
|
22
|
+
instance_eval &block
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# The declaration of a feature, defines what operations
|
27
|
+
# are modified by it
|
28
|
+
class FeatureDecl
|
29
|
+
attr_reader :name, :operations
|
30
|
+
|
31
|
+
def initialize(name, &block)
|
32
|
+
@name = name
|
33
|
+
@operations = []
|
34
|
+
instance_eval &block
|
35
|
+
end
|
36
|
+
|
37
|
+
def description(text=nil)
|
38
|
+
@description = text if text
|
39
|
+
@description
|
40
|
+
end
|
41
|
+
|
42
|
+
# Add a new operation or modify an existing one through BLOCK
|
43
|
+
def operation(name, &block)
|
44
|
+
unless op = @operations.find { |op| op.name == name }
|
45
|
+
op = Operation.new(name, &block)
|
46
|
+
@operations << op
|
47
|
+
else
|
48
|
+
op.instance_eval(&block) if block_given?
|
49
|
+
end
|
50
|
+
op
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# A specific feature enabled by a driver (see +feature+)
|
55
|
+
class Feature
|
56
|
+
attr_reader :decl
|
57
|
+
|
58
|
+
def initialize(decl, &block)
|
59
|
+
@decl = decl
|
60
|
+
instance_eval &block if block_given?
|
61
|
+
end
|
62
|
+
|
63
|
+
def name
|
64
|
+
decl.name
|
65
|
+
end
|
66
|
+
|
67
|
+
def operations
|
68
|
+
decl.operations
|
69
|
+
end
|
70
|
+
|
71
|
+
def description
|
72
|
+
decl.description
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.feature_decls
|
77
|
+
@@feature_decls ||= {}
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.feature_decl_for(collection, name)
|
81
|
+
decls = feature_decls[collection]
|
82
|
+
if decls
|
83
|
+
decls.find { |dcl| dcl.name == name }
|
84
|
+
else
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Declare a new feature
|
90
|
+
def self.declare_feature(collection, name, &block)
|
91
|
+
feature_decls[collection] ||= []
|
92
|
+
raise DuplicateFeatureDeclError if feature_decl_for(collection, name)
|
93
|
+
feature_decls[collection] << FeatureDecl.new(name, &block)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.features
|
97
|
+
@@features ||= {}
|
98
|
+
end
|
99
|
+
|
100
|
+
# Declare in a driver that it supports a specific feature
|
101
|
+
#
|
102
|
+
# The same feature can be declared multiple times in a driver, so that
|
103
|
+
# it can be changed successively by passing in different blocks.
|
104
|
+
def self.feature(collection, name, &block)
|
105
|
+
features[collection] ||= []
|
106
|
+
if f = features[collection].find { |f| f.name == name }
|
107
|
+
f.instance_eval(&block) if block_given?
|
108
|
+
return f
|
109
|
+
end
|
110
|
+
unless decl = feature_decl_for(collection, name)
|
111
|
+
raise UndeclaredFeatureError, "No feature #{name} for #{collection}"
|
112
|
+
end
|
113
|
+
features[collection] << Feature.new(decl, &block)
|
114
|
+
end
|
115
|
+
|
116
|
+
def features(collection)
|
117
|
+
self.class.features[collection] || []
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Declaration of optional features
|
122
|
+
#
|
123
|
+
declare_feature :instances, :user_name do
|
124
|
+
description "Accept a user-defined name on instance creation"
|
125
|
+
operation :create do
|
126
|
+
param :name, :string, :optional, nil,
|
127
|
+
"The user-defined name"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
declare_feature :instances, :user_data do
|
132
|
+
description "Make user-defined data available on a special webserver"
|
133
|
+
operation :create do
|
134
|
+
param :user_data, :string, :optional, nil,
|
135
|
+
"Base64 encoded user data will be published to internal webserver"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
declare_feature :instances, :authentication_key do
|
140
|
+
operation :create do
|
141
|
+
param :keyname, :string, :optional, nil
|
142
|
+
"EC2 key authentification method"
|
143
|
+
end
|
144
|
+
operation :show do
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
declare_feature :instances, :authentication_password do
|
149
|
+
operation :create do
|
150
|
+
param :password, :string, :optional
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
declare_feature :instances, :hardware_profiles do
|
155
|
+
description "Size instances according to changes to a hardware profile"
|
156
|
+
# The parameters are filled in from the hardware profiles
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|