mirror of
				https://github.com/fog/fog.git
				synced 2022-11-09 13:51:43 -05:00 
			
		
		
		
	[cloudstack|compute] Public IP Address model improvement
This commit is contained in:
		
							parent
							
								
									9e5007fb06
								
							
						
					
					
						commit
						2924bf0226
					
				
					 10 changed files with 213 additions and 49 deletions
				
			
		| 
						 | 
				
			
			@ -2,51 +2,94 @@ module Fog
 | 
			
		|||
  module Compute
 | 
			
		||||
    class Cloudstack
 | 
			
		||||
      class PublicIpAddress < Fog::Model
 | 
			
		||||
        identity  :id,                    :aliases => '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
 | 
			
		||||
        identity  :id
 | 
			
		||||
 | 
			
		||||
       def save
 | 
			
		||||
          requires :display_text, :name
 | 
			
		||||
        attribute :account
 | 
			
		||||
        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 = {
 | 
			
		||||
            'displaytext' => display_text,
 | 
			
		||||
            'name'        => name,
 | 
			
		||||
            'customized'  => is_customized,
 | 
			
		||||
            'disksize'    => disk_size,
 | 
			
		||||
            'domain_id'   => domain_id,
 | 
			
		||||
            'storagetype' => storage_type,
 | 
			
		||||
            'tags'        => tags
 | 
			
		||||
          }
 | 
			
		||||
        def initialize(attributes = {})
 | 
			
		||||
          # assign server first to prevent race condition with persisted?
 | 
			
		||||
          self.server = attributes.delete(:server)
 | 
			
		||||
          super
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
          response = service.associate_ip_address(options)
 | 
			
		||||
          merge_attributes(response['associateipaddressresponse'])
 | 
			
		||||
        def ready?
 | 
			
		||||
          state == 'Allocated'
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def destroy
 | 
			
		||||
          requires :id
 | 
			
		||||
 | 
			
		||||
          response = service.disassociate_ip_address('id' => id )
 | 
			
		||||
          success_status = response['disassociateipaddressresponse']['success']
 | 
			
		||||
 | 
			
		||||
          success_status == 'true'
 | 
			
		||||
          requires :identity
 | 
			
		||||
          service.disassociate_ip_address('id' => id)
 | 
			
		||||
          true
 | 
			
		||||
        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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
require 'fog/core/collection'
 | 
			
		||||
require 'fog/cloudstack/models/compute/address'
 | 
			
		||||
require 'fog/cloudstack/models/compute/public_ip_address'
 | 
			
		||||
 | 
			
		||||
module Fog
 | 
			
		||||
  module Compute
 | 
			
		||||
| 
						 | 
				
			
			@ -14,10 +14,12 @@ module Fog
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def get(address_id)
 | 
			
		||||
          options = { 'id' => address_id }
 | 
			
		||||
          response = service.list_public_ip_addresses(options)
 | 
			
		||||
          public_ip_addresses = response["listpublicipaddressesresponse"]["publicipaddress"].first
 | 
			
		||||
          new(public_ip_addresses)
 | 
			
		||||
          response = service.list_public_ip_addresses('id' => address_id)
 | 
			
		||||
          if public_ip_address = response["listpublicipaddressesresponse"]["publicipaddress"].first
 | 
			
		||||
            new(public_ip_address)
 | 
			
		||||
          end
 | 
			
		||||
        rescue Fog::Compute::Cloudstack::BadRequest
 | 
			
		||||
          nil
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,8 +22,9 @@ module Fog
 | 
			
		|||
 | 
			
		||||
      class Mock
 | 
			
		||||
        def associate_ip_address(*args)
 | 
			
		||||
          public_ip_address_id = Fog::Cloudstack.uuid
 | 
			
		||||
          public_ip_address = {
 | 
			
		||||
            "id"                => "f2f2f2f2-f2f2-f2f2-f2f2-f2f2f2f2f2",
 | 
			
		||||
            "id"                => public_ip_address_id,
 | 
			
		||||
            "ipaddress"         => "192.168.200.3",
 | 
			
		||||
            "allocated"         => "2014-12-22T22:32:39+0000",
 | 
			
		||||
            "zoneid"            => "0e276270-7950-4483-bf21-3dc897dbe08a",
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +49,6 @@ module Fog
 | 
			
		|||
          {'associateipaddressresponse' => public_ip_address}
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,32 @@ module Fog
 | 
			
		|||
        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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ module Fog
 | 
			
		|||
 | 
			
		||||
      class Mock
 | 
			
		||||
        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]
 | 
			
		||||
            self.data[:public_ip_addresses].delete(public_ip_address_id)
 | 
			
		||||
            { "disassociateipaddressresponse" => { "success" => "true" }}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,49 @@ module Fog
 | 
			
		|||
        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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,12 +23,22 @@ module Fog
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
      class Mock
 | 
			
		||||
        def list_public_ip_addresses(*arg)
 | 
			
		||||
          public_ip_addresses = self.data[:public_ip_addresses]
 | 
			
		||||
          { "listpublicipaddressesresponse" => { "count"=> public_ip_addresses.count, "publicipaddress"=> public_ip_addresses.values } }
 | 
			
		||||
        def list_public_ip_addresses(*args)
 | 
			
		||||
          public_ip_address_id = args[0].is_a?(Hash) ? args[0]['id'] : nil
 | 
			
		||||
          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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										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' },
 | 
			
		||||
      :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
 | 
			
		||||
    },
 | 
			
		||||
    :glesys   => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue