From: martyntaylor <[email protected]>

---
 src/app/controllers/quota_controller.rb        |  133 ++++++++++++++++++++++++
 src/app/views/pool/show.html.erb               |    1 +
 src/app/views/provider/accounts.html.erb       |    1 +
 src/app/views/quota/edit.html.erb              |   21 ++++
 src/app/views/quota/new.html.erb               |   21 ++++
 src/app/views/quota/show.html.erb              |   58 ++++++++++
 src/db/migrate/20090802000000_create_quotas.rb |   15 ++-
 src/features/pool.feature                      |   27 +++++
 src/features/step_definitions/pool_steps.rb    |   10 ++
 9 files changed, 282 insertions(+), 5 deletions(-)
 create mode 100644 src/app/controllers/quota_controller.rb
 create mode 100644 src/app/views/quota/edit.html.erb
 create mode 100644 src/app/views/quota/new.html.erb
 create mode 100644 src/app/views/quota/show.html.erb

diff --git a/src/app/controllers/quota_controller.rb 
b/src/app/controllers/quota_controller.rb
new file mode 100644
index 0000000..6a42d00
--- /dev/null
+++ b/src/app/controllers/quota_controller.rb
@@ -0,0 +1,133 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+
+
+class QuotaController < ApplicationController
+
+  def show
+    @parent = get_parent_object(params)
+    @parent_type = params[:parent_type]
+    @quota = @parent.quota
+
+    require_privilege(Privilege::QUOTA_VIEW, @parent)
+  end
+
+  def new
+    @parent = get_parent_object(params)
+    @parent_type = params[:parent_type]
+    @name = get_parent_name(@parent, @parent_type)
+    require_privilege(Privilege::QUOTA_MODIFY, @parent)
+  end
+
+  def create
+    #TODO Should be in Transaction
+    @parent = get_parent_object(params)
+    @parent_type = params[:parent_type]
+    @quota = @parent.quota
+    if !...@quota
+      require_privilege(Privilege::QUOTA_MODIFY, @parent)
+      @quota = Quota.new(params[:quota])
+
+      # Populate Current Pool totals to Quota
+      @parent.instances.each do |instance|
+        hwp = HardwareProfile.find(instance.hardware_profile_id)
+        if instance.state == Instance::STATE_RUNNING
+          @quota.running_instances += 1
+          @quota.running_memory += hwp.memory
+          #TODO Add CPUs
+        end
+
+        if InstanceObserver::ACTIVE_STATES.include?(instance.state)
+          @quota.total_instances += 1
+          @quota.total_storage += hwp.storage
+        end
+      end
+
+      if @quota.save
+        flash[:notice] = "Quota Created!"
+        @parent.quota_id = @quota.id
+        @parent.save!
+        redirect_to :action => 'show', :id => @parent, :parent_type => 
@parent_type
+      else
+        render :action => :new
+      end
+    else
+      @parent.errors.add("quota_id", "There already exists a quota for this " 
+ @parent_type)
+      render :action => :new
+    end
+  end
+
+  def edit
+    @parent = get_parent_object(params)
+    @parent_type = params[:parent_type]
+    @name = get_parent_name(@parent, @parent_type)
+
+    @quota = @parent.quota
+
+    require_privilege(Privilege::QUOTA_MODIFY, @parent)
+  end
+
+  def update
+    @parent = @parent = get_parent_object(params)
+    @parent_type = params[:parent_type]
+    require_privilege(Privilege::QUOTA_MODIFY, @parent)
+
+    @quota = @parent.quota
+    if @quota.update_attributes(params[:quota])
+      flash[:notice] = "Quota updated!"
+      redirect_to :action => 'show', :id => @parent, :parent_type => 
@parent_type
+    else
+      render :action => :edit
+    end
+  end
+
+  def delete
+    @parent = get_parent_object(params)
+    @parent_type = params[:parent_type]
+    @quota = @parent.quota
+    require_privilege(Privilege::QUOTA_MODIFY, @parent)
+    if @quota.delete
+      flash[:notice] = "Quota Deleted!"
+      redirect_to :action => 'show', :id => @parent, :parent_type => 
@parent_type
+    end
+  end
+
+  private
+  def get_parent_object(params)
+    if params[:parent_type] == "pool"
+      return Pool.find(params[:id])
+    elsif params[:parent_type] == "cloud_account"
+      return CloudAccount.find(params[:id])
+    end
+    #TODO Throw no match to pool or cloud account exception
+  end
+
+  def get_parent_name(parent, parent_type)
+    if parent_type == "pool"
+      return parent.name
+    elsif parent_type == "cloud_account"
+      return parent.username
+    end
+    #TODO Throw no match to pool or cloud account exception
+  end
+
+
+end
diff --git a/src/app/views/pool/show.html.erb b/src/app/views/pool/show.html.erb
index 1230c64..8fb8fb6 100644
--- a/src/app/views/pool/show.html.erb
+++ b/src/app/views/pool/show.html.erb
@@ -39,3 +39,4 @@
 <%= link_to "User access",  {:controller => "permissions", :action => "list", 
:pool_id => @pool.id}, :class=>"actionlink" if has_view_perms? %>
 <%= link_to "Hardware Profiles",  {:action => "hardware_profiles", :id => 
@pool.id}, :class=>"actionlink"%>
 <%= link_to "Realms",  {:action => "realms", :id => @pool.id}, 
