From: Matt Wagner<matt.wagner(a)redhat.com>
Implements
https://www.aeolusproject.org/redmine/issues/1529
---
src/app/controllers/pools_controller.rb | 23 +++++++++++------------
src/app/models/deployment.rb | 3 +++
src/app/models/instance.rb | 9 ++++++++-
src/app/models/pool.rb | 16 ++++++++++++++++
src/app/views/deployments/_deployment.haml | 11 +++++++++++
src/app/views/deployments/_filter_view.haml | 18 ++++++++++++++++++
src/app/views/deployments/_pretty_view.haml | 1 +
src/app/views/pools/_statistics.haml | 21 +++++++++++++++++++++
src/app/views/pools/edit.haml | 2 +-
src/app/views/pools/show.haml | 10 ++++++----
src/features/pool.feature | 12 ++++++++++--
src/features/step_definitions/pool_steps.rb | 8 ++++++++
src/features/support/paths.rb | 4 ++++
13 files changed, 118 insertions(+), 20 deletions(-)
create mode 100644 src/app/views/deployments/_deployment.haml
create mode 100644 src/app/views/deployments/_filter_view.haml
create mode 100644 src/app/views/deployments/_pretty_view.haml
create mode 100644 src/app/views/pools/_statistics.haml
diff --git a/src/app/controllers/pools_controller.rb
b/src/app/controllers/pools_controller.rb
index 18688c7..a42e162 100644
--- a/src/app/controllers/pools_controller.rb
+++ b/src/app/controllers/pools_controller.rb
@@ -23,20 +23,12 @@ class PoolsController< ApplicationController
def show
@pool = Pool.find(params[:id])
require_privilege(Privilege::VIEW, @pool)
- @url_params = params.clone
- load_instances
- @tab_captions = ['Properties', 'Deployments', 'Instances',
'History', 'Permissions']
- @details_tab = params[:details_tab].blank? ? 'properties' :
params[:details_tab]
save_breadcrumb(pool_path(@pool), @pool.name)
+ @statistics = @pool.statistics
+ @view = params[:view] == 'filter' ? 'deployments/filter_view' :
'deployments/pretty_view'
respond_to do |format|
- # TODO - With the new UI, the logic here will probably need to be updated
- format.js do
- if @url_params.delete :details_pane
- render :partial => 'layouts/details_pane' and return
- end
- render :partial => @details_tab and return
- end
- format.html { render :action => 'show'}
+ format.js { render :partial => @view, :locals => {:deployments =>
@pool.deployments} }
+ format.html { render :action => :show}
format.json { render :json => @pool }
end
end
@@ -182,6 +174,13 @@ class PoolsController< ApplicationController
{ :name => "Pool Family", :sort_attr =>
"pool_families.name" },
{ :name => "Enabled", :sort_attr => :enabled }
]
+ @deployments_header = [
+ { :name => "Deployment Name", :sort_attr => :name },
+ { :name => "Base Deployable", :sort_attr =>
'deployable.name' },
+ { :name => "Uptime", :sort_attr => :created_at },
+ { :name => "Instances", :sort_attr => 'instances.count'
},
+ { :name => "Provider", :sort_attr => :provider }
+ ]
end
def load_pools
diff --git a/src/app/models/deployment.rb b/src/app/models/deployment.rb
index 9f382c0..11e2b97 100644
--- a/src/app/models/deployment.rb
+++ b/src/app/models/deployment.rb
@@ -55,6 +55,9 @@ class Deployment< ActiveRecord::Base
:order => "permissions.id ASC"
belongs_to :owner, :class_name => "User", :foreign_key =>
"owner_id"
after_create "assign_owner_roles(owner)"
+ # TODO - Strictly, this should be a belongs_to, but :through seems to only work
one-way,
+ # and we don't much care about the inverse here.
+ has_one :provider, :through => :realm
validates_presence_of :pool_id
validates_presence_of :deployable_id
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index ef38263..4d1c5c6 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -117,6 +117,13 @@ class Instance< ActiveRecord::Base
STATE_SHUTTING_DOWN, STATE_STOPPED, STATE_CREATE_FAILED,
STATE_ERROR]
+ named_scope :deployed, :conditions => { :state => [STATE_RUNNING,
STATE_SHUTTING_DOWN] }
+ # FIXME: "pending" is misleading as it doesn't just cover STATE_PENDING
+ named_scope :pending, :conditions => { :state => [STATE_NEW, STATE_PENDING]
}
+ # FIXME: "failed" is misleading too...
+ named_scope :failed, :conditions => { :state => [STATE_CREATE_FAILED,
STATE_ERROR] }
+
+
SEARCHABLE_COLUMNS = %w(name state)
validates_inclusion_of :state,
@@ -261,7 +268,7 @@ class Instance< ActiveRecord::Base
}
instances = []
- pools = Pool.list_for_user(user, Privilege::VIEW, Instance)
+ pools = Pool.list_for_user(user, Privilege::VIEW, :target_type => Instance)
pools.each{|pool| pool.instances.each {|i| instances<< i}}
instances.each do |i|
if i.state == Instance::STATE_RUNNING
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index cd7e11a..866ecce 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -60,6 +60,8 @@ class Pool< ActiveRecord::Base
:include => [:role],
:order => "permissions.id ASC"
+ has_many :deployments
+
before_destroy :destroyable?
def cloud_accounts
@@ -75,4 +77,18 @@ class Pool< ActiveRecord::Base
instances.all? {|i| i.destroyable? }
end
+ # TODO: Implement Alerts, Updates, and Quotas
+ def statistics
+ # TODO - Need to set up cache invalidation before this is safe
+ #Rails.cache.fetch("pool-#{id}-statistics") do
+ {
+ :cloud_providers => instances.collect{|i| i.provider_account}.uniq.count,
+ :deployments => deployments.count,
+ :instances_deployed => instances.deployed.count,
+ :instances_pending => instances.pending.count,
+ :instances_failed => instances.failed.count
+ }
+ #end
+ end
+
end
diff --git a/src/app/views/deployments/_deployment.haml
b/src/app/views/deployments/_deployment.haml
new file mode 100644
index 0000000..f07cc00
--- /dev/null
+++ b/src/app/views/deployments/_deployment.haml
@@ -0,0 +1,11 @@
+%div.deployment_pretty
+ %h3
+ = deployment.name
+ %ul
+ %li
+ = count_uptime(deployment.created_at)
+ %li
+ = deployment.instances.count
+ Instances
+ %p
+ = deployment.provider.provider_type.name if deployment.provider
\ No newline at end of file
diff --git a/src/app/views/deployments/_filter_view.haml
b/src/app/views/deployments/_filter_view.haml
new file mode 100644
index 0000000..ad3f1b2
--- /dev/null
+++ b/src/app/views/deployments/_filter_view.haml
@@ -0,0 +1,18 @@
+- form_tag do
+ %table
+ -# FIXME: sortable_table_header won't actually work as-is since it sorts on
Pools, not Deployments...
+ -# TODO: There are no defined actions for the checkboxes yet; they'll go here
+ = sortable_table_header(@deployments_header)
+ - deployments.each do |deployment|
+ %tr
+ %td
+ %input{:name => "deployment_selected[]", :type =>
"checkbox", :value => deployment.id, :id =>
"deployment_checkbox_#{deployment.id}" }
+ = deployment.name
+ %td
+ = deployment.deployable.name
+ %td
+ = count_uptime(deployment.created_at)
+ %td
+ = deployment.instances.count
+ %td
+ = deployment.provider.provider_type.name if deployment.provider
\ No newline at end of file
diff --git a/src/app/views/deployments/_pretty_view.haml
b/src/app/views/deployments/_pretty_view.haml
new file mode 100644
index 0000000..5721367
--- /dev/null
+++ b/src/app/views/deployments/_pretty_view.haml
@@ -0,0 +1 @@
+= render :partial => deployments
\ No newline at end of file
diff --git a/src/app/views/pools/_statistics.haml b/src/app/views/pools/_statistics.haml
new file mode 100644
index 0000000..1d37026
--- /dev/null
+++ b/src/app/views/pools/_statistics.haml
@@ -0,0 +1,21 @@
+%h1
+ = @pool.name
+ Pool
+
+= link_to 'New Deployment', launch_new_deployments_path, :class =>
'button', :id => 'new_deployment_button'
+= link_to 'Edit', edit_pool_path(@pool), :class => 'button', :id
=> 'edit_pool_button'
+- form_tag do
+ = hidden_field(@pool, :id)
+ = restful_submit_tag('Delete', 'destroy', pool_url(@pool),
'DELETE')
+
+%div.statistics
+ Cloud Providers
+ = @statistics[:cloud_providers]
+%div.statistics
+ Deployments
+ = @statistics[:deployments]
+%div.instances
+ = @statistics[:instances_deployed]
+ = @statistics[:instances_pending]
+ = @statistics[:instances_failed]
+-# TODO: Implement alerts, updates, and quota overview
diff --git a/src/app/views/pools/edit.haml b/src/app/views/pools/edit.haml
index ea8dd88..8e2be85 100644
--- a/src/app/views/pools/edit.haml
+++ b/src/app/views/pools/edit.haml
@@ -1 +1 @@
-= render :partial => 'edit'
\ No newline at end of file
+= render :partial => 'edit'
diff --git a/src/app/views/pools/show.haml b/src/app/views/pools/show.haml
index 05eeedd..c411511 100644
--- a/src/app/views/pools/show.haml
+++ b/src/app/views/pools/show.haml
@@ -1,5 +1,7 @@
-- content_for :list do
- = render :partial => 'list'
+= render :partial => 'statistics'
-- content_for :details do
- = render :partial => 'layouts/details_pane'
+-# TODO - Alerts aren't implemented just yet
+-#= render :partial => 'alerts'
+
+-# TODO: %w(Deployments History Properties Permissions) links/tabs, plus filter
links/icons, go here
+= render :partial => @view, :locals => {:deployments => @pool.deployments}
diff --git a/src/features/pool.feature b/src/features/pool.feature
index 29f4098..2eae7ce 100644
--- a/src/features/pool.feature
+++ b/src/features/pool.feature
@@ -129,11 +129,19 @@ Feature: Manage Pools
Then I should see pool "mockpool" in JSON format
Scenario: View a pool over XHR
- Given a pool "mockpool" exists
+ Given a pool "mockpool42" exists with deployment
"mockdeployment"
And I request XHR
When I am viewing the pool "mockpool"
Then I should get back a partial
- And I should see "mockpool"
+ And I should see "mockdeployment"
+
+ Scenario: View a pool in filter view over XHR
+ Given a pool "mockpool42" exists with deployment
"mockdeployment"
+ And I request XHR
+ When I go to the "mockpool42" pool filter view page
+ Then I should get back a partial
+ And I should see "Deployment Name"
+ And I should see "mockdeployment"
Scenario: Create a pool and get JSON response
Given I accept JSON
diff --git a/src/features/step_definitions/pool_steps.rb
b/src/features/step_definitions/pool_steps.rb
index 11db612..91d8a6a 100644
--- a/src/features/step_definitions/pool_steps.rb
+++ b/src/features/step_definitions/pool_steps.rb
@@ -22,6 +22,14 @@ Given /^a pool "([^"]*)" exists$/ do |pool_name|
Pool.create!(:name => pool_name, :pool_family => pool_family, :quota =>
quota)
end
+Given /^a pool "([^"]*)" exists with deployment
"([^"]*)"$/ do |pool_name, deployment_name|
+ pool_family = PoolFamily.find_by_name('default') || Factory(:pool_family)
+ quota = Factory(:quota)
+ pool = Pool.find_by_name(pool_name) || Pool.create!(:name => pool_name,
:pool_family => pool_family, :quota => quota)
+ deployable = Deployable.create!(:name => 'deployable1', :owner =>
User.first)
+ Deployment.create!(:name => deployment_name, :pool => pool, :deployable =>
deployable, :owner => User.first)
+end
+
Then /^I should have a pool named "([^\"]*)"$/ do |name|
Pool.find_by_name(name).should_not be_nil
end
diff --git a/src/features/support/paths.rb b/src/features/support/paths.rb
index 6718403..b6ee8d5 100644
--- a/src/features/support/paths.rb
+++ b/src/features/support/paths.rb
@@ -134,6 +134,10 @@ module NavigationHelpers
when /^(.*)'s deployment page$/
deployment_path(Deployment.find_by_name($1))
+ when /^the "(.*)" pool filter view page$/
+ pool = Pool.find_by_name($1)
+ pool_path(pool, :view => 'filter')
+
# Add more mappings here.
# Here is an example that pulls values out of the Regexp:
#