require 'rubygems' require 'uuidtools' module IClassify class Agent attr_accessor :node attr_accessor :uuid attr_accessor :password # # Create a new Agent. Takes a path to a file to either read or drop # a UUID, and a server URL. # def initialize(uuidfile="/etc/icagent/icagent.uuid", server_url="http://localhost:3000") @uuid = nil @password = nil if File.exists?(uuidfile) IO.foreach(uuidfile) do |line| @uuid, @password = line.chomp.split("!") end unless @password @password = random_password(30) write_uuidfile(uuidfile) end else @uuid = UUIDTools::UUID.random_create @password = random_password(30) write_uuidfile(uuidfile) end @client = IClassify::Client.new(server_url, @uuid, @password) end # # Loads data about this node from the iClassify service # def load begin @node = @client.get_node(@uuid) rescue Net::HTTPServerException => e if e.to_s =~ /^404/ @node = IClassify::Node.new() @node.description = "New Node" @node.tags << "unclassified" @node.password = @password @node.uuid = @uuid else throw(e) end end end # # Updates this node in the iClassify service. # def update if @node.description == "New Node" hostname = attrib?("hostname") hostname ||= "New Node" @node.description = hostname end @client.update_node(@node) end # # Deletes this node from the iClassify service. # def delete @client.delete_node(@node) end # # Returns the tag name if this node has that tag. # def tag?(tag) @node.tag?(tag) end # Returns the values for this attribute, if it exists for this node. If # there is only one, it will return it, if it's an array, you get the # array. You have to check! def attrib?(attrib) @node.attrib?(attrib) end # Returns the current node as a string. def to_s @node.to_s end # Returns the value if the given attribute has a given attribute. def attrib_has_value?(attrib, value) na = @node.attribs.detect { |a| a[:name] == attrib } if na return na.values.detect { |v| v == value} else return nil end end # Add a tag to this node. def add_tag(tag) load unless @node @node.tags << tag end # Add an attribute to this node. Requires a name and either a string or # array of values. # # Will be cumulative! def add_attrib(name, values) load unless @node @node.attribs << { :name => name, :values => values.kind_of?(Array) ? values : [ values ] } end # Replace the attribute with the given name's values in place. # Will add a new attribute if it needs to. def replace_attrib(name, values) exists = @node.attribs.detect { |a| a[:name] == name } if exists exists[:values] = values.kind_of?(Array) ? values : [ values ] else add_attrib(name, values) end end # Set the description for the node def description(value) @node.description = value end # return the value of @node.description def description?() @node.description end # Run an iclassify script. def run_script(scriptfile) eval(IO.read(scriptfile)) end protected def random_password(len) chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a newpass = "" 1.upto(len) { |i| newpass << chars[rand(chars.size-1)] } newpass end def write_uuidfile(uuidfile) File.open(uuidfile, "w") do |file| file.puts "#{@uuid}!#{@password}" end end end end