Blame SOURCES/bz1264360-01-web-UI-add-support-for-unmanaged-resources.patch

15f218
From cf1c95354a9db8b81712d7b98d0cc55e777e0516 Mon Sep 17 00:00:00 2001
15f218
From: Ondrej Mular <omular@redhat.com>
15f218
Date: Thu, 4 Aug 2016 00:59:11 +0200
15f218
Subject: [PATCH] web UI: add support for unmanaged resources
15f218
15f218
---
15f218
 pcsd/cluster_entity.rb        | 13 ++++++++--
15f218
 pcsd/pcs.rb                   |  1 +
15f218
 pcsd/public/js/nodes-ember.js | 22 +++++++++++++----
15f218
 pcsd/public/js/pcsd.js        | 52 ++++++++++++++++++++++++++++++++++++++++
15f218
 pcsd/remote.rb                | 55 +++++++++++++++++++++++++++++++++++++++----
15f218
 pcsd/views/main.erb           | 26 ++++++++++++++++++++
15f218
 6 files changed, 158 insertions(+), 11 deletions(-)
15f218
15f218
diff --git a/pcsd/cluster_entity.rb b/pcsd/cluster_entity.rb
15f218
index fa56fe2..7216626 100644
15f218
--- a/pcsd/cluster_entity.rb
15f218
+++ b/pcsd/cluster_entity.rb
15f218
@@ -332,7 +332,11 @@ module ClusterEntity
15f218
       :unknown => {
15f218
         :val => 6,
15f218
         :str => 'unknown'
15f218
-      }
15f218
+      },
15f218
+      :unmanaged => {
15f218
+        :val => 7,
15f218
+        :str => 'unmanaged'
15f218
+      },
15f218
     }
15f218
 
15f218
     def initialize(status=:unknown)
15f218
@@ -532,8 +536,11 @@ module ClusterEntity
15f218
     def get_status
15f218
       running = 0
15f218
       failed = 0
15f218
+      unmanaged = 0
15f218
       @crm_status.each do |s|
15f218
-        if s.active
15f218
+        if !s.managed
15f218
+          unmanaged += 1
15f218
+        elsif s.active
15f218
           running += 1
15f218
         elsif s.failed
15f218
           failed += 1
15f218
@@ -542,6 +549,8 @@ module ClusterEntity
15f218
 
15f218
       if disabled?
15f218
         status = ClusterEntity::ResourceStatus.new(:disabled)
15f218
+      elsif unmanaged >0
15f218
+        status = ClusterEntity::ResourceStatus.new(:unmanaged)
15f218
       elsif running > 0
15f218
         status = ClusterEntity::ResourceStatus.new(:running)
15f218
       elsif failed > 0 or @error_list.length > 0
15f218
diff --git a/pcsd/pcs.rb b/pcsd/pcs.rb
15f218
index 1eb9e9e..553a20c 100644
15f218
--- a/pcsd/pcs.rb
15f218
+++ b/pcsd/pcs.rb
15f218
@@ -1703,6 +1703,7 @@ def get_node_status(auth_user, cib_dom)
15f218
         'sbd',
15f218
         'ticket_constraints',
15f218
         'moving_resource_in_group',
15f218
+        'unmanaged_resource',
15f218
       ]
15f218
   }
15f218
 
15f218
diff --git a/pcsd/public/js/nodes-ember.js b/pcsd/public/js/nodes-ember.js
15f218
index 3d4fe79..c51a341 100644
15f218
--- a/pcsd/public/js/nodes-ember.js
15f218
+++ b/pcsd/public/js/nodes-ember.js
15f218
@@ -57,6 +57,9 @@ Pcs = Ember.Application.createWithMixins({
15f218
       this.get("available_features").indexOf("moving_resource_in_group") != -1
15f218
     );
15f218
   }.property("available_features"),
15f218
+  is_supported_unmanaged_resource: function() {
15f218
+    return (this.get("available_features").indexOf("unmanaged_resource") != -1);
15f218
+  }.property("available_features"),
15f218
   is_sbd_running: false,
15f218
   is_sbd_enabled: false,
