ruby-jss 1.2.10 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby-jss might be problematic. Click here for more details.

Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +208 -1
  3. data/lib/jamf.rb +18 -16
  4. data/lib/jamf/api/base_classes/collection_resource.rb +613 -0
  5. data/lib/jamf/api/{abstract_classes → base_classes}/json_object.rb +110 -102
  6. data/lib/jamf/api/{abstract_classes → base_classes}/prestage.rb +56 -31
  7. data/lib/jamf/api/{abstract_classes → base_classes}/resource.rb +10 -6
  8. data/lib/jamf/api/{abstract_classes → base_classes}/singleton_resource.rb +4 -3
  9. data/lib/jamf/api/connection.rb +20 -12
  10. data/lib/jamf/api/connection/api_error.rb +8 -8
  11. data/lib/jamf/api/connection/token.rb +36 -15
  12. data/lib/jamf/api/json_objects/device_enrollment_device.rb +14 -7
  13. data/lib/jamf/api/json_objects/{location.rb → device_enrollment_device_sync_state.rb} +27 -41
  14. data/lib/jamf/api/json_objects/device_enrollment_sync_status.rb +1 -1
  15. data/lib/jamf/api/json_objects/{attachment.rb → locale.rb} +14 -23
  16. data/lib/jamf/api/json_objects/md_prestage_name.rb +1 -1
  17. data/lib/jamf/api/json_objects/md_prestage_names.rb +2 -2
  18. data/lib/jamf/api/json_objects/md_prestage_skip_setup_items.rb +50 -1
  19. data/lib/jamf/api/json_objects/prestage_assignment.rb +2 -2
  20. data/lib/jamf/api/json_objects/prestage_location.rb +3 -3
  21. data/lib/jamf/api/json_objects/prestage_purchasing_data.rb +7 -7
  22. data/lib/jamf/api/json_objects/prestage_scope.rb +1 -1
  23. data/lib/jamf/api/{resources/collection_resources → json_objects}/time_zone.rb +9 -23
  24. data/lib/jamf/api/mixins/{abstract.rb → base_class.rb} +34 -16
  25. data/lib/jamf/api/mixins/bulk_deletable.rb +27 -6
  26. data/lib/jamf/api/mixins/change_log.rb +201 -51
  27. data/lib/jamf/api/{resources/collection_resources/extension_attribute.rb → mixins/filterable.rb} +20 -14
  28. data/lib/jamf/api/mixins/pageable.rb +208 -0
  29. data/lib/jamf/api/{json_objects/installed_application.rb → mixins/sortable.rb} +33 -33
  30. data/lib/jamf/api/resources/collection_resources/building.rb +16 -9
  31. data/lib/jamf/api/resources/collection_resources/category.rb +5 -4
  32. data/lib/jamf/api/resources/collection_resources/computer_prestage.rb +12 -5
  33. data/lib/jamf/api/resources/collection_resources/department.rb +1 -3
  34. data/lib/jamf/api/resources/collection_resources/device_enrollment.rb +13 -13
  35. data/lib/jamf/api/resources/collection_resources/inventory_preload_record.rb +11 -3
  36. data/lib/jamf/api/resources/collection_resources/mobile_device_prestage.rb +25 -23
  37. data/lib/jamf/api/resources/collection_resources/script.rb +61 -25
  38. data/lib/jamf/api/resources/singleton_resources/app_store_country_codes.rb +15 -5
  39. data/lib/jamf/api/resources/singleton_resources/locales.rb +155 -0
  40. data/lib/jamf/api/resources/singleton_resources/time_zones.rb +213 -0
  41. data/lib/jamf/configuration.rb +7 -9
  42. data/lib/jamf/ruby_extensions.rb +1 -0
  43. data/lib/jamf/ruby_extensions/array.rb +1 -1
  44. data/lib/jamf/ruby_extensions/array/utils.rb +3 -3
  45. data/lib/jamf/{api/resources/collection_resources/computer.rb → ruby_extensions/dig.rb} +22 -19
  46. data/lib/jamf/validate.rb +63 -24
  47. data/lib/jamf/version.rb +1 -1
  48. data/lib/jss.rb +4 -1
  49. data/lib/jss/api_connection.rb +111 -433
  50. data/lib/jss/api_object.rb +16 -13
  51. data/lib/jss/api_object/advanced_search.rb +27 -26
  52. data/lib/jss/api_object/app_store_country_codes.rb +298 -0
  53. data/lib/jss/api_object/categorizable.rb +1 -1
  54. data/lib/jss/api_object/computer.rb +13 -0
  55. data/lib/jss/api_object/configuration_profile.rb +60 -4
  56. data/lib/jss/api_object/directory_binding.rb +273 -0
  57. data/lib/jss/api_object/directory_binding_type.rb +96 -0
  58. data/lib/jss/api_object/directory_binding_type/active_directory.rb +539 -0
  59. data/lib/jss/api_object/directory_binding_type/admitmac.rb +594 -0
  60. data/lib/jss/api_object/directory_binding_type/centrify.rb +226 -0
  61. data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
  62. data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
  63. data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
  64. data/lib/jss/api_object/distribution_point.rb +97 -37
  65. data/lib/jss/api_object/dock_item.rb +143 -0
  66. data/lib/jss/api_object/ebook.rb +1 -2
  67. data/lib/jss/api_object/extendable.rb +1 -1
  68. data/lib/jss/api_object/extension_attribute.rb +4 -3
  69. data/lib/jss/api_object/group.rb +33 -2
  70. data/lib/jss/api_object/mac_application.rb +107 -8
  71. data/lib/jss/api_object/mobile_device_application.rb +12 -0
  72. data/lib/jss/api_object/network_segment.rb +195 -70
  73. data/lib/jss/api_object/package.rb +105 -40
  74. data/lib/jss/api_object/patch_source.rb +10 -9
  75. data/lib/jss/api_object/policy.rb +596 -32
  76. data/lib/jss/api_object/printer.rb +446 -0
  77. data/lib/jss/api_object/scopable.rb +10 -15
  78. data/lib/jss/api_object/scopable/scope.rb +371 -55
  79. data/lib/jss/api_object/self_servable.rb +17 -9
  80. data/lib/jss/api_object/uploadable.rb +1 -1
  81. data/lib/jss/api_object/user.rb +42 -1
  82. data/lib/jss/api_object/vpp_account.rb +209 -0
  83. data/lib/jss/api_object/vppable.rb +169 -13
  84. data/lib/jss/composer.rb +1 -1
  85. data/lib/jss/exceptions.rb +3 -0
  86. data/lib/jss/server.rb +15 -0
  87. data/lib/jss/utility.rb +143 -52
  88. data/lib/jss/validate.rb +53 -10
  89. data/lib/jss/version.rb +1 -1
  90. metadata +56 -61
  91. data/lib/jamf/api/abstract_classes/advanced_search.rb +0 -86
  92. data/lib/jamf/api/abstract_classes/collection_resource.rb +0 -433
  93. data/lib/jamf/api/abstract_classes/generic_reference.rb +0 -145
  94. data/lib/jamf/api/abstract_classes/prestage_skip_setup_items.rb +0 -126
  95. data/lib/jamf/api/json_objects/account_prefs.rb +0 -79
  96. data/lib/jamf/api/json_objects/android_details.rb +0 -139
  97. data/lib/jamf/api/json_objects/appletv_details.rb +0 -110
  98. data/lib/jamf/api/json_objects/cellular_network.rb +0 -151
  99. data/lib/jamf/api/json_objects/computer_prestage_skip_setup_items.rb +0 -67
  100. data/lib/jamf/api/json_objects/criterion.rb +0 -152
  101. data/lib/jamf/api/json_objects/extension_attribute_value.rb +0 -128
  102. data/lib/jamf/api/json_objects/installed_certificate.rb +0 -53
  103. data/lib/jamf/api/json_objects/installed_configuration_profile.rb +0 -67
  104. data/lib/jamf/api/json_objects/installed_ebook.rb +0 -58
  105. data/lib/jamf/api/json_objects/installed_provisioning_profile.rb +0 -59
  106. data/lib/jamf/api/json_objects/ios_details.rb +0 -244
  107. data/lib/jamf/api/json_objects/mobile_device_details.rb +0 -219
  108. data/lib/jamf/api/json_objects/mobile_device_security.rb +0 -101
  109. data/lib/jamf/api/json_objects/purchasing_data.rb +0 -125
  110. data/lib/jamf/api/mixins/locatable.rb +0 -124
  111. data/lib/jamf/api/mixins/referable.rb +0 -92
  112. data/lib/jamf/api/resources/collection_resources/account.rb +0 -163
  113. data/lib/jamf/api/resources/collection_resources/advanced_mobile_device_search.rb +0 -52
  114. data/lib/jamf/api/resources/collection_resources/advanced_user_search.rb +0 -52
  115. data/lib/jamf/api/resources/collection_resources/mobile_device.rb +0 -315
  116. data/lib/jamf/api/resources/collection_resources/site.rb +0 -77
  117. data/lib/jamf/api/resources/singleton_resources/authorization.rb +0 -88
  118. data/lib/jamf/api/resources/singleton_resources/client_checkin_settings.rb +0 -139
  119. data/lib/jamf/api/resources/singleton_resources/reenrollment_settings.rb +0 -95
