ruby-jss 1.4.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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]
|