You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by mf...@redhat.com on 2011/11/02 15:05:28 UTC

Unified way how we deal with IP addresses

Hi,

This patchset introduce a new model 'InstanceAddress' for storing and
manipulating with all different address types we need to deal across
cloud providers.
Previously we have some sort of 'address' type guessing which fails
in most cases and caused a lot of confusion with VNC ports and so.

Currently we have five types of addresses in instance:

1) :ipv6     - Indicate that address is given in IPv6 format (127.0.0.1)
2) :mac      - Address contain a MAC address of the instance NIC adapter
3) :hostname - Address is reported in 'hostname' format (inst0.example.com)
4) :vnc      - Address points to VNC server. Optionally a port attribute is specified 
5) :unavailable - Address is currently unavailable (case when instance is
                  booting / or no address is available 'yet')

Client code should be already compatible with this XML format:

<public_addresses>
  <address type="vnc" port="3001">10.0.0.1</address>
  <address type="ipv6">1.1.1.1</address>
</public_addresses>

 -- Michal


[PATCH core 2/4] Core: Added InstanceAddress model for storing public/private_addresses

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/deltacloud/models/instance_address.rb |   56 ++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)
 create mode 100644 server/lib/deltacloud/models/instance_address.rb

diff --git a/server/lib/deltacloud/models/instance_address.rb b/server/lib/deltacloud/models/instance_address.rb
new file mode 100644
index 0000000..f94ef25
--- /dev/null
+++ b/server/lib/deltacloud/models/instance_address.rb
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# Model to store the hardware profile applied to an instance together with
+# any instance-specific overrides
+
+class InstanceAddress
+  attr_accessor :address
+  attr_accessor :port
+  attr_accessor :address_type
+
+  def initialize(address, opts={})
+    self.address = address
+    self.port = opts[:port] if opts[:port]
+    self.address_type = opts[:type] || :ipv6
+    self
+  end
+
+  def address_type
+    (address and !address.strip.empty?) ? @address_type : :unavailable
+  end
+
+  def to_s
+    return ['VNC', address, port].join(':') if is_vnc?
+    address
+  end
+
+  def is_mac?
+    address_type == :mac
+  end
+
+  def is_ipv6?
+    address_type == :ipv6
+  end
+
+  def is_hostname?
+    address_type == :hostname
+  end
+
+  def is_vnc?
+    address_type == :vnc
+  end
+
+end
-- 
1.7.4.4


[PATCH core 4/4] Core: Updated views to support InstanceAddress. Get rid of address type guessing and formating

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 .../lib/deltacloud/helpers/application_helper.rb   |   25 --------------------
 server/views/instances/show.html.haml              |    4 +-
 server/views/instances/show.xml.haml               |   11 +++-----
 3 files changed, 6 insertions(+), 34 deletions(-)

diff --git a/server/lib/deltacloud/helpers/application_helper.rb b/server/lib/deltacloud/helpers/application_helper.rb
index 859129a..d44f108 100644
--- a/server/lib/deltacloud/helpers/application_helper.rb
+++ b/server/lib/deltacloud/helpers/application_helper.rb
@@ -248,31 +248,6 @@ module ApplicationHelper
     end
   end
 
-  # FIXME: It would be cleaner if we stored the type of address explicitly in
-  # public_addresses instead of guessing it; especially since now a RHEV-M
-  # vnc address in theory could look like type ipv4.
-  #
-  # Instead of pushing just the address onto public_addresses, we should
-  # just push a pair [type, address], i.e. [:vnc, "172.16.0.1"] or a hash
-  # { :vnc => "172.16.0.1" }
-  #
-  def address_type(address)
-    case address
-      when /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/; :ipv4
-      when /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:[\-\d]+)$/; :vnc
-      when /^(\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2})?$/; :mac
-      else :hostname
-    end
-  end
-
-  def format_address(address, opts={})
-    capture_haml do
-      haml_tag :address, { :type => address_type(address) }.merge(opts) do
-        haml_concat address
-      end
-    end
-  end
-
   def translate_error_code(code)
     case code
       when 400; { :message => "Bad Request" }
