1
0
Fork 0
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:
Brian Dorry 2011-10-09 21:14:05 -04:00
parent f0f24772d1
commit 0a0148399b
19 changed files with 458 additions and 42 deletions

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View 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

View file

@ -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)

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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