:class=>"actionlink"%>
+<%= link_to "Quota",  {:controller => "quota", :action => "show", :id => 
@pool, :parent_type => "pool"}, :class=>"actionlink"%>
diff --git a/src/app/views/provider/accounts.html.erb 
b/src/app/views/provider/accounts.html.erb
index ddc8f27..8ce98a8 100644
--- a/src/app/views/provider/accounts.html.erb
+++ b/src/app/views/provider/accounts.html.erb
@@ -15,6 +15,7 @@
           <td><%= acct.username %></td>
           <td><%= link_to "Edit",   {:controller => 'cloud_accounts', :action 
=> 'edit', :id => acct.id}    if has_account_modify?(@provider) %></td>
           <td><%= link_to "Delete", {:controller => 'cloud_accounts', :action 
=> 'destroy', :id => acct.id} if has_account_modify?(@provider) && 
acct.destroyable? %></td>
+                 <td><%= link_to "Quota", {:controller => 'quota', :action => 
'show', :id => acct.id, :parent_type => "cloud_account"} %></td>
         </tr>
       <% } %>
     </tbody>
diff --git a/src/app/views/quota/edit.html.erb 
b/src/app/views/quota/edit.html.erb
new file mode 100644
index 0000000..5e742bb
--- /dev/null
+++ b/src/app/views/quota/edit.html.erb
@@ -0,0 +1,21 @@
+<div class="dcloud_form">
+  <%= error_messages_for @parent_type %>
+  <%= error_messages_for 'quota' %>
+
+  <h2>Edit Quota for <%= @parent_type + ": " + @name%></legend></h2><br />
+
+  <% form_tag :action => 'update' do -%>
+    <%=hidden_field_tag 'id', @parent.id %>
+       <%=hidden_field_tag 'parent_type', @parent_type %>
+
+    <ul>
+      <li><label>Max Running Instances</label><%= text_field :quota, 
:maximum_running_instances %></li>
+         <li><label>Max Running Memory</label><%= text_field :quota, 
:maximum_running_memory %></li>
+         <li><label>Max Running CPUs</label><%= text_field :quota, 
:maximum_running_cpus %></li>
+         <li><label>Max Total Instances</label><%= text_field :quota, 
:maximum_total_instances %></li>
+         <li><label>Max Total Storage</label><%= text_field :quota, 
:maximum_total_storage %></li>
+    </ul>
+    </fieldset>
+    <%= submit_tag "Save", :class => "submit" %>
+  <% end %>
+</div>
\ No newline at end of file
diff --git a/src/app/views/quota/new.html.erb b/src/app/views/quota/new.html.erb
new file mode 100644
index 0000000..1f99bd9
--- /dev/null
+++ b/src/app/views/quota/new.html.erb
@@ -0,0 +1,21 @@
+<div class="dcloud_form">
+  <%= error_messages_for @parent_type %>
+  <%= error_messages_for 'quota' %>
+
+  <h2>Create Quota for <%= @parent_type + ": " + @name%></legend></h2><br />
+
+  <% form_tag :action => 'create' do -%>
+    <%=hidden_field_tag 'id', @parent.id %>
+       <%=hidden_field_tag 'parent_type', @parent_type %>
+
+    <ul>
+      <li><label>Max Running Instances</label><%= text_field :quota, 
:maximum_running_instances %></li>
+         <li><label>Max Running Memory</label><%= text_field :quota, 
:maximum_running_memory %></li>
+         <li><label>Max Running CPUs</label><%= text_field :quota, 
:maximum_running_cpus %></li>
+         <li><label>Max Total Instances</label><%= text_field :quota, 
:maximum_total_instances %></li>
+         <li><label>Max Total Storage</label><%= text_field :quota, 
:maximum_total_storage %></li>
+    </ul>
+    </fieldset>
+    <%= submit_tag "Save", :class => "submit" %>
+  <% end %>
+</div>
\ No newline at end of file
diff --git a/src/app/views/quota/show.html.erb 
b/src/app/views/quota/show.html.erb
new file mode 100644
index 0000000..03a4fc5
--- /dev/null
+++ b/src/app/views/quota/show.html.erb
@@ -0,0 +1,58 @@
+<% if !...@quota %>
+<h1>There is no Quota on this <%= @parent_type %></h1>
+<%= link_to "Create Quota", {:action => "new", :id => @parent, :parent_type => 
@parent_type}, :class=>"actionlink"%>
+<% else %>
+    <table>
+      <thead>
+        <tr>
+          <th scope="col">Resource</th>
+          <th scope="col">Max Capacity</th>
+          <th scope="col">Used Capacity</th>
+          <th scope="col">Free Capacity</th>
+          <th scope="col">% Used</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <td>Running Instances</td>
+          <td><%= sprintf("%.1f", @quota.maximum_running_instances) %></td>
+          <td><%= sprintf("%.1f", @quota.running_instances) %></td>
+          <td><%= sprintf("%.1f", @quota.maximum_running_instances - 
@quota.running_instances) %></td>
+          <td><%=      percentage = (100.to_f / 
@quota.maximum_running_instances) * @quota.running_instances
+                                       sprintf("%.2f", percentage) %></td>
+        </tr>
+        <tr>
+          <td>Running Memory / MB</td>
+          <td><%= sprintf("%.1f", @quota.maximum_running_memory.to_f) %></td>
+          <td><%= sprintf("%.1f", @quota.running_memory.to_f) %></td>
+                 <td><%= sprintf("%.1f", @quota.maximum_running_memory.to_f - 
@quota.running_memory.to_f) %></td>
+                 <td><%=       percentage = (100.to_f / 
@quota.maximum_running_memory.to_f) * @quota.running_memory.to_f
+                                       sprintf("%.2f", percentage) %></td>
+          <td></td>
+        </tr>
+        <tr>
+          <td>Running CPUs</td>
+          <td><%= sprintf("%.1f", @quota.maximum_running_cpus) %></td>
+          <td><%= sprintf("%.1f", @quota.running_cpus) %></td>
+                 <td><%= sprintf("%.1f",@quota.maximum_running_cpus.to_f - 
@quota.running_cpus.to_f) %></td>
+          <td><%= sprintf("%.2f", (100.to_f / 
@quota.maximum_running_cpus.to_f) * @quota.running_cpus.to_f) %></td>
+        </tr>
+        <tr>
+          <td>Total Instances</td>
+          <td><%= sprintf("%.1f", @quota.maximum_total_instances) %></td>
+          <td><%= sprintf("%.1f", @quota.total_instances) %></td>
+                 <td><%= sprintf("%.1f", @quota.maximum_total_instances - 
@quota.total_instances) %></td>
+          <td><%= sprintf("%.2f", (100.to_f / @quota.maximum_total_instances) 
* @quota.total_instances) %></td>
+        </tr>
+        <tr>
+          <td>Total Storage / GB</td>
+          <td><%= sprintf("%.1f", @quota.maximum_total_storage.to_f) %></td>
+          <td><%= sprintf("%.1f", @quota.total_storage.to_f) %></td>
+                 <td><%= sprintf("%.1f", @quota.maximum_total_storage.to_f - 
@quota.total_storage.to_f) %></td>
+          <td><%= sprintf("%.2f", (100.to_f / 
@quota.maximum_total_storage.to_f) * @quota.total_storage.to_f) %></td>
+        </tr>
+    </tbody>
+  </table>
+  <%= link_to "Edit", {:action => "edit", :id => @parent, :parent_type => 
@parent_type}, :class=>"actionlink"%>
+  <%= link_to "Delete", {:action => "delete", :id => @parent, :parent_type => 
@parent_type}, :class=>"actionlink"%>
+<% end %>
\ No newline at end of file
diff --git a/src/db/migrate/20090802000000_create_quotas.rb 
b/src/db/migrate/20090802000000_create_quotas.rb
index c61fb16..9cdda4f 100644
--- a/src/db/migrate/20090802000000_create_quotas.rb
+++ b/src/db/migrate/20090802000000_create_quotas.rb
@@ -20,11 +20,16 @@
 class CreateQuotas < ActiveRecord::Migration
   def self.up
     create_table :quotas do |t|
