Class: Jamf::NetworkSegment
- Defined in:
- lib/jamf/api/classic/api_objects/network_segment.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: nil, cnx: Jamf.cnx) ⇒ 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: nil, cnx: Jamf.cnx) ⇒ Array<Integer>, Array<String>
Find the current network segment ids for the machine running this code.
-
.network_ranges(refresh = false, api: nil, cnx: Jamf.cnx) ⇒ 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: nil, cnx: Jamf.cnx) ⇒ 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: nil, cnx: Jamf.cnx) ⇒ Integer?
Which network segment is seen as current for a given IP addr?.
-
.network_segments_for_ip(ipaddr, refresh = false, api: nil, cnx: Jamf.cnx) ⇒ Array<Integer>
Find the ids of the network segments that contain a given IP address.
-
.subnets(refresh = false, api: nil, cnx: Jamf.cnx) ⇒ 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, cnx: nil) ⇒ APIObject
included
from Creatable
make a clone of this API object, with a new name.
-
#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.
Constructor Details
#initialize(**args) ⇒ NetworkSegment
Instantiate a NetworkSegment
addresses can be provided when using id: :new
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 374 def initialize(**args) super 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.
346 347 348 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 346 def building @building end |
#department ⇒ String
Returns department for this segment. Must be one of the depts in the JSS.
349 350 351 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 349 def department @department end |
#distribution_point ⇒ String
Returns the name of the distribution point to be used from this network segment.
352 353 354 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 352 def distribution_point @distribution_point end |
#ending_address ⇒ IPAddr
Returns ending IP adresss.
343 344 345 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 343 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.
358 359 360 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 358 def netboot_server @netboot_server end |
#override_buildings ⇒ Boolean
Returns should machines checking in from this segment update their building.
367 368 369 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 367 def override_buildings @override_buildings end |
#override_departments ⇒ Boolean
Returns should machines checking in from this segment update their dept.
364 365 366 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 364 def override_departments @override_departments end |
#starting_address ⇒ IPAddr
Returns starting IP adresss.
340 341 342 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 340 def starting_address @starting_address end |
#swu_server ⇒ String
Returns the swupdate server for this segment.
361 362 363 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 361 def swu_server @swu_server end |
#url ⇒ String (readonly)
Returns the mount url for the distribution point.
355 356 357 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 355 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.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 171 def self.ip_range(starting_address: nil, ending_address: nil, mask: nil, cidr: nil) raise Jamf::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.
291 292 293 294 295 296 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 291 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
203 204 205 206 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 203 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: nil, cnx: Jamf.cnx) ⇒ 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
324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 324 def self.my_network_segment(refresh = false, name: false, api: nil, cnx: Jamf.cnx) cnx = api if api my_ip = Jamf::Client.my_ip_address return nil unless my_ip id = network_segment_for_ip(my_ip, refresh: refresh, cnx: cnx) return id unless name map_all_ids_to(:name, cnx: cnx)[id] end |
.my_network_segments(refresh = false, names: false, api: nil, cnx: Jamf.cnx) ⇒ 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.
306 307 308 309 310 311 312 313 314 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 306 def self.my_network_segments(refresh = false, names: false, api: nil, cnx: Jamf.cnx) cnx = api if api ids = network_segments_for_ip Jamf::Client.my_ip_address, refresh, cnx: cnx return ids unless names ids_to_names = map_all_ids_to :name, cnx: cnx ids.map { |id| ids_to_names[id] } end |
.network_ranges(refresh = false, api: nil, cnx: Jamf.cnx) ⇒ 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.
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 77 def self.network_ranges(refresh = false, api: nil, cnx: Jamf.cnx) cnx = api if api @network_ranges = nil if refresh return @network_ranges if @network_ranges @network_ranges = {} all(refresh, cnx: cnx).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: nil, cnx: Jamf.cnx) ⇒ 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
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 107 def self.network_ranges_as_integers(refresh = false, api: nil, cnx: Jamf.cnx) cnx = api if api @network_ranges_as_integers = nil if refresh return @network_ranges_as_integers if @network_ranges_as_integers @network_ranges_as_integers = {} all(refresh, cnx: cnx).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: nil, cnx: Jamf.cnx) ⇒ 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
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 256 def self.network_segment_for_ip(ipaddr, refresh: false, api: nil, cnx: Jamf.cnx) cnx = api if 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, cnx: cnx).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: nil, cnx: Jamf.cnx) ⇒ 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.
236 237 238 239 240 241 242 243 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 236 def self.network_segments_for_ip(ipaddr, refresh = false, api: nil, cnx: Jamf.cnx) cnx = api if 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, cnx: cnx).select { |_id, range| range.include? ip }.keys end |
.subnets(refresh = false, api: nil, cnx: Jamf.cnx) ⇒ Object
An alias for network_ranges
DEPRECATED: This will be going away in a future release.
128 129 130 131 132 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 128 def self.subnets(refresh = false, api: nil, cnx: Jamf.cnx) cnx = api if api network_ranges refresh, cnx: cnx 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
216 217 218 219 220 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 216 def self.validate_ip_range(startip, endip) return nil if IPAddr.new(startip.to_s) <= IPAddr.new(endip.to_s) raise Jamf::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
448 449 450 451 452 453 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 448 def ==(other) raise TypeError, 'Argument must be a Jamf::NetworkSegment' unless \ other.is_a? Jamf::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)
617 618 619 620 621 622 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 617 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, cnx: nil) ⇒ APIObject Originally defined in module Creatable
make a clone of this API object, with a new name. The class must be creatable
#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.
431 432 433 434 435 436 437 438 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 431 def include?(thing) if thing.is_a? Jamf::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?
416 417 418 419 420 421 422 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 416 def overlap?(other_segment) raise TypeError, 'Argument must be a Jamf::NetworkSegment' unless \ other_segment.is_a? Jamf::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.
406 407 408 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 406 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.
641 642 643 644 645 646 647 648 649 650 651 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 641 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 |