@@ -23,12 +23,11 @@
23
23
  ###
24
24
  ###
25
25
 
26
- # This is just a stub for now.
27
26
 
28
27
  #
29
28
  module JSS
30
29
 
31
- #
30
+ # This is just a stub for now.
32
31
  class EBook < APIObject
33
32
 
34
33
  include Sitable
@@ -23,7 +23,6 @@
23
23
  #
24
24
  #
25
25
 
26
- #
27
26
  module JSS
28
27
 
29
28
  # Sub-Modules
@@ -221,6 +220,7 @@ module JSS
221
220
  eaxml = REXML::Element.new('extension_attributes')
222
221
  @extension_attributes.each do |ea|
223
222
  next unless @changed_eas.include? ea[:name]
223
+
224
224
  ea_el = eaxml.add_element('extension_attribute')
225
225
  ea_el.add_element('name').text = ea[:name]
226
226
 
@@ -179,9 +179,10 @@ module JSS
179
179
  # deprecated - no longer in the UI
180
180
  @recon_display = @init_data[:recon_display] || @web_display
181
181
 
182
- # the name of the EA might have spaces and caps, which the will come to us as symbols with the spaces
183
- # as underscores, like this.
184
- @symbolized_name = @name.gsub(/-| /, '_').to_sym
182
+ # When used in Advanced Search results, the EA name
183
+ # has colons removed, spaces & dashes turned to underscores.
184
+ # and then ruby-jss symbolizes the name.
185
+ @symbolized_name = @name.gsub(':', '').gsub(/-| /, '_').to_sym
185
186
  end # init
