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
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 391 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.
363 364 365 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 363 def building @building end |
#department ⇒ String
Returns department for this segment. Must be one of the depts in the JSS.
366 367 368 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 366 def department @department end |
#distribution_point ⇒ String
Returns the name of the distribution point to be used from this network segment.
369 370 371 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 369 def distribution_point @distribution_point end |
#ending_address ⇒ IPAddr
Returns ending IP adresss.
360 361 362 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 360 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.
375 376 377 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 375 def netboot_server @netboot_server end |
#override_buildings ⇒ Boolean
Returns should machines checking in from this segment update their building.
384 385 386 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 384 def override_buildings @override_buildings end |
#override_departments ⇒ Boolean
Returns should machines checking in from this segment update their dept.
381 382 383 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 381 def override_departments @override_departments end |
#starting_address ⇒ IPAddr
Returns starting IP adresss.
357 358 359 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 357 def starting_address @starting_address end |
#swu_server ⇒ String
Returns the swupdate server for this segment.
378 379 380 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 378 def swu_server @swu_server end |
#url ⇒ String (readonly)
Returns the mount url for the distribution point.
372 373 374 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 372 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.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 189 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.
308 309 310 311 312 313 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 308 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
220 221 222 223 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 220 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
341 342 343 344 345 346 347 348 349 350 351 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 341 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.
323 324 325 326 327 328 329 330 331 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 323 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.
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 95 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
125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 125 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
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 273 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.
253 254 255 256 257 258 259 260 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 253 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.
146 147 148 149 150 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 146 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
233 234 235 236 237 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 233 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
464 465 466 467 468 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 464 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)
630 631 632 633 634 635 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 630 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.
447 448 449 450 451 452 453 454 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 447 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?
433 434 435 436 437 438 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 433 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.
423 424 425 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 423 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.
654 655 656 657 658 659 660 661 662 663 664 |
# File 'lib/jamf/api/classic/api_objects/network_segment.rb', line 654 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 |