I had to put the code aside and just recently pulled it out again. Some/most of it is pretty ugly. I had quite a bit done though.
So here I am "refactoring" (and I use that term VERY VERY loosely) the code base. So I'm happily parsing away - iterating over the cfg_file/cfg_dir entries and build a nice big hash to hold all the object definitions. I dump it to a YAML file for validation when I notice this nice bit of junk in my timeperiod dump:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4: | |
- name: us-holidays | |
- timeperiod_name: us-holidays | |
- alias: U.S. Holidays | |
- january: 1 00:00-00:00 | |
- monday: -1 may 00:00-00:00 | |
- july: 4 00:00-00:00 | |
- monday: 1 september 00:00-00:00 | |
- thursday: -1 november 00:00-00:00 | |
- december: 25 00:00-00:00 |
Oh yeah...that looks right =/
For those who don't know, nagios object definitions are pretty straightforward. Here's an example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define host { | |
use linux-server | |
host_name oio | |
alias oio | |
address oio.mydomain.int | |
hostgroups webs | |
} |
Easy enough to parse, right? Object type named (host). A clear beginning and end denoted by curly braces. Object attributes in a seemingly key/value type markup. Some people smash the opening brace up against the object type definition but that's easily caught.
Iterating over the definition in Ruby is pretty straightforward (assuming a perfect example):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
objfile.each_line do |line| | |
if line =~ /^define/ | |
def_start, obj_type, open_brace = line.split | |
next | |
end | |
unless line =~ /\}/ | |
obj_param, obj_val =- line.split(nil,2) | |
# Do something | |
end | |
end |
december 25 00:00-00:00
Things can be even MORE complicated if I wanted to handle non-date holidays:
monday 1 september 00:00-00:00 ; Labor Day (first Monday in September)
thursday -1 november 00:00-00:00 ; Thanksgiving (last Thursday in November)
Ugly, no? I searched high and low for the ability to split starting from the right and didn't find anything native. I had to resort to implementing my own rsplit method for String:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class String | |
def rsplit(delim,count) | |
self.reverse.split(delim, count).map(&:reverse).reverse | |
end | |
end |
It works but I also can't use it across the board. If I do, I break things that were working (alias, service_description) that can have a space in the value.
I'm not even going to get into trying to convert timeperiod definitions into Date objects yet. That gives me cold sweats.