186
187
 
187
188
  # Public Instance Methods
@@ -241,7 +241,7 @@ module JSS
241
241
  #
242
242
  # @param retries [Integer] If calculate_members is true, refetching the
243
243
  # group to re-read the membership can happen too fast, the JSS won't know
244
- # it exists yet and will throw a RestClient::NotFound error. If that
244
+ # it exists yet and will throw a NoSuchItem error. If that
245
245
  # happens, try again this many times with a 1 second pause between attempts.
246
246
  #
247
247
  def create(calculate_members: true, retries: 10)
@@ -256,7 +256,7 @@ module JSS
256
256
  begin
257
257
  refresh_members
258
258
  break
259
- rescue RestClient::NotFound
259
+ rescue
260
260
  sleep 1
261
261
  tries += 1
262
262
  end # begin
@@ -311,6 +311,37 @@ module JSS
311
311
  super
312
312
  end
313
313
 
314
+ # Change static group to smart group
315
+ #
316
+ # @param args[Hash] the options and settings use for switching the computer group from static group to smart group
317
+ #
318
+ # @option args criteria[Array] The criterias to be user for the smart group
319
+ def set_smart(*params)
320
+ return if @is_smart
321
+
322
+ params[:criteria] = [] if params[:criteria].nil?
323
+
324
+ criteria = params[:criteria]
325
+
326
+ @is_smart = true
327
+ @need_to_update = true
328
+ end
329
+
330
+ # Change smart group to static group
331
+ #
332
+ # @param args[Hash] the options and settings use for switching the computer group from smart group to static group
333
+ #
334
+ # @option args preserve_members[Boolean] Should the smart group preserve it's current members?
335
+ def set_static(*params)
336
+ return unless @is_smart
337
+
338
+ preserve_members = params.include? :preserve_members
339
+
340
+ @is_smart = false
341
+
342
+ clear() unless preserve_members
343
+ end
344
+
314
345
  # How many members of the group?
315
346
  #
316
347
  # @return [Integer] the number of members of the group
@@ -22,15 +22,19 @@
22
22
  ### language governing permissions and limitations under the Apache License.
23
23
  ###
24
24
 
25
- # This is just a stub for now.
26
-
27
- #
28
25
  module JSS
29
26
 
30
- #
31
- class MacApplication < APIObject
27
+ # This is just a stub for now.
28
+ class MacApplication < JSS::APIObject
32
29
 
33
- include Sitable
30
+ # Mix-Ins
31
+ #####################################
32
+ include JSS::Updatable
33
+ include JSS::Scopable
34
+ include JSS::SelfServable
35
+ include JSS::Categorizable
36
+ include JSS::VPPable
37
+ include JSS::Sitable
34
38
 
35
39
  ### The base for REST resources of this class
36
40
  RSRC_BASE = 'macapplications'.freeze
@@ -47,9 +51,104 @@ module JSS
47
51
  # See {APIObject#add_object_history_entry}
48
52
  OBJECT_HISTORY_OBJECT_TYPE = 350
49
53
 
54
+ # See JSS::Scopable
55
+ SCOPE_TARGET_KEY = :computers
56
+
57
+ # Where is the Category in the API JSON?
58
+ CATEGORY_SUBSET = :general
59
+
60
+ # How is the category stored in the API data?
61
+ CATEGORY_DATA_TYPE = Hash
62
+
50
63
  # Where is the Site data in the API JSON?
51
64
  SITE_SUBSET = :general
52
65
 
53
- end
66
+ # Attributes
67
+ #############################################
68
+
69
+ # @return [String]
70
+ attr_reader :version
71
+
72
+ # @return [Boolean]
73
+ attr_reader :is_free
74
+ alias free? is_free
75
+
76
+ # @return [String]
77
+ attr_reader :bundle_id
78
+
79
+ # @return [String]
80
+ attr_reader :url
81
+
82
+ ## Constructor
83
+ #####################################
84
+
85
+ def initialize(args = {})
86
+ super
87
+ general = @init_data[:general]
88
+ @version = general[:version]
89
+ @is_free = general[:is_free]
90
+ @bundle_id = general[:bundle_id]
91
+ @url = general[:url]
92
+ end
93
+
94
+ # Overrides, because consistency isn't alway a thing in the
95
+ # classic API
96
+ #############################################
97
+
98
+ # Override self_service_display_name getter
99
+ def self_service_display_name
100
+ raise JSS::UnsupportedError, 'MacApplications do not have separate display names. Please use the object name.'
101
+ end
102
+
103
+ # Override self_service_display_name setter
104
+ def self_service_display_name=(_newname)
105
+ raise JSS::UnsupportedError, 'MacApplications do not have separate display names. Please use the object name.'
106
+ end
107
+
108
+ # Override reinstall_button_text getter
109
+ def reinstall_button_text
110
+ raise JSS::UnsupportedError, 'MacApplications do not have separate text for reinstall buttons. Please use install_button_text.'
111
+ end
112
+
113
+ # Override reinstall_button_text setter
114
+ def reinstall_button_text=(_new)
115
+ raise JSS::UnsupportedError, 'MacApplications do not have separate text for reinstall buttons. Please use install_button_text.'
116
+ end
117
+
118
+ # Alas, SSvc icons are not uploadable via the API for
119
+ # mac apps
120
+ def upload(_type, _local_file)
121
+ raise JSS::UnsupportedError, 'The Classic API does not support uploading icons for MacApplications. Please use the Web UI'
122
+ end
123
+
124
+ ## Private Instance Methods
125
+ #####################################
126
+ private
127
+
128
+ ### Return the xml for creating or updating this script in the JSS
129
+ ###
130
+ def rest_xml
131
+ doc = REXML::Document.new APIConnection::XML_HEADER
132
+ obj = doc.add_element RSRC_OBJECT_KEY.to_s
133
+
134
+ general = obj.add_element('general')
135
+
136
+ general.add_element('version').text = @version
137
+ general.add_element('is_free').text = @is_free.to_s
138
+ general.add_element('bundle_id').text = @bundle_id
139
+ general.add_element('url').text = @url
140
+
141
+ obj << @scope.scope_xml
142
+
143
+ add_self_service_xml doc
144
+ add_category_to_xml doc
145
+ add_site_to_xml doc
146
+ add_vpp_xml doc
147
+
148
+ doc.to_s
149
+
150
+ end
151
+
152
+ end # class MacApplication
54
153
 
