ruby-jss 2.1.0b4 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a00af3813560fa65f8597fc6a516d1b9933eb333f2aee3478646df1f93a45b9
4
- data.tar.gz: 892e4f5ed6b7271c55377671ff13ccb7778a51b34d57b9da67086cd95ec7d0ca
3
+ metadata.gz: 970c4289986bb3f0b3ea9a60b31777a29b4c927879a3204d28c3f9bdd46a2a9f
4
+ data.tar.gz: f75ae4ae8ba5bd0cfadb065c62f495fcb4eea86b2473aa5d8357569e9ce49059
5
5
  SHA512:
6
- metadata.gz: 6461d576566cfd365c77ff36758a8c9558deb2bad8936b87be03f12dd3c7f7662734ec2eaaa7f1f4b5b83c9bb0264c9e06609c2f8f0ef20106d3c8db8be45484
7
- data.tar.gz: 30a9a4dcf60a9aa0a25c4a64429e34f1f8cf6cf9609f80c94b675c0e498f74f46f3fc0842fab2d20ed248f0a792c2349a7373a273905ec45c3994b3b6f4fc3eb
6
+ metadata.gz: b86acc435cc02cdd0976361305331b4bf98b176fd25c8accb791cfba794c7bdf6d42d94d62cc76b11cb510e9c3ac23495ac99aa244e76a39e5e6e061aeeae4a8
7
+ data.tar.gz: 31f95548e2cb64bedb1781977222c705183c3e866ce8c8a9fb5532dfdbdeabe11d59faa92818c8506d5235d2fc868d1eb58d949b17ecc5f6c3d66bafde910750
data/CHANGES.md CHANGED
@@ -14,25 +14,28 @@ __Please update all installations of ruby-jss to at least v1.6.0.__
14
14
 
15
15
  Many many thanks to actae0n of Blacksun Hackers Club for reporting this issue and providing examples of how it could be exploited.
16
16
 
17
- ## \[2.1.0] - unreleased
17
+ ## \[2.1.0] - 2022-10-10
18
18
 
19
19
  ### Added
20
20
 
21
- - Support for the `/v1/jamf-management-framework/redeploy/{id}` Jamf Pro API endpoint in `Jamf::Computer` and
21
+ - Support for the `/v1/jamf-management-framework/redeploy/{id}` Jamf Pro API endpoint in `Jamf::Computer` and
22
22
  `Jamf::ComputerGroup`. The method `redeploy_mgmt_framework` is both a Class and an Instance method for those classes
23
23
  - The instance method sends the redeployment to the single computer or all the members of the single computer group.
24
- - The class method accepts a single id, or an array of ids.
24
+ - The class method accepts a single id, or an array of ids.
25
25
  - When using `Jamf::Computer.redeploy_mgmt_framework` provide computer ids
26
26
  - When using `Jamf::ComputerGroup.redeploy_mgmt_framework` provide group ids, and all members of all groups will get
27
27
  the redeployment
