mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Merge pull request #906 from engineyard/cloudstack
[cloudstack|compute] server abstraction and mocks
This commit is contained in:
commit
41494239e6
23 changed files with 813 additions and 63 deletions
|
@ -17,12 +17,24 @@ module Fog
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.signed_params(key,params)
|
def self.signed_params(key,params)
|
||||||
query = params.to_a.sort.collect{|c| "#{c[0]}=#{escape(c[1].to_s)}"}.join('&').downcase
|
query = params.map{|k,v| [k.to_s, v]}.sort.collect{|c| "#{c[0]}=#{escape(c[1].to_s)}"}.join('&').downcase
|
||||||
|
|
||||||
signed_string = Base64.encode64(OpenSSL::HMAC.digest(@@digest,key,query)).strip
|
signed_string = Base64.encode64(OpenSSL::HMAC.digest(@@digest,key,query)).strip
|
||||||
|
|
||||||
signed_string
|
signed_string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.uuid
|
||||||
|
[8,4,4,4,12].map{|i| Fog::Mock.random_hex(i)}.join("-")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.ip_address
|
||||||
|
4.times.map{ Fog::Mock.random_numbers(3) }.join(".")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.mac_address
|
||||||
|
6.times.map{ Fog::Mock.random_numbers(2) }.join(":")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,18 @@ module Fog
|
||||||
|
|
||||||
request_path 'fog/cloudstack/requests/compute'
|
request_path 'fog/cloudstack/requests/compute'
|
||||||
|
|
||||||
|
|
||||||
|
model_path 'fog/cloudstack/models/compute'
|
||||||
|
model :address
|
||||||
|
model :server
|
||||||
|
collection :servers
|
||||||
|
model :image
|
||||||
|
collection :images
|
||||||
|
model :flavor
|
||||||
|
collection :flavors
|
||||||
|
model :zone
|
||||||
|
collection :zones
|
||||||
|
|
||||||
request :acquire_ip_address
|
request :acquire_ip_address
|
||||||
request :assign_to_load_balancer_rule
|
request :assign_to_load_balancer_rule
|
||||||
request :attach_volume
|
request :attach_volume
|
||||||
|
@ -40,6 +52,7 @@ module Fog
|
||||||
request :delete_ssh_key_pair
|
request :delete_ssh_key_pair
|
||||||
request :delete_snapshot
|
request :delete_snapshot
|
||||||
request :delete_snapshot_policies
|
request :delete_snapshot_policies
|
||||||
|
request :delete_template
|
||||||
request :delete_user
|
request :delete_user
|
||||||
request :delete_volume
|
request :delete_volume
|
||||||
request :detach_volume
|
request :detach_volume
|
||||||
|
@ -247,7 +260,175 @@ module Fog
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
end # Real
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def self.data
|
||||||
|
@data ||= begin
|
||||||
|
rc_options = Fog.credentials[:cloudstack] || {}
|
||||||
|
zone_id = rc_options[:zone_id] ||"c554c592-e09c-9df5-7688-4a32754a4305"
|
||||||
|
image_id = rc_options[:image_id] || "8a31cf9c-f248-0588-256e-9dbf58785216"
|
||||||
|
flavor_id = rc_options[:flavor_id] || "4437ac6c-9fe3-477a-57ec-60a5a45896a4"
|
||||||
|
account_id = "8bec6f15-e2b8-44fc-a8f3-a022b2873440"
|
||||||
|
user_id = Fog::Cloudstack.uuid
|
||||||
|
domain_id = Fog::Cloudstack.uuid
|
||||||
|
network_id = (Array(rc_options[:network_ids]) || [Fog::Cloudstack.uuid]).first
|
||||||
|
domain_name = "exampleorg"
|
||||||
|
domain = {
|
||||||
|
"id" => domain_id,
|
||||||
|
"name" => domain_name,
|
||||||
|
"level" => 1,
|
||||||
|
"parentdomainid" => Fog::Cloudstack.uuid,
|
||||||
|
"parentdomainname" => "ROOT",
|
||||||
|
"haschild" => false,
|
||||||
|
"path" => "ROOT/accountname"
|
||||||
|
}
|
||||||
|
{
|
||||||
|
:networks => { network_id => {
|
||||||
|
"id" => network_id,
|
||||||
|
"name" => "10.56.23.0/26",
|
||||||
|
"displaytext" => "10.56.23.0/26",
|
||||||
|
"broadcastdomaintype" => "Vlan",
|
||||||
|
"traffictype" => "Guest",
|
||||||
|
"gateway" => "10.56.23.1",
|
||||||
|
"netmask" => "255.255.255.192",
|
||||||
|
"cidr" => "10.56.23.0/26",
|
||||||
|
"zoneid" => zone_id,
|
||||||
|
"zonename" => "zone-00",
|
||||||
|
"networkofferingid" => "af0c9bd5-a1b2-4ad0-bf4b-d6fa9b1b9d5b",
|
||||||
|
"networkofferingname" => "DefaultSharedNetworkOffering",
|
||||||
|
"networkofferingdisplaytext" => "Offering for Shared networks",
|
||||||
|
"networkofferingavailability" => "Optional",
|
||||||
|
"issystem" => false,
|
||||||
|
"state" => "Setup",
|
||||||
|
"related" => "86bbc9fc-d92e-49db-9fdc-296189090017",
|
||||||
|
"broadcasturi" => "vlan://800",
|
||||||
|
"dns1" => "10.0.80.11",
|
||||||
|
"type" => "Shared",
|
||||||
|
"vlan" => "800",
|
||||||
|
"acltype" => "Domain",
|
||||||
|
"subdomainaccess" => true,
|
||||||
|
"domainid" => domain_id,
|
||||||
|
"domain" => "ROOT",
|
||||||
|
"service" => [
|
||||||
|
{"name" => "UserData"},
|
||||||
|
{"name" => "Dhcp"},
|
||||||
|
{"name" => "Dns", "capability" => [
|
||||||
|
{"name" => "AllowDnsSuffixModification",
|
||||||
|
"value" => "true",
|
||||||
|
"canchooseservicecapability" => false}]
|
||||||
|
}],
|
||||||
|
"networkdomain" => "cs1cloud.internal",
|
||||||
|
"physicalnetworkid" => "8f4627c5-1fdd-4504-8a92-f61b4e9cb3e3",
|
||||||
|
"restartrequired" => false,
|
||||||
|
"specifyipranges" => true}
|
||||||
|
},
|
||||||
|
:zones => { zone_id => {
|
||||||
|
"id" => zone_id,
|
||||||
|
"name"=> "zone-00",
|
||||||
|
"domainid" => 1,
|
||||||
|
"domainname" => "ROOT",
|
||||||
|
"networktype" => "Advanced",
|
||||||
|
"securitygroupsenabled" => false,
|
||||||
|
"allocationstate" => "Enabled",
|
||||||
|
"zonetoken" => Fog::Cloudstack.uuid,
|
||||||
|
"dhcpprovider" => "VirtualRouter"}},
|
||||||
|
:images => { image_id => {
|
||||||
|
"id" => image_id,
|
||||||
|
"name" => "CentOS 5.6(64-bit) no GUI (XenServer)",
|
||||||
|
"displaytext" => "CentOS 5.6(64-bit) no GUI (XenServer)",
|
||||||
|
"ispublic" => true,
|
||||||
|
"created" => "2012-05-09T15:29:33-0500",
|
||||||
|
"isready" => true,
|
||||||
|
"passwordenabled" => false,
|
||||||
|
"format" => "VHD",
|
||||||
|
"isfeatured" => true,
|
||||||
|
"crossZones" => true,
|
||||||
|
"ostypeid" => "a6a6694a-18f5-4765-8418-2b7a5f37cd0f",
|
||||||
|
"ostypename" => "CentOS 5.3 (64-bit)",
|
||||||
|
"account" => "system",
|
||||||
|
"zoneid" => zone_id,
|
||||||
|
"zonename" => "zone-00",
|
||||||
|
"status" => "Download Complete",
|
||||||
|
"size" => 21474836480,
|
||||||
|
"templatetype" => "BUILTIN",
|
||||||
|
"domain" => "ROOT",
|
||||||
|
"domainid" => "6023b6fe-5bef-4358-bc76-9f4e75afa52f",
|
||||||
|
"isextractable" => true,
|
||||||
|
"checksum" => "905cec879afd9c9d22ecc8036131a180"}},
|
||||||
|
:flavors => { flavor_id => {
|
||||||
|
"id" => flavor_id,
|
||||||
|
"name" => "Medium Instance",
|
||||||
|
"displaytext" => "Medium Instance",
|
||||||
|
"cpunumber" => 1,
|
||||||
|
"cpuspeed" => 1000,
|
||||||
|
"memory" => 1024,
|
||||||
|
"created" => "2012-05-09T14:48:36-0500",
|
||||||
|
"storagetype" => "shared",
|
||||||
|
"offerha" => false,
|
||||||
|
"limitcpuuse" => false,
|
||||||
|
"issystem" => false,
|
||||||
|
"defaultuse" => false}},
|
||||||
|
:accounts => { account_id => {
|
||||||
|
"id" => account_id,
|
||||||
|
"name" => "accountname",
|
||||||
|
"accounttype" => 2,
|
||||||
|
"domainid" => domain_id,
|
||||||
|
"domain" => domain_name,
|
||||||
|
"receivedbytes" => 0,
|
||||||
|
"sentbytes" => 0,
|
||||||
|
"vmlimit" => "Unlimited",
|
||||||
|
"vmtotal" => 0,
|
||||||
|
"vmavailable" => "Unlimited",
|
||||||
|
"iplimit" => "Unlimited",
|
||||||
|
"iptotal" => 0,
|
||||||
|
"ipavailable" => "Unlimited",
|
||||||
|
"volumelimit" => "Unlimited",
|
||||||
|
"volumetotal" => 0,
|
||||||
|
"volumeavailable" => "Unlimited",
|
||||||
|
"snapshotlimit" => "Unlimited",
|
||||||
|
"snapshottotal" => 0,
|
||||||
|
"snapshotavailable" => "Unlimited",
|
||||||
|
"templatelimit" => "Unlimited",
|
||||||
|
"templatetotal" => 0,
|
||||||
|
"templateavailable" => "Unlimited",
|
||||||
|
"vmstopped" => 0,
|
||||||
|
"vmrunning" => 0,
|
||||||
|
"projectlimit" => "Unlimited",
|
||||||
|
"projecttotal" => 1,
|
||||||
|
"projectavailable" => "Unlimited",
|
||||||
|
"networklimit" => "Unlimited",
|
||||||
|
"networktotal" => 0,
|
||||||
|
"networkavailable" => "Unlimited",
|
||||||
|
"state" => "enabled",
|
||||||
|
"user" =>
|
||||||
|
[{"id" => user_id,
|
||||||
|
"username" => "username",
|
||||||
|
"firstname" => "Bob",
|
||||||
|
"lastname" => "Lastname",
|
||||||
|
"email" => "email@example.com",
|
||||||
|
"created" => "2012-05-14T16:25:17-0500",
|
||||||
|
"state" => "enabled",
|
||||||
|
"account" => "accountname",
|
||||||
|
"accounttype" => 2,
|
||||||
|
"domainid" => domain_id,
|
||||||
|
"domain" => domain_name,
|
||||||
|
"apikey" => Fog::Cloudstack.uuid,
|
||||||
|
"secretkey" => Fog::Cloudstack.uuid}]}},
|
||||||
|
:domains => { domain_id => domain },
|
||||||
|
:servers => {}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.reset
|
||||||
|
@data= nil
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
def data
|
||||||
|
self.class.data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end # Cloudstack
|
||||||
|
end # Compute
|
||||||
|
end # Fog
|
||||||
|
|
17
lib/fog/cloudstack/models/compute/address.rb
Normal file
17
lib/fog/cloudstack/models/compute/address.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
class Address < Fog::Model
|
||||||
|
identity :id, :aliases => 'id'
|
||||||
|
attribute :network_id, :aliases => 'networkid'
|
||||||
|
attribute :ip_address, :aliases => 'ipaddress'
|
||||||
|
attribute :traffic_type, :aliases => 'traffictype'
|
||||||
|
attribute :is_default, :aliases => 'isdefault'
|
||||||
|
attribute :mac_address, :aliases => 'macaddress'
|
||||||
|
attribute :netmask
|
||||||
|
attribute :gateway
|
||||||
|
attribute :type
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
33
lib/fog/cloudstack/models/compute/flavor.rb
Normal file
33
lib/fog/cloudstack/models/compute/flavor.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
class Flavor < Fog::Model
|
||||||
|
identity :id, :aliases => 'id'
|
||||||
|
attribute :cpu_number, :aliases => 'cpunumber'
|
||||||
|
attribute :cpu_speed, :aliases => 'cpuspeed'
|
||||||
|
attribute :created
|
||||||
|
attribute :default_use, :aliases => 'defaultuse'
|
||||||
|
attribute :display_text, :aliases => 'display_text'
|
||||||
|
attribute :domain
|
||||||
|
attribute :host_tags, :aliases => 'host_tags'
|
||||||
|
attribute :is_system, :aliases => 'is_system'
|
||||||
|
attribute :limit_cpu_use, :aliases => 'limitcpuuse'
|
||||||
|
attribute :tags
|
||||||
|
attribute :system_vm_type, :aliases => 'systemvm'
|
||||||
|
attribute :storage_type, :aliases => 'storagetype'
|
||||||
|
attribute :offer_ha, :aliases => 'offerha'
|
||||||
|
attribute :network_rate, :aliases => 'networkrate'
|
||||||
|
attribute :name
|
||||||
|
attribute :memory
|
||||||
|
|
||||||
|
def save
|
||||||
|
raise Fog::Errors::Error.new('Creating a flavor is not supported')
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
raise Fog::Errors::Error.new('Destroying a flavor is not supported')
|
||||||
|
end
|
||||||
|
end # Server
|
||||||
|
end # Cloudstack
|
||||||
|
end # Compute
|
||||||
|
end # Fog
|
28
lib/fog/cloudstack/models/compute/flavors.rb
Normal file
28
lib/fog/cloudstack/models/compute/flavors.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
require 'fog/core/collection'
|
||||||
|
require 'fog/cloudstack/models/compute/flavor'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
|
||||||
|
class Flavors < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Compute::Cloudstack::Flavor
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = connection.list_service_offerings["listserviceofferingsresponse"]["serviceoffering"] || []
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(flavor_id)
|
||||||
|
if flavor = connection.list_service_offerings('id' => flavor_id)["listserviceofferingsresponse"]["serviceoffering"].first
|
||||||
|
new(flavor)
|
||||||
|
end
|
||||||
|
rescue Fog::Compute::Cloudstack::BadRequest
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
72
lib/fog/cloudstack/models/compute/image.rb
Normal file
72
lib/fog/cloudstack/models/compute/image.rb
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
class Image < Fog::Model
|
||||||
|
identity :id, :aliases => 'id'
|
||||||
|
attribute :account
|
||||||
|
attribute :account_id, :aliases => 'accountid'
|
||||||
|
attribute :bootable
|
||||||
|
attribute :checksum
|
||||||
|
attribute :created
|
||||||
|
attribute :cross_zones, :aliases => 'crossZones'
|
||||||
|
attribute :details
|
||||||
|
attribute :display_text, :aliases => 'displaytext'
|
||||||
|
attribute :domain
|
||||||
|
attribute :domain_id, :aliases => 'domainid'
|
||||||
|
attribute :format
|
||||||
|
attribute :host_id, :aliases => 'hostid'
|
||||||
|
attribute :host_name, :aliases => 'hostname'
|
||||||
|
attribute :hypervisor
|
||||||
|
attribute :job_id, :aliases => 'jobid'
|
||||||
|
attribute :job_status, :aliases => 'jobstatus'
|
||||||
|
attribute :is_extractable, :aliases => 'isextractable'
|
||||||
|
attribute :is_featured, :aliases => 'isfeatured'
|
||||||
|
attribute :is_public, :aliases => 'ispublic'
|
||||||
|
attribute :is_ready, :aliases => 'isready'
|
||||||
|
attribute :name
|
||||||
|
attribute :os_type_id, :aliases => 'ostypeid'
|
||||||
|
attribute :os_type_name, :aliases => 'ostypename'
|
||||||
|
attribute :password_enabled, :aliases => 'ostypename'
|
||||||
|
attribute :project
|
||||||
|
attribute :project_id, :aliases => 'projectid'
|
||||||
|
attribute :removed
|
||||||
|
attribute :size
|
||||||
|
attribute :source_template_id, :aliases => 'sourcetemplateid'
|
||||||
|
attribute :status
|
||||||
|
attribute :template_tag, :aliases => 'templatetag'
|
||||||
|
attribute :template_type, :aliases => 'templatetype'
|
||||||
|
attribute :zone_id, :aliases => 'zoneid'
|
||||||
|
attribute :zone_name, :aliases => 'zonename'
|
||||||
|
|
||||||
|
attr_accessor :bits, :requires_hvm, :snapshot_id, :url, :virtual_machine_id, :volume_id
|
||||||
|
|
||||||
|
def save
|
||||||
|
options = {
|
||||||
|
'displaytext' => display_text,
|
||||||
|
'name' => name,
|
||||||
|
'ostypeid' => os_type_id,
|
||||||
|
'bits' => bits,
|
||||||
|
'details' => details,
|
||||||
|
'isfeatured' => is_featured,
|
||||||
|
'ispublic' => is_public,
|
||||||
|
'passwordenabled' => password_enabled,
|
||||||
|
'requireshvm' => requires_hvm,
|
||||||
|
'snapshotid' => snapshot_id,
|
||||||
|
'templatetag' => template_tag,
|
||||||
|
'url' => url,
|
||||||
|
'virtualmachineid' => virtual_machine_id,
|
||||||
|
'volumeid' => volume_id
|
||||||
|
}
|
||||||
|
data = connection.create_template(options)
|
||||||
|
merge_attributes(data['createtemplateresponse'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
requires :id
|
||||||
|
connection.delete_template('id' => self.id)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end # Server
|
||||||
|
end # Cloudstack
|
||||||
|
end # Compute
|
||||||
|
end # Fog
|
32
lib/fog/cloudstack/models/compute/images.rb
Normal file
32
lib/fog/cloudstack/models/compute/images.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
require 'fog/core/collection'
|
||||||
|
require 'fog/cloudstack/models/compute/image'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
|
||||||
|
class Images < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Compute::Cloudstack::Image
|
||||||
|
|
||||||
|
def all(filters={})
|
||||||
|
options = {
|
||||||
|
'templatefilter' => 'self'
|
||||||
|
}.merge(filters)
|
||||||
|
|
||||||
|
data = connection.list_templates(options)["listtemplatesresponse"]["template"] || []
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(template_id)
|
||||||
|
if template = connection.list_templates('id' => template_id)["listtemplatesresponse"]["template"].first
|
||||||
|
new(template)
|
||||||
|
end
|
||||||
|
rescue Fog::Compute::Cloudstack::BadRequest
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
84
lib/fog/cloudstack/models/compute/server.rb
Normal file
84
lib/fog/cloudstack/models/compute/server.rb
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
require 'fog/compute/models/server'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
class Server < Fog::Compute::Server
|
||||||
|
identity :id, :aliases => 'id'
|
||||||
|
attribute :name
|
||||||
|
attribute :account
|
||||||
|
attribute :domain
|
||||||
|
attribute :created
|
||||||
|
attribute :state
|
||||||
|
attribute :haenable
|
||||||
|
attribute :memory
|
||||||
|
attribute :display_name, :aliases => 'displayname'
|
||||||
|
attribute :domain_id, :aliases => 'domainid'
|
||||||
|
attribute :host_id, :aliases => 'hostid'
|
||||||
|
attribute :host_name, :aliases => 'hostname'
|
||||||
|
attribute :project_id, :aliases => 'projectid'
|
||||||
|
attribute :zone_id, :aliases => 'zoneid'
|
||||||
|
attribute :zone_name, :aliases => 'zonename'
|
||||||
|
attribute :image_id, :aliases => ['templateid', :template_id]
|
||||||
|
attribute :image_name, :aliases => ['templatename', :template_name]
|
||||||
|
attribute :templated_display_text, :aliases => 'templatedisplaytext'
|
||||||
|
attribute :password_enabled, :aliases => 'passwordenabled'
|
||||||
|
attribute :flavor_id, :aliases => ['serviceofferingid', :service_offering_id]
|
||||||
|
attribute :flavor_name, :aliases => ['serviceofferingname', :service_offering_name]
|
||||||
|
attribute :cpu_number, :aliases => 'cpunumber'
|
||||||
|
attribute :cpu_speed, :aliases => 'cpuspeed'
|
||||||
|
attribute :cpu_used, :aliases => 'cpuused'
|
||||||
|
attribute :network_kbs_read, :aliases => 'networkkbsread'
|
||||||
|
attribute :network_kbs_write, :aliases => 'networkkbswrite'
|
||||||
|
attribute :guest_os_id, :aliases => 'guestosid'
|
||||||
|
attribute :root_device_id, :aliases => 'rootdeviceid'
|
||||||
|
attribute :root_device_type, :aliases => 'rootdevicetype'
|
||||||
|
attribute :security_group, :aliases => 'securitygroup'
|
||||||
|
attribute :nics, :aliases => 'nic'
|
||||||
|
|
||||||
|
attr_accessor :network_ids, :disk_offering_id, :ip_address, :ip_to_network_list
|
||||||
|
|
||||||
|
def ready?
|
||||||
|
state == 'Running'
|
||||||
|
end
|
||||||
|
|
||||||
|
def save
|
||||||
|
requires :image_id, :flavor_id, :zone_id
|
||||||
|
|
||||||
|
options = {
|
||||||
|
'templateid' => image_id,
|
||||||
|
'serviceofferingid' => flavor_id,
|
||||||
|
'zoneid' => zone_id,
|
||||||
|
'networkids' => network_ids,
|
||||||
|
'diskofferingid' => disk_offering_id,
|
||||||
|
'displayname' => display_name,
|
||||||
|
'domainid' => domain_id,
|
||||||
|
'hostid' => host_id,
|
||||||
|
'ipaddress' => ip_address,
|
||||||
|
'iptonetworklist' => ip_to_network_list,
|
||||||
|
'projectid' => project_id
|
||||||
|
}
|
||||||
|
|
||||||
|
options.merge!('networkids' => network_ids) if network_ids
|
||||||
|
|
||||||
|
data = connection.deploy_virtual_machine(options)
|
||||||
|
merge_attributes(data['deployvirtualmachineresponse'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def addresses
|
||||||
|
nics.map{|nic| Address.new(nic)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def flavor
|
||||||
|
connection.flavors.get(self.flavor_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
requires :id
|
||||||
|
connection.destroy_virtual_machine(:id => id)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end # Server
|
||||||
|
end # Cloudstack
|
||||||
|
end # Compute
|
||||||
|
end # Fog
|
34
lib/fog/cloudstack/models/compute/servers.rb
Normal file
34
lib/fog/cloudstack/models/compute/servers.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
require 'fog/core/collection'
|
||||||
|
require 'fog/cloudstack/models/compute/server'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
|
||||||
|
class Servers < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Compute::Cloudstack::Server
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = connection.list_virtual_machines["listvirtualmachinesresponse"]["virtualmachine"] || []
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def bootstrap(new_attributes = {})
|
||||||
|
server = create(new_attributes)
|
||||||
|
server.wait_for { ready? }
|
||||||
|
server
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(server_id)
|
||||||
|
if server = connection.list_virtual_machines('id' => server_id)["listvirtualmachinesresponse"]["virtualmachine"].first
|
||||||
|
new(server)
|
||||||
|
end
|
||||||
|
rescue Fog::Compute::Cloudstack::BadRequest
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
39
lib/fog/cloudstack/models/compute/zone.rb
Normal file
39
lib/fog/cloudstack/models/compute/zone.rb
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
class Zone < Fog::Model
|
||||||
|
identity :id, :aliases => 'id'
|
||||||
|
attribute :name
|
||||||
|
attribute :domain_id, :aliases => 'domainid'
|
||||||
|
attribute :domain_name, :aliases => ['domainname', 'domain']
|
||||||
|
attribute :network_type, :aliases => 'networktype'
|
||||||
|
attribute :security_groups_enabled, :aliases => ['securitygroupsenabled', 'securitygroupenabled']
|
||||||
|
attribute :allocation_state, :aliases => 'allocationstate'
|
||||||
|
attribute :zone_token, :aliases => 'zonetoken'
|
||||||
|
attribute :dhcp_provider, :aliases => 'dhcpprovider'
|
||||||
|
|
||||||
|
attr_accessor :dns1, :dns2, :internaldns1, :internaldns2, :guest_cidr_address
|
||||||
|
|
||||||
|
def save
|
||||||
|
options = {
|
||||||
|
'dns1' => dns1,
|
||||||
|
'internaldns1' => internaldns1,
|
||||||
|
'name' => name,
|
||||||
|
'networktype' => network_type,
|
||||||
|
'allocationstate' => allocation_state,
|
||||||
|
'dns2' => dns2,
|
||||||
|
'domain' => domain_name,
|
||||||
|
'domainid' => domain_id,
|
||||||
|
'guestcidraddress' => guest_cidr_address,
|
||||||
|
'internaldns2' => internaldns2,
|
||||||
|
'securitygroupenabled' => security_group_enabled,
|
||||||
|
}
|
||||||
|
data = connection.create_zone(options)
|
||||||
|
merge_attributes(data['createzoneresponse'])
|
||||||
|
end
|
||||||
|
|
||||||
|
end # Zone
|
||||||
|
end # Cloudstack
|
||||||
|
end # Compute
|
||||||
|
end # Fog
|
||||||
|
|
33
lib/fog/cloudstack/models/compute/zones.rb
Normal file
33
lib/fog/cloudstack/models/compute/zones.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
require 'fog/core/collection'
|
||||||
|
require 'fog/cloudstack/models/compute/zone'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
|
||||||
|
class Zones < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Compute::Cloudstack::Zone
|
||||||
|
|
||||||
|
def all(filters={})
|
||||||
|
options = {
|
||||||
|
'templatefilter' => 'self'
|
||||||
|
}.merge(filters)
|
||||||
|
|
||||||
|
data = connection.list_zones(options)["listzonesresponse"]["zone"] || []
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(zone_id)
|
||||||
|
if zone = connection.list_zones('id' => zone_id)["listzonesresponse"]["zone"].first
|
||||||
|
new(zone)
|
||||||
|
end
|
||||||
|
rescue Fog::Compute::Cloudstack::BadRequest
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
20
lib/fog/cloudstack/requests/compute/delete_template.rb
Normal file
20
lib/fog/cloudstack/requests/compute/delete_template.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Cloudstack
|
||||||
|
class Real
|
||||||
|
|
||||||
|
# Deletes a specified template.
|
||||||
|
#
|
||||||
|
# {CloudStack API Reference}[http://http://download.cloud.com/releases/3.0.0/api_3.0.0/user/deleteTemplate.html]
|
||||||
|
def delete_template(options={})
|
||||||
|
options.merge!(
|
||||||
|
'command' => 'deleteTemplate'
|
||||||
|
)
|
||||||
|
|
||||||
|
request(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,23 +11,119 @@ module Fog
|
||||||
'command' => 'deployVirtualMachine'
|
'command' => 'deployVirtualMachine'
|
||||||
)
|
)
|
||||||
|
|
||||||
if ( securitygroupids = options.delete('securitygroupids') ).is_a?(Array)
|
if security_group_ids = options.delete('securitygroupids')
|
||||||
options.merge!('securitygroupids' => securitygroupids.join(','))
|
options.merge!('securitygroupids' => Array(security_group_ids).join(','))
|
||||||
end
|
end
|
||||||
|
|
||||||
if ( securitygroupnames = options.delete('securitygroupnames') ).is_a?(Array)
|
if security_group_names = options.delete('securitygroupnames')
|
||||||
options.merge!('securitygroupnames' => securitygroupnames.join(','))
|
options.merge!('securitygroupnames' => Array(security_group_names).join(','))
|
||||||
end
|
end
|
||||||
|
|
||||||
if ( networkids = options.delete('networkids') ).is_a?(Array)
|
if network_ids = options.delete('networkids')
|
||||||
options.merge!('networkids' => networkids.join(','))
|
options.merge!('networkids' => Array(network_ids).join(','))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
request(options)
|
request(options)
|
||||||
end
|
end
|
||||||
|
end # Real
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
|
||||||
|
def deploy_virtual_machine(options={})
|
||||||
|
zone_id = options['zoneid']
|
||||||
|
unless zone_id
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new('Unable to execute API command deployvirtualmachine due to missing parameter zoneid')
|
||||||
end
|
end
|
||||||
|
unless zone = self.data[:zones][zone_id]
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new("Unable to execute API command deployvirtualmachine due to invalid value. Object zone(uuid: #{zone_id}) does not exist.")
|
||||||
end
|
end
|
||||||
|
zone_name = zone[:name]
|
||||||
|
|
||||||
|
template_id = options['templateid']
|
||||||
|
unless template = self.data[:images][template_id]
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new('Unable to execute API command deployvirtualmachine due to missing parameter templateid')
|
||||||
end
|
end
|
||||||
end
|
template_name = template[:name]
|
||||||
|
template_display_text = template[:display_text]
|
||||||
|
|
||||||
|
service_offering_id = options['serviceofferingid']
|
||||||
|
unless service_offering = self.data[:flavors][service_offering_id]
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new('Unable to execute API command deployvirtualmachine due to missing parameter serviceofferingid')
|
||||||
|
end
|
||||||
|
|
||||||
|
service_offering_name = service_offering[:name]
|
||||||
|
service_offering_cpu_number = service_offering[:cpunumber]
|
||||||
|
service_offering_cpu_speed = service_offering[:cpuspeed]
|
||||||
|
service_offering_memory = service_offering[:cpumemory]
|
||||||
|
|
||||||
|
identity = Fog::Cloudstack.uuid
|
||||||
|
name = options['name'] || Fog::Cloudstack.uuid
|
||||||
|
display_name = options['displayname'] || name
|
||||||
|
account_name = options['account'] || self.data[:accounts].first[1]["name"]
|
||||||
|
|
||||||
|
domain = options['domainid'] ? self.data[:domains][options['domainid']] : self.data[:domains].first[1]
|
||||||
|
domain_id = domain[:id]
|
||||||
|
domain_name = domain[:name]
|
||||||
|
|
||||||
|
# how is this setup
|
||||||
|
password = nil
|
||||||
|
password_enabled = false
|
||||||
|
|
||||||
|
guest_os_id = Fog::Cloudstack.uuid
|
||||||
|
|
||||||
|
security_group_ids = options['securitygroupids'] || [] # TODO: for now
|
||||||
|
|
||||||
|
network_ids = Array(options['networkids']) || [self.data[:networks].first[1]["id"]]
|
||||||
|
networks = network_ids.map{|nid| self.data[:networks][nid]}
|
||||||
|
nic = networks.map do |network|
|
||||||
|
{
|
||||||
|
"id" => Fog::Cloudstack.uuid,
|
||||||
|
"networkid" => network["id"],
|
||||||
|
"netmask" => Fog::Cloudstack.ip_address,
|
||||||
|
"gateway" => network["gateway"],
|
||||||
|
"ipaddress" => Fog::Cloudstack.ip_address,
|
||||||
|
"traffictype" => "Guest", # TODO: ?
|
||||||
|
"type" => network["type"],
|
||||||
|
"isdefault" => true, # TODO: ?
|
||||||
|
"macaddress" => Fog::Cloudstack.mac_address
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
virtual_machine = {
|
||||||
|
"id" => identity,
|
||||||
|
"name" => name,
|
||||||
|
"displayname" => display_name,
|
||||||
|
"account" => account_name,
|
||||||
|
"domainid" => domain_id,
|
||||||
|
"domain" => domain_name,
|
||||||
|
"created" => Time.now.to_s,
|
||||||
|
"state" => "Running",
|
||||||
|
"haenable" => false,
|
||||||
|
"zoneid" => zone_id,
|
||||||
|
"zonename" => zone_name,
|
||||||
|
"templateid" => template_id,
|
||||||
|
"templatename" => template_name,
|
||||||
|
"templatedisplaytext" => template_display_text,
|
||||||
|
"passwordenabled" => false,
|
||||||
|
"serviceofferingid" => service_offering_id,
|
||||||
|
"serviceofferingname" => service_offering_name,
|
||||||
|
"cpunumber" => service_offering_cpu_number,
|
||||||
|
"cpuspeed" => service_offering_cpu_speed,
|
||||||
|
"memory" => service_offering_memory,
|
||||||
|
"cpuused" => "0%",
|
||||||
|
"networkkbsread" => 0,
|
||||||
|
"networkkbswrite" => 0,
|
||||||
|
"guestosid" => guest_os_id,
|
||||||
|
"rootdeviceid" => 0,
|
||||||
|
"rootdevicetype" => "NetworkFilesystem",
|
||||||
|
"securitygroup" => security_group_ids, # TODO: mayhaps?
|
||||||
|
"nic" => nic
|
||||||
|
}
|
||||||
|
|
||||||
|
self.data[:servers][identity]= virtual_machine
|
||||||
|
{'deployvirtualmachineresponse' => virtual_machine}
|
||||||
|
end
|
||||||
|
end # Mock
|
||||||
|
end # Cloudstack
|
||||||
|
end # Compute
|
||||||
|
end # Fog
|
||||||
|
|
|
@ -14,7 +14,16 @@ module Fog
|
||||||
request(options)
|
request(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end # Real
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
|
||||||
|
def destroy_virtual_machine(options={})
|
||||||
|
identity = options[:id]
|
||||||
|
|
||||||
|
self.data[:servers].delete(identity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end # Cloudstack
|
||||||
end
|
end # Compute
|
||||||
|
end # Fog
|
||||||
|
|
|
@ -14,7 +14,22 @@ module Fog
|
||||||
request(options)
|
request(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end # Real
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
|
||||||
|
def list_service_offerings(options={})
|
||||||
|
flavors = self.data[:flavors].values
|
||||||
|
|
||||||
|
{
|
||||||
|
"listserviceofferingsresponse" =>
|
||||||
|
{
|
||||||
|
"count" => flavors.size,
|
||||||
|
"serviceoffering"=> flavors
|
||||||
|
}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end # Mock
|
||||||
end
|
end # Cloudstack
|
||||||
end
|
end # Compute
|
||||||
|
end # Fog
|
||||||
|
|
|
@ -14,7 +14,22 @@ module Fog
|
||||||
request(options)
|
request(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end # Real
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
|
||||||
|
def list_templates(options={})
|
||||||
|
templates = self.data[:images].values
|
||||||
|
|
||||||
|
{
|
||||||
|
"listtemplatesresponse" =>
|
||||||
|
{
|
||||||
|
"count" => templates.size,
|
||||||
|
"template"=> templates
|
||||||
|
}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end # Mock
|
||||||
end
|
end # Cloudstack
|
||||||
end
|
end # Compute
|
||||||
|
end # Fog
|
||||||
|
|
|
@ -13,8 +13,14 @@ module Fog
|
||||||
|
|
||||||
request(options)
|
request(options)
|
||||||
end
|
end
|
||||||
|
end # Real
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def list_virtual_machines(options={})
|
||||||
|
{"listvirtualmachinesresponse" =>
|
||||||
|
{"count" => self.data[:servers].values.size, "virtualmachine" => self.data[:servers].values}}
|
||||||
end
|
end
|
||||||
end
|
end # Mock
|
||||||
end
|
end # Cloudstack
|
||||||
end
|
end # Compute
|
||||||
|
end # Fog
|
||||||
|
|
|
@ -14,7 +14,21 @@ module Fog
|
||||||
request(options)
|
request(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end # Real
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def list_zones(options={})
|
||||||
|
zones = self.data[:zones].values
|
||||||
|
|
||||||
|
{
|
||||||
|
"listzonesresponse"=>
|
||||||
|
{
|
||||||
|
"count" => zones.size,
|
||||||
|
"zone" => zones
|
||||||
|
}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end # Mock
|
||||||
end
|
end # Cloudstack
|
||||||
end
|
end # Compute
|
||||||
|
end # Fog
|
||||||
|
|
|
@ -4,35 +4,35 @@ Shindo.tests('Fog::Compute[:cloudstack] | virtual machine requests', ['cloudstac
|
||||||
'listvirtualmachinesresponse' => {
|
'listvirtualmachinesresponse' => {
|
||||||
'count' => Integer,
|
'count' => Integer,
|
||||||
'virtualmachine' => [
|
'virtualmachine' => [
|
||||||
'id' => Integer,
|
'id' => String,
|
||||||
'name' => String,
|
'name' => String,
|
||||||
'displayname' => String,
|
'displayname' => String,
|
||||||
'account' => String,
|
'account' => String,
|
||||||
'domainid' => Integer,
|
'domainid' => String,
|
||||||
'domain' => String,
|
'domain' => String,
|
||||||
'created' => String,
|
'created' => String,
|
||||||
'state' => String,
|
'state' => String,
|
||||||
'haenable' => Fog::Boolean,
|
'haenable' => Fog::Boolean,
|
||||||
'zoneid' => Integer,
|
'zoneid' => String,
|
||||||
'zonename' => String,
|
'zonename' => String,
|
||||||
'hostid' => Fog::Nullable::String,
|
'hostid' => Fog::Nullable::String,
|
||||||
'hostname' => Fog::Nullable::String,
|
'hostname' => Fog::Nullable::String,
|
||||||
'templateid' => Integer,
|
'templateid' => String,
|
||||||
'templatename' => String,
|
'templatename' => String,
|
||||||
'templatedisplaytext' => String,
|
'templatedisplaytext' => String,
|
||||||
'passwordenabled' => Fog::Boolean,
|
'passwordenabled' => Fog::Boolean,
|
||||||
'serviceofferingid' => Integer,
|
'serviceofferingid' => String,
|
||||||
'serviceofferingname' => String,
|
'serviceofferingname' => String,
|
||||||
'cpunumber' => Integer,
|
'cpunumber' => Integer,
|
||||||
'cpuspeed' => Integer,
|
'cpuspeed' => Integer,
|
||||||
'networkkbsread' => Fog::Nullable::Integer,
|
'networkkbsread' => Fog::Nullable::Integer,
|
||||||
'memory' => Integer,
|
'memory' => Integer,
|
||||||
'cpuused' => Fog::Nullable::String,
|
'cpuused' => Fog::Nullable::String,
|
||||||
'guestosid' => Integer,
|
'guestosid' => String,
|
||||||
'networkkbswrite' => Fog::Nullable::Integer,
|
'networkkbswrite' => Fog::Nullable::Integer,
|
||||||
'rootdeviceid' => Integer,
|
'rootdeviceid' => Integer,
|
||||||
'rootdevicetype' => String,
|
'rootdevicetype' => String,
|
||||||
'hypervisor' => String,
|
'hypervisor' => Fog::Nullable::String,
|
||||||
'group' => Fog::Nullable::String,
|
'group' => Fog::Nullable::String,
|
||||||
'groupid' => Fog::Nullable::Integer,
|
'groupid' => Fog::Nullable::Integer,
|
||||||
'isoname' => Fog::Nullable::String,
|
'isoname' => Fog::Nullable::String,
|
||||||
|
@ -43,8 +43,8 @@ Shindo.tests('Fog::Compute[:cloudstack] | virtual machine requests', ['cloudstac
|
||||||
'description' => Fog::Nullable::String
|
'description' => Fog::Nullable::String
|
||||||
],
|
],
|
||||||
'nic' => [
|
'nic' => [
|
||||||
'id' => Integer,
|
'id' => String,
|
||||||
'networkid' => Integer,
|
'networkid' => String,
|
||||||
'netmask' => String,
|
'netmask' => String,
|
||||||
'gateway' => String,
|
'gateway' => String,
|
||||||
'ipaddress' => String,
|
'ipaddress' => String,
|
||||||
|
|
|
@ -19,6 +19,14 @@ def compute_providers
|
||||||
},
|
},
|
||||||
:mocked => false
|
:mocked => false
|
||||||
},
|
},
|
||||||
|
:openstack => { :mocked => true},
|
||||||
|
:cloudstack => {
|
||||||
|
:provider_attributes => {
|
||||||
|
:cloudstack_host => 'http://host.foo'
|
||||||
|
},
|
||||||
|
:server_attributes => Fog.credentials[:cloudstack],
|
||||||
|
:mocked => true
|
||||||
|
},
|
||||||
:glesys => {
|
:glesys => {
|
||||||
:mocked => false
|
:mocked => false
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
for provider, config in compute_providers
|
for provider, config in compute_providers
|
||||||
|
|
||||||
Shindo.tests("Fog::Compute[:#{provider}] | servers", [provider.to_s]) do
|
Shindo.tests("Fog::Compute[:#{provider}] | servers", [provider.to_s]) do
|
||||||
|
|
|
@ -15,6 +15,7 @@ if Fog.mock?
|
||||||
:bluebox_customer_id => 'bluebox_customer_id',
|
:bluebox_customer_id => 'bluebox_customer_id',
|
||||||
:brightbox_client_id => 'brightbox_client_id',
|
:brightbox_client_id => 'brightbox_client_id',
|
||||||
:brightbox_secret => 'brightbox_secret',
|
:brightbox_secret => 'brightbox_secret',
|
||||||
|
:cloudstack_host => 'http://cloudstack.example.org',
|
||||||
:clodo_api_key => 'clodo_api_key',
|
:clodo_api_key => 'clodo_api_key',
|
||||||
:clodo_username => 'clodo_username',
|
:clodo_username => 'clodo_username',
|
||||||
:dnsimple_email => 'dnsimple_email',
|
:dnsimple_email => 'dnsimple_email',
|
||||||
|
@ -77,5 +78,5 @@ if Fog.mock?
|
||||||
:libvirt_uri => 'qemu:///system',
|
:libvirt_uri => 'qemu:///system',
|
||||||
:libvirt_username => 'root',
|
:libvirt_username => 'root',
|
||||||
:libvirt_password => 'password'
|
:libvirt_password => 'password'
|
||||||
}
|
}.merge(Fog.credentials)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue