ruby-jss 0.7.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby-jss might be problematic. Click here for more details.

Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +29 -22
  3. data/README.md +66 -86
  4. data/bin/jamfHelperBackgrounder +148 -0
  5. data/bin/netseg-update +0 -1
  6. data/lib/jss.rb +20 -9
  7. data/lib/jss/api_connection.rb +369 -295
  8. data/lib/jss/api_object.rb +651 -418
  9. data/lib/jss/api_object/account.rb +69 -77
  10. data/lib/jss/api_object/advanced_search.rb +201 -236
  11. data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +42 -42
  12. data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +33 -43
  13. data/lib/jss/api_object/advanced_search/advanced_user_search.rb +33 -43
  14. data/lib/jss/api_object/building.rb +39 -52
  15. data/lib/jss/api_object/categorizable.rb +221 -0
  16. data/lib/jss/api_object/category.rb +81 -89
  17. data/lib/jss/api_object/computer.rb +486 -525
  18. data/lib/jss/api_object/computer_invitation.rb +73 -86
  19. data/lib/jss/api_object/criteriable.rb +6 -7
  20. data/lib/jss/api_object/ebook.rb +21 -0
  21. data/lib/jss/api_object/extendable.rb +6 -8
  22. data/lib/jss/api_object/group.rb +0 -3
  23. data/lib/jss/api_object/locatable.rb +19 -20
  24. data/lib/jss/api_object/mac_application.rb +21 -0
  25. data/lib/jss/api_object/mobile_device.rb +30 -21
  26. data/lib/jss/api_object/mobile_device_application.rb +447 -0
  27. data/lib/jss/api_object/mobile_device_configuration_profile.rb +21 -0
  28. data/lib/jss/api_object/osx_configuration_profile.rb +0 -3
  29. data/lib/jss/api_object/package.rb +21 -34
  30. data/lib/jss/api_object/peripheral.rb +16 -18
  31. data/lib/jss/api_object/policy.rb +5 -83
  32. data/lib/jss/api_object/purchasable.rb +11 -13
  33. data/lib/jss/api_object/scopable.rb +11 -12
  34. data/lib/jss/api_object/script.rb +3 -17
  35. data/lib/jss/api_object/self_servable.rb +419 -205
  36. data/lib/jss/api_object/self_servable/icon.rb +179 -0
  37. data/lib/jss/api_object/updatable.rb +35 -34
  38. data/lib/jss/api_object/uploadable.rb +72 -70
  39. data/lib/jss/api_object/user.rb +6 -7
  40. data/lib/jss/api_object/vppable.rb +117 -0
  41. data/lib/jss/client.rb +264 -225
  42. data/lib/jss/db_connection.rb +7 -5
  43. data/lib/jss/exceptions.rb +50 -42
  44. data/lib/jss/ruby_extensions.rb +8 -7
  45. data/lib/jss/ruby_extensions/object.rb +19 -0
  46. data/lib/jss/utility.rb +82 -40
  47. data/lib/jss/version.rb +1 -1
  48. metadata +37 -68
  49. data/bin/jss-webhook-server +0 -3
  50. data/lib/jss/webhooks.rb +0 -53
  51. data/lib/jss/webhooks/README.md +0 -269
  52. data/lib/jss/webhooks/configuration.rb +0 -213
  53. data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation-executable +0 -91
  54. data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation.rb +0 -45
  55. data/lib/jss/webhooks/data/sample_jsons/ComputerAdded.json +0 -27
  56. data/lib/jss/webhooks/data/sample_jsons/ComputerCheckIn.json +0 -27
  57. data/lib/jss/webhooks/data/sample_jsons/ComputerInventoryCompleted.json +0 -27
  58. data/lib/jss/webhooks/data/sample_jsons/ComputerPolicyFinished.json +0 -27
  59. data/lib/jss/webhooks/data/sample_jsons/ComputerPushCapabilityChanged.json +0 -27
  60. data/lib/jss/webhooks/data/sample_jsons/JSSShutdown.json +0 -14
  61. data/lib/jss/webhooks/data/sample_jsons/JSSStartup.json +0 -14
  62. data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCheckIn.json +0 -26
  63. data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCommandCompleted.json +0 -26
  64. data/lib/jss/webhooks/data/sample_jsons/MobileDeviceEnrolled.json +0 -26
  65. data/lib/jss/webhooks/data/sample_jsons/MobileDevicePushSent.json +0 -26
  66. data/lib/jss/webhooks/data/sample_jsons/MobileDeviceUnEnrolled.json +0 -26
  67. data/lib/jss/webhooks/data/sample_jsons/PatchSoftwareTitleUpdated.json +0 -14
  68. data/lib/jss/webhooks/data/sample_jsons/PushSent.json +0 -11
  69. data/lib/jss/webhooks/data/sample_jsons/RestAPIOperation.json +0 -15
  70. data/lib/jss/webhooks/data/sample_jsons/SCEPChallenge.json +0 -10
  71. data/lib/jss/webhooks/data/sample_jsons/SmartGroupComputerMembershipChange.json +0 -13
  72. data/lib/jss/webhooks/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +0 -13
  73. data/lib/jss/webhooks/event.rb +0 -139
  74. data/lib/jss/webhooks/event/computer_added.rb +0 -38
  75. data/lib/jss/webhooks/event/computer_check_in.rb +0 -38
  76. data/lib/jss/webhooks/event/computer_inventory_completed.rb +0 -38
  77. data/lib/jss/webhooks/event/computer_policy_finished.rb +0 -38
  78. data/lib/jss/webhooks/event/computer_push_capability_changed.rb +0 -38
  79. data/lib/jss/webhooks/event/handlers.rb +0 -192
  80. data/lib/jss/webhooks/event/jss_shutdown.rb +0 -38
  81. data/lib/jss/webhooks/event/jss_startup.rb +0 -38
  82. data/lib/jss/webhooks/event/mobile_device_check_in.rb +0 -38
  83. data/lib/jss/webhooks/event/mobile_device_command_completed.rb +0 -38
  84. data/lib/jss/webhooks/event/mobile_device_enrolled.rb +0 -38
  85. data/lib/jss/webhooks/event/mobile_device_push_sent.rb +0 -38
  86. data/lib/jss/webhooks/event/mobile_device_unenrolled.rb +0 -38
  87. data/lib/jss/webhooks/event/patch_software_title_updated.rb +0 -38
  88. data/lib/jss/webhooks/event/push_sent.rb +0 -38
  89. data/lib/jss/webhooks/event/rest_api_operation.rb +0 -38
  90. data/lib/jss/webhooks/event/scep_challenge.rb +0 -38
  91. data/lib/jss/webhooks/event/smart_group_computer_membership_change.rb +0 -38
  92. data/lib/jss/webhooks/event/smart_group_mobile_device_membership_change.rb +0 -38
  93. data/lib/jss/webhooks/event/webhook.rb +0 -40
  94. data/lib/jss/webhooks/event_objects.rb +0 -112
  95. data/lib/jss/webhooks/event_objects/computer.rb +0 -49
  96. data/lib/jss/webhooks/event_objects/jss.rb +0 -36
  97. data/lib/jss/webhooks/event_objects/mobile_device.rb +0 -48
  98. data/lib/jss/webhooks/event_objects/patch_software_title_update.rb +0 -38
  99. data/lib/jss/webhooks/event_objects/push.rb +0 -33
  100. data/lib/jss/webhooks/event_objects/rest_api_operation.rb +0 -37
  101. data/lib/jss/webhooks/event_objects/scep_challenge.rb +0 -32
  102. data/lib/jss/webhooks/event_objects/smart_group.rb +0 -35
  103. data/lib/jss/webhooks/server_app.rb +0 -37
  104. data/lib/jss/webhooks/server_app/routes.rb +0 -27
  105. data/lib/jss/webhooks/server_app/routes/handle_webhook_event.rb +0 -39
  106. data/lib/jss/webhooks/server_app/routes/home.rb +0 -37
  107. data/lib/jss/webhooks/server_app/self_signed_cert.rb +0 -65
  108. data/lib/jss/webhooks/server_app/server.rb +0 -60
  109. data/lib/jss/webhooks/version.rb +0 -32
