jss-api 0.5.8 → 0.6.1

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 (68) hide show
  1. data/CHANGES.md +55 -7
  2. data/README.md +2 -1
  3. data/bin/cgrouper +1 -1
  4. data/bin/subnet-update +1 -1
  5. data/lib/jss-api.rb +2 -363
  6. data/lib/jss-api/api_connection.rb +78 -15
  7. data/lib/jss-api/api_object.rb +1 -1
  8. data/lib/jss-api/api_object/advanced_search.rb +1 -1
  9. data/lib/jss-api/api_object/advanced_search/advanced_computer_search.rb +1 -1
  10. data/lib/jss-api/api_object/advanced_search/advanced_mobile_device_search.rb +1 -1
  11. data/lib/jss-api/api_object/advanced_search/advanced_user_search.rb +1 -1
  12. data/lib/jss-api/api_object/building.rb +1 -1
  13. data/lib/jss-api/api_object/category.rb +1 -1
  14. data/lib/jss-api/api_object/computer.rb +1 -1
  15. data/lib/jss-api/api_object/creatable.rb +1 -1
  16. data/lib/jss-api/api_object/criteriable.rb +1 -1
  17. data/lib/jss-api/api_object/criteriable/criteria.rb +1 -1
  18. data/lib/jss-api/api_object/criteriable/criterion.rb +1 -1
  19. data/lib/jss-api/api_object/department.rb +1 -1
  20. data/lib/jss-api/api_object/distribution_point.rb +92 -22
  21. data/lib/jss-api/api_object/extendable.rb +1 -1
  22. data/lib/jss-api/api_object/extension_attribute.rb +1 -1
  23. data/lib/jss-api/api_object/extension_attribute/computer_extension_attribute.rb +1 -1
  24. data/lib/jss-api/api_object/extension_attribute/mobile_device_extension_attribute.rb +1 -1
  25. data/lib/jss-api/api_object/extension_attribute/user_extension_attribute.rb +1 -1
  26. data/lib/jss-api/api_object/group.rb +1 -1
  27. data/lib/jss-api/api_object/group/computer_group.rb +1 -1
  28. data/lib/jss-api/api_object/group/mobile_device_group.rb +1 -1
  29. data/lib/jss-api/api_object/group/user_group.rb +1 -1
  30. data/lib/jss-api/api_object/ldap_server.rb +1 -1
  31. data/lib/jss-api/api_object/locatable.rb +1 -1
  32. data/lib/jss-api/api_object/matchable.rb +1 -1
  33. data/lib/jss-api/api_object/mobile_device.rb +1 -1
  34. data/lib/jss-api/api_object/netboot_server.rb +1 -1
  35. data/lib/jss-api/api_object/network_segment.rb +1 -1
  36. data/lib/jss-api/api_object/osx_configuration_profile.rb +1 -1
  37. data/lib/jss-api/api_object/package.rb +117 -64
  38. data/lib/jss-api/api_object/peripheral.rb +1 -1
  39. data/lib/jss-api/api_object/peripheral_type.rb +1 -1
  40. data/lib/jss-api/api_object/policy.rb +1 -1
  41. data/lib/jss-api/api_object/purchasable.rb +1 -1
  42. data/lib/jss-api/api_object/removable_macaddr.rb +1 -1
  43. data/lib/jss-api/api_object/scopable.rb +1 -1
  44. data/lib/jss-api/api_object/scopable/scope.rb +1 -1
  45. data/lib/jss-api/api_object/script.rb +1 -1
  46. data/lib/jss-api/api_object/self_servable.rb +1 -1
  47. data/lib/jss-api/api_object/site.rb +1 -1
  48. data/lib/jss-api/api_object/software_update_server.rb +1 -1
  49. data/lib/jss-api/api_object/updatable.rb +1 -1
  50. data/lib/jss-api/api_object/uploadable.rb +1 -1
  51. data/lib/jss-api/api_object/user.rb +1 -1
  52. data/lib/jss-api/client.rb +22 -21
  53. data/lib/jss-api/compatibility.rb +1 -1
  54. data/lib/jss-api/composer.rb +2 -2
  55. data/lib/jss-api/configuration.rb +1 -1
  56. data/lib/jss-api/db_connection.rb +63 -12
  57. data/lib/jss-api/exceptions.rb +1 -1
  58. data/lib/jss-api/ruby_extensions.rb +1 -1
  59. data/lib/jss-api/ruby_extensions/filetest.rb +1 -1
  60. data/lib/jss-api/ruby_extensions/hash.rb +1 -1
  61. data/lib/jss-api/ruby_extensions/ipaddr.rb +1 -1
  62. data/lib/jss-api/ruby_extensions/pathname.rb +1 -1
  63. data/lib/jss-api/ruby_extensions/string.rb +17 -1
  64. data/lib/jss-api/ruby_extensions/time.rb +1 -1
  65. data/lib/jss-api/server.rb +1 -1
  66. data/lib/jss-api/utility.rb +416 -0
  67. data/lib/jss-api/version.rb +8 -8
  68. metadata +3 -2
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,25 +1,25 @@
1
- ### Copyright 2014 Pixar
2
- ###
1
+ ### Copyright 2016 Pixar
2
+ ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
5
5
  ### compliance with the Apache License and the following modification to it:
