This graph, appearing at the top of the dashboard's front page, provides a
succinct overview of the current state of your infrastructure.  Nodes are
classified in one of four distinct categories:

 * Unresponsive - Dashboard has not received a recent report from the node.
 * Failed - The node is responsive, but the most recent report indicated 
failure.
 * Pending - The node is responsive and did not fail, but the most recent 
report had at least one 'noop' event.
 * Compliant - The node is responsive, did not fail, and has no pending changes.

Paired-With: Nick Lewis

Signed-off-by: Pieter van de Bruggen <[email protected]>
---
Local-branch: tickets/next/6991
 app/controllers/pages_controller.rb       |   17 ++++++--
 app/helpers/pages_helper.rb               |    3 +
 app/views/pages/_node_summary_row.haml    |   13 ++++++
 app/views/pages/home.html.haml            |   38 ++++--------------
 public/stylesheets/application.css        |   49 +++++++++++++++++++++++
 public/stylesheets/sass/application.scss  |   60 +++++++++++++++++++++++++++++
 spec/controllers/pages_controller_spec.rb |   39 +++++++++++-------
 7 files changed, 170 insertions(+), 49 deletions(-)
 create mode 100644 app/views/pages/_node_summary_row.haml

diff --git a/app/controllers/pages_controller.rb 
b/app/controllers/pages_controller.rb
index 8a36e1c..36160a9 100644
--- a/app/controllers/pages_controller.rb
+++ b/app/controllers/pages_controller.rb
@@ -1,11 +1,18 @@
 class PagesController < ApplicationController
   def home
-    @currently_failing_nodes = Node.by_currentness_and_successfulness(true, 
false).unhidden
-    @unreported_nodes = Node.unreported.unhidden
-    @no_longer_reporting_nodes = Node.no_longer_reporting.unhidden
-    @recently_reported_nodes = 
Node.reported.by_report_date.unhidden.all(:limit => 10)
+    @nodes = Node.unhidden
 
-    @unhidden_nodes = Node.unhidden
+    @currently_failing_nodes = @nodes.by_currentness_and_successfulness(true, 
false)
+    @unreported_nodes = @nodes.unreported
+    @no_longer_reporting_nodes = @nodes.no_longer_reporting
+    @recently_reported_nodes = @nodes.reported.by_report_date.all(:limit => 10)
+
+    @unresponsive_nodes = @nodes.current(false)
+    @current_nodes      = @nodes.current(true)
+    @failed_nodes       = @current_nodes.successful(false)
+    @successful_nodes   = @current_nodes.successful(true)
+    @pending_nodes      = @successful_nodes.pending(true)
+    @compliant_nodes    = @successful_nodes.pending(false)
   end
 
   def release_notes
diff --git a/app/helpers/pages_helper.rb b/app/helpers/pages_helper.rb
index 2c057fd..0de5b40 100644
--- a/app/helpers/pages_helper.rb
+++ b/app/helpers/pages_helper.rb
@@ -1,2 +1,5 @@
 module PagesHelper
+  def percentage(nodes)
+    (100 * nodes.length / @nodes.length.to_f).round(2)
+  end
 end
diff --git a/app/views/pages/_node_summary_row.haml 
b/app/views/pages/_node_summary_row.haml
new file mode 100644
index 0000000..bf3fb96
--- /dev/null
+++ b/app/views/pages/_node_summary_row.haml
@@ -0,0 +1,13 @@
+- nodes      = local_assigns[:nodes]
+- title      = local_assigns[:title]
+- puts title.inspect
+- class_name = title[/\w*/].downcase
+
+%tr{:class => class_name}
+  %td.count
+    %span= nodes.length
+  %td
+    %span.label= title
+    %em= "#{percentage(nodes)}%"
+    %br/
+    %hr{:style => "width: #{percentage(nodes)}%"}
diff --git a/app/views/pages/home.html.haml b/app/views/pages/home.html.haml
index 887ade8..b1f8e4f 100644
--- a/app/views/pages/home.html.haml
+++ b/app/views/pages/home.html.haml
@@ -3,37 +3,17 @@
   .header
     %h2 Dashboard
   .item