55
- end
154
+ end # Module JSS
@@ -444,6 +444,18 @@ module JSS
444
444
  refresh_ipa
445
445
  end
446
446
 
447
+ # Remove the various cached data
448
+ # from the instance_variables used to create
449
+ # pretty-print (pp) output.
450
+ #
451
+ # @return [Array] the desired instance_variables
452
+ #
453
+ def pretty_print_instance_variables
454
+ vars = super
455
+ vars.delete :@ipa
456
+ vars
457
+ end
458
+
447
459
  # Private Instance Methods
448
460
  ###########################################
449
461
  private
@@ -67,21 +67,70 @@ module JSS
67
67
  ### Class Methods
68
68
  #####################################
69
69
 
70
- ### All NetworkSegments in the jss as IPAddr object Ranges representing the
71
- ### Segment, e.g. with starting = 10.24.9.1 and ending = 10.24.15.254
72
- ### the range looks like:
73
- ### <IPAddr: IPv4:10.24.9.1/255.255.255.255>..#<IPAddr: IPv4:10.24.15.254/255.255.255.255>
74
- ###
75
- ### Using the #include? method on those Ranges is very useful.
76
- ###
77
- ### @param refresh[Boolean] re-read the data from the API?
78
- ###
79
- ### @param api[JSS::APIConnection] The API connection to query
80
- ###
81
- ### @return [Hash{Integer => Range}] the network segments as IPv4 address Ranges
82
- ###
70
+ # All NetworkSegments in the given API as ruby Ranges of IPAddr instances
71
+ # representing the Segment,
72
+ # e.g. with starting = 10.24.9.1 and ending = 10.24.15.254
73
+ # the range looks like:
74
+ # <IPAddr: IPv4:10.24.9.1/255.255.255.255>
75
+ # ..
76
+ # <IPAddr: IPv4:10.24.15.254/255.255.255.255>
77
+ #
78
+ # Using the #include? method on those Ranges is very useful.
79
+ #
80
+ # Note1: We don't use the IPAddr#to_range method because that works
81
+ # best for masked IPAddrs (which are ranges of IPs with widths
82
+ # determined by the mask) and Jamf Network Segments can have arbitrary
83
+ # widths.
84
+ #
85
+ # Note2: See the network_ranges_as_integers method below, which is similar
86
+ # but much faster.
87
+ #
88
+ # @param refresh[Boolean] should the data be re-queried?
89
+ #
90
+ # @param api[JSS::APIConnection] the API to query
91
+ #
92
+ # @return [Hash{Integer => Range}] the network segments as IPv4 address Ranges
93
+ # keyed by id
94
+ #
83
95
  def self.network_ranges(refresh = false, api: JSS.api)
84
- api.network_ranges refresh
96
+ @network_ranges = nil if refresh
97
+ return @network_ranges if @network_ranges
98
+
99
+ @network_ranges = {}
100
+ all(refresh, api: api).each do |ns|
101
+ @network_ranges[ns[:id]] = IPAddr.new(ns[:starting_address])..IPAddr.new(ns[:ending_address])
102
+ end
103
+ @network_ranges
104
+ end # def network_segments
105
+
106
+ # An IPv4 Address is really just a 32-bit integer, displayed as four
107
+ # 8-bit integers. e.g. '10.0.69.1' is really the integer 167789825
108
+ # The #to_i method of IPAddr objects returns that integer (or the first of
109
+ # them if the IPAddr is masked).
110
+ #
111
+ # Using ranges made of those integers is far faster than using ranges
112
+ # if IPAddr objects, so that's what this method returns.
113
+ #
114
+ # See also: the network_ranges method above
115
+ #
116
+ # @param refresh[Boolean] should the data be re-queried?
117
+ #
118
+ # @param api[JSS::APIConnection] the APIConnection to query
119
+ #
120
+ # @return [Hash{Integer => Range}] the network segments as Integer Ranges
121
+ # keyed by id
122
+ #
123
+ def self.network_ranges_as_integers(refresh = false, api: JSS.api)
124
+ @network_ranges_as_integers = nil if refresh
125
+ return @network_ranges_as_integers if @network_ranges_as_integers
126
+
127
+ @network_ranges_as_integers = {}
128
+ all(refresh, api: api).each do |ns|
129
+ first = IPAddr.new(ns[:starting_address]).to_i
130
+ last = IPAddr.new(ns[:ending_address]).to_i
131
+ @network_ranges_as_integers[ns[:id]] = first..last
132
+ end
133
+ @network_ranges_as_integers
85
134
  end # def network_segments
86
135
 
87
136
  ### An alias for {NetworkSegment.network_ranges}
@@ -195,23 +244,72 @@ module JSS
195
244
  ###
196
245
  ### @return [Array<Integer>] the ids of the NetworkSegments containing the given ip
197
246
  ###
198
- def self.network_segments_for_ip(ip, refresh = false, api: JSS.api)
199
- ok_ip = IPAddr.new(ip)
200
- matches = []
201
- network_ranges(refresh, api: api).each { |id, subnet| matches << id if subnet.include?(ok_ip) }
202
- matches
247
+ def self.network_segments_for_ip(ipaddr, refresh = false, api: JSS.api)
248
+ # get the ip as a 32bit interger
249
+ ip = IPAddr.new(ipaddr.to_s).to_i
250
+ # a hash of NetSeg ids => Range<Integer>
251
+ network_ranges_as_integers(refresh, api: api).select { |_id, range| range.include? ip }.keys
252
+ end
253
+
254
+ # Which network segment is seen as current for a given IP addr?
255
+ #
256
+ # According to the Jamf Pro Admin Guide, if an IP is in more than one network
257
+ # segment, it uses the 'smallest' (narrowest) one - the one with fewest
258
+ # IP addrs within it.
259
+ #
260
+ # If multiple ones have the same width, then it uses the one of
261
+ # those with the lowest starting address
262
+ #
263
+ # @return [Integer, nil] the id of the current net segment, or nil
264
+ #
265
+ def self.network_segment_for_ip(ipaddr, refresh: false, api: JSS.api)
266
+ # get the ip as a 32bit interger
267
+ ip = IPAddr.new(ipaddr.to_s).to_i
268
+ # a hash of NetSeg ids => Range<Integer>
269
+ ranges = network_ranges_as_integers(refresh, api: api).select { |_id, range| range.include? ip }
270
+
271
+ # we got nuttin
272
+ return nil if ranges.empty?
273
+
274
+ # if we got only one, its the one
275
+ return ranges.keys.first if ranges.size == 1
276
+
277
+ # got more than one, sort by range size/width, asc.
278
+ sorted_by_size = ranges.sort_by { |_i, r| r.size }.to_h
279
+
280
+ # the first one is the smallest/narrowest.
281
+ _smallest_range_id, smallest_range = sorted_by_size.first
282
+
283
+ smallest_range_size = smallest_range.size
284
+
285
+ # select all of them that are the same size
286
+ all_of_small_size = sorted_by_size.select { |_i, r| r.size == smallest_range_size }
287
+
288
+ # sort them by the start of each range (r.first)
289
+ # and return the lowest start (returned by min_by)
290
+ my_range_id, _my_range = all_of_small_size.min_by { |_i, r| r.first }
291
+
292
+ # and return the id
293
+ my_range_id
203
294
  end
204
295
 
