mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Merge pull request #3553 from atsaki/cloudstack_publicip_model
[cloudstack|compute] Public IP Address model improvement
This commit is contained in:
commit
77197e8291
10 changed files with 213 additions and 49 deletions
|
@ -2,51 +2,94 @@ module Fog
|
||||||
module Compute
|
module Compute
|
||||||
class Cloudstack
|
class Cloudstack
|
||||||
class PublicIpAddress < Fog::Model
|
class PublicIpAddress < Fog::Model
|
||||||
identity :id, :aliases => 'id'
|
identity :id
|
||||||
attribute :network_id, :aliases => 'networkid'
|
|
||||||
attribute :associated_network_id, :aliases => 'associatednetworkid'
|
|
||||||
attribute :physical_network_id, :aliases => 'physicalnetworkid'
|
|
||||||
attribute :ip_address, :aliases => 'ipaddress'
|
|
||||||
attribute :mac_address, :aliases => 'macaddress'
|
|
||||||
attribute :state, :aliases => 'state'
|
|
||||||
attribute :traffic_type, :aliases => 'traffictype'
|
|
||||||
attribute :is_default, :aliases => 'isdefault', :type => :boolean
|
|
||||||
attribute :is_source_nat, :aliases => 'issourcenat', :type => :boolean
|
|
||||||
attribute :is_static_nat, :aliases => 'isstaticnat', :type => :boolean
|
|
||||||
attribute :is_system, :aliases => 'issytem', :type => :boolean
|
|
||||||
attribute :is_portable, :aliases => 'isportable', :type => :boolean
|
|
||||||
attribute :allocated, :aliases => 'allocated', :type => :time
|
|
||||||
attribute :zone_id, :aliases => 'zone_id'
|
|
||||||
attribute :domain_id, :aliases => 'domain_id'
|
|
||||||
attribute :tags, :type => :array
|
|
||||||
attribute :type
|
|
||||||
|
|
||||||
def save
|
attribute :account
|
||||||
requires :display_text, :name
|
attribute :allocated, :type => :time
|
||||||
|
attribute :associated_network_id, :aliases => 'associatednetworkid'
|
||||||
|
attribute :associated_network_name, :aliases => 'associatednetworkname'
|
||||||
|
attribute :domain
|
||||||
|
attribute :domain_id, :aliases => 'domainid'
|
||||||
|
attribute :for_virtual_network, :type => :boolean, :aliases => 'forvirtualnetwork'
|
||||||
|
attribute :ip_address, :aliases => 'ipaddress'
|
||||||
|
attribute :is_portable, :type => :boolean, :aliases => 'isportable'
|
||||||
|
attribute :is_source_nat, :type => :boolean, :aliases => 'issourcenat'
|
||||||
|
attribute :is_static_nat, :type => :boolean, :aliases => 'isstaticnat'
|
||||||
|
attribute :is_system, :type => :boolean, :aliases => 'issystem'
|
||||||
|
attribute :network_id, :type => :boolean, :aliases => 'networkid'
|
||||||
|
attribute :physical_network_id, :aliases => 'physicalnetworkid'
|
||||||
|
attribute :project
|
||||||
|
attribute :project_id, :aliases => 'projectid'
|
||||||
|
attribute :purpose
|
||||||
|
attribute :state
|
||||||
|
attribute :server_display_name, :aliases => 'virtualmachinedisplayname'
|
||||||
|
attribute :server_id, :aliases => 'virtualmachineid'
|
||||||
|
attribute :server_name, :aliases => 'virtualmachinename'
|
||||||
|
attribute :vlan_id, :aliases => 'vlanid'
|
||||||
|
attribute :vlan_name, :aliases => 'vlanname'
|
||||||
|
attribute :server_ip_address, :aliases => 'vmipaddress'
|
||||||
|
attribute :vpc_id, :aliases => 'vpcid'
|
||||||
|
attribute :zone_id, :aliases => 'zoneid'
|
||||||
|
attribute :zone_name, :aliases => 'zonename'
|
||||||
|
attribute :tags, :type => :array
|
||||||
|
attribute :job_id, :aliases => 'jobid' # only on associate
|
||||||
|
|
||||||
options = {
|
def initialize(attributes = {})
|
||||||
'displaytext' => display_text,
|
# assign server first to prevent race condition with persisted?
|
||||||
'name' => name,
|
self.server = attributes.delete(:server)
|
||||||
'customized' => is_customized,
|
super
|
||||||
'disksize' => disk_size,
|
end
|
||||||
'domain_id' => domain_id,
|
|
||||||
'storagetype' => storage_type,
|
|
||||||
'tags' => tags
|
|
||||||
}
|
|
||||||
|
|
||||||
response = service.associate_ip_address(options)
|
def ready?
|
||||||
merge_attributes(response['associateipaddressresponse'])
|
state == 'Allocated'
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
requires :id
|
requires :identity
|
||||||
|
service.disassociate_ip_address('id' => id)
|
||||||
response = service.disassociate_ip_address('id' => id )
|
true
|
||||||
success_status = response['disassociateipaddressresponse']['success']
|
|
||||||
|
|
||||||
success_status == 'true'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def server=(new_server)
|
||||||
|
@server = new_server
|
||||||
|
if persisted?
|
||||||
|
if !server_id.nil? && (new_server.nil? || server_id != new_server.id)
|
||||||
|
service.disable_static_nat('ipaddressid' => id)
|
||||||
|
self.server_display_name = nil
|
||||||
|
self.server_id = nil
|
||||||
|
self.server_name = nil
|
||||||
|
self.server_ip_address = nil
|
||||||
|
self.is_static_nat = false
|
||||||
|
end
|
||||||
|
unless new_server.nil?
|
||||||
|
service.enable_static_nat(
|
||||||
|
'ipaddressid' => id, 'virtualmachineid' => new_server.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def server
|
||||||
|
service.servers.get(server_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def save
|
||||||
|
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
|
||||||
|
options = {
|
||||||
|
'account' => account,
|
||||||
|
'domainid' => domain_id,
|
||||||
|
'isportable' => is_portable,
|
||||||
|
'networkid' => network_id,
|
||||||
|
'projectid' => project_id,
|
||||||
|
'vpcid' => vpc_id,
|
||||||
|
'zoneid' => zone_id,
|
||||||
|
}
|
||||||
|
response = service.associate_ip_address(options)
|
||||||
|
merge_attributes(response['associateipaddressresponse'])
|
||||||
|
if @server
|
||||||
|
self.server = @server
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'fog/core/collection'
|
require 'fog/core/collection'
|
||||||
require 'fog/cloudstack/models/compute/address'
|
require 'fog/cloudstack/models/compute/public_ip_address'
|
||||||
|
|
||||||
module Fog
|
module Fog
|
||||||
module Compute
|
module Compute
|
||||||
|
@ -14,10 +14,12 @@ module Fog
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(address_id)
|
def get(address_id)
|
||||||
options = { 'id' => address_id }
|
response = service.list_public_ip_addresses('id' => address_id)
|
||||||
response = service.list_public_ip_addresses(options)
|
if public_ip_address = response["listpublicipaddressesresponse"]["publicipaddress"].first
|
||||||
public_ip_addresses = response["listpublicipaddressesresponse"]["publicipaddress"].first
|
new(public_ip_address)
|
||||||
new(public_ip_addresses)
|
end
|
||||||
|
rescue Fog::Compute::Cloudstack::BadRequest
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,8 +22,9 @@ module Fog
|
||||||
|
|
||||||
class Mock
|
class Mock
|
||||||
def associate_ip_address(*args)
|
def associate_ip_address(*args)
|
||||||
|
public_ip_address_id = Fog::Cloudstack.uuid
|
||||||
public_ip_address = {
|
public_ip_address = {
|
||||||
"id" => "f2f2f2f2-f2f2-f2f2-f2f2-f2f2f2f2f2",
|
"id" => public_ip_address_id,
|
||||||
"ipaddress" => "192.168.200.3",
|
"ipaddress" => "192.168.200.3",
|
||||||
"allocated" => "2014-12-22T22:32:39+0000",
|
"allocated" => "2014-12-22T22:32:39+0000",
|
||||||
"zoneid" => "0e276270-7950-4483-bf21-3dc897dbe08a",
|
"zoneid" => "0e276270-7950-4483-bf21-3dc897dbe08a",
|
||||||
|
@ -48,7 +49,6 @@ module Fog
|
||||||
{'associateipaddressresponse' => public_ip_address}
|
{'associateipaddressresponse' => public_ip_address}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,6 +19,32 @@ module Fog
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def disable_static_nat(*args)
|
||||||
|
ip_address_id = args[0].is_a?(Hash) ? args[0]['ipaddressid'] : args[0]
|
||||||
|
|
||||||
|
address = self.data[:public_ip_addresses][ip_address_id]
|
||||||
|
|
||||||
|
unless address
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new(
|
||||||
|
"Unable to execute API command disablestaticnat due to invalid value. \
|
||||||
|
Invalid parameter ipaddressid value=#{ip_address_id} due to incorrect long value format, \
|
||||||
|
or entity does not exist or due to incorrect parameter annotation for the field in api cmd class.")
|
||||||
|
end
|
||||||
|
|
||||||
|
if address['virtualmachineid'].nil?
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new(
|
||||||
|
"Specified IP address id is not associated with any vm Id")
|
||||||
|
end
|
||||||
|
|
||||||
|
address.merge!(
|
||||||
|
'virtualmachineid' => nil,
|
||||||
|
'virtualmachinname' => nil,
|
||||||
|
'virtualmachinedisplayname' => nil
|
||||||
|
)
|
||||||
|
{'enablestaticnatresponse' => {'success' => 'true'}}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@ module Fog
|
||||||
|
|
||||||
class Mock
|
class Mock
|
||||||
def disassociate_ip_address(*args)
|
def disassociate_ip_address(*args)
|
||||||
public_ip_address_id = options['id']
|
public_ip_address_id = args[0].is_a?(Hash) ? args[0]['id'] : args[0]
|
||||||
if self.data[:public_ip_addresses][public_ip_address_id]
|
if self.data[:public_ip_addresses][public_ip_address_id]
|
||||||
self.data[:public_ip_addresses].delete(public_ip_address_id)
|
self.data[:public_ip_addresses].delete(public_ip_address_id)
|
||||||
{ "disassociateipaddressresponse" => { "success" => "true" }}
|
{ "disassociateipaddressresponse" => { "success" => "true" }}
|
||||||
|
|
|
@ -20,6 +20,49 @@ module Fog
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def enable_static_nat(*args)
|
||||||
|
ip_address_id = nil
|
||||||
|
virtual_machine_id = nil
|
||||||
|
if args[0].is_a? Hash
|
||||||
|
ip_address_id = args[0]['ipaddressid']
|
||||||
|
virtual_machine_id = args[0]['virtualmachineid']
|
||||||
|
else
|
||||||
|
ip_address_id = args[0]
|
||||||
|
virtual_machine_id = args[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
server = self.data[:servers][virtual_machine_id]
|
||||||
|
address = self.data[:public_ip_addresses][ip_address_id]
|
||||||
|
|
||||||
|
unless server
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new(
|
||||||
|
"Unable to execute API command enablestaticnat due to invalid value. \
|
||||||
|
Invalid parameter virtualmachineid value=#{virtual_machine_id} due to incorrect long value format, \
|
||||||
|
or entity does not exist or due to incorrect parameter annotation for the field in api cmd class.")
|
||||||
|
end
|
||||||
|
|
||||||
|
unless address
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new(
|
||||||
|
"Unable to execute API command enablestaticnat due to invalid value. \
|
||||||
|
Invalid parameter ipaddressid value=#{ip_address_id} due to incorrect long value format, \
|
||||||
|
or entity does not exist or due to incorrect parameter annotation for the field in api cmd class.")
|
||||||
|
end
|
||||||
|
|
||||||
|
unless address['virtualmachineid'].nil?
|
||||||
|
raise Fog::Compute::Cloudstack::BadRequest.new(
|
||||||
|
"Failed to enable static nat for the ip address id=#{ip_address_id} \
|
||||||
|
as vm id=#{virtual_machine_id} is already associated with ip id=#{ip_address_id}")
|
||||||
|
end
|
||||||
|
|
||||||
|
address.merge!(
|
||||||
|
'virtualmachineid' => server['id'],
|
||||||
|
'virtualmachinname' => server['name'],
|
||||||
|
'virtualmachinedisplayname' => server['displayname']
|
||||||
|
)
|
||||||
|
{'enablestaticnatresponse' => {'success' => 'true'}}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,12 +23,22 @@ module Fog
|
||||||
end
|
end
|
||||||
|
|
||||||
class Mock
|
class Mock
|
||||||
def list_public_ip_addresses(*arg)
|
def list_public_ip_addresses(*args)
|
||||||
public_ip_addresses = self.data[:public_ip_addresses]
|
public_ip_address_id = args[0].is_a?(Hash) ? args[0]['id'] : nil
|
||||||
{ "listpublicipaddressesresponse" => { "count"=> public_ip_addresses.count, "publicipaddress"=> public_ip_addresses.values } }
|
if public_ip_address_id
|
||||||
|
public_ip_addresses = [self.data[:public_ip_addresses][public_ip_address_id]]
|
||||||
|
else
|
||||||
|
public_ip_addresses = self.data[:public_ip_addresses].values
|
||||||
|
end
|
||||||
|
|
||||||
|
{
|
||||||
|
'listpublicipaddressesresponse' => {
|
||||||
|
'count' => public_ip_addresses.size,
|
||||||
|
'publicipaddress' => public_ip_addresses
|
||||||
|
}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
27
tests/cloudstack/compute/models/public_ip_address_tests.rb
Normal file
27
tests/cloudstack/compute/models/public_ip_address_tests.rb
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Shindo.tests("Fog::Compute[:cloudstack] | public_ip_address", "cloudstack") do
|
||||||
|
config = compute_providers[:cloudstack]
|
||||||
|
compute = Fog::Compute[:cloudstack]
|
||||||
|
|
||||||
|
model_tests(compute.public_ip_addresses, config[:public_ip_address_attributes], config[:mocked]) do
|
||||||
|
@server = Fog::Compute[:cloudstack].servers.create(config[:server_attributes])
|
||||||
|
@server.wait_for { ready? }
|
||||||
|
|
||||||
|
tests('#server=').succeeds do
|
||||||
|
@instance.server = @server
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#server') do
|
||||||
|
test(' == @server') do
|
||||||
|
@instance.reload
|
||||||
|
@instance.server_id == @server.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test('#server = nil') do
|
||||||
|
@instance.server = nil
|
||||||
|
@instance.server_id.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
@server.destroy
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
Shindo.tests("Fog::Compute[:cloudstack] | public_ip_addresses", ['cloudstack']) do
|
||||||
|
|
||||||
|
collection_tests(Fog::Compute[:cloudstack].public_ip_addresses, {}, true)
|
||||||
|
|
||||||
|
end
|
|
@ -56,6 +56,14 @@ def compute_providers
|
||||||
},
|
},
|
||||||
:disk_offering_attributes => { :name => "new disk offering", :display_text => 'New Disk Offering' },
|
:disk_offering_attributes => { :name => "new disk offering", :display_text => 'New Disk Offering' },
|
||||||
:egress_firewall_rule_attributes => { :protocol => "tcp", :network_id => "8aacae29-e0a4-4b7b-8a7a-3ee11cfb4362", :cidr_list =>"10.1.1.0/24"},
|
:egress_firewall_rule_attributes => { :protocol => "tcp", :network_id => "8aacae29-e0a4-4b7b-8a7a-3ee11cfb4362", :cidr_list =>"10.1.1.0/24"},
|
||||||
|
:public_ip_address_attributes => {}.tap do |hash|
|
||||||
|
[:zone_id].each do |k|
|
||||||
|
key = "cloudstack_#{k}".to_sym
|
||||||
|
if Fog.credentials[key]
|
||||||
|
hash[k]= Fog.credentials[key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
:mocked => true
|
:mocked => true
|
||||||
},
|
},
|
||||||
:glesys => {
|
:glesys => {
|
||||||
|
|
Loading…
Reference in a new issue