-      t.integer :running_cpus
-      t.integer :running_memory
-      t.integer :running_instances
-      t.integer :total_storage
-      t.integer :total_instances
+      t.string :running_cpus, :default => 0
+      t.string  :running_memory, :default => 0
+      t.integer :running_instances, :default => 0
+      t.string  :total_storage, :default => 0
+      t.integer :total_instances, :default => 0
+      t.string :maximum_running_cpus
+      t.string  :maximum_running_memory
+      t.integer :maximum_running_instances
+      t.string  :maximum_total_storage
+      t.integer :maximum_total_instances
       t.integer :lock_version, :default => 0
       t.timestamps
     end
diff --git a/src/features/pool.feature b/src/features/pool.feature
index 5d8f219..7308dd4 100644
--- a/src/features/pool.feature
+++ b/src/features/pool.feature
@@ -45,3 +45,30 @@ Feature: Manage Pools
          When I follow "Realms"
          Then I should see "Europe"
          And I should see "United States"
+
+  @tag
+  Scenario: View Pool's Quota Usage
+    Given I own a pool named "mockpool"
+    And the Pool has a quota with following capacities:
+    | resource                  | capacity |
+    | maximum_running_instances | 10       |
+    | maximum_running_memory    | 10240    |
+    | maximum_running_cpus      | 20       |
+    | maximum_total_instances   | 15       |
+    | maximum_total_storage     | 8500     |
+    | running_instances         | 8        |
+    | running_memory            | 9240     |
+    | running_cpus              | 16       |
+    | total_instances           | 15       |
+    | total_storage             | 8400     |
+    And I am on the homepage
+    When I follow "mockpool"
+    Then I should be on the show pool page
+    When I follow "Quota"
+    Then I should see the following:
+    | Resource          | Max Capacity | Used Capacity | Free Capacity | % 
Used |
+    | Running Instances | 10           | 8             | 2             | 80.00 
 |
+    | Running Memory    | 10240        | 9240          | 1000          | 90.23 
 |
+    | Running CPUs      | 20           | 16            | 4             | 80.00 
 |
+    | Total Instances   | 15           | 15            | 0             | 
100.00 |
+    | Total Storage     | 8500         | 8400          | 100           | 98.82 
 |
\ No newline at end of file
diff --git a/src/features/step_definitions/pool_steps.rb 
b/src/features/step_definitions/pool_steps.rb
index 3d97da6..3be5808 100644
--- a/src/features/step_definitions/pool_steps.rb
+++ b/src/features/step_definitions/pool_steps.rb
@@ -48,3 +48,13 @@ Then /^I should see the following:$/ do |table|
     end
   end
 end
+
+Given /^the Pool has a quota with following capacities:$/ do |table|
+  quota_hash = { "pool_id" => @pool, "pool" => @pool}
+  table.hashes.each do |hash|
+    quota_hash[hash["resource"]] = hash["capacity"]
+  end
+
+  @quota = Factory(:quota, quota_hash)
+  puts @quota.pool_id
+end
\ 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