205
- # @deprecated use network_segments_for_ip
206
- # Here for Backward compatibility
207
- def self.network_segment_for_ip(ip, api: JSS.api)
208
- network_segments_for_ip(ip, api: api)
296
+ # given 2 IPAddr instances, find out how 'wide' they are -
297
+ # how many IP addresses exist between them.
298
+ def self.ip_range_width(ip1, ip2)
299
+ raise ArgumentError, 'Parameters must be IPAddr objects' unless ip1.is_a?(IPAddr) && ip2.is_a?(IPAddr)
300
+
301
+ low, high = [ip1, ip2].sort
302
+ high.to_i - low.to_i
209
303
  end
210
304
 
211
- ### Find the current network segment ids for the machine running this code
212
- ###
213
- ### @return [Array<Integer>] the NetworkSegment ids for this machine right now.
214
- ###
305
+ # Find the current network segment ids for the machine running this code
306
+ #
307
+ # See my_network_segment to get the current one according to the server.
308
+ #
309
+ # @param names [Boolean] the array will contain Network Segment names, not ids
310
+ #
311
+ # @return [Array<Integer>,Array<String>] the NetworkSegment ids or names for this machine right now.
312
+ #
215
313
  def self.my_network_segments(refresh = false, names: false, api: JSS.api)
216
314
  ids = network_segments_for_ip JSS::Client.my_ip_address, refresh, api: api
217
315
  return ids unless names
@@ -220,35 +318,23 @@ module JSS
220
318
  ids.map { |id| ids_to_names[id] }
221
319
  end
222
320
 
223
- # @deprecated use my_network_segments
224
- # Here for backward compatibility
225
- def self.my_network_segment(api: JSS.api)
226
- my_network_segments api: api
227
- end
228
-
229
- # All NetworkSegments in the given API as IPAddr object Ranges representing the
230
- # Segment, e.g. with starting = 10.24.9.1 and ending = 10.24.15.254
231
- # the range looks like:
232
- # <IPAddr: IPv4:10.24.9.1/255.255.255.255>..#<IPAddr: IPv4:10.24.15.254/255.255.255.255>
321
+ # Which network segment is seen as current? According to the
322
+ # Jamf Pro Admin Guide, the 'smallest' one - the one with fewest IP
323
+ # addrs within it. If multiple ones have the same number of IPs,
324
+ # then its the one with the lowest starting address
233
325
  #
234
- # Using the #include? method on those Ranges is very useful.
326
+ # @param name [Boolean] return the name of the netsegment, not the id
235
327
  #
236
- # @param refresh[Boolean] should the data be re-queried?
237
- #
238
- # @param api[JSS::APIConnection] the API to query
239
- #
240
- # @return [Hash{Integer => Range}] the network segments as IPv4 address Ranges
241
- # keyed by id
242
- #
243
- def self.network_ranges(refresh = false, api: JSS.api)
244
- @network_ranges = nil if refresh
245
- return @network_ranges if @network_ranges
246
- @network_ranges = {}
247
- all(refresh, api: api).each do |ns|
248
- @network_ranges[ns[:id]] = IPAddr.new(ns[:starting_address])..IPAddr.new(ns[:ending_address])
249
- end
250
- @network_ranges
251
- end # def network_segments
328
+ # @return [Integer, String, nil] the id of the current net segment, or nil
329
+ def self.my_network_segment(refresh = false, name: false, api: JSS.api)
330
+ my_ip = JSS::Client.my_ip_address
331
+ return nil unless my_ip
332
+
333
+ id = network_segment_for_ip(my_ip, refresh: refresh, api: api)
334
+ return id unless name
335
+
336
+ map_all_ids_to(:name)[id]
337
+ end
252
338
 
253
339
  ### Attributes
254
340
  #####################################
@@ -373,9 +459,17 @@ module JSS
373
459
  ### @return [void]
374
460
  ###
375
461
  def building=(newval)
376
- new = JSS::Building.all.select { |b| (b[:id] == newval) || (b[:name] == newval) }[0]
377
- raise JSS::MissingDataError, "No building matching '#{newval}'" unless new
378
- @building = new[:name]
462
+ new =
463
+ if newval.to_s.empty?
464
+ JSS::BLANK
465
+ else
466
+ id = JSS::Building.valid_id newval
467
+ raise JSS::MissingDataError, "No building matching '#{newval}'" unless id
468
+
469
+ JSS::Building.map_all_ids_to(:name)[id]
470
+ end
471
+
472
+ @building = new
379
473
  @need_to_update = true
