ruby-jss 0.10.1 → 0.10.2a4
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/lib/jss/api_connection.rb +38 -19
- data/lib/jss/api_object/advanced_search.rb +5 -1
- data/lib/jss/api_object/computer.rb +315 -291
- data/lib/jss/api_object/computer_invitation.rb +5 -3
- data/lib/jss/api_object/ebook.rb +5 -0
- data/lib/jss/api_object/group/computer_group.rb +4 -0
- data/lib/jss/api_object/group/mobile_device_group.rb +4 -1
- data/lib/jss/api_object/group.rb +6 -1
- data/lib/jss/api_object/mac_application.rb +5 -0
- data/lib/jss/api_object/mdm.rb +1268 -0
- data/lib/jss/api_object/mobile_device.rb +56 -335
- data/lib/jss/api_object/mobile_device_application.rb +6 -0
- data/lib/jss/api_object/mobile_device_configuration_profile.rb +36 -0
- data/lib/jss/api_object/osx_configuration_profile.rb +115 -151
- data/lib/jss/api_object/patch.rb +38 -0
- data/lib/jss/api_object/patch_policy.rb +38 -0
- data/lib/jss/api_object/peripheral.rb +5 -7
- data/lib/jss/api_object/policy.rb +5 -0
- data/lib/jss/api_object/restricted_software.rb +5 -0
- data/lib/jss/api_object/scopable/scope.rb +367 -411
- data/lib/jss/api_object/self_servable.rb +15 -4
- data/lib/jss/api_object/sitable.rb +197 -0
- data/lib/jss/api_object/site.rb +45 -76
- data/lib/jss/api_object/user.rb +6 -2
- data/lib/jss/api_object.rb +74 -4
- data/lib/jss/utility.rb +21 -0
- data/lib/jss/version.rb +1 -1
- data/lib/jss.rb +4 -0
- metadata +8 -4
@@ -1,206 +1,188 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
27
|
module JSS
|
28
28
|
|
29
29
|
module Scopable
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
###
|
31
|
+
# Classes
|
32
|
+
#####################################
|
33
|
+
|
34
|
+
#
|
35
|
+
# This class represents a Scope in the JSS, as can be applied to Scopable objects like
|
36
|
+
# Policies, Profiles, etc. Instances of this class are generally used as the value of the @scope attribute
|
37
|
+
# of those objects.
|
38
|
+
#
|
39
|
+
# Scope data comes from the API as a hash within the overall object data. The main keys of the hash
|
40
|
+
# define the included targets of the scope. A sub-hash defines limitations on those inclusions,
|
41
|
+
# and another sub-hash defines explicit exclusions.
|
42
|
+
#
|
43
|
+
# This class provides methods for adding, removing, or fully replacing the
|
44
|
+
# various parts of the scope's inclusions, limitations, and exclusions.
|
45
|
+
#
|
46
|
+
# @todo Implement simple LDAP queries using the defined {LDAPServer}s to confirm the
|
47
|
+
# existance of users or groups used in limitations and exclusions. As things are now
|
48
|
+
# if you add invalid user or group names, you'll get a 409 conflict error when you try
|
49
|
+
# to save your changes to the JSS.
|
50
|
+
#
|
51
|
+
# @see JSS::Scopable
|
52
|
+
#
|
54
53
|
class Scope
|
55
54
|
|
56
|
-
|
57
|
-
### Mix-Ins
|
55
|
+
# Class Constants
|
58
56
|
#####################################
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
78
|
-
:
|
79
|
-
:
|
80
|
-
:
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
:user => JSS::User,
|
87
|
-
:user_groups => JSS::UserGroup,
|
88
|
-
:user_group => JSS::UserGroup
|
89
|
-
}
|
90
|
-
|
91
|
-
### Some things get checked in LDAP as well as the JSS
|
92
|
-
LDAP_USER_KEYS = [:user, :users]
|
93
|
-
LDAP_GROUP_KEYS = [:user_groups, :user_group]
|
58
|
+
# These are the classes that Scopes can use for defining a scope,
|
59
|
+
# keyed by appropriate symbols.
|
60
|
+
SCOPING_CLASSES = {
|
61
|
+
computers: JSS::Computer,
|
62
|
+
computer: JSS::Computer,
|
63
|
+
computer_groups: JSS::ComputerGroup,
|
64
|
+
computer_group: JSS::ComputerGroup,
|
65
|
+
mobile_devices: JSS::MobileDevice,
|
66
|
+
mobile_device: JSS::MobileDevice,
|
67
|
+
mobile_device_groups: JSS::MobileDeviceGroup,
|
68
|
+
mobile_device_group: JSS::MobileDeviceGroup,
|
69
|
+
buildings: JSS::Building,
|
70
|
+
building: JSS::Building,
|
71
|
+
departments: JSS::Department,
|
72
|
+
department: JSS::Department,
|
73
|
+
network_segments: JSS::NetworkSegment,
|
74
|
+
network_segment: JSS::NetworkSegment,
|
75
|
+
users: JSS::User,
|
76
|
+
user: JSS::User,
|
77
|
+
user_groups: JSS::UserGroup,
|
78
|
+
user_group: JSS::UserGroup
|
79
|
+
}.freeze
|
80
|
+
|
81
|
+
# Some things get checked in LDAP as well as the JSS
|
82
|
+
LDAP_USER_KEYS = %i[user users].freeze
|
83
|
+
LDAP_GROUP_KEYS = %i[user_groups user_group].freeze
|
94
84
|
CHECK_LDAP_KEYS = LDAP_USER_KEYS + LDAP_GROUP_KEYS
|
95
85
|
|
96
|
-
|
97
|
-
|
98
|
-
TARGETS_AND_GROUPS = {:
|
86
|
+
# This hash maps the availble Scope Target keys from SCOPING_CLASSES to
|
87
|
+
# their corresponding target group keys from SCOPING_CLASSES.
|
88
|
+
TARGETS_AND_GROUPS = { computers: :computer_groups, mobile_devices: :mobile_device_groups }.freeze
|
99
89
|
|
100
|
-
|
101
|
-
|
102
|
-
INCLUSIONS = [
|
90
|
+
# These can be part of the base inclusion list of the scope,
|
91
|
+
# along with the appropriate target and target group keys
|
92
|
+
INCLUSIONS = %i[buildings departments].freeze
|
103
93
|
|
104
|
-
|
105
|
-
LIMITATIONS = [
|
94
|
+
# These can limit the inclusion list
|
95
|
+
LIMITATIONS = %i[network_segments users user_groups].freeze
|
106
96
|
|
107
|
-
|
97
|
+
# any of them can be excluded
|
108
98
|
EXCLUSIONS = INCLUSIONS + LIMITATIONS
|
109
99
|
|
110
|
-
|
100
|
+
# Here's a default scope as it might come from the API.
|
111
101
|
DEFAULT_SCOPE = {
|
112
|
-
:
|
113
|
-
:
|
114
|
-
:
|
115
|
-
:
|
116
|
-
}
|
117
|
-
|
118
|
-
|
102
|
+
all_computers: true,
|
103
|
+
all_mobile_devices: true,
|
104
|
+
limitations: {},
|
105
|
+
exclusions: {}
|
106
|
+
}.freeze
|
119
107
|
|
120
|
-
|
121
|
-
### Attributes
|
108
|
+
# Attributes
|
122
109
|
######################
|
123
110
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
111
|
+
# @return [JSS::APIObject subclass]
|
112
|
+
#
|
113
|
+
# A reference to the object that contains this Scope
|
114
|
+
#
|
115
|
+
# For telling it when a change is made and an update needed
|
129
116
|
attr_accessor :container
|
130
117
|
|
131
|
-
|
132
|
-
|
118
|
+
# @return [Boolean] should we expect a potential 409 Conflict
|
119
|
+
# if we can't connect to LDAP servers for verification?
|
133
120
|
attr_accessor :unable_to_verify_ldap_entries
|
134
121
|
|
135
|
-
|
122
|
+
# what type of target is this scope for? Computers or Mobiledevices?
|
136
123
|
attr_reader :target_class
|
137
124
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
125
|
+
# @return [Hash<Array>]
|
126
|
+
#
|
127
|
+
# The items which form the base scope of included targets
|
128
|
+
#
|
129
|
+
# This is the group of targets to which the limitations and exclusions apply.
|
130
|
+
# they keys are:
|
131
|
+
# - :targets
|
132
|
+
# - :target_groups
|
133
|
+
# - :departments
|
134
|
+
# - :buildings
|
135
|
+
# and the values are Arrays of names of those things.
|
136
|
+
#
|
150
137
|
attr_reader :inclusions
|
151
138
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
139
|
+
# @return [Boolean]
|
140
|
+
#
|
141
|
+
# Does this scope cover all targets?
|
142
|
+
#
|
143
|
+
# If this is true, the @inclusions Hash is ignored, and all
|
144
|
+
# targets in the JSS form the base scope.
|
145
|
+
#
|
159
146
|
attr_reader :all_targets
|
160
147
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
### - :user_groups
|
171
|
-
###
|
148
|
+
# @return [Hash<Array>]
|
149
|
+
#
|
150
|
+
# The items in these arrays are the limitations applied to targets in the @inclusions .
|
151
|
+
#
|
152
|
+
# The arrays of names are:
|
153
|
+
# - :network_segments
|
154
|
+
# - :users
|
155
|
+
# - :user_groups
|
156
|
+
#
|
172
157
|
attr_reader :limitations
|
173
158
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
159
|
+
# @return [Hash<Array>]
|
160
|
+
#
|
161
|
+
# The items in these arrays are the exclusions applied to targets in the @inclusions .
|
162
|
+
#
|
163
|
+
# The arrays of names are:
|
164
|
+
# - :targets
|
165
|
+
# - :target_groups
|
166
|
+
# - :departments
|
167
|
+
# - :buildings
|
168
|
+
# - :network_segments
|
169
|
+
# - :users
|
170
|
+
# - :user_groups
|
171
|
+
#
|
187
172
|
attr_reader :exclusions
|
188
173
|
|
189
|
-
|
190
|
-
#####################################
|
191
|
-
### Public Instance Methods
|
174
|
+
# Public Instance Methods
|
192
175
|
#####################################
|
193
176
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
api_scope ||= DEFAULT_SCOPE
|
177
|
+
# If raw_scope is empty, a default scope, scoped to all targets, is created, and can be modified
|
178
|
+
# as needed.
|
179
|
+
#
|
180
|
+
# @param target_key[Symbol] the kind of thing we're scopeing, one of {TARGETS_AND_GROUPS}
|
181
|
+
#
|
182
|
+
# @param raw_scope[Hash] the JSON :scope data from an API query that is scopable, e.g. a Policy.
|
183
|
+
#
|
184
|
+
def initialize(target_key, raw_scope = nil)
|
185
|
+
raw_scope ||= DEFAULT_SCOPE
|
204
186
|
raise JSS::InvalidDataError, "The target class of a Scope must be one of the symbols :#{TARGETS_AND_GROUPS.keys.join(', :')}" unless TARGETS_AND_GROUPS.keys.include? target_key
|
205
187
|
|
206
188
|
@target_key = target_key
|
@@ -212,70 +194,66 @@ module JSS
|
|
212
194
|
@exclusion_keys = [@target_key, @group_key] + EXCLUSIONS
|
213
195
|
|
214
196
|
@all_key = "all_#{target_key}".to_sym
|
215
|
-
@all_targets =
|
197
|
+
@all_targets = raw_scope[@all_key]
|
216
198
|
|
217
|
-
|
218
|
-
|
199
|
+
# Everything gets mapped from an Array of Hashes to an Array of names (or an empty array)
|
200
|
+
# since names are all that really matter when submitting the scope.
|
219
201
|
@inclusions = {}
|
220
|
-
@inclusion_keys.each{|k| @inclusions[k] =
|
202
|
+
@inclusion_keys.each { |k| @inclusions[k] = raw_scope[k] ? raw_scope[k].map { |n| n[:name] } : [] }
|
221
203
|
|
222
204
|
@limitations = {}
|
223
|
-
if
|
224
|
-
LIMITATIONS.each{|k| @limitations[k] =
|
205
|
+
if raw_scope[:limitations]
|
206
|
+
LIMITATIONS.each { |k| @limitations[k] = raw_scope[:limitations][k] ? raw_scope[:limitations][k].map { |n| n[:name] } : [] }
|
225
207
|
end
|
226
208
|
|
227
209
|
@exclusions = {}
|
228
|
-
if
|
229
|
-
@exclusion_keys.each{|k| @exclusions[k] =
|
210
|
+
if raw_scope[:exclusions]
|
211
|
+
@exclusion_keys.each { |k| @exclusions[k] = raw_scope[:exclusions][k] ? raw_scope[:exclusions][k].map { |n| n[:name] } : [] }
|
230
212
|
end
|
231
213
|
|
232
214
|
@container = nil
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
### @return [void]
|
245
|
-
###
|
215
|
+
end # init
|
216
|
+
|
217
|
+
# Set the scope's inclusions to all targets.
|
218
|
+
#
|
219
|
+
# By default, the limitations and exclusions remain.
|
220
|
+
# If a non-false parameter is provided, they will be removed also.
|
221
|
+
#
|
222
|
+
# @param clear[Boolean] Should the limitations and exclusions be removed also?
|
223
|
+
#
|
224
|
+
# @return [void]
|
225
|
+
#
|
246
226
|
def include_all(clear = false)
|
247
227
|
@inclusions = {}
|
248
|
-
@inclusion_keys.each{|k| @inclusions[k] = []}
|
228
|
+
@inclusion_keys.each { |k| @inclusions[k] = [] }
|
249
229
|
@all_targets = true
|
250
230
|
if clear
|
251
231
|
@limitations = {}
|
252
|
-
LIMITATIONS.each{|k| @limitations[k] = []}
|
232
|
+
LIMITATIONS.each { |k| @limitations[k] = [] }
|
253
233
|
|
254
234
|
@exclusions = {}
|
255
|
-
@exclusion_keys.each{|k| @exclusions[k] = []}
|
235
|
+
@exclusion_keys.each { |k| @exclusions[k] = [] }
|
256
236
|
end
|
257
237
|
@container.should_update if @container
|
258
238
|
end
|
259
239
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
### @return [void]
|
275
|
-
###
|
240
|
+
# Replace a list of item names for inclusion in this scope.
|
241
|
+
#
|
242
|
+
# The list must be an Array of names of items of the Class represented by the key.
|
243
|
+
# Each will be checked for existence in the JSS, and an exception raised if the item doesn't exist.
|
244
|
+
#
|
245
|
+
# @param key[Symbol] the key from #{SCOPING_CLASSES} for the kind of items being included, :computer, :building, etc...
|
246
|
+
#
|
247
|
+
# @param list[Array] the names of the items being added
|
248
|
+
#
|
249
|
+
# @example
|
250
|
+
# set_inclusion(:computers, ['kimchi','mantis'])
|
251
|
+
#
|
252
|
+
# @return [void]
|
253
|
+
#
|
276
254
|
def set_inclusion(key, list)
|
277
255
|
raise JSS::InvalidDataError, "Inclusion key must be one of :#{@inclusion_keys.join(', :')}" unless @inclusion_keys.include? key
|
278
|
-
raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.
|
256
|
+
raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.is_a? Array
|
279
257
|
|
280
258
|
return nil if list.sort == @inclusions[key].sort
|
281
259
|
|
@@ -283,15 +261,15 @@ module JSS
|
|
283
261
|
if list.empty?
|
284
262
|
@inclusion[key] = list
|
285
263
|
# if ALL the @inclusion keys are empty, then set all targets to true.
|
286
|
-
@all_targets = @inclusions.values.reject{|a| a.nil?
|
264
|
+
@all_targets = @inclusions.values.reject { |a| a.nil? || a.empty? }.empty?
|
287
265
|
@container.should_update if @container
|
288
266
|
return list
|
289
267
|
end
|
290
268
|
|
291
|
-
|
269
|
+
# check the names
|
292
270
|
list.each do |name|
|
293
271
|
raise JSS::NoSuchItemError, "No existing #{key} with name '#{name}'" unless check_name key, name
|
294
|
-
raise JSS::AlreadyExistsError, "Can't set #{key} scope to '#{name}' because it's already an explicit exclusion." if @exclusions[key]
|
272
|
+
raise JSS::AlreadyExistsError, "Can't set #{key} scope to '#{name}' because it's already an explicit exclusion." if @exclusions[key] && @exclusions[key].include?(name)
|
295
273
|
end # each
|
296
274
|
|
297
275
|
@inclusions[key] = list
|
@@ -299,84 +277,78 @@ module JSS
|
|
299
277
|
@container.should_update if @container
|
300
278
|
end # sinclude_in_scope
|
301
279
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
###
|
317
|
-
def add_inclusion (key, item)
|
280
|
+
# Add a single item for this inclusion in this scope.
|
281
|
+
#
|
282
|
+
# The item name will be checked for existence in the JSS, and an exception raised if the item doesn't exist.
|
283
|
+
#
|
284
|
+
# @param key[Symbol] the key from #{SCOPING_CLASSES} for the kind of item being added, :computer, :building, etc...
|
285
|
+
#
|
286
|
+
# @param item[String] the name of the item being added
|
287
|
+
#
|
288
|
+
# @example
|
289
|
+
# add_inclusion(:computer, "mantis")
|
290
|
+
#
|
291
|
+
# @return [void]
|
292
|
+
#
|
293
|
+
def add_inclusion(key, item)
|
318
294
|
raise JSS::InvalidDataError, "Inclusion key must be one of :#{@inclusion_keys.join(', :')}" unless @inclusion_keys.include? key
|
319
|
-
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.
|
295
|
+
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.is_a? String
|
320
296
|
|
321
|
-
return nil if @inclusions[key]
|
297
|
+
return nil if @inclusions[key] && @inclusions[key].include?(item)
|
322
298
|
|
323
|
-
|
299
|
+
# check the name
|
324
300
|
raise JSS::NoSuchItemError, "No existing #{key} with name '#{item}'" unless check_name key, item
|
325
|
-
raise JSS::AlreadyExistsError, "Can't set #{key} scope to '#{item}' because it's already an explicit exclusion." if @exclusions[key]
|
326
|
-
|
301
|
+
raise JSS::AlreadyExistsError, "Can't set #{key} scope to '#{item}' because it's already an explicit exclusion." if @exclusions[key] && @exclusions[key].include?(item)
|
327
302
|
|
328
303
|
@inclusions[key] << item
|
329
304
|
@all_targets = false
|
330
305
|
@container.should_update if @container
|
331
306
|
end
|
332
307
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
def remove_inclusion (key, item)
|
308
|
+
# Remove a single item for this scope.
|
309
|
+
#
|
310
|
+
# @param key[Symbol] the key from #{SCOPING_CLASSES} for the kind of item being removed, :computer, :building, etc...
|
311
|
+
#
|
312
|
+
# @param item[String] the name of the item being removed
|
313
|
+
#
|
314
|
+
# @example
|
315
|
+
# remove_inclusion(:computer, "mantis")
|
316
|
+
#
|
317
|
+
# @return [void]
|
318
|
+
#
|
319
|
+
def remove_inclusion(key, item)
|
346
320
|
raise JSS::InvalidDataError, "Inclusion key must be one of :#{@inclusion_keys.join(', :')}" unless @inclusion_keys.include? key
|
347
|
-
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.
|
321
|
+
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.is_a? String
|
348
322
|
|
349
|
-
return nil unless @inclusions[key]
|
323
|
+
return nil unless @inclusions[key] && @inclusions[key].include?(item)
|
350
324
|
|
351
325
|
@inclusions[key] -= [item]
|
352
326
|
|
353
327
|
# if ALL the @inclusion keys are empty, then set all targets to true.
|
354
|
-
@all_targets =
|
328
|
+
@all_targets = @inclusions.values.reject { |a| a.nil? || a.empty? }.empty?
|
355
329
|
|
356
330
|
@container.should_update if @container
|
357
331
|
end
|
358
332
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
###
|
377
|
-
def set_limitation (key, list)
|
333
|
+
# Replace a limitation list for this scope.
|
334
|
+
#
|
335
|
+
# The list must be an Array of names of items of the Class represented by the key.
|
336
|
+
# Each will be checked for existence in the JSS, and an exception raised if the item doesn't exist.
|
337
|
+
#
|
338
|
+
# @param key[Symbol] the type of items being set as limitations, :network_segments, :users, etc...
|
339
|
+
#
|
340
|
+
# @param list[Array] the names of the items being set as limitations
|
341
|
+
#
|
342
|
+
# @example
|
343
|
+
# set_limitation(:network_segments, ['foo','bar'])
|
344
|
+
#
|
345
|
+
# @return [void]
|
346
|
+
#
|
347
|
+
# @todo handle ldap user group lookups
|
348
|
+
#
|
349
|
+
def set_limitation(key, list)
|
378
350
|
raise JSS::InvalidDataError, "Limitation key must be one of :#{LIMITATIONS.join(', :')}" unless LIMITATIONS.include? key
|
379
|
-
raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.
|
351
|
+
raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.is_a? Array
|
380
352
|
return nil if list.sort == @limitations[key].sort
|
381
353
|
|
382
354
|
if list.empty?
|
@@ -385,92 +357,85 @@ module JSS
|
|
385
357
|
return list
|
386
358
|
end
|
387
359
|
|
388
|
-
|
360
|
+
# check the names
|
389
361
|
list.each do |name|
|
390
|
-
raise JSS::NoSuchItemError, "No existing #{key} with name '#{name}'" unless check_name key,
|
391
|
-
raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." if @exclusions[key]
|
362
|
+
raise JSS::NoSuchItemError, "No existing #{key} with name '#{name}'" unless check_name key, name
|
363
|
+
raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." if @exclusions[key] && @exclusions[key].include?(name)
|
392
364
|
end # each
|
393
365
|
|
394
366
|
@limitations[key] = list
|
395
367
|
@container.should_update if @container
|
396
368
|
end # limit scope
|
397
369
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
###
|
415
|
-
def add_limitation (key, item)
|
370
|
+
# Add a single item for limiting this scope.
|
371
|
+
#
|
372
|
+
# The item name will be checked for existence in the JSS, and an exception raised if the item doesn't exist.
|
373
|
+
#
|
374
|
+
# @param key[Symbol] the type of item being added, :computer, :building, etc...
|
375
|
+
#
|
376
|
+
# @param item[String] the name of the item being added
|
377
|
+
#
|
378
|
+
# @example
|
379
|
+
# add_limitation(:network_segments, "foo")
|
380
|
+
#
|
381
|
+
# @return [void]
|
382
|
+
#
|
383
|
+
# @todo handle ldap user/group lookups
|
384
|
+
#
|
385
|
+
def add_limitation(key, item)
|
416
386
|
raise JSS::InvalidDataError, "Limitation key must be one of :#{LIMITATIONS.join(', :')}" unless LIMITATIONS.include? key
|
417
|
-
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.
|
387
|
+
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.is_a? String
|
418
388
|
|
419
|
-
return nil if @limitations[key]
|
389
|
+
return nil if @limitations[key] && @limitations[key].include?(item)
|
420
390
|
|
421
|
-
|
391
|
+
# check the name
|
422
392
|
raise JSS::NoSuchItemError, "No existing #{key} with name '#{item}'" unless check_name key, item
|
423
|
-
raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." if @exclusions[key]
|
424
|
-
|
393
|
+
raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." if @exclusions[key] && @exclusions[key].include?(item)
|
425
394
|
|
426
395
|
@limitations[key] << item
|
427
396
|
@container.should_update if @container
|
428
397
|
end
|
429
398
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
def remove_limitation( key, item)
|
399
|
+
# Remove a single item for limiting this scope.
|
400
|
+
#
|
401
|
+
# @param key[Symbol] the type of item being removed, :computer, :building, etc...
|
402
|
+
#
|
403
|
+
# @param item[String] the name of the item being removed
|
404
|
+
#
|
405
|
+
# @example
|
406
|
+
# remove_limitation(:network_segments, "foo")
|
407
|
+
#
|
408
|
+
# @return [void]
|
409
|
+
#
|
410
|
+
# @todo handle ldap user/group lookups
|
411
|
+
#
|
412
|
+
def remove_limitation(key, item)
|
445
413
|
raise JSS::InvalidDataError, "Limitation key must be one of :#{LIMITATIONS.join(', :')}" unless LIMITATIONS.include? key
|
446
|
-
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.
|
414
|
+
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.is_a? String
|
447
415
|
|
448
|
-
return nil unless @limitations[key]
|
416
|
+
return nil unless @limitations[key] && @limitations[key].include?(item)
|
449
417
|
|
450
418
|
@limitations[key] -= [item]
|
451
419
|
@container.should_update if @container
|
452
|
-
end
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
### @return [void]
|
470
|
-
###
|
471
|
-
def set_exclusion (key, list)
|
420
|
+
end ###
|
421
|
+
|
422
|
+
# Replace an exclusion list for this scope
|
423
|
+
#
|
424
|
+
# The list must be an Array of names of items of the Class being excluded from the scope
|
425
|
+
# Each will be checked for existence in the JSS, and an exception raised if the item doesn't exist.
|
426
|
+
#
|
427
|
+
# @param key[Symbol] the type of item being excluded, :computer, :building, etc...
|
428
|
+
#
|
429
|
+
# @param list[Array] the names of the items being added
|
430
|
+
#
|
431
|
+
# @example
|
432
|
+
# set_exclusion(:network_segments, ['foo','bar'])
|
433
|
+
#
|
434
|
+
# @return [void]
|
435
|
+
#
|
436
|
+
def set_exclusion(key, list)
|
472
437
|
raise JSS::InvalidDataError, "Exclusion key must be one of :#{@exclusion_keys.join(', :')}" unless @exclusion_keys.include? key
|
473
|
-
raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.
|
438
|
+
raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.is_a? Array
|
474
439
|
return nil if list.sort == @exclusions[key].sort
|
475
440
|
|
476
441
|
if list.empty?
|
@@ -479,131 +444,122 @@ module JSS
|
|
479
444
|
return list
|
480
445
|
end
|
481
446
|
|
482
|
-
|
447
|
+
# check the names
|
483
448
|
list.each do |name|
|
484
449
|
raise JSS::NoSuchItemError, "No existing #{key} with name '#{name}'" unless check_name key, name
|
485
450
|
case key
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
451
|
+
when *@inclusion_keys
|
452
|
+
raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{name}' because it's already explicitly included." if @inclusions[key] && @inclusions[key].include?(name)
|
453
|
+
when *LIMITATIONS
|
454
|
+
raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{name}' because it's already an explicit limitation." if @limitations[key] && @limitations[key].include?(name)
|
490
455
|
end
|
491
|
-
|
492
456
|
end # each
|
493
457
|
|
494
458
|
@exclusions[key] = list
|
495
459
|
@container.should_update if @container
|
496
460
|
end # limit scope
|
497
461
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
def add_exclusion (key, item)
|
462
|
+
# Add a single item for exclusions of this scope.
|
463
|
+
#
|
464
|
+
# The item name will be checked for existence in the JSS, and an exception raised if the item doesn't exist.
|
465
|
+
#
|
466
|
+
# @param key[Symbol] the type of item being added to the exclusions, :computer, :building, etc...
|
467
|
+
#
|
468
|
+
# @param item[String] the name of the item being added
|
469
|
+
#
|
470
|
+
# @example
|
471
|
+
# add_exclusion(:network_segments, "foo")
|
472
|
+
#
|
473
|
+
# @return [void]
|
474
|
+
#
|
475
|
+
def add_exclusion(key, item)
|
513
476
|
raise JSS::InvalidDataError, "Exclusion key must be one of :#{@exclusion_keys.join(', :')}" unless @exclusion_keys.include? key
|
514
|
-
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.
|
477
|
+
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.is_a? String
|
515
478
|
|
516
|
-
return nil if @exclusions[key]
|
479
|
+
return nil if @exclusions[key] && @exclusions[key].include?(item)
|
517
480
|
|
518
|
-
|
481
|
+
# check the name
|
519
482
|
raise JSS::NoSuchItemError, "No existing #{key} with name '#{item}'" unless check_name key, item
|
520
|
-
raise JSS::AlreadyExistsError, "Can't exclude #{key} scope to '#{item}' because it's already explicitly included." if @inclusions[key]
|
521
|
-
raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{item}' because it's already an explicit limitation." if @limitations[key]
|
483
|
+
raise JSS::AlreadyExistsError, "Can't exclude #{key} scope to '#{item}' because it's already explicitly included." if @inclusions[key] && @inclusions[key].include?(item)
|
484
|
+
raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{item}' because it's already an explicit limitation." if @limitations[key] && @limitations[key].include?(item)
|
522
485
|
|
523
486
|
@exclusions[key] << item
|
524
487
|
@container.should_update if @container
|
525
488
|
end
|
526
489
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
def remove_exclusion (key, item)
|
490
|
+
# Remove a single item for exclusions of this scope
|
491
|
+
#
|
492
|
+
# @param key[Symbol] the type of item being removed from the excludions, :computer, :building, etc...
|
493
|
+
#
|
494
|
+
# @param item[String] the name of the item being removed
|
495
|
+
#
|
496
|
+
# @example
|
497
|
+
# remove_exclusion(:network_segments, "foo")
|
498
|
+
#
|
499
|
+
# @return [void]
|
500
|
+
#
|
501
|
+
def remove_exclusion(key, item)
|
540
502
|
raise JSS::InvalidDataError, "Exclusion key must be one of :#{@exclusion_keys.join(', :')}" unless @exclusion_keys.include? key
|
541
|
-
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.
|
503
|
+
raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.is_a? String
|
542
504
|
|
543
|
-
return nil unless @exclusions[key]
|
505
|
+
return nil unless @exclusions[key] && @exclusions[key].include?(item)
|
544
506
|
|
545
507
|
@exclusions[key] -= [item]
|
546
508
|
@container.should_update if @container
|
547
509
|
end
|
548
510
|
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
###
|
511
|
+
# @api private
|
512
|
+
# Return a REXML Element containing the current state of the Scope
|
513
|
+
# for adding into the XML of the container.
|
514
|
+
#
|
515
|
+
# @return [REXML::Element]
|
516
|
+
#
|
556
517
|
def scope_xml
|
557
|
-
scope = REXML::Element.new
|
518
|
+
scope = REXML::Element.new 'scope'
|
558
519
|
scope.add_element(@all_key.to_s).text = @all_targets
|
559
520
|
|
560
|
-
@inclusions.each do |klass,list|
|
561
|
-
list_as_hash = list.map{|i| {:
|
562
|
-
scope << SCOPING_CLASSES[klass].xml_list(
|
521
|
+
@inclusions.each do |klass, list|
|
522
|
+
list_as_hash = list.map { |i| { name: i } }
|
523
|
+
scope << SCOPING_CLASSES[klass].xml_list(list_as_hash, :name)
|
563
524
|
end
|
564
525
|
|
565
526
|
limitations = scope.add_element('limitations')
|
566
|
-
@limitations.each do |klass,list|
|
567
|
-
list_as_hash = list.map{|i| {:
|
568
|
-
limitations << SCOPING_CLASSES[klass].xml_list(
|
527
|
+
@limitations.each do |klass, list|
|
528
|
+
list_as_hash = list.map { |i| { name: i } }
|
529
|
+
limitations << SCOPING_CLASSES[klass].xml_list(list_as_hash, :name)
|
569
530
|
end
|
570
531
|
|
571
532
|
exclusions = scope.add_element('exclusions')
|
572
|
-
@exclusions.each do |klass,list|
|
573
|
-
list_as_hash = list.map{|i| {:
|
574
|
-
exclusions << SCOPING_CLASSES[klass].xml_list(
|
533
|
+
@exclusions.each do |klass, list|
|
534
|
+
list_as_hash = list.map { |i| { name: i } }
|
535
|
+
exclusions << SCOPING_CLASSES[klass].xml_list(list_as_hash, :name)
|
575
536
|
end
|
576
|
-
|
577
|
-
end #scope_xml
|
537
|
+
scope
|
538
|
+
end # scope_xml
|
578
539
|
|
579
|
-
|
580
|
-
### Aliases
|
540
|
+
# Aliases
|
581
541
|
|
582
542
|
alias all_targets? all_targets
|
583
543
|
|
584
|
-
|
585
|
-
#####################################
|
586
|
-
### Private Instance Methods
|
544
|
+
# Private Instance Methods
|
587
545
|
#####################################
|
588
546
|
private
|
589
547
|
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
###
|
548
|
+
# Given a name of some class of item to be used in the scope, check that it
|
549
|
+
# exists in the JSS.
|
550
|
+
#
|
551
|
+
# @return [Boolean] does the name exist for the key in JSS or LDAP?
|
552
|
+
#
|
596
553
|
def check_name(key, name)
|
597
|
-
|
598
|
-
found_in_jss = SCOPING_CLASSES[key].all_names(api: @api).include?(name)
|
554
|
+
found_in_jss = SCOPING_CLASSES[key].all_names(api: container.api).include?(name)
|
599
555
|
|
600
556
|
return true if found_in_jss
|
601
557
|
|
602
558
|
return false unless CHECK_LDAP_KEYS.include?(key)
|
603
559
|
|
604
560
|
begin
|
605
|
-
return JSS::LDAPServer.user_in_ldap?(name, api:
|
606
|
-
return JSS::LDAPServer.group_in_ldap?(name, api:
|
561
|
+
return JSS::LDAPServer.user_in_ldap?(name, api: container.api) if LDAP_USER_KEYS.include?(key)
|
562
|
+
return JSS::LDAPServer.group_in_ldap?(name, api: container.api) if LDAP_GROUP_KEYS.include?(key)
|
607
563
|
|
608
564
|
# if an ldap server isn't connected, make a note of it and return true
|
609
565
|
rescue JSS::InvalidConnectionError
|
@@ -611,11 +567,11 @@ module JSS
|
|
611
567
|
return true
|
612
568
|
end # begin
|
613
569
|
|
614
|
-
|
570
|
+
false
|
615
571
|
end
|
616
572
|
|
573
|
+
end # class Scope
|
617
574
|
|
575
|
+
end # module Scopable
|
618
576
|
|
619
|
-
end # class Scope
|
620
|
-
end #module Scopable
|
621
577
|
end # module
|