diff --git a/server/views/instances/show.html.haml b/server/views/instances/show.html.haml
index 63286e8..6891f1b 100644
--- a/server/views/instances/show.html.haml
+++ b/server/views/instances/show.html.haml
@@ -28,10 +28,10 @@
         default
     %li{ :'data-role' => 'list-divider'} Public addresses
     %li
-      %p{ :'data-role' => 'fieldcontain'}=@instance.public_addresses.map.join(',')
+      %p{ :'data-role' => 'fieldcontain'}=@instance.public_addresses.join(',')
     %li{ :'data-role' => 'list-divider'} Private addresses
     %li
-      %p{ :'data-role' => 'fieldcontain'}=@instance.private_addresses.map.join(',')
+      %p{ :'data-role' => 'fieldcontain'}=@instance.private_addresses.join(',')
     - if @instance.password or @instance.keyname
       %li{ :'data-role' => 'list-divider'} Authentication
     - if @instance.password
diff --git a/server/views/instances/show.xml.haml b/server/views/instances/show.xml.haml
index ab60fb7..5b929f4 100644
--- a/server/views/instances/show.xml.haml
+++ b/server/views/instances/show.xml.haml
@@ -31,15 +31,12 @@
       =@instance.launch_time
   - if @instance.public_addresses
     %public_addresses<
-      - @instance.public_addresses.each do |address|
-        - if address.class.eql?(Hash) and address[:address]!=""
-          =format_address(address[:address], :port => address[:port], :type => address[:type], :mac => address[:mac])
-        - elsif address.class.eql?(String)
-          =format_address(address)
+      - @instance.public_addresses.each do |a|
+        %address{ :type => a.address_type, :port => a.port }=a.address
   - if @instance.private_addresses
     %private_addresses<
-      - @instance.private_addresses.each do |address|
-        =format_address(address)
+      - @instance.private_addresses.each do |a|
+        %address{ :type => a.address_type, :port => a.port }=a.address
   - if @instance.firewalls
     %firewalls<
       - @instance.firewalls.each do |firewall|
-- 
1.7.4.4


[PATCH core 1/4] RHEVM: Various optimization to preserve multiple requests to access single resource

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 .../lib/deltacloud/drivers/rhevm/rhevm_client.rb   |   46 ++++++++++++--------
 .../lib/deltacloud/drivers/rhevm/rhevm_driver.rb   |   40 +++++++++--------
 2 files changed, 49 insertions(+), 37 deletions(-)

diff --git a/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb b/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
index c7b671b..d08d2cc 100644
--- a/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
+++ b/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
@@ -196,16 +196,21 @@ module RHEVM
         :accept => "application/xml"
       }
       headers.merge!(auth_header)
-      if opts[:id]
-        vm = Client::parse_response(RHEVM::client(@api_entrypoint)["/templates/%s" % opts[:id]].get(headers)).root
-        [ RHEVM::Template::new(self, vm)]
-      else
-        Client::parse_response(RHEVM::client(@api_entrypoint)["/templates"].get(headers)).xpath('/templates/template').collect do |vm|
-          RHEVM::Template::new(self, vm)
-        end
+      rhevm_templates = RHEVM::client(@api_entrypoint)["/templates"].get(headers)
+      Client::parse_response(rhevm_templates).xpath('/templates/template').collect do |t|
+        RHEVM::Template::new(self, t)
       end
     end
 
+    def template(template_id)
+      headers = {
+        :accept => "application/xml"
+      }
+      headers.merge!(auth_header)
+      rhevm_template = RHEVM::client(@api_entrypoint)["/templates/%s" % template_id].get(headers)
+      RHEVM::Template::new(self, Client::parse_response(rhevm_template).root)
+    end
+
     def clusters(opts={})
       headers = {
         :accept => "application/xml; detail=datacenters"
@@ -226,16 +231,21 @@ module RHEVM
         :accept => "application/xml"
       }
       headers.merge!(auth_header)
-      if opts[:id]
-        vm = Client::parse_response(RHEVM::client(@api_entrypoint)["/datacenters/%s" % opts[:id]].get(headers)).root
-        [ RHEVM::DataCenter::new(self, vm)]
-      else
-        Client::parse_response(RHEVM::client(@api_entrypoint)["/datacenters"].get(headers)).xpath('/data_centers/data_center').collect do |vm|
-          RHEVM::DataCenter::new(self, vm)
-        end
+      rhevm_datacenters = RHEVM::client(@api_entrypoint)["/datacenters"].get(headers)
+      Client::parse_response(rhevm_datacenters).xpath('/data_centers/data_center').collect do |dc|
+        RHEVM::DataCenter::new(self, dc)
       end
     end
 
