0

Hello everyone I am currently trying to let my Table on my dashboard display an Array which should look like this.

Email - Array containing LotusServer and POP3-Server

Each of those containing different values like a host_name, service_descriptions, uptime duration ...

I need to send back a json output to the table, its working to display the POP3-Server and LotusServer on their own but, the idea is to have groups of hosts being displayed.

I am trying to push those Array's into a new Array called latest and send that back to the table but I don't seem to get the syntax right. Im quite new to ruby maybe someone can give me a hint or help me solve this problem?

Here's some code that might explain better where I'm stuck:

# get the url to download the status.cgi which contains the values

def request_status(url, user, pass, type)
  case type
  when "host"
    url_part = "style=hostdetail"
  when "service"
    url_part = "host=all&hoststatustypes=3"
  else
    throw "status type '" + type + "' is not supported!"
  end

  uri = URI.parse(url + "?" + url_part + "&nostatusheader&jsonoutput&sorttype=1&sortoption=6")

  http = Net::HTTP.new(uri.host, uri.port)
  request = Net::HTTP::Get.new(uri.request_uri)
  if (user and pass)
    request.basic_auth(user, pass)
  end
  response = http.request(request)
  return JSON.parse(response.body)["status"][type+"_status"]
end


  # when service_description in status("usv") push the values into the usv Array
  # after that push the usv Array into the latest Array <-- Problem 
  case status["service_description"]
  when "usv"
      usv.push({ cols: [
        { value: status['host_name'].to_json},
        { value: status['status'].to_json, class: 'icinga-status icinga-status-'+status['status'].downcase },
      ]})
      usv.push({ cols: [
        { value: status['service_description'].to_json, class: 'icinga-servicename' },
        { value: status['duration'].gsub(/^0d\s+(0h\s+)?/, ''), class: 'icinga-duration' }
      ]})
      latest.push({ cols:[
        { value: usv.to_json},
      ]})
  when "Disk Space"
      disk.push({ cols: [
        { value: status['host_name']},
        { value: status['status'], class: 'icinga-status icinga-status-'+status['status'].downcase },
      ]})
      disk.push({ cols: [
        { value: status['service_description'], class: 'icinga-servicename' },
        { value: status['duration'].gsub(/^0d\s+(0h\s+)?/, ''), class: 'icinga-duration' }
      ]})
  end

This is the output I get :

[{"cols":[{"value":"\"usv\""},{"value":"\OK"","class":"icinga-status icinga-status-ok"}]},{"cols":[{"value":"\"usv\"","class":"icinga-servicename"},{"value":"9h 47m 3s","class":"icinga-duration"}]}]

I got a Table widget. Displaying for example "E-Mail" then a check or a cross to see whether its down or up. Then the next entry Network same for that. Each of those Entries have different hosts in them for example for E-Mail POP3 Server and Lotus Server which all have different states Up/down, uptime, host_name and so on. So when one of those hosts has a problem it should display a cross in the list next to E-Mail if all states are ok it should be a check.

The question is how can I access the stuff in latest[usv]['host_name'] for example I am planning to display a list of the groups and check for any errors in the Up/down state and/or other problems for each group respectivly.

Thank you in advance Fabian

Felix
  • 4,510
  • 2
  • 31
  • 46