6
6
  ### Section 6. Trademarks. is deleted and replaced with:
7
- ###
7
+ ###
8
8
  ### 6. Trademarks. This License does not grant permission to use the trade
9
9
  ### names, trademarks, service marks, or product names of the Licensor
10
10
  ### and its affiliates, except as required to comply with Section 4(c) of
11
11
  ### the License and to reproduce the content of the NOTICE file.
12
- ###
12
+ ###
13
13
  ### You may obtain a copy of the Apache License at
14
- ###
14
+ ###
15
15
  ### http://www.apache.org/licenses/LICENSE-2.0
16
- ###
16
+ ###
17
17
  ### Unless required by applicable law or agreed to in writing, software
18
18
  ### distributed under the Apache License with the above modification is
19
19
  ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
20
  ### KIND, either express or implied. See the Apache License for the specific
21
21
  ### language governing permissions and limitations under the Apache License.
22
- ###
22
+ ###
23
23
  ###
24
24
 
25
25
  ###
@@ -56,7 +56,7 @@ module JSS
56
56
  ### The Pathname to the jamf binary executable
57
57
  ### As of El Capitan (OS X 10.11) the location has moved.
58
58
  ORIG_JAMF_BINARY = Pathname.new "/usr/sbin/jamf"
59
- ELCAP_JAMF_BINARY = Pathname.new "/usr/local/sbin/jamf"
59
+ ELCAP_JAMF_BINARY = Pathname.new "/usr/local/jamf/bin/jamf"
60
60
  JAMF_BINARY = ELCAP_JAMF_BINARY.executable? ? ELCAP_JAMF_BINARY : ORIG_JAMF_BINARY
61
61
 
62
62
  ### The Pathname to the jamfHelper executable
@@ -109,7 +109,7 @@ module JSS
109
109
  #####################################
110
110
  ### Class Methods
111
111
  #####################################
112
-
112
+
113
113
  ###
114
114
  ### Get the current IP address as a String.
115
115
  ###
@@ -126,7 +126,7 @@ module JSS
126
126
  ### turn off reverse DNS resolution temporarily
127
127
  ### @note the 'socket' library has already been required by 'rest-client'
128
128
  orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
129
-
129
+
130
130
  UDPSocket.open do |s|
131
131
  s.connect '192.168.0.0', 1
132
132
  s.addr.last
@@ -243,16 +243,15 @@ module JSS
243
243
  ### @return [Hash] the HardwareDataType data from the system_profiler command
244
244
  ###
245
245
  def self.hardware_data
246
- Plist.parse_xml(`system_profiler SPHardwareDataType -xml`)[0]["_items"][0]
246
+ raw = `/usr/sbin/system_profiler SPHardwareDataType -xml 2>/dev/null`
247
+ Plist.parse_xml(raw)[0]["_items"][0]
247
248
  end
248
249
 
249
250
 
250
-
251
+ ### Run an arbitrary jamf binary command.
251
252
  ###
252
253
  ### @note Most jamf commands require superuser/root privileges.
253
254
  ###
254
- ### Run an arbitrary jamf binary command.
255
- ###
256
255
  ### @param command[String,Symbol] the jamf binary command to run