+    def datacenter(datacenter_id)
+      headers = {
+        :accept => "application/xml"
+      }
+      headers.merge!(auth_header)
+      rhevm_datacenter = RHEVM::client(@api_entrypoint)["/datacenters/%s" % datacenter_id].get(headers)
+      RHEVM::DataCenter::new(self, Client::parse_response(rhevm_datacenter).root)
+    end
+
     def hosts(opts={})
       headers = {
         :accept => "application/xml"
@@ -347,10 +357,10 @@ module RHEVM
       @macs = (xml/'nics/nic/mac').collect { |mac| mac[:address] }
       @creation_time = (xml/'creation_time').text
       @ip = ((xml/'guest_info/ip').first[:address] rescue nil)
-      unless @ip
-        @vnc = ((xml/'display/address').first.text rescue "127.0.0.1")
-        @vnc += ":#{((xml/'display/port').first.text rescue "5890")}"
-      end
+      @vnc = {
+        :address => ((xml/'display/address').first.text rescue "127.0.0.1"),
+        :port => ((xml/'display/port').first.text rescue "5890")
+      } unless @ip
     end
 
   end
diff --git a/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb b/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
index 7ee953a..dfcc7ad 100644
--- a/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
+++ b/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
@@ -74,14 +74,12 @@ class RHEVMDriver < Deltacloud::BaseDriver
   # Realms
   #
 
-  def realms(credentials, opts=nil)
+  def realms(credentials, opts={})
     client = new_client(credentials)
     realm_arr = []
     safely do
-      clusters = client.clusters
-      clusters.each do |r|
-        d = client.datacenters(:id => r.datacenter.id).first
-        realm_arr << convert_realm(r, d)
+      realm_arr = client.clusters.collect do |r|
+        convert_realm(r, client.datacenter(r.datacenter.id))
       end
     end
     realm_arr = filter_on( realm_arr, :id, opts )
@@ -92,12 +90,10 @@ class RHEVMDriver < Deltacloud::BaseDriver
     client = new_client(credentials)
     img_arr = []
     safely do
-      templates = client.templates
       if (!opts.nil? && opts[:id])
-        templates = templates.select{|t| opts[:id] == t.id}
-      end
-      templates.each do |t|
-        img_arr << convert_image(client, t)
+        img_arr << convert_image(client, client.template(opts[:id]))
+      else
+        img_arr = client.templates.collect { |t| convert_image(client, t) }
       end
     end
     img_arr = filter_on( img_arr, :architecture, opts )
@@ -233,15 +229,21 @@ class RHEVMDriver < Deltacloud::BaseDriver
                                    :hwp_storage => "#{storage_size}"
     )
     public_addresses = []
