Class: JSS::NetworkSegment
- Defined in:
- lib/jss/api_object/network_segment.rb,
lib/jss.rb
Overview
A Network Segment in the JSS
Constant Summary collapse
- RSRC_BASE =
the REST resource base
'networksegments'.freeze
- RSRC_LIST_KEY =
the hash key used for the JSON list output of all objects in the JSS
:network_segments
- RSRC_OBJECT_KEY =
The hash key used for the JSON object output. It's also used in various error messages
:network_segment
- OBJECT_HISTORY_OBJECT_TYPE =
the object type for this object in the object history table. See APIObject#add_object_history_entry
43
Instance Attribute Summary collapse
-
#building ⇒ String
Building for this segment.
-
#department ⇒ String
Department for this segment.
-
#distribution_point ⇒ String
The name of the distribution point to be used from this network segment.
-
#ending_address ⇒ IPAddr
Ending IP adresss.
-
#need_to_update ⇒ Boolean
included
from Updatable
readonly
Do we have unsaved changes?.
-
#netboot_server ⇒ String
The netboot server for this segment.
-
#override_buildings ⇒ Boolean
Should machines checking in from this segment update their building.
-
#override_departments ⇒ Boolean
Should machines checking in from this segment update their dept.
-
#starting_address ⇒ IPAddr
Starting IP adresss.
-
#swu_server ⇒ String
The swupdate server for this segment.
-
#url ⇒ String
readonly
The mount url for the distribution point.
Class Method Summary collapse
-
.ip_range(starting_address: nil, ending_address: nil, mask: nil, cidr: nil) ⇒ Range<IPAddr>
Given a starting address & ending address, mask, or cidr, return a Range object of IPAddr objects.
-
.ip_range_width(ip1, ip2) ⇒ Object
given 2 IPAddr instances, find out how 'wide' they are - how many IP addresses exist between them.
-
.masked_starting_address(starting_address: nil, mask: nil, cidr: nil) ⇒ String
If we are given a mask or cidr, append them to the starting_address.
-
.my_network_segment(refresh = false, name: false, api: JSS.api) ⇒ Integer, ...
Which network segment is seen as current? According to the Jamf Pro Admin Guide, the 'smallest' one - the one with fewest IP addrs within it.
-
.my_network_segments(refresh = false, names: false, api: JSS.api) ⇒ Array<Integer>, Array<String>
Find the current network segment ids for the machine running this code.
-
.network_ranges(refresh = false, api: JSS.api) ⇒ Hash{Integer => Range}
All NetworkSegments in the given API as ruby Ranges of IPAddr instances representing the Segment, e.g.
-
.network_ranges_as_integers(refresh = false, api: JSS.api) ⇒ Hash{Integer => Range}
An IPv4 Address is really just a 32-bit integer, displayed as four 8-bit integers.
-
.network_segment_for_ip(ipaddr, refresh: false, api: JSS.api) ⇒ Integer?
Which network segment is seen as current for a given IP addr?.
-
.network_segments_for_ip(ipaddr, refresh = false, api: JSS.api) ⇒ Array<Integer>
Find the ids of the network segments that contain a given IP address.
-
.subnets(refresh = false, api: JSS.api) ⇒ Object
An alias for NetworkSegment.network_ranges.
-
.validate_ip_range(startip, endip) ⇒ void
Raise an exception if a given starting ip is higher than a given ending ip.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Does this network segment equal another? equality means the ranges are equal.
-
#cidr=(newval) ⇒ void
(also: #mask=)
set the ending address by applying a new cidr (e.g. 24) or mask (e.g. 255.255.255.0).
-
#clone(new_name, api: nil) ⇒ APIObject
included
from Creatable
make a clone of this API object, with a new name.
-
#create ⇒ Integer
included
from Creatable
Create a new object in the JSS.
-
#include?(thing) ⇒ Boolean
(also: #cover?)
Does this network segment include an address or another segment? Inclusion means the other is completely inside this one.
-
#initialize(args = {}) ⇒ NetworkSegment
constructor
Instantiate a NetworkSegment.
-
#name=(newname) ⇒ void
included
from Updatable
Change the name of this item Remember to #update to push changes to the server.
-
#overlap?(other_segment) ⇒ Boolean
Does this network segment overlap with another?.
-
#range ⇒ Range<IPAddr>
(also: #to_range)
a Range built from the start and end addresses.
-
#set_ip_range(starting_address: nil, ending_address: nil, mask: nil, cidr: nil) ⇒ void
set a new starting and ending addr at the same time.
-
#update ⇒ Boolean
included
from Updatable
Save changes to the JSS.
Constructor Details
#initialize(args = {}) ⇒ NetworkSegment
Instantiate a NetworkSegment
addresses can be provided when using id: :new
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
# File 'lib/jss/api_object/network_segment.rb', line 377 def initialize(args = {}) super args if args[:id] == :new range = self.class.ip_range( starting_address: args[:starting_address], ending_address: args[:ending_address], mask: args[:mask], cidr: args[:cidr] ) @init_data[:starting_address] = range.begin.to_s @init_data[:ending_address] = range.end.to_s end @starting_address = IPAddr.new @init_data[:starting_address] @ending_address = IPAddr.new @init_data[:ending_address] @building = @init_data[:building] @department = @init_data[:department] @distribution_point = @init_data[:distribution_point] @netboot_server = @init_data[:netboot_server] @override_buildings = @init_data[:override_buildings] @override_departments = @init_data[:override_departments] @swu_server = @init_data[:swu_server] @url = @init_data[:url] end |
Instance Attribute Details
#building ⇒ String
Returns building for this segment. Must be one of the buildings in the JSS.
349 350 351 |
# File 'lib/jss/api_object/network_segment.rb', line 349 def building @building end |
#department ⇒ String
Returns department for this segment. Must be one of the depts in the JSS.
352 353 354 |
# File 'lib/jss/api_object/network_segment.rb', line 352 def department @department end |
#distribution_point ⇒ String
Returns the name of the distribution point to be used from this network segment.
355 356 357 |
# File 'lib/jss/api_object/network_segment.rb', line 355 def distribution_point @distribution_point end |
#ending_address ⇒ IPAddr
Returns ending IP adresss.
346 347 348 |
# File 'lib/jss/api_object/network_segment.rb', line 346 def ending_address @ending_address end |
#need_to_update ⇒ Boolean (readonly) Originally defined in module Updatable
Returns do we have unsaved changes?.
#netboot_server ⇒ String
Returns the netboot server for this segment.
361 362 363 |
# File 'lib/jss/api_object/network_segment.rb', line 361 def netboot_server @netboot_server end |
#override_buildings ⇒ Boolean
Returns should machines checking in from this segment update their building.
370 371 372 |
# File 'lib/jss/api_object/network_segment.rb', line 370 def override_buildings @override_buildings end |
#override_departments ⇒ Boolean
Returns should machines checking in from this segment update their dept.
367 368 369 |
# File 'lib/jss/api_object/network_segment.rb', line 367 def override_departments @override_departments end |
#starting_address ⇒ IPAddr
Returns starting IP adresss.
343 344 345 |
# File 'lib/jss/api_object/network_segment.rb', line 343 def starting_address @starting_address end |
#swu_server ⇒ String
Returns the swupdate server for this segment.
364 365 366 |
# File 'lib/jss/api_object/network_segment.rb', line 364 def swu_server @swu_server end |
#url ⇒ String (readonly)
Returns the mount url for the distribution point.
358 359 360 |
# File 'lib/jss/api_object/network_segment.rb', line 358 def url @url end |
Class Method Details
.ip_range(starting_address: nil, ending_address: nil, mask: nil, cidr: nil) ⇒ Range<IPAddr>
Given a starting address & ending address, mask, or cidr, return a Range object of IPAddr objects.
starting_address: must be provided, and may be a masked address, in which case nothing else is needed.
If starting_address: is an unmasked address, then one of ending_address: cidr: or mask: must be provided.
If given, ending_address: overrides mask:, cidr:, and a masked starting_address:
These give the same result:
ip_range starting_address: '192.168.1.0', ending_address: '192.168.1.255' ip_range starting_address: '192.168.1.0', mask: '255.255.255.0' ip_range starting_address: '192.168.1.0', cidr: 24 ip_range starting_address: '192.168.1.0/24' ip_range starting_address: '192.168.1.0/255.255.255.0'
All the above will produce:
#<IPAddr: IPv4:192.168.1.0/255.255.255.255>..#<IPAddr: IPv4:192.168.1.255/255.255.255.255>
An exception is raised if the starting address is above the ending address.
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/jss/api_object/network_segment.rb', line 183 def self.ip_range(starting_address: nil, ending_address: nil, mask: nil, cidr: nil) raise JSS::MissingDataError, 'starting_address: must be provided' unless starting_address starting_address = masked_starting_address(starting_address: starting_address, mask: mask, cidr: cidr) if ending_address startip = IPAddr.new starting_address.split('/').first endip = IPAddr.new ending_address.to_s validate_ip_range(startip, endip) else raise ArgumentError, 'Must provide ending_address:, mask:, cidr: or a masked starting_address:' unless starting_address.include? '/' subnet = IPAddr.new starting_address startip = subnet.to_range.first.mask 32 endip = subnet.to_range.last.mask 32 end startip..endip end |
.ip_range_width(ip1, ip2) ⇒ Object
given 2 IPAddr instances, find out how 'wide' they are - how many IP addresses exist between them.
298 299 300 301 302 303 |
# File 'lib/jss/api_object/network_segment.rb', line 298 def self.ip_range_width(ip1, ip2) raise ArgumentError, 'Parameters must be IPAddr objects' unless ip1.is_a?(IPAddr) && ip2.is_a?(IPAddr) low, high = [ip1, ip2].sort high.to_i - low.to_i end |
.masked_starting_address(starting_address: nil, mask: nil, cidr: nil) ⇒ String
If we are given a mask or cidr, append them to the starting_address
214 215 216 217 |
# File 'lib/jss/api_object/network_segment.rb', line 214 def self.masked_starting_address(starting_address: nil, mask: nil, cidr: nil) starting_address = "#{starting}/#{mask || cidr}" if mask || cidr starting_address.to_s end |
.my_network_segment(refresh = false, name: false, api: JSS.api) ⇒ Integer, ...
Which network segment is seen as current? According to the Jamf Pro Admin Guide, the 'smallest' one - the one with fewest IP addrs within it. If multiple ones have the same number of IPs, then its the one with the lowest starting address
329 330 331 332 333 334 335 336 337 |
# File 'lib/jss/api_object/network_segment.rb', line 329 def self.my_network_segment(refresh = false, name: false, api: JSS.api) my_ip = JSS::Client.my_ip_address return nil unless my_ip id = network_segment_for_ip(my_ip, refresh: refresh, api: api) return id unless name map_all_ids_to(:name)[id] end |
.my_network_segments(refresh = false, names: false, api: JSS.api) ⇒ Array<Integer>, Array<String>
Find the current network segment ids for the machine running this code
See my_network_segment to get the current one according to the server.
313 314 315 316 317 318 319 |
# File 'lib/jss/api_object/network_segment.rb', line 313 def self.my_network_segments(refresh = false, names: false, api: JSS.api) ids = network_segments_for_ip JSS::Client.my_ip_address, refresh, api: api return ids unless names ids_to_names = map_all_ids_to :name ids.map { |id| ids_to_names[id] } end |
.network_ranges(refresh = false, api: JSS.api) ⇒ Hash{Integer => Range}
All NetworkSegments in the given API as ruby Ranges of IPAddr instances representing the Segment, e.g. with starting = 10.24.9.1 and ending = 10.24.15.254 the range looks like:
<IPAddr: IPv4:10.24.9.1/255.255.255.255>
..
<IPAddr: IPv4:10.24.15.254/255.255.255.255>
Using the #include? method on those Ranges is very useful.
Note1: We don't use the IPAddr#to_range method because that works
best for masked IPAddrs (which are ranges of IPs with widths
determined by the mask) and Jamf Network Segments can have arbitrary
widths.
Note2: See the network_ranges_as_integers method below, which is similar
but much faster.
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/jss/api_object/network_segment.rb', line 95 def self.network_ranges(refresh = false, api: JSS.api) @network_ranges = nil if refresh return @network_ranges if @network_ranges @network_ranges = {} all(refresh, api: api).each do |ns| @network_ranges[ns[:id]] = IPAddr.new(ns[:starting_address])..IPAddr.new(ns[:ending_address]) end @network_ranges end |
.network_ranges_as_integers(refresh = false, api: JSS.api) ⇒ Hash{Integer => Range}
An IPv4 Address is really just a 32-bit integer, displayed as four 8-bit integers. e.g. '10.0.69.1' is really the integer 167789825 The #to_i method of IPAddr objects returns that integer (or the first of them if the IPAddr is masked).
Using ranges made of those integers is far faster than using ranges if IPAddr objects, so that's what this method returns.
See also: the network_ranges method above
123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/jss/api_object/network_segment.rb', line 123 def self.network_ranges_as_integers(refresh = false, api: JSS.api) @network_ranges_as_integers = nil if refresh return @network_ranges_as_integers if @network_ranges_as_integers @network_ranges_as_integers = {} all(refresh, api: api).each do |ns| first = IPAddr.new(ns[:starting_address]).to_i last = IPAddr.new(ns[:ending_address]).to_i @network_ranges_as_integers[ns[:id]] = first..last end @network_ranges_as_integers end |
.network_segment_for_ip(ipaddr, refresh: false, api: JSS.api) ⇒ Integer?
Which network segment is seen as current for a given IP addr?
According to the Jamf Pro Admin Guide, if an IP is in more than one network segment, it uses the 'smallest' (narrowest) one - the one with fewest IP addrs within it.
If multiple ones have the same width, then it uses the one of those with the lowest starting address
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/jss/api_object/network_segment.rb', line 265 def self.network_segment_for_ip(ipaddr, refresh: false, api: JSS.api) # get the ip as a 32bit interger ip = IPAddr.new(ipaddr.to_s).to_i # a hash of NetSeg ids => Range<Integer> ranges = network_ranges_as_integers(refresh, api: api).select { |_id, range| range.include? ip } # we got nuttin return nil if ranges.empty? # if we got only one, its the one return ranges.keys.first if ranges.size == 1 # got more than one, sort by range size/width, asc. sorted_by_size = ranges.sort_by { |_i, r| r.size }.to_h # the first one is the smallest/narrowest. _smallest_range_id, smallest_range = sorted_by_size.first smallest_range_size = smallest_range.size # select all of them that are the same size all_of_small_size = sorted_by_size.select { |_i, r| r.size == smallest_range_size } # sort them by the start of each range (r.first) # and return the lowest start (returned by min_by) my_range_id, _my_range = all_of_small_size.min_by { |_i, r| r.first } # and return the id my_range_id end |
.network_segments_for_ip(ipaddr, refresh = false, api: JSS.api) ⇒ Array<Integer>
Find the ids of the network segments that contain a given IP address.
Even tho IPAddr.include? will take a String or an IPAddr I convert the ip to an IPAddr so that an exception will be raised if the ip isn't a valid ip.
247 248 249 250 251 252 |
# File 'lib/jss/api_object/network_segment.rb', line 247 def self.network_segments_for_ip(ipaddr, refresh = false, api: JSS.api) # get the ip as a 32bit interger ip = IPAddr.new(ipaddr.to_s).to_i # a hash of NetSeg ids => Range<Integer> network_ranges_as_integers(refresh, api: api).select { |_id, range| range.include? ip }.keys end |
.subnets(refresh = false, api: JSS.api) ⇒ Object
An alias for network_ranges
DEPRECATED: This will be going away in a future release.
142 143 144 |
# File 'lib/jss/api_object/network_segment.rb', line 142 def self.subnets(refresh = false, api: JSS.api) network_ranges refresh, api: api end |
.validate_ip_range(startip, endip) ⇒ void
This method returns an undefined value.
Raise an exception if a given starting ip is higher than a given ending ip
227 228 229 230 231 |
# File 'lib/jss/api_object/network_segment.rb', line 227 def self.validate_ip_range(startip, endip) return nil if IPAddr.new(startip.to_s) <= IPAddr.new(endip.to_s) raise JSS::InvalidDataError, "Starting IP #{startip} is higher than ending ip #{endip} " end |
Instance Method Details
#==(other) ⇒ Boolean
Does this network segment equal another? equality means the ranges are equal
450 451 452 453 454 |
# File 'lib/jss/api_object/network_segment.rb', line 450 def ==(other) raise TypeError, 'Argument must be a JSS::NetworkSegment' unless \ other.is_a? JSS::NetworkSegment range == other.range end |
#cidr=(newval) ⇒ void Also known as: mask=
This method returns an undefined value.
set the ending address by applying a new cidr (e.g. 24) or mask (e.g. 255.255.255.0)
616 617 618 619 620 621 |
# File 'lib/jss/api_object/network_segment.rb', line 616 def cidr=(newval) new_end = IPAddr.new("#{@starting_address}/#{newval}").to_range.end.mask 32 self.class.validate_ip_range(@starting_address, new_end) @ending_address = new_end @need_to_update = true end |
#clone(new_name, api: nil) ⇒ APIObject Originally defined in module Creatable
make a clone of this API object, with a new name. The class must be creatable
#create ⇒ Integer Originally defined in module Creatable
Create a new object in the JSS.
#include?(thing) ⇒ Boolean Also known as: cover?
Does this network segment include an address or another segment? Inclusion means the other is completely inside this one.
433 434 435 436 437 438 439 440 |
# File 'lib/jss/api_object/network_segment.rb', line 433 def include?(thing) if thing.is_a? JSS::NetworkSegment @starting_address <= thing.range.begin && @ending_address >= thing.range.end else thing = IPAddr.new thing.to_s range.cover? thing end end |
#name=(newname) ⇒ void Originally defined in module Updatable
This method returns an undefined value.
Change the name of this item Remember to #update to push changes to the server.
#overlap?(other_segment) ⇒ Boolean
Does this network segment overlap with another?
419 420 421 422 423 424 |
# File 'lib/jss/api_object/network_segment.rb', line 419 def overlap?(other_segment) raise TypeError, 'Argument must be a JSS::NetworkSegment' unless \ other_segment.is_a? JSS::NetworkSegment other_range = other_segment.range range.include?(other_range.begin) || range.include?(other_range.end) end |
#range ⇒ Range<IPAddr> Also known as: to_range
a Range built from the start and end addresses. To be used for finding inclusion and overlaps.
409 410 411 |
# File 'lib/jss/api_object/network_segment.rb', line 409 def range @starting_address..@ending_address end |
#set_ip_range(starting_address: nil, ending_address: nil, mask: nil, cidr: nil) ⇒ void
This method returns an undefined value.
set a new starting and ending addr at the same time.
and ending addresses.
640 641 642 643 644 645 646 647 648 649 650 |
# File 'lib/jss/api_object/network_segment.rb', line 640 def set_ip_range(starting_address: nil, ending_address: nil, mask: nil, cidr: nil) range = self.class.ip_range( starting_address: starting_address, ending_address: ending_address, mask: mask, cidr: cidr ) @starting_address = range.first @ending_address = range.last @need_to_update = true end |
#update ⇒ Boolean Originally defined in module Updatable
Save changes to the JSS