257
256
  ### The command is the single jamf command that comes after the/usr/bin/jamf.
258
257
  ###
@@ -260,7 +259,7 @@ module JSS
260
259
  ### This is to be passed to Kernel.` (backtick), after being combined with the
261
260
  ### jamf binary and the jamf command
262
261
  ###
263
- ### @param show_output[Boolean] Should the stdout & stderr of the jamf binary be sent to
262
+ ### @param verbose[Boolean] Should the stdout & stderr of the jamf binary be sent to
264
263
  ### the current stdout in realtime, as well as returned as a string?
265
264
  ###
266
265
  ### @return [String] the stdout & stderr of the jamf binary.
@@ -276,8 +275,7 @@ module JSS
276
275
  ### The details of the Process::Status for the jamf binary process can be captured from $?
277
276
  ### immediately after calling. (See Process::Status)
278
277
  ###
279
- ###
280
- def self.run_jamf(command, args = nil, show_output = false)
278
+ def self.run_jamf(command, args = nil, verbose = false)
281
279
  raise JSS::UnmanagedError, "The jamf binary is not installed on this computer." unless self.installed?
282
280
  raise JSS::UnsupportedError, "You must have root privileges to run that jamf binary command" unless ROOTLESS_JAMF_COMMANDS.include? command.to_sym or JSS.superuser?
283
281
 
@@ -292,16 +290,19 @@ module JSS
292
290
  raise JSS::InvalidDataError, "args must be a String or Array of Strings"
293
291
  end # case
294
292
 
293
+ cmd += " -verbose" if verbose and (not cmd.include? " -verbose")
294
+ puts "Running: #{cmd}" if verbose
295
+
295
296
  output = []
296
297
  IO.popen("#{cmd} 2>&1") do |proc|
297
298
  while line = proc.gets
298
299
  output << line
299
- puts line if show_output
300
+ puts line if verbose
300
301
  end
301
302
  end
302
-
303
- return output.join('')
304
-
303
+ install_out = output.join('')
304
+ install_out.force_encoding("UTF-8") if install_out.respond_to? :force_encoding
305
+ return install_out
305
306
  end # run_jamf
306
307
 
307
308
 
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -86,7 +86,7 @@ module JSS
86
86
  opts[:out_dir] ||= DEFAULT_OUT_DIR
87
87
  opts[:bundle_id_prefix] ||= PKG_BUNDLE_ID_PFX
88
88
 
89
- pkg_filename = "#{name}.pkg"
89
+ pkg_filename = name.end_with?(".pkg") ? name : name+".pkg"
90
90
  pkg_id = opts[:bundle_id_prefix] + "." + name
91
91
  pkg_out = "#{opts[:out_dir]}/#{pkg_filename}"
92
92
  pkg_ownership = opts[:preserve_ownership] ? "preserve" : "recommended"
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -84,7 +84,10 @@ module JSS
84
84
 
85
85
  ###
86
86
  DFT_SOCKET = '/var/mysql/mysql.sock'
87
-
87
+
88
+ ### the default MySQL port
89
+ DFT_PORT = 3306
90
+
88
91
  ### the strftime format for reading/writing dates in the db
89
92
  SQL_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
90
93
 
@@ -140,8 +143,12 @@ module JSS
140
143
  ###
141
144
  def connect(args = {})
142
145
 
146
+ # server might come frome several places
147
+ # if not given in the args, use #hostname to figure out
148
+ # which
149
+ @server = args[:server] ? args[:server] : hostname
150
+
143
151
  # settings from config if they aren't in the args
144
- args[:server] ||= JSS::CONFIG.db_server_name
145
152
  args[:port] ||= JSS::CONFIG.db_server_port
146
153
  args[:socket] ||= JSS::CONFIG.db_server_socket
147
154
  args[:db_name] ||= JSS::CONFIG.db_name
@@ -169,7 +176,6 @@ module JSS
169
176
  @connected = false
170
177
  end
171
178
 
172
- @server = args[:server]
173
179
  @port = args[:port]
174
180
  @socket = args[:socket]
175
181
  @mysql_name = args[:db_name]
@@ -178,14 +184,13 @@ module JSS
178
184
  @read_timeout = args[:read_timeout]
