#!/usr/bin/env ruby require 'rubygems' require 'net/ping' require 'open3' require 'optparse' #CUSTOMIZATIONS HERE defaultFirmware = "4.5.5" #Default firmware version defaultRadioIP = "169.254.1.1" #Default IP of the radio to program defaultFTPIP = "169.254.1.10" #Default IP of the FTP server to provide firmware/config defaultSNMPString = "private" #Default factory read/write snmp string defaultPostSNMPString = "Canopyprivate" #Default read/write snmp string to set. defaultAdminPassword = "adminpass" #Default admin password for SSH. defaultePMPBaseConfig = "ePMPBaseConfig.json" defaultePMP300BaseConfig = "ePMPBaseConfigF300.json" def up?(host) check = Net::Ping::External.new(host) check.ping? end host = "" type = "" ftp = "" firmware = "" skipFirmware = false skipConfig = false snmpstring = "" baseConfig = "" useFirmware = "" firmwareWrites = 1 OptionParser.new do |opts| opts.banner = "Usage: ePMPDefaulterrewerite.rb [options]" opts.on("--ip ip", "Target IP address for provisioning.") do |ip| host = ip end opts.on("-t", "--type type", "Radio model. Supports 180/200/1G/190/300.") do |t| type = t end opts.on("--ftp ftp", "Target FTP address to pull files.") do |ftpopt| ftp = ftpopt end opts.on("--firmware firmware", "Version of firmware file name on FTP server. (e.g. 3.5.6)") do |firmopt| firmware = firmopt end opts.on("--skip-firmware", "Skip firmware update.") do skipFirmware = true end opts.on("--skip-config", "Skip configuration update.") do skipConfig = true end opts.on("--snmp-string snmp", "Read-write SNMP string.") do |snmpopt| snmpstring = snmpopt end opts.on("--firmware-writes writes", "How many times to write firmware to the device.") do |firmwrite| firmwareWrites = firmwrite.to_i end opts.on("-u", "Same as, and overrides, --snmp-string Canopyprivate") do snmpstring = defaultPostSNMPString end opts.on("-h", "--help", "Prints this help.") do puts opts exit end end.parse! if host == "" then host = defaultRadioIP end if type == "" then puts "Which radio to configure? (180/190/200/300/1G)" type = gets.chomp.downcase end if (type != "180") && (type != "200") && (type != "1g") && (type != "190") && (type != "300") then puts "Invalid radio to configure." exit end if ftp == "" then ftp = defaultFTPIP end if firmware == "" then firmware = defaultFirmware end if snmpstring == "" then snmpstring = defaultSNMPString end if (type == "300") then useFirmware = "ePMP-AC-v#{firmware}.img" baseConfig = defaultePMP300BaseConfig else useFirmware = "ePMP-NonGPS_Synced-v#{firmware}.tar.gz" baseConfig = defaultePMPBaseConfig end puts "Host: #{host}, Type: #{type}, FTP Server: #{ftp}, Firmware version: #{useFirmware}, Restoration template: #{baseConfig}" #Slowly pings and waits for the ePMP to fully start. Slightly iffy, so best to get the ePMP running first, then run the script. count = 0 while count <=3 do if (up?(host)) then count = count + 1 end sleep(1) end sleep(5) if !skipFirmware then firmwareCount = 0 while firmwareCount < firmwareWrites do puts "ePMP is connected. Sending firmware update command..." #Command uses SNMP to reach out to host and orders it to do an FTP firmware upgrade given the path in the last argument. `/usr/bin/snmpset -v 2c -c #{snmpstring} #{host} .1.3.6.1.4.1.17713.21.4.7.0 s ftp://#{ftp}/#{useFirmware}` #The following is teeter-tottering bullshit. The ePMPs respond to a triple-ping test before they restart network # services during boot. The best workaround is chained timers. The below has functioned since early firmware 3.x # so should be fairly reliable. sleep(240) count = 0 while count <=3 do if (up?(host)) then count = count + 1 end sleep(1) end sleep (10) puts "ePMP has restarted." firmwareCount += 1 end end if !skipConfig then puts "Sending config restore command..." #Use SNMP to tell host to restore from backup over FTP using the path in the last argument. `/usr/bin/snmpset -v 2c -c #{snmpstring} #{host} .1.3.6.1.4.1.17713.21.6.4.1.0 s ftp://#{ftp}/#{baseConfig}` #The ePMP takes two minutes to restart (generally speaking, it changes with every firmware version, if it's raining, and if the Patriots won the Super Bowl last year). sleep(240) puts "Beginning configuration commands..." #Opens a transparent TTY and SSH connection to the radio, then runs the commands below. Open3.popen3("/bin/sshpass -p #{defaultAdminPassword} /bin/ssh admin@#{host} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -oKexAlgorithms=+diffie-hellman-group14-sha1") do | input, output, error, wait_thr | input.sync = true output.sync = true begin sleep 1 input.puts "config set systemConfigDeviceName \"#{useFirmware}\"" sleep 1 #Commit changes to device (equivalent to the 'save' button in the WUI) input.puts "config commit" sleep 1 input.puts "reboot" sleep 1 input.puts "exit" rescue puts "Error commiting after-restoration commands." exit end end end puts "ePMP configuration complete!"