ruby-jss 2.1.0b4 → 2.1.0

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.
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: