Module | MCollective::Util |
In: |
lib/mcollective/util.rb
|
Some basic utility helper methods useful to clients, agents, runner etc.
Picks a config file defaults to ~/.mcollective else /etc/mcollective/client.cfg
# File lib/mcollective/util.rb, line 124 124: def self.config_file_for_user 125: # expand_path is pretty lame, it relies on HOME environment 126: # which isnt't always there so just handling all exceptions 127: # here as cant find reverting to default 128: begin 129: config = File.expand_path("~/.mcollective") 130: 131: unless File.readable?(config) && File.file?(config) 132: config = "/etc/mcollective/client.cfg" 133: end 134: rescue Exception => e 135: config = "/etc/mcollective/client.cfg" 136: end 137: 138: return config 139: end
Creates a standard options hash
# File lib/mcollective/util.rb, line 142 142: def self.default_options 143: {:verbose => false, 144: :disctimeout => 2, 145: :timeout => 5, 146: :config => config_file_for_user, 147: :filter => empty_filter} 148: end
Creates an empty filter
# File lib/mcollective/util.rb, line 115 115: def self.empty_filter 116: {"fact" => [], 117: "cf_class" => [], 118: "agent" => [], 119: "identity" => []} 120: end
Checks if the passed in filter is an empty one
# File lib/mcollective/util.rb, line 110 110: def self.empty_filter?(filter) 111: filter == empty_filter || filter == {} 112: end
Gets the value of a specific fact, mostly just a duplicate of MCollective::Facts.get_fact but it kind of goes with the other classes here
# File lib/mcollective/util.rb, line 49 49: def self.get_fact(fact) 50: Facts.get_fact(fact) 51: end
Finds out if this MCollective has an agent by the name passed
If the passed name starts with a / it‘s assumed to be regex and will use regex to match
# File lib/mcollective/util.rb, line 8 8: def self.has_agent?(agent) 9: agent = Regexp.new(agent.gsub("\/", "")) if agent.match("^/") 10: 11: if agent.is_a?(Regexp) 12: if Agents.agentlist.grep(agent).size > 0 13: return true 14: else 15: return false 16: end 17: else 18: return Agents.agentlist.include?(agent) 19: end 20: 21: false 22: end
Checks if this node has a configuration management class by parsing the a text file with just a list of classes, recipes, roles etc. This is ala the classes.txt from puppet.
If the passed name starts with a / it‘s assumed to be regex and will use regex to match
# File lib/mcollective/util.rb, line 30 30: def self.has_cf_class?(klass) 31: klass = Regexp.new(klass.gsub("\/", "")) if klass.match("^/") 32: cfile = Config.instance.classesfile 33: 34: Log.debug("Looking for configuration management classes in #{cfile}") 35: 36: File.readlines(cfile).each do |k| 37: if klass.is_a?(Regexp) 38: return true if k.chomp.match(klass) 39: else 40: return true if k.chomp == klass 41: end 42: end 43: 44: false 45: end
Compares fact == value,
If the passed value starts with a / it‘s assumed to be regex and will use regex to match
# File lib/mcollective/util.rb, line 57 57: def self.has_fact?(fact, value, operator) 58: 59: Log.debug("Comparing #{fact} #{operator} #{value}") 60: Log.debug("where :fact = '#{fact}', :operator = '#{operator}', :value = '#{value}'") 61: 62: fact = Facts.get_fact(fact).clone 63: 64: if operator == '=~' 65: # to maintain backward compat we send the value 66: # as /.../ which is what 1.0.x needed. this strips 67: # off the /'s wich is what we need here 68: if value =~ /^\/(.+)\/$/ 69: value = $1 70: end 71: 72: return true if fact.match(Regexp.new(value)) 73: 74: elsif operator == "==" 75: return true if fact == value 76: 77: elsif ['<=', '>=', '<', '>', '!='].include?(operator) 78: # Yuk - need to type cast, but to_i and to_f are overzealous 79: if value =~ /^[0-9]+$/ && fact =~ /^[0-9]+$/ 80: fact = Integer(fact) 81: value = Integer(value) 82: elsif value =~ /^[0-9]+.[0-9]+$/ && fact =~ /^[0-9]+.[0-9]+$/ 83: fact = Float(fact) 84: value = Float(value) 85: end 86: 87: return true if eval("fact #{operator} value") 88: end 89: 90: false 91: end
Checks if the configured identity matches the one supplied
If the passed name starts with a / it‘s assumed to be regex and will use regex to match
# File lib/mcollective/util.rb, line 97 97: def self.has_identity?(identity) 98: identity = Regexp.new(identity.gsub("\/", "")) if identity.match("^/") 99: 100: if identity.is_a?(Regexp) 101: return Config.instance.identity.match(identity) 102: else 103: return true if Config.instance.identity == identity 104: end 105: 106: false 107: end
Wrapper around PluginManager.loadclass
# File lib/mcollective/util.rb, line 160 160: def self.loadclass(klass) 161: PluginManager.loadclass(klass) 162: end
Constructs the full target name based on topicprefix and topicsep config options
# File lib/mcollective/util.rb, line 151 151: def self.make_target(agent, type) 152: config = Config.instance 153: 154: raise("Uknown target type #{type}") unless type == :command || type == :reply 155: 156: [config.topicprefix, agent, type].join(config.topicsep) 157: end
Parse a fact filter string like foo=bar into the tuple hash thats needed
# File lib/mcollective/util.rb, line 165 165: def self.parse_fact_string(fact) 166: if fact =~ /^([^ ]+?)[ ]*=>[ ]*(.+)/ 167: return {:fact => $1, :value => $2, :operator => '>=' } 168: elsif fact =~ /^([^ ]+?)[ ]*=<[ ]*(.+)/ 169: return {:fact => $1, :value => $2, :operator => '<=' } 170: elsif fact =~ /^([^ ]+?)[ ]*(<=|>=|<|>|!=|==|=~)[ ]*(.+)/ 171: return {:fact => $1, :value => $3, :operator => $2 } 172: elsif fact =~ /^(.+?)[ ]*=[ ]*\/(.+)\/$/ 173: return {:fact => $1, :value => "/#{$2}/", :operator => '=~' } 174: elsif fact =~ /^([^= ]+?)[ ]*=[ ]*(.+)/ 175: return {:fact => $1, :value => $2, :operator => '==' } 176: end 177: 178: return false 179: end