-    # First check if RHEV-M guest tools are installed and IP address is offered by them
-    public_addresses << inst.ip if inst.ip
-    # Second check if ConfServer broker is running, then ask for an IP there
-    public_addresses << confserver_ip(inst.id) if ENV['CONFIG_SERVER_ADDRESS'] and public_addresses.empty?
-    public_addresses.compact!
-    # If everything fails fallback to report MAC address
-    public_addresses = inst.macs if public_addresses.empty?
-    public_addresses.flatten!
-    public_addresses << inst.vnc if inst.vnc
+    # First try to get IP address from RHEV-M. This require rhev-agent package
+    # installed on guest
+    public_addresses << InstanceAddress.new(inst.ip, :type => :ipv6) if inst.ip
+    # ConfServer will overide the IP address returned by RHEV-M guest agent
+    if ENV['CONFIG_SERVER_ADDRESS']
+      ip = confserver_ip(inst.id)
+      public_addresses = [ InstanceAddress.new(ip, :type => :ipv6) ]
+    end
+    # If IP retrieval failed, fallback to VNC and MAC address
+    if public_addresses.empty?
+      public_addresses = inst.macs.collect { |mac_address| InstanceAddress.new(mac_address, :type => :mac) }
+    end
+    if inst.vnc
+      public_addresses << InstanceAddress.new(inst.vnc[:address], :port => inst.vnc[:port], :type => :vnc)
+    end
     Instance.new(
       :id => inst.id,
       :name => inst.name,
-- 
1.7.4.4


Re: Unified way how we deal with IP addresses

Posted by Michal Fojtik <mf...@redhat.com>.
Hi,

Thanks Marios for reviewing this. 

marios@redhat.com wrote:

> * probably we should update the docs on 'Instances' in the API, to
> explain the 'types' of addresses the client can expect,

Definitely yes. Actually this is an addon to our current API and it should
not break anything. But I fully agree that it would be nice that client
now have a way how to recognize what address it got.

  -- Michal

>
> marios
>
> On 02/11/11 16:05, mfojtik@redhat.com wrote:
>> Hi,
>>
>> This patchset introduce a new model 'InstanceAddress' for storing and
>> manipulating with all different address types we need to deal across
>> cloud providers.
>> Previously we have some sort of 'address' type guessing which fails
>> in most cases and caused a lot of confusion with VNC ports and so.
>>
>> Currently we have five types of addresses in instance:
>>
>> 1) :ipv6     - Indicate that address is given in IPv6 format (127.0.0.1)
>> 2) :mac      - Address contain a MAC address of the instance NIC adapter
>> 3) :hostname - Address is reported in 'hostname' format (inst0.example.com)
>> 4) :vnc      - Address points to VNC server. Optionally a port attribute is specified 
>> 5) :unavailable - Address is currently unavailable (case when instance is
>>                   booting / or no address is available 'yet')
>>
>> Client code should be already compatible with this XML format:
>>
>> <public_addresses>
>>   <address type="vnc" port="3001">10.0.0.1</address>
>>   <address type="ipv6">1.1.1.1</address>
>> </public_addresses>
>>
>>  -- Michal
>>
>

Re: Unified way how we deal with IP addresses

Posted by "marios@redhat.com" <ma...@redhat.com>.
ACK to the series:

* applies clean, I tested against ec2 driver works well

* wondering if we should make ipv4 an explicit 'type' (i.e. currently if
it's not :mac, :hostname etc, its implied type is ipv4)

* InstanceAddress is an 'internal' model - i.e. its not exposed as a top
level collection - which means we don't need to add a new section to the
API docs ... but

* probably we should update the docs on 'Instances' in the API, to
explain the 'types' of addresses the client can expect,

marios

On 02/11/11 16:05, mfojtik@redhat.com wrote:
> Hi,
> 
> This patchset introduce a new model 'InstanceAddress' for storing and
> manipulating with all different address types we need to deal across
> cloud providers.
> Previously we have some sort of 'address' type guessing which fails
> in most cases and caused a lot of confusion with VNC ports and so.
> 
> Currently we have five types of addresses in instance:
> 
> 1) :ipv6     - Indicate that address is given in IPv6 format (127.0.0.1)
> 2) :mac      - Address contain a MAC address of the instance NIC adapter
> 3) :hostname - Address is reported in 'hostname' format (inst0.example.com)
> 4) :vnc      - Address points to VNC server. Optionally a port attribute is specified 
> 5) :unavailable - Address is currently unavailable (case when instance is
>                   booting / or no address is available 'yet')
> 
> Client code should be already compatible with this XML format:
> 
> <public_addresses>
>   <address type="vnc" port="3001">10.0.0.1</address>
>   <address type="ipv6">1.1.1.1</address>
> </public_addresses>
> 
>  -- Michal
> 


[PATCH core 3/4] Core: Updated all drivers to support common way to handle IP addresses using InstanceAddress

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 .../lib/deltacloud/drivers/condor/condor_driver.rb |    3 ++-
 server/lib/deltacloud/drivers/ec2/ec2_driver.rb    |    8 ++++----
 .../lib/deltacloud/drivers/gogrid/gogrid_driver.rb |    2 +-
 .../drivers/mock/data/instances/inst0.yml          |    8 ++++++--
 .../drivers/mock/data/instances/inst1.yml          |    8 ++++++--
 .../drivers/mock/data/instances/inst2.yml          |    8 ++++++--
 server/lib/deltacloud/drivers/mock/mock_driver.rb  |    4 ++--
 .../drivers/opennebula/opennebula_driver.rb        |    2 +-
 .../drivers/rackspace/rackspace_driver.rb          |    8 ++++----
 .../drivers/rimuhosting/rimuhosting_driver.rb      |    2 +-
 server/lib/deltacloud/drivers/sbc/sbc_driver.rb    |    2 +-
 .../drivers/terremark/terremark_driver.rb          |    4 ++--
 .../deltacloud/drivers/vsphere/vsphere_driver.rb   |    9 +++++++--
 server/lib/deltacloud/models.rb                    |    1 +
 14 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/server/lib/deltacloud/drivers/condor/condor_driver.rb b/server/lib/deltacloud/drivers/condor/condor_driver.rb
