jss-api 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/lib/jss-api.rb +1 -191
  2. metadata +16 -146
  3. data/.yardopts +0 -7
  4. data/CHANGES.md +0 -88
  5. data/LICENSE.txt +0 -174
  6. data/README.md +0 -396
  7. data/THANKS.md +0 -6
  8. data/bin/cgrouper +0 -485
  9. data/bin/subnet-update +0 -400
  10. data/lib/jss-api/api_connection.rb +0 -400
  11. data/lib/jss-api/api_object.rb +0 -616
  12. data/lib/jss-api/api_object/advanced_search.rb +0 -389
  13. data/lib/jss-api/api_object/advanced_search/advanced_computer_search.rb +0 -95
  14. data/lib/jss-api/api_object/advanced_search/advanced_mobile_device_search.rb +0 -96
  15. data/lib/jss-api/api_object/advanced_search/advanced_user_search.rb +0 -95
  16. data/lib/jss-api/api_object/building.rb +0 -92
  17. data/lib/jss-api/api_object/category.rb +0 -147
  18. data/lib/jss-api/api_object/computer.rb +0 -852
  19. data/lib/jss-api/api_object/creatable.rb +0 -98
  20. data/lib/jss-api/api_object/criteriable.rb +0 -189
  21. data/lib/jss-api/api_object/criteriable/criteria.rb +0 -231
  22. data/lib/jss-api/api_object/criteriable/criterion.rb +0 -228
  23. data/lib/jss-api/api_object/department.rb +0 -93
  24. data/lib/jss-api/api_object/distribution_point.rb +0 -560
  25. data/lib/jss-api/api_object/extendable.rb +0 -221
  26. data/lib/jss-api/api_object/extension_attribute.rb +0 -457
  27. data/lib/jss-api/api_object/extension_attribute/computer_extension_attribute.rb +0 -362
  28. data/lib/jss-api/api_object/extension_attribute/mobile_device_extension_attribute.rb +0 -189
  29. data/lib/jss-api/api_object/extension_attribute/user_extension_attribute.rb +0 -117
  30. data/lib/jss-api/api_object/group.rb +0 -380
  31. data/lib/jss-api/api_object/group/computer_group.rb +0 -124
  32. data/lib/jss-api/api_object/group/mobile_device_group.rb +0 -139
  33. data/lib/jss-api/api_object/group/user_group.rb +0 -139
  34. data/lib/jss-api/api_object/ldap_server.rb +0 -535
  35. data/lib/jss-api/api_object/locatable.rb +0 -286
  36. data/lib/jss-api/api_object/matchable.rb +0 -97
  37. data/lib/jss-api/api_object/mobile_device.rb +0 -556
  38. data/lib/jss-api/api_object/netboot_server.rb +0 -148
  39. data/lib/jss-api/api_object/network_segment.rb +0 -414
  40. data/lib/jss-api/api_object/osx_configuration_profile.rb +0 -261
  41. data/lib/jss-api/api_object/package.rb +0 -812
  42. data/lib/jss-api/api_object/peripheral.rb +0 -335
  43. data/lib/jss-api/api_object/peripheral_type.rb +0 -295
  44. data/lib/jss-api/api_object/policy.rb +0 -898
  45. data/lib/jss-api/api_object/purchasable.rb +0 -316
  46. data/lib/jss-api/api_object/removable_macaddr.rb +0 -98
  47. data/lib/jss-api/api_object/scopable.rb +0 -136
  48. data/lib/jss-api/api_object/scopable/scope.rb +0 -621
  49. data/lib/jss-api/api_object/script.rb +0 -631
  50. data/lib/jss-api/api_object/self_servable.rb +0 -355
  51. data/lib/jss-api/api_object/site.rb +0 -93
  52. data/lib/jss-api/api_object/software_update_server.rb +0 -109
  53. data/lib/jss-api/api_object/updatable.rb +0 -117
  54. data/lib/jss-api/api_object/uploadable.rb +0 -138
  55. data/lib/jss-api/api_object/user.rb +0 -272
  56. data/lib/jss-api/client.rb +0 -504
  57. data/lib/jss-api/compatibility.rb +0 -66
  58. data/lib/jss-api/composer.rb +0 -171
  59. data/lib/jss-api/configuration.rb +0 -306
  60. data/lib/jss-api/db_connection.rb +0 -298
  61. data/lib/jss-api/exceptions.rb +0 -95
  62. data/lib/jss-api/ruby_extensions.rb +0 -35
  63. data/lib/jss-api/ruby_extensions/filetest.rb +0 -43
  64. data/lib/jss-api/ruby_extensions/hash.rb +0 -79
  65. data/lib/jss-api/ruby_extensions/ipaddr.rb +0 -91
  66. data/lib/jss-api/ruby_extensions/pathname.rb +0 -77
  67. data/lib/jss-api/ruby_extensions/string.rb +0 -59
  68. data/lib/jss-api/ruby_extensions/time.rb +0 -63
  69. data/lib/jss-api/server.rb +0 -108
  70. data/lib/jss-api/utility.rb +0 -416
  71. data/lib/jss-api/version.rb +0 -31
@@ -1,616 +0,0 @@
1
- ### Copyright 2016 Pixar
2
- ###
3
- ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
- ### with the following modification; you may not use this file except in
5
- ### compliance with the Apache License and the following modification to it:
6
- ### Section 6. Trademarks. is deleted and replaced with:
7
- ###
8
- ### 6. Trademarks. This License does not grant permission to use the trade
9
- ### names, trademarks, service marks, or product names of the Licensor
10
- ### and its affiliates, except as required to comply with Section 4(c) of
11
- ### the License and to reproduce the content of the NOTICE file.
12
- ###
13
- ### You may obtain a copy of the Apache License at
14
- ###
15
- ### http://www.apache.org/licenses/LICENSE-2.0
16
- ###
17
- ### Unless required by applicable law or agreed to in writing, software
18
- ### distributed under the Apache License with the above modification is
19
- ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
- ### KIND, either express or implied. See the Apache License for the specific
21
- ### language governing permissions and limitations under the Apache License.
22
- ###
23
- ###
24
-
25
- ###
26
- module JSS
27
-
28
- #####################################
29
- ### Module Variables
30
- #####################################
31
-
32
- #####################################
33
- ### Module Methods
34
- #####################################
35
-
36
- #####################################
37
- ### Classes
38
- #####################################
39
-
40
- ###
41
- ### This class is the parent to all JSS API objects. It provides standard methods and structures
42
- ### that apply to all API resouces.
43
- ###
44
- ### See the README.md file for general info about using subclasses of JSS::APIObject
45
- ###
46
- ### == Subclassing
47
- ###
48
- ### === Constructor
49
- ###
50
- ### In general, subclasses should do any class-specific argument checking before
51
- ### calling super, and then afterwards, use the contents of @init_data to populate
52
- ### any class-specific attributes. @id, @name, @rest_rsrc, and @in_jss are handled here.
53
- ###
54
- ### If a subclass can be looked up by some key other than :name or :id, the subclass must
55
- ### pass the keys as an Array in the second argument when calling super from #initialize.
56
- ### See {JSS::Computer#initialize} for an example of how to implement this feature.
57
- ###
58
- ### === Object Creation
59
- ###
60
- ### If a subclass should be able to be created in the JSS be sure to include {JSS::Creatable}
61
- ###
62
- ### The constructor should verify any extra required data (aside from :name) in the args before or after
63
- ### calling super.
64
- ###
65
- ### See {JSS::Creatable} for more details.
66
- ###
67
- ### === Object Modification
68
- ###
69
- ### If a subclass should be modifiable in the JSS, include {JSS::Updatable}, q.v. for details.
70
- ###
71
- ### === Object Deletion
72
- ###
73
- ### All subclasses can be deleted in the JSS.
74
- ###
75
- ### === Required Constants
76
- ###
77
- ### Subclasses *must* provide certain Constants in order to correctly interpret API data and
78
- ### communicate with the API.
79
- ###
80
- ### ==== RSRC_BASE = [String], The base for REST resources of this class
81
- ###
82
- ### e.g. 'computergroups' in "https://casper.mycompany.com:8443/JSSResource/computergroups/id/12"
83
- ###
84
- ### ==== RSRC_LIST_KEY = [Symbol] The Hash key for the JSON list output of all objects of this class in the JSS.
85
- ###
86
- ### e.g. the JSON output of resource "JSSResource/computergroups" is a hash
87
- ### with one item (an Array of computergroups). That item's key is the Symbol :computer_groups
88
- ###
89
- ### ==== RSRC_OBJECT_KEY = [Symbol] The Hash key used for individual JSON object output.
90
- ### It's also used in various error messages
91
- ###
92
- ### e.g. the JSON output of the resource "JSSResource/computergroups/id/436" is
93
- ### a hash with one item (another hash with details of one computergroup).
94
- ### That item's key is the Symbol :computer_group
95
- ###
96
- ### ==== VALID_DATA_KEYS = [Array<Symbol>] The Hash keys used to verify validity of :data
97
- ### When instantiating a subclass using :data => somehash, some minimal checks are performed
98
- ### to ensure the data is valid for the subclass
99
- ###
100
- ### The Symbols in this Array are compared to the keys of the hash provided.
101
- ### If any of these don't exist in the hash's keys, then the :data is
102
- ### not valid and an exception is raised.
103
- ###
104
- ### The keys :id and :name must always exist in the hash.
105
- ### If only :id and :name are valid, VALID_DATA_KEYS should be an empty array.
106
- ###
107
- ### e.g. for a department, only :id and :name are valid, so VALID_DATA_KEYS is an empty Array ([])
108
- ### but for a computer group, the keys :computers and :is_smart must be present as well.
109
- ### so VALID_DATA_KEYS will be [:computers, :is_smart]
110
- ###
111
- ### *NOTE* Some API objects have data broken into subsections, in which case the
112
- ### VALID_DATA_KEYS are expected in the section :general.
113
- ###
114
- class APIObject
115
-
116
- #####################################
117
- ### Mix-Ins
118
- #####################################
119
-
120
- #####################################
121
- ### Class Variables
122
- #####################################
123
-
124
- ### This Hash holds the most recent API query for a list of all items in any subclass,
125
- ### keyed by the subclass's RSRC_LIST_KEY. See the self.all class method.
126
- ###
127
- ### When the .all method is called without an argument, and this hash has
128
- ### a matching value, the value is returned, rather than requerying the
129
- ### API. The first time a class calls .all, or whnever refresh is
130
- ### not false, the API is queried and the value in this hash is updated.
131
- ###
132
- @@all_items = {}
133
-
134
- #####################################
135
- ### Class Methods
136
- #####################################
137
-
138
- ###
139
- ### Return an Array of Hashes for all objects of this subclass in the JSS.
140
- ###
141
- ### This method is only valid in subclasses of JSS::APIObject, and is
142
- ### the parsed JSON output of an API query for the resource defined in the subclass's RSRC_BASE,
143
- ### e.g. for JSS::Computer, with the RSRC_BASE of :computers,
144
- ### This method retuens the output of the 'JSSResource/computers' resource,
145
- ### which is a list of all computers in the JSS.
146
- ###
147
- ### Each item in the Array is a Hash with at least two keys, :id and :name.
148
- ### The class methods .all_ids and .all_names provide easier access to those data
149
- ### as mapped Arrays.
150
- ###
151
- ### Some API classes provide other data in each Hash, e.g. :udid (for computers
152
- ### and mobile devices) or :is_smart (for groups).
153
- ###
154
- ### Subclasses implementing those API classes should provide .all_xxx
155
- ### class methods for accessing those other values as mapped Arrays,
156
- ### e.g. JSS::Computer.all_udids
157
- ###
158
- ### The results of the first query for each subclass is stored in @@all_items
159
- ### and returned at every future call, so as to not requery the server every time.
160
- ###
161
- ### To force requerying to get updated data, provided a non-false argument.
162
- ### I usually use :refresh, so that it's obvious what I'm doing, but true, 1,
163
- ### or anything besides false or nil will work.
164
- ###
165
- ### @param refresh[Boolean] should the data be re-queried from the API?
166
- ###
167
- ### @return [Array<Hash{:name=>String, :id=> Integer}>]
168
- ###
169
- def self.all(refresh = false)
170
- raise JSS::UnsupportedError, ".all can only be called on subclasses of JSS::APIObject" if self == JSS::APIObject
171
- @@all_items[self::RSRC_LIST_KEY] = nil if refresh
172
- return @@all_items[self::RSRC_LIST_KEY] if @@all_items[self::RSRC_LIST_KEY]
173
- @@all_items[self::RSRC_LIST_KEY] = JSS::API.get_rsrc(self::RSRC_BASE)[self::RSRC_LIST_KEY]
174
- end
175
-
176
- ###
177
- ### Returns an Array of the JSS id numbers of all the members
178
- ### of the subclass.
179
- ###
180
- ### e.g. When called from subclass JSS::Computer,
181
- ### returns the id's of all computers in the JSS
182
- ###
183
- ### @param refresh[Boolean] should the data be re-queried from the API?
184
- ###
185
- ### @return [Array<Integer>] the ids of all items of this subclass in the JSS
186
- ###
187
- def self.all_ids(refresh = false)
188
- self.all(refresh).map{|i| i[:id]}
189
- end
190
-
191
- ###
192
- ### Returns an Array of the JSS names of all the members
193
- ### of the subclass.
194
- ###
195
- ### e.g. When called from subclass JSS::Computer,
196
- ### returns the names of all computers in the JSS
197
- ###
198
- ### @param refresh[Boolean] should the data be re-queried from the API?
199
- ###
200
- ### @return [Array<String>] the names of all item of this subclass in the JSS
201
- ###
202
- def self.all_names(refresh = false)
203
- self.all(refresh).map{|i| i[:name]}
204
- end
205
-
206
- ###
207
- ### Return a hash of all objects of this subclass
208
- ### in the JSS where the key is the id, and the value
209
- ### is some other key in the data items returned by the JSS::APIObject.all.
210
- ###
211
- ### If the other key doesn't exist in the API
212
- ### data, (eg :udid for JSS::Department) the values will be nil.
213
- ###
214
- ### Use this method to map ID numbers to other identifiers returned
215
- ### by the API list resources. Invert its result to map the other
216
- ### identfier to ids.
217
- ###
218
- ### @example
219
- ### JSS::Computer.map_all_ids_to(:name)
220
- ###
221
- ### # Returns, eg {2 => "kimchi", 5 => "mantis"}
222
- ###
223
- ### JSS::Computer.map_all_ids_to(:name).invert
224
- ###
225
- ### # Returns, eg {"kimchi" => 2, "mantis" => 5}
226
- ###
227
- ### @param other_key[Symbol] the other data key with which to associate each id
228
- ###
229
- ### @param refresh[Boolean] should the data re-queried from the API?
230
- ###
231
- ### @return [Hash{Integer => Oject}] the associated ids and data
232
- ###
233
- def self.map_all_ids_to(other_key, refresh = false)
234
- h = {}
235
- self.all(refresh).each{|i| h[i[:id]] = i[other_key]}
236
- h
237
- end
238
-
239
-
240
- ### Return an Array of JSS::APIObject subclass instances
241
- ### e.g when called on JSS::Package, return all JSS::Package
242
- ### objects in the JSS.
243
- ###
244
- ### NOTE: This may be slow as it has to look up each object individually!
245
- ### use it wisely.
246
- ###
247
- ### @param refresh[Boolean] should the data re-queried from the API?
248
- ###
249
- ### @return [Hash{Integer => Object}] the objects requested
250
- def self.all_objects(refresh = false)
251
- objects_key = "#{self::RSRC_LIST_KEY}_objects".to_sym
252
- @@all_items[objects_key] = nil if refresh
253
- return @@all_items[objects_key] if @@all_items[objects_key]
254
- @@all_items[objects_key] = self.all(refresh = false).map{|o| self.new :id => o[:id]}
255
- end
256
-
257
-
258
-
259
- ###
260
- ### Convert an Array of Hashes of API object data to a
261
- ### REXML element.
262
- ###
263
- ### Given an Array of Hashes of items in the subclass
264
- ### where each Hash has at least an :id or a :name key,
265
- ### (as what comes from the .all class method)
266
- ### return a REXML <classes> element
267
- ### with one <class> element per Hash member.
268
- ###
269
- ### @example
270
- ### # for class JSS::Computer
271
- ### some_comps = [{:id=>2, :name=>"kimchi"},{:id=>5, :name=>"mantis"}]
272
- ### xml_names = JSS::Computer.xml_list some_comps
273
- ### puts xml_names # output manually formatted for clarity, xml.to_s has no newlines between elements
274
- ###
275
- ### <computers>
276
- ### <computer>
277
- ### <name>kimchi</name>
278
- ### </computer>
279
- ### <computer>
280
- ### <name>mantis</name>
281
- ### </computer>
282
- ### </computers>
283
- ###
284
- ### xml_ids = JSS::Computer.xml_list some_comps, :id
285
- ### puts xml_names # output manually formatted for clarity, xml.to_s has no newlines between elements
286
- ###
287
- ### <computers>
288
- ### <computer>
289
- ### <id>2</id>
290
- ### </computer>
291
- ### <computer>
292
- ### <id>5</id>
293
- ### </computer>
294
- ### </computers>
295
- ###
296
- ### @param array[Array<Hash{:name=>String, :id =>Integer, Symbol=>#to_s}>] the Array of subclass data to convert
297
- ###
298
- ### @param content[Symbol] the Hash key to use as the inner element for each member of the Array
299
- ###
300
- ### @return [REXML::Element] the XML element representing the data
301
- ###
302
- def self.xml_list(array, content = :name)
303
- JSS.item_list_to_rexml_list self::RSRC_LIST_KEY, self::RSRC_OBJECT_KEY, array, content
304
- end
305
-
306
- ###
307
- ### Some API objects contain references to other API objects. Usually those
308
- ### references are a Hash containing the :id and :name of the target. Sometimes,
309
- ### however the reference is just the name of the target.
310
- ###
311
- ### A Script has a property :category, which comes from the API as
312
- ### a String, the name of the category for that script. e.g. "GoodStuff"
313
- ###
314
- ### A Policy also has a property :category, but it comes from the API as a Hash
315
- ### with both the name and id, e.g. !{:id => 8, :name => "GoodStuff"}
316
- ###
317
- ### When that reference is to a single thing (like the category to which something belongs)
318
- ### APIObject subclasses usually store only the name, and use the name when
319
- ### returning data to the API.
320
- ###
321
- ### When an object references a list of related objects
322
- ### (like the computers assigned to a user) that list will be and Array of Hashes
323
- ### as above, with both the :id and :name
324
- ###
325
- ###
326
- ### This method is just a handy way to extract the name regardless of how it comes
327
- ### from the API. Most APIObject subclasses use it in their #initialize method
328
- ###
329
- ### @param a_thing[String,Array] the api data from which we're extracting the name
330
- ###
331
- ### @return [String] the name extracted from a_thing
332
- ###
333
- def self.get_name(a_thing)
334
- case a_thing
335
- when String
336
- a_thing
337
- when Hash
338
- a_thing[:name]
339
- when nil
340
- nil
341
- end
342
- end
343
-
344
- #####################################
345
- ### Class Constants
346
- #####################################
347
-
348
- ###
349
- ### These Symbols are added to VALID_DATA_KEYS for performing the
350
- ### :data validity test described above.
351
- ###
352
- REQUIRED_DATA_KEYS = [:id, :name]
353
-
354
- ###
355
- ### By default, these keys are available for object lookups
356
- ### Others can be added by subclasses using an array of them
357
- ### as the second argument to super(initialize)
358
- ### The keys must be Symbols that match the keyname in the resource url.
359
- ### e.g. :serialnumber for JSSResource/computers/serialnumber/xxxxx
360
- ###
361
- DEFAULT_LOOKUP_KEYS = [:id, :name]
362
-
363
- #####################################
364
- ### Attributes
365
- #####################################
366
-
367
- ### @return [Integer] the JSS id number
368
- attr_reader :id
369
-
370
- ### @return [String] the name
371
- attr_reader :name
372
-
373
- ### @return [Boolean] is it in the JSS?
374
- attr_reader :in_jss
375
-
376
- ### @return [String] the Rest resource for API access (the part after "JSSResource/" )
377
- attr_reader :rest_rsrc
378
-
379
- #####################################
380
- ### Constructor
381
- #####################################
382
-
383
- ###
384
- ### The args hash must include :id, :name, or :data.
385
- ### * :id or :name will be looked up via the API
386
- ### * * if the subclass includes JSS::Creatable, :id can be :new, to create a new object in the JSS.
387
- ### and :name is required
388
- ### * :data must be the JSON output of a separate {JSS::APIConnection} query (a Hash of valid object data)
389
- ###
390
- ### Some subclasses can accept other options, by pasing their keys in a final Array
391
- ###
392
- ### @param args[Hash] the data for looking up, or constructing, a new object.
393
- ###
394
- ### @option args :id[Integer] the jss id to look up
395
- ###
396
- ### @option args :name[String] the name to look up
397
- ###
398
- ### @option args :data[Hash] the JSON output of a separate {JSS::APIConnection} query
399
- ###
400
- ### @param other_lookup_keys[Array<Symbol>] Hash keys other than :id and :name, by which an API
401
- ### lookup may be performed.
402
- ###
403
- def initialize(args = {}, other_lookup_keys = [])
404
-
405
- ################################
406
- ################################
407
- ####### Previously looked-up JSON data
408
- if args[:data]
409
-
410
- @init_data = args[:data]
411
- ### Does this data come in subsets?
412
- @got_subsets = @init_data[:general].kind_of?(Hash)
413
-
414
- ### data must include all they keys in REQUIRED_DATA_KEYS + VALID_DATA_KEYS
415
- ### in either the main hash keys or the :general sub-hash, if it exists
416
- hash_to_check = @got_subsets ? @init_data[:general] : @init_data
417
- combined_valid_keys = self.class::REQUIRED_DATA_KEYS + self.class::VALID_DATA_KEYS
418
- keys_ok = (hash_to_check.keys & combined_valid_keys).count == combined_valid_keys.count
419
- raise JSS::InvalidDataError, ":data is not valid JSON for a #{self.class::RSRC_OBJECT_KEY} from the API. It needs at least the keys :#{combined_valid_keys.join ', :'}" unless keys_ok
420
-
421
- ### and the id must be in the jss
422
- raise NoSuchItemError, "No #{self.class::RSRC_OBJECT_KEY} with JSS id: #{@init_data[:id]}" unless self.class.all_ids.include? hash_to_check[:id]
423
-
424
-
425
- ################################
426
- ################################
427
- ###### Make a new one in the JSS, but only if we've included the Creatable module
428
- elsif args[:id] == :new
429
-
430
- raise JSS::UnsupportedError, "Creating #{self.class::RSRC_LIST_KEY} isn't yet supported. Please use other Casper workflows." unless defined? self.class::CREATABLE
431
-
432
- raise JSS::MissingDataError, "You must provide a :name for a new #{self.class::RSRC_OBJECT_KEY}." unless args[:name]
433
-
434
- raise JSS::AlreadyExistsError, "A #{self.class::RSRC_OBJECT_KEY} already exists with the name '#{args[:name]}'" if self.class.all_names.include? args[:name]
435
-
436
-
437
- ### NOTE: subclasses may want to pre-populate more keys in @init_data when :id == :new
438
- ### then parse them into attributes later.
439
- @name = args[:name]
440
- @init_data = {:name => args[:name]}
441
- @in_jss = false
442
- @rest_rsrc = "#{self.class::RSRC_BASE}/name/#{URI.escape @name}"
443
- @need_to_update = true
444
- return
445
-
446
- ################################
447
- ################################
448
- ###### Look up the data via the API
449
- else
450
- ### what lookup key are we using?
451
- combined_lookup_keys = self.class::DEFAULT_LOOKUP_KEYS + other_lookup_keys
452
- lookup_key = (combined_lookup_keys & args.keys)[0]
453
-
454
- raise JSS::MissingDataError, "Args must include :#{combined_lookup_keys.join(', :')}, or :data" unless lookup_key
455
-
456
- rsrc = "#{self.class::RSRC_BASE}/#{lookup_key}/#{args[lookup_key]}"
457
-
458
- begin
459
- @init_data = JSS::API.get_rsrc(rsrc)[self.class::RSRC_OBJECT_KEY]
460
-
461
- ### If we're looking up by id or name and we're here,
462
- ### then we have it regardless of which subset it's in
463
- ### otherwise, first assume they are in the init hash
464
- @id = lookup_key == :id ? args[lookup_key] : @init_data[:id]
465
- @name = lookup_key == :name ? args[lookup_key] : @init_data[:name]
466
-
467
- rescue RestClient::ResourceNotFound
468
- raise NoSuchItemError, "No #{self.class::RSRC_OBJECT_KEY} found matching: #{args[:name] ? args[:name] : args[:id]}"
469
- end
470
- end ## end arg parsing
471
-
472
- # Find the "main" subset which contains :id and :name
473
- #
474
- # If they aren't at the top-level of the init hash they are in a subset hash,
475
- # usually :general, but sometimes someething else,
476
- # like ldap servers, which have them in :connection
477
- # Whereever both :id and :name are, that's the main subset
478
-
479
- @init_data.keys.each do |subset|
480
- @main_subset = @init_data[subset] if @init_data[subset].kind_of? Hash and @init_data[subset][:id] and @init_data[subset][:name]
481
- break if @main_subset
482
- end
483
- @main_subset ||= @init_data
484
-
485
- @id ||= @main_subset[:id]
486
- @name ||= @main_subset[:name]
487
-
488
- # many things have a :site
489
- if @main_subset[:site]
490
- @site = JSS::APIObject.get_name( @main_subset[:site])
491
- end
492
-
493
- # many things have a :category
494
- if @main_subset[:category]
495
- @category = JSS::APIObject.get_name( @main_subset[:category])
496
- end
497
-
498
- # set empty strings to nil
499
- @init_data.jss_nillify! '', :recurse
500
-
501
- @in_jss = true
502
- @rest_rsrc = "#{self.class::RSRC_BASE}/id/#{@id}"
503
- @need_to_update = false
504
- end # init
505
-
506
- #####################################
507
- ### Public Instance Methods
508
- #####################################
509
-
510
- ###
511
- ### Either Create or Update this object in the JSS
512
- ###
513
- ### If this item is creatable or updatable, then
514
- ### create it if needed, or update it if it already exists.
515
- ###
516
- ### @return [Integer] the id of the item created or updated
517
- ###
518
- def save
519
- if @in_jss
520
- raise JSS::UnsupportedError, "Updating this object in the JSS is currently not supported" \
521
- unless defined? self.class::UPDATABLE
522
- return self.update
523
- else
524
- raise JSS::UnsupportedError, "Creating this object in the JSS is currently not supported" \
525
- unless defined? self.class::CREATABLE
526
- return self.create
527
- end
528
- end
529
-
530
-
531
- ###
532
- ### Delete this item from the JSS.
533
- ###
534
- ### Subclasses may want to redefine this method,
535
- ### first calling super, then setting other attributes to
536
- ### nil, false, empty, etc..
537
- ###
538
- ### @return [void]
539
- ###
540
- def delete
541
- return nil unless @in_jss
542
- JSS::API.delete_rsrc @rest_rsrc
543
- @rest_rsrc = "#{self.class::RSRC_BASE}/name/#{URI.escape @name}"
544
- @id = nil
545
- @in_jss = false
546
- @need_to_update = false
547
- end # delete
548
-
549
- #####################################
550
- ### Private Instance Methods
551
- #####################################
552
- private
553
-
554
- ###
555
- ### Return a String with the XML Resource
556
- ### for submitting creation or changes to the JSS via
557
- ### the API via the Creatable or Updatable modules
558
- ###
559
- ### Most classes will redefine this method.
560
- ###
561
- def rest_xml
562
- doc = REXML::Document.new APIConnection::XML_HEADER
563
- tmpl = doc.add_element self.class::RSRC_OBJECT_KEY.to_s
564
- tmpl.add_element('name').text = @name
565
- return doc.to_s
566
- end
567
-
568
-
569
- ### Aliases
570
-
571
- alias in_jss? in_jss
572
-
573
- end # class APIObject
574
-
575
-
576
-
577
- end # module JSS
578
-
579
- ### Mix-in Sub Modules
580
- require "jss-api/api_object/creatable"
581
- require "jss-api/api_object/uploadable"
582
- require "jss-api/api_object/locatable"
583
- require "jss-api/api_object/matchable"
584
- require "jss-api/api_object/purchasable"
585
- require "jss-api/api_object/updatable"
586
- require "jss-api/api_object/extendable"
587
-
588
- ### Mix-in Sub Modules with Classes
589
- require "jss-api/api_object/criteriable"
590
- require "jss-api/api_object/scopable"
591
-
592
- ### APIObject SubClasses with SubClasses
593
- require "jss-api/api_object/advanced_search"
594
- require "jss-api/api_object/extension_attribute"
595
- require "jss-api/api_object/group"
596
-
597
- ### APIObject SubClasses without SubClasses
598
- require "jss-api/api_object/building"
599
- require "jss-api/api_object/category"
600
- require "jss-api/api_object/computer"
601
- require "jss-api/api_object/department"
602
- require "jss-api/api_object/distribution_point"
603
- require "jss-api/api_object/ldap_server"
604
- require "jss-api/api_object/mobile_device"
605
- require "jss-api/api_object/netboot_server"
606
- require "jss-api/api_object/network_segment"
607
- require "jss-api/api_object/package"
608
- require "jss-api/api_object/peripheral_type"
609
- require "jss-api/api_object/peripheral"
610
- require "jss-api/api_object/policy"
611
- require "jss-api/api_object/removable_macaddr"
612
- require "jss-api/api_object/script"
613
- require "jss-api/api_object/site"
614
- require "jss-api/api_object/software_update_server"
615
- require "jss-api/api_object/user"
616
-