ruby-jss 0.14.0 → 1.0.0b2
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 +31 -0
- data/lib/jss.rb +5 -4
- data/lib/jss/api_connection.rb +67 -33
- data/lib/jss/api_object.rb +86 -34
- data/lib/jss/api_object/categorizable.rb +53 -28
- data/lib/jss/api_object/configuration_profile.rb +7 -0
- data/lib/jss/api_object/creatable.rb +6 -11
- data/lib/jss/api_object/criteriable/criterion.rb +9 -7
- data/lib/jss/api_object/distribution_point.rb +1 -0
- data/lib/jss/api_object/group.rb +177 -233
- data/lib/jss/api_object/mobile_device_application.rb +6 -0
- data/lib/jss/api_object/package.rb +8 -1
- data/lib/jss/api_object/patch_policy.rb +588 -2
- data/lib/jss/api_object/patch_source.rb +357 -0
- data/lib/jss/api_object/patch_source/patch_external_source.rb +156 -0
- data/lib/jss/api_object/{patch.rb → patch_source/patch_internal_source.rb} +21 -4
- data/lib/jss/api_object/patch_title.rb +480 -0
- data/lib/jss/api_object/patch_title/version.rb +171 -0
- data/lib/jss/api_object/policy.rb +780 -679
- data/lib/jss/api_object/scopable/scope.rb +18 -13
- data/lib/jss/api_object/script.rb +7 -0
- data/lib/jss/api_object/self_servable.rb +417 -70
- data/lib/jss/api_object/self_servable/icon.rb +12 -0
- data/lib/jss/api_object/sitable.rb +4 -4
- data/lib/jss/api_object/updatable.rb +2 -2
- data/lib/jss/exceptions.rb +22 -19
- data/lib/jss/ruby_extensions/hash.rb +18 -13
- data/lib/jss/utility.rb +7 -71
- data/lib/jss/validate.rb +68 -3
- data/lib/jss/version.rb +1 -1
- data/lib/jss/xml_workaround.rb +208 -0
- metadata +10 -5
@@ -41,15 +41,22 @@ module JSS
|
|
41
41
|
# Objects in the JSS present category data in two different ways:
|
42
42
|
#
|
43
43
|
# 1) An 'old' style, where the top-level Hash of the API data contains a
|
44
|
-
# :category which contains a String, being the category name.
|
44
|
+
# :category key which contains a String, being the category name.
|
45
45
|
#
|
46
|
-
# 2) A 'new' style, where the
|
47
|
-
#
|
48
|
-
#
|
49
|
-
# This module can detect and handle either type.
|
46
|
+
# 2) A 'new' style, where the :category key is a Hash with a :name and :id key.
|
47
|
+
# This Hash is usually in the :general subset, but may be elsewhere.
|
50
48
|
#
|
51
49
|
# Classes mixing in this module MUST:
|
52
50
|
#
|
51
|
+
# - Define the constant CATEGORY_SUBSET as a symbol indicating where in
|
52
|
+
# the API data the :category key will be found. The symbol is either
|
53
|
+
# :top for the top-level of the API data, or the name of the subsection
|
54
|
+
# Hash containing :category, e.g. :general.
|
55
|
+
#
|
56
|
+
# - Define the constant CATEGORY_DATA_TYPE as either String or Hash
|
57
|
+
# (the class names) which indicate if the contents of the :category key
|
58
|
+
# is a String (The category name) or a Hash (containing :name and :id)
|
59
|
+
#
|
53
60
|
# - call {#add_category_to_xml(xmldoc)} from their #rest_xml method if they are
|
54
61
|
# {Updatable} or {Creatable}
|
55
62
|
#
|
@@ -60,8 +67,9 @@ module JSS
|
|
60
67
|
|
61
68
|
CATEGORIZABLE = true
|
62
69
|
|
63
|
-
# When no category has been assigned, this is the 'name'
|
70
|
+
# When no category has been assigned, this is the 'name'
|
64
71
|
NO_CATEGORY_NAME = 'No category assigned'.freeze
|
72
|
+
# When no category has been assigned, this is the id
|
65
73
|
NO_CATEGORY_ID = -1
|
66
74
|
|
67
75
|
# Setting the category to any of these values will unset the category
|
@@ -73,12 +81,6 @@ module JSS
|
|
73
81
|
NO_CATEGORY_ID
|
74
82
|
].freeze
|
75
83
|
|
76
|
-
# These classes use old-style categories in their data.
|
77
|
-
OLD_STYLE_CATEGORY_CLASSES = [
|
78
|
-
JSS::Script,
|
79
|
-
JSS::Package
|
80
|
-
].freeze
|
81
|
-
|
82
84
|
# Mixed-in Public Instance Methods
|
83
85
|
#####################################
|
84
86
|
|
@@ -107,7 +109,7 @@ module JSS
|
|
107
109
|
#
|
108
110
|
def category_object
|
109
111
|
return nil unless category_assigned?
|
110
|
-
JSS::Category.
|
112
|
+
JSS::Category.fetch id: @category_id
|
111
113
|
end # cat obj
|
112
114
|
|
113
115
|
# Does this object have a category assigned?
|
@@ -187,18 +189,29 @@ module JSS
|
|
187
189
|
# @return [void] description_of_returned_object
|
188
190
|
#
|
189
191
|
def parse_category
|
190
|
-
|
191
|
-
|
192
|
+
cat =
|
193
|
+
if self.class::CATEGORY_SUBSET == :top
|
194
|
+
@init_data[:category]
|
195
|
+
else
|
196
|
+
@init_data[self.class::CATEGORY_SUBSET][:category]
|
197
|
+
end
|
198
|
+
|
199
|
+
if cat.is_a? String
|
200
|
+
@category_name = cat
|
192
201
|
@category_id = JSS::Category.category_id_from_name @category_name
|
193
|
-
|
194
|
-
@category_name =
|
195
|
-
@category_id =
|
202
|
+
else
|
203
|
+
@category_name = cat[:name]
|
204
|
+
@category_id = cat[:id]
|
196
205
|
end
|
197
|
-
|
198
|
-
@category_name = nil if @category_name.to_s.casecmp(NO_CATEGORY_NAME).zero?
|
199
|
-
@category_id = nil if @category_id == NO_CATEGORY_ID
|
206
|
+
clean_raw_categories
|
200
207
|
end # parse category
|
201
208
|
|
209
|
+
# Set the category name and id to nil, if need be.
|
210
|
+
def clean_raw_categories
|
211
|
+
@category_name = nil if @category_name && @category_name.to_s.casecmp(NO_CATEGORY_NAME).zero?
|
212
|
+
@category_id = nil if @category_id == NO_CATEGORY_ID
|
213
|
+
end
|
214
|
+
|
202
215
|
# Add the category to the XML for POSTing or PUTting to the API.
|
203
216
|
#
|
204
217
|
# @param xmldoc[REXML::Document] The in-construction XML document
|
@@ -206,15 +219,27 @@ module JSS
|
|
206
219
|
# @return [void]
|
207
220
|
#
|
208
221
|
def add_category_to_xml(xmldoc)
|
209
|
-
return if
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
cat_elem = gen_elem.add_element 'category'
|
222
|
+
return if category_name.to_s.empty?
|
223
|
+
cat_elem = REXML::Element.new('category')
|
224
|
+
|
225
|
+
if self.class::CATEGORY_DATA_TYPE == String
|
226
|
+
cat_elem.text = @category_name.to_s
|
227
|
+
elsif self.class::CATEGORY_DATA_TYPE == Hash
|
216
228
|
cat_elem.add_element('name').text = @category_name.to_s
|
229
|
+
else
|
230
|
+
raise JSS::InvalidDataError, "Uknown CATEGORY_DATA_TYPE for class #{self.class}"
|
231
|
+
end
|
232
|
+
|
233
|
+
root = xmldoc.root
|
234
|
+
|
235
|
+
if self.class::CATEGORY_SUBSET == :top
|
236
|
+
root.add_element cat_elem
|
237
|
+
return
|
217
238
|
end
|
239
|
+
|
240
|
+
parent = root.elements[self.class::CATEGORY_SUBSET.to_s]
|
241
|
+
parent ||= root.add_element self.class::CATEGORY_SUBSET.to_s
|
242
|
+
parent.add_element cat_elem
|
218
243
|
end # add_category_to_xml
|
219
244
|
|
220
245
|
end # module categorizable
|
@@ -62,6 +62,13 @@ module JSS
|
|
62
62
|
# Where is the Site data in the API JSON?
|
63
63
|
SITE_SUBSET = :general
|
64
64
|
|
65
|
+
# Where is the Category in the API JSON?
|
66
|
+
CATEGORY_SUBSET = :general
|
67
|
+
|
68
|
+
# How is the category stored in the API data?
|
69
|
+
CATEGORY_DATA_TYPE = Hash
|
70
|
+
|
71
|
+
|
65
72
|
# Attributes
|
66
73
|
###################################
|
67
74
|
|
@@ -26,12 +26,6 @@
|
|
26
26
|
###
|
27
27
|
module JSS
|
28
28
|
|
29
|
-
### Module Variables
|
30
|
-
#####################################
|
31
|
-
|
32
|
-
### Module Methods
|
33
|
-
#####################################
|
34
|
-
|
35
29
|
### Sub-Modules
|
36
30
|
#####################################
|
37
31
|
|
@@ -42,8 +36,8 @@ module JSS
|
|
42
36
|
### can be instantiated with :id => :new, and :name => "some_new_name".
|
43
37
|
###
|
44
38
|
###
|
45
|
-
### Classes mixing this module *must* provide a #rest_xml instance method that
|
46
|
-
### String to be submitted to the API for object creation.
|
39
|
+
### Classes mixing this module *must* provide a #rest_xml instance method that
|
40
|
+
### returns the XML String to be submitted to the API for object creation.
|
47
41
|
###
|
48
42
|
### The instance can be used to set desired values for the new object, and
|
49
43
|
### once everything's good, use #create to create it in the JSS.
|
@@ -52,6 +46,7 @@ module JSS
|
|
52
46
|
### the subclass may want to redefine #initialize to require those data before
|
53
47
|
### calling super, or may want to redefine #create or #rest_xml to check
|
54
48
|
### the data for consistency, and then call super
|
49
|
+
###
|
55
50
|
### It is also wise to have the individual setter methods do data validation
|
56
51
|
###
|
57
52
|
### @see APIObject#save
|
@@ -78,9 +73,9 @@ module JSS
|
|
78
73
|
#
|
79
74
|
def create(api: nil)
|
80
75
|
api ||= @api
|
81
|
-
raise JSS::UnsupportedError, "Creating or editing #{self.class::RSRC_LIST_KEY} isn't yet supported. Please use other Casper workflows." unless
|
76
|
+
raise JSS::UnsupportedError, "Creating or editing #{self.class::RSRC_LIST_KEY} isn't yet supported. Please use other Casper workflows." unless creatable?
|
82
77
|
raise AlreadyExistsError, "This #{self.class::RSRC_OBJECT_KEY} already exists. Use #update to make changes." if @in_jss
|
83
|
-
api.post_rsrc(
|
78
|
+
api.post_rsrc(rest_rsrc, rest_xml) =~ %r{><id>(\d+)</id><}
|
84
79
|
@id = Regexp.last_match(1).to_i
|
85
80
|
@in_jss = true
|
86
81
|
@need_to_update = false
|
@@ -99,7 +94,7 @@ module JSS
|
|
99
94
|
###
|
100
95
|
def clone(new_name, api: nil)
|
101
96
|
api ||= @api
|
102
|
-
raise JSS::UnsupportedError, 'This class is not creatable in via ruby-jss' unless
|
97
|
+
raise JSS::UnsupportedError, 'This class is not creatable in via ruby-jss' unless creatable?
|
103
98
|
raise JSS::AlreadyExistsError, "A #{self.class::RSRC_OBJECT_KEY} already exists with that name" if \
|
104
99
|
self.class.all_names(:refresh, api: api).include? new_name
|
105
100
|
|
@@ -1,26 +1,26 @@
|
|
1
1
|
### Copyright 2018 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
|
###
|
@@ -82,7 +82,9 @@ module JSS
|
|
82
82
|
"member of",
|
83
83
|
"not member of",
|
84
84
|
"current",
|
85
|
-
"not current"
|
85
|
+
"not current",
|
86
|
+
'matches regex',
|
87
|
+
'does not match regex'
|
86
88
|
]
|
87
89
|
|
88
90
|
### the acceptable symboles for and/or
|
data/lib/jss/api_object/group.rb
CHANGED
@@ -1,195 +1,159 @@
|
|
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
|
-
###
|
27
|
-
module JSS
|
28
|
-
|
29
|
-
#####################################
|
30
|
-
### Module Constants
|
31
|
-
#####################################
|
32
|
-
|
33
|
-
#####################################
|
34
|
-
### Module Variables
|
35
|
-
#####################################
|
1
|
+
# Copyright 2018 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
|
+
#
|
36
25
|
|
37
|
-
|
38
|
-
### Module Methods
|
39
|
-
#####################################
|
26
|
+
module JSS
|
40
27
|
|
41
|
-
|
42
|
-
### Classes
|
28
|
+
# Classes
|
43
29
|
#####################################
|
44
30
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
###
|
31
|
+
# This is the parent class of the smart/static group objects in the JSS
|
32
|
+
# namely, {ComputerGroup}, {MobileDeviceGroup}, and {UserGroup}
|
33
|
+
#
|
34
|
+
# It provides methods for working with the membership of static groups and, by
|
35
|
+
# including {JSS::Criteriable}, the criteria for smart groups.
|
36
|
+
#
|
37
|
+
# When changing the criteria of a smart group, use the #criteria attribute,
|
38
|
+
# which is a {JSS::Criteria} instance.
|
39
|
+
#
|
40
|
+
# Subclasses must define the constant MEMBER_CLASS which indicates Ruby class
|
41
|
+
# to which the group members belong (e.g. JSS::MobileDevice)
|
42
|
+
#
|
43
|
+
# @see JSS::APIObject
|
44
|
+
#
|
45
|
+
# @see JSS::Criteriable
|
46
|
+
#
|
62
47
|
class Group < JSS::APIObject
|
63
48
|
|
64
|
-
|
65
|
-
### Mix-Ins
|
49
|
+
# Mix-Ins
|
66
50
|
#####################################
|
67
51
|
include JSS::Creatable
|
68
52
|
include JSS::Updatable
|
69
53
|
include JSS::Criteriable
|
70
54
|
include JSS::Sitable
|
71
55
|
|
72
|
-
|
73
|
-
#####################################
|
74
|
-
### Class Constants
|
56
|
+
# Class Constants
|
75
57
|
#####################################
|
76
58
|
|
77
|
-
|
78
|
-
GROUP_TYPES = [
|
59
|
+
# the types of groups allowed for creation
|
60
|
+
GROUP_TYPES = %i[smart static].freeze
|
79
61
|
|
80
62
|
# Where is the Site data in the API JSON?
|
81
63
|
SITE_SUBSET = :top
|
82
64
|
|
83
|
-
|
84
|
-
### Class Variables
|
85
|
-
#####################################
|
86
|
-
|
87
|
-
#####################################
|
88
|
-
### Class Methods
|
65
|
+
# Class Methods
|
89
66
|
#####################################
|
90
67
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
###
|
68
|
+
# Returns an Array of all the smart
|
69
|
+
# groups.
|
70
|
+
#
|
95
71
|
def self.all_smart(refresh = false, api: JSS.api)
|
96
|
-
all(refresh, api: api).select{|g| g[:is_smart] }
|
72
|
+
all(refresh, api: api).select { |g| g[:is_smart] }
|
97
73
|
end
|
98
74
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
###
|
75
|
+
# Returns an Array of all the static
|
76
|
+
# groups.
|
77
|
+
#
|
103
78
|
def self.all_static(refresh = false, api: JSS.api)
|
104
|
-
all(refresh, api: api).select{|g|
|
79
|
+
all(refresh, api: api).select { |g| (g[:is_smart]) }
|
105
80
|
end
|
106
81
|
|
107
|
-
|
108
|
-
### Attributes
|
82
|
+
# Attributes
|
109
83
|
#####################################
|
110
84
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
85
|
+
# @return [Array<Hash>] the group membership
|
86
|
+
#
|
87
|
+
# Each hash contains the identifiers for
|
88
|
+
# a member of the group, those being:
|
89
|
+
# - :id, :name, and possibly :udid, :serial_number, :mac_address, :alt_mac_address, and :wifi_mac_address
|
90
|
+
#
|
91
|
+
# @see #member_ids
|
92
|
+
#
|
93
|
+
# @see #member_names
|
94
|
+
#
|
121
95
|
attr_reader :members
|
122
96
|
|
123
|
-
|
97
|
+
# @return [Boolean] is this a smart group
|
124
98
|
attr_reader :is_smart
|
125
99
|
|
126
|
-
|
100
|
+
# @return [Boolean] does this group send notifications when it changes?
|
127
101
|
attr_reader :notify_on_change
|
128
102
|
|
129
|
-
|
130
|
-
### @return [String] the :name of the site for this group
|
103
|
+
# @return [String] the :name of the site for this group
|
131
104
|
attr_reader :site
|
132
105
|
|
133
|
-
|
134
|
-
#####################################
|
135
|
-
### Constructor
|
106
|
+
# Constructor
|
136
107
|
#####################################
|
137
108
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
###
|
109
|
+
# When creating a new group in the JSS, you must call .new with a :type key
|
110
|
+
# and a value of :smart or :static, as well as a :name and the :id => :new
|
111
|
+
#
|
112
|
+
# @see JSS::APIObject
|
113
|
+
#
|
144
114
|
def initialize(args = {})
|
145
|
-
|
146
115
|
if args[:id] == :new
|
147
|
-
raise JSS::InvalidDataError,
|
116
|
+
raise JSS::InvalidDataError, 'New group creation must specify a :type of :smart or :static' unless GROUP_TYPES.include? args[:type]
|
148
117
|
end
|
149
118
|
|
150
119
|
super args
|
151
120
|
|
152
121
|
@is_smart = @init_data[:is_smart] || (args[:type] == :smart)
|
153
122
|
|
154
|
-
@members =
|
155
|
-
@init_data[self.class::MEMBER_CLASS::RSRC_LIST_KEY]
|
156
|
-
|
157
|
-
|
158
|
-
|
123
|
+
@members =
|
124
|
+
if @init_data[self.class::MEMBER_CLASS::RSRC_LIST_KEY]
|
125
|
+
@init_data[self.class::MEMBER_CLASS::RSRC_LIST_KEY]
|
126
|
+
else
|
127
|
+
[]
|
128
|
+
end
|
159
129
|
|
160
130
|
@site = JSS::APIObject.get_name(@init_data[:site])
|
131
|
+
end # init
|
161
132
|
|
162
|
-
|
163
|
-
|
164
|
-
#####################################
|
165
|
-
### Public Instance Methods
|
133
|
+
# Public Instance Methods
|
166
134
|
#####################################
|
167
135
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
def create
|
136
|
+
# @see Creatable#create
|
137
|
+
#
|
138
|
+
def create(calculate_members: true)
|
172
139
|
if @is_smart
|
173
|
-
raise JSS::MissingDataError,
|
140
|
+
raise JSS::MissingDataError, 'No criteria specified for smart group' unless @criteria
|
174
141
|
end
|
175
|
-
super
|
176
|
-
refresh_members
|
177
|
-
|
142
|
+
super()
|
143
|
+
refresh_members if calculate_members
|
144
|
+
@id
|
178
145
|
end
|
179
146
|
|
180
|
-
|
181
|
-
|
182
|
-
### @see Updatable#update
|
183
|
-
###
|
147
|
+
# @see Updatable#update
|
148
|
+
#
|
184
149
|
def update
|
185
150
|
super
|
186
151
|
refresh_members
|
187
152
|
true
|
188
153
|
end
|
189
154
|
|
190
|
-
|
191
|
-
|
192
|
-
###
|
155
|
+
# @see APIObject#delete
|
156
|
+
#
|
193
157
|
def delete
|
194
158
|
super
|
195
159
|
@is_smart = nil
|
@@ -198,54 +162,48 @@ module JSS
|
|
198
162
|
@members = []
|
199
163
|
end # delete
|
200
164
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
raise InvalidDataError, "Only smart groups have criteria." unless @is_smart
|
165
|
+
# Apply a new set of criteria to a smart group
|
166
|
+
#
|
167
|
+
# @param new_criteria[JSS::Criteria] the new criteria for the smart group
|
168
|
+
#
|
169
|
+
def criteria=(new_criteria)
|
170
|
+
raise InvalidDataError, 'Only smart groups have criteria.' unless @is_smart
|
208
171
|
super
|
209
172
|
end
|
210
173
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
###
|
174
|
+
# How many members of the group?
|
175
|
+
#
|
176
|
+
# @return [Integer] the number of members of the group
|
177
|
+
#
|
216
178
|
def size
|
217
179
|
@members.count
|
218
180
|
end
|
219
181
|
|
220
|
-
|
221
|
-
|
222
|
-
### @return [Array<String>] the names of the group members
|
223
|
-
###
|
182
|
+
# @return [Array<String>] the names of the group members
|
183
|
+
#
|
224
184
|
def member_names
|
225
|
-
@members.map{|m| m[:name]}
|
185
|
+
@members.map { |m| m[:name] }
|
226
186
|
end
|
227
187
|
|
228
|
-
|
229
|
-
|
230
|
-
###
|
188
|
+
# @return [Array<Integer>] the ids of the group members
|
189
|
+
#
|
231
190
|
def member_ids
|
232
|
-
@members.map{|m| m[:id]}
|
191
|
+
@members.map { |m| m[:id] }
|
233
192
|
end
|
234
193
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
def members= (new_members)
|
194
|
+
# Replace all @members with an array of uniq device identfiers (names, ids, serial numbers, etc)
|
195
|
+
# E.g: [ 'lambic', 1233, '2341', 'monkey']
|
196
|
+
#
|
197
|
+
# They must all be in the JSS or an error is raised
|
198
|
+
# before doing anything. See {#check_member}
|
199
|
+
#
|
200
|
+
# @param new_members[Array<Integer,String>] the new group members
|
201
|
+
#
|
202
|
+
# @return [void]
|
203
|
+
#
|
204
|
+
def members=(new_members)
|
247
205
|
raise UnsupportedError, "Smart group members can't be changed." if @is_smart
|
248
|
-
raise InvalidDataError,
|
206
|
+
raise InvalidDataError, 'Arg must be an array of names and/or ids' unless new_members.is_a? Array
|
249
207
|
ok_members = []
|
250
208
|
new_members.each do |m|
|
251
209
|
ok_members << check_member(m)
|
@@ -253,48 +211,41 @@ module JSS
|
|
253
211
|
|
254
212
|
ok_members.uniq!
|
255
213
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
end
|
214
|
+
# make sure we've actually changed...
|
215
|
+
return if members.map { |m| m[:id] }.sort == ok_members.map { |m| m[:id] }.sort
|
216
|
+
@members = ok_members
|
217
|
+
@need_to_update = true
|
261
218
|
end
|
262
219
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
def add_member(m)
|
220
|
+
# Add a member, by name or id
|
221
|
+
#
|
222
|
+
# @param m[Integer,String] the id or name of the member to add
|
223
|
+
#
|
224
|
+
# @return [void]
|
225
|
+
#
|
226
|
+
def add_member(mem)
|
271
227
|
raise UnsupportedError, "Smart group members can't be changed." if @is_smart
|
272
|
-
@members << check_member(
|
228
|
+
@members << check_member(mem)
|
273
229
|
@need_to_update = true
|
274
230
|
end
|
275
231
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
def remove_member(m)
|
232
|
+
# Remove a member by id, or name
|
233
|
+
#
|
234
|
+
# @param m[Integer,String] the id or name of the member to remove
|
235
|
+
#
|
236
|
+
# @return [void]
|
237
|
+
#
|
238
|
+
def remove_member(mem)
|
284
239
|
raise InvalidDataError, "Smart group members can't be changed." if @is_smart
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
else
|
289
|
-
raise JSS::NoSuchItemError, "No member matches '#{m}'"
|
290
|
-
end
|
240
|
+
raise InvalidDataError, "Can't remove nil" if mem.nil?
|
241
|
+
removed = @members.reject! { |mm| [mm[:id], mm[:name], mm[:username]].include? mem }
|
242
|
+
@need_to_update = true if removed
|
291
243
|
end
|
292
244
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
###
|
245
|
+
# Remove all members
|
246
|
+
#
|
247
|
+
# @return [void]
|
248
|
+
#
|
298
249
|
def clear
|
299
250
|
raise InvalidDataError, "Smart group members can't be changed." if @is_smart
|
300
251
|
return if @members.empty?
|
@@ -302,61 +253,55 @@ module JSS
|
|
302
253
|
@need_to_update = true
|
303
254
|
end
|
304
255
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
###
|
256
|
+
# Refresh the membership from the API
|
257
|
+
#
|
258
|
+
# @return [Array<Hash>] the refresh membership
|
259
|
+
#
|
310
260
|
def refresh_members
|
311
261
|
@members = @api.get_rsrc(@rest_rsrc)[self.class::RSRC_OBJECT_KEY][self.class::MEMBER_CLASS::RSRC_LIST_KEY]
|
312
262
|
end
|
313
263
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
def site= (new_val)
|
264
|
+
# Change the site for this group
|
265
|
+
#
|
266
|
+
# @param new_val[String] the name of the new site
|
267
|
+
#
|
268
|
+
# @return [void]
|
269
|
+
#
|
270
|
+
def site=(new_val)
|
322
271
|
raise JSS::NoSuchItemError, "No site named #{new_val} in the JSS" unless JSS::Site.all_names(api: @api).include? new_val
|
323
272
|
@site = new_val
|
324
273
|
@need_to_update = true
|
325
274
|
end
|
326
275
|
|
327
|
-
|
328
|
-
### aliases
|
276
|
+
# aliases
|
329
277
|
|
330
278
|
alias smart? is_smart
|
331
279
|
alias notify_on_change? notify_on_change
|
332
280
|
alias notify? notify_on_change
|
333
281
|
alias count size
|
334
282
|
|
335
|
-
|
336
|
-
### Public Instance Methods
|
283
|
+
# Public Instance Methods
|
337
284
|
#####################################
|
338
285
|
private
|
339
286
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
###
|
287
|
+
# Check that a potential group member is valid in the JSS.
|
288
|
+
# Arg must be an id or name.
|
289
|
+
# An exception is raised if the device doesn't exist.
|
290
|
+
#
|
291
|
+
# @return [Hash{:id=>Integer,:name=>String}] the valid id and name
|
292
|
+
#
|
347
293
|
def check_member(m)
|
348
294
|
potential_members = self.class::MEMBER_CLASS.map_all_ids_to(:name, api: @api)
|
349
295
|
if m.to_s =~ /^\d+$/
|
350
|
-
return {:
|
296
|
+
return { id: m.to_i, name: potential_members[m] } if potential_members.key?(m.to_i)
|
351
297
|
else
|
352
|
-
return {:
|
298
|
+
return { name: m, id: potential_members.invert[m] } if potential_members.value?(m)
|
353
299
|
end
|
354
300
|
raise JSS::NoSuchItemError, "No #{self.class::MEMBER_CLASS::RSRC_OBJECT_KEY} matching '#{m}' in the JSS."
|
355
301
|
end
|
356
302
|
|
357
|
-
|
358
|
-
|
359
|
-
###
|
303
|
+
# the xml formated data for adding or updating this in the JSS,
|
304
|
+
#
|
360
305
|
def rest_xml
|
361
306
|
doc = REXML::Document.new JSS::APIConnection::XML_HEADER
|
362
307
|
group = doc.add_element self.class::RSRC_OBJECT_KEY.to_s
|
@@ -370,14 +315,13 @@ module JSS
|
|
370
315
|
|
371
316
|
add_site_to_xml(doc)
|
372
317
|
|
373
|
-
|
374
|
-
|
375
|
-
end #rest_xml
|
318
|
+
doc.to_s
|
319
|
+
end # rest_xml
|
376
320
|
|
377
321
|
end # class ComputerGroup
|
378
322
|
|
379
323
|
end # module JSS
|
380
324
|
|
381
|
-
require
|
382
|
-
require
|
383
|
-
require
|
325
|
+
require 'jss/api_object/group/computer_group'
|
326
|
+
require 'jss/api_object/group/mobile_device_group'
|
327
|
+
require 'jss/api_object/group/user_group'
|