From: marios <[email protected]>

Current operations are list (index), create and delete a firewall rule. Also 
these patches contain only the html haml (not yet xml - want to decide if this 
is the model before doing this).
---
 server/deltacloud.rb                               |    1 +
 server/lib/deltacloud/base_driver/base_driver.rb   |   16 +++
 .../drivers/terremark/terremark_driver.rb          |  100 +++++++++++++++++++-
 server/lib/deltacloud/models/firewall_rule.rb      |    9 ++
 server/server.rb                                   |   88 ++++++++++++++++--
 server/views/firewall_rules/index.html.haml        |   37 +++++++
 server/views/firewall_rules/new.html.haml          |   22 +++++
 server/views/firewall_rules/show.html.haml         |   21 ++++
 8 files changed, 285 insertions(+), 9 deletions(-)
 create mode 100644 server/lib/deltacloud/models/firewall_rule.rb
 create mode 100644 server/views/firewall_rules/index.html.haml
 create mode 100644 server/views/firewall_rules/new.html.haml
 create mode 100644 server/views/firewall_rules/show.html.haml

diff --git a/server/deltacloud.rb b/server/deltacloud.rb
index 1c19a5d..561fdfb 100644
--- a/server/deltacloud.rb
+++ b/server/deltacloud.rb
@@ -12,3 +12,4 @@ require 'deltacloud/models/instance'
 require 'deltacloud/models/instance_profile'
 require 'deltacloud/models/storage_snapshot'
 require 'deltacloud/models/storage_volume'
+require 'deltacloud/models/firewall_rule'
diff --git a/server/lib/deltacloud/base_driver/base_driver.rb 
b/server/lib/deltacloud/base_driver/base_driver.rb
index a2b3bbe..b334db1 100644
--- a/server/lib/deltacloud/base_driver/base_driver.rb
+++ b/server/lib/deltacloud/base_driver/base_driver.rb
@@ -154,6 +154,22 @@ module Deltacloud
     def reboot_instance(credentials, id)
     end
 
+    def firewall_rules(credentials, opts)
+      []
+    end
+
+    def firewall_rule(credentials, opts)
+      rules = firewall_rules(credentials, opts)
+      return rules.first unless rules.empty?
+      nil
+    end
+
+    def create_firewall_rule(credentials, opts)
+    end
+    def delete_firewall_rule(credentials, opts)
+    end
+
+
     def storage_volume(credentials, opts)
       volumes = storage_volumes(credentials, opts)
       return volumes.first unless volumes.empty?
diff --git a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb 
b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
index ae3c554..d464052 100644
--- a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
+++ b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
@@ -32,7 +32,7 @@ module Deltacloud
 
 class TerremarkDriver < Deltacloud::BaseDriver
 
-  feature :instances, :user_name
+#  feature :instances, :user_name
 
 #--
 # Vapp State Map... for use with convert_instance (get an integer back from 
