Return-Path: X-Original-To: apmail-incubator-deltacloud-dev-archive@minotaur.apache.org Delivered-To: apmail-incubator-deltacloud-dev-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 86E944085 for ; Wed, 15 Jun 2011 13:23:08 +0000 (UTC) Received: (qmail 57044 invoked by uid 500); 15 Jun 2011 13:23:08 -0000 Delivered-To: apmail-incubator-deltacloud-dev-archive@incubator.apache.org Received: (qmail 57019 invoked by uid 500); 15 Jun 2011 13:23:08 -0000 Mailing-List: contact deltacloud-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: deltacloud-dev@incubator.apache.org Delivered-To: mailing list deltacloud-dev@incubator.apache.org Received: (qmail 57011 invoked by uid 99); 15 Jun 2011 13:23:08 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 15 Jun 2011 13:23:08 +0000 X-ASF-Spam-Status: No, hits=-5.0 required=5.0 tests=RCVD_IN_DNSWL_HI,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of mfojtik@redhat.com designates 209.132.183.28 as permitted sender) Received: from [209.132.183.28] (HELO mx1.redhat.com) (209.132.183.28) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 15 Jun 2011 13:23:04 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5FDMh6q024976 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 15 Jun 2011 09:22:43 -0400 Received: from dhcp-2-126.brq.redhat.com (dhcp-2-126.brq.redhat.com [10.34.2.126]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p5FDMeF6028216 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Wed, 15 Jun 2011 09:22:41 -0400 Subject: Re: [PATCH 1/3] Implements 'firewalls' - ec2 security groups Mime-Version: 1.0 (Apple Message framework v1084) Content-Type: text/plain; charset=us-ascii From: Michal Fojtik In-Reply-To: <1307717036-23761-2-git-send-email-marios@redhat.com> Date: Wed, 15 Jun 2011 15:23:19 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: <547AB5DA-1555-4D89-97FE-23C496397571@redhat.com> References: <1307717036-23761-1-git-send-email-marios@redhat.com> <1307717036-23761-2-git-send-email-marios@redhat.com> To: deltacloud-dev@incubator.apache.org X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 On Jun 10, 2011, at 4:43 PM, marios@redhat.com wrote: ACK. A few minor indentation/whitespace doubts inline. -- Michal > From: marios >=20 >=20 > Signed-off-by: marios > --- > server/Gemfile | 3 +- > server/deltacloud.rb | 2 + > server/lib/deltacloud/base_driver/base_driver.rb | 14 ++- > server/lib/deltacloud/base_driver/features.rb | 8 +- > server/lib/deltacloud/drivers/ec2/ec2_driver.rb | 149 = +++++++++++++++++++++- > server/lib/deltacloud/models/bucket.rb | 2 +- > server/lib/deltacloud/models/firewall.rb | 22 +++ > server/lib/deltacloud/models/firewall_rule.rb | 23 ++++ > server/public/javascripts/application.js | 63 +++++++-- > server/server.rb | 112 = ++++++++++++++++ > server/views/firewalls/index.html.haml | 25 ++++ > server/views/firewalls/index.xml.haml | 23 ++++ > server/views/firewalls/new.html.haml | 11 ++ > server/views/firewalls/new_rule.html.haml | 26 ++++ > server/views/firewalls/show.html.haml | 44 +++++++ > server/views/firewalls/show.xml.haml | 21 +++ > 16 files changed, 522 insertions(+), 26 deletions(-) > create mode 100644 server/lib/deltacloud/models/firewall.rb > create mode 100644 server/lib/deltacloud/models/firewall_rule.rb > create mode 100644 server/views/firewalls/index.html.haml > create mode 100644 server/views/firewalls/index.xml.haml > create mode 100644 server/views/firewalls/new.html.haml > create mode 100644 server/views/firewalls/new_rule.html.haml > create mode 100644 server/views/firewalls/show.html.haml > create mode 100644 server/views/firewalls/show.xml.haml >=20 > diff --git a/server/Gemfile b/server/Gemfile > index 3ab3d5c..ee5f805 100644 > --- a/server/Gemfile > +++ b/server/Gemfile > @@ -15,7 +15,8 @@ group :azure do > end >=20 > group :ec2 do > - gem 'aws' > + gem 'aws', ">=3D 2.5.4" > + > end >=20 > group :gogrid do > diff --git a/server/deltacloud.rb b/server/deltacloud.rb > index 7caf34f..5628e31 100644 > --- a/server/deltacloud.rb > +++ b/server/deltacloud.rb > @@ -36,6 +36,8 @@ require 'deltacloud/models/storage_volume' > require 'deltacloud/models/bucket' > require 'deltacloud/models/blob' > require 'deltacloud/models/load_balancer' > +require 'deltacloud/models/firewall' > +require 'deltacloud/models/firewall_rule' >=20 > require 'deltacloud/validation' > require 'deltacloud/helpers' > diff --git a/server/lib/deltacloud/base_driver/base_driver.rb = b/server/lib/deltacloud/base_driver/base_driver.rb > index 2c780d9..7f8bd65 100644 > --- a/server/lib/deltacloud/base_driver/base_driver.rb > +++ b/server/lib/deltacloud/base_driver/base_driver.rb > @@ -149,7 +149,12 @@ module Deltacloud > # def keys(credentials, opts) > # def create_key(credentials, opts) > # def destroy_key(credentials, opts) > - > + # > + # def firewalls(credentials, opts) > + # def create_firewall(credentials, opts) > + # def delete_firewall(credentials, opts) > + # def create_firewall_rule(credentials, opts) > + # def delete_firewall_rule(credentials, opts) I don't think this change is necessary. > def realm(credentials, opts) > realms =3D realms(credentials, opts).first if = has_capability?(:realms) > end > @@ -183,8 +188,12 @@ module Deltacloud > keys(credentials, opts).first if has_capability?(:keys) > end >=20 > + def firewall(credentials, opts=3D{}) > + firewalls(credentials, opts).first if = has_capability?(:firewalls) > + end > + > MEMBER_SHOW_METHODS =3D > - [ :realm, :image, :instance, :storage_volume, :bucket, :blob, = :key ] > + [ :realm, :image, :instance, :storage_volume, :bucket, :blob, = :key, :firewall ] >=20 > def has_capability?(capability) > if MEMBER_SHOW_METHODS.include?(capability.to_sym) > @@ -194,7 +203,6 @@ module Deltacloud > end > end >=20 > - > def filter_on(collection, attribute, opts) > return collection if opts.nil? > return collection if opts[attribute].nil? > diff --git a/server/lib/deltacloud/base_driver/features.rb = b/server/lib/deltacloud/base_driver/features.rb > index b5bc3ee..4a2f1f8 100644 > --- a/server/lib/deltacloud/base_driver/features.rb > +++ b/server/lib/deltacloud/base_driver/features.rb > @@ -187,11 +187,11 @@ module Deltacloud > end > end >=20 > - declare_feature :instances, :security_group do > - description "Put instance in one or more security groups on = launch" > + declare_feature :instances, :firewall do > + description "Put instance in one or more firewalls (security = groups) on launch" > operation :create do > - param :security_group, :array, :optional, [], > - "Array of security group names" > + param :firewalls, :array, :optional, nil, "Array of firewall = ID strings" > + "Array of firewall (security group) id" > end > end >=20 > diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb = b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb > index 4edd989..fbf39f1 100644 > --- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb > +++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb > @@ -33,12 +33,13 @@ module Deltacloud > class EC2Driver < Deltacloud::BaseDriver >=20 > def supported_collections > - DEFAULT_COLLECTIONS + [ :keys, :buckets, :load_balancers, = :addresses ] > + > + DEFAULT_COLLECTIONS + [ :keys, :buckets, :load_balancers, = :addresses, :firewalls ] > end >=20 > feature :instances, :user_data > feature :instances, :authentication_key > - feature :instances, :security_group > + feature :instances, :firewall > feature :instances, :instance_count > feature :images, :owner_id > feature :buckets, :bucket_location > @@ -201,7 +202,7 @@ module Deltacloud > instance_options.merge!(:key_name =3D> opts[:keyname]) if = opts[:keyname] > instance_options.merge!(:availability_zone =3D> = opts[:realm_id]) if opts[:realm_id] > instance_options.merge!(:instance_type =3D> opts[:hwp_id]) = if opts[:hwp_id] && opts[:hwp_id].length > 0 > - instance_options.merge!(:group_ids =3D> = opts[:security_group]) if opts[:security_group] > + instance_options.merge!(:group_ids =3D> opts[:firewalls]) = if opts[:firewalls] > instance_options.merge!( > :min_count =3D> opts[:instance_count], > :max_count =3D> opts[:instance_count] > @@ -571,6 +572,73 @@ module Deltacloud > end > end >=20 > +#-- > +#FIREWALLS - ec2 security groups > +#-- > + def firewalls(credentials, opts=3D{}) > + ec2 =3D new_client(credentials) > + the_firewalls =3D [] > + groups =3D [] > + safely do > + if opts[:id] > + groups =3D ec2.describe_security_groups([opts[:id]]) > + else > + groups =3D ec2.describe_security_groups() > + end > + end > + groups.each do |security_group| > + the_firewalls << convert_security_group(security_group) > + end > + the_firewalls > + end Here you're using 4 spaces for indentation. > + > +#-- > +#Create firewall > +#-- > + def create_firewall(credentials, opts=3D{}) > + ec2 =3D new_client(credentials) Here you're using 2 spaces. I would prefer to use just 2 spaces ;-) > + safely do > + ec2.create_security_group(opts["name"], = opts["description"]) > + end > + Firewall.new( { :id=3D>opts["name"], :name=3D>opts["name"], > + :description =3D> opts["description"], = :owner_id =3D> "", :rules =3D> [] } ) > + end > + > +#-- > +#Delete firewall > +#-- > + def delete_firewall(credentials, opts=3D{}) > + ec2 =3D new_client(credentials) > + safely do > + ec2.delete_security_group(opts["id"]) > + end > + end > +#-- > +#Create firewall rule > +#-- > + def create_firewall_rule(credentials, opts=3D{}) > + ec2 =3D new_client(credentials) > + groups =3D [] > + opts['groups'].each do |k,v| > + groups << {"group_name" =3D> k, "owner" =3D>v} > + end > + safely do > + ec2.manage_security_group_ingress(opts['id'], = opts['from_port'], opts['to_port'], opts['protocol'], > + "authorize", opts['addresses'], groups) > + end > + end > +#-- > +#Delete firewall rule > +#-- > + def delete_firewall_rule(credentials, opts=3D{}) > + ec2 =3D new_client(credentials) > + firewall =3D opts[:id] > + protocol, from_port, to_port, addresses, groups =3D = firewall_rule_params(opts[:rule_id]) > + safely do > + ec2.manage_security_group_ingress(firewall, from_port, = to_port, protocol, "revoke", addresses, groups) > + end > + end > + > def valid_credentials?(credentials) > retval =3D true > begin > @@ -764,6 +832,81 @@ module Deltacloud > balancer > end >=20 > + #generate uid from firewall rule parameters (amazon doesn't = do this for us > + def firewall_rule_id(user_id, protocol, from_port, to_port, = sources) > + sources_string =3D "" > + sources.each do |source| > + sources_string<<"@" > + source.each_pair do |key,value| > + sources_string<< "#{value}," > + end > + sources_string.chomp!(",") > + end > + #sources_string is = @group,297467797945,test@address,ipv4,10.1.1.1,24 etc > + id_string =3D = "#{user_id}~#{protocol}~#{from_port}~#{to_port}~#{sources_string}" > + end > + > + #extract params from uid > + def firewall_rule_params(id) > + #user_id~protocol~from_port~to_port~sources_string > + params =3D id.split("~") > + protocol =3D params[1] > + from_port =3D params[2] > + to_port =3D params[3] > + sources =3D params[4].split("@") > + sources.shift #first match is "" > + addresses =3D [] > + groups =3D [] > + = #@group,297467797945,test@address,ipv4,10.1.1.1,24@address,ipv4,192.168.1.= 1,24 > + sources.each do |source| > + current =3D source.split(",") > + type =3D current[0] > + case type > + when 'group' > + #group,297467797945,test > + owner =3D current[1] > + name =3D current[2] > + groups << {'group_name' =3D> name, 'owner' =3D> = owner} > + when 'address' > + #address,ipv4,10.1.1.1,24 > + address =3D current[2] > + address<<"/#{current[3]}" > + addresses << address > + end > + end > + return protocol, from_port, to_port, addresses, groups > + end > + > + #Convert ec2 security group to = server/lib/deltacloud/models/firewall > + def convert_security_group(security_group) > + rules =3D [] > + security_group[:aws_perms].each do |perm| > + sources =3D [] > + perm[:groups].each do |group| > + sources << {:type =3D> "group", :name =3D> = group[:group_name], :owner =3D> group[:owner]} > + end > + perm[:ip_ranges].each do |ip| > + sources << {:type =3D> "address", :family=3D>"ipv4", > + :address=3D>ip[:cidr_ip].split("/").first, > + :prefix=3D>ip[:cidr_ip].split("/").last} > + end > + rule_id =3D firewall_rule_id(security_group[:aws_owner], = perm[:protocol], > + perm[:from_port] , = perm[:to_port], sources) > + rules << FirewallRule.new({:id =3D> rule_id, > + :allow_protocol =3D> = perm[:protocol], > + :port_from =3D> = perm[:from_port], > + :port_to =3D> perm[:to_port], > + :direction =3D> 'ingress', > + :sources =3D> sources}) > + end > + Firewall.new( { :id =3D> security_group[:aws_group_name], > + :name =3D> = security_group[:aws_group_name], > + :description =3D> = security_group[:aws_description], > + :owner_id =3D> = security_group[:aws_owner], > + :rules =3D> rules > + } ) > + end > + > def convert_state(ec2_state) > case ec2_state > when "terminated" > diff --git a/server/lib/deltacloud/models/bucket.rb = b/server/lib/deltacloud/models/bucket.rb > index e6b2b34..bef36ac 100644 > --- a/server/lib/deltacloud/models/bucket.rb > +++ b/server/lib/deltacloud/models/bucket.rb > @@ -24,7 +24,7 @@ class Bucket < BaseModel >=20 > def to_hash > h =3D self.to_hash_original > - h[:blob_list] =3D self.blob_list.collect { |blob| { :id =3D> = blob,=20 > + h[:blob_list] =3D self.blob_list.collect { |blob| { :id =3D> = blob, > :href =3D> = "#{Sinatra::UrlForHelper::DEFAULT_URI_PREFIX}/buckets/#{self.id}/#{blob.id= }"}} > return h > end > diff --git a/server/lib/deltacloud/models/firewall.rb = b/server/lib/deltacloud/models/firewall.rb > new file mode 100644 > index 0000000..dc0ae3d > --- /dev/null > +++ b/server/lib/deltacloud/models/firewall.rb > @@ -0,0 +1,22 @@ > +# > +# 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. > + > +class Firewall < BaseModel > + attr_accessor :name > + attr_accessor :description > + attr_accessor :owner_id > + attr_accessor :rules > +end > \ No newline at end of file > diff --git a/server/lib/deltacloud/models/firewall_rule.rb = b/server/lib/deltacloud/models/firewall_rule.rb > new file mode 100644 > index 0000000..3959eb6 > --- /dev/null > +++ b/server/lib/deltacloud/models/firewall_rule.rb > @@ -0,0 +1,23 @@ > +# > +# 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. > + > +class FirewallRule < BaseModel > + attr_accessor :allow_protocol # tcp/udp/icmp > + attr_accessor :port_from > + attr_accessor :port_to > + attr_accessor :sources > + attr_accessor :direction #ingress egress > +end > diff --git a/server/public/javascripts/application.js = b/server/public/javascripts/application.js > index 95c9bc2..703879c 100644 > --- a/server/public/javascripts/application.js > +++ b/server/public/javascripts/application.js > @@ -19,10 +19,10 @@ $(document).ready(function() { >=20 > function more_fields() > { > - //increment the hidden input that captures how many meta_data = are passed > - var meta_params =3D document.getElementsByName('meta_params') > + //increment the hidden input that captures how many meta_data are = passed > + var meta_params =3D document.getElementsByName('meta_params') > current_number_params =3D eval(meta_params[0].value)+1 > - meta_params[0].value =3D current_number_params > + meta_params[0].value =3D current_number_params > var new_meta =3D = document.getElementById('metadata_holder').cloneNode(true); > new_meta.id =3D 'metadata_holder' + current_number_params; > new_meta.style.display =3D 'block'; > @@ -39,15 +39,50 @@ function more_fields() > function less_fields() > { > var meta_params =3D document.getElementsByName('meta_params') > - current_val =3D eval(meta_params[0].value) > - if (current_val =3D=3D 0) > - { > - return; > - } > - else > - { > - var theDiv =3D = document.getElementById('metadata_holder'+current_val) > - theDiv.parentNode.removeChild(theDiv) > - meta_params[0].value =3D eval(current_val)-1 > - } > + current_val =3D eval(meta_params[0].value) > + if (current_val =3D=3D 0) > + { > + return; > + } > + else > + { > + var theDiv =3D = document.getElementById('metadata_holder'+current_val) > + theDiv.parentNode.removeChild(theDiv) > + meta_params[0].value =3D eval(current_val)-1 > + } > +} > + > +var addresses =3D 0; > +var groups =3D 0; > +function make_fields(type) > +{ > + form =3D document.getElementById("new_rule_form") > + button =3D document.getElementById("submit_button") > + if(type =3D=3D "address") > + { > + name =3D "ip_address" + eval(++addresses) > + create_rule_source_field(name, "Address " + eval(addresses) + " = [use CIDR notation 0.0.0.0/0]", form, button) > + } > + else if(type =3D=3D "group") > + { > + name =3D "group" + eval(++groups) > + create_rule_source_field(name, "Name of group " + eval(groups), = form, button) > + name =3D "group" + eval(groups) + "owner" > + create_rule_source_field(name, "Group " + eval(groups) + " owner = (required)", form, button) > + } > +} > + > +function create_rule_source_field(name, label, form, button) > +{ > + element =3D document.createElement("INPUT") > + element.type =3D "input" > + element.size =3D 35 > + element.name =3D name > + text =3D document.createTextNode(label) > + form.insertBefore(element, button) > + form.insertBefore(text, element) > + form.insertBefore(document.createElement('BR'), element) > + form.insertBefore(document.createElement('BR'), button) > + form.insertBefore(document.createElement('BR'), button) > + form.insertBefore(document.createElement('BR'), button) > } > diff --git a/server/server.rb b/server/server.rb > index ba87c67..ae23263 100644 > --- a/server/server.rb > +++ b/server/server.rb > @@ -948,3 +948,115 @@ collection :addresses do > end >=20 > end > + > +#html for creating a new firewall > +get "#{Sinatra::UrlForHelper::DEFAULT_URI_PREFIX}/firewalls/new" do > + respond_to do |format| > + format.html { haml :"firewalls/new" } > + end > +end > + > +#html for creating a new firewall rule > +get = "#{Sinatra::UrlForHelper::DEFAULT_URI_PREFIX}/firewalls/:firewall/new_rule= " do > + @firewall_name =3D params[:firewall] > + respond_to do |format| > + format.html {haml :"firewalls/new_rule" } > + end > +end > + > +#FIREWALLS > +collection :firewalls do > + description "Allow user to define firewall rules for an instance = (ec2 security groups) eg expose ssh access [port 22, tcp]." > + operation :index do > + description 'List all firewalls' > + with_capability :firewalls > + control { filter_all(:firewalls) } > + end > + > + operation :show do > + description 'Show details for a specific firewall - list all = rules' > + with_capability :firewall > + param :id, :string, :required > + control { show(:firewall) } > + end > + > + operation :create do > + description 'Create a new firewall' > + with_capability :create_firewall > + param :name, :string, :required > + param :description, :string, :required > + control do > + @firewall =3D driver.create_firewall(credentials, params ) > + respond_to do |format| > + format.xml do > + response.status =3D 201 # Created > + haml :"firewalls/show" > + end > + format.html {haml :"firewalls/show"} > + format.json {convert_to_json(:firewall, @firewall)} > + end > + end > + end > + > + operation :destroy do > + description 'Delete a specified firewall - error if firewall has = rules' > + with_capability :delete_firewall > + param :id, :string, :required > + control do > + driver.delete_firewall(credentials, params) > + respond_to do |format| > + format.xml { 204 } > + format.json { 204 } > + format.html { redirect(firewalls_url) } > + end > + end > + end > + > +#create a new firewall rule - POST /api/firewalls/:firewall/rules > + operation :rules, :method =3D> :post, :member =3D> true do > + description 'Create a new firewall rule for the specified = firewall' > + param :firewall, :required, :string, [], "Name of firewall in = which to apply this rule" > + param :protocol, :required, :string, ['tcp','udp','icmp'], = "Transport layer protocol for the rule" > + param :from_port, :required, :string, [], "Start of port range = for the rule" > + param :to_port, :required, :string, [], "End of port range for = the rule" > + with_capability :create_firewall_rule > + control do > + #source IPs from params > + addresses =3D params.inject([]){|result,current| result << = current.last unless current.grep(/^ip[-_]address/i).empty?; result} > + #source groups from params > + groups =3D {} > + max_groups =3D params.select{|k,v| k=3D~/^group/}.size/2 > + for i in (1..max_groups) do > + = groups.merge!({params["group#{i}"]=3D>params["group#{i}owner"]}) > + end > + params.merge!( {'addresses' =3D> addresses} ) ; params.merge!( = {'groups' =3D> groups} ) > + driver.create_firewall_rule(credentials, params) > + @firewall =3D driver.firewall(credentials, {:id =3D> = params[:firewall]}) > + respond_to do |format| > + format.html {haml :"firewalls/show"} > + format.xml do > + response.status =3D 201 #created > + haml :"firewall/show" > + end > + format.json {convert_to_json(:firewall, @firewall)} > + end > + end > + end > + > +#delete a firewall rule DELETE /api/firewalls/:firewall/rule - with = param rule_id > + operation :rule, :method =3D> :delete, :member =3D> true do > + description 'Delete the specified firewall rule from the given = firewall' > + param :firewall, :required, :string > + param :rule_id, :required, :string > + with_capability :delete_firewall_rule > + control do > + driver.delete_firewall_rule(credentials, params) > + respond_to do |format| > + format.html {redirect firewall_url(params[:id])} > + format.xml {204} > + format.json {204} > + end > + end > + end > + > +end #firewalls > diff --git a/server/views/firewalls/index.html.haml = b/server/views/firewalls/index.html.haml > new file mode 100644 > index 0000000..3312a32 > --- /dev/null > +++ b/server/views/firewalls/index.html.haml > @@ -0,0 +1,25 @@ > +%h1 Firewalls > +%br > +%p > + =3Dlink_to 'Create new firewall', "/api/firewalls/new" > +%table.display > + %thead > + %tr > + %th Id > + %th Name > + %th Description > + %th Owner ID > + %th Rules > + %tbody > + - @firewalls.each do |firewall| > + %tr > + %td > + =3D link_to firewall.id, firewall_url(firewall.id) > + %td > + =3D firewall.name > + %td > + =3D firewall.description > + %td > + =3D firewall.owner_id > + %td > + =3D link_to 'view rules', firewall_url(firewall.id) > diff --git a/server/views/firewalls/index.xml.haml = b/server/views/firewalls/index.xml.haml > new file mode 100644 > index 0000000..f027785 > --- /dev/null > +++ b/server/views/firewalls/index.xml.haml > @@ -0,0 +1,23 @@ > +!!! XML > +%firewalls > + - @firewalls.each do |firewall| > + %firewall{:href =3D> firewall_url(firewall.id), :id =3D> = firewall.id} > + - firewall.attributes.select{ |attr| attr !=3D :id && attr!=3D = :rules}.each do |attribute| > + - haml_tag("#{attribute}".tr('-', '_'), :<) do > + - if [:name, :description].include?(attribute) > + =3Dcdata do > + - haml_concat firewall.send(attribute) > + - else > + - haml_concat firewall.send(attribute) > + %rules > + - firewall.rules.each do |rule| > + %rule{:id =3D> rule.id} > + - rule.attributes.select{|attr| attr !=3D :sources && = attr !=3D :id}.each do |rule_attrib| > + - haml_tag("#{rule_attrib}".tr('-', '_'), :<) do > + - haml_concat rule.send(rule_attrib) > + %sources > + - rule.sources.each do |source| > + - if source[:type] =3D=3D "group" > + %source{:name =3D> source[:name], :type=3D> = source[:type], :owner=3D> source[:owner]} > + - else > + %source{:prefix =3D> source[:prefix], :address=3D> = source[:address], :family=3D>source[:family], :type =3D> source[:type]} > \ No newline at end of file > diff --git a/server/views/firewalls/new.html.haml = b/server/views/firewalls/new.html.haml > new file mode 100644 > index 0000000..4a230a6 > --- /dev/null > +++ b/server/views/firewalls/new.html.haml > @@ -0,0 +1,11 @@ > +%h1 New Firewall > + > +%form{:action =3D> firewalls_url, :method =3D> :post} > + %label > + Firewall Name > + %input{:name =3D> 'name', :size =3D> 25}/ > + %br > + %label > + Firewall Description > + %input{:name =3D> 'description', :size =3D> 100}/ > + %input{:type =3D> :submit, :name =3D> "commit", :value=3D>"create"} > \ No newline at end of file > diff --git a/server/views/firewalls/new_rule.html.haml = b/server/views/firewalls/new_rule.html.haml > new file mode 100644 > index 0000000..b25206a > --- /dev/null > +++ b/server/views/firewalls/new_rule.html.haml > @@ -0,0 +1,26 @@ > +%h1 New Firewall Rule > + > +%form{ :action =3D> "#{firewall_url(@firewall_name)}/rules", :id =3D> = "new_rule_form", :method =3D> :post, :enctype =3D> = 'multipart/form-data'} > + %label > + Protocol: > + %br > + %input{ :name =3D> 'protocol', :size =3D> 10}/ > + %br > + %br > + %label > + =46rom port: > + %br > + %input{ :name =3D> 'from_port', :size =3D> 10}/ > + %br > + %br > + To port: > + %br > + %input{ :name =3D> 'to_port', :size =3D> 10}/ > + %br > + %br > + %a{ :href =3D> "javascript:;", :onclick =3D> = "make_fields('address');"} Add source IP address > + %br > + %a{ :href =3D> "javascript:;", :onclick =3D> = "make_fields('group');"} Add source group > + %br > + %br > + %input{ :type =3D> :submit, :id =3D> "submit_button", :name =3D> = "commit", :value =3D> "create"}/ > diff --git a/server/views/firewalls/show.html.haml = b/server/views/firewalls/show.html.haml > new file mode 100644 > index 0000000..b77aaa4 > --- /dev/null > +++ b/server/views/firewalls/show.html.haml > @@ -0,0 +1,44 @@ > +%h1 Firewall > +%h2 > + =3D @firewall.id > +%dl > + %di > + %dt Name > + %dd > + =3D @firewall.name > + %dt Owner > + %dd > + =3D @firewall.owner_id > + %dt Description > + %dd > + =3D @firewall.description > + > +%h2 > + Rules > + %br > + %p > + =3Dlink_to 'Create a new rule', = "/api/firewalls/#{@firewall.name}/new_rule" > +%dl > + - @firewall.rules.each do |rule| > + %di > + Rule > + - rule.attributes.select{|attr| attr !=3D :sources}.each do = |attrib| > + %dt #{attrib} > + %dd > + =3D rule.send(attrib) > + %dt sources > + %dd > + - rule.sources.each do |source| > + - if source[:type] =3D=3D "group" > + type: #{source[:type]}, name: #{source[:name]}, owner: = #{source[:owner]} > + %br > + - else > + type: #{source[:type]}, family: #{source[:family]}, = address: #{source[:address]}, prefix: #{source[:prefix]} > + %br > + %dd > + %form{ :action =3D> "#{firewall_url(@firewall.name)}/rule", = :method =3D> :post} > + %input{:type =3D> "hidden", :name =3D> "_method", :value =3D>= "delete"} > + %input{:type =3D> "hidden", :name =3D> "rule_id", :value =3D>= rule.id} > + %input{:type =3D> :submit, :value =3D> "Delete Rule"} > + %dd > + =3D link_to_action 'Delete Firewall', = destroy_firewall_url(@firewall.name), :delete > diff --git a/server/views/firewalls/show.xml.haml = b/server/views/firewalls/show.xml.haml > new file mode 100644 > index 0000000..9d1fc48 > --- /dev/null > +++ b/server/views/firewalls/show.xml.haml > @@ -0,0 +1,21 @@ > +!!! XML > +%firewall{:href =3D> firewall_url(@firewall.id), :id =3D> = @firewall.id} > + - @firewall.attributes.select{ |attr| attr !=3D :id && attr!=3D = :rules}.each do |attribute| > + - haml_tag("#{attribute}".tr('-', '_'), :<) do > + - if [:name, :description].include?(attribute) > + =3Dcdata do > + - haml_concat @firewall.send(attribute) > + - else > + - haml_concat @firewall.send(attribute) > + %rules > + - @firewall.rules.each do |rule| > + %rule{:id =3D> rule.id} > + - rule.attributes.select{|attr| attr !=3D :sources && attr !=3D= :id}.each do |rule_attrib| > + - haml_tag("#{rule_attrib}".tr('-', '_'), :<) do > + - haml_concat rule.send(rule_attrib) > + %sources > + - rule.sources.each do |source| > + - if source[:type] =3D=3D "group" > + %source{:name =3D> source[:name], :type=3D> = source[:type], :owner=3D>source[:owner]} > + - else > + %source{:prefix =3D> source[:prefix], :address=3D> = source[:address], :family=3D>source[:family], :type =3D> source[:type]} > \ No newline at end of file > --=20 > 1.7.3.4 >=20 ------------------------------------------------------ Michal Fojtik, mfojtik@redhat.com Deltacloud API: http://deltacloud.org