@@ -1,26 +1,26 @@
1
1
  ### Copyright 2017 Pixar
2
2
 
3
- ###
3
+ ###
4
4
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
5
  ### with the following modification; you may not use this file except in
6
6
  ### compliance with the Apache License and the following modification to it:
7
7
  ### Section 6. Trademarks. is deleted and replaced with:
8
- ###
8
+ ###
9
9
  ### 6. Trademarks. This License does not grant permission to use the trade
10
10
  ### names, trademarks, service marks, or product names of the Licensor
11
11
  ### and its affiliates, except as required to comply with Section 4(c) of
12
12
  ### the License and to reproduce the content of the NOTICE file.
13
- ###
13
+ ###
14
14
  ### You may obtain a copy of the Apache License at
15
- ###
15
+ ###
16
16
  ### http://www.apache.org/licenses/LICENSE-2.0
17
- ###
17
+ ###
18
18
  ### Unless required by applicable law or agreed to in writing, software
19
19
  ### distributed under the Apache License with the above modification is
20
20
  ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
21
  ### KIND, either express or implied. See the Apache License for the specific
22
22
  ### language governing permissions and limitations under the Apache License.
23
- ###
23
+ ###
24
24
  ###
25
25
 
26
26
  ###
@@ -172,7 +172,6 @@ module JSS
172
172
  @total_vpp_code_count = @init_data[:links][:total_vpp_code_count]
173
173
  end
174
174
 
175
- parse_ext_attrs
176
175
  end
177
176
 
178
177
  #####################################
