ruby-jss 0.14.0 → 1.0.0b2
Sign up to get free protection for your applications and to get access to all the features.
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'
|