ruby-jss 0.6.5 → 0.6.6
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 +57 -5
- data/lib/jss.rb +78 -94
- data/lib/jss/api_connection.rb +8 -0
- data/lib/jss/api_object.rb +126 -102
- data/lib/jss/api_object/creatable.rb +33 -15
- data/lib/jss/api_object/distribution_point.rb +4 -1
- data/lib/jss/api_object/extension_attribute.rb +1 -1
- data/lib/jss/api_object/package.rb +121 -187
- data/lib/jss/api_object/policy.rb +590 -251
- data/lib/jss/api_object/script.rb +92 -128
- data/lib/jss/api_object/self_servable.rb +93 -117
- data/lib/jss/api_object/updatable.rb +12 -27
- data/lib/jss/api_object/uploadable.rb +12 -15
- data/lib/jss/client.rb +178 -156
- data/lib/jss/db_connection.rb +34 -49
- data/lib/jss/ruby_extensions/string.rb +25 -21
- data/lib/jss/version.rb +1 -1
- data/lib/jss/webhooks.rb +52 -0
- data/lib/jss/webhooks/README.md +269 -0
- data/lib/jss/webhooks/configuration.rb +212 -0
- data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation-executable +90 -0
- data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation.rb +44 -0
- data/lib/jss/webhooks/data/sample_jsons/ComputerAdded.json +27 -0
- data/lib/jss/webhooks/data/sample_jsons/ComputerCheckIn.json +27 -0
- data/lib/jss/webhooks/data/sample_jsons/ComputerInventoryCompleted.json +27 -0
- data/lib/jss/webhooks/data/sample_jsons/ComputerPolicyFinished.json +27 -0
- data/lib/jss/webhooks/data/sample_jsons/ComputerPushCapabilityChanged.json +27 -0
- data/lib/jss/webhooks/data/sample_jsons/JSSShutdown.json +14 -0
- data/lib/jss/webhooks/data/sample_jsons/JSSStartup.json +14 -0
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCheckIn.json +26 -0
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCommandCompleted.json +26 -0
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceEnrolled.json +26 -0
- data/lib/jss/webhooks/data/sample_jsons/MobileDevicePushSent.json +26 -0
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceUnEnrolled.json +26 -0
- data/lib/jss/webhooks/data/sample_jsons/PatchSoftwareTitleUpdated.json +14 -0
- data/lib/jss/webhooks/data/sample_jsons/PushSent.json +11 -0
- data/lib/jss/webhooks/data/sample_jsons/RestAPIOperation.json +15 -0
- data/lib/jss/webhooks/data/sample_jsons/SCEPChallenge.json +10 -0
- data/lib/jss/webhooks/data/sample_jsons/SmartGroupComputerMembershipChange.json +13 -0
- data/lib/jss/webhooks/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +13 -0
- data/lib/jss/webhooks/event.rb +138 -0
- data/lib/jss/webhooks/event/computer_added.rb +37 -0
- data/lib/jss/webhooks/event/computer_check_in.rb +37 -0
- data/lib/jss/webhooks/event/computer_inventory_completed.rb +37 -0
- data/lib/jss/webhooks/event/computer_policy_finished.rb +37 -0
- data/lib/jss/webhooks/event/computer_push_capability_changed.rb +37 -0
- data/lib/jss/webhooks/event/handlers.rb +191 -0
- data/lib/jss/webhooks/event/jss_shutdown.rb +37 -0
- data/lib/jss/webhooks/event/jss_startup.rb +37 -0
- data/lib/jss/webhooks/event/mobile_device_check_in.rb +37 -0
- data/lib/jss/webhooks/event/mobile_device_command_completed.rb +37 -0
- data/lib/jss/webhooks/event/mobile_device_enrolled.rb +37 -0
- data/lib/jss/webhooks/event/mobile_device_push_sent.rb +37 -0
- data/lib/jss/webhooks/event/mobile_device_unenrolled.rb +37 -0
- data/lib/jss/webhooks/event/patch_software_title_updated.rb +37 -0
- data/lib/jss/webhooks/event/push_sent.rb +37 -0
- data/lib/jss/webhooks/event/rest_api_operation.rb +37 -0
- data/lib/jss/webhooks/event/scep_challenge.rb +37 -0
- data/lib/jss/webhooks/event/smart_group_computer_membership_change.rb +37 -0
- data/lib/jss/webhooks/event/smart_group_mobile_device_membership_change.rb +37 -0
- data/lib/jss/webhooks/event/webhook.rb +39 -0
- data/lib/jss/webhooks/event_objects.rb +111 -0
- data/lib/jss/webhooks/event_objects/computer.rb +48 -0
- data/lib/jss/webhooks/event_objects/jss.rb +35 -0
- data/lib/jss/webhooks/event_objects/mobile_device.rb +47 -0
- data/lib/jss/webhooks/event_objects/patch_software_title_update.rb +37 -0
- data/lib/jss/webhooks/event_objects/push.rb +32 -0
- data/lib/jss/webhooks/event_objects/rest_api_operation.rb +36 -0
- data/lib/jss/webhooks/event_objects/scep_challenge.rb +31 -0
- data/lib/jss/webhooks/event_objects/smart_group.rb +34 -0
- data/lib/jss/webhooks/server_app.rb +36 -0
- data/lib/jss/webhooks/server_app/routes.rb +26 -0
- data/lib/jss/webhooks/server_app/routes/handle_webhook_event.rb +38 -0
- data/lib/jss/webhooks/server_app/routes/home.rb +36 -0
- data/lib/jss/webhooks/server_app/self_signed_cert.rb +64 -0
- data/lib/jss/webhooks/server_app/server.rb +59 -0
- data/lib/jss/webhooks/version.rb +31 -0
- metadata +63 -4
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
### Copyright 2016 Pixar
|
|
2
|
-
###
|
|
2
|
+
###
|
|
3
3
|
### Licensed under the Apache License, Version 2.0 (the "Apache License")
|
|
4
4
|
### with the following modification; you may not use this file except in
|
|
5
5
|
### compliance with the Apache License and the following modification to it:
|
|
6
6
|
### Section 6. Trademarks. is deleted and replaced with:
|
|
7
|
-
###
|
|
7
|
+
###
|
|
8
8
|
### 6. Trademarks. This License does not grant permission to use the trade
|
|
9
9
|
### names, trademarks, service marks, or product names of the Licensor
|
|
10
10
|
### and its affiliates, except as required to comply with Section 4(c) of
|
|
11
11
|
### the License and to reproduce the content of the NOTICE file.
|
|
12
|
-
###
|
|
12
|
+
###
|
|
13
13
|
### You may obtain a copy of the Apache License at
|
|
14
|
-
###
|
|
14
|
+
###
|
|
15
15
|
### http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
-
###
|
|
16
|
+
###
|
|
17
17
|
### Unless required by applicable law or agreed to in writing, software
|
|
18
18
|
### distributed under the Apache License with the above modification is
|
|
19
19
|
### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
20
20
|
### KIND, either express or implied. See the Apache License for the specific
|
|
21
21
|
### language governing permissions and limitations under the Apache License.
|
|
22
|
-
###
|
|
22
|
+
###
|
|
23
23
|
###
|
|
24
24
|
|
|
25
25
|
###
|
|
@@ -29,7 +29,6 @@ module JSS
|
|
|
29
29
|
### Module Variables
|
|
30
30
|
#####################################
|
|
31
31
|
|
|
32
|
-
|
|
33
32
|
#####################################
|
|
34
33
|
### Module Methods
|
|
35
34
|
#####################################
|
|
@@ -91,13 +90,12 @@ module JSS
|
|
|
91
90
|
### Constants
|
|
92
91
|
#####################################
|
|
93
92
|
|
|
94
|
-
UPLOAD_RSRC_PREFIX =
|
|
93
|
+
UPLOAD_RSRC_PREFIX = 'fileuploads'.freeze
|
|
95
94
|
|
|
96
95
|
#####################################
|
|
97
96
|
### Variables
|
|
98
97
|
#####################################
|
|
99
98
|
|
|
100
|
-
|
|
101
99
|
#####################################
|
|
102
100
|
### Methods
|
|
103
101
|
#####################################
|
|
@@ -115,22 +113,21 @@ module JSS
|
|
|
115
113
|
### @return [String] The xml response from the server.
|
|
116
114
|
###
|
|
117
115
|
def upload(type, local_file)
|
|
118
|
-
|
|
119
116
|
### the thing's gotta be in the JSS, and have an @id
|
|
120
|
-
raise JSS::NoSuchItemError, 'Create this #{self.class::RSRC_OBJECT_KEY} in the JSS before uploading files to it.' unless @id
|
|
117
|
+
raise JSS::NoSuchItemError, 'Create this #{self.class::RSRC_OBJECT_KEY} in the JSS before uploading files to it.' unless @id && @in_jss
|
|
121
118
|
|
|
122
119
|
### the type has to be defined in the class of self.
|
|
123
|
-
raise JSS::InvalidDataError, "#{self.class::RSRC_LIST_KEY} only take uploads of type: :#{self.class::UPLOAD_TYPES.keys.join(', :')}."
|
|
120
|
+
raise JSS::InvalidDataError, "#{self.class::RSRC_LIST_KEY} only take uploads of type: :#{self.class::UPLOAD_TYPES.keys.join(', :')}." \
|
|
121
|
+
unless self.class::UPLOAD_TYPES.keys.include? type
|
|
124
122
|
|
|
125
123
|
### figure out the resource after the UPLOAD_RSRC_PREFIX
|
|
126
124
|
upload_rsrc = "#{UPLOAD_RSRC_PREFIX}/#{self.class::UPLOAD_TYPES[type]}/id/#{@id}"
|
|
127
125
|
|
|
128
|
-
### make a File object to hand to REST.
|
|
126
|
+
### make a File object to hand to REST. 'rb' = read,binary
|
|
129
127
|
file = File.new local_file.to_s, 'rb'
|
|
130
128
|
|
|
131
129
|
### upload it!
|
|
132
|
-
JSS::API.cnx[upload_rsrc].post :
|
|
133
|
-
|
|
130
|
+
JSS::API.cnx[upload_rsrc].post name: file
|
|
134
131
|
end # def upload file
|
|
135
132
|
|
|
136
133
|
end # module FileUpload
|
data/lib/jss/client.rb
CHANGED
|
@@ -25,19 +25,15 @@
|
|
|
25
25
|
###
|
|
26
26
|
module JSS
|
|
27
27
|
|
|
28
|
-
#####################################
|
|
29
28
|
### Module Variables
|
|
30
29
|
#####################################
|
|
31
30
|
|
|
32
|
-
#####################################
|
|
33
31
|
### Module Methods
|
|
34
32
|
#####################################
|
|
35
33
|
|
|
36
|
-
#####################################
|
|
37
34
|
### Classes
|
|
38
35
|
#####################################
|
|
39
36
|
|
|
40
|
-
###
|
|
41
37
|
### This class represents a Casper/JSS Client computer, on which
|
|
42
38
|
### this code is running.
|
|
43
39
|
###
|
|
@@ -55,42 +51,42 @@ module JSS
|
|
|
55
51
|
|
|
56
52
|
### The Pathname to the jamf binary executable
|
|
57
53
|
### As of El Capitan (OS X 10.11) the location has moved.
|
|
58
|
-
ORIG_JAMF_BINARY = Pathname.new
|
|
59
|
-
ELCAP_JAMF_BINARY = Pathname.new
|
|
54
|
+
ORIG_JAMF_BINARY = Pathname.new '/usr/sbin/jamf'
|
|
55
|
+
ELCAP_JAMF_BINARY = Pathname.new '/usr/local/jamf/bin/jamf'
|
|
60
56
|
JAMF_BINARY = ELCAP_JAMF_BINARY.executable? ? ELCAP_JAMF_BINARY : ORIG_JAMF_BINARY
|
|
61
57
|
|
|
62
58
|
### The Pathname to the jamfHelper executable
|
|
63
|
-
JAMF_HELPER = Pathname.new
|
|
59
|
+
JAMF_HELPER = Pathname.new '/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper'
|
|
64
60
|
|
|
65
61
|
### The window_type options for jamfHelper
|
|
66
62
|
JAMF_HELPER_WINDOW_TYPES = {
|
|
67
|
-
:
|
|
68
|
-
:
|
|
69
|
-
:
|
|
70
|
-
:
|
|
71
|
-
:
|
|
72
|
-
}
|
|
63
|
+
hud: 'hud',
|
|
64
|
+
utility: 'utility',
|
|
65
|
+
util: 'utility',
|
|
66
|
+
full_screen: 'fs',
|
|
67
|
+
fs: 'fs'
|
|
68
|
+
}.freeze
|
|
73
69
|
|
|
74
70
|
### The possible window positions for jamfHelper
|
|
75
|
-
JAMF_HELPER_WINDOW_POSITIONS =
|
|
71
|
+
JAMF_HELPER_WINDOW_POSITIONS = [nil, :ul, :ll, :ur, :lr].freeze
|
|
76
72
|
|
|
77
73
|
### The available buttons in jamfHelper
|
|
78
|
-
JAMF_HELPER_BUTTONS = [1,2]
|
|
74
|
+
JAMF_HELPER_BUTTONS = [1, 2].freeze
|
|
79
75
|
|
|
80
76
|
### The possible alignment positions in jamfHelper
|
|
81
|
-
JAMF_HELPER_ALIGNMENTS = [:right, :left, :center, :justified, :natural]
|
|
77
|
+
JAMF_HELPER_ALIGNMENTS = [:right, :left, :center, :justified, :natural].freeze
|
|
82
78
|
|
|
83
79
|
### The Pathname to the preferences plist used by the jamf binary
|
|
84
|
-
JAMF_PLIST = Pathname.new
|
|
80
|
+
JAMF_PLIST = Pathname.new '/Library/Preferences/com.jamfsoftware.jamf.plist'
|
|
85
81
|
|
|
86
82
|
### The Pathname to the JAMF support folder
|
|
87
|
-
JAMF_SUPPORT_FOLDER = Pathname.new
|
|
83
|
+
JAMF_SUPPORT_FOLDER = Pathname.new '/Library/Application Support/JAMF'
|
|
88
84
|
|
|
89
85
|
### The JAMF receipts folder, where package installs are tracked.
|
|
90
|
-
RECEIPTS_FOLDER = JAMF_SUPPORT_FOLDER +
|
|
86
|
+
RECEIPTS_FOLDER = JAMF_SUPPORT_FOLDER + 'Receipts'
|
|
91
87
|
|
|
92
88
|
### The JAMF downloads folder
|
|
93
|
-
DOWNLOADS_FOLDER = JAMF_SUPPORT_FOLDER +
|
|
89
|
+
DOWNLOADS_FOLDER = JAMF_SUPPORT_FOLDER + 'Downloads'
|
|
94
90
|
|
|
95
91
|
### These jamf commands don't need root privs (most do)
|
|
96
92
|
ROOTLESS_JAMF_COMMANDS = [
|
|
@@ -100,7 +96,8 @@ module JSS
|
|
|
100
96
|
:getComputerName,
|
|
101
97
|
:help,
|
|
102
98
|
:listUsers,
|
|
103
|
-
:version
|
|
99
|
+
:version
|
|
100
|
+
].freeze
|
|
104
101
|
|
|
105
102
|
#####################################
|
|
106
103
|
### Class Variables
|
|
@@ -110,7 +107,6 @@ module JSS
|
|
|
110
107
|
### Class Methods
|
|
111
108
|
#####################################
|
|
112
109
|
|
|
113
|
-
###
|
|
114
110
|
### Get the current IP address as a String.
|
|
115
111
|
###
|
|
116
112
|
### This handy code doesn't acutally make a UDP connection,
|
|
@@ -125,7 +121,8 @@ module JSS
|
|
|
125
121
|
def self.my_ip_address
|
|
126
122
|
### turn off reverse DNS resolution temporarily
|
|
127
123
|
### @note the 'socket' library has already been required by 'rest-client'
|
|
128
|
-
orig
|
|
124
|
+
orig = Socket.do_not_reverse_lookup
|
|
125
|
+
Socket.do_not_reverse_lookup = true
|
|
129
126
|
|
|
130
127
|
UDPSocket.open do |s|
|
|
131
128
|
s.connect '192.168.0.0', 1
|
|
@@ -135,8 +132,23 @@ module JSS
|
|
|
135
132
|
Socket.do_not_reverse_lookup = orig
|
|
136
133
|
end
|
|
137
134
|
|
|
135
|
+
### Who's logged in to the console right now?
|
|
136
|
+
###
|
|
137
|
+
### @return [String, nil] the username of the current console user, or nil if none.
|
|
138
|
+
###
|
|
139
|
+
def self.console_user
|
|
140
|
+
cmd = '/usr/sbin/scutil'
|
|
141
|
+
qry = 'show State:/Users/ConsoleUser'
|
|
142
|
+
Open3.popen2e(cmd) do |cmdin, cmdouterr, _wait_thr|
|
|
143
|
+
cmdin.puts qry
|
|
144
|
+
cmdin.close
|
|
145
|
+
out = cmdouterr.read
|
|
146
|
+
user = out.lines.select { |l| l =~ /^\s+Name\s*:/ }.first.to_s.split(/\s*:\s*/).last
|
|
147
|
+
return user.nil? ? user : user.chomp
|
|
148
|
+
end # do
|
|
149
|
+
end
|
|
138
150
|
|
|
139
|
-
|
|
151
|
+
### Is the jamf binary installed?
|
|
140
152
|
###
|
|
141
153
|
### @return [Boolean] is the jamf binary installed?
|
|
142
154
|
###
|
|
@@ -144,50 +156,56 @@ module JSS
|
|
|
144
156
|
JAMF_BINARY.executable?
|
|
145
157
|
end
|
|
146
158
|
|
|
159
|
+
### What version of the jamf binary is installed?
|
|
147
160
|
###
|
|
148
161
|
### @return [String,nil] the version of the jamf binary installed on this client, nil if not installed
|
|
149
162
|
###
|
|
150
163
|
def self.jamf_version
|
|
151
|
-
|
|
164
|
+
installed? ? run_jamf(:version).chomp.split('=')[1] : nil
|
|
152
165
|
end
|
|
153
166
|
|
|
167
|
+
### the URL to the jss for this client
|
|
154
168
|
###
|
|
155
169
|
### @return [String] the url to the JSS for this client
|
|
156
170
|
###
|
|
157
171
|
def self.jss_url
|
|
158
|
-
@url =
|
|
172
|
+
@url = jamf_plist['jss_url']
|
|
159
173
|
return nil if @url.nil?
|
|
160
174
|
@url =~ %r{(https?)://(.+):(\d+)/}
|
|
161
|
-
@protocol =
|
|
162
|
-
@server =
|
|
163
|
-
@port =
|
|
164
|
-
|
|
175
|
+
@protocol = Regexp.last_match(1)
|
|
176
|
+
@server = Regexp.last_match(2)
|
|
177
|
+
@port = Regexp.last_match(3)
|
|
178
|
+
@url
|
|
165
179
|
end
|
|
166
180
|
|
|
181
|
+
### The JSS server hostname for this client
|
|
167
182
|
###
|
|
168
183
|
### @return [String] the JSS server for this client
|
|
169
184
|
###
|
|
170
185
|
def self.jss_server
|
|
171
|
-
|
|
172
|
-
|
|
186
|
+
jss_url
|
|
187
|
+
@server
|
|
173
188
|
end
|
|
174
189
|
|
|
190
|
+
### The protocol for JSS connections for this client
|
|
175
191
|
###
|
|
176
192
|
### @return [String] the protocol to the JSS for this client, "http" or "https"
|
|
177
193
|
###
|
|
178
194
|
def self.jss_protocol
|
|
179
|
-
|
|
180
|
-
|
|
195
|
+
jss_url
|
|
196
|
+
@protocol
|
|
181
197
|
end
|
|
182
198
|
|
|
199
|
+
### The port number for JSS connections for this client
|
|
183
200
|
###
|
|
184
201
|
### @return [Integer] the port to the JSS for this client
|
|
185
202
|
###
|
|
186
203
|
def self.jss_port
|
|
187
|
-
|
|
188
|
-
@port
|
|
204
|
+
jss_url
|
|
205
|
+
@port ? @port.to_i : 80
|
|
189
206
|
end
|
|
190
207
|
|
|
208
|
+
### The contents of the JAMF plist
|
|
191
209
|
###
|
|
192
210
|
### @return [Hash] the parsed contents of the JAMF_PLIST if it exists, an empty hash if not
|
|
193
211
|
###
|
|
@@ -196,58 +214,59 @@ module JSS
|
|
|
196
214
|
Plist.parse_xml `/usr/libexec/PlistBuddy -x -c print #{Shellwords.escape JSS::Client::JAMF_PLIST.to_s}`
|
|
197
215
|
end
|
|
198
216
|
|
|
199
|
-
|
|
217
|
+
### All the JAMF receipts on this client
|
|
200
218
|
###
|
|
201
219
|
### @return [Array<Pathname>] an array of Pathnames for all regular files in the jamf receipts folder
|
|
202
220
|
###
|
|
203
221
|
def self.receipts
|
|
204
222
|
raise JSS::NoSuchItemError, "The JAMF Receipts folder doesn't exist on this computer." unless RECEIPTS_FOLDER.exist?
|
|
205
|
-
RECEIPTS_FOLDER.children.select
|
|
223
|
+
RECEIPTS_FOLDER.children.select(&:file?)
|
|
206
224
|
end
|
|
207
225
|
|
|
226
|
+
### Is the JSS available right now?
|
|
208
227
|
###
|
|
209
228
|
### @return [Boolean] is the JSS available now?
|
|
210
229
|
###
|
|
211
230
|
def self.jss_available?
|
|
212
|
-
|
|
213
|
-
|
|
231
|
+
run_jamf :checkJSSConnection, '-retry 1'
|
|
232
|
+
$CHILD_STATUS.exitstatus.zero?
|
|
214
233
|
end
|
|
215
234
|
|
|
216
|
-
|
|
235
|
+
### The JSS::Computer object for this computer
|
|
217
236
|
###
|
|
218
|
-
### @return [JSS::Computer] The JSS record for this computer
|
|
237
|
+
### @return [JSS::Computer,nil] The JSS record for this computer, nil if not in the JSS
|
|
219
238
|
###
|
|
220
239
|
def self.jss_record
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
JSS::Computer.new :serial_number => self.serial_number
|
|
225
|
-
end
|
|
240
|
+
JSS::Computer.new udid: udid
|
|
241
|
+
rescue JSS::NoSuchItemError
|
|
242
|
+
nil
|
|
226
243
|
end
|
|
227
244
|
|
|
245
|
+
### The UUID for this computer via system_profiler
|
|
228
246
|
###
|
|
229
247
|
### @return [String] the UUID/UDID for this computer
|
|
230
248
|
###
|
|
231
249
|
def self.udid
|
|
232
|
-
|
|
250
|
+
hardware_data['platform_UUID']
|
|
233
251
|
end
|
|
234
252
|
|
|
253
|
+
### The serial number for this computer via system_profiler
|
|
235
254
|
###
|
|
236
255
|
### @return [String] the serial number for this computer
|
|
237
256
|
###
|
|
238
257
|
def self.serial_number
|
|
239
|
-
|
|
258
|
+
hardware_data['serial_number']
|
|
240
259
|
end
|
|
241
260
|
|
|
261
|
+
### The parsed HardwareDataType output from system_profiler
|
|
242
262
|
###
|
|
243
263
|
### @return [Hash] the HardwareDataType data from the system_profiler command
|
|
244
264
|
###
|
|
245
265
|
def self.hardware_data
|
|
246
266
|
raw = `/usr/sbin/system_profiler SPHardwareDataType -xml 2>/dev/null`
|
|
247
|
-
Plist.parse_xml(raw)[0][
|
|
267
|
+
Plist.parse_xml(raw)[0]['_items'][0]
|
|
248
268
|
end
|
|
249
269
|
|
|
250
|
-
|
|
251
270
|
### Run an arbitrary jamf binary command.
|
|
252
271
|
###
|
|
253
272
|
### @note Most jamf commands require superuser/root privileges.
|
|
@@ -275,22 +294,23 @@ module JSS
|
|
|
275
294
|
### The details of the Process::Status for the jamf binary process can be captured from $?
|
|
276
295
|
### immediately after calling. (See Process::Status)
|
|
277
296
|
###
|
|
278
|
-
def self.run_jamf(command, args = nil, verbose
|
|
279
|
-
raise JSS::UnmanagedError,
|
|
280
|
-
raise JSS::UnsupportedError,
|
|
297
|
+
def self.run_jamf(command, args = nil, verbose = false)
|
|
298
|
+
raise JSS::UnmanagedError, 'The jamf binary is not installed on this computer.' unless installed?
|
|
299
|
+
raise JSS::UnsupportedError, 'You must have root privileges to run that jamf binary command' unless \
|
|
300
|
+
ROOTLESS_JAMF_COMMANDS.include?(command.to_sym) || JSS.superuser?
|
|
281
301
|
|
|
282
302
|
cmd = case args
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
cmd +=
|
|
303
|
+
when nil
|
|
304
|
+
"#{JAMF_BINARY} #{command}"
|
|
305
|
+
when String
|
|
306
|
+
"#{JAMF_BINARY} #{command} #{args}"
|
|
307
|
+
when Array
|
|
308
|
+
([JAMF_BINARY.to_s, command] + args).join(' ').to_s
|
|
309
|
+
else
|
|
310
|
+
raise JSS::InvalidDataError, 'args must be a String or Array of Strings'
|
|
311
|
+
end # case
|
|
312
|
+
|
|
313
|
+
cmd += ' -verbose' if verbose && (!cmd.include? ' -verbose')
|
|
294
314
|
puts "Running: #{cmd}" if verbose
|
|
295
315
|
|
|
296
316
|
output = []
|
|
@@ -301,11 +321,10 @@ module JSS
|
|
|
301
321
|
end
|
|
302
322
|
end
|
|
303
323
|
install_out = output.join('')
|
|
304
|
-
install_out.force_encoding(
|
|
305
|
-
|
|
324
|
+
install_out.force_encoding('UTF-8') if install_out.respond_to? :force_encoding
|
|
325
|
+
install_out
|
|
306
326
|
end # run_jamf
|
|
307
327
|
|
|
308
|
-
|
|
309
328
|
### A wrapper for the jamfHelper command, which can display a window on the client machine.
|
|
310
329
|
###
|
|
311
330
|
### The first parameter must be a symbol defining what kind of window to display. The options are
|
|
@@ -345,7 +364,7 @@ module JSS
|
|
|
345
364
|
###
|
|
346
365
|
### @option opts :window_position [Symbol,nil] one of [ nil, :ul, :ll. :ur, :lr ]
|
|
347
366
|
### Positions window in the upper right, upper left, lower right or lower left of the user's screen
|
|
348
|
-
|
|
367
|
+
### If no input is given, the window defaults to the center of the screen
|
|
349
368
|
###
|
|
350
369
|
### @option opts :title [String]
|
|
351
370
|
### Sets the window's title to the specified string
|
|
@@ -354,13 +373,13 @@ module JSS
|
|
|
354
373
|
### Sets the heading of the window to the specified string
|
|
355
374
|
###
|
|
356
375
|
### @option opts :align_heading [Symbol] one of [:right, :left, :center, :justified, :natural]
|
|
357
|
-
|
|
376
|
+
### Aligns the heading to the specified alignment
|
|
358
377
|
###
|
|
359
378
|
### @option opts :description [String]
|
|
360
379
|
### Sets the main contents of the window to the specified string
|
|
361
380
|
###
|
|
362
381
|
### @option opts :align_description [Symbol] one of [:right, :left, :center, :justified, :natural]
|
|
363
|
-
|
|
382
|
+
### Aligns the description to the specified alignment
|
|
364
383
|
###
|
|
365
384
|
### @option opts :icon [String,Pathname]
|
|
366
385
|
### Sets the windows image field to the image located at the specified path
|
|
@@ -370,7 +389,7 @@ module JSS
|
|
|
370
389
|
###
|
|
371
390
|
### @option opts :full_screen_icon [any value]
|
|
372
391
|
### Scales the "icon" to the full size of the window.
|
|
373
|
-
|
|
392
|
+
### Note: Only available in full screen mode
|
|
374
393
|
###
|
|
375
394
|
### @option opts :button1 [String]
|
|
376
395
|
### Creates a button with the specified label
|
|
@@ -379,17 +398,17 @@ module JSS
|
|
|
379
398
|
### Creates a second button with the specified label
|
|
380
399
|
###
|
|
381
400
|
### @option opts :default_button [Integer] either 1 or 2
|
|
382
|
-
|
|
401
|
+
### Sets the default button of the window to the specified button. The Default Button will respond to "return"
|
|
383
402
|
###
|
|
384
403
|
### @option opts :cancel_button [Integer] either 1 or 2
|
|
385
|
-
|
|
404
|
+
### Sets the cancel button of the window to the specified button. The Cancel Button will respond to "escape"
|
|
386
405
|
###
|
|
387
406
|
### @option opts :timeout [Integer]
|
|
388
407
|
### Causes the window to timeout after the specified amount of seconds
|
|
389
|
-
|
|
408
|
+
### Note: The timeout will cause the default button, button 1 or button 2 to be selected (in that order)
|
|
390
409
|
###
|
|
391
410
|
### @option opts :show_delay_options [String,Array<Integer>] A String of comma-separated Integers, or an Array of Integers.
|
|
392
|
-
|
|
411
|
+
### Enables the "Delay Options Mode". The window will display a dropdown with the values passed through the string
|
|
393
412
|
###
|
|
394
413
|
### @option opts :countdown [any value]
|
|
395
414
|
### Displays a string notifying the user when the window will time out
|
|
@@ -403,8 +422,7 @@ module JSS
|
|
|
403
422
|
### @return [Integer] the exit status of the jamfHelper command. See above.
|
|
404
423
|
###
|
|
405
424
|
def self.jamf_helper(window_type = :hud, opts = {})
|
|
406
|
-
|
|
407
|
-
raise JSS::UnmanagedError, "The jamfHelper app is not installed properly on this computer." unless JAMF_HELPER.executable?
|
|
425
|
+
raise JSS::UnmanagedError, 'The jamfHelper app is not installed properly on this computer.' unless JAMF_HELPER.executable?
|
|
408
426
|
|
|
409
427
|
unless JAMF_HELPER_WINDOW_TYPES.include? window_type
|
|
410
428
|
raise JSS::InvalidDataError, "The first parameter must be a window type, one of :#{JAMF_HELPER_WINDOW_TYPES.keys.join(', :')}."
|
|
@@ -412,93 +430,97 @@ module JSS
|
|
|
412
430
|
|
|
413
431
|
# start building the arg array
|
|
414
432
|
|
|
415
|
-
args = [
|
|
433
|
+
args = ['-startlaunchd', '-windowType', JAMF_HELPER_WINDOW_TYPES[window_type]]
|
|
416
434
|
|
|
417
435
|
opts.keys.each do |opt|
|
|
418
436
|
case opt
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
437
|
+
when :window_position
|
|
438
|
+
raise JSS::InvalidDataError, ":window_position must be one of :#{JAMF_HELPER_WINDOW_POSITIONS.join(', :')}." unless \
|
|
439
|
+
JAMF_HELPER_WINDOW_POSITIONS.include? opts[opt].to_sym
|
|
440
|
+
args << '-windowPosition'
|
|
441
|
+
args << opts[opt].to_s
|
|
442
|
+
|
|
443
|
+
when :title
|
|
444
|
+
args << '-title'
|
|
445
|
+
args << opts[opt].to_s
|
|
446
|
+
|
|
447
|
+
when :heading
|
|
448
|
+
args << '-heading'
|
|
449
|
+
args << opts[opt].to_s
|
|
450
|
+
|
|
451
|
+
when :align_heading
|
|
452
|
+
raise JSS::InvalidDataError, ":align_heading must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless \
|
|
453
|
+
JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
|
|
454
|
+
args << '-alignHeading'
|
|
455
|
+
args << opts[opt].to_s
|
|
456
|
+
|
|
457
|
+
when :description
|
|
458
|
+
args << '-description'
|
|
459
|
+
args << opts[opt].to_s
|
|
460
|
+
|
|
461
|
+
when :align_description
|
|
462
|
+
raise JSS::InvalidDataError, ":align_description must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless \
|
|
463
|
+
JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
|
|
464
|
+
args << '-alignDescription'
|
|
465
|
+
args << opts[opt].to_s
|
|
466
|
+
|
|
467
|
+
when :icon
|
|
468
|
+
args << '-icon'
|
|
469
|
+
args << opts[opt].to_s
|
|
470
|
+
|
|
471
|
+
when :icon_size
|
|
472
|
+
args << '-iconSize'
|
|
473
|
+
args << opts[opt].to_s
|
|
474
|
+
|
|
475
|
+
when :full_screen_icon
|
|
476
|
+
args << '-fullScreenIcon'
|
|
477
|
+
|
|
478
|
+
when :button1
|
|
479
|
+
args << '-button1'
|
|
480
|
+
args << opts[opt].to_s
|
|
481
|
+
|
|
482
|
+
when :button2
|
|
483
|
+
args << '-button2'
|
|
484
|
+
args << opts[opt].to_s
|
|
485
|
+
|
|
486
|
+
when :default_button
|
|
487
|
+
raise JSS::InvalidDataError, ":default_button must be one of #{JAMF_HELPER_BUTTONS.join(', ')}." unless \
|
|
488
|
+
JAMF_HELPER_BUTTONS.include? opts[opt]
|
|
489
|
+
args << '-defaultButton'
|
|
490
|
+
args << opts[opt].to_s
|
|
491
|
+
|
|
492
|
+
when :cancel_button
|
|
493
|
+
raise JSS::InvalidDataError, ":cancel_button must be one of #{JAMF_HELPER_BUTTONS.join(', ')}." unless \
|
|
494
|
+
JAMF_HELPER_BUTTONS.include? opts[opt]
|
|
495
|
+
args << '-cancelButton'
|
|
496
|
+
args << opts[opt].to_s
|
|
497
|
+
|
|
498
|
+
when :timeout
|
|
499
|
+
args << '-timeout'
|
|
500
|
+
args << opts[opt].to_s
|
|
501
|
+
|
|
502
|
+
when :show_delay_options
|
|
503
|
+
args << '-showDelayOptions'
|
|
504
|
+
args << JSS.to_s_and_a(opts[opt])[:arrayform].join(', ')
|
|
505
|
+
|
|
506
|
+
when :countdown
|
|
507
|
+
args << '-countdown'
|
|
508
|
+
|
|
509
|
+
when :align_countdown
|
|
510
|
+
raise JSS::InvalidDataError, ":align_countdown must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless \
|
|
511
|
+
JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
|
|
512
|
+
args << '-alignCountdown'
|
|
513
|
+
args << opts[opt].to_s
|
|
514
|
+
|
|
515
|
+
when :lock_hud
|
|
516
|
+
args << '-lockHUD'
|
|
493
517
|
end # case opt
|
|
494
518
|
end # each do opt
|
|
495
519
|
|
|
496
520
|
system JAMF_HELPER.to_s, *args
|
|
497
|
-
|
|
498
|
-
|
|
521
|
+
$CHILD_STATUS.exitstatus
|
|
499
522
|
end # def self.jamf_helper
|
|
500
523
|
|
|
501
|
-
|
|
502
524
|
end # class Client
|
|
503
525
|
|
|
504
526
|
end # module
|