mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
[cloudstack] added additional networking support and volume management commands
This commit is contained in:
parent
f0f24772d1
commit
0a0148399b
19 changed files with 458 additions and 42 deletions
|
@ -17,9 +17,6 @@ module Fog
|
|||
end
|
||||
|
||||
def self.signed_params(key,params)
|
||||
# remove empty attributes, cloudstack will not takem them into account when verifying signature
|
||||
params.reject!{|k,v| v.nil? || v.to_s == ''}
|
||||
|
||||
query = params.to_a.sort.collect{|c| "#{c[0]}=#{escape(c[1].to_s)}"}.join('&').downcase
|
||||
|
||||
signed_string = Base64.encode64(OpenSSL::HMAC.digest(DIGEST,key,query)).strip
|
||||
|
|
|
@ -1,43 +1,48 @@
|
|||
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'cloudstack'))
|
||||
require 'fog/compute'
|
||||
require 'digest/md5'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Cloudstack < Fog::Service
|
||||
|
||||
class BadRequest < Fog::Errors::Error; end
|
||||
class BadRequest < Fog::Compute::Cloudstack::Error; end
|
||||
class Unauthorized < Fog::Compute::Cloudstack::Error; end
|
||||
|
||||
requires :cloudstack_api_key, :cloudstack_secret_access_key, :host
|
||||
recognizes :host, :port, :path, :scheme, :persistent
|
||||
requires :cloudstack_host
|
||||
|
||||
recognizes :cloudstack_api_key, :cloudstack_secret_access_key, :cloudstack_session_key, :cloudstack_session_id,
|
||||
:cloudstack_port, :cloudstack_path, :cloudstack_scheme, :cloudstack_persistent
|
||||
|
||||
request_path 'fog/cloudstack/requests/compute'
|
||||
|
||||
request :acquire_ip_address
|
||||
request :assign_to_load_balancer_rule
|
||||
request :attach_volume
|
||||
request :authorize_security_group_ingress
|
||||
|
||||
request :create_account
|
||||
request :create_domain
|
||||
request :create_port_forwarding_rule
|
||||
request :create_load_balancer_rule
|
||||
request :create_security_group
|
||||
request :create_snapshot
|
||||
request :create_user
|
||||
|
||||
request :create_volume
|
||||
request :delete_account
|
||||
request :delete_domain
|
||||
request :delete_load_balancer_rule
|
||||
request :delete_port_forwarding_rule
|
||||
request :delete_security_group
|
||||
request :delete_snapshot
|
||||
request :delete_user
|
||||
|
||||
request :delete_volume
|
||||
request :detach_volume
|
||||
request :deploy_virtual_machine
|
||||
|
||||
request :destroy_virtual_machine
|
||||
|
||||
request :disable_user
|
||||
|
||||
request :enable_user
|
||||
|
||||
request :generate_usage_records
|
||||
|
||||
request :get_vm_password
|
||||
|
||||
request :list_accounts
|
||||
request :list_alerts
|
||||
request :list_async_jobs
|
||||
|
@ -56,11 +61,15 @@ module Fog
|
|||
request :list_hypervisors
|
||||
request :list_instance_groups
|
||||
request :list_isos
|
||||
request :list_load_balancer_rules
|
||||
request :list_load_balancer_rule_instances
|
||||
request :list_network_offerings
|
||||
request :list_networks
|
||||
request :list_os_categories
|
||||
request :list_os_types
|
||||
request :list_pods
|
||||
request :list_port_forwarding_rules
|
||||
request :list_public_ip_addresses
|
||||
request :list_resource_limits
|
||||
request :list_security_groups
|
||||
request :list_service_offerings
|
||||
|
@ -73,17 +82,14 @@ module Fog
|
|||
request :list_virtual_machines
|
||||
request :list_volumes
|
||||
request :list_zones
|
||||
|
||||
request :query_async_job_result
|
||||
|
||||
request :reboot_virtual_machine
|
||||
request :register_user_keys
|
||||
|
||||
request :remove_from_load_balancer_rule
|
||||
request :reset_password_for_virtual_machine
|
||||
request :revoke_security_group_ingress
|
||||
|
||||
request :start_virtual_machine
|
||||
request :stop_virtual_machine
|
||||
|
||||
request :update_account
|
||||
request :update_domain
|
||||
request :update_user
|
||||
|
@ -121,54 +127,122 @@ module Fog
|
|||
require 'multi_json'
|
||||
@cloudstack_api_key = options[:cloudstack_api_key]
|
||||
@cloudstack_secret_access_key = options[:cloudstack_secret_access_key]
|
||||
@host = options[:host]
|
||||
@path = options[:path] || '/client/api'
|
||||
@port = options[:port] || 443
|
||||
@scheme = options[:scheme] || 'https'
|
||||
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", options[:persistent])
|
||||
@cloudstack_session_id = options[:cloudstack_session_id]
|
||||
@cloudstack_session_key = options[:cloudstack_session_key]
|
||||
@host = options[:cloudstack_host]
|
||||
@path = options[:cloudstack_path] || '/client/api'
|
||||
@port = options[:cloudstack_port] || 443
|
||||
@scheme = options[:cloudstack_scheme] || 'https'
|
||||
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", options[:cloudstack_persistent])
|
||||
end
|
||||
|
||||
def reload
|
||||
@connection.reset
|
||||
end
|
||||
|
||||
def request(params)
|
||||
params.merge!({
|
||||
'apiKey' => @cloudstack_api_key,
|
||||
'response' => 'json'
|
||||
def login(username,password,domain)
|
||||
response = issue_request({
|
||||
'response' => 'json',
|
||||
'command' => 'login',
|
||||
'username' => username,
|
||||
'password' => Digest::MD5.hexdigest(password),
|
||||
'domain' => domain
|
||||
})
|
||||
|
||||
signature = Fog::Cloudstack.signed_params(@cloudstack_secret_access_key,params)
|
||||
|
||||
# Parse response cookies to retrive JSESSIONID token
|
||||
cookies = CGI::Cookie.parse(response.get_header('Set-Cookie'))
|
||||
sessionid = cookies['JSESSIONID'].first
|
||||
|
||||
# Decode the login response
|
||||
response = MultiJson.decode(response.body)
|
||||
|
||||
user = response['loginresponse']
|
||||
user.merge!('sessionid' => sessionid)
|
||||
|
||||
@cloudstack_session_id = user['sessionid']
|
||||
@cloudstack_session_key = user['sessionkey']
|
||||
|
||||
user
|
||||
end
|
||||
|
||||
def request(params)
|
||||
params.reject!{|k,v| v.nil?}
|
||||
|
||||
params.merge!('response' => 'json')
|
||||
|
||||
if has_session?
|
||||
params, headers = authorize_session(params)
|
||||
elsif has_keys?
|
||||
params, headers = authorize_api_keys(params)
|
||||
end
|
||||
|
||||
response = issue_request(params,headers)
|
||||
response = MultiJson.decode(response.body) unless response.body.empty?
|
||||
response
|
||||
end
|
||||
|
||||
private
|
||||
def has_session?
|
||||
@cloudstack_session_id && @cloudstack_session_key
|
||||
end
|
||||
|
||||
def has_keys?
|
||||
@cloudstack_api_key && @cloudstack_secret_access_key
|
||||
end
|
||||
|
||||
def authorize_session(params)
|
||||
# set the session id cookie for the request
|
||||
headers = {'Cookie' => "JSESSIONID=#{@cloudstack_session_id};"}
|
||||
# set the sesion key for the request, params are not signed using session auth
|
||||
params.merge!('sessionkey' => @cloudstack_session_key)
|
||||
|
||||
return params, headers
|
||||
end
|
||||
|
||||
def authorize_api_keys(params)
|
||||
headers = {}
|
||||
# merge the api key into the params
|
||||
params.merge!('apiKey' => @cloudstack_api_key)
|
||||
# sign the request parameters
|
||||
signature = Fog::Cloudstack.signed_params(@cloudstack_secret_access_key,params)
|
||||
# merge signature into request param
|
||||
params.merge!({'signature' => signature})
|
||||
|
||||
return params, headers
|
||||
end
|
||||
|
||||
def issue_request(params={},headers={},method='GET',expects=200)
|
||||
begin
|
||||
puts params.inspect
|
||||
response = @connection.request({
|
||||
:query => params,
|
||||
:method => 'GET',
|
||||
:expects => 200
|
||||
:headers => headers,
|
||||
:method => method,
|
||||
:expects => expects
|
||||
})
|
||||
|
||||
rescue Excon::Errors::HTTPStatusError => error
|
||||
error_response = MultiJson.decode(error.response.body)
|
||||
|
||||
error_code = error_response.values.first['errorcode']
|
||||
error_text = error_response.values.first['errortext']
|
||||
|
||||
puts error_response.inspect
|
||||
|
||||
puts error_code
|
||||
puts error_text
|
||||
|
||||
case error_code
|
||||
when 401
|
||||
raise Fog::Compute::Cloudstack::Unauthorized, error_text
|
||||
when 431
|
||||
raise Fog::Compute::Cloudstack::BadRequest.new(error_text)
|
||||
raise Fog::Compute::Cloudstack::BadRequest, error_text
|
||||
else
|
||||
raise Fog::Compute::Cloudstack::Error.new(error_text)
|
||||
raise Fog::Compute::Cloudstack::Error, error_text
|
||||
end
|
||||
end
|
||||
|
||||
unless response.body.empty?
|
||||
response = MultiJson.decode(response.body)
|
||||
end
|
||||
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
21
lib/fog/cloudstack/requests/compute/acquire_ip_address.rb
Normal file
21
lib/fog/cloudstack/requests/compute/acquire_ip_address.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Creates an account.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/associateIpAddress.html]
|
||||
def acquire_ip_address(options={})
|
||||
options.merge!(
|
||||
'command' => 'associateIpAddress'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Assigns virtual machine or a list of virtual machines to a load balancer rule.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/assignToLoadBalancerRule.html]
|
||||
def assign_to_load_balancer_rule(id,virtualmachineids=[])
|
||||
virtualmachineids = [*virtualmachineids]
|
||||
|
||||
options = {
|
||||
'command' => 'assignToLoadBalancerRule',
|
||||
'id' => id,
|
||||
'virtualmachineids' => virtualmachineids.join(',')
|
||||
}
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
23
lib/fog/cloudstack/requests/compute/attach_volume.rb
Normal file
23
lib/fog/cloudstack/requests/compute/attach_volume.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Attaches a disk volume to a virtual machine.
|
||||
#
|
||||
# {CloudStack API Reference}[http://http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/attachVolume.html]
|
||||
def attach_volume(id,virtualmachineid,deviceid=nil)
|
||||
options = {
|
||||
'command' => 'attachVolume',
|
||||
'id' => id,
|
||||
'virtualmachineid' => virtualmachineid,
|
||||
'deviceid' => deviceid
|
||||
}
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Creates a load balancer rule
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.11/global_admin/createLoadBalancerRule.html]
|
||||
def create_load_balancer_rule(options={})
|
||||
options.merge!(
|
||||
'command' => 'createLoadBalancerRule'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Creates a domain.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/createPortForwardingRule.html]
|
||||
def create_port_forwarding_rule(options={})
|
||||
options.merge!(
|
||||
'command' => 'createPortForwardingRule'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
20
lib/fog/cloudstack/requests/compute/create_volume.rb
Normal file
20
lib/fog/cloudstack/requests/compute/create_volume.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Creates a volume for an account that already exists.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/createVolume.html]
|
||||
def create_volume(options={})
|
||||
options.merge!(
|
||||
'command' => 'createVolume'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Creates a domain.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/deleteLoadBalancerRule.html]
|
||||
def delete_load_balancer_rule(options={})
|
||||
options.merge!(
|
||||
'command' => 'deleteLoadBalancerRule'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Creates a domain.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/deletePortForwardingRule.html]
|
||||
def delete_port_forwarding_rule(options={})
|
||||
options.merge!(
|
||||
'command' => 'deletePortForwardingRule'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
20
lib/fog/cloudstack/requests/compute/delete_volume.rb
Normal file
20
lib/fog/cloudstack/requests/compute/delete_volume.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Deletes a specified user.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/deleteVolume.html]
|
||||
def delete_volume(options={})
|
||||
options.merge!(
|
||||
'command' => 'deleteVolume'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,7 +12,7 @@ module Fog
|
|||
)
|
||||
|
||||
if ( securitygroupids = options.delete('securitygroupids') ).is_a?(Array)
|
||||
options.merge!('securitygroupids' => securitygroupnames.join(','))
|
||||
options.merge!('securitygroupids' => securitygroupids.join(','))
|
||||
end
|
||||
|
||||
if ( securitygroupnames = options.delete('securitygroupnames') ).is_a?(Array)
|
||||
|
|
21
lib/fog/cloudstack/requests/compute/detach_volume.rb
Normal file
21
lib/fog/cloudstack/requests/compute/detach_volume.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Deletes a specified domain.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/detachVolume.html]
|
||||
def detach_volume(id)
|
||||
options = {
|
||||
'command' => 'detachVolume',
|
||||
'id' => id
|
||||
}
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Lists resource limits.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/listLoadBalancerRuleInstances.html]
|
||||
def list_load_balancer_rule_instances(load_balancer_rule_id,options={})
|
||||
options.merge!(
|
||||
'command' => 'listLoadBalancerRuleInstances',
|
||||
'id' => load_balancer_rule_id
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Lists resource limits.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/listLoadBalancerRules.html]
|
||||
def list_load_balancer_rules(options={})
|
||||
options.merge!(
|
||||
'command' => 'listLoadBalancerRules'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Lists resource limits.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/listPortForwardingRules.html]
|
||||
def list_port_forwarding_rules(options={})
|
||||
options.merge!(
|
||||
'command' => 'listPortForwardingRules'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Lists resource limits.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/listPublicIpAddresses.html]
|
||||
def list_public_ip_addresses(options={})
|
||||
options.merge!(
|
||||
'command' => 'listPublicIpAddresses'
|
||||
)
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Removes a virtual machine or a list of virtual machines from a load balancer rule.
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/removeFromLoadBalancerRule.html]
|
||||
def remove_from_load_balancer_rule(id,virtualmachineids=[])
|
||||
virtualmachineids = [*virtualmachineids]
|
||||
|
||||
options = {
|
||||
'command' => 'removeFromLoadBalancerRule',
|
||||
'id' => id,
|
||||
'virtualmachineids' => virtualmachineids.join(',')
|
||||
}
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Cloudstack
|
||||
class Real
|
||||
|
||||
# Returns an encrypted password for the VM
|
||||
#
|
||||
# {CloudStack API Reference}[http://download.cloud.com/releases/2.2.0/api_2.2.4/global_admin/resetPasswordForVirtualMachine.html]
|
||||
def reset_password_for_virtual_machine(id)
|
||||
options = {
|
||||
'command' => 'resetPasswordForVirtualMachine',
|
||||
'id' => id
|
||||
}
|
||||
|
||||
request(options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue