Class: ExternalNode
Overview
This class holds all the methods for creating and accessing the properties of an external node. There are really only two public methods: initialize and a special version of to_yaml
Direct Known Subclasses
Instance Attribute Summary collapse
-
#classes ⇒ Object
Make these instance variables get/set-able with eponymous methods.
-
#environment ⇒ Object
Make these instance variables get/set-able with eponymous methods.
-
#hostname ⇒ Object
Make these instance variables get/set-able with eponymous methods.
-
#parameters ⇒ Object
Make these instance variables get/set-able with eponymous methods.
Instance Method Summary collapse
-
#initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/', environmentdir = 'environment/') ⇒ ExternalNode
constructor
- initialize takes three arguments: hostname
- usually passed in via ARGV but it could be anything classdir
- directory under WORKINGDIR to look for files named after classes parameterdir
-
directory under WORKINGDIR to look for directories to set parameters.
-
#match_classes(fullpath) ⇒ Object
private method - takes a path to look for files, iterates through all readable, regular files it finds, and matches this instance’s @hostname against each line; if any match, the class will be set for this node.
-
#match_environment(fullpath) ⇒ Object
match_environment is similar to match_classes but it overwrites any previously set value (usually just the default, ‘production’) with a match.
-
#match_parameters(fullpath) ⇒ Object
Parameters are handled slightly differently; we make another level of directories to get the parameter name, then use the names of the files contained in there for the values of those parameters.
-
#matched_in_patternfile?(filepath, matchthis) ⇒ Boolean
Private method that expects an absolute path to a file and a string to match - it returns true if the string was matched by any of the lines in the file.
-
#parse_argv(hostname) ⇒ Object
private method called by initialize which sanity-checks our hostname.
-
#to_yaml ⇒ Object
to_yaml massages a copy of the object and outputs clean yaml so we don’t feed weird things back to puppet []<.
Constructor Details
#initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/', environmentdir = 'environment/') ⇒ ExternalNode
initialize takes three arguments:
- hostname
-
usually passed in via ARGV but it could be anything
- classdir
-
directory under WORKINGDIR to look for files named after
classes
- parameterdir
-
directory under WORKINGDIR to look for directories to set
parameters
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 90 def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/', environmentdir = 'environment/') # instance variables that contain the lists of classes and parameters @hostname @classes = Set.new @parameters = Hash.new("unknown") # sets a default value of "unknown" @environment = "production" self.parse_argv(hostname) self.match_classes("#{WORKINGDIR}/#{classdir}") self.match_parameters("#{WORKINGDIR}/#{parameterdir}") self.match_environment("#{WORKINGDIR}/#{environmentdir}") end |
Instance Attribute Details
#classes ⇒ Object
Make these instance variables get/set-able with eponymous methods
82 83 84 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 82 def classes @classes end |
#environment ⇒ Object
Make these instance variables get/set-able with eponymous methods
82 83 84 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 82 def environment @environment end |
#hostname ⇒ Object
Make these instance variables get/set-able with eponymous methods
82 83 84 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 82 def hostname @hostname end |
#parameters ⇒ Object
Make these instance variables get/set-able with eponymous methods
82 83 84 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 82 def parameters @parameters end |
Instance Method Details
#match_classes(fullpath) ⇒ Object
private method - takes a path to look for files, iterates through all readable, regular files it finds, and matches this instance’s @hostname against each line; if any match, the class will be set for this node.
176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 176 def match_classes(fullpath) Dir.foreach(fullpath) do |patternfile| filepath = "#{fullpath}/#{patternfile}" next unless File.file?(filepath) and File.readable?(filepath) next if patternfile =~ /^\./ log("Attempting to match [#{@hostname}] in [#{filepath}]") if matched_in_patternfile?(filepath,@hostname) @classes << patternfile.to_s log("Appended #{patternfile.to_s} to classes instance variable") end end end |
#match_environment(fullpath) ⇒ Object
match_environment is similar to match_classes but it overwrites any previously set value (usually just the default, ‘production’) with a match
193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 193 def match_environment(fullpath) Dir.foreach(fullpath) do |patternfile| filepath = "#{fullpath}/#{patternfile}" next unless File.file?(filepath) and File.readable?(filepath) next if patternfile =~ /^\./ log("Attempting to match [#{@hostname}] in [#{filepath}]") if matched_in_patternfile?(filepath,@hostname) @environment = patternfile.to_s log("Wrote #{patternfile.to_s} to environment instance variable") end end end |
#match_parameters(fullpath) ⇒ Object
Parameters are handled slightly differently; we make another level of directories to get the parameter name, then use the names of the files contained in there for the values of those parameters.
ex: cat ./parameters/service/production ^prodweb would set parameters = “production” for prodweb001
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 215 def match_parameters(fullpath) Dir.foreach(fullpath) do |parametername| filepath = "#{fullpath}/#{parametername}" next if File.basename(filepath) =~ /^\./ # skip over dotfiles next unless File.directory?(filepath) and File.readable?(filepath) # skip over non-directories log("Considering contents of #{filepath}") Dir.foreach("#{filepath}") do |patternfile| secondlevel = "#{filepath}/#{patternfile}" log("Found parameters patternfile at #{secondlevel}") next unless File.file?(secondlevel) and File.readable?(secondlevel) log("Attempting to match [#{@hostname}] in [#{secondlevel}]") if matched_in_patternfile?(secondlevel, @hostname) @parameters[ parametername.to_s ] = patternfile.to_s log("Set @parameters[#{parametername.to_s}] = #{patternfile.to_s}") end end end end |
#matched_in_patternfile?(filepath, matchthis) ⇒ Boolean
Private method that expects an absolute path to a file and a string to match - it returns true if the string was matched by any of the lines in the file
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 132 def matched_in_patternfile?(filepath, matchthis) patternlist = [] begin open(filepath).each { |l| l.chomp! next if l =~ /^$/ next if l =~ /^#/ if l =~ /^\s*(\S+)/ m = Regexp.last_match log("found a non-comment line, transforming [#{l}] into [#{m[1]}]") l.gsub!(l,m[1]) else next l end pattern = %r{#{l}} patternlist << pattern log("appending [#{pattern}] to patternlist for [#{filepath}]") } rescue StandardError log("Problem reading #{filepath}: #{$!}",:err) exit(1) end log("list of patterns for #{filepath}: #{patternlist}") if matchthis =~ Regexp.union(patternlist) log("matched #{$~.to_s} in #{matchthis}, returning true") return true else # hostname didn't match anything in patternlist log("#{matchthis} unmatched, returning false") return nil end end |
#parse_argv(hostname) ⇒ Object
private method called by initialize which sanity-checks our hostname. good candidate for overriding in a subclass if you need different checks
105 106 107 108 109 110 111 112 113 114 115 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 105 def parse_argv(hostname) if hostname =~ /^([-\w]+?)\.([-\w\.]+)/ # non-greedy up to the first . is hostname @hostname = $1 elsif hostname =~ /^([-\w]+)$/ # sometimes puppet's @name is just a name @hostname = hostname log("got shortname for [#{hostname}]") else log("didn't receive parsable hostname, got: [#{hostname}]",:err) exit(1) end end |
#to_yaml ⇒ Object
to_yaml massages a copy of the object and outputs clean yaml so we don’t feed weird things back to puppet []<
119 120 121 122 123 124 125 126 127 |
# File 'ext/regexp_nodes/regexp_nodes.rb', line 119 def to_yaml classes = self.classes.to_a if self.parameters.empty? # otherwise to_yaml prints "parameters: {}" parameters = nil else parameters = self.parameters end ({ 'classes' => classes, 'parameters' => parameters, 'environment' => environment}).to_yaml end |