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.
Potentially problematic release.
This version of ruby-jss might be problematic. Click here for more details.
- 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
@@ -26,133 +26,125 @@
|
|
26
26
|
###
|
27
27
|
module JSS
|
28
28
|
|
29
|
-
|
30
|
-
### Module Variables
|
29
|
+
# Module Variables
|
31
30
|
#####################################
|
32
31
|
|
33
|
-
|
34
|
-
### Module Methods
|
32
|
+
# Module Methods
|
35
33
|
#####################################
|
36
34
|
|
37
|
-
|
38
|
-
### Classes
|
35
|
+
# Classes
|
39
36
|
#####################################
|
40
37
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
###
|
38
|
+
# A User or group in the JSS.
|
39
|
+
#
|
40
|
+
# @see JSS::APIObject
|
41
|
+
#
|
46
42
|
class Account < JSS::APIObject
|
47
43
|
|
48
|
-
|
49
|
-
|
44
|
+
# Note: This class is not fully extended and since the resource
|
45
|
+
# is different than the rest, methods like JSS::Account.all do not work
|
50
46
|
|
51
|
-
|
52
|
-
### Mix-Ins
|
47
|
+
# Mix-Ins
|
53
48
|
#####################################
|
54
49
|
|
50
|
+
# Class Constants
|
55
51
|
#####################################
|
56
|
-
|
52
|
+
|
53
|
+
# The base for REST resources of this class
|
54
|
+
RSRC_BASE = 'accounts'.freeze
|
55
|
+
|
56
|
+
# the hash key used for the JSON list output of all objects in the JSS
|
57
|
+
RSRC_LIST_KEY = :accounts
|
58
|
+
|
59
|
+
# The hash key used for the JSON object output.
|
60
|
+
# It's also used in various error messages
|
61
|
+
RSRC_OBJECT_KEY = :account
|
62
|
+
|
63
|
+
# these keys, as well as :id and :name, can be used to look up objects of this class in the JSS
|
64
|
+
OTHER_LOOKUP_KEYS = [:userid, :username, :groupid, :groupname].freeze
|
65
|
+
|
66
|
+
# Class Methods
|
57
67
|
#####################################
|
58
68
|
|
59
|
-
|
69
|
+
# @return [Array<Hash>] all JSS account users
|
60
70
|
def self.all_users(refresh = false)
|
61
|
-
|
71
|
+
all(refresh)[:users]
|
62
72
|
end
|
63
73
|
|
64
|
-
|
74
|
+
# @return [Array<Hash>] all JSS account user ids
|
65
75
|
def self.all_user_ids(refresh = false)
|
66
|
-
|
76
|
+
all(refresh)[:users].map { |i| i[:id] }
|
67
77
|
end
|
68
78
|
|
69
|
-
|
79
|
+
# @return [Array<Hash>] all JSS account user names
|
70
80
|
def self.all_user_names(refresh = false)
|
71
|
-
|
81
|
+
all(refresh)[:users].map { |i| i[:name] }
|
72
82
|
end
|
73
83
|
|
74
|
-
|
84
|
+
# @return [Array<Hash>] all JSS account groups
|
75
85
|
def self.all_groups(refresh = false)
|
76
|
-
|
86
|
+
all(refresh)[:groups]
|
77
87
|
end
|
78
88
|
|
79
|
-
|
89
|
+
# @return [Array<Hash>] all JSS account group ids
|
80
90
|
def self.all_group_ids(refresh = false)
|
81
|
-
|
91
|
+
all(refresh)[:groups].map { |i| i[:id] }
|
82
92
|
end
|
83
93
|
|
84
|
-
|
94
|
+
# @return [Array<Hash>] all JSS account group names
|
85
95
|
def self.all_group_names(refresh = false)
|
86
|
-
|
96
|
+
all(refresh)[:groups].map { |i| i[:name] }
|
87
97
|
end
|
88
98
|
|
99
|
+
# Attributes
|
89
100
|
#####################################
|
90
|
-
### Class Constants
|
91
|
-
#####################################
|
92
|
-
|
93
|
-
### The base for REST resources of this class
|
94
|
-
RSRC_BASE = "accounts"
|
95
|
-
|
96
|
-
### the hash key used for the JSON list output of all objects in the JSS
|
97
|
-
RSRC_LIST_KEY = :accounts
|
98
|
-
|
99
|
-
### The hash key used for the JSON object output.
|
100
|
-
### It's also used in various error messages
|
101
|
-
RSRC_OBJECT_KEY = :account
|
102
101
|
|
103
|
-
|
104
|
-
### Attributes
|
105
|
-
#####################################
|
106
|
-
|
107
|
-
### @return [String] The user's full name
|
102
|
+
# @return [String] The user's full name
|
108
103
|
attr_reader :full_name
|
109
104
|
|
110
|
-
|
105
|
+
# @return [String] The user's email address
|
111
106
|
attr_reader :email
|
112
107
|
|
113
|
-
|
108
|
+
# @return [String] The user's access level
|
114
109
|
attr_reader :access_level
|
115
110
|
|
116
|
-
|
111
|
+
# @return [String] The user's privilege set
|
117
112
|
attr_reader :privilege_set
|
118
113
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
114
|
+
# @return [Hash]
|
115
|
+
#
|
116
|
+
# Info about the privileges assigned to the user
|
117
|
+
#
|
118
|
+
# Note: these arrays may be empty, they always exist
|
119
|
+
#
|
120
|
+
# The Hash keys are:
|
121
|
+
# * :jss_objects => An array of jss_object privileges
|
122
|
+
# * :jss_settings => An array of jss_settings privileges
|
123
|
+
# * :jss_actions => An array of jss_actions privileges
|
124
|
+
# * :recon => An array of Casper Recon privileges
|
125
|
+
# * :casper_admin => An array of Casper Admin privileges
|
126
|
+
# * :casper_remote => An array of Casper Remote privileges
|
127
|
+
# * :casper_imaging => An array of Casper Imaging privileges
|
133
128
|
attr_reader :privileges
|
134
129
|
|
135
|
-
|
136
|
-
### Constructor
|
130
|
+
# Constructor
|
137
131
|
#####################################
|
138
132
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
super args, [:userid, :username, :groupid, :groupname]
|
133
|
+
# See JSS::APIObject#initialize
|
134
|
+
#
|
135
|
+
def initialize(args = {})
|
136
|
+
super args
|
144
137
|
|
145
138
|
# check to see if a user has been specified, haven't built groups yet
|
146
139
|
is_user = [:userid, :username].any? { |key| args.keys.include? key }
|
147
140
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
end
|
141
|
+
return unless is_user
|
142
|
+
@user_name = @init_data[:name]
|
143
|
+
@full_name = @init_data[:full_name]
|
144
|
+
@email = @init_data[:email]
|
145
|
+
@access_level = @init_data[:access_level]
|
146
|
+
@privilege_set = @init_data[:privilege_set]
|
147
|
+
@privileges = @init_data[:privileges]
|
156
148
|
|
157
149
|
end # initialize
|
158
150
|
|
@@ -1,188 +1,171 @@
|
|
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
|
###
|
27
27
|
module JSS
|
28
28
|
|
29
|
-
|
30
|
-
### Module Variables
|
29
|
+
# Module Variables
|
31
30
|
#####################################
|
32
31
|
|
33
|
-
|
34
|
-
### Module Methods
|
32
|
+
# Module Methods
|
35
33
|
#####################################
|
36
34
|
|
37
|
-
|
38
|
-
### Classes
|
35
|
+
# Classes
|
39
36
|
#####################################
|
40
37
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
38
|
+
#
|
39
|
+
# A Parent class for Advanced Computer, MobileDevice, and User searchs
|
40
|
+
#
|
41
|
+
# Subclasses must define:
|
42
|
+
# * the constant RESULT_CLASS which is the JSS Module class of
|
43
|
+
# the item returned by the search, e.g. JSS::Computer
|
44
|
+
# * the constant RESULT_ID_FIELDS, which is an Array of Symbols
|
45
|
+
# that come from the API in the search_results along with the
|
46
|
+
# symbolized display fields.
|
47
|
+
# E.g. for AdvancedComputerSearches, :id, :name, and :udid are present along with
|
48
|
+
# whatever display fields have been defined.
|
49
|
+
#
|
50
|
+
#
|
51
|
+
# @see JSS::AdvancedComputerSearch
|
52
|
+
# @see JSS::AdvancedMobileDeviceSearch
|
53
|
+
# @see JSS::AdvancedUserSearch
|
54
|
+
# @see JSS::APIObject
|
55
|
+
#
|
59
56
|
class AdvancedSearch < JSS::APIObject
|
60
57
|
|
61
|
-
|
62
|
-
### Mix-Ins
|
58
|
+
# Mix-Ins
|
63
59
|
#####################################
|
64
60
|
include JSS::Creatable
|
65
61
|
include JSS::Updatable
|
66
62
|
include JSS::Criteriable
|
67
63
|
|
68
|
-
|
69
|
-
### Class Constants
|
64
|
+
# Class Constants
|
70
65
|
#####################################
|
71
66
|
|
72
|
-
EXPORT_FORMATS = [:csv, :tab, :xml]
|
67
|
+
EXPORT_FORMATS = [:csv, :tab, :xml].freeze
|
73
68
|
|
69
|
+
# Attributes
|
74
70
|
#####################################
|
75
|
-
### Attributes
|
76
|
-
#####################################
|
77
|
-
|
78
71
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
72
|
+
#
|
73
|
+
# @return [Array<Hash>] the results of the search
|
74
|
+
#
|
75
|
+
# Each Hash is one object that matches the criteria.
|
76
|
+
# Within each hash there are variable keys, but always at least
|
77
|
+
# the keys defined in each subclasses RESULT_ID_FIELDS
|
78
|
+
#
|
79
|
+
# The other keys correspond to the {AdvancedSearch#display_fields} defined for this
|
80
|
+
# Advanced Search.
|
81
|
+
#
|
89
82
|
attr_reader :search_results
|
90
83
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
84
|
+
# @return [Array<Symbol>]
|
85
|
+
#
|
86
|
+
# The search result Hash keys for the {#display_fields} of the search
|
87
|
+
#
|
88
|
+
# The field names in {#display_fields} are strings matching how the field is labeled
|
89
|
+
# in the web UI (including the names of Extension Attributes). They have to be that way
|
90
|
+
# when submitting them to the API, and thats mostly what {#display_fields} and related
|
91
|
+
# methods are for.
|
92
|
+
#
|
93
|
+
# However, when those names come back as the Hash Keys of the {#search_results}
|
94
|
+
# they (inconsistently) have spaces and/or dashes converted to underscores, and,
|
95
|
+
# the JSON module converts the keys to Symbols, so they don't match the {#display_fields}.
|
96
|
+
#
|
97
|
+
# For example, the display field "Last Check-in" might come back as any of these Symbols:
|
98
|
+
# - :"Last Check-in"
|
99
|
+
# - :Last_Check_in
|
100
|
+
# - :"Last_Check-in"
|
101
|
+
#
|
102
|
+
# Also, the data returned in the {#search_results} contains more keys than just the
|
103
|
+
# {#display_fields} - namely it comes with some standard identifiers for each found item.
|
104
|
+
# such as JSS id number and name.
|
105
|
+
#
|
106
|
+
# {#result_display_keys} will hold just the Hash keys corresponding to the
|
107
|
+
# {#display_fields} by taking the keys from the first result Hash, and removing the
|
108
|
+
# identifier keys as listed in each subclass's RESULT_ID_FIELDS constant.
|
109
|
+
#
|
117
110
|
attr_reader :result_display_keys
|
118
111
|
|
119
|
-
|
112
|
+
# @return [String] the name of the site for this search
|
120
113
|
attr_reader :site
|
121
114
|
|
122
|
-
|
115
|
+
# @return [String] the SQL query generated by the JSS based on the critera
|
123
116
|
attr_reader :sql_text
|
124
117
|
|
125
|
-
|
126
|
-
### Constructor
|
118
|
+
# Constructor
|
127
119
|
#####################################
|
128
120
|
|
129
|
-
|
130
|
-
|
131
|
-
|
121
|
+
#
|
122
|
+
# @see APIObject#initialize
|
123
|
+
#
|
132
124
|
def initialize(args = {})
|
133
|
-
|
134
125
|
super args
|
135
126
|
|
136
|
-
|
137
|
-
|
127
|
+
# @init_data now has the raw data
|
128
|
+
# so fill in our attributes or set defaults
|
138
129
|
|
139
130
|
@sql_text = @init_data[:sql_text]
|
140
131
|
@site = JSS::APIObject.get_name(@init_data[:site])
|
141
132
|
|
133
|
+
@display_fields = @init_data[:display_fields] ? @init_data[:display_fields].map { |f| f[:name] } : []
|
142
134
|
|
143
|
-
|
144
|
-
@display_fields = @init_data[:display_fields] ? @init_data[:display_fields].map{|f| f[:name]} : []
|
145
|
-
|
146
|
-
@search_results = @init_data[self.class::RESULT_CLASS::RSRC_LIST_KEY]
|
135
|
+
@search_results = @init_data[self.class::RESULT_CLASS::RSRC_LIST_KEY]
|
147
136
|
@search_results ||= []
|
148
|
-
if @search_results.empty?
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
137
|
+
@result_display_keys = if @search_results.empty?
|
138
|
+
[]
|
139
|
+
else
|
140
|
+
@search_results[0].keys - self.class::RESULT_ID_FIELDS
|
141
|
+
end
|
153
142
|
|
154
143
|
# make sure each hash of the search results
|
155
144
|
# has a key matching a standard key.
|
156
145
|
#
|
157
146
|
@search_results.each do |hash|
|
158
147
|
hash.keys.each do |key|
|
159
|
-
std_key = key.to_s.gsub(/ |-/,
|
148
|
+
std_key = key.to_s.gsub(/ |-/, '_').to_sym
|
160
149
|
next if hash[std_key]
|
161
150
|
hash[std_key] = hash[key]
|
162
151
|
end
|
163
152
|
end
|
164
|
-
|
165
|
-
parse_criteria
|
166
|
-
|
167
|
-
|
168
153
|
end # init
|
169
154
|
|
170
|
-
|
171
|
-
### Public Instance Methods
|
155
|
+
# Public Instance Methods
|
172
156
|
#####################################
|
173
157
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
###
|
158
|
+
# Create in the JSS
|
159
|
+
#
|
160
|
+
# If get_results is true, they'll be available in {#search_results}. This might be slow.
|
161
|
+
#
|
162
|
+
# @param get_results[Boolean] should the results of the search be queried immediately?
|
163
|
+
#
|
164
|
+
# @return [Integer] the id of the newly created search
|
165
|
+
#
|
183
166
|
def create(get_results = false)
|
184
|
-
raise JSS::InvalidDataError,
|
185
|
-
raise JSS::InvalidDataError,
|
167
|
+
raise JSS::InvalidDataError, 'JSS::Criteriable::Criteria instance required' unless @criteria.is_a? JSS::Criteriable::Criteria
|
168
|
+
raise JSS::InvalidDataError, 'display_fields must be an Array.' unless @display_fields.is_a? Array
|
186
169
|
|
187
170
|
orig_timeout = JSS::API.cnx.options[:timeout]
|
188
171
|
JSS::API.timeout = 1800
|
@@ -191,18 +174,16 @@ module JSS
|
|
191
174
|
JSS::API.timeout = orig_timeout
|
192
175
|
|
193
176
|
@id # remember to return the id
|
194
|
-
|
195
177
|
end
|
196
178
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
###
|
179
|
+
# Save any changes
|
180
|
+
#
|
181
|
+
# If get_results is true, they'll be available in {#search_results}. This might be slow.
|
182
|
+
#
|
183
|
+
# @param get_results[Boolean] should the results of the search be queried immediately?
|
184
|
+
#
|
185
|
+
# @return [Integer] the id of the updated search
|
186
|
+
#
|
206
187
|
def update(get_results = false)
|
207
188
|
orig_timeout = JSS::API.cnx.options[:timeout]
|
208
189
|
JSS::API.timeout = 1800
|
@@ -210,24 +191,22 @@ module JSS
|
|
210
191
|
requery_search_results if get_results
|
211
192
|
JSS::API.timeout = orig_timeout
|
212
193
|
|
213
|
-
@id
|
194
|
+
@id # remember to return the id
|
214
195
|
end
|
215
196
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
### @return [Array<Hash>] the new search results
|
223
|
-
###
|
197
|
+
# Requery the API for the search results.
|
198
|
+
#
|
199
|
+
# This can be very slow, so temporarily reset the API timeout to 30 minutes
|
200
|
+
#
|
201
|
+
# @return [Array<Hash>] the new search results
|
202
|
+
#
|
224
203
|
def requery_search_results
|
225
204
|
orig_open_timeout = JSS::API.cnx.options[:open_timeout]
|
226
205
|
orig_timeout = JSS::API.cnx.options[:timeout]
|
227
206
|
JSS::API.timeout = 1800
|
228
207
|
JSS::API.open_timeout = 1800
|
229
208
|
begin
|
230
|
-
requery = self.class.new(:
|
209
|
+
requery = self.class.new(id: @id)
|
231
210
|
@search_results = requery.search_results
|
232
211
|
@result_display_keys = requery.result_display_keys
|
233
212
|
ensure
|
@@ -236,66 +215,57 @@ module JSS
|
|
236
215
|
end
|
237
216
|
end
|
238
217
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
### @param new_val[Array<String>] the new field names
|
264
|
-
###
|
265
|
-
def display_fields= (new_val)
|
266
|
-
raise JSS::InvalidDataError, "display_fields must be an Array." unless new_val.kind_of? Array
|
218
|
+
# @return [Array<String>] the fields to be returned with the search results
|
219
|
+
#
|
220
|
+
# The API delivers these as an array of Hashes,
|
221
|
+
# where each hash has only one key, :name => the name of the fields/ExtAttrib
|
222
|
+
# to display. It should probably not have the underlying Hashes, and just
|
223
|
+
# be an array of names. This class converts it to just an Array of field names
|
224
|
+
# (Strings) for internal use.
|
225
|
+
#
|
226
|
+
# These fields are returned in the @search_results
|
227
|
+
# data along with :id, :name, and other unique identifiers
|
228
|
+
# for each found item. In that data, their names have
|
229
|
+
# spaces and dashes converted to underscores, and they are
|
230
|
+
# symbolized.
|
231
|
+
#
|
232
|
+
#
|
233
|
+
attr_reader :display_fields
|
234
|
+
|
235
|
+
# Set the list of fields to be retrieved with the
|
236
|
+
# search results.
|
237
|
+
#
|
238
|
+
# @param new_val[Array<String>] the new field names
|
239
|
+
#
|
240
|
+
def display_fields=(new_val)
|
241
|
+
raise JSS::InvalidDataError, 'display_fields must be an Array.' unless new_val.is_a? Array
|
267
242
|
return if new_val.sort == @display_fields.sort
|
268
243
|
@display_fields = new_val
|
269
244
|
@need_to_update = true
|
270
245
|
end
|
271
246
|
|
272
|
-
|
273
|
-
|
274
|
-
###
|
275
|
-
### @return [Integer] the number of items found by the search
|
276
|
-
###
|
247
|
+
# @return [Integer] the number of items found by the search
|
248
|
+
#
|
277
249
|
def count
|
278
250
|
@search_results.count
|
279
251
|
end
|
280
252
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
###
|
253
|
+
# Export the display fields of the search results to a file.
|
254
|
+
#
|
255
|
+
# @param output_file[String,Pathname] The file in which to store the exported results
|
256
|
+
#
|
257
|
+
# @param format[Symbol] one of :csv, :tab, or :xml, defaults to :csv
|
258
|
+
#
|
259
|
+
# @param overwrite[Boolean] should the output_file be overwrite if it exists? Defaults to false
|
260
|
+
#
|
261
|
+
# @return [Pathname] the path to the output file
|
262
|
+
#
|
263
|
+
# @note This method only exports the display fields defined in this advanced search for
|
264
|
+
# the search_result members (computers, mobile_devices, or users)
|
265
|
+
# It doesn't currently provide the ability to export subsets of info about those objects, as the
|
266
|
+
# Web UI does (e.g. group memberships, applications, receipts, etc)
|
267
|
+
#
|
297
268
|
def export(output_file, format = :csv, overwrite = false)
|
298
|
-
|
299
269
|
raise JSS::InvalidDataError, "Export format must be one of: :#{EXPORT_FORMATS.join ', :'}" unless EXPORT_FORMATS.include? format
|
300
270
|
|
301
271
|
out = Pathname.new output_file
|
@@ -304,65 +274,61 @@ module JSS
|
|
304
274
|
raise JSS::AlreadyExistsError, "The output file already exists: #{out}" if out.exist?
|
305
275
|
end
|
306
276
|
|
307
|
-
|
308
277
|
case format
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
@search_results.each do |row|
|
314
|
-
csv << @result_display_keys.map {|key| row[key]}
|
315
|
-
end # each do row
|
316
|
-
end #CSV.open
|
317
|
-
|
318
|
-
when :tab
|
319
|
-
tabbed = @result_display_keys.join("\t") + "\n"
|
278
|
+
when :csv
|
279
|
+
require 'csv'
|
280
|
+
CSV.open(out.to_s, 'wb') do |csv|
|
281
|
+
csv << @result_display_keys
|
320
282
|
@search_results.each do |row|
|
321
|
-
|
283
|
+
csv << @result_display_keys.map { |key| row[key] }
|
322
284
|
end # each do row
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
@
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
285
|
+
end # CSV.open
|
286
|
+
|
287
|
+
when :tab
|
288
|
+
tabbed = @result_display_keys.join("\t") + "\n"
|
289
|
+
@search_results.each do |row|
|
290
|
+
tabbed << @result_display_keys.map { |key| row[key] }.join("\t") + "\n"
|
291
|
+
end # each do row
|
292
|
+
out.jss_save tabbed.chomp
|
293
|
+
|
294
|
+
else # :xml
|
295
|
+
doc = REXML::Document.new '<?xml version="1.0" encoding="ISO-8859-1"?>'
|
296
|
+
members = doc.add_element self.class::RESULT_CLASS::RSRC_LIST_KEY.to_s
|
297
|
+
@search_results.each do |row|
|
298
|
+
member = members.add_element self.class::RESULT_CLASS::RSRC_OBJECT_KEY.to_s
|
299
|
+
@result_display_keys.each do |field|
|
300
|
+
member.add_element(field.to_s.tr(' ', '_')).text = row[field].empty? ? nil : row[field]
|
301
|
+
end # ech do field
|
302
|
+
end # each do row
|
303
|
+
out.jss_save doc.to_s.gsub('><', ">\n<")
|
335
304
|
end # case
|
336
305
|
|
337
|
-
|
306
|
+
out
|
338
307
|
end
|
339
308
|
|
340
|
-
|
341
|
-
#####################################
|
342
|
-
### Private Instance Methods
|
309
|
+
# Private Instance Methods
|
343
310
|
#####################################
|
344
311
|
private
|
345
312
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
end
|
313
|
+
# Clean up the inconsistent "Display Field" keys in the search results.
|
314
|
+
#
|
315
|
+
# Sometimes spaces have been converted to underscores, sometimes not, sometimes both.
|
316
|
+
# Same for dashes.
|
317
|
+
# E.g :"Last Check-in"/:Last_Check_in/:"Last_Check-in", :Computer_Name, and :"Display Name"/:Display_Name
|
318
|
+
#
|
319
|
+
# This ensures there's always the fully underscored version.
|
320
|
+
#
|
321
|
+
# Update an internally used array of the display field names, symbolized, with
|
322
|
+
# spaces and dashes converted to underscores. We use these
|
323
|
+
# to overcome inconsistencies in how the names come from the API
|
324
|
+
#
|
325
|
+
# @return [void]
|
326
|
+
#
|
327
|
+
# def standardize_display_field_keys
|
328
|
+
# spdash =
|
329
|
+
# us =
|
330
|
+
# @display_field_std_keys = @display_fields.map { |f| f.gsub(/ |-/, '_').to_sym }
|
331
|
+
# end
|
366
332
|
|
367
333
|
def rest_xml
|
368
334
|
doc = REXML::Document.new APIConnection::XML_HEADER
|
@@ -375,16 +341,15 @@ module JSS
|
|
375
341
|
acs << @criteria.rest_xml
|
376
342
|
|
377
343
|
df = acs.add_element('display_fields')
|
378
|
-
@display_fields.each{|f| df.add_element('display_field').add_element('name').text = f }
|
344
|
+
@display_fields.each { |f| df.add_element('display_field').add_element('name').text = f }
|
379
345
|
|
380
|
-
|
346
|
+
doc.to_s
|
381
347
|
end # rest xml
|
382
348
|
|
383
349
|
end # class AdvancedSearch
|
384
350
|
|
385
351
|
end # module JSS
|
386
352
|
|
387
|
-
require
|
388
|
-
require
|
389
|
-
require
|
390
|
-
|
353
|
+
require 'jss/api_object/advanced_search/advanced_computer_search'
|
354
|
+
require 'jss/api_object/advanced_search/advanced_mobile_device_search'
|
355
|
+
require 'jss/api_object/advanced_search/advanced_user_search'
|