@@ -0,0 +1,117 @@
1
+ ### Copyright 2017 Pixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+
26
+ ###
27
+ module JSS
28
+
29
+ # A mix-in module to handle VPP-related data in API objects that can be
30
+ # assigned via VPP.
31
+ #
32
+ # To use this module, merely `include VPPable` when defining your
33
+ # subclass of JSS::APIObject
34
+ #
35
+ # classes doing so MUST call {#add_vpp_xml(xmldoc)} in their {#rest_xml} method
36
+ #
37
+ module VPPable
38
+
39
+ # Mixed-in Constants
40
+ #####################################
41
+ VPPABLE = true
42
+
43
+ # Mixed-in Attributes
44
+ #####################################
45
+
46
+ # @return [Hash]
47
+ attr_reader :vpp_codes
48
+
49
+ # @return [Integer]
50
+ attr_reader :vpp_admin_account_id
51
+
52
+ # @return [Boolean]
53
+ attr_reader :assign_vpp_device_based_licenses
54
+ alias vpp_device_based? assign_vpp_device_based_licenses
55
+
56
+ # @return [Integer]
57
+ attr_reader :total_vpp_licenses
58
+ alias vpp_total_licenses total_vpp_licenses
59
+ alias vpp_license_count total_vpp_licenses
60
+
61
+ # @return [Integer]
62
+ attr_reader :remaining_vpp_licenses
63
+ alias vpp_licenses_remaining remaining_vpp_licenses
64
+
65
+ # @return [Integer]
66
+ attr_reader :used_vpp_licenses
67
+ alias vpp_licenses_used used_vpp_licenses
68
+
69
+
70
+ # Set whether or not the VPP licenses should be assigned
71
+ # by device rather than by user
72
+ #
73
+ # @param new_val[Boolean] The new value
74
+ #
75
+ # @return [void]
76
+ #
77
+ def assign_vpp_device_based_licenses=(new_val)
78
+ return nil if new_val == @assign_vpp_device_based_licenses
79
+ raise JSS::InvalidDataError, 'New value must be true or false' unless new_val.jss_boolean?
80
+ @assign_vpp_device_based_licenses = new_val
81
+ @need_to_update = true
82
+ end
83
+ alias vpp_device_based= assign_vpp_device_based_licenses=
84
+
85
+ # Mixed-in Private Instance Methods
86
+ #####################################
87
+ private
88
+
89
+ # Parse the vpp data from the incoming API data
90
+ #
91
+ # @return [void]
92
+ #
93
+ def parse_vpp
94
+ @vpp_codes = @init_data[:vpp_codes]
95
+ @vpp_admin_account_id = @init_data[:vpp][:vpp_admin_account_id]
96
+ @assign_vpp_device_based_licenses = @init_data[:vpp][:assign_vpp_device_based_licenses]
97
+ @total_vpp_licenses = @init_data[:vpp][:total_vpp_licenses]
98
+ @remaining_vpp_licenses = @init_data[:vpp][:remaining_vpp_licenses]
99
+ @used_vpp_licenses = @init_data[:vpp][:used_vpp_licenses]
100
+ end
101
+
102
+ # Insert an appropriate vpp element into the XML for sending changes
103
+ # to the JSS
104
+ #
105
+ # @param xdoc[REXML::Document] The XML document to work with
106
+ #
107
+ # @return [void]
108
+ #
109
+ def add_vpp_xml(xdoc)
110
+ doc_root = xdoc.root
111
+ vpp = doc_root.add_element 'vpp'
112
+ vpp.add_element('assign_vpp_device_based_licenses').text = @assign_vpp_device_based_licenses
113
+ end
114
+
115
+ end # VPPable
116
+
117
+ end # JSS
@@ -26,40 +26,39 @@
26
26
  ###
27
27
  module JSS
28
28
 
29
- ### Module Variables
29
+ # Module Variables
30
30
  #####################################
31
31
 
32
- ### Module Methods
32
+ # Module Methods
33
33
  #####################################
34
34
 
35
- ### Classes
35
+ # Classes
36
36
  #####################################
37
37
 
38
- ### This class represents a Casper/JSS Client computer, on which
39
- ### this code is running.
40
- ###
41
- ### Since the class represents the current machine, there's no need
42
- ### to make an instance of it, all methods are class methods.
43
- ###
44
- ### At the moment, only Macintosh computers are supported.
45
- ###
46
- ###
38
+ # This class represents a Casper/JSS Client computer, on which
39
+ # this code is running.
40
+ #
41
+ # Since the class represents the current machine, there's no need
42
+ # to make an instance of it, all methods are class methods.
43
+ #
44
+ # At the moment, only Macintosh computers are supported.
45
+ #
46
+ #
47
47
  class Client
48
48
 
49
- #####################################
50
- ### Class Constants
49
+ # Class Constants
51
50
  #####################################
52
51
 
53
- ### The Pathname to the jamf binary executable
54
- ### As of El Capitan (OS X 10.11) the location has moved.
52
+ # The Pathname to the jamf binary executable
53
+ # As of El Capitan (OS X 10.11) the location has moved.
55
54
  ORIG_JAMF_BINARY = Pathname.new '/usr/sbin/jamf'
56
55
  ELCAP_JAMF_BINARY = Pathname.new '/usr/local/jamf/bin/jamf'
57
56
  JAMF_BINARY = ELCAP_JAMF_BINARY.executable? ? ELCAP_JAMF_BINARY : ORIG_JAMF_BINARY
58
57
 
59
- ### The Pathname to the jamfHelper executable
58
+ # The Pathname to the jamfHelper executable
60
59
  JAMF_HELPER = Pathname.new '/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper'
61
60
 
62
- ### The window_type options for jamfHelper
61
+ # The window_type options for jamfHelper
63
62
  JAMF_HELPER_WINDOW_TYPES = {
64
63
  hud: 'hud',
65
64
  utility: 'utility',
@@ -68,28 +67,28 @@ module JSS
68
67
  fs: 'fs'
69
68
  }.freeze
70
69
 
71
- ### The possible window positions for jamfHelper
70
+ # The possible window positions for jamfHelper
72
71
  JAMF_HELPER_WINDOW_POSITIONS = [nil, :ul, :ll, :ur, :lr].freeze
73
72
 
74
- ### The available buttons in jamfHelper
73
+ # The available buttons in jamfHelper
75
74
  JAMF_HELPER_BUTTONS = [1, 2].freeze
76
75
 
77
- ### The possible alignment positions in jamfHelper
76
+ # The possible alignment positions in jamfHelper
78
77
  JAMF_HELPER_ALIGNMENTS = [:right, :left, :center, :justified, :natural].freeze
79
78
 
80
- ### The Pathname to the preferences plist used by the jamf binary
79
+ # The Pathname to the preferences plist used by the jamf binary
81
80
  JAMF_PLIST = Pathname.new '/Library/Preferences/com.jamfsoftware.jamf.plist'
82
81
 
83
- ### The Pathname to the JAMF support folder
82
+ # The Pathname to the JAMF support folder
84
83
  JAMF_SUPPORT_FOLDER = Pathname.new '/Library/Application Support/JAMF'
85
84
 
86
- ### The JAMF receipts folder, where package installs are tracked.
85
+ # The JAMF receipts folder, where package installs are tracked.
87
86
  RECEIPTS_FOLDER = JAMF_SUPPORT_FOLDER + 'Receipts'
88
87
 
89
- ### The JAMF downloads folder
88
+ # The JAMF downloads folder
90
89
  DOWNLOADS_FOLDER = JAMF_SUPPORT_FOLDER + 'Downloads'
91
90
 
92
- ### These jamf commands don't need root privs (most do)
91
+ # These jamf commands don't need root privs (most do)
93
92
  ROOTLESS_JAMF_COMMANDS = [
94
93
  :about,
95
94
  :checkJSSConnection,
@@ -101,27 +100,27 @@ module JSS
101
100
  ].freeze
102
101
 
103
102
  #####################################
104
- ### Class Variables
103
+ # Class Variables
105
104
  #####################################
106
105
 
107
106
  #####################################
108
- ### Class Methods
107
+ # Class Methods
109
108
  #####################################
110
109
 
111
- ### Get the current IP address as a String.
112
- ###
113
- ### This handy code doesn't acutally make a UDP connection,
114
- ### it just starts to set up the connection, then uses that to get
115
- ### the local IP.
116
- ###
117
- ### Lifted gratefully from
118
- ### http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
119
- ###
120
- ### @return [String] the current IP address.
121
- ###
110
+ # Get the current IP address as a String.
111
+ #
112
+ # This handy code doesn't acutally make a UDP connection,
113
+ # it just starts to set up the connection, then uses that to get
114
+ # the local IP.
115
+ #
116
+ # Lifted gratefully from
117
+ # http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
118
+ #
119
+ # @return [String] the current IP address.
120
+ #
122
121
  def self.my_ip_address
123
- ### turn off reverse DNS resolution temporarily
124
- ### @note the 'socket' library has already been required by 'rest-client'
122
+ # turn off reverse DNS resolution temporarily
123
+ # @note the 'socket' library has already been required by 'rest-client'
125
124
  orig = Socket.do_not_reverse_lookup
126
125
  Socket.do_not_reverse_lookup = true
127
126
 
@@ -133,10 +132,10 @@ module JSS
133
132
  Socket.do_not_reverse_lookup = orig
134
133
  end
135
134
 
136
- ### Who's logged in to the console right now?
137
- ###
138
- ### @return [String, nil] the username of the current console user, or nil if none.
139
- ###
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
+ #
140
139
  def self.console_user
141
140
  cmd = '/usr/sbin/scutil'
142
141
  qry = 'show State:/Users/ConsoleUser'
@@ -149,26 +148,26 @@ module JSS
149
148
  end # do
150
149
  end
151
150
 
152
- ### Is the jamf binary installed?
153
- ###
154
- ### @return [Boolean] is the jamf binary installed?
155
- ###
151
+ # Is the jamf binary installed?
152
+ #
153
+ # @return [Boolean] is the jamf binary installed?
154
+ #
156
155
  def self.installed?
157
156
  JAMF_BINARY.executable?
158
157
  end
159
158
 
160
- ### What version of the jamf binary is installed?
161
- ###
162
- ### @return [String,nil] the version of the jamf binary installed on this client, nil if not installed
163
- ###
159
+ # What version of the jamf binary is installed?
160
+ #
161
+ # @return [String,nil] the version of the jamf binary installed on this client, nil if not installed
162
+ #
164
163
  def self.jamf_version
165
164
  installed? ? run_jamf(:version).chomp.split('=')[1] : nil
166
165
  end
167
166
 
168
- ### the URL to the jss for this client
169
- ###
170
- ### @return [String] the url to the JSS for this client
171
- ###
167
+ # the URL to the jss for this client
168
+ #
169
+ # @return [String] the url to the JSS for this client
170
+ #
172
171
  def self.jss_url
173
172
  @url = jamf_plist['jss_url']
174
173
  return nil if @url.nil?
@@ -179,122 +178,122 @@ module JSS
179
178
  @url
180
179
  end
181
180
 
182
- ### The JSS server hostname for this client
183
- ###
184
- ### @return [String] the JSS server for this client
185
- ###
181
+ # The JSS server hostname for this client
182
+ #
183
+ # @return [String] the JSS server for this client
184
+ #
186
185
  def self.jss_server
187
186
  jss_url
188
187
  @server
189
188
  end
190
189
 
191
- ### The protocol for JSS connections for this client
192
- ###
193
- ### @return [String] the protocol to the JSS for this client, "http" or "https"
194
- ###
190
+ # The protocol for JSS connections for this client
191
+ #
192
+ # @return [String] the protocol to the JSS for this client, "http" or "https"
193
+ #
195
194
  def self.jss_protocol
196
195
  jss_url
197
196
  @protocol
198
197
  end
199
198
 
200
- ### The port number for JSS connections for this client
201
- ###
202
- ### @return [Integer] the port to the JSS for this client
203
- ###
199
+ # The port number for JSS connections for this client
200
+ #
201
+ # @return [Integer] the port to the JSS for this client
202
+ #
204
203
  def self.jss_port
205
204
  jss_url
206
- @port ? @port.to_i : 80
205
+ @port
207
206
  end
208
207
 
209
- ### The contents of the JAMF plist
210
- ###
211
- ### @return [Hash] the parsed contents of the JAMF_PLIST if it exists, an empty hash if not
212
- ###
208
+ # The contents of the JAMF plist
209
+ #
210
+ # @return [Hash] the parsed contents of the JAMF_PLIST if it exists, an empty hash if not
211
+ #
213
212
  def self.jamf_plist
214
213
  return {} unless JAMF_PLIST.file?
215
214
  Plist.parse_xml `/usr/libexec/PlistBuddy -x -c print #{Shellwords.escape JSS::Client::JAMF_PLIST.to_s}`
216
215
  end
217
216
 
218
- ### All the JAMF receipts on this client
219
- ###
220
- ### @return [Array<Pathname>] an array of Pathnames for all regular files in the jamf receipts folder
221
- ###
217
+ # All the JAMF receipts on this client
218
+ #
219
+ # @return [Array<Pathname>] an array of Pathnames for all regular files in the jamf receipts folder
220
+ #
222
221
  def self.receipts
223
222
  raise JSS::NoSuchItemError, "The JAMF Receipts folder doesn't exist on this computer." unless RECEIPTS_FOLDER.exist?
224
223
  RECEIPTS_FOLDER.children.select(&:file?)
225
224
  end
226
225
 
227
- ### Is the JSS available right now?
228
- ###
229
- ### @return [Boolean] is the JSS available now?
230
- ###
226
+ # Is the JSS available right now?
227
+ #
228
+ # @return [Boolean] is the JSS available now?
229
+ #
231
230
  def self.jss_available?
232
231
  run_jamf :checkJSSConnection, '-retry 1'
233
232
  $CHILD_STATUS.exitstatus.zero?
234
233
  end
235
234
 
236
- ### The JSS::Computer object for this computer
237
- ###
238
- ### @return [JSS::Computer,nil] The JSS record for this computer, nil if not in the JSS
239
- ###
235
+ # The JSS::Computer object for this computer
236
+ #
237
+ # @return [JSS::Computer,nil] The JSS record for this computer, nil if not in the JSS
238
+ #
240
239
  def self.jss_record
241
240
  JSS::Computer.new udid: udid
242
241
  rescue JSS::NoSuchItemError
243
242
  nil
244
243
  end
245
244
 
246
- ### The UUID for this computer via system_profiler
247
- ###
248
- ### @return [String] the UUID/UDID for this computer
249
- ###
245
+ # The UUID for this computer via system_profiler
246
+ #
247
+ # @return [String] the UUID/UDID for this computer
248
+ #
250
249
  def self.udid
251
250
  hardware_data['platform_UUID']
252
251
  end
253
252
 
254
- ### The serial number for this computer via system_profiler
255
- ###
256
- ### @return [String] the serial number for this computer
257
- ###
253
+ # The serial number for this computer via system_profiler
254
+ #
255
+ # @return [String] the serial number for this computer
256
+ #
258
257
  def self.serial_number
259
258
  hardware_data['serial_number']
260
259
  end
261
260
 
262
- ### The parsed HardwareDataType output from system_profiler
263
- ###
264
- ### @return [Hash] the HardwareDataType data from the system_profiler command
265
- ###
261
+ # The parsed HardwareDataType output from system_profiler
262
+ #
263
+ # @return [Hash] the HardwareDataType data from the system_profiler command
264
+ #
266
265
  def self.hardware_data
267
266
  raw = `/usr/sbin/system_profiler SPHardwareDataType -xml 2>/dev/null`
268
267
  Plist.parse_xml(raw)[0]['_items'][0]
269
268
  end
270
269
 
271
- ### Run an arbitrary jamf binary command.
272
- ###
273
- ### @note Most jamf commands require superuser/root privileges.
274
- ###
275
- ### @param command[String,Symbol] the jamf binary command to run
276
- ### The command is the single jamf command that comes after the/usr/bin/jamf.
277
- ###
278
- ### @param args[String,Array] the arguments passed to the jamf command.
279
- ### This is to be passed to Kernel.` (backtick), after being combined with the
280
- ### jamf binary and the jamf command
281
- ###
282
- ### @param verbose[Boolean] Should the stdout & stderr of the jamf binary be sent to
283
- ### the current stdout in realtime, as well as returned as a string?
284
- ###
285
- ### @return [String] the stdout & stderr of the jamf binary.
286
- ###
287
- ### @example
288
- ### These two are equivalent:
289
- ###
290
- ### JSS::Client.run_jamf "recon", "-assetTag 12345 -department 'IT Support'"
291
- ###
292
- ### JSS::Client.run_jamf :recon, ['-assetTag', '12345', '-department', 'IT Support'"]
293
- ###
294
- ###
295
- ### The details of the Process::Status for the jamf binary process can be captured from $?
296
- ### immediately after calling. (See Process::Status)
297
- ###
270
+ # Run an arbitrary jamf binary command.
271
+ #
272
+ # @note Most jamf commands require superuser/root privileges.
273
+ #
274
+ # @param command[String,Symbol] the jamf binary command to run
275
+ # The command is the single jamf command that comes after the/usr/bin/jamf.
276
+ #
277
+ # @param args[String,Array] the arguments passed to the jamf command.
278
+ # This is to be passed to Kernel.` (backtick), after being combined with the
279
+ # jamf binary and the jamf command
280
+ #
281
+ # @param verbose[Boolean] Should the stdout & stderr of the jamf binary be sent to
282
+ # the current stdout in realtime, as well as returned as a string?
283
+ #
284
+ # @return [String] the stdout & stderr of the jamf binary.
285
+ #
286
+ # @example
287
+ # These two are equivalent:
288
+ #
289
+ # JSS::Client.run_jamf "recon", "-assetTag 12345 -department 'IT Support'"
290
+ #
291
+ # JSS::Client.run_jamf :recon, ['-assetTag', '12345', '-department', 'IT Support'"]
292
+ #
293
+ #
294
+ # The details of the Process::Status for the jamf binary process can be captured from $?
295
+ # immediately after calling. (See Process::Status)
296
+ #
298
297
  def self.run_jamf(command, args = nil, verbose = false)
299
298
  raise JSS::UnmanagedError, 'The jamf binary is not installed on this computer.' unless installed?
300
299
  raise JSS::UnsupportedError, 'You must have root privileges to run that jamf binary command' unless \
@@ -326,102 +325,124 @@ module JSS
326
325
  install_out
327
326
  end # run_jamf
328
327
 