-    - if @currently_failing_nodes.present?
-      .section.error
-        %h3 Node failures
-        %p
-          = pluralize @currently_failing_nodes.length, 'node'
-          are currently reporting failures:
-          = succeed '.' do
-            = truncated_node_sentence(@currently_failing_nodes, :more_link => 
nodes_path(:current => true, :successful => false))
-
-    - if @no_longer_reporting_nodes.present?
-      .section.warning
-        %h3 Nodes no longer reporting
-        %p
-          = pluralize @no_longer_reporting_nodes.length, 'node'
-          = @no_longer_reporting_nodes.length == 1 ? 'has' : 'have'
-          not reported in the last #{time_ago_in_words 
SETTINGS.no_longer_reporting_cutoff.seconds.ago}:
-          = succeed '.' do
-            = truncated_node_sentence(@no_longer_reporting_nodes, :more_link 
=> no_longer_reporting_nodes_path)
-
-    - if @unreported_nodes.present?
-      .section.warning
-        %h3 Nodes never reported
-        %p
-          = pluralize @unreported_nodes.length, 'node'
-          = @unreported_nodes.length == 1 ? 'has' : 'have'
-          never reported:
-          = succeed '.' do
-            = truncated_node_sentence(@unreported_nodes, :more_link => 
unreported_nodes_path)
+    .section
+      %table.node_summary
+        - [ { :title => 'Unresponsive', :nodes => @unresponsive_nodes },
+            { :title => 'Failed',       :nodes => @failed_nodes },
+            { :title => 'Pending',      :nodes => @pending_nodes },
+            { :title => 'Compliant',    :nodes => @compliant_nodes },
+            { :title => 'Total Nodes',  :nodes => @nodes } ].each do |section|
+          = render 'node_summary_row', section
 
     .section
-      = render 'statuses/run_failure', :nodes => @unhidden_nodes
+      = render 'statuses/run_failure', :nodes => @nodes
     .section
       %h3 Recently-reported nodes
       = render 'nodes/nodes', :nodes => @recently_reported_nodes, :more_link 
