mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
[Vcloud] Instantiate Vapps & get firewall acls
-Also a small refactor of some of the vdc model's collections
This commit is contained in:
parent
11fb548059
commit
07a23dbbe5
13 changed files with 318 additions and 24 deletions
|
@ -73,6 +73,12 @@ module Fog
|
|||
end
|
||||
end
|
||||
|
||||
def xmlns
|
||||
{ "xmlns" => "http://www.vmware.com/vcloud/v0.8",
|
||||
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
||||
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
|
||||
end
|
||||
|
||||
def reload
|
||||
@connections.each_value { |k,v| v.reset if v }
|
||||
end
|
||||
|
@ -343,12 +349,6 @@ module Fog
|
|||
@login_uri = get_login_uri
|
||||
end
|
||||
|
||||
def xmlns
|
||||
{ "xmlns" => "http://www.vmware.com/vcloud/v0.8",
|
||||
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
||||
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
|
||||
end
|
||||
|
||||
def mock_it(status, mock_data, mock_headers = {})
|
||||
response = Excon::Response.new
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ module Fog
|
|||
model_path 'fog/vcloud/terremark/ecloud/models'
|
||||
model :catalog_item
|
||||
model :catalog
|
||||
model :firewall_acl
|
||||
model :firewall_acls
|
||||
model :internet_service
|
||||
model :internet_services
|
||||
model :ip
|
||||
|
@ -27,6 +29,7 @@ module Fog
|
|||
request_path 'fog/vcloud/terremark/ecloud/requests'
|
||||
request :add_internet_service
|
||||
request :add_node
|
||||
request :clone_vapp
|
||||
request :configure_internet_service
|
||||
request :configure_network
|
||||
request :configure_network_ip
|
||||
|
@ -38,6 +41,8 @@ module Fog
|
|||
request :get_catalog
|
||||
request :get_catalog_item
|
||||
request :get_customization_options
|
||||
request :get_firewall_acls
|
||||
request :get_firewall_acl
|
||||
request :get_internet_services
|
||||
request :get_network
|
||||
request :get_network_ip
|
||||
|
@ -50,7 +55,9 @@ module Fog
|
|||
request :get_task
|
||||
request :get_task_list
|
||||
request :get_vapp
|
||||
request :get_vapp_template
|
||||
request :get_vdc
|
||||
request :instantiate_vapp_template
|
||||
request :power_off
|
||||
request :power_on
|
||||
request :power_reset
|
||||
|
|
28
lib/fog/vcloud/terremark/ecloud/models/firewall_acl.rb
Normal file
28
lib/fog/vcloud/terremark/ecloud/models/firewall_acl.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
module Fog
|
||||
module Vcloud
|
||||
module Terremark
|
||||
module Ecloud
|
||||
class FirewallAcl < Fog::Vcloud::Model
|
||||
|
||||
identity :href, :Href
|
||||
|
||||
ignore_attributes :xmlns, :xmlns_i
|
||||
|
||||
attribute :name, :aliases => :Name
|
||||
attribute :id, :aliases => :Id
|
||||
attribute :protocol, :aliases => :Protocol
|
||||
attribute :source, :aliases => :Source
|
||||
attribute :destination, :aliases => :Destination
|
||||
attribute :permission, :aliases => :Permission
|
||||
attribute :port_start, :aliases => :PortStart
|
||||
attribute :port_end, :aliases => :PortEnd
|
||||
attribute :port_type, :aliases => :PortType
|
||||
attribute :type, :aliases => :Type
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
31
lib/fog/vcloud/terremark/ecloud/models/firewall_acls.rb
Normal file
31
lib/fog/vcloud/terremark/ecloud/models/firewall_acls.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
module Fog
|
||||
module Vcloud
|
||||
module Terremark
|
||||
module Ecloud
|
||||
|
||||
class FirewallAcls < Fog::Vcloud::Collection
|
||||
|
||||
model Fog::Vcloud::Terremark::Ecloud::FirewallAcl
|
||||
|
||||
attribute :href, :aliases => :Href
|
||||
|
||||
def all
|
||||
if data = connection.get_firewall_acls(href).body[:FirewallAcl]
|
||||
data = [ data ] if data.is_a?(Hash)
|
||||
load(data)
|
||||
end
|
||||
end
|
||||
|
||||
def get(uri)
|
||||
if data = connection.get_firewall_acl(uri).body
|
||||
new(data)
|
||||
end
|
||||
rescue Fog::Errors::NotFound
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,7 +21,7 @@ module Fog
|
|||
end
|
||||
end
|
||||
|
||||
# Optimize later, no need to get_internet_services again
|
||||
# Optimize later, no need to get_internet_services again?
|
||||
def get(uri)
|
||||
internet_services = connection.get_internet_services(href).body[:InternetService]
|
||||
internet_services = [ internet_services ] if internet_services.is_a?(Hash)
|
||||
|
|
|
@ -91,7 +91,7 @@ module Fog
|
|||
|
||||
def memory
|
||||
{ :amount => memory_mess[:VirtualQuantity].to_i,
|
||||
:units => memory_mess[:VirtualQuantityUnits] }
|
||||
:units => memory_mess[:AllocationUnits] }
|
||||
end
|
||||
|
||||
def memory=(amount)
|
||||
|
@ -132,17 +132,14 @@ module Fog
|
|||
end
|
||||
|
||||
def reload
|
||||
super
|
||||
reset_tracking
|
||||
super
|
||||
end
|
||||
|
||||
def save
|
||||
if new_record?
|
||||
requires :name
|
||||
puts "NOOP"
|
||||
return false
|
||||
#result = connection.instantiate_vapp_template( stuff )
|
||||
#merge_attributes(result.body)
|
||||
#Lame ...
|
||||
raise RuntimeError, "Should not be here"
|
||||
else
|
||||
if on?
|
||||
if @changed
|
||||
|
@ -159,7 +156,6 @@ module Fog
|
|||
def reset_tracking
|
||||
@disk_change = false
|
||||
@changed = false
|
||||
true
|
||||
end
|
||||
|
||||
def _compose_vapp_data
|
||||
|
|
|
@ -5,6 +5,8 @@ module Fog
|
|||
|
||||
class Servers < Fog::Vcloud::Collection
|
||||
|
||||
undef_method :create
|
||||
|
||||
model Fog::Vcloud::Terremark::Ecloud::Server
|
||||
|
||||
attribute :href, :aliases => :Href
|
||||
|
@ -21,6 +23,15 @@ module Fog
|
|||
nil
|
||||
end
|
||||
|
||||
def create( catalog_item_uri, options )
|
||||
options[:vdc_uri] = href
|
||||
options[:cpus] ||= 1
|
||||
options[:memory] ||= 512
|
||||
data = connection.instantiate_vapp_template( catalog_item_uri, options ).body
|
||||
object = new(data)
|
||||
object
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _resource_entities
|
||||
|
|
|
@ -20,15 +20,11 @@ module Fog
|
|||
attribute :instantiated_vm_quota
|
||||
|
||||
def public_ips
|
||||
load_unless_loaded!
|
||||
@public_ips ||= Fog::Vcloud::Terremark::Ecloud::PublicIps.new( :connection => connection,
|
||||
:href => other_links.detect { |link| link[:type] == "application/vnd.tmrk.ecloud.publicIpsList+xml" }[:href] )
|
||||
@public_ips ||= collection_based_on_type("application/vnd.tmrk.ecloud.publicIpsList+xml")
|
||||
end
|
||||
|
||||
def internet_services
|
||||
@internet_services ||= Fog::Vcloud::Terremark::Ecloud::InternetServices.
|
||||
new( :connection => connection,
|
||||
:href => href.to_s.gsub('vdc','extensions/vdc') + "/internetServices" )
|
||||
@internet_services ||= collection_based_on_type("application/vnd.tmrk.ecloud.internetServicesList+xml")
|
||||
end
|
||||
|
||||
def networks
|
||||
|
@ -50,11 +46,32 @@ module Fog
|
|||
end
|
||||
|
||||
def catalog
|
||||
@catalog ||= Fog::Vcloud::Terremark::Ecloud::Catalog.
|
||||
new( :connection => connection,
|
||||
:href => href + "/catalog" )
|
||||
@catalog ||= collection_based_on_type("application/vnd.vmware.vcloud.catalog+xml")
|
||||
end
|
||||
|
||||
def firewall_acls
|
||||
@firewall_acls ||= collection_based_on_type("application/vnd.tmrk.ecloud.firewallAclsList+xml")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def collection_based_on_type(type)
|
||||
load_unless_loaded!
|
||||
if link = other_links.detect { |link| link[:type] == type }
|
||||
case type
|
||||
when "application/vnd.tmrk.ecloud.publicIpsList+xml"
|
||||
Fog::Vcloud::Terremark::Ecloud::PublicIps
|
||||
when "application/vnd.tmrk.ecloud.internetServicesList+xml"
|
||||
Fog::Vcloud::Terremark::Ecloud::InternetServices
|
||||
when "application/vnd.vmware.vcloud.catalog+xml"
|
||||
Fog::Vcloud::Terremark::Ecloud::Catalog
|
||||
when "application/vnd.tmrk.ecloud.firewallAclsList+xml"
|
||||
Fog::Vcloud::Terremark::Ecloud::FirewallAcls
|
||||
end.new( :connection => connection, :href => link[:href] )
|
||||
else
|
||||
[ ]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
50
lib/fog/vcloud/terremark/ecloud/requests/clone_vapp.rb
Normal file
50
lib/fog/vcloud/terremark/ecloud/requests/clone_vapp.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
module Fog
|
||||
module Vcloud
|
||||
module Terremark
|
||||
module Ecloud
|
||||
|
||||
module Real
|
||||
|
||||
def validate_clone_vapp_options(options)
|
||||
valid_opts = [:name, :poweron]
|
||||
unless valid_opts.all? { |opt| options.keys.include?(opt) }
|
||||
raise ArgumentError.new("Required data missing: #{(valid_opts - options.keys).map(&:inspect).join(", ")}")
|
||||
end
|
||||
end
|
||||
|
||||
def generate_clone_vapp_request(uri, options)
|
||||
xml = Builder::XmlMarkup.new
|
||||
xml.CloneVAppParams(xmlns.merge!(:name => options[:name], :deploy => "true", :powerOn => options[:poweron])) {
|
||||
xml.VApp( :href => uri, :type => "application/vnd.vmware.vcloud.vApp+xml",
|
||||
:xmlns => "http://www.vmware.com/vcloud/v0.8")
|
||||
}
|
||||
end
|
||||
|
||||
def clone_vapp(vdc_uri, vapp_uri, options = {})
|
||||
unless options.has_key?(:poweron)
|
||||
options[:poweron] = "false"
|
||||
end
|
||||
|
||||
validate_clone_vapp_options(options)
|
||||
|
||||
request(
|
||||
:body => generate_clone_vapp_request(vapp_uri, options),
|
||||
:expects => 202,
|
||||
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.cloneVAppParams+xml'},
|
||||
:method => 'POST',
|
||||
:uri => vdc_uri + '/action/clonevapp',
|
||||
:parse => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
module Mock
|
||||
def clone_vapp(vdc_uri, vapp_uri, customization_data)
|
||||
validate_customization_data(customization_data)
|
||||
Fog::Mock.not_implemented
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
lib/fog/vcloud/terremark/ecloud/requests/get_firewall_acl.rb
Normal file
18
lib/fog/vcloud/terremark/ecloud/requests/get_firewall_acl.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
module Fog
|
||||
module Vcloud
|
||||
module Terremark
|
||||
module Ecloud
|
||||
|
||||
module Real
|
||||
basic_request :get_firewall_acl
|
||||
end
|
||||
|
||||
module Mock
|
||||
def get_firewall_acl(firewall_acl_uri)
|
||||
Fog::Mock.not_implemented
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
module Fog
|
||||
module Vcloud
|
||||
module Terremark
|
||||
module Ecloud
|
||||
|
||||
module Real
|
||||
basic_request :get_firewall_acls
|
||||
end
|
||||
|
||||
module Mock
|
||||
def get_firewall_acls(firewall_acls_uri)
|
||||
Fog::Mock.not_implemented
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
module Fog
|
||||
module Vcloud
|
||||
module Terremark
|
||||
module Ecloud
|
||||
|
||||
module Real
|
||||
basic_request :get_vapp_template
|
||||
end
|
||||
|
||||
module Mock
|
||||
def get_vapp_template(templace_uri)
|
||||
Fog::Mock.not_implemented
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,100 @@
|
|||
module Fog
|
||||
module Vcloud
|
||||
module Terremark
|
||||
module Ecloud
|
||||
|
||||
module Real
|
||||
|
||||
def validate_instantiate_vapp_template_options(catalog_item_uri, options)
|
||||
valid_opts = [:name, :vdc_uri, :network_uri, :cpus, :memory, :row, :group]
|
||||
unless valid_opts.all? { |opt| options.keys.include?(opt) }
|
||||
raise ArgumentError.new("Required data missing: #{(valid_opts - options.keys).map(&:inspect).join(", ")}")
|
||||
end
|
||||
|
||||
# Figure out the template_uri
|
||||
catalog_item = get_catalog_item( catalog_item_uri ).body
|
||||
catalog_item[:Entity] = [ catalog_item[:Entity] ] if catalog_item[:Entity].is_a?(Hash)
|
||||
catalog_item[:Link] = [ catalog_item[:Link] ] if catalog_item[:Link].is_a?(Hash)
|
||||
|
||||
options[:template_uri] = begin
|
||||
catalog_item[:Entity].detect { |entity| entity[:type] == "application/vnd.vmware.vcloud.vAppTemplate+xml" }[:href]
|
||||
rescue
|
||||
raise RuntimeError.new("Unable to locate template uri for #{catalog_item_uri}")
|
||||
end
|
||||
|
||||
customization_options = begin
|
||||
customization_href = catalog_item[:Link].detect { |link| link[:type] == "application/vnd.tmrk.ecloud.catalogItemCustomizationParameters+xml" }[:href]
|
||||
get_customization_options( customization_href ).body
|
||||
rescue
|
||||
raise RuntimeError.new("Unable to get customization options for #{catalog_item_uri}")
|
||||
end
|
||||
|
||||
# Check to see if we can set the password
|
||||
if options[:password] and customization_options[:CustomizePassword] == "false"
|
||||
raise ArgumentError.new("This catalog item (#{catalog_item_uri}) does not allow setting a password.")
|
||||
end
|
||||
|
||||
# According to the docs if CustomizePassword is "true" then we NEED to set a password
|
||||
if customization_options[:CustomizePassword] == "true" and ( options[:password].nil? or options[:password].empty? )
|
||||
raise ArgumentError.new("This catalog item (#{catalog_item_uri}) requires a :password to instantiate.")
|
||||
end
|
||||
end
|
||||
|
||||
def generate_instantiate_vapp_template_request(options)
|
||||
xml = Builder::XmlMarkup.new
|
||||
xml.InstantiateVAppTemplateParams(xmlns.merge!(:name => options[:name], :"xml:lang" => "en")) {
|
||||
xml.VAppTemplate(:href => options[:template_uri])
|
||||
xml.InstantiationParams {
|
||||
xml.ProductSection( :"xmlns:q1" => "http://www.vmware.com/vcloud/v0.8", :"xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1") {
|
||||
if options[:password]
|
||||
xml.Property( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1", :"ovf:key" => "password", :"ovf:value" => options[:password] )
|
||||
end
|
||||
xml.Property( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1", :"ovf:key" => "row", :"ovf:value" => options[:row] )
|
||||
xml.Property( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1", :"ovf:key" => "group", :"ovf:value" => options[:group] )
|
||||
}
|
||||
xml.VirtualHardwareSection( :"xmlns:q1" => "http://www.vmware.com/vcloud/v0.8" ) {
|
||||
# # of CPUS
|
||||
xml.Item( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1" ) {
|
||||
xml.InstanceID(1, :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
|
||||
xml.ResourceType(3, :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
|
||||
xml.VirtualQuantity(options[:cpus], :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
|
||||
}
|
||||
# Memory
|
||||
xml.Item( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1" ) {
|
||||
xml.InstanceID(2, :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
|
||||
xml.ResourceType(4, :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
|
||||
xml.VirtualQuantity(options[:memory], :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
|
||||
}
|
||||
}
|
||||
xml.NetworkConfigSection {
|
||||
xml.NetworkConfig {
|
||||
xml.NetworkAssociation( :href => options[:network_uri] )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def instantiate_vapp_template(catalog_item_uri, options = {})
|
||||
validate_instantiate_vapp_template_options(catalog_item_uri, options)
|
||||
|
||||
request(
|
||||
:body => generate_instantiate_vapp_template_request(options),
|
||||
:expects => 200,
|
||||
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'},
|
||||
:method => 'POST',
|
||||
:uri => options[:vdc_uri] + '/action/instantiatevAppTemplate',
|
||||
:parse => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
module Mock
|
||||
def instantiate_vapp_template(vdc_uri)
|
||||
Fog::Mock.not_implemented
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue