Blob Blame History Raw
From 082be752ee38c8d1314c2130a029e60648f7896b Mon Sep 17 00:00:00 2001
From: Tomas Jelinek <tojeline@redhat.com>
Date: Tue, 11 Aug 2015 16:34:02 +0200
Subject: [PATCH] add nagios support to 'pcs resource list' and web UI

---
 pcs/resource.py  | 58 ++++++++++++++++++++++++++++++++++++++++++--------------
 pcsd/remote.rb   |  4 ++++
 pcsd/resource.rb | 23 ++++++++++++++++++----
 pcsd/settings.rb |  1 +
 4 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/pcs/resource.py b/pcs/resource.py
index f7d8821..8e05aeb 100644
--- a/pcs/resource.py
+++ b/pcs/resource.py
@@ -198,13 +198,28 @@ def parse_resource_options(argv, with_clone=False):
 # List available resources
 # TODO make location more easily configurable
 def resource_list_available(argv):
+    def get_name_and_desc(full_res_name, metadata):
+        sd = ""
+        try:
+            dom = parseString(metadata)
+            shortdesc = dom.documentElement.getElementsByTagName("shortdesc")
+            if len(shortdesc) > 0:
+                sd = " - " +  format_desc(
+                    len(full_res_name + " - "),
+                    shortdesc[0].firstChild.nodeValue.strip().replace("\n", " ")
+                )
+        except xml.parsers.expat.ExpatError:
+            sd = ""
+        finally:
+            return full_res_name + sd + "\n"
+
     ret = ""
     if len(argv) != 0:
         filter_string = argv[0]
     else:
         filter_string = ""
 
-# ocf agents
+    # ocf agents
     os.environ['OCF_ROOT'] = "/usr/lib/ocf/"
     providers = sorted(os.listdir("/usr/lib/ocf/resource.d"))
     for provider in providers:
@@ -223,32 +238,47 @@ def resource_list_available(argv):
             metadata = utils.get_metadata("/usr/lib/ocf/resource.d/" + provider + "/" + resource)
             if metadata == False:
                 continue
-            sd = ""
-            try:
-                dom = parseString(metadata)
-                shortdesc = dom.documentElement.getElementsByTagName("shortdesc")
-                if len(shortdesc) > 0:
-                    sd = " - " +  format_desc(full_res_name.__len__() + 3, shortdesc[0].firstChild.nodeValue.strip().replace("\n", " "))
-            except xml.parsers.expat.ExpatError:
-                sd = ""
-            finally:
-                ret += full_res_name + sd + "\n"
-# lsb agents
+            ret += get_name_and_desc(
+                "ocf:" + provider + ":" + resource,
+                metadata
+            )
+
+    # lsb agents
     lsb_dir = "/etc/init.d/"
     agents = sorted(os.listdir(lsb_dir))
     for agent in agents:
         if os.access(lsb_dir + agent, os.X_OK):
             ret += "lsb:" + agent + "\n"
-# systemd agents
+
+    # systemd agents
     if utils.is_systemctl():
         agents, retval = utils.run(["systemctl", "list-unit-files", "--full"])
         agents = agents.split("\n")
-
     for agent in agents:
         match = re.search(r'^([\S]*)\.service',agent)
         if match:
             ret += "systemd:" + match.group(1) + "\n"
 
+    # nagios metadata
+    nagios_metadata_path = "/usr/share/pacemaker/nagios/plugins-metadata"
+    for metadata_file in sorted(os.listdir(nagios_metadata_path)):
+        if metadata_file.startswith("."):
+            continue
+        full_res_name = "nagios:" + metadata_file
+        if full_res_name.lower().endswith(".xml"):
+            full_res_name = full_res_name[:-len(".xml")]
+        if "--nodesc" in utils.pcs_options:
+            ret += full_res_name + "\n"
+            continue
+        try:
+            ret += get_name_and_desc(
+                full_res_name,
+                open(os.path.join(nagios_metadata_path, metadata_file), "r").read()
+            )
+        except EnvironmentError as e:
+            pass
+
+    # output
     if not ret:
         utils.err(
             "No resource agents available. "
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
index 5b7c753..cb5b176 100644
--- a/pcsd/remote.rb
+++ b/pcsd/remote.rb
@@ -1373,6 +1373,8 @@ def resource_form(params, request, session)
       @resource.required_options, @resource.optional_options, @resource.info = getResourceMetadata(HEARTBEAT_AGENTS_DIR + @cur_resource.type)
     elsif @cur_resource.provider == 'pacemaker'
       @resource.required_options, @resource.optional_options, @resource.info = getResourceMetadata(PACEMAKER_AGENTS_DIR + @cur_resource.type)
+    elsif @cur_resource._class == 'nagios'
+      @resource.required_options, @resource.optional_options, @resource.info = getResourceMetadata(NAGIOS_METADATA_DIR + @cur_resource.type + '.xml')
     end
     @existing_resource = true
     if @resource
@@ -1546,6 +1548,8 @@ def resource_metadata(params, request, session)
     @resource.required_options, @resource.optional_options, @resource.info = getResourceMetadata(HEARTBEAT_AGENTS_DIR + resource_name)
   elsif class_provider == "ocf:pacemaker"
     @resource.required_options, @resource.optional_options, @resource.info = getResourceMetadata(PACEMAKER_AGENTS_DIR + resource_name)
+  elsif class_provider == 'nagios'
+    @resource.required_options, @resource.optional_options, @resource.info = getResourceMetadata(NAGIOS_METADATA_DIR + resource_name + '.xml')
   end
   @new_resource = params[:new]
   @resources, @groups = getResourcesGroups(session)
diff --git a/pcsd/resource.rb b/pcsd/resource.rb
index f375bae..c6b513b 100644
--- a/pcsd/resource.rb
+++ b/pcsd/resource.rb
@@ -303,13 +303,28 @@ def getColocationConstraints(session, resource_id)
 end
 
 def getResourceMetadata(resourcepath)
-  ENV['OCF_ROOT'] = OCF_ROOT
-  metadata = `#{resourcepath} meta-data`
-  doc = REXML::Document.new(metadata)
   options_required = {}
   options_optional = {}
   long_desc = ""
   short_desc = ""
+
+  if resourcepath.end_with?('.xml')
+    begin
+      metadata = IO.read(resourcepath)
+    rescue
+      metadata = ""
+    end
+  else
+    ENV['OCF_ROOT'] = OCF_ROOT
+    metadata = `#{resourcepath} meta-data`
+  end
+
+  begin
+    doc = REXML::Document.new(metadata)
+  rescue REXML::ParseException
+    return [options_required, options_optional, [short_desc, long_desc]]
+  end
+
   doc.elements.each('resource-agent/longdesc') {|ld|
     long_desc = ld.text ? ld.text.strip : ld.text
   }
@@ -345,7 +360,7 @@ def getResourceMetadata(resourcepath)
       options_optional[param.attributes["name"]] = temp_array
     end
   }
-  [options_required, options_optional, [short_desc,long_desc]]
+  [options_required, options_optional, [short_desc, long_desc]]
 end
 
 def getResourceAgents(session, resource_agent=nil)
diff --git a/pcsd/settings.rb b/pcsd/settings.rb
index 0cd3109..4cea800 100644
--- a/pcsd/settings.rb
+++ b/pcsd/settings.rb
@@ -8,6 +8,7 @@ COOKIE_FILE = PCSD_VAR_LOCATION + 'pcsd.cookiesecret'
 OCF_ROOT = "/usr/lib/ocf"
 HEARTBEAT_AGENTS_DIR = "/usr/lib/ocf/resource.d/heartbeat/"
 PACEMAKER_AGENTS_DIR = "/usr/lib/ocf/resource.d/pacemaker/"
+NAGIOS_METADATA_DIR = '/usr/share/pacemaker/nagios/plugins-metadata/'
 PENGINE = "/usr/libexec/pacemaker/pengine"
 CRM_MON = "/usr/sbin/crm_mon"
 CRM_NODE = "/usr/sbin/crm_node"
-- 
1.9.1