index ad444d5..f48c9d3 100644
--- a/server/lib/deltacloud/drivers/condor/condor_driver.rb
+++ b/server/lib/deltacloud/drivers/condor/condor_driver.rb
@@ -105,7 +105,8 @@ module Deltacloud
                 :realm_id => 'default',
                 :instance_profile => InstanceProfile::new(instance.instance_profile.name),
                 :image_id => instance.image_id,
-                :public_addresses => [ ip_address ],
+                :public_addresses => [ InstanceAddress.new(ip_address) ],
+                :private_addresses => [],
                 :owner_id => instance.owner_id,
                 :description => instance.name,
                 :architecture => 'x86_64',
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index dd52fa8..12f4fb3 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -134,7 +134,7 @@ module Deltacloud
           opts ||= {}
           if opts[:id]
             safely do
-              img_arr = ec2.describe_images(opts[:id]).collect do |image|
+              img_arr = ec2.describe_images([opts[:id]]).collect do |image|
                 convert_image(image)
               end
             end
@@ -142,7 +142,7 @@ module Deltacloud
           end
           owner_id = opts[:owner_id] || default_image_owner
           safely do
-            img_arr = ec2.describe_images_by_owner(owner_id, default_image_type).collect do |image|
+            img_arr = ec2.describe_images_by_owner([owner_id], default_image_type).collect do |image|
               convert_image(image)
             end
           end
@@ -794,8 +794,8 @@ module Deltacloud
             :launch_time => instance[:aws_launch_time],
             :instance_profile => InstanceProfile.new(instance[:aws_instance_type], inst_profile_opts),
             :realm_id => instance[:aws_availability_zone],
-            :private_addresses => instance[:private_dns_name],
-            :public_addresses => instance[:dns_name],
+            :public_addresses => [InstanceAddress.new(instance[:dns_name], :type => :hostname)],
+            :private_addresses => [InstanceAddress.new(instance[:private_dns_name], :type => :hostname)],
             :firewalls => instance[:aws_groups],
             :create_image => can_create_image
           )
diff --git a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
index 5e20c6a..285f58f 100644
--- a/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
+++ b/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
@@ -471,7 +471,7 @@ class GogridDriver < Deltacloud::BaseDriver
       :realm_id => instance['ip']['datacenter']['id'],
       :state => state,
       :actions => instance_actions_for(state),
-      :public_addresses => [ instance['ip']['ip'] ],
+      :public_addresses => [ InstanceAddress.new(instance['ip']['ip']) ],
       :private_addresses => [],
       :username => instance['username'],
       :password => instance['password'],
diff --git a/server/lib/deltacloud/drivers/mock/data/instances/inst0.yml b/server/lib/deltacloud/drivers/mock/data/instances/inst0.yml
index 447a99c..c6a9b11 100644
--- a/server/lib/deltacloud/drivers/mock/data/instances/inst0.yml
+++ b/server/lib/deltacloud/drivers/mock/data/instances/inst0.yml
@@ -8,9 +8,13 @@
 - :stop
 :owner_id: mockuser
 :public_addresses:
-- img1.inst0.public.com
+- !ruby/object:InstanceAddress
+  address: img1.inst0.public.com
+  address_type: :hostname
 :private_addresses:
-- img1.inst0.private.com
+- !ruby/object:InstanceAddress
+  address: img1.inst0.private.com
+  address_type: :hostname
 :create_image: true
 :image_id: img1
 :name: Mock Instance With Profile Change
