cloudstack_api 1.0.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +123 -0
- data/Rakefile +32 -0
- data/lib/cloudstack/api.rb +179 -0
- data/lib/cloudstack/configuration.rb +59 -0
- data/lib/cloudstack/railtie.rb +10 -0
- data/lib/cloudstack/version.rb +3 -0
- data/lib/cloudstack.rb +19 -0
- data/lib/config/api_spec.yml +6293 -0
- data/lib/tasks/cloudstack_tasks.rake +11 -0
- data/lib/tasks/config/cloudstack.yml +14 -0
- data/test/api_test.rb +67 -0
- data/test/cloudstack_test.rb +12 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cloudstack.yml +13 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +38 -0
- data/test/dummy/config/environments/production.rb +82 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/assets.rb +8 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +56 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/test.log +705 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/test_helper.rb +15 -0
- metadata +220 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1a71fad5fd898a7b1c3660a34b5c9eb251049ebb
|
4
|
+
data.tar.gz: 3045b355845b58ccb21352d8f394cff175a0a921
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 864c0045e465200e2e5b6b41706b5c8dfbfd6aedc630a552f2b4c29d833531db344d3a0b624e8373855b56276c76ef19470886ac93f6092c79d0aa852df59467
|
7
|
+
data.tar.gz: c8f27faf0e8175c605f32435fd2b4f17886e5c11cc18ceda50d829099e6b3067b62e465885b0ac16ba8ac2426de7ab37fb71f9aee61807b4da687a7ade358cff
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
= cloudstack_api
|
2
|
+
|
3
|
+
Ruby library for the CloudStack API. Current version uses CloudStack API
|
4
|
+
version 4.3.0 ({API Reference}[http://cloudstack.apache.org/docs/api/apidocs-4.3/TOC_Root_Admin.html])
|
5
|
+
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
Cloudstack library requires Ruby 1.9.3 or later. To install, add this line to your
|
10
|
+
+Gemfile+ and run <tt>bundle install</tt>:
|
11
|
+
|
12
|
+
gem 'cloudstack_api'
|
13
|
+
|
14
|
+
Gem was renamed from +cloudstack+ to +cloudstack_api+ to avoid name conflicts with CloudStack trademark.
|
15
|
+
|
16
|
+
|
17
|
+
== Configuration
|
18
|
+
|
19
|
+
By default module uses configuration from <tt>config/cloudstack.yml</tt> file. To generate it run:
|
20
|
+
|
21
|
+
rake cloudstack:install
|
22
|
+
|
23
|
+
This command generates file <tt>config/cloudstack.yml</tt> which contains configuration for each environment
|
24
|
+
|
25
|
+
default: &default
|
26
|
+
api_key: xxxxxxxxx
|
27
|
+
secret_key: xxxxxxxxx
|
28
|
+
api_url: https://your.domain.com/client/api
|
29
|
+
|
30
|
+
production:
|
31
|
+
<<: *default
|
32
|
+
|
33
|
+
development:
|
34
|
+
<<: *default
|
35
|
+
|
36
|
+
test:
|
37
|
+
<<: *default
|
38
|
+
api_mode: test
|
39
|
+
|
40
|
+
Fill in +api_url+, +api_key+ and +secret_key+ for each environment or use +default+ template.
|
41
|
+
|
42
|
+
You can configure module at runtime if you need:
|
43
|
+
|
44
|
+
Cloudstack.configure do |config|
|
45
|
+
config.api_key = 'xxxxx'
|
46
|
+
config.secret_key = 'xxxxxx'
|
47
|
+
config.api_url = 'https://your.domain.com/client/api'
|
48
|
+
config.api_mode = 'test' # don't execute any command, just return signed request
|
49
|
+
end
|
50
|
+
|
51
|
+
or set each configuration option separately:
|
52
|
+
|
53
|
+
Cloudstack.config.api_key = 'xxxxxx'
|
54
|
+
|
55
|
+
== Usage
|
56
|
+
|
57
|
+
To use library you need to create an instance of Cloudstack::Api class and call it methods:
|
58
|
+
|
59
|
+
@api = Cloudstack::Api.new
|
60
|
+
@api.execute_command('listVirtualMachines', account: 'myuser', domainid: '1bd9a980-0f11-4892-aa0b-7c434dbd6d1c')
|
61
|
+
|
62
|
+
Last line returns a result hash:
|
63
|
+
|
64
|
+
{
|
65
|
+
:count => 1,
|
66
|
+
:virtualmachine => [
|
67
|
+
{
|
68
|
+
:id => "0e061655-d982-4c2d-810e-6f3aa7d2ccde",
|
69
|
+
:name => "cloudvds4509",
|
70
|
+
:displayname => "cloudvds4509",
|
71
|
+
:account => "myuser",
|
72
|
+
:domainid => "1bd9a980-0f11-4892-aa0b-7c434dbd6d1c",
|
73
|
+
:domain => "core",
|
74
|
+
:created => "2014-08-15T15:35:20+0000",
|
75
|
+
:state => "Stopped",
|
76
|
+
:haenable => true,
|
77
|
+
...
|
78
|
+
|
79
|
+
or +false+ if an error was occured. All error messages stores in an +errors+ method.
|
80
|
+
+errors+ method is a functionality of <tt>ActiveModel::Validations</tt> module.
|
81
|
+
|
82
|
+
@api.errors.messages
|
83
|
+
|
84
|
+
returns:
|
85
|
+
|
86
|
+
{:base=>["could not find account user in domain 1bd9a980-0f11-4892-aa0b-7c434dbd6d1c"]}
|
87
|
+
|
88
|
+
If you prefer to work with exceptions you can use functions with <tt>!</tt> suffix. For example:
|
89
|
+
|
90
|
+
begin
|
91
|
+
@api = Cloudstack::Api.new
|
92
|
+
@api.execute_command!('listVirtualMachines', account: 'myuser', domainid: '1bd9a980-0f11-4892-aa0b-7c434dbd6d1c')
|
93
|
+
rescue Exception => e
|
94
|
+
puts e.message # => could not find account myuser in domain 1bd9a980-0f11-4892-aa0b-7c434dbd6d1c
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
== Shortcuts for API commands
|
99
|
+
|
100
|
+
For writing more readable code, use API commands shortcuts.
|
101
|
+
|
102
|
+
@api.list_virtual_machines(account: 'myuser', domainid: '1bd9a980-0f11-4892-aa0b-7c434dbd6d1c')
|
103
|
+
|
104
|
+
is the same as:
|
105
|
+
|
106
|
+
@api.execute_command('listVirtualMachines', account: 'myuser', domainid: '1bd9a980-0f11-4892-aa0b-7c434dbd6d1c')
|
107
|
+
|
108
|
+
Shortcuts commands is an underscored API commands. For example command +deployVirtualMachine+
|
109
|
+
has +deploy_virtual_machine+ shortcut method.
|
110
|
+
|
111
|
+
Exception raises methods have shotcuts too. Just add <tt>!</tt> suffix to it:
|
112
|
+
|
113
|
+
begin
|
114
|
+
@api.list_virtual_machines!(account: 'myuser', domainid: '1bd9a980-0f11-4892-aa0b-7c434dbd6d1c')
|
115
|
+
rescue Exception => e
|
116
|
+
puts e.message # => could not find account myuser in domain 1bd9a980-0f11-4892-aa0b-7c434dbd6d1c
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
====== TODO
|
121
|
+
|
122
|
+
- Handle async jobs
|
123
|
+
- Write documentation!!!
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Cloudstack'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib'
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = false
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task default: :test
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module Cloudstack
|
2
|
+
|
3
|
+
# Instance of Cloudstack::Api class uses to prepare CloudStack API request
|
4
|
+
# and send it to Cloudstack Management Server. Then Cludstack::Api handles
|
5
|
+
# a response and return it in usable type.
|
6
|
+
|
7
|
+
class Api
|
8
|
+
include ActiveModel::AttributeMethods
|
9
|
+
include ActiveModel::Validations
|
10
|
+
|
11
|
+
validate :validate_api_params
|
12
|
+
|
13
|
+
# methods with '!' suffix will raise an exception when error occurs
|
14
|
+
attribute_method_suffix '!'
|
15
|
+
|
16
|
+
# add api commands as methods to api instance
|
17
|
+
define_attribute_methods Cloudstack.config.methods
|
18
|
+
|
19
|
+
|
20
|
+
# Calls CloudStack API command on a remote server.
|
21
|
+
# Method arguments is +command+ and a list of +params+
|
22
|
+
# - +command+ is one of the commands described on a
|
23
|
+
# {CloudStack API reference page}[http://cloudstack.apache.org/docs/api/apidocs-4.3/TOC_Root_Admin.html]
|
24
|
+
# - +params+ is a hash of +command+ parameters
|
25
|
+
#
|
26
|
+
# Method returns a response hash (if request was success) or
|
27
|
+
# raises an error else. Before raising an error it stores in an
|
28
|
+
# #errors object. It works like ActiveModel::Validations
|
29
|
+
# So error messages can be retrieved:
|
30
|
+
# api_instance.errors.messages
|
31
|
+
#
|
32
|
+
# == Example
|
33
|
+
#
|
34
|
+
# @api = Cloudstack::Api.new
|
35
|
+
# @api.execute_command('some command', some_param: 'some value') # => raises ArgumentError exception
|
36
|
+
# @api.errors.messages # => {:command=>["'some command' is invalid command"]}
|
37
|
+
#
|
38
|
+
|
39
|
+
def execute_command!(command, params={})
|
40
|
+
# Clear errors from previous request
|
41
|
+
errors.clear
|
42
|
+
|
43
|
+
# Set local variables
|
44
|
+
@command = command.to_s
|
45
|
+
@params = params.symbolize_keys
|
46
|
+
|
47
|
+
# Validate command and parameters
|
48
|
+
raise ArgumentError if invalid?
|
49
|
+
|
50
|
+
# Assemble request_options
|
51
|
+
request_options = {
|
52
|
+
command: @command,
|
53
|
+
apikey: Cloudstack.config.api_key,
|
54
|
+
response: 'json'
|
55
|
+
}
|
56
|
+
request_options.merge! @params
|
57
|
+
|
58
|
+
# Generate request signature and add it to request_options
|
59
|
+
request_options[:signature] = sign_request(request_options)
|
60
|
+
|
61
|
+
# Generate request url with parameters
|
62
|
+
request_url = Cloudstack.config.api_url + '?' + request_options.to_query
|
63
|
+
|
64
|
+
# Check current mode. If mode is +test+ than command not executes,
|
65
|
+
# but only returns request url.
|
66
|
+
return request_url if Cloudstack.config.api_mode == 'test'
|
67
|
+
|
68
|
+
begin
|
69
|
+
# send curl request to the CloudStack server
|
70
|
+
curl = Curl::Easy.new(request_url)
|
71
|
+
curl.ssl_verify_peer = false
|
72
|
+
curl.perform
|
73
|
+
|
74
|
+
# handle response
|
75
|
+
response = JSON.parse(curl.body_str, symbolize_names: true)
|
76
|
+
rescue Exception => e
|
77
|
+
# If error occurs, it adds to instance errors
|
78
|
+
errors.add(:base, e.message)
|
79
|
+
raise e
|
80
|
+
end
|
81
|
+
|
82
|
+
# Checks if a command returns a CloudStack error. If error occurs,
|
83
|
+
# it adds to errors and excepions reises.
|
84
|
+
if response[:errorresponse].present?
|
85
|
+
errors.add(:base, response[:errorresponse][:errortext])
|
86
|
+
raise StandardError, response[:errorresponse][:errortext]
|
87
|
+
end
|
88
|
+
|
89
|
+
result = response["#{command}response".downcase.to_sym]
|
90
|
+
|
91
|
+
if result[:errortext].present?
|
92
|
+
errors.add(:base, result[:errortext])
|
93
|
+
raise StandardError, result[:errortext]
|
94
|
+
end
|
95
|
+
|
96
|
+
# If all pass success, returns a result hash
|
97
|
+
result
|
98
|
+
end
|
99
|
+
|
100
|
+
# Method provides the same functionality as #execute_command! except
|
101
|
+
# it does not raises exceptions. When error occurs, it just returns +false+.
|
102
|
+
# So if method returns +false+, errors message should be in #errors
|
103
|
+
#
|
104
|
+
# == Example
|
105
|
+
#
|
106
|
+
# @api = Cloudstack::Api.new
|
107
|
+
# @api.execute_command('some command', some_param: 'some value') # => false
|
108
|
+
# @api.errors.messages # => {:command=>["'some command' is invalid command"]}
|
109
|
+
#
|
110
|
+
|
111
|
+
def execute_command(command, options={})
|
112
|
+
begin
|
113
|
+
return execute_command!(command, options)
|
114
|
+
rescue
|
115
|
+
return false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
protected
|
120
|
+
|
121
|
+
# Generates a signature for api request.
|
122
|
+
# Details {Signing API Requests}[http://cloudstack.apache.org/docs/en-US/Apache_CloudStack/4.0.0-incubating/html/API_Developers_Guide/signing-api-requests.html]
|
123
|
+
def sign_request(request_options)
|
124
|
+
request_string = Hash[request_options.sort].to_query.downcase
|
125
|
+
Base64.encode64(OpenSSL::HMAC.digest( OpenSSL::Digest.new('sha1'), Cloudstack.config.secret_key, request_string)).strip
|
126
|
+
end
|
127
|
+
|
128
|
+
# Method provides shortcuts for api commands. For example
|
129
|
+
# it can be called
|
130
|
+
# @api.list_virtual_machines!(parameters)
|
131
|
+
# instead of
|
132
|
+
# @api.execute_command!('listVirtualMachines', parameters)
|
133
|
+
#
|
134
|
+
# It's useful in a command line mode. Function names will autocompletes.
|
135
|
+
def attribute!(attr, *args)
|
136
|
+
execute_command!(Cloudstack.config.method_to_command(attr), *args)
|
137
|
+
end
|
138
|
+
|
139
|
+
# The same as #attribute! method, but calls #execute_command method,
|
140
|
+
# which doesn't raise errors.
|
141
|
+
def attribute(attr, *args)
|
142
|
+
execute_command(Cloudstack.config.method_to_command(attr), *args)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Validates api command and parameters. CloudStack API specification
|
146
|
+
# stores in a lib/config/api_spec.yml file. Method checks command name,
|
147
|
+
# parameters names and required parameters presence.
|
148
|
+
#
|
149
|
+
# If command or parameters is invalid, then corresponding error will be
|
150
|
+
# added to #errors
|
151
|
+
def validate_api_params
|
152
|
+
# retrieve parameters that belongs
|
153
|
+
allowed_params = Cloudstack.config.command_params(@command)
|
154
|
+
|
155
|
+
# if no parameters for current command then command is incorrect
|
156
|
+
unless allowed_params.present?
|
157
|
+
errors.add(:command, "'#{@command}' is invalid command")
|
158
|
+
return
|
159
|
+
end
|
160
|
+
|
161
|
+
# each parameter name should be in allowed parameters for current command
|
162
|
+
(@params.keys - allowed_params).each do |param|
|
163
|
+
errors.add(:params, "'#{param}' parameter is not allowed")
|
164
|
+
end
|
165
|
+
|
166
|
+
# check required parameters
|
167
|
+
required_params = Cloudstack.config.command_required_params(@command)
|
168
|
+
(required_params - @params.keys).each do |param|
|
169
|
+
errors.add(:params, "'#{param}' parameter is required")
|
170
|
+
end
|
171
|
+
|
172
|
+
# # each parameter value should be a string
|
173
|
+
# @params.each do |key,value|
|
174
|
+
# errors.add(:params, "'#{value}' parameter should be a String") unless value.is_a? String
|
175
|
+
# end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Configuration
|
2
|
+
|
3
|
+
attr_accessor :api_key,
|
4
|
+
:secret_key,
|
5
|
+
:api_url,
|
6
|
+
:api_spec,
|
7
|
+
:api_mode
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
if defined?(Rails) and File.exist?(File.expand_path('config/cloudstack.yml', Rails.root))
|
11
|
+
config = YAML.load_file(File.expand_path('config/cloudstack.yml', Rails.root))[Rails.env]
|
12
|
+
|
13
|
+
@api_key = config['api_key'] if config['api_key'].present?
|
14
|
+
@secret_key = config['secret_key'] if config['secret_key'].present?
|
15
|
+
@api_url = config['api_url'] if config['api_url'].present?
|
16
|
+
@api_mode = config['api_mode'] if config['api_mode'].present?
|
17
|
+
end
|
18
|
+
@api_spec = YAML.load_file(File.expand_path('../../config/api_spec.yml', __FILE__))
|
19
|
+
|
20
|
+
# contain map of underscore api commands relative to camelize
|
21
|
+
@method_to_command = Hash[ @api_spec.keys.map {|key| [key.underscore.to_sym, key]} ]
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
##
|
26
|
+
# return an array of api methods. Method is an underscored command.
|
27
|
+
# it was done, because ruby methods should be underscored, but CloudStack
|
28
|
+
# uses camelCased command names
|
29
|
+
def methods
|
30
|
+
@api_methods ||= @api_spec.keys.map{ |key| key.underscore.to_sym }
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
##
|
35
|
+
# return an array of available api commands. It uses in validations and so on.
|
36
|
+
def commands
|
37
|
+
@api_commands ||= @api_spec.keys
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
##
|
42
|
+
# convert underscored method name to camelCased command
|
43
|
+
def method_to_command(command)
|
44
|
+
@method_to_command[command.to_sym]
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# return an array of given command parameters
|
49
|
+
def command_params(command)
|
50
|
+
@api_spec[command.to_s]['params'].keys.map(&:to_sym) if @api_spec[command.to_s]
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# return an array of given command required parameters
|
55
|
+
def command_required_params(command)
|
56
|
+
@api_spec[command.to_s]['params'].map {|k,v| k.to_sym if v['required']}.compact
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/lib/cloudstack.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Cloudstack
|
2
|
+
require 'cloudstack/railtie' if defined?(Rails)
|
3
|
+
require 'cloudstack/configuration'
|
4
|
+
autoload :Api, 'cloudstack/api'
|
5
|
+
require 'curb'
|
6
|
+
|
7
|
+
# Gives access to the current configuration
|
8
|
+
def self.config
|
9
|
+
@configuration ||= Configuration.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# Allows easy setting of multiple configuration options. See Configuration
|
13
|
+
# for all available options.
|
14
|
+
def self.configure
|
15
|
+
config = self.config
|
16
|
+
yield(config)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|