329
- ### A wrapper for the jamfHelper command, which can display a window on the client machine.
330
- ###
331
- ### The first parameter must be a symbol defining what kind of window to display. The options are
332
- ### - :hud - creates an Apple "Heads Up Display" style window
333
- ### - :utility or :util - creates an Apple "Utility" style window
334
- ### - :fs or :full_screen or :fullscreen - creates a full screen window that restricts all user input
335
- ### WARNING: Remote access must be used to unlock machines in this mode
336
- ###
337
- ### The remaining options Hash can contain any of the options listed. See below for descriptions.
338
- ###
339
- ### The value returned is the Integer exitstatus/stdout (both are the same) of the jamfHelper command.
340
- ### The meanings of those integers are:
341
- ###
342
- ### - 0 - Button 1 was clicked
343
- ### - 1 - The Jamf Helper was unable to launch
344
- ### - 2 - Button 2 was clicked
345
- ### - 3 - Process was started as a launchd task
346
- ### - XX1 - Button 1 was clicked with a value of XX seconds selected in the drop-down
347
- ### - XX2 - Button 2 was clicked with a value of XX seconds selected in the drop-down
348
- ### - 239 - The exit button was clicked
349
- ### - 240 - The "ProductVersion" in sw_vers did not return 10.5.X, 10.6.X or 10.7.X
350
- ### - 243 - The window timed-out with no buttons on the screen
351
- ### - 250 - Bad "-windowType"
352
- ### - 254 - Cancel button was select with delay option present
353
- ### - 255 - No "-windowType"
354
- ###
355
- ### See also /Library/Application\ Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -help
356
- ###
357
- ### @note the -startlaunchd and -kill options are not available in this implementation, since
358
- ### they don't work at the moment (casper 9.4).
359
- ### -startlaunchd seems to be required to NOT use launchd, and when it's ommited, an error is generated
360
- ### about the launchd plist permissions being incorrect.
361
- ###
362
- ### @param window_type[Symbol] The type of window to display
363
- ###
364
- ### @param opts[Hash] the options for the window
365
- ###
366
- ### @option opts :window_position [Symbol,nil] one of [ nil, :ul, :ll. :ur, :lr ]
367
- ### Positions window in the upper right, upper left, lower right or lower left of the user's screen
368
- ### If no input is given, the window defaults to the center of the screen
369
- ###
370
- ### @option opts :title [String]
371
- ### Sets the window's title to the specified string
372
- ###
373
- ### @option opts :heading [String]
374
- ### Sets the heading of the window to the specified string
375
- ###
376
- ### @option opts :align_heading [Symbol] one of [:right, :left, :center, :justified, :natural]
377
- ### Aligns the heading to the specified alignment
378
- ###
379
- ### @option opts :description [String]
380
- ### Sets the main contents of the window to the specified string
381
- ###
382
- ### @option opts :align_description [Symbol] one of [:right, :left, :center, :justified, :natural]
383
- ### Aligns the description to the specified alignment
384
- ###
385
- ### @option opts :icon [String,Pathname]
386
- ### Sets the windows image field to the image located at the specified path
387
- ###
388
- ### @option opts :icon_size [Integer]
389
- ### Changes the image frame to the specified pixel size
390
- ###
391
- ### @option opts :full_screen_icon [any value]
392
- ### Scales the "icon" to the full size of the window.
393
- ### Note: Only available in full screen mode
394
- ###
395
- ### @option opts :button1 [String]
396
- ### Creates a button with the specified label
397
- ###
398
- ### @option opts :button2 [String]
399
- ### Creates a second button with the specified label
400
- ###
401
- ### @option opts :default_button [Integer] either 1 or 2
402
- ### Sets the default button of the window to the specified button. The Default Button will respond to "return"
403
- ###
404
- ### @option opts :cancel_button [Integer] either 1 or 2
405
- ### Sets the cancel button of the window to the specified button. The Cancel Button will respond to "escape"
406
- ###
407
- ### @option opts :timeout [Integer]
408
- ### Causes the window to timeout after the specified amount of seconds
409
- ### Note: The timeout will cause the default button, button 1 or button 2 to be selected (in that order)
410
- ###
411
- ### @option opts :show_delay_options [String,Array<Integer>] A String of comma-separated Integers, or an Array of Integers.
412
- ### Enables the "Delay Options Mode". The window will display a dropdown with the values passed through the string
413
- ###
414
- ### @option opts :countdown [any value]
415
- ### Displays a string notifying the user when the window will time out
416
- ###
417
- ### @option opts :align_countdown [Symbol] one of [:right, :left, :center, :justified, :natural]
418
- ### Aligns the countdown to the specified alignment
419
- ###
420
- ### @option opts :lock_hud [any value]
421
- ### Removes the ability to exit the HUD by selecting the close button
422
- ###
423
- ### @return [Integer] the exit status of the jamfHelper command. See above.
424
- ###
328
+ # A wrapper for the jamfHelper command, which can display a window on the client machine.
329
+ #
330
+ # The first parameter must be a symbol defining what kind of window to display. The options are
331
+ # - :hud - creates an Apple "Heads Up Display" style window
332
+ # - :utility or :util - creates an Apple "Utility" style window
333
+ # - :fs or :full_screen or :fullscreen - creates a full screen window that restricts all user input
334
+ # WARNING: Remote access must be used to unlock machines in this mode
335
+ #
336
+ # The remaining options Hash can contain any of the options listed. See below for descriptions.
337
+ #
338
+ # The value returned is the Integer exitstatus/stdout (both are the same) of the jamfHelper command.
339
+ # The meanings of those integers are:
340
+ #
341
+ # - 0 - Button 1 was clicked
342
+ # - 1 - The Jamf Helper was unable to launch
343
+ # - 2 - Button 2 was clicked
344
+ # - 3 - Process was started as a launchd task
345
+ # - XX1 - Button 1 was clicked with a value of XX seconds selected in the drop-down
346
+ # - XX2 - Button 2 was clicked with a value of XX seconds selected in the drop-down
347
+ # - 239 - The exit button was clicked
348
+ # - 240 - The "ProductVersion" in sw_vers did not return 10.5.X, 10.6.X or 10.7.X
349
+ # - 243 - The window timed-out with no buttons on the screen
350
+ # - 250 - Bad "-windowType"
351
+ # - 254 - Cancel button was select with delay option present
352
+ # - 255 - No "-windowType"
353
+ #
354
+ # If the :abandon_process option is given, the integer returned is the Process ID
355
+ # of the abondoned process running jamfHelper.
356
+ #
357
+ # See also /Library/Application\ Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -help
358
+ #
359
+ # @note the -startlaunchd and -kill options are not available in this implementation, since
360
+ # they don't work at the moment (casper 9.4).
361
+ # -startlaunchd seems to be required to NOT use launchd, and when it's ommited, an error is generated
362
+ # about the launchd plist permissions being incorrect.
363
+ #
364
+ # @param window_type[Symbol] The type of window to display
365
+ #
366
+ # @param opts[Hash] the options for the window
367
+ #
368
+ # @option opts :window_position [Symbol,nil] one of [ nil, :ul, :ll. :ur, :lr ]
369
+ # Positions window in the upper right, upper left, lower right or lower left of the user's screen
370
+ # If no input is given, the window defaults to the center of the screen
371
+ #
372
+ # @option opts :title [String]
373
+ # Sets the window's title to the specified string
374
+ #
375
+ # @option opts :heading [String]
376
+ # Sets the heading of the window to the specified string
377
+ #
378
+ # @option opts :align_heading [Symbol] one of [:right, :left, :center, :justified, :natural]
379
+ # Aligns the heading to the specified alignment
380
+ #
381
+ # @option opts :description [String]
382
+ # Sets the main contents of the window to the specified string
383
+ #
384
+ # @option opts :align_description [Symbol] one of [:right, :left, :center, :justified, :natural]
385
+ # Aligns the description to the specified alignment
386
+ #
387
+ # @option opts :icon [String,Pathname]
388
+ # Sets the windows image field to the image located at the specified path
389
+ #
390
+ # @option opts :icon_size [Integer]
391
+ # Changes the image frame to the specified pixel size
392
+ #
393
+ # @option opts :full_screen_icon [any value]
394
+ # Scales the "icon" to the full size of the window.
395
+ # Note: Only available in full screen mode
396
+ #
397
+ # @option opts :button1 [String]
398
+ # Creates a button with the specified label
399
+ #
400
+ # @option opts :button2 [String]
401
+ # Creates a second button with the specified label
402
+ #
403
+ # @option opts :default_button [Integer] either 1 or 2
404
+ # Sets the default button of the window to the specified button. The Default Button will respond to "return"
405
+ #
406
+ # @option opts :cancel_button [Integer] either 1 or 2
407
+ # Sets the cancel button of the window to the specified button. The Cancel Button will respond to "escape"
408
+ #
409
+ # @option opts :timeout [Integer]
410
+ # Causes the window to timeout after the specified amount of seconds
411
+ # Note: The timeout will cause the default button, button 1 or button 2 to be selected (in that order)
412
+ #
413
+ # @option opts :show_delay_options [String,Array<Integer>] A String of comma-separated Integers, or an Array of Integers.
414
+ # Enables the "Delay Options Mode". The window will display a dropdown with the values passed through the string
415
+ #
416
+ # @option opts :countdown [any value]
417
+ # Displays a string notifying the user when the window will time out
418
+ #
419
+ # @option opts :align_countdown [Symbol] one of [:right, :left, :center, :justified, :natural]
420
+ # Aligns the countdown to the specified alignment
421
+ #
422
+ # @option opts :lock_hud [Boolean]
423
+ # Removes the ability to exit the HUD by selecting the close button
424
+ #
425
+ # @option opts :abandon_process [Boolean] Abandon the jamfHelper process so that your code can exit.
426
+ # This is mostly used so that a policy can finish while a dialog is waiting
427
+ # (possibly forever) for user response. When true, the returned value is the
428
+ # process id of the abandoned jamfHelper process.
429
+ #
430
+ # @option opts :output_file [String, Pathname] Save the output of jamfHelper
431
+ # (the exit code) into this file. This is useful when using abandon_process.
432
+ # The output file can be examined later to see what happened. If this option
433
+ # is not provided, no output is saved.
434
+ #
435
+ # @option opts :arg_string [String] The jamfHelper commandline args as a single
436
+ # String, the way you'd specify them in a shell. This is appended to any
437
+ # Ruby options provided when calling the method. So calling:
438
+ # JSS::Client.jamf_helper :hud, title: 'This is a title', arg_string: '-heading "this is a heading"'
439
+ # will run
440
+ # jamfHelper -windowType hud -title 'this is a title' -heading "this is a heading"
441
+ # When using this, be careful not to specify the windowType, since it's generated
442
+ # by the first, required, parameter of this method.
443
+ #
444
+ # @return [Integer] the exit status of the jamfHelper command. See above.
445
+ #
425
446
  def self.jamf_helper(window_type = :hud, opts = {})
