Class: Iqeo::Hostspec::Hostspec
- Inherits:
-
Object
- Object
- Iqeo::Hostspec::Hostspec
- Includes:
- Enumerable
- Defined in:
- lib/iqeo/hostspec/hostspec.rb
Instance Attribute Summary collapse
-
#address_spec ⇒ Object
readonly
Returns the value of attribute address_spec.
-
#hostname ⇒ Object
readonly
Returns the value of attribute hostname.
-
#mask ⇒ Object
readonly
Returns the value of attribute mask.
-
#mask_length ⇒ Object
readonly
Returns the value of attribute mask_length.
-
#string ⇒ Object
readonly
Returns the value of attribute string.
Instance Method Summary collapse
- #check_octet_value(str) ⇒ Object
- #each_address ⇒ Object (also: #each)
-
#initialize(spec_str) ⇒ Hostspec
constructor
A new instance of Hostspec.
- #last ⇒ Object
- #mask_address_spec ⇒ Object
- #max ⇒ Object
- #min ⇒ Object
- #minmax ⇒ Object
- #parse_address_spec(str) ⇒ Object
- #parse_hostname(str) ⇒ Object
- #parse_mask(str) ⇒ Object
- #parse_octet(str) ⇒ Object
- #parse_octet_value(str) ⇒ Object
- #recursively_iterate_octets(octet_index = 0, address = [], &block) ⇒ Object
- #size ⇒ Object
- #split_on_slash(str) ⇒ Object
Constructor Details
#initialize(spec_str) ⇒ Hostspec
Returns a new instance of Hostspec.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 14 def initialize spec_str @string = spec_str raise HostspecException, 'spec cannot be empty' if spec_str.empty? host_str, mask_str = split_on_slash spec_str raise HostspecException, 'host cannot be empty' if host_str.empty? parse_mask mask_str begin parse_address_spec host_str rescue HostspecException parse_hostname host_str end raise HostspecException, 'complex spec cannot have mask length' if @mask_specified && @address_spec.any? { |octet| octet.size > 1 } mask_address_spec end |
Instance Attribute Details
#address_spec ⇒ Object (readonly)
Returns the value of attribute address_spec.
12 13 14 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 12 def address_spec @address_spec end |
#hostname ⇒ Object (readonly)
Returns the value of attribute hostname.
12 13 14 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 12 def hostname @hostname end |
#mask ⇒ Object (readonly)
Returns the value of attribute mask.
12 13 14 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 12 def mask @mask end |
#mask_length ⇒ Object (readonly)
Returns the value of attribute mask_length.
12 13 14 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 12 def mask_length @mask_length end |
#string ⇒ Object (readonly)
Returns the value of attribute string.
12 13 14 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 12 def string @string end |
Instance Method Details
#check_octet_value(str) ⇒ Object
111 112 113 114 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 111 def check_octet_value str match = str.match /^(25[0-5]|2[0-4]\d|[0-1]\d\d|\d\d|\d)$/ raise HostspecException, "bad ip, octet value is not a number in 0-255: #{str}" unless match end |
#each_address ⇒ Object Also known as: each
137 138 139 140 141 142 143 144 145 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 137 def each_address if block_given? recursively_iterate_octets do |address_str| yield address_str end else return to_enum( :each_address ) { size } end end |
#last ⇒ Object
161 162 163 164 165 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 161 def last address = nil each { |addr| address = addr } address end |
#mask_address_spec ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 55 def mask_address_spec @address_spec.each_with_index do |octet,index| high_bit_position = ( index * 8 ) + 1 low_bit_position = ( index + 1 ) * 8 @address_spec[index] = case when @mask_length >= low_bit_position then octet when @mask_length < high_bit_position then [0..255] else octet_mask_length = @mask_length % 8 octet_mask = ( ( 2 ** octet_mask_length ) - 1 ) << ( 8 - octet_mask_length ) octet_mask_inverted = octet_mask ^ 255 octet_min = octet_mask & octet[0] octet_max = octet_min | octet_mask_inverted [octet_min..octet_max] end end end |
#max ⇒ Object
167 168 169 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 167 def max last end |
#min ⇒ Object
157 158 159 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 157 def min first end |
#minmax ⇒ Object
171 172 173 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 171 def minmax [first,last] end |
#parse_address_spec(str) ⇒ Object
73 74 75 76 77 78 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 73 def parse_address_spec str octet_strs = str.split '.' raise HostspecException, 'bad ip, expected 4 octets' unless octet_strs.size == 4 octets = octet_strs.collect { |octet_str| parse_octet octet_str } @address_spec = octets end |
#parse_hostname(str) ⇒ Object
116 117 118 119 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 116 def parse_hostname str @hostname = str parse_address_spec Resolv.getaddress(str) end |
#parse_mask(str) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 37 def parse_mask str if str.empty? @mask = '255.255.255.255' @mask_length = 32 @mask_specified = false return end if match = str.match( /^\d+$/ ) @mask_length = match[0].to_i raise "bad mask length (#{@mask_length}), expected between 0 ad 32" unless @mask_length.between? 0,32 mask_int = ((2**@mask_length)-1) << (32-@mask_length) @mask = [24,16,8,0].collect { |n| ( mask_int & ( 255 << n ) ) >> n }.join '.' @mask_specified = true else raise "bad format, expected mask length after '/'" end end |
#parse_octet(str) ⇒ Object
80 81 82 83 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 80 def parse_octet str values = str.split ',' values.collect { |value_str| parse_octet_value value_str } end |
#parse_octet_value(str) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 85 def parse_octet_value str # values may be dash denoted ranges, possibilities... # n : just a number : 'n'.split '-' == ['n'] <= same = problem! 'n'.split '-', -1 == [ "n" ] # n-m : range from n to m : 'n-m'.split '-' == ['n','m'] 'n-m'.split '-', -1 == [ "n" , "m" ] # n- : range from n to 255 : 'n-'.split '-' == ['n'] <= same = problem! 'n-'.split '-', -1 == [ "n" , "" ] # -m : range from 0 to m : '-m'.split '-' == ['','m'] '-m'.split '-', -1 == [ "" , "m" ] # - : range from 0 to 255 : '-'.split '-' == [] '-'.split '-', -1 == [ "" , "" ] numbers = str.split '-', -1 # maximize return fields to distinguish 'n' from '-m' case numbers.size when 1 then check_octet_value numbers[0] numbers[0].to_i when 2 then numbers[0] = '0' if numbers[0].empty? numbers[1] = '255' if numbers[1].empty? check_octet_value numbers[0] check_octet_value numbers[1] range_start = numbers[0].to_i range_finish = numbers[1].to_i raise HostspecException, "bad ip, reversed range in octet value: #{str}" if range_start > range_finish range_start..range_finish else raise HostspecException, "bad ip, invalid octet value: #{str}" end end |
#recursively_iterate_octets(octet_index = 0, address = [], &block) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 121 def recursively_iterate_octets octet_index = 0, address = [], &block @address_spec[octet_index].each do |item| if item.respond_to? :each item.each do |value| address.push value octet_index == 3 ? yield( address.join '.' ) : recursively_iterate_octets( octet_index + 1, address, &block ) address.pop end else address.push item octet_index == 3 ? yield( address.join '.' ) : recursively_iterate_octets( octet_index + 1, address, &block ) address.pop end end end |
#size ⇒ Object
149 150 151 152 153 154 155 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 149 def size if @mask_length == 32 @address_spec.inject(1) { |oc,o| oc * o.inject(0) { |vc,v| vc + ( v.respond_to?(:each) ? v.size : 1 ) } } else 2**(32-@mask_length) end end |
#split_on_slash(str) ⇒ Object
29 30 31 32 33 34 35 |
# File 'lib/iqeo/hostspec/hostspec.rb', line 29 def split_on_slash str case str.count '/' when 0 then [ str.strip, '' ] when 1 then str.strip.split '/' else raise 'bad format, expected 0 or 1 "/"' end end |