15f218
   is_sbd_enabled_or_running: function() {
15f218
@@ -869,9 +872,17 @@ Pcs.ResourceObj = Ember.Object.extend({
15f218
     return '' + this.get('status') + '';
15f218
   }.property("status_style", "disabled"),
15f218
   status_class: function() {
15f218
-    var show = ((Pcs.clusterController.get("show_all_resources"))? "" : "hidden ");
15f218
-    return ((this.get("status_val") == get_status_value("ok") || this.status == "disabled") ? show + "default-hidden" : "");
15f218
-  }.property("status_val"),
15f218
+    if (
15f218
+      this.get("status_val") == get_status_value("ok") ||
15f218
+      ["disabled", "unmanaged"].indexOf(this.get("status")) != -1
15f218
+    ) {
15f218
+      return (
15f218
+        Pcs.clusterController.get("show_all_resources") ? "" : "hidden "
15f218
+        ) + "default-hidden";
15f218
+    } else {
15f218
+      return "";
15f218
+    }
15f218
+  }.property("status_val", "status"),
15f218
   status_class_fence: function() {
15f218
     var show = ((Pcs.clusterController.get("show_all_fence"))? "" : "hidden ");
15f218
     return ((this.get("status_val") == get_status_value("ok")) ? show + "default-hidden" : "");
15f218
@@ -1681,8 +1692,9 @@ Pcs.Cluster = Ember.Object.extend({
15f218
     var num = 0;
15f218
     $.each(this.get(type), function(key, value) {
15f218
       if (value.get("status_val") < get_status_value("ok") &&
15f218
-        value.status != "disabled" && value.status != "standby" &&
15f218
-        value.status != "maintenance"
15f218
+        [
15f218
+          "unmanaged", "disabled", "standby", "maintenance"
15f218
+        ].indexOf(value.status) == -1
15f218
       ) {
15f218
         num++;
15f218
       }
15f218
diff --git a/pcsd/public/js/pcsd.js b/pcsd/public/js/pcsd.js
15f218
index 82187ef..56219d4 100644
15f218
--- a/pcsd/public/js/pcsd.js
15f218
+++ b/pcsd/public/js/pcsd.js
15f218
@@ -1333,6 +1333,9 @@ function remove_resource(ids, force) {
15f218
           message += "\n\n" + xhr.responseText.replace(
15f218
             "--force", "'Enforce removal'"
15f218
           );
15f218
+          alert(message);
15f218
+          $("#verify_remove_submit_btn").button("option", "disabled", false);
15f218
+          return;
15f218
         }
15f218
       }
15f218
       alert(message);
15f218
@@ -1957,6 +1960,7 @@ function get_status_value(status) {
15f218
     maintenance: 2,
15f218
     "partially running": 2,
15f218
     disabled: 3,
15f218
+    unmanaged: 3,
15f218
     unknown: 4,
15f218
     ok: 5,
15f218
     running: 5,
15f218
@@ -2987,3 +2991,51 @@ function sbd_status_dialog() {
15f218
     buttons: buttonsOpts
15f218
   });
15f218
 }
15f218
+
15f218
+function unmanage_resource(resource_id) {
15f218
+  if (!resource_id) {
15f218
+    return;
15f218
+  }
15f218
+  fade_in_out("#resource_unmanage_link");
15f218
+  ajax_wrapper({
15f218
+    type: 'POST',
15f218
+    url: get_cluster_remote_url() + "unmanage_resource",
15f218
+    data: {
15f218
+      resource_list_json: JSON.stringify([resource_id]),
15f218
+    },
15f218
+    timeout: pcs_timeout,
15f218
+    complete: function() {
15f218
+      Pcs.update();
15f218
+    },
15f218
+    error: function (xhr, status, error) {
15f218
+      alert(
15f218
+        `Unable to unmanage '${resource_id}': ` +
15f218
+        ajax_simple_error(xhr, status, error)
15f218
+      );
15f218
+    },
15f218
+  });
15f218
+}
15f218
+
15f218
+function manage_resource(resource_id) {
15f218
+  if (!resource_id) {
15f218
+    return;
15f218
+  }
15f218
+  fade_in_out("#resource_manage_link");
15f218
+  ajax_wrapper({
15f218
+    type: 'POST',
15f218
+    url: get_cluster_remote_url() + "manage_resource",
15f218
+    data: {
15f218
+      resource_list_json: JSON.stringify([resource_id]),
15f218
+    },
15f218
+    timeout: pcs_timeout,
15f218
+    complete: function() {
15f218
+      Pcs.update();
15f218
+    },
15f218
+    error: function (xhr, status, error) {
15f218
+      alert(
15f218
+        `Unable to manage '${resource_id}': ` +
15f218
+        ajax_simple_error(xhr, status, error)
15f218
+      );
15f218
+    }
15f218
+  });
15f218
+}
15f218
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
15f218
index 4844adf..ebf425c 100644
15f218
--- a/pcsd/remote.rb
15f218
+++ b/pcsd/remote.rb
15f218
@@ -116,7 +116,9 @@ def remote(params, request, auth_user)
15f218
       :set_resource_utilization => method(:set_resource_utilization),
15f218
       :set_node_utilization => method(:set_node_utilization),
15f218
       :get_resource_agent_metadata => method(:get_resource_agent_metadata),
15f218
-      :get_fence_agent_metadata => method(:get_fence_agent_metadata)
15f218
+      :get_fence_agent_metadata => method(:get_fence_agent_metadata),
15f218
+      :manage_resource => method(:manage_resource),
15f218
+      :unmanage_resource => method(:unmanage_resource),
15f218
   }
15f218
 
15f218
   command = params[:command].to_sym
15f218
@@ -1575,10 +1577,10 @@ def remove_resource(params, request, auth_user)
15f218
       end
15f218
       cmd = [PCS, '-f', tmp_file.path, 'resource', 'disable']
15f218
       resource_list.each { |resource|
15f218
-        _, err, retval = run_cmd(user, *(cmd + [resource]))
15f218
+        out, err, retval = run_cmd(user, *(cmd + [resource]))
15f218
         if retval != 0
15f218
           unless (
15f218
-            err.join('').index('unable to find a resource') != -1 and
15f218
+            (out + err).join('').include?(' does not exist.') and
15f218
             no_error_if_not_exists
15f218
           )
15f218
             errors += "Unable to stop resource '#{resource}': #{err.join('')}"
15f218
@@ -1613,7 +1615,10 @@ def remove_resource(params, request, auth_user)
15f218
     end
15f218
     out, err, retval = run_cmd(auth_user, *cmd)
15f218
     if retval != 0
15f218
-      unless out.index(' does not exist.') != -1 and no_error_if_not_exists
15f218
+      unless (
15f218
+        (out + err).join('').include?(' does not exist.') and
15f218
+        no_error_if_not_exists
15f218
+      )
15f218
         errors += err.join(' ').strip + "\n"
15f218
       end
15f218
     end
15f218
@@ -2630,3 +2635,45 @@ def qdevice_client_start(param, request, auth_user)
15f218
     return [400, msg]
15f218
   end
15f218
 end
15f218
+
15f218
+def manage_resource(param, request, auth_user)
15f218
+  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
15f218
+    return 403, 'Permission denied'
15f218
+  end
15f218
+  unless param[:resource_list_json]
15f218
+    return [400, "Required parameter 'resource_list_json' is missing."]
15f218
+  end
15f218
+  begin
15f218
+    resource_list = JSON.parse(param[:resource_list_json])
15f218
+    _, err, retval = run_cmd(
15f218
+      auth_user, PCS, 'resource', 'manage', *resource_list
15f218
+    )
15f218
+    if retval != 0
15f218
+      return [400, err.join('')]
15f218
+    end
15f218
+    return [200, '']
15f218
+  rescue JSON::ParserError
15f218
+    return [400, 'Invalid input data format']
15f218
+  end
15f218
+end
15f218
+
15f218
+def unmanage_resource(param, request, auth_user)
15f218
+  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
15f218
+    return 403, 'Permission denied'
15f218
+  end
15f218
+  unless param[:resource_list_json]
15f218
+    return [400, "Required parameter 'resource_list_json' is missing."]
15f218
+  end
15f218
+  begin
15f218
+    resource_list = JSON.parse(param[:resource_list_json])
15f218
+    _, err, retval = run_cmd(
15f218
+      auth_user, PCS, 'resource', 'unmanage', *resource_list
15f218
+    )
15f218
+    if retval != 0
15f218
+      return [400, err.join('')]
15f218
+    end
15f218
+    return [200, '']
15f218
+  rescue JSON::ParserError
15f218
+    return [400, 'Invalid input data format']
15f218
+  end
15f218
+end
15f218
diff --git a/pcsd/views/main.erb b/pcsd/views/main.erb
15f218
index 1b21f92..64fe560 100644
15f218
--- a/pcsd/views/main.erb
15f218
+++ b/pcsd/views/main.erb
15f218
@@ -160,6 +160,7 @@
15f218
       
15f218
     
15f218
     
15f218
+    
15f218
     {{#if resource.stonith}}
15f218
       
15f218
       
15f218
@@ -174,7 +175,32 @@
15f218
       
15f218
       
15f218
       
15f218
+      
15f218
+      
15f218
+      {{#if Pcs.is_supported_unmanaged_resource}}
15f218
+        
15f218
+        
15f218
+        
15f218
+          id="resource_manage_link"
15f218
+          class="link"
15f218
+          onclick="manage_resource(curResource());"
15f218
+        >
15f218
+          Manage
15f218
+        
15f218
+        
15f218
+        
15f218
+        
15f218
+        
15f218
+          id="resource_unmanage_link"
15f218
+          class="link"
15f218
+          onclick="unmanage_resource(curResource());"
15f218
+        >
15f218
+          Unmanage
15f218
+        
15f218
+        
15f218
+      {{/if}}
15f218
     {{/if}}
15f218
+    
15f218
       
15f218
       
15f218
       
15f218
-- 
15f218
1.8.3.1
15f218