diff --git a/server/lib/deltacloud/drivers/mock/data/instances/inst1.yml b/server/lib/deltacloud/drivers/mock/data/instances/inst1.yml
index f0bed5c..7befa88 100644
--- a/server/lib/deltacloud/drivers/mock/data/instances/inst1.yml
+++ b/server/lib/deltacloud/drivers/mock/data/instances/inst1.yml
@@ -4,9 +4,13 @@
 :realm_id: us
 :owner_id: mockuser
 :public_addresses:
-- img3.inst1.public.com
+- !ruby/object:InstanceAddress
+  address: img1.inst1.public.com
+  address_type: :hostname
 :private_addresses:
-- img3.inst1.private.com
+- !ruby/object:InstanceAddress
+  address: img1.inst1.private.com
+  address_type: :hostname
 :create_image: true
 :image_id: img3
 :name: MockUserInstance
diff --git a/server/lib/deltacloud/drivers/mock/data/instances/inst2.yml b/server/lib/deltacloud/drivers/mock/data/instances/inst2.yml
index a6fcd43..2acb937 100644
--- a/server/lib/deltacloud/drivers/mock/data/instances/inst2.yml
+++ b/server/lib/deltacloud/drivers/mock/data/instances/inst2.yml
@@ -4,9 +4,13 @@
 :realm_id: us
 :owner_id: anotheruser
 :public_addresses:
-- img1.inst2.public.com
+- !ruby/object:InstanceAddress
+  address: img1.inst2.public.com
+  address_type: :hostname
 :private_addresses:
-- img1.inst2.private.com
+- !ruby/object:InstanceAddress
+  address: img1.inst2.private.com
+  address_type: :hostname
 :create_image: true
 :image_id: img1
 :name: AnotherInstance
diff --git a/server/lib/deltacloud/drivers/mock/mock_driver.rb b/server/lib/deltacloud/drivers/mock/mock_driver.rb
index 29d18ef..c4eb03a 100644
--- a/server/lib/deltacloud/drivers/mock/mock_driver.rb
+++ b/server/lib/deltacloud/drivers/mock/mock_driver.rb
@@ -195,8 +195,8 @@ module Deltacloud::Drivers::Mock
         :keyname => opts[:keyname],
         :image_id=>image_id,
         :owner_id=>credentials.user,
-        :public_addresses=>["#{image_id}.#{next_id}.public.com"],
-        :private_addresses=>["#{image_id}.#{next_id}.private.com"],
+        :public_addresses=>[ InstanceAddress.new("#{image_id}.#{next_id}.public.com", :type => :hostname) ],
+        :private_addresses=>[ InstanceAddress.new("#{image_id}.#{next_id}.private.com", :type => :hostname) ],
         :instance_profile => InstanceProfile.new(hwp.name, opts),
         :realm_id=>realm_id,
         :create_image=>true,
diff --git a/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb b/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
index 84cf99d..e4f8f4d 100644
--- a/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
+++ b/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
@@ -190,7 +190,7 @@ class OpennebulaDriver < Deltacloud::BaseDriver
 
 	networks = []
 	(computehash['NETWORK'].each do |n|
-		networks << n.attributes['ip']
+		networks << InstanceAddress.new(n.attributes['ip'])
 	end) unless computehash['NETWORK'].nil?
 
 	Instance.new( {
diff --git a/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb b/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
index dd4099d..4a0ec54 100644
--- a/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
+++ b/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
@@ -394,8 +394,8 @@ class RackspaceDriver < Deltacloud::BaseDriver
       :architecture => 'x86_64',
       :image_id => server.imageId.to_s,
       :instance_profile => InstanceProfile::new(server.flavorId.to_s),
-      :public_addresses => server.addresses[:public],
-      :private_addresses => server.addresses[:private],
+      :public_addresses => server.addresses[:public].collect { |ip| InstanceAddress.new(ip) },
+      :private_addresses => server.addresses[:private].collect { |ip| InstanceAddress.new(ip) },
       :username => 'root',
       :password => password ? password : nil
     )
@@ -415,8 +415,8 @@ class RackspaceDriver < Deltacloud::BaseDriver
       :architecture => 'x86_64',
       :image_id => server[:imageId].to_s,
       :instance_profile => InstanceProfile::new(server[:flavorId].to_s),
-      :public_addresses => server[:addresses][:public],
-      :private_addresses => server[:addresses][:private]
+      :public_addresses => server[:addresses][:public].collect { |ip| InstanceAddress.new(ip) },
+      :private_addresses => server[:addresses][:private].collect { |ip| InstanceAddress.new(ip) },
     )
     inst.create_image = 'RUNNING'.eql?(inst.state)
     inst.actions = instance_actions_for(inst.state)
