You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by ma...@apache.org on 2013/04/26 17:47:00 UTC

[03/14] git commit: Network API rev 3 - OpenStack Driver implementation

Network API rev 3 - OpenStack Driver implementation


Project: http://git-wip-us.apache.org/repos/asf/deltacloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltacloud/commit/3163f817
Tree: http://git-wip-us.apache.org/repos/asf/deltacloud/tree/3163f817
Diff: http://git-wip-us.apache.org/repos/asf/deltacloud/diff/3163f817

Branch: refs/heads/master
Commit: 3163f817efd26bb51e3e9d4c96163d6832dcfdc3
Parents: a7ad95f
Author: marios <ma...@redhat.com>
Authored: Fri Apr 12 12:22:19 2013 +0300
Committer: marios <ma...@redhat.com>
Committed: Fri Apr 26 18:01:55 2013 +0300

----------------------------------------------------------------------
 .../drivers/openstack/openstack_driver.rb          |  192 ++++++++++++++-
 1 files changed, 184 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltacloud/blob/3163f817/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
----------------------------------------------------------------------
diff --git a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
index 343934d..bfa4cb6 100644
--- a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
+++ b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
@@ -162,19 +162,24 @@ module Deltacloud
 
         def instances(credentials, opts={})
           os = new_client(credentials)
-          insts = attachments = []
+          insts = attachments = nics = []
           safely do
+            if have_quantum?(credentials)
+              nics = network_interfaces(credentials)
+            end
             if opts[:id]
               begin
                 server = os.get_server(opts[:id])
-                insts << convert_from_server(server, os.connection.authuser, get_attachments(opts[:id], os))
+                inst_nics = nics.inject([]){|res, cur| res << cur.id if cur.instance == opts[:id]  ;res}
+                insts << convert_from_server(server, os.connection.authuser, get_attachments(opts[:id], os), inst_nics)
               rescue => e
                 raise e unless e.message =~ /The resource could not be found/
                 insts = []
               end
             else
               insts = os.list_servers_detail.collect do |s|
-                convert_from_server(s, os.connection.authuser,get_attachments(s[:id], os))
+                inst_nics = nics.inject([]){|res, cur| res << cur.id if cur.instance == s[:id]  ;res}
+                convert_from_server(s, os.connection.authuser,get_attachments(s[:id], os), inst_nics)
               end
             end
           end
@@ -182,6 +187,15 @@ module Deltacloud
           insts
         end
 
+        def have_quantum?(credentials)
+          begin
+            quantum = new_client(credentials, "network")
+          rescue => e
+            return nil
+          end
+          quantum
+        end
+
         def create_instance(credentials, image_id, opts)
           os = new_client( credentials, "compute")
           result = nil
@@ -473,6 +487,124 @@ module Deltacloud
           end
         end
 
+        def networks(credentials, opts={})
+          os = new_client(credentials, "network")
+          networks = []
+          safely do
+            subnets = os.subnets
+            if opts[:id]
+              begin
+                net = os.network(opts[:id])
+                addr_blocks = get_address_blocks_for(net.id, subnets)
+                networks << convert_network(net, addr_blocks)
+              rescue => e
+                raise e unless e.message =~ /Network not found/
+                networks = []
+              end
+            else
+              os.networks.each do |net|
+                addr_blocks = get_address_blocks_for(net.id, subnets)
+                networks << convert_network(net, addr_blocks)
+              end
+            end
+          end
+          networks = filter_on(networks, :id, opts)
+        end
+
+        #require params for openstack: {:name}
+        def create_network(credentials, opts={})
+          os = new_client(credentials, "network")
+          safely do
+            net = os.create_network(opts[:name] || "net_#{Time.now.to_i}")
+            convert_network(net)
+          end
+        end
+
+        def destroy_network(credentials, id)
+          os = new_client(credentials, "network")
+          safely do
+            os.delete_network(id)
+          end
+        end
+
+        def subnets(credentials, opts={})
+          os = new_client(credentials, "network")
+          subnets = []
+          safely do
+            if opts[:id]
+              begin
+                snet = os.subnet opts[:id]
+                subnets << convert_subnet(snet)
+              rescue => e
+                raise e unless e.message =~ /Subnet not found/
+                subnets = []
+              end
+            else
+              os.subnets.each do |subnet|
+                subnets << convert_subnet(subnet)
+              end
+            end
+          end
+          subnets = filter_on(subnets, :id, opts)
+        end
+
+        #required params:  :network_id, cidr_block
+        #optional params:  :ip_version, :gateway_ip, :allocation_pools
+        def create_subnet(credentials, opts={})
+          os = new_client(credentials, "network")
+          safely do
+            convert_subnet(os.create_subnet(opts[:network_id], opts[:address_block]))
+          end
+        end
+
+        def destroy_subnet(credentials, subnet_id)
+          os = new_client(credentials, "network")
+          safely do
+            os.delete_subnet(subnet_id)
+          end
+        end
+
+        def network_interfaces(credentials, opts={})
+          os = new_client(credentials, "network")
+          nics = []
+          safely do
+            if opts[:id]
+              begin
+                nic = os.port(opts[:id])
+                nics << convert_nic(nic)
+              rescue => e
+                raise e unless e.message =~ /Port not found/
+                nics = []
+              end
+            else
+              os.ports.each do |port|
+                nics << convert_nic(port)
+              end
+            end
+          end
+          nics = filter_on(nics, :id, opts)
+        end
+
+        def create_network_interface(credentials, opts={})
+          quantum = new_client(credentials, "network")
+          safely do
+            #first discover the network for the supplied subnet
+            #i.e. opts[:network] is actually a subnet
+            snet = quantum.subnet(opts[:network])
+            network = snet.network_id
+            name = opts[:name] || "nic_#{Time.now.to_i}"
+            port = quantum.create_port(network, {"fixed_ips"=>[{"subnet_id"=>opts[:network]}], "device_id"=>opts[:instance], "name"=>name})
+            convert_nic(port)
+          end
+        end
+
+        def destroy_network_interface(credentials, nic_id)
+          os = new_client(credentials, "network")
+          safely do
+            os.delete_port(nic_id)
+          end
+        end
+
 private
         #for v2 authentication credentials.name == "username+tenant_name"
         def new_client(credentials, type="compute", ignore_provider=false)