Fabian Fulde
  • 340
  • 3
  • 9
  • I am sorry but I didn't understand what you're asking. What are you exactly expecting to happen? – Surya Sep 19 '14 at 06:54
  • The output should be the group name in this case the Array "USV" or "Disk Space" which should be containing the values so I can check for example the Up/Down State of the Host. The question is just how can I access the stuff in latest[usv]['host_name'] for example I am planning to display a list of the groups and check for any errors in the Up/down state and/or other problems for each group respectivly – Fabian Fulde Sep 19 '14 at 06:59
  • Can you post the expected output in question for better understanding? – Surya Sep 19 '14 at 07:01
  • I am sorry but question is still a bit confusing to me. What do you mean by groups? And why are you doing `status['host_name'].to_json`? `status['host_name']` should be OK in your case as to_json adds extra quotes to the string. – Surya Sep 19 '14 at 07:09
  • OK here's the idea. I got a Table widget. Displaying for example "E-Mail" then a check or a cross to see whether its down or up. Then the next entry Network same for that. Each of those Entries have different hosts in them for example for E-Mail POP3 Server and Lotus Server which all have different states Up/down, uptime, host_name and so on. So when one of those hosts has a problem it should display a cross in the list next to E-Mail if all states are ok it should be a check. does that explain it? – Fabian Fulde Sep 19 '14 at 07:13
  • This is what you want ? `{'usv': ['hostname' : 'something', 'status': 'soemthing']}` – Pramod Solanky Sep 19 '14 at 07:19
  • latest is the array I give back to my table, I want to push the usv Array into the latest Array with the values of host_name, status still being in there so i can access them – Fabian Fulde Sep 19 '14 at 07:29
  • is this what you want: `latest = [{'usv': ['hostname' : 'something', 'status': 'soemthing']}, {'Disk Space': ['hostname' : 'something', 'status': 'soemthing']}]`? – Surya Sep 19 '14 at 07:31
  • Gives me a syntax error unexpected ':' and from what I assume this adds values to the array ? Do I really have to add them all again I mean they are already in the usv array I just want to put the usv array into the latest array so that the latest array has both the usv and the disk space array in it and I can display the host_name from the usv array and the disk space array afterwards – Fabian Fulde Sep 19 '14 at 07:48

2 Answers2

0

Maybe you can avoid case since you are repeating the same code in it.

groups = []

['usv', 'Disk Space'].each do |group|
  groups << { status['service_description'] => {
                host_name: status['host_name'],
                status: status['status'],
                status_class: "icinga-status icinga-status-#{status['status'].downcase}",
                service_description: status['service_description'],
                service_description_class: 'icinga-servicename',
                duration: status['duration'].gsub(/^0d\s+(0h\s+)?/, ''),
                duration_class: 'icinga-duration'
              }
            }
end

return groups.to_json

When you get the JSON on view, using jQuery you can display:

var response = $.parseJSON(response.responseText);
var response_html = "<thead> 
                      <tr>
                        <th> Host Name </th>
                        <th> Status </th>
                        <th> Service description </th>
                        <th> Duration </th>
                      </tr>
                    </thead>";
response_html +=  "<tbody>";

for (var i = 0; i < response.length; i++ ) {
  response_html +=  "<tr>";
  // Run upto 3. Since, there are 4 columns.
  for (var j = 0; j < 4; j++){
    response_html += "<td>" + response[i].host_name + "</td>";
    response_html += "<td class='" + response[i].status_class + "'>" + response[i].status + "</td>";
    response_html += "<td class='" + response[i].service_description_class + "'>" + response[i].service_description + "</td>";
    response_html += "<td class='" + response[i].duration_class + "'>" + response[i].duration + "</td>";
  }
  response_html += "</tr>";
}

response_html +=  "</tbody>";
$('table#services').html(response_html);
Surya
  • 15,703
  • 3
  • 51
  • 74
0

I reduced the code as much as I could and finally figured out what the status stands for...

require "net/https"
require "uri"


SCHEDULER.every '15s', :first_in => 0 do |job|

icinga_user = settings.icinga_user
icinga_pass = settings.icinga_pass

#host

uri = URI.parse("http://localhost/cgi-bin/icinga/status.cgi?style=hostdetail&nostatusheader&jsonoutput&sorttype=1&sortoption=6")

http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request.basic_auth(icinga_user, icinga_pass)
response = http.request(request)
    status = JSON.parse(response.body)["status"]["host_status"]

    rows = []

    status.each { |status|

    case status['host_name']
    when "usv"
    rows.push({ cols: [
      { value: status['host_name']}
    ]})
    end

}

send_event('icinga-hosts-latest', {
  rows: rows
  })
end
Conspicuous Compiler
  • 6,403
  • 1
  • 40
  • 52
Fabian Fulde
  • 340
  • 3
  • 9
  • Welcome to the site! [Please use Answers exclusively to answer the question](//meta.stackoverflow.com/q/92107). You should [edit] your original question to add additional information. – Mogsdad Apr 20 '16 at 22:07