426
447
  raise JSS::UnmanagedError, 'The jamfHelper app is not installed properly on this computer.' unless JAMF_HELPER.executable?
427
448
 
@@ -505,7 +526,7 @@ module JSS
505
526
  args << JSS.to_s_and_a(opts[opt])[:arrayform].join(', ')
506
527
 
507
528
  when :countdown
508
- args << '-countdown'
529
+ args << '-countdown' if opts[opt]
509
530
 
510
531
  when :align_countdown
511
532
  raise JSS::InvalidDataError, ":align_countdown must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless \
@@ -514,12 +535,30 @@ module JSS
514
535
  args << opts[opt].to_s
515
536
 
516
537
  when :lock_hud
517
- args << '-lockHUD'
538
+ args << '-lockHUD' if opts[opt]
539
+
518
540
  end # case opt
519
541
  end # each do opt
520
542
 
521
- system JAMF_HELPER.to_s, *args
522
- $CHILD_STATUS.exitstatus
543
+ cmd = Shellwords.escape JAMF_HELPER.to_s
544
+ args.each { |arg| cmd << " #{Shellwords.escape arg}" }
545
+ cmd << " #{opts[:arg_string]}" if opts[:arg_string]
546
+ cmd << " > #{Shellwords.escape opts[:output_file]}" if opts[:output_file]
547
+
548
+ if opts[:abandon_process]
549
+ pid = Process.fork
550
+ if pid.nil?
551
+ # In child
552
+ exec cmd
553
+ else
554
+ # In parent
555
+ Process.detach(pid)
556
+ pid
557
+ end
558
+ else
559
+ system cmd
560
+ $CHILD_STATUS.exitstatus
561
+ end
523
562
  end # def self.jamf_helper
524
563
 
525
564
  end # class Client