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.
- checksums.yaml +4 -4
- data/CHANGES.md +29 -22
- data/README.md +66 -86
- data/bin/jamfHelperBackgrounder +148 -0
- data/bin/netseg-update +0 -1
- data/lib/jss.rb +20 -9
- data/lib/jss/api_connection.rb +369 -295
- data/lib/jss/api_object.rb +651 -418
- data/lib/jss/api_object/account.rb +69 -77
- data/lib/jss/api_object/advanced_search.rb +201 -236
- data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +42 -42
- data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +33 -43
- data/lib/jss/api_object/advanced_search/advanced_user_search.rb +33 -43
- data/lib/jss/api_object/building.rb +39 -52
- data/lib/jss/api_object/categorizable.rb +221 -0
- data/lib/jss/api_object/category.rb +81 -89
- data/lib/jss/api_object/computer.rb +486 -525
- data/lib/jss/api_object/computer_invitation.rb +73 -86
- data/lib/jss/api_object/criteriable.rb +6 -7
- data/lib/jss/api_object/ebook.rb +21 -0
- data/lib/jss/api_object/extendable.rb +6 -8
- data/lib/jss/api_object/group.rb +0 -3
- data/lib/jss/api_object/locatable.rb +19 -20
- data/lib/jss/api_object/mac_application.rb +21 -0
- data/lib/jss/api_object/mobile_device.rb +30 -21
- data/lib/jss/api_object/mobile_device_application.rb +447 -0
- data/lib/jss/api_object/mobile_device_configuration_profile.rb +21 -0
- data/lib/jss/api_object/osx_configuration_profile.rb +0 -3
- data/lib/jss/api_object/package.rb +21 -34
- data/lib/jss/api_object/peripheral.rb +16 -18
- data/lib/jss/api_object/policy.rb +5 -83
- data/lib/jss/api_object/purchasable.rb +11 -13
- data/lib/jss/api_object/scopable.rb +11 -12
- data/lib/jss/api_object/script.rb +3 -17
- data/lib/jss/api_object/self_servable.rb +419 -205
- data/lib/jss/api_object/self_servable/icon.rb +179 -0
- data/lib/jss/api_object/updatable.rb +35 -34
- data/lib/jss/api_object/uploadable.rb +72 -70
- data/lib/jss/api_object/user.rb +6 -7
- data/lib/jss/api_object/vppable.rb +117 -0
- data/lib/jss/client.rb +264 -225
- data/lib/jss/db_connection.rb +7 -5
- data/lib/jss/exceptions.rb +50 -42
- data/lib/jss/ruby_extensions.rb +8 -7
- data/lib/jss/ruby_extensions/object.rb +19 -0
- data/lib/jss/utility.rb +82 -40
- data/lib/jss/version.rb +1 -1
- metadata +37 -68
- data/bin/jss-webhook-server +0 -3
- data/lib/jss/webhooks.rb +0 -53
- data/lib/jss/webhooks/README.md +0 -269
- data/lib/jss/webhooks/configuration.rb +0 -213
- data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation-executable +0 -91
- data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation.rb +0 -45
- data/lib/jss/webhooks/data/sample_jsons/ComputerAdded.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/ComputerCheckIn.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/ComputerInventoryCompleted.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/ComputerPolicyFinished.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/ComputerPushCapabilityChanged.json +0 -27
- data/lib/jss/webhooks/data/sample_jsons/JSSShutdown.json +0 -14
- data/lib/jss/webhooks/data/sample_jsons/JSSStartup.json +0 -14
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCheckIn.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCommandCompleted.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceEnrolled.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/MobileDevicePushSent.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/MobileDeviceUnEnrolled.json +0 -26
- data/lib/jss/webhooks/data/sample_jsons/PatchSoftwareTitleUpdated.json +0 -14
- data/lib/jss/webhooks/data/sample_jsons/PushSent.json +0 -11
- data/lib/jss/webhooks/data/sample_jsons/RestAPIOperation.json +0 -15
- data/lib/jss/webhooks/data/sample_jsons/SCEPChallenge.json +0 -10
- data/lib/jss/webhooks/data/sample_jsons/SmartGroupComputerMembershipChange.json +0 -13
- data/lib/jss/webhooks/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +0 -13
- data/lib/jss/webhooks/event.rb +0 -139
- data/lib/jss/webhooks/event/computer_added.rb +0 -38
- data/lib/jss/webhooks/event/computer_check_in.rb +0 -38
- data/lib/jss/webhooks/event/computer_inventory_completed.rb +0 -38
- data/lib/jss/webhooks/event/computer_policy_finished.rb +0 -38
- data/lib/jss/webhooks/event/computer_push_capability_changed.rb +0 -38
- data/lib/jss/webhooks/event/handlers.rb +0 -192
- data/lib/jss/webhooks/event/jss_shutdown.rb +0 -38
- data/lib/jss/webhooks/event/jss_startup.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_check_in.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_command_completed.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_enrolled.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_push_sent.rb +0 -38
- data/lib/jss/webhooks/event/mobile_device_unenrolled.rb +0 -38
- data/lib/jss/webhooks/event/patch_software_title_updated.rb +0 -38
- data/lib/jss/webhooks/event/push_sent.rb +0 -38
- data/lib/jss/webhooks/event/rest_api_operation.rb +0 -38
- data/lib/jss/webhooks/event/scep_challenge.rb +0 -38
- data/lib/jss/webhooks/event/smart_group_computer_membership_change.rb +0 -38
- data/lib/jss/webhooks/event/smart_group_mobile_device_membership_change.rb +0 -38
- data/lib/jss/webhooks/event/webhook.rb +0 -40
- data/lib/jss/webhooks/event_objects.rb +0 -112
- data/lib/jss/webhooks/event_objects/computer.rb +0 -49
- data/lib/jss/webhooks/event_objects/jss.rb +0 -36
- data/lib/jss/webhooks/event_objects/mobile_device.rb +0 -48
- data/lib/jss/webhooks/event_objects/patch_software_title_update.rb +0 -38
- data/lib/jss/webhooks/event_objects/push.rb +0 -33
- data/lib/jss/webhooks/event_objects/rest_api_operation.rb +0 -37
- data/lib/jss/webhooks/event_objects/scep_challenge.rb +0 -32
- data/lib/jss/webhooks/event_objects/smart_group.rb +0 -35
- data/lib/jss/webhooks/server_app.rb +0 -37
- data/lib/jss/webhooks/server_app/routes.rb +0 -27
- data/lib/jss/webhooks/server_app/routes/handle_webhook_event.rb +0 -39
- data/lib/jss/webhooks/server_app/routes/home.rb +0 -37
- data/lib/jss/webhooks/server_app/self_signed_cert.rb +0 -65
- data/lib/jss/webhooks/server_app/server.rb +0 -60
- data/lib/jss/webhooks/version.rb +0 -32
data/lib/jss/api_object/user.rb
CHANGED
|
@@ -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
|
data/lib/jss/client.rb
CHANGED
|
@@ -26,40 +26,39 @@
|
|
|
26
26
|
###
|
|
27
27
|
module JSS
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
# Module Variables
|
|
30
30
|
#####################################
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
# Module Methods
|
|
33
33
|
#####################################
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
# Classes
|
|
36
36
|
#####################################
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
54
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
70
|
+
# The possible window positions for jamfHelper
|
|
72
71
|
JAMF_HELPER_WINDOW_POSITIONS = [nil, :ul, :ll, :ur, :lr].freeze
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
# The available buttons in jamfHelper
|
|
75
74
|
JAMF_HELPER_BUTTONS = [1, 2].freeze
|
|
76
75
|
|
|
77
|
-
|
|
76
|
+
# The possible alignment positions in jamfHelper
|
|
78
77
|
JAMF_HELPER_ALIGNMENTS = [:right, :left, :center, :justified, :natural].freeze
|
|
79
78
|
|
|
80
|
-
|
|
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
|
-
|
|
82
|
+
# The Pathname to the JAMF support folder
|
|
84
83
|
JAMF_SUPPORT_FOLDER = Pathname.new '/Library/Application Support/JAMF'
|
|
85
84
|
|
|
86
|
-
|
|
85
|
+
# The JAMF receipts folder, where package installs are tracked.
|
|
87
86
|
RECEIPTS_FOLDER = JAMF_SUPPORT_FOLDER + 'Receipts'
|
|
88
87
|
|
|
89
|
-
|
|
88
|
+
# The JAMF downloads folder
|
|
90
89
|
DOWNLOADS_FOLDER = JAMF_SUPPORT_FOLDER + 'Downloads'
|
|
91
90
|
|
|
92
|
-
|
|
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
|
-
|
|
103
|
+
# Class Variables
|
|
105
104
|
#####################################
|
|
106
105
|
|
|
107
106
|
#####################################
|
|
108
|
-
|
|
107
|
+
# Class Methods
|
|
109
108
|
#####################################
|
|
110
109
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
124
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
|
205
|
+
@port
|
|
207
206
|
end
|
|
208
207
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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
|
-
|
|
522
|
-
|
|
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
|