ruby-jss 0.7.0 → 0.8.1

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.
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