terremark)
@@ -50,6 +50,89 @@ VAPP_STATE_MAP = { "0" =>  "PENDING", "1" =>  "PENDING", "2" 
=>  "STOPPED", "4"
   #storage_disks [1..15]
 
 #--
+# FIREWALL RULES
+#--
+  def firewall_rules(credentials, opts=nil)
+    firewall_rules = []
+    terremark_client = new_client(credentials)
+    services = 
terremark_client.get_internet_services(terremark_client.default_vdc_id).body['InternetServices'].each
 do |service|
+    s_id = service['Id'].to_s
+    public_ip = service['PublicIpAddress']['Name']
+    public_port = service['Port']
+    protocol = service['Protocol']
+    nodes = terremark_client.get_node_services(s_id).body['NodeServices']
+    unless nodes.empty?
+      nodes.each do |node|
+        #puts "Id is #{node['Id']}, public_ip is #{public_ip}, public_port is 
#{public_port}, Private IP is #{node['IpAddress']}, private port is 
#{node['Port']} and protocol is #{protocol}"
+        firewall_rules << FirewallRule.new({     :id => s_id,
+                                                 :public_address => public_ip,
+                                                 :public_port => public_port,
+                                                 :private_address => 
node['IpAddress'],
+                                                 :private_port => node['Port'],
+                                                 :protocol => protocol
+                                                })
+      end #nodes.each do
+    end #unless nodes empty
+   end #services.each do
+   firewall_rules = filter_on( firewall_rules, :id, opts )
+   firewall_rules
+ end
+
+#--
+# DELETE FIREWALL RULE
+#--can expect that the service ID is passed in the opts...
+ def delete_firewall_rule(credentials, opts=nil)
+   service_id = opts[:id].to_s
+   terremark_client = new_client(credentials)
+   nodes = terremark_client.get_node_services(service_id).body['NodeServices']
+   unless nodes.empty?
+     nodes.each do |node|
+       terremark_client.delete_node_service(node['Id'])
+     end
+   end
+   terremark_client.delete_internet_service(service_id)
+ end
+
+#--
+# CREATE NEW FIREWALL RULE
+#--expected input: private and public ip address, private and public ports, 
protocol
+#--opts['public_address']
+#--pts['service_protocol']
+#--opts['public_port']
+#--opts['private_port']
+#--opts['private_address']
+#--opts['service_name'] - OPTIONAL
+#--opts['node_name'] - OPTIONAL
+  def create_firewall_rule(credentials, opts=nil)
+    terremark_client = new_client(credentials)
+    public_address = opts['public_address']
+    public_port = opts['public_port']
+    protocol = opts['service_protocol']
+    #check if internet service exists or creating a new one
+    service_id = internet_service_exists(terremark_client, public_address, 
public_port, protocol)
+    unless service_id
+      ip_id = nil
+      #need to deduce the ip id to create a new internet service
+      ips = 
terremark_client.get_public_ips(terremark_client.default_vdc_id).body['PublicIpAddresses']
+      ips.each do |ip|
+        if (ip['name'] == public_address)
+          ip_id = ip['id'].to_s
+          break
+        end
+      end #end ips.each
+      service_name ||= opts['service_name']
+      service_name ||= "svc" + (rand(1000)*Time.now.to_i).to_s.slice(0,7)
+      service_id = terremark_client.add_internet_service(ip_id, service_name, 
protocol, public_port).body['Id'].to_s
+    end
+    #it adds the node service to the internet service... 
+    node_name ||= opts['node_name']
+    node_name ||= "nod" + (rand(1000)*Time.now.to_i).to_s.slice(0,7)
+    private_address = opts['private_address']
+    private_port = opts['private_port']
+    terremark_client.add_node_service(service_id, private_address, node_name, 
private_port)
+  end
+
+#--
 # IMAGES
 #--
 #aka "vapp_templates"
@@ -183,6 +266,21 @@ end
  private
 
 #--
+# INTERNET_SERVICE_EXISTS
+#-- helper to check if a given public IP/Port combination are defined as an 
existing internet service
+#-- used by the create_firewall_rule method
+def internet_service_exists(terremark_client, public_address, public_port, 
protocol)
+    services = 
terremark_client.get_internet_services(terremark_client.default_vdc_id)
+    services.body['InternetServices'].each do |current_service|
+      if ( (current_service['PublicIpAddress']['Name'] == public_address) && 
(current_service['Port'].to_s == public_port) &&
+            (current_service['Protocol'].upcase == protocol.upcase) )
+            return current_service['Id']
+      end
+    end
+    nil
+end
+
+#--
 # CONVERT IMAGE
 #--
 #gets a vapp_template from a catalog and makes it a Image
diff --git a/server/lib/deltacloud/models/firewall_rule.rb 
b/server/lib/deltacloud/models/firewall_rule.rb
new file mode 100644
index 0000000..390ede3
--- /dev/null
+++ b/server/lib/deltacloud/models/firewall_rule.rb
@@ -0,0 +1,9 @@
+class FirewallRule < BaseModel
+
+  attr_accessor :public_address
+  attr_accessor :public_port
+  attr_accessor :private_address
+  attr_accessor :private_port
+  attr_accessor :protocol
+
+end
\ No newline at end of file
diff --git a/server/server.rb b/server/server.rb
index b5bdfac..cb15bdf 100644
--- a/server/server.rb
+++ b/server/server.rb
@@ -65,6 +65,8 @@ def show(model)
 end
 
 
+
+
 #
 # Error handlers
 #
@@ -108,7 +110,60 @@ get '/api\/?' do
     end
 end
 
+get '/api/firewall_rules/:id/destroy' do
+  method = "delete_firewall_rule"
+  not_found unless driver.respond_to?(method)
+  opts = {}
+  opts[:id] = params[:id]
+  driver.send(method, credentials, opts)
+  redirect firewall_rules_url
+end
+
+get '/api/firewall_rules/new' do
+  respond_to do |format|
+    format.html { haml :"firewall_rules/new" }
+  end
+end
+
+
+def delete_firewall_rule(service_id)
+  driver.send(delete_firewall_rule, credentials, {:id => params[:id]})
+end
+
 # Rabbit DSL
+collection :firewall_rules do
+
+  description "Allow user to expose a public IP address/port and map these 
onto an internal IP address/port. eg expose ssh access [port 22, tcp]."
+  operation :index do
+    description 'Show all available network services'
+    control { filter_all(:firewall_rules) }
+  end
+
+  operation :show do
+    description 'Show a firewall rule identified by its id'
+    param :id,            :string, :required
+    control { show(:firewall_rule) }
+  end
+  
+  operation :create do
+    description 'Create a new firewall rule'
+    param :public_address,  :string, :required
+    param :public_port,     :string, :required
+    param :private_address, :string, :required
+    param :private_port,    :string, :required
+    param :service_protocol, :string, :required
+    control do
+      driver.create_firewall_rule(credentials, params )
+      filter_all(:firewall_rules)
+    end
+  end
+    
+  operation :destroy, :method => :post do
+    description 'destroy given firewall rule'
+    param :id,            :string, :required
+    control { delete_firewall_rule(:id) }
+  end
+end
 
 collection :realms do
   description "Within a cloud provider a realm represents a boundary 
containing resources. The exact definition of a realm is left to the cloud 
provider. In some cases, a realm may represent different datacenters, different 
continents, or different pools of resources within a single datacenter. A cloud 
provider may insist that resources must all exist within a single realm in 
order to cooperate. For instance, storage volumes may only be allowed to be 
mounted to instances within the same realm."
@@ -186,6 +241,22 @@ collection :instance_states do
   end
 end
 
+# Special instance get operations that we only allow for HTML
+get "/api/instances/:id/:action" do
+   meth = :"#{params[:action]}_instance"
+   not_found unless driver.respond_to?(meth)
+   respond_to do |format|
+     format.html do
+       driver.send(meth, credentials, params[:id])
+       if ( (params[:action] == 'destroy') or (params[:action] == 'stop') )
+         redirect instances_url
+       else
+         redirect instance_url(params[:id])
+       end
+     end
+   end
+end
+
 get "/api/instances/new" do
   @instance = Instance.new( { :id=>params[:id], :image_id=>params[:image_id] } 
)
   @image   = driver.image( credentials, :id => params[:image_id] )
@@ -197,14 +268,15 @@ get "/api/instances/new" do
 end
 
 def instance_action(name)
-  @instance = driver.send(:"#{name}_instance", credentials, params["id"])
-
-  return redirect(instances_url) if name.eql?(:destroy) or 
@instance.class!=Instance
-
-  respond_to do |format|
-    format.html { haml :"instances/show" }
-    format.xml { haml :"instances/show" }
-    format.json {convert_to_json(:instance, @instance) }
+  @instance = driver.send(:"#{name}_instance", credentials, params[:id])
+  if name==:destroy
+    redirect instances_url
+  else
+    respond_to do |format|
+      format.html { haml :"instances/show" }
+      format.xml { haml :"instances/show" }
+      format.json {convert_to_json(:instance, @instance) }
+    end
   end
 end
 
diff --git a/server/views/firewall_rules/index.html.haml 
b/server/views/firewall_rules/index.html.haml
new file mode 100644
index 0000000..47990b0
--- /dev/null
+++ b/server/views/firewall_rules/index.html.haml
@@ -0,0 +1,37 @@
+%h1
+  Firewall Rules
+%h3 
+  = link_to("Create new firewall rule", firewall_rules_url() + "/new")
+%table.display
+  %thead
+    %tr
+      %th
+        ID
+      %th
+        Public Address
+      %th
+        Public Port
+      %th
+        Private Address
+      %th
+        Private Port
+      %th
+        Protocol
+  %tbody
+  - if @firewall_rules
+    -  for rule in @firewall_rules
+      %tr
+        %td
+          = link_to rule.id, firewall_rules_url()+"/#{rule.id}"
+        %td
+          = rule.public_address
+        %td
+          = rule.public_port
+        %td
+          = rule.private_address
+        %td
+          = rule.private_port
+        %td
+          = rule.protocol
+        %td
+          = link_to("destroy", firewall_rules_url()+"/#{rule.id}/destroy", 
{:method => :post})
\ No newline at end of file
diff --git a/server/views/firewall_rules/new.html.haml 
b/server/views/firewall_rules/new.html.haml
new file mode 100644
index 0000000..9c6f0a0
--- /dev/null
+++ b/server/views/firewall_rules/new.html.haml
@@ -0,0 +1,22 @@
+%h1 New Firewall Rule
+
+%form{ :action => firewall_rules_url, :method => :post }
+  %p
+    %label
+      Public  Address:
+      %input{ :name => 'public_address', :size => 16 }
+    %label
+      Public Port:
+      %input{ :name => 'public_port', :size => 6}
+    %label 
+      Protocol:
+      %input{ :name => 'service_protocol', :size => 5}
+  %p 
+    %label
+      Private Address:
+      %input{ :name => 'private_address', :size => 16 } 
+    %label
+      Private Port:
+      %input{ :name => 'private_port', :size => 6}
+  %p
+  %input{ :type => :submit, :name => 'commit', :value => "create" }
\ No newline at end of file
diff --git a/server/views/firewall_rules/show.html.haml 
b/server/views/firewall_rules/show.html.haml
new file mode 100644
index 0000000..8ec81c2
--- /dev/null
+++ b/server/views/firewall_rules/show.html.haml
@@ -0,0 +1,21 @@
+%h1 Firewall Rule
+%h2
+  = @firewall_rule.id
+
+%dl
+  %di
+    %dt Public IP
+    %dd
+      = @firewall_rule.public_address
+    %dt Public Port
+    %dd
+      = @firewall_rule.public_port
+    %dt Private IP
+    %dd
+      = @firewall_rule.private_address
+    %dt Private Port
+    %dd
+      = @firewall_rule.private_port
+    %dt Protocol
+    %dd
+      = @firewall_rule.protocol
\ No newline at end of file
-- 
1.6.6.1

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to