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