jss-api 0.5.4

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.
Files changed (65) hide show
  1. data/CHANGES.md +4 -0
  2. data/LICENSE.txt +174 -0
  3. data/README.md +368 -0
  4. data/THANKS.md +6 -0
  5. data/lib/jss-api.rb +549 -0
  6. data/lib/jss-api/api_connection.rb +326 -0
  7. data/lib/jss-api/api_object.rb +590 -0
  8. data/lib/jss-api/api_object/advanced_search.rb +389 -0
  9. data/lib/jss-api/api_object/advanced_search/advanced_computer_search.rb +95 -0
  10. data/lib/jss-api/api_object/advanced_search/advanced_mobile_device_search.rb +96 -0
  11. data/lib/jss-api/api_object/advanced_search/advanced_user_search.rb +95 -0
  12. data/lib/jss-api/api_object/building.rb +92 -0
  13. data/lib/jss-api/api_object/category.rb +147 -0
  14. data/lib/jss-api/api_object/computer.rb +852 -0
  15. data/lib/jss-api/api_object/creatable.rb +98 -0
  16. data/lib/jss-api/api_object/criteriable.rb +189 -0
  17. data/lib/jss-api/api_object/criteriable/criteria.rb +231 -0
  18. data/lib/jss-api/api_object/criteriable/criterion.rb +228 -0
  19. data/lib/jss-api/api_object/department.rb +93 -0
  20. data/lib/jss-api/api_object/distribution_point.rb +490 -0
  21. data/lib/jss-api/api_object/extendable.rb +221 -0
  22. data/lib/jss-api/api_object/extension_attribute.rb +457 -0
  23. data/lib/jss-api/api_object/extension_attribute/computer_extension_attribute.rb +362 -0
  24. data/lib/jss-api/api_object/extension_attribute/mobile_device_extension_attribute.rb +189 -0
  25. data/lib/jss-api/api_object/extension_attribute/user_extension_attribute.rb +117 -0
  26. data/lib/jss-api/api_object/group.rb +380 -0
  27. data/lib/jss-api/api_object/group/computer_group.rb +124 -0
  28. data/lib/jss-api/api_object/group/mobile_device_group.rb +139 -0
  29. data/lib/jss-api/api_object/group/user_group.rb +139 -0
  30. data/lib/jss-api/api_object/ldap_server.rb +535 -0
  31. data/lib/jss-api/api_object/locatable.rb +268 -0
  32. data/lib/jss-api/api_object/matchable.rb +97 -0
  33. data/lib/jss-api/api_object/mobile_device.rb +556 -0
  34. data/lib/jss-api/api_object/netboot_server.rb +148 -0
  35. data/lib/jss-api/api_object/network_segment.rb +414 -0
  36. data/lib/jss-api/api_object/package.rb +760 -0
  37. data/lib/jss-api/api_object/peripheral.rb +335 -0
  38. data/lib/jss-api/api_object/peripheral_type.rb +295 -0
  39. data/lib/jss-api/api_object/policy.rb +882 -0
  40. data/lib/jss-api/api_object/purchasable.rb +316 -0
  41. data/lib/jss-api/api_object/removable_macaddr.rb +98 -0
  42. data/lib/jss-api/api_object/scopable.rb +136 -0
  43. data/lib/jss-api/api_object/scopable/scope.rb +621 -0
  44. data/lib/jss-api/api_object/script.rb +631 -0
  45. data/lib/jss-api/api_object/site.rb +93 -0
  46. data/lib/jss-api/api_object/software_update_server.rb +109 -0
  47. data/lib/jss-api/api_object/updatable.rb +117 -0
  48. data/lib/jss-api/api_object/uploadable.rb +138 -0
  49. data/lib/jss-api/api_object/user.rb +272 -0
  50. data/lib/jss-api/client.rb +500 -0
  51. data/lib/jss-api/compatibility.rb +66 -0
  52. data/lib/jss-api/composer.rb +171 -0
  53. data/lib/jss-api/configuration.rb +301 -0
  54. data/lib/jss-api/db_connection.rb +243 -0
  55. data/lib/jss-api/exceptions.rb +83 -0
  56. data/lib/jss-api/ruby_extensions.rb +35 -0
  57. data/lib/jss-api/ruby_extensions/filetest.rb +43 -0
  58. data/lib/jss-api/ruby_extensions/hash.rb +79 -0
  59. data/lib/jss-api/ruby_extensions/ipaddr.rb +91 -0
  60. data/lib/jss-api/ruby_extensions/pathname.rb +77 -0
  61. data/lib/jss-api/ruby_extensions/string.rb +43 -0
  62. data/lib/jss-api/ruby_extensions/time.rb +63 -0
  63. data/lib/jss-api/server.rb +108 -0
  64. data/lib/jss-api/version.rb +31 -0
  65. metadata +219 -0
