<commit_before># -*- ruby -*-
#encoding: utf-8

require 'etc'

require 'arborist/node'
require 'arborist/mixins'


# A node type for Arborist trees that represent network-connected hosts.
#
#    host_node = Arborist::Node.create( :host, 'acme' ) do
#        description "Public-facing webserver"
#        address '172.16.31.10'
#
#        tags :public, :dmz
#
#        resource 'disk'
#        resource 'memory' do
#            config hwm: '3.4G'
#        end
#        resource 'loadavg'
#        resource 'processes' do
#            config expect: { nginx: 2 }
#        end
#
#        service 'ssh'
#        service 'www'
#
#    end
#
#
class Arborist::Node::Host < Arborist::Node
	include Arborist::NetworkUtilities

	### Create a new Host node.
	def initialize( identifier, attributes={}, &block )
		@addresses = []
		super
	end


	######
	public
	######

	##
	# The network address(es) of this Host as an Array of IPAddr objects
	attr_reader :addresses

	##
	# An optional hostname.
	dsl_accessor :hostname


	### Set one or more node +attributes+. Supported attributes (in addition to
	### those supported by Node) are: +addresses+.
	def modify( attributes )
		attributes = stringify_keys( attributes )

		super

		self.hostname( attributes['hostname'] ) if attributes[ 'hostname' ]
		if attributes[ 'addresses' ]
			self.addresses.clear
			Array( attributes['addresses'] ).each do |addr|
				self.address( addr )
			end
		end
	end


	### Return the host's operational attributes.
	def operational_values
		properties = super
		return properties.merge(
			hostname: @hostname,
			addresses: self.addresses.map(&:to_s)
		)
	end


	### Set an IP address of the host.
	def address( new_address )
		self.log.debug "Adding address %p to %p" % [ new_address, self ]

		if new_address =~ /^[[:alnum:]][a-z0-9\-]+/i && ! @hostname
			@hostname = new_address
		end

		@addresses += normalize_address( new_address )
		@addresses.uniq!
	end


	### Returns +true+ if the node matches the specified +key+ and +val+ criteria.
	def match_criteria?( key, val )
		return case key
			when 'hostname' then @hostname == val
			when 'address'
				search_addr = IPAddr.new( val )
				@addresses.any? {|a| search_addr.include?(a) }
			else
				super
			end
	end


	### Return host-node-specific information for #inspect.
	def node_description
		return "{no addresses}" if self.addresses.empty?
		return "{addresses: %s}" % [ self.addresses.map(&:to_s).join(', ') ]
	end


	#
	# Serialization
	#

	### Return a Hash of the host node's state.
	def to_h( * )
		return super.merge(
			hostname:  @hostname,
			addresses: self.addresses.map(&:to_s)
		)
	end


	### Marshal API -- set up the object's state using the +hash+ from a previously-marshalled
	### node. Overridden to turn the addresses back into IPAddr objects.
	def marshal_load( hash )
		super
		@addresses = hash[:addresses].map {|addr| IPAddr.new(addr) }
		@hostname = hash[:hostname]
	end


	### Equality operator -- returns +true+ if +other_node+ is equal to the
	### receiver. Overridden to also compare addresses.
	def ==( other_host )
		return super &&
			other_host.addresses == self.addresses &&
			other_host.hostname == @hostname
	end

end # class Arborist::Node::Host
<commit_msg>Shut up warnings about uninitialized instance vars<commit_after># -*- ruby -*-
#encoding: utf-8

require 'etc'

require 'arborist/node'
require 'arborist/mixins'


# A node type for Arborist trees that represent network-connected hosts.
#
#    host_node = Arborist::Node.create( :host, 'acme' ) do
#        description "Public-facing webserver"
#        address '172.16.31.10'
#
#        tags :public, :dmz
#
#        resource 'disk'
#        resource 'memory' do
#            config hwm: '3.4G'
#        end
#        resource 'loadavg'
#        resource 'processes' do
#            config expect: { nginx: 2 }
#        end
#
#        service 'ssh'
#        service 'www'
#
#    end
#
#
class Arborist::Node::Host < Arborist::Node
	include Arborist::NetworkUtilities

	### Create a new Host node.
	def initialize( identifier, attributes={}, &block )
		@addresses = []
		@hostname = nil
		super
	end


	######
	public
	######

	##
	# The network address(es) of this Host as an Array of IPAddr objects
	attr_reader :addresses

	##
	# An optional hostname.
	dsl_accessor :hostname


	### Set one or more node +attributes+. Supported attributes (in addition to
	### those supported by Node) are: +addresses+.
	def modify( attributes )
		attributes = stringify_keys( attributes )

		super

		self.hostname( attributes['hostname'] ) if attributes[ 'hostname' ]
		if attributes[ 'addresses' ]
			self.addresses.clear
			Array( attributes['addresses'] ).each do |addr|
				self.address( addr )
			end
		end
	end


	### Return the host's operational attributes.
	def operational_values
		properties = super
		return properties.merge(
			hostname: @hostname,
			addresses: self.addresses.map(&:to_s)
		)
	end


	### Set an IP address of the host.
	def address( new_address )
		self.log.debug "Adding address %p to %p" % [ new_address, self ]

		if new_address =~ /^[[:alnum:]][a-z0-9\-]+/i && ! @hostname
			@hostname = new_address
		end

		@addresses += normalize_address( new_address )
		@addresses.uniq!
	end


	### Returns +true+ if the node matches the specified +key+ and +val+ criteria.
	def match_criteria?( key, val )
		return case key
			when 'hostname' then @hostname == val
			when 'address'
				search_addr = IPAddr.new( val )
				@addresses.any? {|a| search_addr.include?(a) }
			else
				super
			end
	end


	### Return host-node-specific information for #inspect.
	def node_description
		return "{no addresses}" if self.addresses.empty?
		return "{addresses: %s}" % [ self.addresses.map(&:to_s).join(', ') ]
	end


	#
	# Serialization
	#

	### Return a Hash of the host node's state.
	def to_h( * )
		return super.merge(
			hostname:  @hostname,
			addresses: self.addresses.map(&:to_s)
		)
	end


	### Marshal API -- set up the object's state using the +hash+ from a previously-marshalled
	### node. Overridden to turn the addresses back into IPAddr objects.
	def marshal_load( hash )
		super
		@addresses = hash[:addresses].map {|addr| IPAddr.new(addr) }
		@hostname = hash[:hostname]
	end


	### Equality operator -- returns +true+ if +other_node+ is equal to the
	### receiver. Overridden to also compare addresses.
	def ==( other_host )
		return super &&
			other_host.addresses == self.addresses &&
			other_host.hostname == @hostname
	end

end # class Arborist::Node::Host

{'fraction_non_alphanumeric': 0.1276661040355992, 'fraction_numerical': 0.004603345097437471, 'mean_word_length': 3.2051612903225806, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3711352', 'n_tokens_mistral': 2330, 'n_tokens_neox': 2145, 'n_words': 642}