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.
- data/CHANGES.md +4 -0
- data/LICENSE.txt +174 -0
- data/README.md +368 -0
- data/THANKS.md +6 -0
- data/lib/jss-api.rb +549 -0
- data/lib/jss-api/api_connection.rb +326 -0
- data/lib/jss-api/api_object.rb +590 -0
- data/lib/jss-api/api_object/advanced_search.rb +389 -0
- data/lib/jss-api/api_object/advanced_search/advanced_computer_search.rb +95 -0
- data/lib/jss-api/api_object/advanced_search/advanced_mobile_device_search.rb +96 -0
- data/lib/jss-api/api_object/advanced_search/advanced_user_search.rb +95 -0
- data/lib/jss-api/api_object/building.rb +92 -0
- data/lib/jss-api/api_object/category.rb +147 -0
- data/lib/jss-api/api_object/computer.rb +852 -0
- data/lib/jss-api/api_object/creatable.rb +98 -0
- data/lib/jss-api/api_object/criteriable.rb +189 -0
- data/lib/jss-api/api_object/criteriable/criteria.rb +231 -0
- data/lib/jss-api/api_object/criteriable/criterion.rb +228 -0
- data/lib/jss-api/api_object/department.rb +93 -0
- data/lib/jss-api/api_object/distribution_point.rb +490 -0
- data/lib/jss-api/api_object/extendable.rb +221 -0
- data/lib/jss-api/api_object/extension_attribute.rb +457 -0
- data/lib/jss-api/api_object/extension_attribute/computer_extension_attribute.rb +362 -0
- data/lib/jss-api/api_object/extension_attribute/mobile_device_extension_attribute.rb +189 -0
- data/lib/jss-api/api_object/extension_attribute/user_extension_attribute.rb +117 -0
- data/lib/jss-api/api_object/group.rb +380 -0
- data/lib/jss-api/api_object/group/computer_group.rb +124 -0
- data/lib/jss-api/api_object/group/mobile_device_group.rb +139 -0
- data/lib/jss-api/api_object/group/user_group.rb +139 -0
- data/lib/jss-api/api_object/ldap_server.rb +535 -0
- data/lib/jss-api/api_object/locatable.rb +268 -0
- data/lib/jss-api/api_object/matchable.rb +97 -0
- data/lib/jss-api/api_object/mobile_device.rb +556 -0
- data/lib/jss-api/api_object/netboot_server.rb +148 -0
- data/lib/jss-api/api_object/network_segment.rb +414 -0
- data/lib/jss-api/api_object/package.rb +760 -0
- data/lib/jss-api/api_object/peripheral.rb +335 -0
- data/lib/jss-api/api_object/peripheral_type.rb +295 -0
- data/lib/jss-api/api_object/policy.rb +882 -0
- data/lib/jss-api/api_object/purchasable.rb +316 -0
- data/lib/jss-api/api_object/removable_macaddr.rb +98 -0
- data/lib/jss-api/api_object/scopable.rb +136 -0
- data/lib/jss-api/api_object/scopable/scope.rb +621 -0
- data/lib/jss-api/api_object/script.rb +631 -0
- data/lib/jss-api/api_object/site.rb +93 -0
- data/lib/jss-api/api_object/software_update_server.rb +109 -0
- data/lib/jss-api/api_object/updatable.rb +117 -0
- data/lib/jss-api/api_object/uploadable.rb +138 -0
- data/lib/jss-api/api_object/user.rb +272 -0
- data/lib/jss-api/client.rb +500 -0
- data/lib/jss-api/compatibility.rb +66 -0
- data/lib/jss-api/composer.rb +171 -0
- data/lib/jss-api/configuration.rb +301 -0
- data/lib/jss-api/db_connection.rb +243 -0
- data/lib/jss-api/exceptions.rb +83 -0
- data/lib/jss-api/ruby_extensions.rb +35 -0
- data/lib/jss-api/ruby_extensions/filetest.rb +43 -0
- data/lib/jss-api/ruby_extensions/hash.rb +79 -0
- data/lib/jss-api/ruby_extensions/ipaddr.rb +91 -0
- data/lib/jss-api/ruby_extensions/pathname.rb +77 -0
- data/lib/jss-api/ruby_extensions/string.rb +43 -0
- data/lib/jss-api/ruby_extensions/time.rb +63 -0
- data/lib/jss-api/server.rb +108 -0
- data/lib/jss-api/version.rb +31 -0
- metadata +219 -0
data/THANKS.md
ADDED
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
|
+
### * & => &
|
233
|
+
### * " => "
|
234
|
+
### * < => <
|
235
|
+
### * > => >
|
236
|
+
### * ' => '
|
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(/&/, '&').gsub(/\"/, '"').gsub(/>/, '>').gsub(/</, '<').gsub(/'/, ''')
|
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"
|