data/THANKS.md ADDED
@@ -0,0 +1,6 @@
1
+ # With Thanks To...
2
+
3
+ * Pixar Systems Management
4
+ * The Pixar Mac Team
5
+ * JAMF Folks
6
+ * Alex
data/lib/jss-api.rb ADDED
@@ -0,0 +1,549 @@
1
+ ### Copyright 2014 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
+ ### JSS, A Ruby module for interacting with the JAMF Software Server via it's REST API.
27
+ ###
28
+ module JSS
29
+
30
+ #####################################
31
+ ### Required Libraries, etc
32
+ #####################################
33
+
34
+ ###################
35
+ ### Standard Libraries
36
+ require 'date'
37
+ require 'singleton'
38
+ require 'pathname'
39
+ require 'fileutils'
40
+ require 'uri'
41
+ require "ipaddr"
42
+ require "rexml/document"
43
+ require "base64"
44
+ require "shellwords"
45
+ require "digest"
46
+ require 'yaml'
47
+
48
+ ###################
49
+ ### Gems
50
+ require 'rest-client'
51
+ require 'json'
52
+ require 'plist'
53
+
54
+
55
+
56
+ #####################################
57
+ ### Constants
58
+ #####################################
59
+
60
+ ### The minimum JSS version that works with this gem, as returned by the API
61
+ ### in the deprecated 'jssuser' resource
62
+ MINIMUM_SERVER_VERSION = "9.4"
63
+
64
+ ### The current local UTC offset as a fraction of a day (Time.now.utc_offset is the offset in seconds,
65
+ ### 60*60*24 is the seconds in a day)
66
+ TIME_ZONE_OFFSET = Rational(Time.now.utc_offset, 60*60*24)
67
+
68
+ ### These are handy for testing values without making new arrays, strings, etc every time.
69
+ TRUE_FALSE = [true, false]
70
+
71
+ ### When parsing a date/time data into a Time object, these will return nil
72
+ NIL_DATES = [0, nil, '', '0']
73
+
74
+ ### The contents of anything piped to stdin, split into lines. See {JSS.stdin}
75
+ STDIN_LINES = $stdin.tty? ? [] : $stdin.read.lines.map{|line| line.chomp("\n") }
76
+
77
+
78
+ #####################################
79
+ ### Module Variables
80
+ #####################################
81
+
82
+ #####################################
83
+ ### Module Methods
84
+ #####################################
85
+
86
+
87
+
88
+
89
+ ###
90
+ ### Given a list of data as a comma-separated string, or an Array of strings,
91
+ ### return a Hash with both versions.
92
+ ###
93
+ ### Some parts of the JSS require lists as comma-separated strings, while
94
+ ### often those data are easier work with as arrays. This method is a handy way
95
+ ### to get either form when given either form.
96
+ ###
97
+ ### @param somedata [String, Array] the data to parse, of either class,
98
+ ###
99
+ ### @return [Hash{:stringform => String, :arrayform => Array}] the data as both comma-separated String and Array
100
+ ###
101
+ ### @example
102
+ ### JSS.to_s_and_a "foo, bar, baz" # Hash => {:stringform => "foo, bar, baz", :arrayform => ["foo", "bar", "baz"]}
103
+ ###
104
+ ### JSS.to_s_and_a ["foo", "bar", "baz"] # Hash => {:stringform => "foo, bar, baz", :arrayform => ["foo", "bar", "baz"]}
105
+ ###
106
+ def self.to_s_and_a (somedata)
107
+ case somedata
108
+ when String
109
+ valstr = somedata
110
+ valarr = somedata.split(/,\s*/)
111
+ when Array
112
+ valstr = somedata.join ", "
113
+ valarr = somedata
114
+ else
115
+ raise JSS::InvalidDataError, "Input must be a comma-separated String or an Array of Strings"
116
+ end # case
117
+ return {:stringform => valstr, :arrayform => valarr}
118
+ end # to_s_and_a
119
+
120
+ ###
121
+ ### Converts an OS Version into an Array of higher OS versions.
122
+ ###
123
+ ### It's unlikely that this library will still be in use as-is by the release of OS X 10.19.15.
124
+ ### Hopefully well before then JAMF will implement a "minimum OS" in the JSS itself.
125
+ ###
126
+ ### @param min_os [String] the mimimum OS version to expand, e.g. ">=10.6.7" or "10.6.7"
127
+ ###
128
+ ### @return [Array] Nearly all potential OS versions from the minimum to 10.19.x.
129
+ ###
130
+ ### @example
131
+ ### JSS.expand_min_os ">=10.6.7" # => returns this array
132
+ ### # ["10.6.7",
133
+ ### # "10.6.8",
134
+ ### # "10.6.9",
135
+ ### # "10.6.10",
136
+ ### # "10.6.11",
137
+ ### # "10.6.12",
138
+ ### # "10.6.13",
139
+ ### # "10.6.14",
140
+ ### # "10.6.15",
141
+ ### # "10.7.x",
142
+ ### # "10.8.x",
143
+ ### # "10.9.x",
144
+ ### # "10.10.x",
145
+ ### # "10.11.x",
146
+ ### # "10.12.x",
147
+ ### # "10.13.x",
148
+ ### # "10.14.x",
149
+ ### # "10.15.x",
150
+ ### # "10.16.x",
151
+ ### # "10.17.x",
152
+ ### # "10.18.x",
153
+ ### # "10.19.x"]
154
+ ###
155
+ ###
156
+ def self.expand_min_os (min_os)
157
+
158
+ min_os.delete! ">="
159
+
160
+ ### split the version into major, minor and maintenance release numbers
161
+ (maj,min,maint) = min_os.split(".")
162
+ maint = "x" if maint.nil? or maint == "0"
163
+
164
+ ### if the maint release number is an "x" just start the list of OK OS's with it
165
+ if maint == "x"
166
+ ok_oses = [maj + "." + min.to_s + ".x"]
167
+
168
+ ### otherwise, start with it and explicitly add all maint releases up to 15
169
+ ### (and hope apple doesn't do more than 15 maint releases for an OS)
170
+ else
171
+ ok_oses = []
172
+ (maint.to_i..15).each do |m|
173
+ ok_oses << maj + "." + min +"." + m.to_s
174
+ end # each m
175
+ end
176
+
177
+ ### now account for all OS X versions starting with 10.
178
+ ### up to at least 10.19.x
179
+ ((min.to_i + 1)..19).each do |v|
180
+ ok_oses << maj + "." + v.to_s + ".x"
181
+ end # each v
182
+ return ok_oses
183
+ end
184
+
185
+ ###
186
+ ### Converts anything that responds to #to_s to a Time, or nil
187
+ ###
188
+ ### Return nil if the item is nil, 0 or an empty String.
189
+ ###
190
+ ### Otherwise the item converted to a string, and parsed with DateTime.parse.
191
+ ### It is then examined to see if it has a UTC offset. If not, the local offset
192
+ ### is applied, then the DateTime is converted to a Time.
193
+ ###
194
+ ### @param a_datetime [#to_s] The thing to convert to a time.
195
+ ###
196
+ ### @return [Time, nil] nil is returned if a_datetime is nil, 0 or an empty String.
197
+ ###
198
+ def self.parse_datetime(a_datetime)
199
+ return nil if NIL_DATES.include? a_datetime
200
+
201
+ the_dt = DateTime.parse(a_datetime.to_s)
202
+
203
+ ### The microseconds in DateTimes are stored as a fraction of a day.
204
+ ### Convert them to an integer of microseconds
205
+ usec = (the_dt.sec_fraction * 60 * 60 * 24 * (10**6)).to_i
206
+
207
+ ### if the UTC offset of the datetime is zero, make a new one with the correct local offset
208
+ ### (which might also be zero if we happen to be in GMT)
209
+ if the_dt.offset == 0
210
+ the_dt = DateTime.new(the_dt.year, the_dt.month, the_dt.day, the_dt.hour, the_dt.min, the_dt.sec, JSS::TIME_ZONE_OFFSET)
211
+ end
212
+ # now convert it to a Time and return it
213
+ Time.at the_dt.strftime('%s').to_i, usec
214
+
215
+ end #parse_datetime
216
+
217
+ ###
218
+ ### Converts JSS epoch (unix epoch + milliseconds) to a Ruby Time object
219
+ ###
220
+ ### @param epoch[String, Integer, nil]
221
+ ###
222
+ ### @return [Time, nil] nil is returned if epoch is nil, 0 or an empty String.
223
+ ###
224
+ def self.epoch_to_time(epoch)
225
+ return nil if NIL_DATES.include? epoch
226
+ Time.at(epoch.to_i / 1000.0)
227
+ end #parse_date
228
+
229
+
230
+ ###
231
+ ### Given a string of xml element text, escape any characters that would make XML unhappy.
232
+ ### * & => &amp;
233
+ ### * " => &quot;
234
+ ### * < => &lt;
235
+ ### * > => &gt;
236
+ ### * ' => &apos;
237
+ ###
238
+ ### @param string [String] the string to make xml-compliant.
239
+ ###
240
+ ### @return [String] the xml-compliant string
241
+ ###
242
+ def self.escape_xml(string)
243
+ string.gsub(/&/, '&amp;').gsub(/\"/, '&quot;').gsub(/>/, '&gt;').gsub(/</, '&lt;').gsub(/'/, '&apos;')
244
+ end
245
+
246
+ ###
247
+ ### Given an element name and an array of content, generate an Array of
248
+ ### REXML::Element objects with that name, and matching content.
249
+ ### The array of REXML elements would render thus:
250
+ ### <foo>bar</foo>
251
+ ### <foo>morefoo</foo>
252
+ ###
253
+ ### @param element [#to_s] an element_name like :foo
254
+ ###
255
+ ### @param list [Array<#to_s>] an Array of element content such as ["bar", :morefoo]
256
+ ###
257
+ ### @return [Array<REXML::Element>]
258
+ ###
259
+ def self.array_to_rexml_array(element,list)
260
+ raise JSS::InvalidDataError, "Arg. must be an Array." unless list.kind_of? Array
261
+ element = element.to_s
262
+ list.map do |v|
263
+ e = REXML::Element.new(element)
264
+ e.text = v
265
+ e
266
+ end
267
+ end
268
+
269
+ ###
270
+ ### Given a simple Hash, convert it to an array of REXML Elements such that each
271
+ ### key becomes an element, and its value becomes the text content of
272
+ ### that element
273
+ ###
274
+ ### @example
275
+ ### my_hash = {:foo => "bar", :baz => :morefoo}
276
+ ### xml = JSS.hash_to_rexml_array(my_hash)
277
+ ### xml.each{|x| puts x }
278
+ ###
279
+ ### <foo>bar</foo>
280
+ ### <baz>morefoo</baz>
281
+ ###
282
+ ### @param hash [Hash{#to_s => #to_s}] the Hash to convert
283
+ ###
284
+ ### @return [Array<REXML::Element>] the Array of REXML elements.
285
+ ###
286
+ def self.hash_to_rexml_array(hash)
287
+ raise InvalidDataError, "Arg. must be a Hash." unless hash.kind_of? Hash
288
+ ary = []
289
+ hash.each_pair do |k,v|
290
+ el = REXML::Element.new k.to_s
291
+ el.text = v
292
+ ary << el
293
+ end
294
+ ary
295
+ end
296
+
297
+
298
+ ###
299
+ ### Given an Array of Hashes with :id and/or :name keys, return
300
+ ### a single REXML element with a sub-element for each item,
301
+ ### each of which contains a :name or :id element.
302
+ ###
303
+ ### @param list_element [#to_s] the name of the XML element that contains the list.
304
+ ### e.g. :computers
305
+ ###
306
+ ### @param item_element [#to_s] the name of each XML element in the list,
307
+ ### e.g. :computer
308
+ ###
309
+ ### @param item_list [Array<Hash>] an Array of Hashes each with a :name or :id key.
310
+ ###
311
+ ### @param content [Symbol] which hash key should be used as the content of if list item? Defaults to :name
312
+ ###
313
+ ### @return [REXML::Element] the item list as REXML
314
+ ###
315
+ ### @example
316
+ ### comps = [{:id=>2,:name=>'kimchi'},{:id=>5,:name=>'mantis'}]
317
+ ### xml = JSS.item_list_to_rexml_list(:computers, :computer , comps, :name)
318
+ ### puts xml
319
+ ### # output manually formatted for clarity. No newlines in the real xml string
320
+ ### <computers>
321
+ ### <computer>
322
+ ### <name>kimchi</name>
323
+ ### </computer>
324
+ ### <computer>
325
+ ### <name>mantis</name>
326
+ ### </computer>
327
+ ### </computers>
328
+ ###
329
+ ### # if content is :id, then, eg. <name>kimchi</name> would be <id>2</id>
330
+ ###
331
+ def self.item_list_to_rexml_list(list_element, item_element , item_list, content = :name)
332
+ xml_list = REXML::Element.new list_element.to_s
333
+ item_list.each do |i|
334
+ xml_list.add_element(item_element.to_s).add_element(content.to_s).text = i[content]
335
+ end
336
+ xml_list
337
+ end
338
+
339
+
340
+ ###
341
+ ### Parse a JSS Version number into something comparable
342
+ ###
343
+ ### Unfortunately, the JSS version numbering is inconsistant and improper at the moment.
344
+ ### Version 9.32 should be version 9.3.2, so that it
345
+ ### will be recognizable as being less than 9.4
346
+ ###
347
+ ### To work around this until JAMF standardizes version numbering,
348
+ ### we will assume any digits before the first dot is the major version
349
+ ### and the first digit after the first dot is the minor version
350
+ ### and anything else, including other dots, is the revision
351
+ ###
352
+ ### If that revision starts with a dot, it is removed.
353
+ ### so 9.32 becomes major-9, minor-3, rev-2
354
+ ### and 9.32.3764 becomes major-9, minor-3, rev-2.3764
355
+ ### and 9.3.2.3764 becomes major-9, minor-3, rev-2.3764
356
+ ###
357
+ ### This method of parsing will break if the minor revision
358
+ ### ever gets above 9.
359
+ ###
360
+ ### Returns a hash with these keys:
361
+ ### * :major => the major version, Integer
362
+ ### * :minor => the minor version, Integor
363
+ ### * :revision => the revision, String
364
+ ### * :version => a Gem::Version object built from the above keys, which is easily compared to others.
365
+ ###
366
+ ### @param version[String] a JSS version number from the API
367
+ ###
368
+ ### @return [Hash{Symbol => String, Gem::Version}] the parsed version data.
369
+ ###
370
+ def self.parse_jss_version(version)
371
+ spl = version.split('.')
372
+
373
+ case spl.count
374
+ when 1
375
+ major = spl[0].to_i
376
+ minor = 0
377
+ revision = '0'
378
+ when 2
379
+ major = spl[0].to_i
380
+ minor = spl[1][0,1].to_i
381
+ revision = spl[1][1..-1]
382
+ revision = '0' if revision.empty?
383
+ else
384
+ major = spl[0].to_i
385
+ minor = spl[1][0,1].to_i
386
+ revision = spl[1..-1].join('.')[1..-1]
387
+ revision = revision[1..-1] if revision.start_with? '.'
388
+ end
389
+
390
+ ###revision = revision[1..-1] if revision.start_with? '.'
391
+ { :major => major,
392
+ :minor => minor,
393
+ :revision => revision,
394
+ :version => Gem::Version.new("#{major}.#{minor}.#{revision}")
395
+ }
396
+ end
397
+
398
+ ###
399
+ ### @return [Boolean] is this code running as root?
400
+ ###
401
+ def self.superuser?
402
+ Process.euid == 0
403
+ end
404
+
405
+ ###
406
+ ### Retrive one or all lines from whatever was piped to standard input.
407
+ ###
408
+ ### Standard input is read completely when the module loads
409
+ ### and the lines are stored as an Array in the constant {STDIN_LINES}
410
+ ###
411
+ ### @param line[Integer] which line of stdin is being retrieved.
412
+ ### The default is zero (0) which returns all of stdin as a single string.
413
+ ###
414
+ ### @return [String, nil] the requested ling of stdin, or nil if it doesn't exist.
415
+ ###
416
+ def self.stdin(line = 0)
417
+
418
+ return STDIN_LINES.join("\n") if line <= 0
419
+
420
+ idx = line - 1
421
+ return STDIN_LINES[idx]
422
+ end
423
+
424
+ ###
425
+ ### Prompt for a password in a terminal.
426
+ ###
427
+ ### @param message [String] the prompt message to display
428
+ ###
429
+ ### @return [String] the text typed by the user
430
+ ###
431
+ def self.prompt_for_password(message)
432
+
433
+ begin
434
+ $stdin.reopen '/dev/tty' unless $stdin.tty?
435
+ $stderr.print "#{message} "
436
+ system "/bin/stty -echo"
437
+ pw = $stdin.gets.chomp("\n")
438
+ puts
439
+ ensure
440
+ system "/bin/stty echo"
441
+ end # begin
442
+ return pw
443
+ end
444
+
445
+
446
+ ###
447
+ ### Define classes and submodules here so that they don't
448
+ ### generate errors when referenced during the loading of
449
+ ### the library.
450
+ ###
451
+
452
+ #####################################
453
+ ### Sub Modules
454
+ #####################################
455
+
456
+ module Composer ; end
457
+
458
+ ### Mix-in Sub Modules
459
+
460
+ module Creatable ; end
461
+ module FileUpload ; end
462
+ module Locatable ; end
463
+ module Matchable ; end
464
+ module Purchasable ; end
465
+ module Updatable ; end
466
+ module Extendable ; end
467
+
468
+ ### Mix-in Sub Modules with Classes
469
+
470
+ module Criteriable ; end
471
+ class Criteriable::Criteria ; end
472
+ class Criteriable::Criterion ; end
473
+
474
+ module Scopable ; end
475
+ class Scopable::Scope ; end
476
+
477
+ #####################################
478
+ ### Classes
479
+ #####################################
480
+
481
+ class APIObject ; end
482
+ class APIConnection ; end
483
+ class Client ; end
484
+ class DBConnection ; end
485
+ class Server ; end
486
+ class Preferences ; end
487
+
488
+ #####################################
489
+ ### SubClasses
490
+ #####################################
491
+
492
+ ### APIObject Classes with SubClasses
493
+
494
+ class AdvancedSearch < JSS::APIObject ; end
495
+ class AdvancedComputerSearch < JSS::AdvancedSearch ; end
496
+ class AdvancedMobileDeviceSearch < JSS::AdvancedSearch ; end
497
+ class AdvancedUserSearch < JSS::AdvancedSearch ; end
498
+
499
+
500
+ class ExtensionAttribute < JSS::APIObject ; end
501
+ class ComputerExtensionAttribute < JSS::ExtensionAttribute ; end
502
+ class MobileDeviceExtensionAttribute < JSS::ExtensionAttribute ; end
503
+ class UserExtensionAttribute < JSS::ExtensionAttribute ; end
504
+
505
+ class Group < JSS::APIObject ; end
506
+ class ComputerGroup < JSS::Group ; end
507
+ class MobileDeviceGroup < JSS::Group ; end
508
+ class UserGroup < JSS::Group ; end
509
+
510
+ ### APIObject Classes without SubClasses
511
+
512
+ class Building < JSS::APIObject ; end
513
+ class Category < JSS::APIObject ; end
514
+ class Computer < JSS::APIObject ; end
515
+ class Department < JSS::APIObject ; end
516
+ class DistributionPoint < JSS::APIObject ; end
517
+ class LDAPServer < JSS::APIObject ; end
518
+ class MobileDevice < JSS::APIObject ; end
519
+ class NetBootServer < JSS::APIObject ; end
520
+ class NetworkSegment < JSS::APIObject ; end
521
+ class Package < JSS::APIObject ; end
522
+ class PeripheralType < JSS::APIObject ; end
523
+ class Peripheral < JSS::APIObject ; end
524
+ class Policy < JSS::APIObject ; end
525
+ class RemovableMacAddress < JSS::APIObject ; end
526
+ class Script < JSS::APIObject ; end
527
+ class Site < JSS::APIObject ; end
528
+ class SoftwareUpdateServer < JSS::APIObject ; end
529
+ class User < JSS::APIObject ; end
530
+
531
+
532
+ end # module JSS
533
+
534
+
535
+ ##################
536
+ ### Load the rest of the module
537
+ # $:.unshift File.dirname(__FILE__)
538
+
539
+ require "jss-api/composer"
540
+ require "jss-api/compatibility"
541
+ require "jss-api/ruby_extensions"
542
+ require "jss-api/exceptions"
543
+ require "jss-api/api_connection"
544
+ require "jss-api/api_object"
545
+ require "jss-api/server"
546
+ require "jss-api/client"
547
+ require "jss-api/configuration"
548
+ require "jss-api/db_connection"
549
+ require "jss-api/version"