ruby-jss 1.2.10 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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