179
185
  @write_timeout = args[:write_timeout]
180
186
 
181
- # make sure we have a user
182
- raise JSS::MissingDataError, "No JSS user specified, or listed in configuration." unless args[:user]
183
-
184
- # passwd from prompt, stdin, or args?
187
+ # make sure we have a user, pw, server
188
+ raise JSS::MissingDataError, "No MySQL user specified, or listed in configuration." unless args[:user]
185
189
  raise JSS::MissingDataError, "Missing :pw (or :prompt/:stdin) for user '#{@user}'" unless args[:pw]
190
+ raise JSS::MissingDataError, "No MySQL Server hostname specified, or listed in configuration." unless @server
186
191
 
187
192
  @pw = if args[:pw] == :prompt
188
- JSS.prompt_for_password "Enter the password for the MySQL user #{@user}@#{args[:server]}:"
193
+ JSS.prompt_for_password "Enter the password for the MySQL user #{@user}@#{@server}:"
189
194
  elsif args[:pw].is_a?(Symbol) and args[:pw].to_s.start_with?('stdin')
190
195
  args[:pw].to_s =~ /^stdin(\d+)$/
191
196
  line = $1
@@ -195,8 +200,6 @@ module JSS
195
200
  args[:pw]
196
201
  end
197
202
 
198
-
199
-
200
203
  @mysql = Mysql.init
201
204
 
202
205
  @mysql.options Mysql::OPT_CONNECT_TIMEOUT, @connect_timeout
@@ -222,10 +225,58 @@ module JSS
222
225
  ###
223
226
  def disconnect
224
227
  @mysql.close if connected?
228
+ @server = nil
229
+ @port = nil
230
+ @socket = nil
231
+ @user = nil
232
+ @connection_timeout = DFT_TIMEOUT
233
+ @read_timeout = DFT_TIMEOUT
234
+ @write_timeout = DFT_TIMEOUT
225
235
  @connected = false
226
236
  nil
227
237
  end # disconnect
228
-
238
+
239
+ ### Test that a given hostname is a MySQL server
240
+ ###
241
+ ### @param server[String] The hostname to test
242
+ ###
243
+ ### @return [Boolean] does the server host a MySQL server?
244
+ ###
245
+ def valid_server? (server, port = DFT_PORT)
246
+ mysql = Mysql.init
247
+ mysql.options Mysql::OPT_CONNECT_TIMEOUT, 5
248
+
249
+ begin
250
+ # this connection should get an access denied error if there is
251
+ # a mysql server there. I'm assuming no one will use this username
252
+ # and pw for anything real
253
+ mysql.connect server, "notArealUser", "definatelyNotA#{$$}password", "not_a_db", port
254
+
255
+ rescue Mysql::ServerError::AccessDeniedError
256
+ return true
257
+ rescue
258
+ return false
259
+ end
260
+ return false
261
+ end
262
+
263
+ ### The server to which we are connected, or will
264
+ ### try connecting to if none is specified with the
265
+ ### call to #connect
266
+ ###
267
+ ### @return [String] the hostname of the server
268
+ ###
269
+ def hostname
270
+ # return it if already set
271
+ return @server if @server
272
+ # otherwise, from the config
273
+ srvr = JSS::CONFIG.db_server_name
274
+ # otherwise, assume its on the JSS server to which this client talks
275
+ srvr ||= JSS::Client.jss_server
276
+ return srvr
277
+ end
278
+
279
+
229
280
  #### Aliases
230
281
 
231
282
  alias connected? connected
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -40,4 +40,20 @@ class String
40
40
  else return nil
41
41
  end # case
42
42
  end # to bool
43
+
44
+ ### Convert a string to a Time object
45
+ ###
46
+ ### returns nil if not parsable by JSS::parse_datetime
47
+ ###
48
+ ### @return [Time] the time represented by the string.
49
+ ###
50
+ def jss_to_time
51
+ begin
52
+ JSS.parse_time self
53
+ rescue
54
+ return nil
55
+ end
56
+ end
57
+
58
+
43
59
  end # class
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
@@ -1,4 +1,4 @@
1
- ### Copyright 2014 Pixar
1
+ ### Copyright 2016 Pixar
2
2
  ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in