fog-softlayer 0.0.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/.gitignore +1 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +49 -0
- data/Rakefile +16 -0
- data/fog-softlayer.gemspec +29 -0
- data/lib/fog/softlayer.rb +1 -0
- data/lib/fog/softlayer/compute.rb +162 -0
- data/lib/fog/softlayer/compute/shared.rb +39 -0
- data/lib/fog/softlayer/core.rb +38 -0
- data/lib/fog/softlayer/requests/compute/create_bare_metal_server.rb +78 -0
- data/lib/fog/softlayer/requests/compute/create_vm.rb +46 -0
- data/lib/fog/softlayer/requests/compute/create_vms.rb +87 -0
- data/lib/fog/softlayer/version.rb +5 -0
- data/spec/fog/compute/softlayer_spec.rb +39 -0
- metadata +161 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
© Copyright IBM Corporation 2014.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# SoftLayer Cloud module for fog (The Ruby cloud services library)
|
2
|
+
|
3
|
+
This gem is a module for the `fog` gem that allows you to manage resources in
|
4
|
+
the SoftLayer Cloud.
|
5
|
+
|
6
|
+
It is included by the main `fog` metagem but can used as an independent library
|
7
|
+
in other applications.
|
8
|
+
|
9
|
+
This release includes support for the following services:
|
10
|
+
* Compute
|
11
|
+
|
12
|
+
Additional services coming soon:
|
13
|
+
* Storage
|
14
|
+
* DNS
|
15
|
+
* Image
|
16
|
+
* Network
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
gem "fog-softlayer"
|
23
|
+
|
24
|
+
And then execute:
|
25
|
+
|
26
|
+
$ bundle
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install fog-softlayer
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
Please see the following references for instructions using the main `fog` gem
|
35
|
+
and its modules:
|
36
|
+
|
37
|
+
* https://github.com/fog/fog
|
38
|
+
* http://fog.io/
|
39
|
+
* http://rubydoc.info/gems/fog/
|
40
|
+
|
41
|
+
## Contributing
|
42
|
+
|
43
|
+
`fog` modules are kept within the main repo.
|
44
|
+
|
45
|
+
1. Fork it ( http://github.com/fog/fog/fork )
|
46
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
47
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
48
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
49
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Matt Eldridge (<matt.eldridge@us.ibm.com>)
|
3
|
+
# © Copyright IBM Corporation 2014.
|
4
|
+
#
|
5
|
+
# LICENSE: MIT (http://opensource.org/licenses/MIT)
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
require "bundler/gem_tasks"
|
10
|
+
require "rake/testtask"
|
11
|
+
|
12
|
+
task :default => :test
|
13
|
+
|
14
|
+
Rake::TestTask.new do |t|
|
15
|
+
t.pattern = File.join("spec", "**", "*_spec.rb")
|
16
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fog/softlayer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fog-softlayer"
|
8
|
+
spec.version = Fog::Softlayer::VERSION
|
9
|
+
spec.authors = ["Matt Eldridge"]
|
10
|
+
spec.email = ["matt.eldridge@us.ibm.com"]
|
11
|
+
spec.description = %q{Module for the 'fog' gem to support SoftLayer Cloud}
|
12
|
+
spec.summary = %q{This library can be used as a module for `fog` or as standalone provider
|
13
|
+
to use the SoftLayer Cloud in applications}
|
14
|
+
spec.homepage = ""
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "fog-core"
|
23
|
+
spec.add_dependency "fog-json"
|
24
|
+
spec.add_dependency("pry-debugger")
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "minitest"
|
29
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'fog/softlayer/compute'
|
@@ -0,0 +1,162 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Matt Eldridge (<matt.eldridge@us.ibm.com>)
|
3
|
+
# © Copyright IBM Corporation 2014.
|
4
|
+
#
|
5
|
+
# LICENSE: MIT (http://opensource.org/licenses/MIT)
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'fog/softlayer/core'
|
9
|
+
require 'fog/softlayer/compute/shared'
|
10
|
+
|
11
|
+
module Fog
|
12
|
+
module Compute
|
13
|
+
class Softlayer < Fog::Service
|
14
|
+
class MissingRequiredParameter < Fog::Errors::Error; end
|
15
|
+
|
16
|
+
# Client credentials
|
17
|
+
requires :softlayer_username, :softlayer_api_key
|
18
|
+
|
19
|
+
# Excon connection settings
|
20
|
+
recognizes :softlayer_api_url
|
21
|
+
|
22
|
+
#model_path 'fog/softlayer/models/compute'
|
23
|
+
#collection :servers
|
24
|
+
#model :server
|
25
|
+
#collection :bare_metal_servers
|
26
|
+
#model :bare_metal_server
|
27
|
+
#collection :global_ipv4s
|
28
|
+
#model :global_ipv4
|
29
|
+
#collection :images
|
30
|
+
#model :image
|
31
|
+
#
|
32
|
+
|
33
|
+
service = File.basename(__FILE__, '.rb')
|
34
|
+
|
35
|
+
path = "fog/softlayer/requests/#{service}"
|
36
|
+
request_path path
|
37
|
+
|
38
|
+
Fog::Softlayer.load_requests(service) do |r|
|
39
|
+
request r
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# The Mock Service allows you to run a fake instance of the Service
|
44
|
+
# which makes no real connections.
|
45
|
+
#
|
46
|
+
#
|
47
|
+
class Mock
|
48
|
+
include Fog::Softlayer::Compute::Shared
|
49
|
+
|
50
|
+
def request(method, path, expected_responses, parameters = {})
|
51
|
+
_request
|
52
|
+
end
|
53
|
+
|
54
|
+
def request_access_token(connection, credentials)
|
55
|
+
_request
|
56
|
+
end
|
57
|
+
|
58
|
+
def _request
|
59
|
+
raise Fog::Errors::MockNotImplemented
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Makes real connections to Softlayer.
|
66
|
+
#
|
67
|
+
class Real
|
68
|
+
include Fog::Softlayer::Compute::Shared
|
69
|
+
|
70
|
+
# Sends the real request to the real SoftLayer service.
|
71
|
+
#
|
72
|
+
# @param [String] service
|
73
|
+
# ...ayer.com/rest/v3/Softlayer_Service_Name...
|
74
|
+
# @param path [String]
|
75
|
+
# ...ayer.com/rest/v3/Softlayer_Service_Name/path.json
|
76
|
+
# @param [Hash] options
|
77
|
+
# @option options [Array<Hash>] :body
|
78
|
+
# HTTP request body parameters
|
79
|
+
# @option options [String] :softlayer_api_url
|
80
|
+
# Override the default (or configured) API endpoint
|
81
|
+
# @option options [String] :softlayer_username
|
82
|
+
# Email or user identifier for user based authentication
|
83
|
+
# @option options [String] :softlayer_api_key
|
84
|
+
# Password for user based authentication
|
85
|
+
# @return [Excon::Response]
|
86
|
+
def request(service, path, options={})
|
87
|
+
|
88
|
+
# default HTTP method to get if not passed
|
89
|
+
http_method = options[:http_method] || :get
|
90
|
+
# set the target base url
|
91
|
+
@request_url = options[:softlayer_api_url] || Fog::Softlayer::API_URL
|
92
|
+
# tack on the username and password
|
93
|
+
credentialize_url(@credentials[:username], @credentials[:api_key])
|
94
|
+
# set the SoftLayer Service name
|
95
|
+
set_sl_service(service)
|
96
|
+
# set the request path (known as the "method" in SL docs)
|
97
|
+
set_sl_path(path)
|
98
|
+
|
99
|
+
# build request params
|
100
|
+
params = { :headers => user_agent_header }
|
101
|
+
params[:headers]['Content-Type'] = 'application/json'
|
102
|
+
params[:expects] = [200,201]
|
103
|
+
params[:body] = Fog::JSON.encode({:parameters => [ options[:body] ]}) unless options[:body].nil?
|
104
|
+
|
105
|
+
# initialize connection object
|
106
|
+
@connection = Fog::Core::Connection.new(@request_url, false, params)
|
107
|
+
|
108
|
+
# send it
|
109
|
+
response = @connection.request(:method => http_method)
|
110
|
+
|
111
|
+
# decode it
|
112
|
+
response.body = Fog::JSON.decode(response.body)
|
113
|
+
response
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def credentialize_url(username, apikey)
|
119
|
+
@request_url = "https://#{username}:#{apikey}@#{@request_url}"
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Prepend "SoftLayer_" to the service name and Snake_Camel_Case the string before appending it to the @request_url.
|
124
|
+
#
|
125
|
+
def set_sl_service(service)
|
126
|
+
service = "SoftLayer_" << service.to_s.gsub(/^softlayer_/i, '').split('_').map{|i|i.capitalize}.join('_')
|
127
|
+
@request_url += "/#{service}"
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# Try to smallCamelCase the path before appending it to the @request_url
|
132
|
+
#
|
133
|
+
def set_sl_path(path)
|
134
|
+
path = path.to_s.underscore.camelize
|
135
|
+
@request_url += "/#{path}.json"
|
136
|
+
end
|
137
|
+
|
138
|
+
def user_agent_header
|
139
|
+
{"User-Agent" => "Fog SoftLayer Adapter #{Fog::Softlayer::VERSION}"}
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
## some helpers for some dirty work
|
150
|
+
class String
|
151
|
+
def camelize
|
152
|
+
self.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
153
|
+
end
|
154
|
+
|
155
|
+
def underscore
|
156
|
+
self.gsub(/::/, '/').
|
157
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
158
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
159
|
+
tr("-", "_").
|
160
|
+
downcase
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Matt Eldridge (<matt.eldridge@us.ibm.com>)
|
3
|
+
# © Copyright IBM Corporation 2014.
|
4
|
+
#
|
5
|
+
# LICENSE: MIT (http://opensource.org/licenses/MIT)
|
6
|
+
#
|
7
|
+
|
8
|
+
module Fog
|
9
|
+
module Softlayer
|
10
|
+
module Compute
|
11
|
+
|
12
|
+
# The Shared module consists of code that was duplicated between the Real
|
13
|
+
# and Mock implementations.
|
14
|
+
#
|
15
|
+
module Shared
|
16
|
+
|
17
|
+
# Creates a new instance of the Softlayer Compute service
|
18
|
+
#
|
19
|
+
# @param [Hash] options
|
20
|
+
# @option options [String] :softlayer_api_url
|
21
|
+
# Override the default (or configured) API endpoint
|
22
|
+
# @option options [String] :softlayer_username
|
23
|
+
# Email or user identifier for user based authentication
|
24
|
+
# @option options [String] :softlayer_api_key
|
25
|
+
# Password for user based authentication
|
26
|
+
#
|
27
|
+
def initialize(options)
|
28
|
+
@api_url = options[:softlayer_api_url] || API_URL
|
29
|
+
@credentials = { :username => options[:softlayer_username], :api_key => options[:softlayer_api_key] }
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.valid_request?(required, passed)
|
33
|
+
required.all? {|k| passed.key?(k)}
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'fog/core'
|
2
|
+
require 'fog/json'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Fog
|
6
|
+
module Softlayer
|
7
|
+
extend Fog::Provider
|
8
|
+
|
9
|
+
API_URL = 'api.softlayer.com/rest/v3' unless defined? API_URL
|
10
|
+
|
11
|
+
service(:compute, 'Compute')
|
12
|
+
|
13
|
+
def self.load_requests(service)
|
14
|
+
path = "providers/softlayer/lib/fog/softlayer/requests/#{service}"
|
15
|
+
Dir.entries(path).reject{|e| e =~ /^\./}.each do |file|
|
16
|
+
_request = File.basename(file, '.rb')
|
17
|
+
yield _request.to_sym
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.mock_account_id
|
22
|
+
Fog.mocking? and @sl_account_id ||= Fog::Mock.random_numbers(7)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.mock_vm_id
|
26
|
+
Fog::Mock.random_numbers(7)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.mock_global_identifier
|
30
|
+
Fog::UUID.uuid
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.valid_request?(required, passed)
|
34
|
+
required.all? {|k| passed.key?(k) and !passed[k].nil?}
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Softlayer
|
4
|
+
|
5
|
+
class Mock
|
6
|
+
|
7
|
+
# Launch a SoftLayer BMC server.
|
8
|
+
#
|
9
|
+
# @param [Array<Hash>] opts
|
10
|
+
# @option opts [Array<Hash>] :body
|
11
|
+
# HTTP request body parameters
|
12
|
+
# @option opts [String] "hostname"
|
13
|
+
# VM hostname, should be unique within the domain.
|
14
|
+
# @option opts [String] "domain"
|
15
|
+
# VM domain.
|
16
|
+
# @option opts [Integer] "processorCoreAmount"
|
17
|
+
# Number of CPU cores provisioned for the VM.
|
18
|
+
# @option opts [Integer] "memoryCapacity"
|
19
|
+
# Available RAM for the server in GB. Valid arguments are 1, 2, 4, 6, 8, 12, 16, 32, 48, 64
|
20
|
+
# @option opts [Boolean] "hourlyBillingFlag"
|
21
|
+
# Should the VM be billed hourly or monthly (monthly is less expensive, minimum charge of 1 month).
|
22
|
+
# @option opts [Boolean] "localDiskFlag"
|
23
|
+
# Should the root volume be on the machine or on the SAN
|
24
|
+
# @option opts [String] "operatingSystemReferenceCode"
|
25
|
+
# A valid SoftLayer operatingSystemReferenceCode string
|
26
|
+
# @option opts [Boolean] "dedicatedAccountHostOnlyFlag"
|
27
|
+
# Defaults to false, pass true for a single-tenant VM.
|
28
|
+
# @return [Excon::Response]
|
29
|
+
def create_bare_metal_server(opts)
|
30
|
+
raise ArgumentError, "Fog::Compute::Softlayer#create_bare_metal_server expects argument of type Hash" unless opts.kind_of?(Hash)
|
31
|
+
response = Excon::Response.new
|
32
|
+
required = %w{hostname domain processorCoreAmount memoryCapacity hourlyBillingFlag operatingSystemReferenceCode}
|
33
|
+
|
34
|
+
begin
|
35
|
+
Fog::Softlayer.valid_request?(required, opts) or raise MissingRequiredParameter
|
36
|
+
response.status = 200
|
37
|
+
# a real response comes back with lots of nil values like this too, it takes 1 - 2 hours for a real BMC server to provision
|
38
|
+
response.body = {
|
39
|
+
"accountId" => Fog::Softlayer.mock_account_id,
|
40
|
+
"createDate" => Time.now.iso8601,
|
41
|
+
"dedicatedAccountHostOnlyFlag" => false,
|
42
|
+
"domain" => nil,
|
43
|
+
"fullyQualifiedDomainName" => nil,
|
44
|
+
"hostname" => nil,
|
45
|
+
"id" => Fog::Softlayer.mock_vm_id,
|
46
|
+
"lastPowerStateId" => nil,
|
47
|
+
"lastVerifiedDate" => nil,
|
48
|
+
"maxCpu" => nil,
|
49
|
+
"maxCpuUnits" => "CORE",
|
50
|
+
"maxMemory" => nil,
|
51
|
+
"metricPollDate" => nil,
|
52
|
+
"modifyDate" => nil,
|
53
|
+
"startCpus" => nil,
|
54
|
+
"statusId" => 1001,
|
55
|
+
"globalIdentifier" => Fog::Softlayer.mock_global_identifier
|
56
|
+
}
|
57
|
+
rescue MissingRequiredParameter
|
58
|
+
response.status = 500
|
59
|
+
response.body = {
|
60
|
+
"code" => "SoftLayer_Exception_MissingCreationProperty",
|
61
|
+
"error" => "Properties #{required.join(', ')} ALL must be set to create an instance of 'SoftLayer_Hardware'."
|
62
|
+
}
|
63
|
+
end
|
64
|
+
response
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Real
|
69
|
+
|
70
|
+
def create_bare_metal_server(opts)
|
71
|
+
raise ArgumentError, "Fog::Compute::Softlayer#create_bare_metal_server expects argument of type Hash" unless opts.kind_of?(Hash)
|
72
|
+
request(:hardware_server, :create_object, :body => opts, :http_method => :POST)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Softlayer
|
4
|
+
|
5
|
+
class Mock
|
6
|
+
|
7
|
+
# Launch a single SoftLayer VM.
|
8
|
+
#
|
9
|
+
# @param [<Hash>] opts
|
10
|
+
# @option opts [<Hash>] :body
|
11
|
+
# HTTP request body parameters
|
12
|
+
# @option opts [String] "hostname"
|
13
|
+
# VM hostname, should be unique within the domain.
|
14
|
+
# @option opts [String] "domain"
|
15
|
+
# VM domain.
|
16
|
+
# @option opts [Integer] "startCpus"
|
17
|
+
# Number of CPU cores provisioned for the VM.
|
18
|
+
# @option opts [Integer] "maxMemory"
|
19
|
+
# Available RAM for the VM in MB. Valid arguments are 1024, 2048, 4096, 6144, 8192, 12288, 16384, 32768, 49152, 65536
|
20
|
+
# @option opts [Boolean] "hourlyBillingFlag"
|
21
|
+
# Should the VM be billed hourly or monthly (monthly is less expensive, minimum charge of 1 month).
|
22
|
+
# @option opts [Boolean] "localDiskFlag"
|
23
|
+
# Should the root volume be on the machine or on the SAN
|
24
|
+
# @option opts [String] "operatingSystemReferenceCode"
|
25
|
+
# A valid SoftLayer operatingSystemReferenceCode string
|
26
|
+
# @option opts [Boolean] "dedicatedAccountHostOnlyFlag"
|
27
|
+
# Defaults to false, pass true for a single-tenant VM.
|
28
|
+
# @return [Excon::Response]
|
29
|
+
def create_vm(opts)
|
30
|
+
raise ArgumentError, "Fog::Compute::Softlayer#create_vm expects argument of type Hash" unless opts.kind_of?(Hash)
|
31
|
+
opts = [opts]
|
32
|
+
self.create_vms(opts)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
class Real
|
38
|
+
def create_vm(opts)
|
39
|
+
raise ArgumentError, "Fog::Compute::Softlayer#create_vm expects argument of type Hash" unless opts.kind_of?(Hash)
|
40
|
+
opts = [opts]
|
41
|
+
self.create_vms(opts)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Softlayer
|
4
|
+
|
5
|
+
class Mock
|
6
|
+
|
7
|
+
# Launch one or more SoftLayer VMs.
|
8
|
+
#
|
9
|
+
# @param [Array<Hash>] opts
|
10
|
+
# @option opts [Array<Hash>] :body
|
11
|
+
# HTTP request body parameters
|
12
|
+
# @option opts [String] "hostname"
|
13
|
+
# VM hostname, should be unique within the domain.
|
14
|
+
# @option opts [String] "domain"
|
15
|
+
# VM domain.
|
16
|
+
# @option opts [Integer] "startCpus"
|
17
|
+
# Number of CPU cores provisioned for the VM.
|
18
|
+
# @option opts [Integer] "maxMemory"
|
19
|
+
# Available RAM for the VM in MB. Valid arguments are 1024, 2048, 4096, 6144, 8192, 12288, 16384, 32768, 49152, 65536
|
20
|
+
# @option opts [Boolean] "hourlyBillingFlag"
|
21
|
+
# Should the VM be billed hourly or monthly (monthly is less expensive, minimum charge of 1 month).
|
22
|
+
# @option opts [Boolean] "localDiskFlag"
|
23
|
+
# Should the root volume be on the machine or on the SAN
|
24
|
+
# @option opts [String] "operatingSystemReferenceCode"
|
25
|
+
# A valid SoftLayer operatingSystemReferenceCode string
|
26
|
+
# @option opts [Boolean] "dedicatedAccountHostOnlyFlag"
|
27
|
+
# Defaults to false, pass true for a single-tenant VM.
|
28
|
+
# @return [Excon::Response]
|
29
|
+
def create_vms(opts)
|
30
|
+
raise ArgumentError, "Fog::Compute::Softlayer#create_vms expects argument of type Array" unless opts.kind_of?(Array)
|
31
|
+
response = Excon::Response.new
|
32
|
+
required = %w{hostname domain startCpus maxMemory hourlyBillingFlag localDiskFlag operatingSystemReferenceCode}
|
33
|
+
|
34
|
+
begin
|
35
|
+
opts.each {|vm| Fog::Softlayer.valid_request?(required, vm) or raise MissingRequiredParameter}
|
36
|
+
response.status = 200
|
37
|
+
response.body = []
|
38
|
+
|
39
|
+
## stub some responses
|
40
|
+
fields = {
|
41
|
+
"accountId" => Fog::Softlayer.mock_account_id,
|
42
|
+
"createDate" => Time.now.iso8601,
|
43
|
+
"dedicatedAccountHostOnlyFlag" => false,
|
44
|
+
"domain" => nil,
|
45
|
+
"fullyQualifiedDomainName" => nil,
|
46
|
+
"hostname" => nil,
|
47
|
+
"id" => Fog::Softlayer.mock_vm_id,
|
48
|
+
"lastPowerStateId" => nil,
|
49
|
+
"lastVerifiedDate" => nil,
|
50
|
+
"maxCpu" => nil,
|
51
|
+
"maxCpuUnits" => "CORE",
|
52
|
+
"maxMemory" => nil,
|
53
|
+
"metricPollDate" => nil,
|
54
|
+
"modifyDate" => nil,
|
55
|
+
"startCpus" => nil,
|
56
|
+
"statusId" => 1001,
|
57
|
+
"globalIdentifier" => Fog::Softlayer.mock_global_identifier
|
58
|
+
}
|
59
|
+
|
60
|
+
# clobber stubbed values where applicable
|
61
|
+
response.body = opts.each_with_index.map do |vm,i|
|
62
|
+
fields.reduce({}) do |result,(field,default)|
|
63
|
+
result[field] = vm[field] || default
|
64
|
+
result
|
65
|
+
end
|
66
|
+
end
|
67
|
+
rescue MissingRequiredParameter
|
68
|
+
response.status = 500
|
69
|
+
response.body = {
|
70
|
+
"code" => "SoftLayer_Exception_MissingCreationProperty",
|
71
|
+
"error" => "Properties #{required.join(', ')} ALL must be set to create an instance of 'SoftLayer_Hardware'."
|
72
|
+
}
|
73
|
+
end
|
74
|
+
response
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
class Real
|
80
|
+
def create_vms(opts)
|
81
|
+
raise ArgumentError, "Fog::Compute::Softlayer#create_vms expects argument of type Array" unless opts.kind_of?(Array)
|
82
|
+
request(:virtual_guest, :create_objects, :body => opts, :http_method => :POST)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "fog/softlayer"
|
3
|
+
|
4
|
+
describe Fog::Compute::Softlayer do
|
5
|
+
describe "when global config is available" do
|
6
|
+
before do
|
7
|
+
|
8
|
+
@arguments = {
|
9
|
+
:softlayer_api_url => "http://localhost",
|
10
|
+
:softlayer_username => "username",
|
11
|
+
:softlayer_api_key => "key"
|
12
|
+
}
|
13
|
+
|
14
|
+
@credential_guard = Minitest::Mock.new
|
15
|
+
def @credential_guard.reject
|
16
|
+
{}
|
17
|
+
end
|
18
|
+
|
19
|
+
Fog.stub :credentials, @credential_guard do
|
20
|
+
@service = Fog::Compute::Softlayer.new(@arguments)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "responds to #request" do
|
25
|
+
assert_respond_to @service, :request
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "when created without required arguments" do
|
31
|
+
it "raises an error" do
|
32
|
+
Fog.stub :credentials, {} do
|
33
|
+
assert_raises ArgumentError do
|
34
|
+
Fog::Compute::Softlayer.new({})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fog-softlayer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Eldridge
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-04-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: fog-core
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: fog-json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: pry-debugger
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: bundler
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.3'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '1.3'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rake
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: minitest
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: Module for the 'fog' gem to support SoftLayer Cloud
|
111
|
+
email:
|
112
|
+
- matt.eldridge@us.ibm.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- .gitignore
|
118
|
+
- CHANGELOG.md
|
119
|
+
- Gemfile
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- fog-softlayer.gemspec
|
124
|
+
- lib/fog/softlayer.rb
|
125
|
+
- lib/fog/softlayer/compute.rb
|
126
|
+
- lib/fog/softlayer/compute/shared.rb
|
127
|
+
- lib/fog/softlayer/core.rb
|
128
|
+
- lib/fog/softlayer/requests/compute/create_bare_metal_server.rb
|
129
|
+
- lib/fog/softlayer/requests/compute/create_vm.rb
|
130
|
+
- lib/fog/softlayer/requests/compute/create_vms.rb
|
131
|
+
- lib/fog/softlayer/version.rb
|
132
|
+
- spec/fog/compute/softlayer_spec.rb
|
133
|
+
homepage: ''
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ! '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 1.8.23
|
155
|
+
signing_key:
|
156
|
+
specification_version: 3
|
157
|
+
summary: This library can be used as a module for `fog` or as standalone provider
|
158
|
+
to use the SoftLayer Cloud in applications
|
159
|
+
test_files:
|
160
|
+
- spec/fog/compute/softlayer_spec.rb
|
161
|
+
has_rdoc:
|