28
- - In all cases the result is a Hash of target computer ids (keys) and result value for each (Strings).
29
- - The result is either the UUID of the sent MDM command, or an error message if the MDM command couldn't be sent.
30
- - All the code is in the `Jamf::MacOSRedeployMgmtFramework` module, q.v. in the [rubydoc documentation](https://www.rubydoc.info/gems/ruby-jss/Jamf/MacOSRedeployMgmtFramework)
28
+ - In all cases the result is a Hash of target computer ids (keys) and result value for each (Strings).
29
+ - The result is either the UUID of the sent MDM command, or an error message if the MDM command couldn't be sent.
30
+ - All the code is in the `Jamf::MacOSRedeployMgmtFramework` module, q.v. in the [rubydoc documentation](https://www.rubydoc.info/gems/ruby-jss/Jamf/MacOSRedeployMgmtFramework)
31
31
 
32
32
  ### Fixed
33
33
 
34
34
  - A few internal rescues of a deprecated exception class
35
35
  - Removed auto-loading of deprecation files; now explicitly loaded.
36
+ - A few Ruby 2 => Ruby 3 bugs - method params needing double-splats (Thanks to @Timelost for reporting this one)
37
+ - Ensure resource paths don't start with a slash
38
+ - Setting the timeouts on an existing API connection object now works.
36
39
 
37
40
  ## \[2.0.0] - 2022-09-12
38
41
 
data/bin/cgrouper CHANGED
@@ -23,10 +23,8 @@
23
23
  ### KIND, either express or implied. See the Apache License for the specific
24
24
  ### language governing permissions and limitations under the Apache License.
25
25
 
26
-
27
26
  # Create or change the membership of a computer group in the JSS
28
27
 
29
-
30
28
  # Load in the JSS library
31
29
  require 'jss-api'
32
30
 
@@ -44,9 +42,9 @@ class App
44
42
  [-S server] [-U user] [-T timeout] [-V] [--debug]
45
43
  group [-f /file/path ] [computer [computer ...]]"
46
44
 
47
- ACTIONS_NEEDING_GROUP = [ :create_group, :rename_group, :delete_group, :add_members, :remove_members, :remove_all, :list_members]
45
+ ACTIONS_NEEDING_GROUP = %i[create_group rename_group delete_group add_members remove_members remove_all list_members]
48
46
 
49
- ACTIONS_FOR_STATIC_GROUPS_ONLY = [:create_group, :add_members, :remove_members, :remove_all]
47
+ ACTIONS_FOR_STATIC_GROUPS_ONLY = %i[create_group add_members remove_members remove_all]
50
48
 
51
49
  #####################################
52
50
  ### Attributes
@@ -57,31 +55,30 @@ class App
57
55
  ###
58
56
  ### set up
59
57
  ###
60
- def initialize(args)
61
-
58
+ def initialize
62
59
  @debug = false
63
60
 
64
61
  # define the options
65
62
  cli_opts = GetoptLong.new(
66
- [ '--help', '-h', '-H', GetoptLong::NO_ARGUMENT ],
67
- [ '--list-groups', '-L', GetoptLong::NO_ARGUMENT ],
68
- [ '--list-static', '-s', GetoptLong::NO_ARGUMENT ],
69
- [ '--list-smart', '-m', GetoptLong::NO_ARGUMENT ],
70
- [ '--create-group', '--create', '-c', GetoptLong::NO_ARGUMENT ],
71
- [ '--rename-group', '--rename', '-n', GetoptLong::REQUIRED_ARGUMENT ],
72
- [ '--delete-group', '--delete', '-d', GetoptLong::NO_ARGUMENT ],
73
- [ '--list-members', '--list-computers', '-l', GetoptLong::NO_ARGUMENT ],
74
- [ '--add-members', '--add', '-a', GetoptLong::NO_ARGUMENT ],
75
- [ '--remove-members', '--remove', '-r', GetoptLong::NO_ARGUMENT ],
76
- [ '--remove-all-members', '-R', GetoptLong::NO_ARGUMENT ],
77
- [ '--file', '-f', GetoptLong::REQUIRED_ARGUMENT ],
78
- [ '--server', '-S', GetoptLong::OPTIONAL_ARGUMENT],
79
- [ '--port', '-P', GetoptLong::OPTIONAL_ARGUMENT],
80
- [ '--user', '-U', GetoptLong::OPTIONAL_ARGUMENT],
81
- [ '--no-verify-cert', '-V', GetoptLong::NO_ARGUMENT],
82
- [ '--timeout', '-T', GetoptLong::OPTIONAL_ARGUMENT],
83
- [ '--no-confirm', '-C', GetoptLong::NO_ARGUMENT],
84
- [ '--debug', GetoptLong::NO_ARGUMENT]
63
+ ['--help', '-h', '-H', GetoptLong::NO_ARGUMENT],
64
+ ['--list-groups', '-L', GetoptLong::NO_ARGUMENT],
65
+ ['--list-static', '-s', GetoptLong::NO_ARGUMENT],
66
+ ['--list-smart', '-m', GetoptLong::NO_ARGUMENT],
67
+ ['--create-group', '--create', '-c', GetoptLong::NO_ARGUMENT],
68
+ ['--rename-group', '--rename', '-n', GetoptLong::REQUIRED_ARGUMENT],
69
+ ['--delete-group', '--delete', '-d', GetoptLong::NO_ARGUMENT],
70
+ ['--list-members', '--list-computers', '-l', GetoptLong::NO_ARGUMENT],
71
+ ['--add-members', '--add', '-a', GetoptLong::NO_ARGUMENT],
72
+ ['--remove-members', '--remove', '-r', GetoptLong::NO_ARGUMENT],
73
+ ['--remove-all-members', '-R', GetoptLong::NO_ARGUMENT],
74
+ ['--file', '-f', GetoptLong::REQUIRED_ARGUMENT],
75
+ ['--server', '-S', GetoptLong::OPTIONAL_ARGUMENT],
76
+ ['--port', '-P', GetoptLong::OPTIONAL_ARGUMENT],
77
+ ['--user', '-U', GetoptLong::OPTIONAL_ARGUMENT],
78
+ ['--no-verify-cert', '-V', GetoptLong::NO_ARGUMENT],
79
+ ['--timeout', '-T', GetoptLong::OPTIONAL_ARGUMENT],
80
+ ['--no-confirm', '-C', GetoptLong::NO_ARGUMENT],
81
+ ['--debug', GetoptLong::NO_ARGUMENT]
85
82
  )
86
83
 
87
84
  # here's where we hold cmdline args and other user options
@@ -92,68 +89,68 @@ class App
92
89
 
93
90
  # if stdin is not a tty, then we must assume
94
91
  # we're being passed a password
95
- @options.getpass = $stdin.tty? ? :prompt : :stdin
92
+ @options.getpass = $stdin.tty? ? :prompt : :stdin
96
93
 
97
94
  # parse the options
98
95
  cli_opts.each do |opt, arg|
99
96
  case opt
100
- when '--help'
101
- show_help
97
+ when '--help'
98
+ show_help
102
99
 
103
- when '--list-groups'
104
- @options.action = :list_groups
100
+ when '--list-groups'
101
+ @options.action = :list_groups
105
102
 
106
- when '--list-static'
107
- @options.action = :list_static
103
+ when '--list-static'
104
+ @options.action = :list_static
108
105
 
109
- when '--list-smart'
110
- @options.action = :list_smart
106
+ when '--list-smart'
107
+ @options.action = :list_smart
111
108
 
112
- when '--list-members'
113
- @options.action = :list_members
109
+ when '--list-members'
110
+ @options.action = :list_members
114
111
 
115
- when '--create-group'
116
- @options.action = :create_group
112
+ when '--create-group'
113
+ @options.action = :create_group
117
114
 
118
- when '--rename-group'
119
- @options.action = :rename_group
120
- @options.new_name = arg
115
+ when '--rename-group'
116
+ @options.action = :rename_group
117
+ @options.new_name = arg
121
118
 
122
- when '--delete-group'
123
- @options.action = :delete_group
119
+ when '--delete-group'
120
+ @options.action = :delete_group
124
121
 
125
- when '--add-members'
126
- @options.action = :add_members
122
+ when '--add-members'
123
+ @options.action = :add_members
127
124
 
128
- when '--remove-members'
129
- @options.action = :remove_members
125
+ when '--remove-members'
126
+ @options.action = :remove_members
130
127
 
131
- when '--remove-all-members'
132
- @options.action = :remove_all
128
+ when '--remove-all-members'
129
+ @options.action = :remove_all
133
130
 
134
- when '--file'
135
- @options.input_file = Pathname.new arg
131
+ when '--file'
132
+ @options.input_file = Pathname.new arg
136
133
 
137
- when '--server'
138
- @options.server = arg
134
+ when '--server'
135
+ @options.server = arg
139
136
 
140
- when '--port'
141
- @options.port = arg
137
+ when '--port'
138
+ @options.port = arg
142
139
 
143
- when '--user'
144
- @options.user = arg
140
+ when '--user'
141
+ @options.user = arg
145
142
 
146
- when '--no-verify-cert'
147
- @options.verify_cert = false
143
+ when '--no-verify-cert'
144
+ @options.verify_cert = false
148
145
 
149
- when '--timeout'
150
- @options.timeout = arg
146
+ when '--timeout'
147
+ @options.timeout = arg
151
148
 
152
- when '--no-confirm'
153
- @options.no_confirm = true
149
+ when '--no-confirm'
150
+ @options.no_confirm = true
154
151
 
155
- when '--debug'
156
- @debug = true
152
+ when '--debug'
153
+ @debug = true
157
154
 
158
155
  end # case
159
156
  end # opts.each
@@ -168,17 +165,13 @@ class App
168
165
 
169
166
  # will we say anything when finished?
170
167
  @done_msg = nil
171
-
172
168
  end # init
173
169
 
174
-
175
-
176
170
  #####################################
177
171
  ###
178
172
  ### Do It
179
173
  ###
180
174
  def run
181
-
182
175
  if @options.action == :none
183
176
  puts USAGE
184
177
  return
@@ -188,75 +181,73 @@ class App
188
181
  @options.user ||= JSS::CONFIG.api_username
189
182
  @options.server ||= JSS::CONFIG.api_server_name
190
183
 
191
- raise JSS::MissingDataError, "No JSS Username provided or found in the JSS gem config." unless @options.user
192
- raise JSS::MissingDataError, "No JSS Server provided or found in the JSS gem config." unless @options.server
193
-
194
- Jamf.cnx.connect( :server => @options.server,
195
- :port => @options.port,
196
- :verify_cert => @options.verify_cert,
197
- :user => @options.user,
198
- :pw => @options.getpass,
199
- :stdin_line => 1,
200
- :timeout => @options.timeout
201
- )
184
+ raise JSS::MissingDataError, 'No JSS Username provided or found in the JSS gem config.' unless @options.user
185
+ raise JSS::MissingDataError, 'No JSS Server provided or found in the JSS gem config.' unless @options.server
202
186
 
187
+ Jamf.cnx.connect(server: @options.server,
188
+ port: @options.port,
189
+ verify_cert: @options.verify_cert,
190
+ user: @options.user,
191
+ pw: @options.getpass,
192
+ stdin_line: 1,
193
+ timeout: @options.timeout)
203
194
 
204
195
  if ACTIONS_NEEDING_GROUP.include? @options.action
205
196
 
206
- raise JSS::MissingDataError, "Please specify a group name" unless @options.group
197
+ raise JSS::MissingDataError, 'Please specify a group name' unless @options.group
207
198
 
208
- # get the group from the API
209
- if @options.action == :create_group
210
- @group = JSS::ComputerGroup.make :name => @options.group, :type => :static
211
- else
212
- @group = JSS::ComputerGroup.fetch :name => @options.group
213
- end
199
+ # get the group from the API
200
+ @group = if @options.action == :create_group
201
+ JSS::ComputerGroup.make name: @options.group, type: :static
202
+ else
203
+ JSS::ComputerGroup.fetch name: @options.group
204
+ end
214
205
 
215
206
  end # if ACTIONS_NEEDING_GROUP
216
207
 
217
208
  # smart groups can't have some things done to them
218
- raise InvalidTypeError, "You can't do that to a smart group. Use the JSS WebApp if needed." if ACTIONS_FOR_STATIC_GROUPS_ONLY.include? @options.action and @group.smart?
219
-
209
+ if ACTIONS_FOR_STATIC_GROUPS_ONLY.include? @options.action and @group.smart?
210
+ raise InvalidTypeError,
211
+ "You can't do that to a smart group. Use the JSS WebApp if needed."
212
+ end
220
213
 
221
214
  case @options.action
222
215
 
223
- when :list_groups
224
- list_groups
216
+ when :list_groups
217
+ list_groups
225
218
 
226
- when :list_static
227
- list_groups :static
219
+ when :list_static
220
+ list_groups :static
228
221
 
229
- when :list_smart
230
- list_groups :smart
222
+ when :list_smart
223
+ list_groups :smart
231
224
 
232
- when :list_members
233
- list_members
225
+ when :list_members
226
+ list_members
234
227
 
235
- when :create_group
236
- create_group
228
+ when :create_group
229
+ create_group
237
230
 
238
- when :rename_group
239
- rename_group
231
+ when :rename_group
232
+ rename_group
240
233
 
241
- when :delete_group
242
- delete_group
234
+ when :delete_group
235
+ delete_group
243
236
 
244
- when :add_members
245
- add_members
237
+ when :add_members
238
+ add_members
246
239
 
247
- when :remove_members
248
- remove_members
240
+ when :remove_members
241
+ remove_members
249
242
 
250
- when :remove_all
251
- remove_all
243
+ when :remove_all
244
+ remove_all
252
245
 
253
246
  end # case @options.action
254
247
 
255
248
  puts "Done! #{@done_msg}" if @done_msg
256
-
257
249
  end # run
258
250
 
259
-
260
251
  #####################################
261
252
  ###
262
253
  ### Show Help
@@ -307,7 +298,6 @@ Notes:
307
298
  (spaces, tabs, & returns in any number or combination)
308
299
 
309
300
  FULLHELP
310
-
311
301
  end
312
302
 
313
303
  #####################################
@@ -316,21 +306,21 @@ Notes:
316
306
  ###
317
307
  def list_groups(show = :all)
318
308
  case show
319
- when :all
320
- label = "All"
321
- groups_to_show = JSS::ComputerGroup.all
322
- when :static
323
- label = "Static"
324
- groups_to_show = JSS::ComputerGroup.all_static
325
- when :smart
326
- label = "Smart"
327
- groups_to_show = JSS::ComputerGroup.all_smart
328
- end #case
309
+ when :all
310
+ label = 'All'
311
+ groups_to_show = JSS::ComputerGroup.all
312
+ when :static
313
+ label = 'Static'
314
+ groups_to_show = JSS::ComputerGroup.all_static
315
+ when :smart
316
+ label = 'Smart'
317
+ groups_to_show = JSS::ComputerGroup.all_smart
318
+ end # case
329
319
 
330
320
  puts "# #{label} computer groups in the JSS"
331
- puts "#---------------------------------------------"
321
+ puts '#---------------------------------------------'
332
322
 
333
- groups_to_show.sort{|a,b| a[:name].downcase <=> b[:name].downcase}.each do |grp|
323
+ groups_to_show.sort { |a, b| a[:name].downcase <=> b[:name].downcase }.each do |grp|
334
324
  puts grp[:name]
335
325
  end
336
326
  end
@@ -341,30 +331,26 @@ Notes:
341
331
  ###
342
332
  def list_members
343
333
  puts "# All members of JSS #{@group.smart? ? 'smart' : 'static'} computer group '#{@options.group}'"
344
- puts "#--- name (id) ---------------------------------"
334
+ puts '#--- name (id) ---------------------------------'
345
335
 
346
336
  # put them into a tmp array, so that
347
337
  # we can sort by computer name, remembering that
348
338
  # there can be duplicate names.
349
339
  list = []
350
- @group.members.each{|mem| list << "#{mem[:name]} (#{mem[:id]})" }
351
- puts list.sort #.join("\n")
340
+ @group.members.each { |mem| list << "#{mem[:name]} (#{mem[:id]})" }
341
+ puts list.sort # .join("\n")
352
342
  end
353
343
 
354
-
355
344
  #####################################
356
345
  ###
357
346
  ### Create a new group
358
347
  ###
359
348
  def create_group
360
-
361
349
  return unless confirm "create a new static group named '#{@options.group}'"
362
- @group.create
363
350
 
364
- unless @options.computers.empty?
365
- add_members
366
- end
351
+ @group.create
367
352
 
353
+ add_members unless @options.computers.empty?
368
354
  end
369
355
 
370
356
  #####################################
@@ -373,36 +359,35 @@ Notes:
373
359
  ###
374
360
  def rename_group
375
361
  return unless confirm "rename group '#{@group.name}' to '#{@options.new_name}'"
362
+
376
363
  @group.name = @options.new_name
377
364
  @group.update
378
365
  end
379
366
 
380
-
381
367
  #####################################
382
368
  ###
383
369
  ### delete a group
384
370
  ###
385
371
  def delete_group
386
372
  return unless confirm "DELETE group '#{@group.name}'"
373
+
387
374
  @group.delete
388
375
  end
389
376
 
390
-
391
377
  #####################################
392
378
  ###
393
379
  ### add members to a group
394
380
  ###
395
381
  def add_members
396
- raise JSS::MissingDataError, "No computer names provided" if @options.computers.empty?
382
+ raise JSS::MissingDataError, 'No computer names provided' if @options.computers.empty?
397
383
  raise JSS::UnsupportedError, "Smart group members can't be changed." if @group.smart?
398
384
  return unless @options.action == :create_group or confirm "add computers to group '#{@group.name}'"
399
385
 
400
386
  @options.computers.each do |c|
401
- begin
402
- @group.add_member c
403
- rescue JSS::NoSuchItemError
404
- puts "#{$!} - skipping"
405
- end # begin
387
+ @group.add_member c
388
+ rescue JSS::NoSuchItemError
389
+ puts "#{$!} - skipping"
390
+ # begin
406
391
  end # each
407
392
 
408
393
  @group.update
@@ -413,15 +398,14 @@ Notes:
413
398
  ### remove members from a group
414
399
  ###
415
400
  def remove_members
416
- raise JSS::MissingDataError, "No computer names provided" if @options.computers.empty?
401
+ raise JSS::MissingDataError, 'No computer names provided' if @options.computers.empty?
417
402
  raise JSS::UnsupportedError, "Smart group members can't be changed." if @group.smart?
418
403
  return unless confirm "remove computers from group '#{@group.name}'"
404
+
419
405
  @options.computers.each do |c|
420
- begin
421
- @group.remove_member c
422
- rescue JSS::NoSuchItemError
423
- puts "#{$!} - skipping"
424
- end
406
+ @group.remove_member c
407
+ rescue JSS::NoSuchItemError
408
+ puts "#{$!} - skipping"
425
409
  end
426
410
  @group.update
427
411
  end
@@ -433,11 +417,11 @@ Notes:
433
417
  def remove_all
434
418
  raise JSS::UnsupportedError, "Smart group members can't be changed." if @group.smart?
435
419
  return unless confirm "remove ALL computers from group '#{@group.name}'"
420
+
436
421
  @group.clear
437
422
  @group.update
438
423
  end
439
424
 
440
-
441
425
  #####################################
442
426
  ###
443
427
  ### Read computer names from a file
@@ -448,6 +432,7 @@ Notes:
448
432
  def get_computers_from_file
449
433
  raise JSS::NoSuchItemError "File #{@options.input_file} isn't a file or isn't readable." unless \
450
434
  @options.input_file.file? and @options.input_file.readable?
435
+
451
436
  @options.input_file.read.split(/\s+/)
452
437
  end
453
438
 
@@ -456,31 +441,26 @@ Notes:
456
441
  ### Get confirmation before doing something
457
442
  ### Returns true or false
458
443
  ###
459
- def confirm (action)
460
- return true if @options.no_confirm
444
+ def confirm(action)
445
+ return true if @options.no_confirm
461
446
 
462
- print "Really #{action}? (y/n): "
463
- $stdin.reopen '/dev/tty'
464
- reply = $stdin.gets.strip
465
- return true if reply =~ /^y/i
466
- return false
447
+ print "Really #{action}? (y/n): "
448
+ $stdin.reopen '/dev/tty'
449
+ reply = $stdin.gets.strip
450
+ return true if reply =~ /^y/i
467
451
 
452
+ false
468
453
  end # confirm
469
454
 
470
-
471
455
  end # class App
472
456
 
473
457
  #######################################
474
458
  begin
475
- app = App.new(ARGV)
459
+ app = App.new
476
460
  app.run
477
-
478
461
  rescue
479
462
  # handle exceptions not handled elsewhere
480
463
  puts "An error occurred: #{$!}"
481
- puts "Backtrace:" if app.debug
464
+ puts 'Backtrace:' if app.debug
482
465
  puts $@ if app.debug
483
-
484
- ensure
485
-
486
466
  end
@@ -53,7 +53,7 @@ class App
53
53
 
54
54
  # Set up
55
55
  #
56
- def initialize(args)
56
+ def initialize(**args)
57
57
  if args.include? '-help'
58
58
  @help = true
59
59
  return
@@ -66,6 +66,7 @@ class App
66
66
 
67
67
  wintype_idx = args.index { |a| a == WIN_TYPE_PARAM }
68
68
  raise 'missing option: -windowType' unless wintype_idx
69
+
69
70
  args.delete_at wintype_idx
70
71
  @window_type = args.delete_at(wintype_idx).to_sym
71
72
 
@@ -93,6 +94,7 @@ class App
93
94
 
94
95
  if @as_user
95
96
  raise 'Only root can do things as another user' unless JSS.superuser?
97
+
96
98
  cmd = ['su', '-l', @as_user, '-c', "#{Shellwords.escape __FILE__} #{@arg_string}"]
97
99
  exec(*cmd)
98
100
  end
@@ -134,7 +136,7 @@ This command takes all the same commandline options as jamfHelper, plus these:
134
136
  WARNING: You shouldn't run this command directly as a launchd job. Rather
135
137
  you should write a small script that runs this command, and use launchd
136
138
  to run that.
137
- ENDHELP
139
+ ENDHELP
138
140
  end # show help
139
141
 
140
142
  end # app
data/bin/netseg-update CHANGED
@@ -55,13 +55,13 @@ class App
55
55
 
56
56
  USAGE = "Usage: #{PROG_NAME} [options] [--help] /path/to/file".freeze
57
57
 
58
- POTENTIAL_COLUMNS = %i(name starting ending cidr mask).freeze
58
+ POTENTIAL_COLUMNS = %i[name starting ending cidr mask].freeze
59
59
 
60
60
  DEFAULT_CACHE_FILE = Pathname.new('~/.last_subnet_update').expand_path
61
61
 
62
62
  DEFAULT_DELIMITER = "\t".freeze
63
63
 
64
- DEFAULT_COLUMNS = [:name, :starting, :ending].freeze
64
+ DEFAULT_COLUMNS = %i[name starting ending].freeze
65
65
 
66
66
  DEFAULT_MANUAL_PREFIX = 'Manual-'.freeze
67
67
 
@@ -84,7 +84,7 @@ class App
84
84
 
85
85
  attr_reader :debug
86
86
 
87
- def initialize(_args)
87
+ def initialize
88
88
  @getpass = $stdin.tty? ? :prompt : :stdin
89
89
  set_defaults
90
90
  parse_cli
@@ -183,7 +183,7 @@ Options:
183
183
  -V, --no-verify-cert - Allow self-signed, unverified SSL certificate
184
184
  -T, --timeout secs - specify the JSS API timeout
185
185
  -N, --no-op - Don't make any changes in the JSS, just report what would
186
- have be changed.
186
+ have been changed.
187
187
  -H, --help - show this help
188
188
  --debug - show the ruby backtrace when errors occur
189
189
 
@@ -254,6 +254,7 @@ Notes:
254
254
  lines.each do |line|
255
255
  parsed_line = parse_a_data_line line
256
256
  next unless parsed_line
257
+
257
258
  name = parsed_line.delete :name
258
259
  parsed_data[name] = parsed_line
259
260
  end
@@ -273,6 +274,7 @@ Notes:
273
274
  @columns.include?(:ending) || \
274
275
  @columns.include?(:cidr) || \
275
276
  @columns.include?(:mask)
277
+
276
278
  @use_cidr = (@columns.include?(:cidr) || @columns.include?(:mask))
277
279
  end
278
280
 
@@ -296,11 +298,13 @@ Notes:
296
298
  # read in the file
297
299
  @raw_data = @file.read
298
300
  return true unless @cache_file.exist?
301
+
299
302
  @raw_data != @cache_file.read
300
303
  end
301
304
 
302
305
  def cache_latest_data
303
306
  return if @noop
307
+
304
308
  @cache_file.jss_save @raw_data
305
309
  end
306
310
 
@@ -375,7 +379,7 @@ end # app
375
379
  # create the app and go
376
380
  begin
377
381
  debug = ARGV.include? '--debug'
378
- app = App.new(ARGV)
382
+ app = App.new
379
383
  app.run
380
384
  rescue
381
385
  # handle exceptions not handled elsewhere
@@ -440,7 +440,7 @@ module Jamf
440
440
  cnx = api if api
441
441
 
442
442
  id = valid_id ident, cnx: cnx
443
- raise "No computer matches identifier: #{ident}" unless id
443
+ raise Jamf::NoSuchItemError, "No computer matches identifier: #{ident}" unless id
444
444
 
445
445
  end_date ||= start_date
446
446
  start_date = Jamf.parse_time start_date
@@ -194,7 +194,7 @@ module Jamf
194
194
  #
195
195
  # See Jamf::APIObject#initialize
196
196
  #
197
- def initialize(args)
197
+ def initialize(**args)
198
198
  super
199
199
  general = @init_data[:general]
200
200
  @display_name = general[:display_name]
@@ -154,7 +154,7 @@ module Jamf
154
154
  # when fetching a specific version, this is a valid version
155
155
  UNKNOWN_VERSION_ID = 'Unknown'.freeze
156
156
 
157
- REPORTS_RSRC_BASE = '/patchreports/patchsoftwaretitleid'.freeze
157
+ REPORTS_RSRC_BASE = 'patchreports/patchsoftwaretitleid'.freeze
158
158
 
159
159
  # Class Methods
160
160
  #######################################
@@ -233,7 +233,7 @@ module Jamf
233
233
  all(refresh, cnx: cnx).map { |i| i[:source_name_id] }
234
234
  end
235
235
 
236
- # Get a patch report for a softwaretitle, withouth fetching an instance.
236
+ # Get a patch report for a softwaretitle, without fetching an instance.
237
237
  # Defaults to reporting all versions. Specifiying a version will be faster.
238
238
  #
239
239
  # The Hash returned has 3 keys:
@@ -269,6 +269,7 @@ module Jamf
269
269
 
270
270
  # TODO: remove this and adjust parsing when jamf fixes the JSON
271
271
  raw_report = XMLWorkaround.data_via_xml(rsrc, PATCH_REPORT_DATA_MAP, cnx)[:patch_report]
272
+
272
273
  report = {}
273
274
  report[:total_computers] = raw_report[:total_computers]
274
275
  report[:total_versions] = raw_report[:total_versions]
@@ -312,7 +313,7 @@ module Jamf
312
313
  # so all other lookup values have to be converted to ID before
313
314
  # the call to super
314
315
  #
315
- def self.fetch(identifier = nil, **params)
316
+ def self.fetch(identifier = nil, **params)
316
317
  # default connection if unspecified
317
318
  cnx = params.delete :cnx
318
319
  cnx ||= params.delete :api # backward compatibility, deprecated
@@ -472,7 +473,6 @@ module Jamf
472
473
  # wrapper to fetch versions after creating
473
474
  def create
474
475
  super
475
-
476
476
  end
477
477
 
478
478
  # wrapper to clear @changed_pkgs after updating
@@ -150,7 +150,8 @@ module Jamf
150
150
  element ? element.text.to_f : model
151
151
  when nil
152
152
  return nil unless element
153
- element.text.downcase == TRUE_STRING ? true : false
153
+
154
+ element.text.downcase == TRUE_STRING
154
155
  when Array
155
156
  element ? elem_as_array(model.first, element) : []
156
157
  when Hash
@@ -176,6 +177,7 @@ module Jamf
176
177
  return unless size_elems.count == 1
177
178
  return if size_elem.has_elements?
178
179
  return unless size_elem.text.jss_integer?
180
+
179
181
  elem.delete_element size_elem
180
182
  end
181
183
 
@@ -74,15 +74,15 @@ module Jamf
74
74
  attr_reader :sticky_session
75
75
  alias sticky_session? sticky_session
76
76
  alias sticky? sticky_session
77
-
77
+
78
78
  # @return [String, nil] The current sticky_session cookie. nil unless
79
79
  # sticky_session is set to true, either as a param to 'connect' or via
80
80
  # #sticky_session=
81
81
  #
82
- # When set via .connect, the cookie is gleaned from the token creation
82
+ # When set via .connect, the cookie is gleaned from the token creation
83
83
  # reponse. When set via #sticky_session=, a HEAD request is made, and the
84
84
  # cookie will be in the response.
85
- #
85
+ #
86
86
  # Only valid when the connection is to a Jamf Cloud server.
87
87
  attr_reader :sticky_session_cookie
88
88
 
@@ -100,7 +100,7 @@ module Jamf
100
100
 
101
101
  # convert boolean-y to boolean
102
102
  value = value ? true : false
103
-
103
+
104
104
  return if @sticky_session == value
105
105
 
106
106
  if value
@@ -125,8 +125,8 @@ module Jamf
125
125
  #
126
126
  def timeout=(new_timeout)
127
127
  @timeout = new_timeout.to_i
128
- @c_cnx&.options[:timeout] = @timeout
129
- @jp_cnx&.options[:timeout] = @timeout
128
+ @c_cnx.options.timeout = @timeout if @c_cnx
129
+ @jp_cnx.options.timeout = @timeout if @jp_cnx
130
130
  end
131
131
 
132
132
  # Reset the open-connection timeout for the rest connection
@@ -137,8 +137,8 @@ module Jamf
137
137
  #
138
138
  def open_timeout=(new_timeout)
139
139
  @open_timeout = new_timeout.to_i
140
- @c_cnx&.options[:open_timeout] = @open_timeout
141
- @jp_cnx&.options[:open_timeout] = @open_timeout
140
+ @c_cnx.options.open_timeout = @open_timeout if @c_cnx
141
+ @jp_cnx.options.open_timeout = @open_timeout if @jp_cnx
142
142
  end
143
143
 
144
144
  # @return [URI::HTTPS] the base URL to the server
@@ -59,6 +59,8 @@ module Jamf
59
59
  # @return [Hash,String] the result of the get
60
60
  #
61
61
  def c_get(rsrc, format = :json, raw_json: false)
62
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
63
+
62
64
  validate_connected @c_cnx
63
65
  raise Jamf::InvalidDataError, 'format must be :json or :xml' unless Jamf::Connection::GET_FORMATS.include?(format)
64
66
 
@@ -92,6 +94,8 @@ module Jamf
92
94
  def c_post(rsrc, xml)
93
95
  validate_connected @c_cnx
94
96
 
97
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
98
+
95
99
  # convert CRs & to &#13;
96
100
  xml&.gsub!(/\r/, '&#13;')
97
101
 
@@ -125,6 +129,8 @@ module Jamf
125
129
  def c_put(rsrc, xml)
126
130
  validate_connected @c_cnx
127
131
 
132
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
133
+
128
134
  # convert CRs & to &#13;
129
135
  xml.gsub!(/\r/, '&#13;')
130
136
 
@@ -157,6 +163,8 @@ module Jamf
157
163
  validate_connected @c_cnx
158
164
  raise MissingDataError, 'Missing :rsrc' if rsrc.nil?
159
165
 
166
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
167
+
160
168
  # delete the resource
161
169
  resp =
162
170
  @c_cnx.delete(rsrc) do |req|
@@ -188,6 +196,7 @@ module Jamf
188
196
  #
189
197
  def upload(rsrc, local_file)
190
198
  validate_connected @c_cnx
199
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
191
200
 
192
201
  # the upload file object for faraday
193
202
  local_file = Pathname.new local_file
@@ -223,7 +232,7 @@ module Jamf
223
232
 
224
233
  cnx.options[:timeout] = @timeout
225
234
  cnx.options[:open_timeout] = @open_timeout
226
-
235
+
227
236
  cnx.request :multipart
228
237
  cnx.request :url_encoded
229
238
 
@@ -87,6 +87,8 @@ module Jamf
87
87
  MIME_JSON = 'application/json'.freeze
88
88
  MIME_XML = 'application/xml'.freeze
89
89
 
90
+ SLASH = '/'
91
+
90
92
  # Only these variables are displayed with PrettyPrint
91
93
  # This avoids, especially, the caches, which are available
92
94
  # as attr_readers
@@ -53,11 +53,12 @@ module Jamf
53
53
 
54
54
  # @param rsrc[String] the resource to get
55
55
  # (the part of the API url after the '/api/' )
56
-
56
+
57
57
  # @return [Hash] the result of the get
58
58
  #######################################################
59
59
  def jp_get(rsrc)
60
60
  validate_connected @jp_cnx
61
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
61
62
  resp = @jp_cnx.get(rsrc) do |req|
62
63
  # Modify the request here if needed.
63
64
  # puts "JPAPI Cookie is: #{req.headers['Cookie']}"
@@ -82,6 +83,7 @@ module Jamf
82
83
  #######################################################
83
84
  def jp_post(rsrc, data)
84
85
  validate_connected @jp_cnx
86
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
85
87
  resp = @jp_cnx.post(rsrc) do |req|
86
88
  req.body = data
87
89
  end
@@ -104,6 +106,7 @@ module Jamf
104
106
  #######################################################
105
107
  def jp_put(rsrc, data)
106
108
  validate_connected @jp_cnx
109
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
107
110
  resp = @jp_cnx.put(rsrc) do |req|
108
111
  req.body = data
109
112
  end
@@ -126,6 +129,7 @@ module Jamf
126
129
  #######################################################
127
130
  def jp_patch(rsrc, data)
128
131
  validate_connected @jp_cnx
132
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
129
133
  resp = @jp_cnx.patch(rsrc) do |req|
130
134
  req.body = data
131
135
  end
@@ -146,6 +150,7 @@ module Jamf
146
150
  #######################################################
147
151
  def jp_delete(rsrc)
148
152
  validate_connected @jp_cnx
153
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
149
154
  resp = @jp_cnx.delete rsrc
150
155
  @last_http_response = resp
151
156
  return resp.body if resp.success?
@@ -159,6 +164,7 @@ module Jamf
159
164
  # a temporary Faraday connection object
160
165
  #######################################################
161
166
  def jp_download(rsrc)
167
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
162
168
  temp_cnx = create_jp_connection(parse_json: false)
163
169
  resp = temp_cnx.get rsrc
164
170
  @last_http_response = resp
data/lib/jamf/version.rb CHANGED
@@ -27,6 +27,6 @@
27
27
  module Jamf
28
28
 
29
29
  ### The version of ruby-jss
30
- VERSION = '2.1.0b4'.freeze
30
+ VERSION = '2.1.0'.freeze
31
31
 
32
32
  end # module
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-jss
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0b4
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Lasell
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-09-15 00:00:00.000000000 Z
13
+ date: 2022-10-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: CFPropertyList
@@ -824,9 +824,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
824
824
  version: 2.6.3
825
825
  required_rubygems_version: !ruby/object:Gem::Requirement
826
826
  requirements:
827
- - - ">"
827
+ - - ">="
828
828
  - !ruby/object:Gem::Version
829
- version: 1.3.1
829
+ version: '0'
830
830
  requirements: []
831
831
  rubygems_version: 3.0.3.1
832
832
  signing_key: