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.
- checksums.yaml +4 -4
- data/CHANGES.md +208 -1
- data/lib/jamf.rb +18 -16
- data/lib/jamf/api/base_classes/collection_resource.rb +613 -0
- data/lib/jamf/api/{abstract_classes → base_classes}/json_object.rb +110 -102
- data/lib/jamf/api/{abstract_classes → base_classes}/prestage.rb +56 -31
- data/lib/jamf/api/{abstract_classes → base_classes}/resource.rb +10 -6
- data/lib/jamf/api/{abstract_classes → base_classes}/singleton_resource.rb +4 -3
- data/lib/jamf/api/connection.rb +20 -12
- data/lib/jamf/api/connection/api_error.rb +8 -8
- data/lib/jamf/api/connection/token.rb +36 -15
- data/lib/jamf/api/json_objects/device_enrollment_device.rb +14 -7
- data/lib/jamf/api/json_objects/{location.rb → device_enrollment_device_sync_state.rb} +27 -41
- data/lib/jamf/api/json_objects/device_enrollment_sync_status.rb +1 -1
- data/lib/jamf/api/json_objects/{attachment.rb → locale.rb} +14 -23
- data/lib/jamf/api/json_objects/md_prestage_name.rb +1 -1
- data/lib/jamf/api/json_objects/md_prestage_names.rb +2 -2
- data/lib/jamf/api/json_objects/md_prestage_skip_setup_items.rb +50 -1
- data/lib/jamf/api/json_objects/prestage_assignment.rb +2 -2
- data/lib/jamf/api/json_objects/prestage_location.rb +3 -3
- data/lib/jamf/api/json_objects/prestage_purchasing_data.rb +7 -7
- data/lib/jamf/api/json_objects/prestage_scope.rb +1 -1
- data/lib/jamf/api/{resources/collection_resources → json_objects}/time_zone.rb +9 -23
- data/lib/jamf/api/mixins/{abstract.rb → base_class.rb} +34 -16
- data/lib/jamf/api/mixins/bulk_deletable.rb +27 -6
- data/lib/jamf/api/mixins/change_log.rb +201 -51
- data/lib/jamf/api/{resources/collection_resources/extension_attribute.rb → mixins/filterable.rb} +20 -14
- data/lib/jamf/api/mixins/pageable.rb +208 -0
- data/lib/jamf/api/{json_objects/installed_application.rb → mixins/sortable.rb} +33 -33
- data/lib/jamf/api/resources/collection_resources/building.rb +16 -9
- data/lib/jamf/api/resources/collection_resources/category.rb +5 -4
- data/lib/jamf/api/resources/collection_resources/computer_prestage.rb +12 -5
- data/lib/jamf/api/resources/collection_resources/department.rb +1 -3
- data/lib/jamf/api/resources/collection_resources/device_enrollment.rb +13 -13
- data/lib/jamf/api/resources/collection_resources/inventory_preload_record.rb +11 -3
- data/lib/jamf/api/resources/collection_resources/mobile_device_prestage.rb +25 -23
- data/lib/jamf/api/resources/collection_resources/script.rb +61 -25
- data/lib/jamf/api/resources/singleton_resources/app_store_country_codes.rb +15 -5
- data/lib/jamf/api/resources/singleton_resources/locales.rb +155 -0
- data/lib/jamf/api/resources/singleton_resources/time_zones.rb +213 -0
- data/lib/jamf/configuration.rb +7 -9
- data/lib/jamf/ruby_extensions.rb +1 -0
- data/lib/jamf/ruby_extensions/array.rb +1 -1
- data/lib/jamf/ruby_extensions/array/utils.rb +3 -3
- data/lib/jamf/{api/resources/collection_resources/computer.rb → ruby_extensions/dig.rb} +22 -19
- data/lib/jamf/validate.rb +63 -24
- data/lib/jamf/version.rb +1 -1
- data/lib/jss.rb +4 -1
- data/lib/jss/api_connection.rb +111 -433
- data/lib/jss/api_object.rb +16 -13
- data/lib/jss/api_object/advanced_search.rb +27 -26
- data/lib/jss/api_object/app_store_country_codes.rb +298 -0
- data/lib/jss/api_object/categorizable.rb +1 -1
- data/lib/jss/api_object/computer.rb +13 -0
- data/lib/jss/api_object/configuration_profile.rb +60 -4
- data/lib/jss/api_object/directory_binding.rb +273 -0
- data/lib/jss/api_object/directory_binding_type.rb +96 -0
- data/lib/jss/api_object/directory_binding_type/active_directory.rb +539 -0
- data/lib/jss/api_object/directory_binding_type/admitmac.rb +594 -0
- data/lib/jss/api_object/directory_binding_type/centrify.rb +226 -0
- data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
- data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
- data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
- data/lib/jss/api_object/distribution_point.rb +97 -37
- data/lib/jss/api_object/dock_item.rb +143 -0
- data/lib/jss/api_object/ebook.rb +1 -2
- data/lib/jss/api_object/extendable.rb +1 -1
- data/lib/jss/api_object/extension_attribute.rb +4 -3
- data/lib/jss/api_object/group.rb +33 -2
- data/lib/jss/api_object/mac_application.rb +107 -8
- data/lib/jss/api_object/mobile_device_application.rb +12 -0
- data/lib/jss/api_object/network_segment.rb +195 -70
- data/lib/jss/api_object/package.rb +105 -40
- data/lib/jss/api_object/patch_source.rb +10 -9
- data/lib/jss/api_object/policy.rb +596 -32
- data/lib/jss/api_object/printer.rb +446 -0
- data/lib/jss/api_object/scopable.rb +10 -15
- data/lib/jss/api_object/scopable/scope.rb +371 -55
- data/lib/jss/api_object/self_servable.rb +17 -9
- data/lib/jss/api_object/uploadable.rb +1 -1
- data/lib/jss/api_object/user.rb +42 -1
- data/lib/jss/api_object/vpp_account.rb +209 -0
- data/lib/jss/api_object/vppable.rb +169 -13
- data/lib/jss/composer.rb +1 -1
- data/lib/jss/exceptions.rb +3 -0
- data/lib/jss/server.rb +15 -0
- data/lib/jss/utility.rb +143 -52
- data/lib/jss/validate.rb +53 -10
- data/lib/jss/version.rb +1 -1
- metadata +56 -61
- data/lib/jamf/api/abstract_classes/advanced_search.rb +0 -86
- data/lib/jamf/api/abstract_classes/collection_resource.rb +0 -433
- data/lib/jamf/api/abstract_classes/generic_reference.rb +0 -145
- data/lib/jamf/api/abstract_classes/prestage_skip_setup_items.rb +0 -126
- data/lib/jamf/api/json_objects/account_prefs.rb +0 -79
- data/lib/jamf/api/json_objects/android_details.rb +0 -139
- data/lib/jamf/api/json_objects/appletv_details.rb +0 -110
- data/lib/jamf/api/json_objects/cellular_network.rb +0 -151
- data/lib/jamf/api/json_objects/computer_prestage_skip_setup_items.rb +0 -67
- data/lib/jamf/api/json_objects/criterion.rb +0 -152
- data/lib/jamf/api/json_objects/extension_attribute_value.rb +0 -128
- data/lib/jamf/api/json_objects/installed_certificate.rb +0 -53
- data/lib/jamf/api/json_objects/installed_configuration_profile.rb +0 -67
- data/lib/jamf/api/json_objects/installed_ebook.rb +0 -58
- data/lib/jamf/api/json_objects/installed_provisioning_profile.rb +0 -59
- data/lib/jamf/api/json_objects/ios_details.rb +0 -244
- data/lib/jamf/api/json_objects/mobile_device_details.rb +0 -219
- data/lib/jamf/api/json_objects/mobile_device_security.rb +0 -101
- data/lib/jamf/api/json_objects/purchasing_data.rb +0 -125
- data/lib/jamf/api/mixins/locatable.rb +0 -124
- data/lib/jamf/api/mixins/referable.rb +0 -92
- data/lib/jamf/api/resources/collection_resources/account.rb +0 -163
- data/lib/jamf/api/resources/collection_resources/advanced_mobile_device_search.rb +0 -52
- data/lib/jamf/api/resources/collection_resources/advanced_user_search.rb +0 -52
- data/lib/jamf/api/resources/collection_resources/mobile_device.rb +0 -315
- data/lib/jamf/api/resources/collection_resources/site.rb +0 -77
- data/lib/jamf/api/resources/singleton_resources/authorization.rb +0 -88
- data/lib/jamf/api/resources/singleton_resources/client_checkin_settings.rb +0 -139
- data/lib/jamf/api/resources/singleton_resources/reenrollment_settings.rb +0 -95
data/lib/jss/api_object/ebook.rb
CHANGED
|
@@ -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
|
-
#
|
|
183
|
-
#
|
|
184
|
-
|
|
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
|
data/lib/jss/api_object/group.rb
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
#
|
|
206
|
-
#
|
|
207
|
-
def self.
|
|
208
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
-
#
|
|
224
|
-
#
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
#
|
|
326
|
+
# @param name [Boolean] return the name of the netsegment, not the id
|
|
235
327
|
#
|
|
236
|
-
# @
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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 =
|
|
377
|
-
|
|
378
|
-
|
|
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 =
|
|
402
|
-
|
|
403
|
-
|
|
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 =
|
|
428
|
-
|
|
429
|
-
|
|
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 =
|
|
441
|
-
|
|
442
|
-
|
|
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 =
|
|
454
|
-
|
|
455
|
-
|
|
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
|
|