Fix Ruby Rake Style Errors When Running Code

I’m facing a few issues with this Ruby script I wrote for work. It’s supposed to check if certain network switches are up using Net::Ping and then send an email if any of them are down, but things aren’t working the way I expected.

Error Code:

code#!/usr/bin/env ruby
require 'net/ping'
require 'net/smtp'

# check if host is up
def up?(host)
check = Net::Ping::External.new(host)
check.ping?
end

# list of switches to check
switch_list = [
['A ', '192.168.1.1'],
['B ', '192.168.1.2'],
['C ', '192.168.1.3']
]

failed_switches = []

switch_list.each do |switch, ip|
puts "#{switch}" + up?(ip).to_s
failed_switches << [switch, ip] unless up?(ip)
end

failed_switches.each do |ip| unless failed_switches.empty?
puts "#{failed_switches}" + up?(ip).to_s + "\n"
end

# email the list of checked and failed switches
message = <<MESSAGE_END
From: abc@gmail.com
To: xyz@gmail.com
Subject: device down!

checked devices:
#{switch_list.map { |switch, ip| 'Device:' + switch + 'IP:' + ip }.join("\n") }

failed devices:
#{failed_switches.map { |switch, ip| 'Device:' + switch + 'IP:' + ip }.join("\n") }

MESSAGE_END
puts "#{message}"

next unless failed_switches.empty?
Net::SMTP.start('your mail server') do |smtp|
smtp.send_message message, 'xyz@gmail.com'
end
end

Solution:

We fixed the script by:

  1. Correcting syntax and block structure: Ensured proper each loop handling and logical flow.
  2. Adjusting the logic for failed switches: Used unless failed_switches.empty? to only send emails when needed.
  3. Improving message formatting: Used <<~ for cleaner multiline email messages.
  4. Clarifying output: Added readable status messages for better monitoring.
  5. Ensuring SMTP configuration: Included port number and corrected the email sending block.

These changes resolve logic errors, improve readability, and ensure smooth operation with correct email notifications.

Corrected Code:

code#!/usr/bin/env ruby
require 'net/ping'
require 'net/smtp'

# Check if the host is up
def up?(host)
check = Net::Ping::External.new(host)
check.ping?
end

# List of switches to check
switch_list = [
['A', '192.168.1.1'],
['B', '192.168.1.2'],
['C', '192.168.1.3']
]

failed_switches = []

# Check the status of each switch
switch_list.each do |switch, ip|
status = up?(ip)
puts "Switch: #{switch}, IP: #{ip}, Status: #{status ? 'Up' : 'Down'}"
failed_switches << [switch, ip] unless status
end

# If there are failed switches, display and send an email
unless failed_switches.empty?
puts "\nFailed Switches:"
failed_switches.each do |switch, ip|
puts "Switch: #{switch}, IP: #{ip} is down"
end

# Construct the email message
message = <<~MESSAGE_END
From: abc@gmail.com
To: xyz@gmail.com
Subject: Device(s) Down!

Checked Devices:
#{switch_list.map { |switch, ip| "Device: #{switch}, IP: #{ip}" }.join("\n")}

Failed Devices:
#{failed_switches.map { |switch, ip| "Device: #{switch}, IP: #{ip}" }.join("\n")}
MESSAGE_END

puts "\nEmail Message:\n#{message}"

# Send the email
Net::SMTP.start('your.mail.server', 25) do |smtp|
smtp.send_message(message, 'abc@gmail.com', 'xyz@gmail.com')
end
else
puts "\nAll devices are up!"
end

Explanation of the Changes:

  1. Proper Block Structure and Syntax Fixes:
    • In your original code, the logic inside failed_switches.each was misplaced. I moved the block to ensure it only runs if there are failed switches.
  2. Use of unless Instead of next for Logic Flow:
    • The next keyword was misplaced. We don’t need to skip the email block; instead, the block should only execute if there are failed switches.
  3. Email Formatting Improvements:
    • I used <<~MESSAGE_END for the email message to handle multiline strings better. This keeps the indentation clean.
  4. Clearer Status Messages:
    • Added more user-friendly puts outputs to indicate the status of each switch in a readable format.
  5. SMTP Setup:
    • Added port 25 to the SMTP start method. You may need to adjust it depending on your server’s configuration.
  6. Handling Edge Cases:
    • If no switches fail, the code will print a message: “All devices are up!” and skip sending the email.

Final Thought

This corrected version of the Ruby script ensures smooth functionality for monitoring network switches by checking their status and sending email alerts if any devices are down. Key improvements include proper syntax corrections, better logic flow, and more readable outputs. The addition of email formatting enhancements and clearer status messages makes the script more user-friendly.

Related blog posts