class Arborist::Node::Service
A node type for Arborist
trees that represent services running on hosts.
Constants
- DEFAULT_PROTOCOL
The default transport layer protocol to use for services that don't specify one
Public Class Methods
Create a new Service
node.
Arborist::Node::new
# File lib/arborist/node/service.rb, line 28 def initialize( identifier, host, attributes={}, &block ) raise Arborist::NodeError, "no host given" unless host.is_a?( Arborist::Node::Host ) qualified_identifier = "%s-%s" % [ host.identifier, identifier ] @host = host @addresses = nil @app_protocol = nil @protocol = nil @port = nil attributes[ :app_protocol ] ||= identifier attributes[ :protocol ] ||= DEFAULT_PROTOCOL super( qualified_identifier, host, attributes, &block ) unless @port service_port = default_port_for( @app_protocol, @protocol ) or raise ArgumentError, "can't determine the port for %s/%s" % [ @app_protocol, @protocol ] @port = Integer( service_port ) end end
Public Instance Methods
Equality operator – returns true
if other_node
is equal to the receiver. Overridden to also compare addresses.
# File lib/arborist/node/service.rb, line 185 def ==( other_host ) return super && other_host.addresses == self.addresses && other_host.protocol == self.protocol && other_host.app_protocol == self.app_protocol && other_host.port == self.port end
Set an IP address of the service. This must be one of the addresses of its containing host.
# File lib/arborist/node/service.rb, line 90 def address( new_address ) self.log.debug "Adding address %p to %p" % [ new_address, self ] normalized_addresses = normalize_address( new_address ) unless normalized_addresses.all? {|addr| @host.addresses.include?(addr) } raise Arborist::ConfigError, "%s is not one of %s's addresses" % [ new_address, @host.identifier ] end @addresses ||= [] @addresses += normalized_addresses end
Delegate the service's address to its host.
# File lib/arborist/node/service.rb, line 105 def addresses return @addresses || @host.addresses end
Get/set the application protocol the service uses
# File lib/arborist/node/service.rb, line 62 dsl_accessor :app_protocol
Return the node family, so observers can know ancestry after serialization for custom node types that inherit from this class.
# File lib/arborist/node/service.rb, line 71 def family return :service end
Delegate the service's hostname to it's parent host.
# File lib/arborist/node/service.rb, line 111 def hostname return @host.hostname end
Returns true
if the node matches the specified key
and val
criteria.
Arborist::Node#match_criteria?
# File lib/arborist/node/service.rb, line 117 def match_criteria?( key, val ) self.log.debug "Matching %p: %p against %p" % [ key, val, self ] array_val = Array( val ) return case key when 'port' vals = array_val.collect do |port| port = default_port_for( port, @protocol ) unless port.is_a?( Integer ) port.to_i end vals.include?( self.port ) when 'address' search_addr = IPAddr.new( val ) self.addresses.any? {|a| search_addr.include?(a) } when 'protocol' then array_val.include?( self.protocol ) when 'app', 'app_protocol' then array_val.include?( self.app_protocol ) else super end end
Set service attributes
.
Arborist::Node#modify
# File lib/arborist/node/service.rb, line 77 def modify( attributes ) attributes = stringify_keys( attributes ) super self.port( attributes['port'] ) self.app_protocol( attributes['app_protocol'] ) self.protocol( attributes['protocol'] ) end
Return service-node-specific information for inspect
.
# File lib/arborist/node/service.rb, line 152 def node_description return "{listening on %s port %d}" % [ self.protocol, self.port, ] end
Return a Hash of the operational values that are included with the node's monitor state.
Arborist::Node#operational_values
# File lib/arborist/node/service.rb, line 140 def operational_values return super.merge( addresses: self.addresses.map( &:to_s ), hostname: self.hostname, port: self.port, protocol: self.protocol, app_protocol: self.app_protocol, ) end
Overridden to disallow modification of a Service's parent, as it needs a reference to the Host node for delegation.
Arborist::Node#parent
# File lib/arborist/node/service.rb, line 162 def parent( new_parent=nil ) return super unless new_parent raise "Can't reparent a service; replace the node instead" end
Get/set the port the service binds to
# File lib/arborist/node/service.rb, line 58 dsl_accessor :port
Get/set the network protocol the service uses
# File lib/arborist/node/service.rb, line 66 dsl_accessor :protocol
Return a Hash of the host node's state.
Arborist::Node#to_h
# File lib/arborist/node/service.rb, line 173 def to_h( ** ) return super.merge( addresses: self.addresses.map(&:to_s), protocol: self.protocol, app_protocol: self.app_protocol, port: self.port ) end
Private Instance Methods
Try to default the appropriate port based on the node's identifier
and protocol
. Raises a SocketError if the service port can't be looked up.
# File lib/arborist/node/service.rb, line 201 def default_port_for( identifier, protocol ) return Socket.getservbyname( identifier, protocol ) rescue SocketError return nil end