@@ -495,7 +627,7 @@ private
           connection_params.merge!({:region => region}) if region && !ignore_provider # hack needed for 'def providers'
           safely do
             raise ValidationFailure.new(Exception.new("Error: tried to initialise Openstack connection using" +
-                    " an unknown service_type: #{type}")) unless ["volume", "compute", "object-store"].include? type
+                    " an unknown service_type: #{type}")) unless ["volume", "compute", "object-store", "network"].include? type
             OpenStack::Connection.create(connection_params)
            end
         end
@@ -529,16 +661,16 @@ private
                     })
         end
 
-        def convert_from_server(server, owner, attachments=[])
+        def convert_from_server(server, owner, attachments=[], nics=[])
           op = (server.class == Hash)? :fetch : :send
           image = server.send(op, :image)
           flavor = server.send(op, :flavor)
-          begin
+         begin
             password = server.send(op, :adminPass) || ""
             rescue IndexError
               password = ""
           end
-          inst = Instance.new(
+          inst_params = {
             :id => server.send(op, :id).to_s,
             :realm_id => "default",
             :owner_id => owner,
@@ -555,7 +687,11 @@ private
             :keyname => server.send(op, :key_name),
             :launch_time => server.send(op, :created),
             :storage_volumes => attachments.inject([]){|res, cur| res << {cur[:volumeId] => cur[:device]} ;res}
-          )
+          }
+          unless nics.empty?
+            inst_params.merge!(:network_interfaces=>nics)
+          end
+          inst = Instance.new(inst_params)
           inst.actions = instance_actions_for(inst.state)
           inst.create_image = 'RUNNING'.eql?(inst.state)
           inst
@@ -656,6 +792,46 @@ private
           )
         end
 
+        def get_address_blocks_for(network_id, subnets)
+          return [] if subnets.empty?
+          addr_blocks = []
+          subnets.each do |sn|
+            if sn.network_id == network_id
+              addr_blocks << sn.cidr
+            end
+          end
+          addr_blocks
+        end
+
+        def convert_network(net, addr_blocks)
+          Network.new({ :id => net.id,
+                        :name => net.name,
+                        :subnets => net.subnets,
+                        :state => (net.admin_state_up ? "UP" : "DOWN"),
+                        :address_blocks => addr_blocks
+          })
+        end
+
+        def convert_subnet(subnet)
+          Subnet.new({  :id => subnet.id,
+                        :name => subnet.name,
+                        :network => subnet.network_id,
+                        :address_block => subnet.cidr,
+                        :state => "UP"
+          })
+        end
+
+        def convert_nic(port)
+          NetworkInterface.new({  :id => port.id,
+                      :name => port.name,
+                      :instance => port.device_id,
+                      :network => port.fixed_ips.first["subnet_id"], #subnet, not network for OS
+                      :state => (port.admin_state_up ? "UP" : "DOWN" ), # true/false
+                      :ip_address =>port.fixed_ips.first["ip_address"]
+                      # this is a structure; [{"subnet_id": ID, "ip_address": addr}] - COULD BE >1 address here...
+          })
+        end
+
         #IN: path1='server_path1'. content1='contents1', path2='server_path2', content2='contents2' etc
         #OUT:{local_path=>server_path, local_path1=>server_path2 etc}
         def extract_personality(opts)