diff --git a/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb b/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
index e39c877..9f786d0 100644
--- a/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
+++ b/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
@@ -131,7 +131,7 @@ class RimuHostingDriver < Deltacloud::BaseDriver
             :owner_id => "root",
             :instance_profile => InstanceProfile.new("none"),
             :actions => instance_actions_for("RUNNING"),
-            :public_addresses => inst["allocated_ips"]["primary_ip"],
+            :public_addresses => [ InstanceAddress.new(inst["allocated_ips"]["primary_ip"] ),
             :launch_time => inst["billing_info"]["order_date"]["iso_format"]
     })
   end
diff --git a/server/lib/deltacloud/drivers/sbc/sbc_driver.rb b/server/lib/deltacloud/drivers/sbc/sbc_driver.rb
index 2e5b39c..90f566d 100644
--- a/server/lib/deltacloud/drivers/sbc/sbc_driver.rb
+++ b/server/lib/deltacloud/drivers/sbc/sbc_driver.rb
@@ -206,7 +206,7 @@ class SBCDriver < Deltacloud::BaseDriver
       :realm_id => instance["location"],
       :state => state,
       :actions => instance_actions_for(state),
-      :public_addresses => [instance["primaryIP"]["ip"]],
+      :public_addresses => [ InstanceAddress.new(instance["primaryIP"]["ip"]) ],
       :private_addresses => [],
       :instance_profile => InstanceProfile.new(instance["instanceType"].gsub('/', '-')),
       :launch_time => instance["launchTime"],
diff --git a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
index ba5209d..c93bfb3 100644
--- a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
+++ b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
@@ -262,8 +262,8 @@ end
                     :realm_id => "US-Miami",
                     :state => current_state,
                     :actions => instance_actions_for(current_state),
-                    :public_addresses => vapp_public_ip,
-                    :private_addresses => vapp_private_ip,
+                    :public_addresses => [ InstanceAddress.new(vapp_public_ip) ],
+                    :private_addresses => [ InstanceAddress.new(vapp_private_ip) ],
                     :instance_profile => profile
                     } )
   end
diff --git a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
index a31c1f1..22f4196 100644
--- a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
+++ b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
@@ -174,7 +174,12 @@ module Deltacloud::Drivers::VSphere
           # We're getting IP address from 'vmware guest tools'.
           # If guest tools are not installed, we return list of MAC addresses
           # assigned to this instance.
-          instance_address = vm.guest[:net].empty? ? vm.macs.values.first : vm.guest[:net].first[:ipAddress].first
+          public_addresses = []
+          if vm.guest[:net].empty?
+            public_addresses = vm.macs.values.collect { |mac_address| InstanceAddress.new(mac_address, :type => :mac) }
+          else
+            public_addresses = InstanceAddress.new(vm.guest[:net].first[:ipAddress].first)
+          end
           Instance.new(
             :id => properties[:name],
             :name => properties[:name],
@@ -183,7 +188,7 @@ module Deltacloud::Drivers::VSphere
             :description => properties[:full_name],
             :realm_id => realm_id,
             :state => instance_state,
-            :public_addresses => instance_address,
+            :public_addresses => public_addresses,
             :private_addresses => [],
             :instance_profile => instance_profile,
             :actions => instance_actions_for( instance_state ),
diff --git a/server/lib/deltacloud/models.rb b/server/lib/deltacloud/models.rb
index 8317232..e8cd035 100644
--- a/server/lib/deltacloud/models.rb
+++ b/server/lib/deltacloud/models.rb
@@ -20,6 +20,7 @@ require 'deltacloud/models/image'
 require 'deltacloud/models/instance'
 require 'deltacloud/models/key'
 require 'deltacloud/models/address'
+require 'deltacloud/models/instance_address'
 require 'deltacloud/models/instance_profile'
 require 'deltacloud/models/storage_snapshot'
 require 'deltacloud/models/storage_volume'
-- 
1.7.4.4