380
474
  end
381
475
 
@@ -398,9 +492,16 @@ module JSS
398
492
  ### @return [void]
399
493
  ###
400
494
  def department=(newval)
401
- new = JSS::Department.all.select { |b| (b[:id] == newval) || (b[:name] == newval) }[0]
402
- raise JSS::MissingDataError, "No department matching '#{newval}' in the JSS" unless new
403
- @department = new[:name]
495
+ new =
496
+ if newval.to_s.empty?
497
+ JSS::BLANK
498
+ else
499
+ id = JSS::Department.valid_id newval
500
+ raise JSS::MissingDataError , "No department matching '#{newval}' in the JSS" unless id
501
+
502
+ JSS::Department.map_all_ids_to(:name)[id]
503
+ end
504
+ @department = new
404
505
  @need_to_update = true
405
506
  end
406
507
 
@@ -419,14 +520,22 @@ module JSS
419
520
 
420
521
  ### set the distribution_point
421
522
  ###
422
- ### @param newval[String, Integer] the new dist. point by name or id, must be in the JSS
523
+ ### @param newval[String, Integer, nil] the new dist. point by name or id, must be in the JSS, or nil or blank to unset
423
524
  ###
424
525
  ### @return [void]
425
526
  ###
426
527
  def distribution_point=(newval)
427
- new = JSS::DistributionPoint.all.select { |b| (b[:id] == newval) || (b[:name] == newval) }[0]
428
- raise JSS::MissingDataError, "No distribution_point matching '#{newval}' in the JSS" unless new
429
- @distribution_point = new[:name]
528
+ new =
529
+ if newval.to_s.empty?
530
+ JSS::BLANK
531
+ else
532
+ id = JSS::DistributionPoint.valid_id newval
533
+ raise JSS::MissingDataError, "No distribution_point matching '#{newval}' in the JSS" unless id
534
+
535
+ JSS::DistributionPoint.map_all_ids_to(:name)[id]
536
+ end
537
+
538
+ @distribution_point = new
430
539
  @need_to_update = true
431
540
  end
432
541
 
@@ -437,9 +546,17 @@ module JSS
437
546
  ### @return [void]
438
547
  ###
439
548
  def netboot_server=(newval)
440
- new = JSS::NetbootServer.all.select { |b| (b[:id] == newval) || (b[:name] == newval) }[0]
441
- raise JSS::MissingDataError, "No netboot_server matching '#{newval}' in the JSS" unless new
442
- @netboot_server = new[:name]
549
+ new =
550
+ if newval.to_s.empty?
551
+ JSS::BLANK
552
+ else
553
+ id = JSS::NetBootServer.valid_id newval
554
+ raise JSS::MissingDataError, "No netboot_server matching '#{newval}' in the JSS" unless id
555
+
556
+ JSS::NetbootServer.map_all_ids_to(:name)[id]
557
+ end
558
+
559
+ @netboot_server = new
443
560
  @need_to_update = true
444
561
  end
445
562
 
@@ -450,9 +567,17 @@ module JSS
450
567
  ### @return [void]
451
568
  ###
452
569
  def swu_server=(newval)
453
- new = JSS::SoftwareUpdateServer.all.select { |b| (b[:id] == newval) || (b[:name] == newval) }[0]
454
- raise JSS::MissingDataError, "No swu_server matching '#{newval}' in the JSS" unless new
455
- @swu_server = new[:name]
570
+ new =
571
+ if newval.to_s.empty?
572
+ JSS::BLANK
573
+ else
574
+ id = JSS::SoftwareUpdateServer.valid_id newval
575
+ raise JSS::MissingDataError, "No swu_server matching '#{newval}' in the JSS" unless id
576
+
577
+ JSS::SoftwareUpdateServer.map_all_ids_to(:name)[id]
578
+ end
579
+
580
+ @swu_server = new
456
581
  @need_to_update = true
457
582
  end
458
583