ruby-jss 1.4.1 → 1.6.0
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 +95 -0
- data/THANKS.md +3 -2
- data/lib/jamf.rb +18 -17
- data/lib/jamf/api/base_classes/collection_resource.rb +613 -0
- data/lib/jamf/api/{abstract_classes → base_classes}/json_object.rb +109 -101
- data/lib/jamf/api/{abstract_classes → base_classes}/prestage.rb +55 -30
- 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 +13 -9
- data/lib/jamf/api/connection/api_error.rb +8 -8
- data/lib/jamf/api/connection/token.rb +16 -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/computer.rb → mixins/filterable.rb} +19 -17
- 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 +0 -2
- data/lib/jamf/api/resources/collection_resources/device_enrollment.rb +10 -10
- 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/client.rb +3 -3
- data/lib/jamf/client/management_action.rb +2 -3
- data/lib/jamf/composer.rb +2 -2
- data/lib/jamf/utility.rb +35 -7
- data/lib/jamf/validate.rb +63 -24
- data/lib/jamf/version.rb +1 -1
- data/lib/jss.rb +2 -2
- data/lib/jss/api_connection.rb +114 -406
- data/lib/jss/api_object.rb +3 -19
- 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 +61 -5
- data/lib/jss/api_object/directory_binding_type.rb +66 -60
- data/lib/jss/api_object/directory_binding_type/active_directory.rb +71 -34
- data/lib/jss/api_object/directory_binding_type/admitmac.rb +536 -467
- data/lib/jss/api_object/directory_binding_type/centrify.rb +21 -7
- data/lib/jss/api_object/directory_binding_type/open_directory.rb +4 -4
- data/lib/jss/api_object/distribution_point.rb +2 -2
- data/lib/jss/api_object/dock_item.rb +102 -96
- data/lib/jss/api_object/extendable.rb +1 -1
- data/lib/jss/api_object/group.rb +33 -2
- data/lib/jss/api_object/network_segment.rb +45 -13
- data/lib/jss/api_object/patch_source.rb +10 -9
- data/lib/jss/api_object/policy.rb +155 -25
- data/lib/jss/api_object/printer.rb +10 -4
- data/lib/jss/api_object/scopable.rb +10 -15
- data/lib/jss/api_object/scopable/scope.rb +31 -30
- data/lib/jss/api_object/script.rb +242 -352
- data/lib/jss/api_object/user.rb +1 -1
- data/lib/jss/client/management_action.rb +1 -2
- data/lib/jss/composer.rb +2 -2
- data/lib/jss/exceptions.rb +3 -0
- data/lib/jss/server.rb +15 -0
- data/lib/jss/utility.rb +213 -45
- data/lib/jss/version.rb +1 -1
- metadata +46 -64
- 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/extension_attribute.rb +0 -45
- 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/user.rb
CHANGED
|
@@ -168,7 +168,7 @@ module JSS
|
|
|
168
168
|
@phone_number = @init_data[:phone_number]
|
|
169
169
|
@position = @init_data[:position]
|
|
170
170
|
@ldap_server = JSS::APIObject.get_name @init_data[:ldap_server]
|
|
171
|
-
@ldap_server_id = @init_data[:ldap_server][:id]
|
|
171
|
+
@ldap_server_id = @init_data[:ldap_server][:id] unless @init_data[:ldap_server].nil?
|
|
172
172
|
@sites = @init_data[:sites] ? @init_data[:sites] : []
|
|
173
173
|
|
|
174
174
|
if @init_data[:links]
|
|
@@ -103,8 +103,7 @@ module JSS
|
|
|
103
103
|
orig_flags = flags
|
|
104
104
|
prefs['apps'] << { 'bundle-id' => MGMT_ACTION_BUNDLE_ID, 'flags' => flags }
|
|
105
105
|
end
|
|
106
|
-
|
|
107
|
-
plist.open('w') { |f| f.write prefs.to_plist }
|
|
106
|
+
plist.open('w') { |f| f.write JSS.xml_plist_from(prefs) }
|
|
108
107
|
system HUP_NOTIF_CTR_CMD if hup
|
|
109
108
|
orig_flags
|
|
110
109
|
end
|
data/lib/jss/composer.rb
CHANGED
|
@@ -126,7 +126,7 @@ module JSS
|
|
|
126
126
|
###
|
|
127
127
|
comp_plist_out = Pathname.new "/tmp/#{PKG_BUNDLE_ID_PFX}-#{pkg_filename}.plist"
|
|
128
128
|
system "#{PKGBUILD} --analyze --root '#{root}' '#{comp_plist_out}'"
|
|
129
|
-
comp_plist =
|
|
129
|
+
comp_plist = JSS.parse_plist comp_plist_out
|
|
130
130
|
|
|
131
131
|
### if the plist is empty, there are no bundles in the pkg
|
|
132
132
|
if comp_plist[0].nil?
|
|
@@ -141,7 +141,7 @@ module JSS
|
|
|
141
141
|
bndl['BundleHasStrictIdentifier'] = false
|
|
142
142
|
end
|
|
143
143
|
### write out the edits
|
|
144
|
-
comp_plist_out.open('w') { |f| f.write comp_plist
|
|
144
|
+
comp_plist_out.open('w') { |f| f.write JSS.xml_plist_from(comp_plist) }
|
|
145
145
|
comp_plist_arg = "--component-plist '#{comp_plist_out}'"
|
|
146
146
|
end
|
|
147
147
|
|
data/lib/jss/exceptions.rb
CHANGED
data/lib/jss/server.rb
CHANGED
|
@@ -110,6 +110,21 @@ module JSS
|
|
|
110
110
|
@act_code_data[:code]
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
+
# Update the activation code and organization name for this server
|
|
114
|
+
#
|
|
115
|
+
# @param org: [String] the organization to which the server is licensed
|
|
116
|
+
# @param code: [String ] the activation code for the server licence
|
|
117
|
+
#
|
|
118
|
+
# @return [void]
|
|
119
|
+
def update_activation_code(org:, code:)
|
|
120
|
+
xml = REXML::Document.new JSS::APIConnection::XML_HEADER
|
|
121
|
+
acode = xml.add_element ACTIVATION_CODE_KEY.to_s
|
|
122
|
+
acode.add_element('organization_name').text = org
|
|
123
|
+
acode.add_element('code').text = code
|
|
124
|
+
|
|
125
|
+
@api.put_rsrc ACTIVATION_CODE_RSRC, xml.to_s
|
|
126
|
+
end
|
|
127
|
+
|
|
113
128
|
# Remove the api object from
|
|
114
129
|
# the instance_variables used to create
|
|
115
130
|
# pretty-print (pp) output.
|
data/lib/jss/utility.rb
CHANGED
|
@@ -23,61 +23,195 @@
|
|
|
23
23
|
#
|
|
24
24
|
#
|
|
25
25
|
|
|
26
|
-
#
|
|
27
26
|
module JSS
|
|
28
27
|
|
|
29
28
|
# A collection of useful utility methods. Mostly for
|
|
30
29
|
# converting values between formats, parsing data, and
|
|
31
30
|
# user interaction.
|
|
32
31
|
|
|
33
|
-
#
|
|
32
|
+
# Hash of 'minor' => 'maint'
|
|
33
|
+
# The maximum maint release for macOS 10.minor.maint
|
|
34
|
+
# e.g the highest release of 10.6 was 10.6.8, the highest release of
|
|
35
|
+
# 10.15 was 10.15.7
|
|
36
|
+
#
|
|
37
|
+
# 12 is the default for the current OS and higher
|
|
38
|
+
# (and hoping apple doesn't release 10.16.13)
|
|
39
|
+
OS_TEN_MAXS = {
|
|
40
|
+
2 => 8,
|
|
41
|
+
3 => 9,
|
|
42
|
+
4 => 11,
|
|
43
|
+
5 => 8,
|
|
44
|
+
6 => 8,
|
|
45
|
+
7 => 5,
|
|
46
|
+
8 => 5,
|
|
47
|
+
9 => 5,
|
|
48
|
+
10 => 5,
|
|
49
|
+
11 => 6,
|
|
50
|
+
12 => 6,
|
|
51
|
+
13 => 6,
|
|
52
|
+
14 => 6,
|
|
53
|
+
15 => 7
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# Hash of 'major' => 'minor'
|
|
57
|
+
# The maximum minor release for macOS major.minor
|
|
58
|
+
# e.g. the highest release of 11 is 11.12
|
|
59
|
+
#
|
|
60
|
+
# 12 is the default for the current OS and higher
|
|
61
|
+
# (and hoping apple doesn't release, e.g., 11.13)
|
|
62
|
+
MAC_OS_MAXS = {
|
|
63
|
+
11 => 12,
|
|
64
|
+
12 => 12,
|
|
65
|
+
13 => 12,
|
|
66
|
+
14 => 12,
|
|
67
|
+
15 => 12,
|
|
68
|
+
16 => 12,
|
|
69
|
+
17 => 12,
|
|
70
|
+
18 => 12,
|
|
71
|
+
19 => 12,
|
|
72
|
+
20 => 12
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# Converts an OS Version into an Array of equal or higher OS versions, up to
|
|
76
|
+
# some non-existant max, hopefully far in the future, currently 20.12.10
|
|
77
|
+
#
|
|
78
|
+
# This array can then be joined with commas and used as the value of the
|
|
79
|
+
# os_requirements for Packages and Scripts.
|
|
34
80
|
#
|
|
35
|
-
# It's unlikely that this
|
|
36
|
-
#
|
|
81
|
+
# It's unlikely that this method, as written, will still be in use by
|
|
82
|
+
# the release of macOS 20.12.10, but currently thats the upper limit.
|
|
37
83
|
#
|
|
38
|
-
#
|
|
84
|
+
# Hopefully well before then JAMF will implement a "minimum OS" in Jamf Pro
|
|
85
|
+
# itself, then we could avoid the inherant limitations in using a method like
|
|
86
|
+
# this.
|
|
39
87
|
#
|
|
40
|
-
#
|
|
88
|
+
# When the highest maint. release of an OS version is not known, because its
|
|
89
|
+
# the currently released OS version or higher, then this method assumes '12'
|
|
90
|
+
# e.g. '10.16.12', '11.12', '12.12', etc.
|
|
91
|
+
#
|
|
92
|
+
# Apple has never released more than 11 updates to a version of macOS
|
|
93
|
+
# (that being 10.4), so hopefully 12 is enough
|
|
94
|
+
#
|
|
95
|
+
# Since Big Sur might report itself as either '10.16' or '11.x.x', this method
|
|
96
|
+
# will allow for both possibilities, and the array will contain whatever
|
|
97
|
+
# iterations needed for both version numbers
|
|
98
|
+
#
|
|
99
|
+
# @param min_os [String] the mimimum OS version to expand, e.g. ">=10.9.4" or "11.1"
|
|
100
|
+
#
|
|
101
|
+
# @return [Array] Nearly all potential OS versions from the minimum to 20.12.10
|
|
41
102
|
#
|
|
42
103
|
# @example
|
|
43
|
-
# JSS.expand_min_os ">=10.
|
|
44
|
-
# # ["10.
|
|
45
|
-
# # "10.
|
|
104
|
+
# JSS.expand_min_os ">=10.9.4" # => returns this array
|
|
105
|
+
# # ["10.9.4",
|
|
106
|
+
# # "10.9.5",
|
|
107
|
+
# # "10.10.x"
|
|
46
108
|
# # ...
|
|
47
|
-
# # "10.
|
|
48
|
-
# # "
|
|
49
|
-
# # "
|
|
109
|
+
# # "10.16.x",
|
|
110
|
+
# # "11.x",
|
|
111
|
+
# # "12.x",
|
|
50
112
|
# # ...
|
|
51
|
-
# # "
|
|
113
|
+
# # "20.x"]
|
|
52
114
|
#
|
|
53
115
|
#
|
|
54
116
|
def self.expand_min_os(min_os)
|
|
55
117
|
min_os = min_os.delete '>='
|
|
56
118
|
|
|
57
119
|
# split the version into major, minor and maintenance release numbers
|
|
58
|
-
|
|
120
|
+
major, minor, maint = min_os.split('.')
|
|
121
|
+
minor = 'x' if minor.nil? || minor == '0'
|
|
59
122
|
maint = 'x' if maint.nil? || maint == '0'
|
|
60
123
|
|
|
61
|
-
|
|
62
|
-
if maint == 'x'
|
|
63
|
-
ok_oses = [maj + '.' + min.to_s + '.x']
|
|
124
|
+
ok_oses = []
|
|
64
125
|
|
|
65
|
-
#
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
126
|
+
# Deal with 10.x.x up to 10.16
|
|
127
|
+
if major == '10'
|
|
128
|
+
|
|
129
|
+
# In big sur with SYSTEM_VERSION_COMPAT
|
|
130
|
+
# set, it will only ever report as `10.16`
|
|
131
|
+
# So if major is 10 and minor is 16, ignore maint
|
|
132
|
+
# and start explicitly at '10.16'
|
|
133
|
+
if minor == '16'
|
|
134
|
+
ok_oses << '10.16'
|
|
135
|
+
|
|
136
|
+
# But for Catalina and below, we need to
|
|
137
|
+
# expand things out
|
|
138
|
+
else
|
|
139
|
+
# e.g. 10.14.x
|
|
140
|
+
# doesn't expand to anything
|
|
141
|
+
if maint == 'x'
|
|
142
|
+
ok_oses << "10.#{minor}.x"
|
|
143
|
+
|
|
144
|
+
# e.g. 10.15.5
|
|
145
|
+
# expand to 10.15.5, 10.15.6, 10.15.7
|
|
146
|
+
else
|
|
147
|
+
max_maint_for_minor = OS_TEN_MAXS[minor.to_i]
|
|
148
|
+
|
|
149
|
+
(maint.to_i..max_maint_for_minor).each do |m|
|
|
150
|
+
ok_oses << "#{major}.#{minor}.#{m}"
|
|
151
|
+
end # each m
|
|
152
|
+
end # if maint == x
|
|
153
|
+
|
|
154
|
+
# now if we started below catalina, account for everything
|
|
155
|
+
# up to 10.15.x
|
|
156
|
+
if minor.to_i < 15
|
|
157
|
+
((minor.to_i + 1)..15).each { |v| ok_oses << "10.#{v}.x" }
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# and add big sur with SYSTEM_VERSION_COMPAT
|
|
161
|
+
ok_oses << '10.16'
|
|
162
|
+
end # if minor == 16
|
|
163
|
+
|
|
164
|
+
# now reset these so we can go higher
|
|
165
|
+
major = '11'
|
|
166
|
+
minor = 'x'
|
|
167
|
+
maint = 'x'
|
|
168
|
+
end # if major == 10
|
|
169
|
+
|
|
170
|
+
# if the min os is 11.0.0 or equiv, and we aven't added 10.16
|
|
171
|
+
# for SYSTEM_VERSION_COMPAT, add it now
|
|
172
|
+
if ['11', '11.x', '11.x.x', '11.0', '11.0.0'].include?(min_os) && !ok_oses.include?('10.16')
|
|
173
|
+
ok_oses << '10.16'
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# e.g. 11.x, or 11.x.x
|
|
177
|
+
# expand to 11.x, 12.x, 13.x, ... 20.x
|
|
178
|
+
if minor == 'x'
|
|
179
|
+
((major.to_i)..20).each { |v| ok_oses << "#{v}.x" }
|
|
180
|
+
|
|
181
|
+
# e.g. 11.2.x
|
|
182
|
+
# expand to 11.2.x, 11.3.x, ... 11.12.x,
|
|
183
|
+
# 12.x, 13.x, ... 20.x
|
|
184
|
+
elsif maint == 'x'
|
|
185
|
+
# first expand the minors out to their max
|
|
186
|
+
# e.g. 11.2.x, 11.3.x, ... 11.12.x
|
|
187
|
+
max_minor_for_major = MAC_OS_MAXS[major.to_i]
|
|
188
|
+
((minor.to_i)..max_minor_for_major).each do |m|
|
|
189
|
+
ok_oses << "#{major}.#{m}.x"
|
|
71
190
|
end # each m
|
|
191
|
+
|
|
192
|
+
# then add the majors out to 20
|
|
193
|
+
((major.to_i + 1)..20).each { |v| ok_oses << "#{v}.x" }
|
|
194
|
+
|
|
195
|
+
# e.g. 11.2.3
|
|
196
|
+
# expand to 11.2.3, 11.2.4, ... 11.2.10,
|
|
197
|
+
# 11.3.x, 11.4.x, ... 11.12.x,
|
|
198
|
+
# 12.x, 13.x, ... 20.x
|
|
199
|
+
else
|
|
200
|
+
# first expand the maints out to 10
|
|
201
|
+
# e.g. 11.2.3, 11.2.4, ... 11.2.10
|
|
202
|
+
((maint.to_i)..10).each { |mnt| ok_oses << "#{major}.#{minor}.#{mnt}" }
|
|
203
|
+
|
|
204
|
+
# then expand the minors out to their max
|
|
205
|
+
# e.g. 11.3.x, ... 11.12.x
|
|
206
|
+
max_minor_for_major = MAC_OS_MAXS[major.to_i]
|
|
207
|
+
((minor.to_i + 1)..max_minor_for_major).each { |min| ok_oses << "#{major}.#{min}.x" }
|
|
208
|
+
|
|
209
|
+
# then add the majors out to 20
|
|
210
|
+
((major.to_i + 1)..20).each { |v| ok_oses << "#{v}.x" }
|
|
72
211
|
end
|
|
73
212
|
|
|
74
|
-
# now account for all OS X versions starting with 10.
|
|
75
|
-
# up to 10.30.x
|
|
76
|
-
((min.to_i + 1)..30).each do |v|
|
|
77
|
-
ok_oses << maj + '.' + v.to_s + '.x'
|
|
78
|
-
end # each v
|
|
79
213
|
ok_oses
|
|
80
|
-
end
|
|
214
|
+
end # def self.expand_min_os(min_os)
|
|
81
215
|
|
|
82
216
|
# Scripts and packages can have processor limitations.
|
|
83
217
|
# This method tests a given processor, against a requirement
|
|
@@ -95,6 +229,7 @@ module JSS
|
|
|
95
229
|
#
|
|
96
230
|
def self.processor_ok?(requirement, processor = nil)
|
|
97
231
|
return true if requirement.to_s.empty? || requirement =~ /none/i
|
|
232
|
+
|
|
98
233
|
processor ||= `/usr/bin/uname -p`
|
|
99
234
|
requirement == (processor.to_s.include?('86') ? 'x86' : 'ppc')
|
|
100
235
|
end
|
|
@@ -115,6 +250,7 @@ module JSS
|
|
|
115
250
|
def self.os_ok?(requirement, os_to_check = nil)
|
|
116
251
|
return true if requirement.to_s =~ /none/i
|
|
117
252
|
return true if requirement.to_s == 'n'
|
|
253
|
+
|
|
118
254
|
requirement = JSS.to_s_and_a(requirement)[:arrayform]
|
|
119
255
|
return true if requirement.empty?
|
|
120
256
|
|
|
@@ -174,19 +310,26 @@ module JSS
|
|
|
174
310
|
{ stringform: valstr, arrayform: valarr }
|
|
175
311
|
end # to_s_and_a
|
|
176
312
|
|
|
177
|
-
# Parse a plist into a Ruby data structure.
|
|
178
|
-
#
|
|
179
|
-
#
|
|
313
|
+
# Parse a plist into a Ruby data structure. The plist parameter may be
|
|
314
|
+
# a String containing an XML plist, or a path to a plist file, or it may be
|
|
315
|
+
# a Pathname object pointing to a plist file. The plist files may be XML or
|
|
316
|
+
# binary.
|
|
180
317
|
#
|
|
181
318
|
# @param plist[Pathname, String] the plist XML, or the path to a plist file
|
|
182
319
|
#
|
|
320
|
+
# @param symbol_keys[Boolean] should any Hash keys in the result be converted
|
|
321
|
+
# into Symbols rather than remain as Strings?
|
|
322
|
+
#
|
|
183
323
|
# @return [Object] the parsed plist as a ruby hash,array, etc.
|
|
184
324
|
#
|
|
185
|
-
def self.parse_plist(plist)
|
|
325
|
+
def self.parse_plist(plist, symbol_keys: false)
|
|
326
|
+
require 'cfpropertylist'
|
|
327
|
+
|
|
186
328
|
# did we get a string of xml, or a string pathname?
|
|
187
329
|
case plist
|
|
188
330
|
when String
|
|
189
|
-
return
|
|
331
|
+
return CFPropertyList.native_types(CFPropertyList::List.new(data: plist).value, symbol_keys) if plist.include? '</plist>'
|
|
332
|
+
|
|
190
333
|
plist = Pathname.new plist
|
|
191
334
|
when Pathname
|
|
192
335
|
true
|
|
@@ -197,9 +340,30 @@ module JSS
|
|
|
197
340
|
# if we're here, its a Pathname
|
|
198
341
|
raise JSS::MissingDataError, "No such file: #{plist}" unless plist.file?
|
|
199
342
|
|
|
200
|
-
|
|
343
|
+
CFPropertyList.native_types(CFPropertyList::List.new(file: plist).value, symbol_keys)
|
|
201
344
|
end # parse_plist
|
|
202
345
|
|
|
346
|
+
# Convert any ruby data to an XML plist.
|
|
347
|
+
#
|
|
348
|
+
# NOTE: Binary data is tricky. Easiest way is to pass in a
|
|
349
|
+
# Pathname or IO object (anything that responds to `read` and
|
|
350
|
+
# returns a bytestring)
|
|
351
|
+
# and then the CFPropertyList.guess method will read it and
|
|
352
|
+
# convert it to a Plist <data> element with base64 encoded
|
|
353
|
+
# data.
|
|
354
|
+
# For more info, see CFPropertyList.guess
|
|
355
|
+
#
|
|
356
|
+
# @param data [Object] the data to be converted, usually a Hash
|
|
357
|
+
#
|
|
358
|
+
# @return [String] the object converted into an XML plist
|
|
359
|
+
#
|
|
360
|
+
def self.xml_plist_from(data)
|
|
361
|
+
require 'cfpropertylist'
|
|
362
|
+
plist = CFPropertyList::List.new
|
|
363
|
+
plist.value = CFPropertyList.guess(data, convert_unknown_to_string: true)
|
|
364
|
+
plist.to_str(CFPropertyList::List::FORMAT_XML)
|
|
365
|
+
end
|
|
366
|
+
|
|
203
367
|
# Converts anything that responds to #to_s to a Time, or nil
|
|
204
368
|
#
|
|
205
369
|
# Return nil if the item is nil, 0 or an empty String.
|
|
@@ -223,9 +387,7 @@ module JSS
|
|
|
223
387
|
|
|
224
388
|
# if the UTC offset of the datetime is zero, make a new one with the correct local offset
|
|
225
389
|
# (which might also be zero if we happen to be in GMT)
|
|
226
|
-
if the_dt.offset.zero?
|
|
227
|
-
the_dt = DateTime.new(the_dt.year, the_dt.month, the_dt.day, the_dt.hour, the_dt.min, the_dt.sec, JSS::TIME_ZONE_OFFSET)
|
|
228
|
-
end
|
|
390
|
+
the_dt = DateTime.new(the_dt.year, the_dt.month, the_dt.day, the_dt.hour, the_dt.min, the_dt.sec, JSS::TIME_ZONE_OFFSET) if the_dt.offset.zero?
|
|
229
391
|
# now convert it to a Time and return it
|
|
230
392
|
Time.at the_dt.strftime('%s').to_i, usec
|
|
231
393
|
end # parse_time
|
|
@@ -247,6 +409,7 @@ module JSS
|
|
|
247
409
|
#
|
|
248
410
|
def self.epoch_to_time(epoch)
|
|
249
411
|
return nil if NIL_DATES.include? epoch
|
|
412
|
+
|
|
250
413
|
Time.at(epoch.to_i / 1000.0)
|
|
251
414
|
end # parse_date
|
|
252
415
|
|
|
@@ -266,6 +429,7 @@ module JSS
|
|
|
266
429
|
def self.api_object_class(name)
|
|
267
430
|
klass = api_object_names[name.downcase.to_sym]
|
|
268
431
|
raise JSS::InvalidDataError, "Unknown API Object Class: #{name}" unless klass
|
|
432
|
+
|
|
269
433
|
klass
|
|
270
434
|
end
|
|
271
435
|
|
|
@@ -283,11 +447,13 @@ module JSS
|
|
|
283
447
|
#
|
|
284
448
|
def self.api_object_names
|
|
285
449
|
return @api_object_names if @api_object_names
|
|
450
|
+
|
|
286
451
|
@api_object_names ||= {}
|
|
287
452
|
JSS.constants.each do |const|
|
|
288
453
|
klass = JSS.const_get const
|
|
289
454
|
next unless klass.is_a? Class
|
|
290
455
|
next unless klass.ancestors.include? JSS::APIObject
|
|
456
|
+
|
|
291
457
|
@api_object_names[klass.const_get(:RSRC_LIST_KEY).to_sym] = klass if klass.constants.include? :RSRC_LIST_KEY
|
|
292
458
|
@api_object_names[klass.const_get(:RSRC_OBJECT_KEY).to_sym] = klass if klass.constants.include? :RSRC_OBJECT_KEY
|
|
293
459
|
end
|
|
@@ -324,6 +490,7 @@ module JSS
|
|
|
324
490
|
#
|
|
325
491
|
def self.array_to_rexml_array(element, list)
|
|
326
492
|
raise JSS::InvalidDataError, 'Arg. must be an Array.' unless list.is_a? Array
|
|
493
|
+
|
|
327
494
|
element = element.to_s
|
|
328
495
|
list.map do |v|
|
|
329
496
|
e = REXML::Element.new(element)
|
|
@@ -350,6 +517,7 @@ module JSS
|
|
|
350
517
|
#
|
|
351
518
|
def self.hash_to_rexml_array(hash)
|
|
352
519
|
raise InvalidDataError, 'Arg. must be a Hash.' unless hash.is_a? Hash
|
|
520
|
+
|
|
353
521
|
ary = []
|
|
354
522
|
hash.each_pair do |k, v|
|
|
355
523
|
el = REXML::Element.new k.to_s
|
|
@@ -428,11 +596,11 @@ module JSS
|
|
|
428
596
|
|
|
429
597
|
{
|
|
430
598
|
major: major.to_i,
|
|
431
|
-
minor:
|
|
432
|
-
revision:
|
|
433
|
-
maint:
|
|
434
|
-
patch:
|
|
435
|
-
build:
|
|
599
|
+
minor: minor.to_i,
|
|
600
|
+
revision: revision.to_i,
|
|
601
|
+
maint: revision.to_i,
|
|
602
|
+
patch: revision.to_i,
|
|
603
|
+
build: build,
|
|
436
604
|
version: Gem::Version.new("#{major}.#{minor}.#{revision}")
|
|
437
605
|
}
|
|
438
606
|
end
|
|
@@ -457,6 +625,7 @@ module JSS
|
|
|
457
625
|
@stdin_lines ||= ($stdin.tty? ? [] : $stdin.read.lines.map { |l| l.chomp("\n") })
|
|
458
626
|
|
|
459
627
|
return @stdin_lines.join("\n") if line <= 0
|
|
628
|
+
|
|
460
629
|
idx = line - 1
|
|
461
630
|
@stdin_lines[idx]
|
|
462
631
|
end
|
|
@@ -489,10 +658,9 @@ module JSS
|
|
|
489
658
|
# @return [Boolean] The new state of devmode
|
|
490
659
|
#
|
|
491
660
|
def self.devmode(setting)
|
|
492
|
-
@devmode = setting == :on
|
|
661
|
+
@devmode = setting == :on
|
|
493
662
|
end
|
|
494
663
|
|
|
495
|
-
|
|
496
664
|
# is devmode currently on?
|
|
497
665
|
#
|
|
498
666
|
# @return [Boolean]
|