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
@@ -26,13 +26,30 @@
|
|
26
26
|
###
|
27
27
|
module JSS
|
28
28
|
|
29
|
-
#
|
30
|
-
#
|
29
|
+
# An 'Internal' patch source. These sources are defined by
|
30
|
+
# Jamf themselves, as a part of the JSS, and cannot be created, modified
|
31
|
+
# or deleted.
|
31
32
|
#
|
32
33
|
# @see JSS::APIObject
|
33
34
|
#
|
34
|
-
class
|
35
|
+
class PatchInternalSource < JSS::PatchSource
|
35
36
|
|
36
|
-
|
37
|
+
# Constants
|
38
|
+
#####################################
|
39
|
+
|
40
|
+
### The base for REST resources of this class
|
41
|
+
RSRC_BASE = 'patchinternalsources'.freeze
|
42
|
+
|
43
|
+
### the hash key used for the JSON list output of all objects in the JSS
|
44
|
+
RSRC_LIST_KEY = :patch_internal_sources
|
45
|
+
|
46
|
+
# The hash key used for the JSON object output.
|
47
|
+
# It's also used in various error messages
|
48
|
+
RSRC_OBJECT_KEY = :patch_internal_source
|
49
|
+
|
50
|
+
### these keys, as well as :id and :name, are present in valid API JSON data for this class
|
51
|
+
VALID_DATA_KEYS = %i[enabled endpoint].freeze
|
52
|
+
|
53
|
+
end # class PatchInternalSource
|
37
54
|
|
38
55
|
end # module JSS
|
@@ -0,0 +1,480 @@
|
|
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
|
+
###
|
25
|
+
|
26
|
+
###
|
27
|
+
module JSS
|
28
|
+
|
29
|
+
# An active Patch Software Title in the JSS.
|
30
|
+
#
|
31
|
+
# This class provides access to titles that have been added to Jamf Pro
|
32
|
+
# via a PatchInternalSource or a PatchExternalSource, and the versions
|
33
|
+
# contained therein.
|
34
|
+
#
|
35
|
+
# Patch versions for the title are available in the #versions read-only
|
36
|
+
# attribute, a Hash of versions keyed by the version string. The values are
|
37
|
+
# JSS::PatchTitle::Version objects.
|
38
|
+
#
|
39
|
+
# Use the patch_report method on the PatchTitle class, an instance of it, or
|
40
|
+
# a PatchTitle::Version, to retrieve a report of computers with a
|
41
|
+
# specific version of the title installed, or :all, :latest, or :unknown
|
42
|
+
# versions. Reports called on the class or an instance default to :all
|
43
|
+
# versions, and are slower to retrieve than a specific version,
|
44
|
+
#
|
45
|
+
# @see JSS::APIObject
|
46
|
+
#
|
47
|
+
class PatchTitle < JSS::APIObject
|
48
|
+
|
49
|
+
include JSS::Sitable
|
50
|
+
include JSS::Categorizable
|
51
|
+
include JSS::Creatable
|
52
|
+
include JSS::Updatable
|
53
|
+
|
54
|
+
# TODO: remove this and adjust parsing when jamf fixes the JSON
|
55
|
+
# Data map for PatchTitle XML data parsing cuz Borked JSON
|
56
|
+
# @see {JSS::XMLWorkaround} for details
|
57
|
+
USE_XML_WORKAROUND = {
|
58
|
+
patch_software_title: {
|
59
|
+
id: -1,
|
60
|
+
name: JSS::BLANK,
|
61
|
+
name_id: JSS::BLANK,
|
62
|
+
source_id: -1,
|
63
|
+
notifications: {
|
64
|
+
email_notification: nil,
|
65
|
+
web_notification: nil
|
66
|
+
},
|
67
|
+
category: {
|
68
|
+
id: -1,
|
69
|
+
name: JSS::BLANK
|
70
|
+
},
|
71
|
+
site: {
|
72
|
+
id: -1,
|
73
|
+
name: JSS::BLANK
|
74
|
+
},
|
75
|
+
versions: [
|
76
|
+
{
|
77
|
+
software_version: JSS::BLANK,
|
78
|
+
package: {
|
79
|
+
id: -1,
|
80
|
+
name: JSS::BLANK
|
81
|
+
}
|
82
|
+
}
|
83
|
+
]
|
84
|
+
}
|
85
|
+
}.freeze
|
86
|
+
|
87
|
+
# TODO: remove this and adjust parsing when jamf fixes the JSON
|
88
|
+
# Data map for PatchReport XML data parsing cuz Borked JSON
|
89
|
+
# @see {JSS::XMLWorkaround} for details
|
90
|
+
PATCH_REPORT_DATA_MAP = {
|
91
|
+
patch_report: {
|
92
|
+
name: JSS::BLANK,
|
93
|
+
patch_software_title_id: -1,
|
94
|
+
total_computers: 0,
|
95
|
+
total_versions: 0,
|
96
|
+
versions: [
|
97
|
+
{
|
98
|
+
software_version: JSS::BLANK,
|
99
|
+
computers: [
|
100
|
+
{
|
101
|
+
id: -1,
|
102
|
+
name: JSS::BLANK,
|
103
|
+
mac_address: JSS::BLANK,
|
104
|
+
alt_mac_address: JSS::BLANK,
|
105
|
+
serial_number: JSS::BLANK
|
106
|
+
}
|
107
|
+
]
|
108
|
+
}
|
109
|
+
]
|
110
|
+
}
|
111
|
+
}.freeze
|
112
|
+
|
113
|
+
### The base for REST resources of this class
|
114
|
+
RSRC_BASE = 'patchsoftwaretitles'.freeze
|
115
|
+
|
116
|
+
### the hash key used for the JSON list output of all objects in the JSS
|
117
|
+
RSRC_LIST_KEY = :patch_software_titles
|
118
|
+
|
119
|
+
# The hash key used for the JSON object output.
|
120
|
+
# It's also used in various error messages
|
121
|
+
RSRC_OBJECT_KEY = :patch_software_title
|
122
|
+
|
123
|
+
### these keys, as well as :id and :name, are present in valid API JSON data for this class
|
124
|
+
VALID_DATA_KEYS = %i[notifications name_id source_id].freeze
|
125
|
+
|
126
|
+
# the object type for this object in
|
127
|
+
# the object history table.
|
128
|
+
# See {APIObject#add_object_history_entry}
|
129
|
+
# TODO: comfirm this in 10.4
|
130
|
+
OBJECT_HISTORY_OBJECT_TYPE = 604
|
131
|
+
|
132
|
+
SITE_SUBSET = :top
|
133
|
+
|
134
|
+
# Where is the Category in the API JSON?
|
135
|
+
CATEGORY_SUBSET = :top
|
136
|
+
|
137
|
+
# How is the category stored in the API data?
|
138
|
+
CATEGORY_DATA_TYPE = Hash
|
139
|
+
|
140
|
+
# when fetching a specific version, this is a valid version
|
141
|
+
LATEST_VERSION_ID = 'Latest'.freeze
|
142
|
+
|
143
|
+
# when fetching a specific version, this is a valid version
|
144
|
+
UNKNOWN_VERSION_ID = 'Unknown'.freeze
|
145
|
+
|
146
|
+
REPORTS_RSRC_BASE = '/patchreports/patchsoftwaretitleid'.freeze
|
147
|
+
|
148
|
+
# Class Methods
|
149
|
+
#######################################
|
150
|
+
|
151
|
+
# The same as @see APIObject.all but also takes an optional
|
152
|
+
# source_id: parameter, which limites the results to
|
153
|
+
# patch titles with the specified source_id.
|
154
|
+
#
|
155
|
+
# ALSO, JAMF BUG: More broken json - the id is coming as a string.
|
156
|
+
# so here we turn it into an integer manually :-(
|
157
|
+
# Ditto for source_id
|
158
|
+
#
|
159
|
+
def self.all(refresh = false, source_id: nil, api: JSS.api)
|
160
|
+
data = super refresh, api: api
|
161
|
+
data.each do |info|
|
162
|
+
info[:id] = info[:id].to_i
|
163
|
+
info[:source_id] = info[:source_id].to_i
|
164
|
+
end
|
165
|
+
return data unless source_id
|
166
|
+
data.select { |p| p[:source_id] == source_id }
|
167
|
+
end
|
168
|
+
|
169
|
+
# The same as @see APIObject.all_names but also takes an optional
|
170
|
+
# source_id: parameter, which limites the results to
|
171
|
+
# patch titles with the specified source_id.
|
172
|
+
#
|
173
|
+
def self.all_names(refresh = false, source_id: nil, api: JSS.api)
|
174
|
+
all(refresh, source_id: source_id, api: api).map { |i| i[:name] }
|
175
|
+
end
|
176
|
+
|
177
|
+
# The same as @see APIObject.all_ids but also takes an optional
|
178
|
+
# source_id: parameter, which limites the results to
|
179
|
+
# patch titles with the specified source_id.
|
180
|
+
#
|
181
|
+
def self.all_ids(refresh = false, source_id: nil, api: JSS.api)
|
182
|
+
all(refresh, source_id: source_id, api: api).map { |i| i[:id] }
|
183
|
+
end
|
184
|
+
|
185
|
+
# @return [Array<String>] all 'name_id' values for active patches
|
186
|
+
#
|
187
|
+
def self.all_name_ids(refresh = false, source_id: nil, api: JSS.api)
|
188
|
+
all(refresh, source_id: source_id, api: api).map { |i| i[:name_id] }
|
189
|
+
end
|
190
|
+
|
191
|
+
# Returns an Array of unique source_ids used by active Patches
|
192
|
+
#
|
193
|
+
# e.g. if there are patches that come from one internal source
|
194
|
+
# and two external sources this might return [1,3,4].
|
195
|
+
#
|
196
|
+
# Regardless of how many patches come from each source, the
|
197
|
+
# source id appears only once in this array.
|
198
|
+
#
|
199
|
+
# @param refresh[Boolean] should the data be re-queried from the API?
|
200
|
+
#
|
201
|
+
# @param api[JSS::APIConnection] an API connection to use for the query.
|
202
|
+
# Defaults to the corrently active API. See {JSS::APIConnection}
|
203
|
+
#
|
204
|
+
# @return [Array<Integer>] the ids of the patch sources used in the JSS
|
205
|
+
#
|
206
|
+
def self.all_source_ids(refresh = false, api: JSS.api)
|
207
|
+
all(refresh, api: api).map { |i| i[:source_id] }.sort.uniq
|
208
|
+
end
|
209
|
+
|
210
|
+
# Get a patch report for a softwaretitle, withouth fetching an instance.
|
211
|
+
# Defaults to reporting all versions. Specifiying a version will be faster.
|
212
|
+
#
|
213
|
+
# The Hash returned has 3 keys:
|
214
|
+
# - :total_comptuters [Integer] total computers found for the requested version(s)
|
215
|
+
# - :total versions [Integer] How many versions does this title have?
|
216
|
+
# Always 1 if you report a specific version
|
217
|
+
# - :versions [Hash {String => Array<Hash>}] Keys are the version(s) requested
|
218
|
+
# values are Arrays of Hashes, one per computer with the keyed version
|
219
|
+
# installed. Computer Hashes have identifiers as keys.
|
220
|
+
#
|
221
|
+
# PatchTitle#patch_report calls this method, as does
|
222
|
+
# PatchTitle::Version.patch_report.
|
223
|
+
#
|
224
|
+
# @param title[Integer, String] The name or id of the software title to
|
225
|
+
# report.
|
226
|
+
#
|
227
|
+
# @param version[String,Symbol] Limit the report to this version.
|
228
|
+
# Can be a string version number like '8.13.2' or :latest, :unknown,
|
229
|
+
# or :all. Defaults to :all
|
230
|
+
#
|
231
|
+
# @param api[JSS::APIConnection] an API connection to use for the query.
|
232
|
+
# Defaults to the corrently active API. See {JSS::APIConnection}
|
233
|
+
#
|
234
|
+
# @return [Hash] the patch report for the version(s) specified.
|
235
|
+
#
|
236
|
+
def self.patch_report(title, version: :all, api: JSS.api)
|
237
|
+
title_id = valid_id title, api: api
|
238
|
+
raise JSS::NoSuchItemError, "No PatchTitle matches '#{title}'" unless title_id
|
239
|
+
|
240
|
+
rsrc = patch_report_rsrc title_id, version
|
241
|
+
|
242
|
+
# TODO: remove this and adjust parsing when jamf fixes the JSON
|
243
|
+
raw_report = XMLWorkaround.data_via_xml(rsrc, PATCH_REPORT_DATA_MAP, api)[:patch_report]
|
244
|
+
report = {}
|
245
|
+
report[:total_computers] = raw_report[:total_computers]
|
246
|
+
report[:total_versions] = raw_report[:total_versions]
|
247
|
+
|
248
|
+
if raw_report[:versions].is_a? Hash
|
249
|
+
vs = raw_report[:versions][:version][:software_version].to_s
|
250
|
+
comps = raw_report[:versions][:version][:computers]
|
251
|
+
comps = [] if comps.empty?
|
252
|
+
report[:versions] = { vs => comps }
|
253
|
+
return report
|
254
|
+
end
|
255
|
+
|
256
|
+
report[:versions] = {}
|
257
|
+
raw_report[:versions].each do |v|
|
258
|
+
report[:versions][v[:software_version].to_s] = v[:computers].empty? ? [] : v[:computers]
|
259
|
+
end
|
260
|
+
report
|
261
|
+
end
|
262
|
+
|
263
|
+
# aliases of patch_report
|
264
|
+
singleton_class.send(:alias_method, :version_report, :patch_report)
|
265
|
+
singleton_class.send(:alias_method, :report, :patch_report)
|
266
|
+
|
267
|
+
# given a requested version, return the rest rsrc for getting
|
268
|
+
# a patch report for it.
|
269
|
+
def self.patch_report_rsrc(id, vers)
|
270
|
+
case vers
|
271
|
+
when :all
|
272
|
+
"#{REPORTS_RSRC_BASE}/#{id}"
|
273
|
+
when :latest
|
274
|
+
"#{REPORTS_RSRC_BASE}/#{id}/version/#{LATEST_VERSION_ID}"
|
275
|
+
when :unknown
|
276
|
+
"#{REPORTS_RSRC_BASE}/#{id}/version/#{UNKNOWN_VERSION_ID}"
|
277
|
+
else
|
278
|
+
"#{REPORTS_RSRC_BASE}/#{id}/version/#{vers}"
|
279
|
+
end
|
280
|
+
end
|
281
|
+
private_class_method :patch_report_rsrc
|
282
|
+
|
283
|
+
# for some reason, patch titles can't be fetched by name.
|
284
|
+
# only by id. SO, look up the id if given a name.
|
285
|
+
#
|
286
|
+
def self.fetch(id: nil, name: nil, api: JSS.api)
|
287
|
+
unless id
|
288
|
+
id = JSS::PatchTitle.map_all_ids_to(:name).invert[name]
|
289
|
+
raise NoSuchItemError, "No matching #{self::RSRC_OBJECT_KEY} found" unless id
|
290
|
+
end
|
291
|
+
|
292
|
+
super id: id, api: api
|
293
|
+
end
|
294
|
+
|
295
|
+
# Attributes
|
296
|
+
#####################################
|
297
|
+
|
298
|
+
# @return [String] the 'name_id' for this patch title. name_id is a unique
|
299
|
+
# identfier provided by the patch source
|
300
|
+
attr_reader :name_id
|
301
|
+
|
302
|
+
# @return [Integer] the id of the patch source from which we get patches
|
303
|
+
# for this title
|
304
|
+
attr_reader :source_id
|
305
|
+
|
306
|
+
# @return [Boolean] Are new patches announced in the JSS web ui?
|
307
|
+
attr_reader :web_notification
|
308
|
+
alias web_notification? web_notification
|
309
|
+
|
310
|
+
# @return [Boolean] Are new patches announced by email?
|
311
|
+
attr_reader :email_notification
|
312
|
+
alias email_notification? email_notification
|
313
|
+
|
314
|
+
# @return [Hash{String => JSS::PatchTitle::Version}] The JSS::PatchVersions fetched for
|
315
|
+
# this title, keyed by version string
|
316
|
+
attr_reader :versions
|
317
|
+
|
318
|
+
# PatchTitles may be fetched by name: or id:
|
319
|
+
#
|
320
|
+
def initialize(**args)
|
321
|
+
super
|
322
|
+
|
323
|
+
@name_id = @init_data[:name_id]
|
324
|
+
@source_id = @init_data[:source_id]
|
325
|
+
|
326
|
+
@init_data[:notifications] ||= {}
|
327
|
+
notifs = @init_data[:notifications]
|
328
|
+
@web_notification = notifs[:web_notification].nil? ? false : notifs[:web_notification]
|
329
|
+
@email_notification = notifs[:email_notification].nil? ? false : notifs[:email_notification]
|
330
|
+
|
331
|
+
@versions = {}
|
332
|
+
@init_data[:versions] ||= []
|
333
|
+
@init_data[:versions].each do |vers|
|
334
|
+
@versions[vers[:software_version]] = JSS::PatchTitle::Version.new(self, vers)
|
335
|
+
end # each do vers
|
336
|
+
|
337
|
+
@changed_pkgs = []
|
338
|
+
end
|
339
|
+
|
340
|
+
# @return [Hash] Subset of @versions, containing those which have packages
|
341
|
+
# assigned
|
342
|
+
#
|
343
|
+
def versions_with_packages
|
344
|
+
versions.select { |_ver_string, vers| vers.package_assigned? }
|
345
|
+
end
|
346
|
+
|
347
|
+
# Set email notifications on or off
|
348
|
+
#
|
349
|
+
# @param new_setting[Boolean] Should email notifications be on or off?
|
350
|
+
#
|
351
|
+
# @return [void]
|
352
|
+
#
|
353
|
+
def email_notification=(new_setting)
|
354
|
+
return if email_notification == new_setting
|
355
|
+
raise JSS::InvalidDataError, 'New Setting must be boolean true or false' unless JSS::TRUE_FALSE.include? @email_notification = new_setting
|
356
|
+
@need_to_update = true
|
357
|
+
end
|
358
|
+
|
359
|
+
# Set web notifications on or off
|
360
|
+
#
|
361
|
+
# @param new_setting[Boolean] Should email notifications be on or off?
|
362
|
+
#
|
363
|
+
# @return [void]
|
364
|
+
#
|
365
|
+
def web_notification=(new_setting)
|
366
|
+
return if web_notification == new_setting
|
367
|
+
raise JSS::InvalidDataError, 'New Setting must be boolean true or false' unless JSS::TRUE_FALSE.include? @web_notification = new_setting
|
368
|
+
@need_to_update = true
|
369
|
+
end
|
370
|
+
|
371
|
+
# this is called by JSS::PatchTitle::Version#package= to update @changed_pkgs which
|
372
|
+
# is used by #rest_xml to change the package assigned to a patch version
|
373
|
+
# in this title.
|
374
|
+
def changed_pkg_for_version(version)
|
375
|
+
@changed_pkgs << version
|
376
|
+
@need_to_update = true
|
377
|
+
end
|
378
|
+
|
379
|
+
def source_id=(new_id)
|
380
|
+
sid = JSS::PatchSource.valid_patch_source_id new_id
|
381
|
+
raise JSS::NoSuchItemError, "No active Patch Sources matche '#{new_id}'" unless sid
|
382
|
+
return if sid == source_id
|
383
|
+
@source_id = sid
|
384
|
+
@need_to_update = true
|
385
|
+
end
|
386
|
+
|
387
|
+
def name_id=(new_id)
|
388
|
+
return if new_id == name_id
|
389
|
+
raise JSS::MissingDataError, 'source_id must be set before setting name_id' if source_id.to_s.empty?
|
390
|
+
raise JSS::NoSuchItemError, "source_id #{source_id} doesn't offer name_id '#{new_id}'" unless JSS::PatchSource.available_name_ids(source_id).include? new_id
|
391
|
+
@name_id = new_id
|
392
|
+
@need_to_update = true
|
393
|
+
end
|
394
|
+
|
395
|
+
# wrapper to fetch versions after creating
|
396
|
+
def create
|
397
|
+
validate_for_saving
|
398
|
+
response = super
|
399
|
+
@versions = self.class.fetch(id: id).versions
|
400
|
+
response
|
401
|
+
end
|
402
|
+
|
403
|
+
# wrapper to clear @changed_pkgs after updating
|
404
|
+
def update
|
405
|
+
validate_for_saving
|
406
|
+
response = super
|
407
|
+
@changed_pkgs.clear
|
408
|
+
response
|
409
|
+
end
|
410
|
+
|
411
|
+
# Get a patch report for this title.
|
412
|
+
#
|
413
|
+
# See the class method JSS::PatchTitle.patch_report
|
414
|
+
#
|
415
|
+
def patch_report(vers = :all)
|
416
|
+
JSS::PatchTitle.patch_report id, version: vers, api: @api
|
417
|
+
end
|
418
|
+
alias version_report patch_report
|
419
|
+
alias report patch_report
|
420
|
+
|
421
|
+
# Remove the various cached data
|
422
|
+
# from the instance_variables used to create
|
423
|
+
# pretty-print (pp) output.
|
424
|
+
#
|
425
|
+
# @return [Array] the desired instance_variables
|
426
|
+
#
|
427
|
+
def pretty_print_instance_variables
|
428
|
+
vars = super
|
429
|
+
vars.delete :@versions
|
430
|
+
vars
|
431
|
+
end
|
432
|
+
|
433
|
+
#################################
|
434
|
+
private
|
435
|
+
|
436
|
+
def validate_for_saving
|
437
|
+
raise JSS::MissingDataError, 'PatchTitles must have valid source_id and name_id' if source_id.to_s.empty? || name_id.to_s.empty?
|
438
|
+
end
|
439
|
+
|
440
|
+
# Return the REST XML for this title, with the current values,
|
441
|
+
# for saving or updating.
|
442
|
+
#
|
443
|
+
def rest_xml
|
444
|
+
doc = REXML::Document.new # JSS::APIConnection::XML_HEADER
|
445
|
+
obj = doc.add_element RSRC_OBJECT_KEY.to_s
|
446
|
+
|
447
|
+
obj.add_element('name').text = name
|
448
|
+
obj.add_element('name_id').text = name_id
|
449
|
+
obj.add_element('source_id').text = source_id
|
450
|
+
|
451
|
+
notifs = obj.add_element 'notifications'
|
452
|
+
notifs.add_element('web_notification').text = web_notification?.to_s
|
453
|
+
notifs.add_element('email_notification').text = email_notification?.to_s
|
454
|
+
|
455
|
+
add_changed_pkg_xml obj unless @changed_pkgs.empty?
|
456
|
+
|
457
|
+
add_category_to_xml doc
|
458
|
+
add_site_to_xml doc
|
459
|
+
|
460
|
+
doc.to_s
|
461
|
+
end # rest_xml
|
462
|
+
|
463
|
+
# add xml for any package changes to patch versions
|
464
|
+
def add_changed_pkg_xml(obj)
|
465
|
+
versions_elem = obj.add_element 'versions'
|
466
|
+
@changed_pkgs.each do |vers|
|
467
|
+
velem = versions_elem.add_element 'version'
|
468
|
+
velem.add_element('software_version').text = vers.to_s
|
469
|
+
pkg = velem.add_element 'package'
|
470
|
+
# leave am empty package element to remove the pkg assignement
|
471
|
+
next if versions[vers].package_id == :none
|
472
|
+
pkg.add_element('id').text = versions[vers].package_id.to_s
|
473
|
+
end # do vers
|
474
|
+
end
|
475
|
+
|
476
|
+
end # class Patch
|
477
|
+
|
478
|
+
end # module JSS
|
479
|
+
|
480
|
+
require 'jss/api_object/patch_title/version'
|