=> nodes_path(:page => 2)
diff --git a/public/stylesheets/application.css 
b/public/stylesheets/application.css
index 15be9f9..0951ffb 100644
--- a/public/stylesheets/application.css
+++ b/public/stylesheets/application.css
@@ -416,6 +416,55 @@ body {
     background: #ffe4c7; }
   body.reports_show_action tr.puppet_log.puppet_log_level_warning td {
     background: #ffebd6; }
+  body.pages_home_action table.node_summary {
+    border: solid 1px #DDD;
+    padding: 1em;
+    width: 75%;
+    margin: 0 auto; }
+    body.pages_home_action table.node_summary tr.unresponsive {
+      color: gray; }
+      body.pages_home_action table.node_summary tr.unresponsive hr {
+        background-color: gray; }
+    body.pages_home_action table.node_summary tr.failed {
+      color: red; }
+      body.pages_home_action table.node_summary tr.failed hr {
+        background-color: red; }
+    body.pages_home_action table.node_summary tr.pending {
+      color: orange; }
+      body.pages_home_action table.node_summary tr.pending hr {
+        background-color: orange; }
+    body.pages_home_action table.node_summary tr.compliant {
+      color: green; }
+      body.pages_home_action table.node_summary tr.compliant hr {
+        background-color: green; }
+    body.pages_home_action table.node_summary tr.total {
+      color: black; }
+      body.pages_home_action table.node_summary tr.total hr {
+        background-color: black; }
+    body.pages_home_action table.node_summary tr td {
+      padding-bottom: 1em; }
+      body.pages_home_action table.node_summary tr td.count {
+        padding-right: 1em;
+        width: 1em;
+        text-align: right; }
+        body.pages_home_action table.node_summary tr td.count span {
+          font-size: 3em;
+          font-weight: bold; }
+      body.pages_home_action table.node_summary tr td .label {
+        font-size: 1.5em; }
+      body.pages_home_action table.node_summary tr td em {
+        color: #888;
+        margin-left: 10px;
+        font-size: 1.25em; }
+      body.pages_home_action table.node_summary tr td hr {
+        height: 5px;
+        align: left;
+        border: 0;
+        margin: 0; }
+    body.pages_home_action table.node_summary tr.total td {
+      padding-top: 1em;
+      padding-bottom: 0;
+      border-top: solid 1px #DDD; }
   body.pages_release_notes_action .markeddown h2 {
     margin-top: 1em;
     margin-bottom: 0.15em; }
diff --git a/public/stylesheets/sass/application.scss 
b/public/stylesheets/sass/application.scss
index 0eaeef6..73cd2c5 100644
--- a/public/stylesheets/sass/application.scss
+++ b/public/stylesheets/sass/application.scss
@@ -98,6 +98,11 @@ $rounding_radius: 0.35em;
     }
 }
 
+@mixin node_summary_row($color) {
+  color: $color;
+  hr { background-color: $color }
+}
+
 body {
   background: #e8eef0;
   color: #444;
@@ -584,6 +589,61 @@ body {
     }
   }
 
+  &.pages_home_action {
+    table.node_summary {
+      border: solid 1px #DDD;
+      padding: 1em;
+      width: 75%;
+      margin: 0 auto;
+
+      tr {
+        &.unresponsive { @include node_summary_row(gray) }
+        &.failed       { @include node_summary_row(red) }
+        &.pending      { @include node_summary_row(orange) }
+        &.compliant    { @include node_summary_row(green) }
+        &.total        { @include node_summary_row(black) }
+
+        td {
+          padding-bottom: 1em;
+
+          &.count {
+            padding-right: 1em;
+            width: 1em;
+            text-align: right;
+
+            span {
+              font-size: 3em;
+              font-weight: bold;
+            }
+          }
+
+          .label {
+            font-size: 1.5em;
+          }
+
+          em {
+            color: #888;
+            margin-left: 10px;
+            font-size: 1.25em;
+          }
+
+          hr {
+            height: 5px;
+            align: left;
+            border: 0;
+            margin: 0;
+          }
+        }
+
+        &.total td {
+          padding-top: 1em;
+          padding-bottom: 0;
+          border-top: solid 1px #DDD;
+        }
+      }
+    }
+  }
+
   &.pages_release_notes_action {
     .markeddown {
         h2 {
diff --git a/spec/controllers/pages_controller_spec.rb 
b/spec/controllers/pages_controller_spec.rb
index 92edd57..244bb8d 100644
--- a/spec/controllers/pages_controller_spec.rb
+++ b/spec/controllers/pages_controller_spec.rb
@@ -5,26 +5,35 @@ describe PagesController do
     before :each do
       SETTINGS.stubs(:no_longer_reporting_cutoff).returns(3600)
 
-      @currently_failing_node          = Node.generate!(:name => 
"currently_failing")
-      @unreported_node                 = Node.generate!(:name => "unreported")
-      @no_longer_reporting_node        = Node.generate!(:name => 
"no_longer_reporting")
-      @hidden_node                     = Node.generate!(:name => "hidden", 
:hidden => true)
-      @unreported_hidden_node          = Node.generate!(:name => 
"unreported_hidden", :hidden => true)
-      @no_longer_reporting_hidden_node = Node.generate!(:name => 
"no_longer_reporting_hidden", :hidden => true)
-      Report.generate(:host => @currently_failing_node.name, :time => 
5.minutes.ago, :status => "failed")
-      Report.generate(:host => @no_longer_reporting_node.name, :time => 
2.hours.ago, :status => "unchanged")
-      Report.generate(:host => @hidden_node.name, :time => 5.minutes.ago, 
:status => "failed")
-      Report.generate(:host => @no_longer_reporting_hidden_node.name, :time => 
2.hours.ago, :status => "failed")
+      [true, false].each do |hidden|
+        prefix = hidden ? 'hidden:' : ''
+        Factory(:node,              :hidden => hidden, :name => prefix + 
'unreported')
+        Factory(:reported_node,     :hidden => hidden, :name => prefix + 
'reported')
+        Factory(:unresponsive_node, :hidden => hidden, :name => prefix + 
'unresponsive')
+        Factory(:current_node,      :hidden => hidden, :name => prefix + 
'current')
+        Factory(:failing_node,      :hidden => hidden, :name => prefix + 
'failing')
+        Factory(:successful_node,   :hidden => hidden, :name => prefix + 
'successful')
+        Factory(:pending_node,      :hidden => hidden, :name => prefix + 
'pending')
+        Factory(:compliant_node,    :hidden => hidden, :name => prefix + 
'compliant')
+      end
     end
 
     it "should properly categorize nodes" do
       get :home
 
-      assigns[:currently_failing_nodes].map(&:name).should =~ 
["currently_failing"]
-      assigns[:unreported_nodes].map(&:name).should =~ ["unreported"]
-      assigns[:no_longer_reporting_nodes].map(&:name).should =~ 
["no_longer_reporting"]
-      assigns[:recently_reported_nodes].map(&:name).should =~ 
["currently_failing", "no_longer_reporting"]
-      assigns[:unhidden_nodes].map(&:name).should =~ ["currently_failing", 
"unreported", "no_longer_reporting"]
+      assigns[:currently_failing_nodes].map(&:name).should   =~ %w[ reported 
unresponsive current failing ]
+      assigns[:unreported_nodes].map(&:name).should          =~ %w[ unreported 
]
+      assigns[:no_longer_reporting_nodes].map(&:name).should =~ %w[ reported 
unresponsive ]
+      assigns[:recently_reported_nodes].map(&:name).should   =~ %w[ reported 
unresponsive current failing successful pending compliant ]
+
+      assigns[:nodes].map(&:name).should =~ %w[ unreported reported 
unresponsive current failing successful pending compliant ]
+
+      assigns[:unresponsive_nodes].map(&:name).should =~ %w[ unreported 
reported unresponsive ]
+      assigns[:current_nodes].map(&:name).should      =~ %w[ current failing 
successful pending compliant ]
+      assigns[:failed_nodes].map(&:name).should       =~ %w[ current failing ]
+      assigns[:successful_nodes].map(&:name).should   =~ %w[ successful 
pending compliant ]
+      assigns[:pending_nodes].map(&:name).should      =~ %w[ pending ]
+      assigns[:compliant_nodes].map(&:name).should    =~ %w[ successful 
compliant ]
     end
   end
 end
-- 
1.7.5.1

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to