xolo-server 1.0.1 → 2.0.3
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 +4 -4
- data/data/client/xolo +182 -82
- data/lib/xolo/core/base_classes/title.rb +261 -20
- data/lib/xolo/core/base_classes/version.rb +53 -8
- data/lib/xolo/core/constants.rb +7 -3
- data/lib/xolo/core/security_cmd.rb +128 -0
- data/lib/xolo/core/version.rb +1 -1
- data/lib/xolo/core.rb +1 -0
- data/lib/xolo/server/app.rb +7 -0
- data/lib/xolo/server/configuration.rb +243 -37
- data/lib/xolo/server/constants.rb +10 -0
- data/lib/xolo/server/helpers/auth.rb +19 -2
- data/lib/xolo/server/helpers/autopkg.rb +170 -0
- data/lib/xolo/server/helpers/client_data.rb +91 -61
- data/lib/xolo/server/helpers/file_transfers.rb +412 -82
- data/lib/xolo/server/helpers/jamf_pro.rb +30 -7
- data/lib/xolo/server/helpers/log.rb +2 -0
- data/lib/xolo/server/helpers/maintenance.rb +1 -0
- data/lib/xolo/server/helpers/notification.rb +4 -3
- data/lib/xolo/server/helpers/pkg_signing.rb +16 -12
- data/lib/xolo/server/helpers/progress_streaming.rb +9 -12
- data/lib/xolo/server/helpers/subscriptions.rb +119 -0
- data/lib/xolo/server/helpers/titles.rb +27 -3
- data/lib/xolo/server/helpers/versions.rb +23 -11
- data/lib/xolo/server/mixins/changelog.rb +9 -16
- data/lib/xolo/server/mixins/title_jamf_access.rb +395 -383
- data/lib/xolo/server/mixins/title_ted_access.rb +29 -3
- data/lib/xolo/server/mixins/version_jamf_access.rb +185 -159
- data/lib/xolo/server/mixins/version_ted_access.rb +25 -0
- data/lib/xolo/server/object_locks.rb +2 -1
- data/lib/xolo/server/routes/auth.rb +2 -2
- data/lib/xolo/server/routes/jamf_pro.rb +11 -1
- data/lib/xolo/server/routes/maint.rb +2 -1
- data/lib/xolo/server/routes/subscriptions.rb +126 -0
- data/lib/xolo/server/routes/title_editor.rb +1 -1
- data/lib/xolo/server/routes/titles.rb +30 -17
- data/lib/xolo/server/routes/uploads.rb +0 -14
- data/lib/xolo/server/routes/versions.rb +22 -17
- data/lib/xolo/server/routes.rb +9 -0
- data/lib/xolo/server/title.rb +107 -78
- data/lib/xolo/server/tmp_overrides.rb +38 -0
- data/lib/xolo/server/version.rb +193 -15
- data/lib/xolo/server.rb +12 -0
- metadata +8 -9
|
@@ -65,6 +65,11 @@ module Xolo
|
|
|
65
65
|
# @return [Windoo::SoftwareTitle]
|
|
66
66
|
##########################
|
|
67
67
|
def create_title_in_ted
|
|
68
|
+
if subscribed?
|
|
69
|
+
log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor creation"
|
|
70
|
+
return
|
|
71
|
+
end
|
|
72
|
+
|
|
68
73
|
# delete an old one if its there
|
|
69
74
|
ted_title&.delete if Windoo::SoftwareTitle.all_ids(cnx: ted_cnx).include? title
|
|
70
75
|
|
|
@@ -173,6 +178,10 @@ module Xolo
|
|
|
173
178
|
# @return [void]
|
|
174
179
|
##########################
|
|
175
180
|
def update_title_in_ted
|
|
181
|
+
if subscribed?
|
|
182
|
+
log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor update"
|
|
183
|
+
return
|
|
184
|
+
end
|
|
176
185
|
return unless changes_for_update
|
|
177
186
|
|
|
178
187
|
unless any_ted_changes?
|
|
@@ -217,10 +226,12 @@ module Xolo
|
|
|
217
226
|
req_change = requirement_change
|
|
218
227
|
return unless req_change
|
|
219
228
|
|
|
220
|
-
new_app_name = changes_for_update.dig :app_name, :new
|
|
221
|
-
new_app_bundle_id = changes_for_update.dig :app_bundle_id, :new
|
|
222
229
|
new_ea_script = changes_for_update.dig :version_script, :new
|
|
223
230
|
|
|
231
|
+
# if either of these are nil in changes, then use the existing value
|
|
232
|
+
new_app_name = changes_for_update.dig(:app_name, :new) || app_name
|
|
233
|
+
new_app_bundle_id = changes_for_update.dig(:app_bundle_id, :new) || app_bundle_id
|
|
234
|
+
|
|
224
235
|
case req_change
|
|
225
236
|
when :app_to_ea
|
|
226
237
|
# create the ea
|
|
@@ -241,6 +252,7 @@ module Xolo
|
|
|
241
252
|
when :update_app
|
|
242
253
|
# set the requirement to use the new app data
|
|
243
254
|
set_ted_title_requirement app_name: new_app_name, app_bundle_id: new_app_bundle_id
|
|
255
|
+
|
|
244
256
|
# for all versions, update the patch compotent criteria to use the new app data
|
|
245
257
|
set_ted_patch_component_criteria_after_update app_name: new_app_name, app_bundle_id: new_app_bundle_id
|
|
246
258
|
|
|
@@ -292,11 +304,19 @@ module Xolo
|
|
|
292
304
|
end
|
|
293
305
|
end
|
|
294
306
|
|
|
307
|
+
# In the TitleEditor, the version script is
|
|
308
|
+
# stored as an Extension Attribute - each title can
|
|
309
|
+
# only have one.
|
|
310
|
+
# and it needs a 'key', which is the name used to indicate the
|
|
311
|
+
# EA in various criteria, and is the EA name in Jamf Patch.
|
|
312
|
+
# The key is jamf_obj_name_pfx on the title
|
|
313
|
+
# so for title 'foobar', it is 'xolo-foobar' or 'xolotest-foobar' for test servers
|
|
314
|
+
# That value is also used as the display name
|
|
295
315
|
# @return [String] The key and display name of a version script stored
|
|
296
316
|
# in the title editor as the ExtAttr for this title
|
|
297
317
|
#####################
|
|
298
318
|
def ted_ea_key
|
|
299
|
-
@ted_ea_key ||=
|
|
319
|
+
@ted_ea_key ||= "#{jamf_obj_name_pfx_base}#{title}"
|
|
300
320
|
end
|
|
301
321
|
|
|
302
322
|
# Create the EA in the Title Editor
|
|
@@ -470,6 +490,8 @@ module Xolo
|
|
|
470
490
|
# @return [String] the URL for the title in the Title Editor
|
|
471
491
|
#####################
|
|
472
492
|
def ted_title_url
|
|
493
|
+
return unless managed?
|
|
494
|
+
|
|
473
495
|
"https://#{Xolo::Server.config.ted_hostname}/softwaretitles/#{ted_id_number}"
|
|
474
496
|
end
|
|
475
497
|
|
|
@@ -482,6 +504,10 @@ module Xolo
|
|
|
482
504
|
# @return [void]
|
|
483
505
|
############################
|
|
484
506
|
def repair_ted_title
|
|
507
|
+
if subscribed?
|
|
508
|
+
log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor repair"
|
|
509
|
+
return
|
|
510
|
+
end
|
|
485
511
|
progress "Title Editor: Repairing SoftwareTitle '#{title}'", log: :info
|
|
486
512
|
|
|
487
513
|
# TODO: version order??
|
|
@@ -26,29 +26,24 @@ module Xolo
|
|
|
26
26
|
|
|
27
27
|
# The group of macs with this version installed
|
|
28
28
|
# is named the full prefix plus this suffix.
|
|
29
|
-
JAMF_SMART_GROUP_NAME_INSTALLED_SFX = '
|
|
29
|
+
JAMF_SMART_GROUP_NAME_INSTALLED_SFX = 'installed'
|
|
30
30
|
|
|
31
31
|
# The policy that does initial installs on-demand
|
|
32
32
|
# (via 'xolo install <title> <version') is named the full
|
|
33
33
|
# prefix plus this suffix.
|
|
34
|
-
JAMF_POLICY_NAME_MANUAL_INSTALL_SFX = '
|
|
34
|
+
JAMF_POLICY_NAME_MANUAL_INSTALL_SFX = 'manual-install'
|
|
35
35
|
|
|
36
36
|
# The policy that does auto-installs is named the full
|
|
37
37
|
# prefix plus this suffix.
|
|
38
38
|
# The scope is changed as needed when a version's status
|
|
39
39
|
# changes
|
|
40
|
-
JAMF_POLICY_NAME_AUTO_INSTALL_SFX = '
|
|
40
|
+
JAMF_POLICY_NAME_AUTO_INSTALL_SFX = 'auto-install'
|
|
41
41
|
|
|
42
42
|
# The policy that does auto-re-installs is named the full
|
|
43
43
|
# prefix plus this suffix.
|
|
44
44
|
# The scope is changed as needed when a version's status
|
|
45
45
|
# changes
|
|
46
|
-
JAMF_POLICY_NAME_AUTO_REINSTALL_SFX = '
|
|
47
|
-
|
|
48
|
-
# How long to wait after a pkg re-upload before creating/enabling/flushing
|
|
49
|
-
# the auto-reinstall policy
|
|
50
|
-
# See TODO in #wait_to_enable_reinstall_policy
|
|
51
|
-
JAMF_AUTO_REINSTALL_WAIT_SECS = 15 * 60
|
|
46
|
+
JAMF_POLICY_NAME_AUTO_REINSTALL_SFX = 'auto-reinstall'
|
|
52
47
|
|
|
53
48
|
# POLICIES, PATCH POLICIES, SCOPING
|
|
54
49
|
#############################
|
|
@@ -197,7 +192,11 @@ module Xolo
|
|
|
197
192
|
jamf_auto_install_policy
|
|
198
193
|
jamf_manual_install_policy
|
|
199
194
|
|
|
200
|
-
|
|
195
|
+
if subscribed?
|
|
196
|
+
activate_subscribed_patch_version_in_jamf
|
|
197
|
+
else
|
|
198
|
+
activate_managed_patch_version_in_jamf
|
|
199
|
+
end
|
|
201
200
|
end
|
|
202
201
|
|
|
203
202
|
# Apply edits to the Xolo version to Jamf as needed
|
|
@@ -213,16 +212,7 @@ module Xolo
|
|
|
213
212
|
update_jamf_pkg_reboot if changes_for_update&.key? :reboot
|
|
214
213
|
update_jamf_pkg_min_os if changes_for_update&.key? :min_os
|
|
215
214
|
|
|
216
|
-
|
|
217
|
-
#
|
|
218
|
-
# - the group exists AND
|
|
219
|
-
# - the title has changed how it determines installed versions, e.g. by adding or
|
|
220
|
-
# changing a version_script or app_bundle_id
|
|
221
|
-
# Changing those is very rare, and ill-advised, so we will implement
|
|
222
|
-
# this later.
|
|
223
|
-
#
|
|
224
|
-
# if jamf_installed_group_exist?
|
|
225
|
-
# end
|
|
215
|
+
update_jamf_patch_policy_patch_unknown if changes_for_update&.key? :patch_unknown
|
|
226
216
|
end
|
|
227
217
|
|
|
228
218
|
# Validate and fix any Jamf::JPackage objects that
|
|
@@ -276,8 +266,6 @@ module Xolo
|
|
|
276
266
|
# Delete package object
|
|
277
267
|
# This is slow and it blocks, so do it in a thread and update progress every
|
|
278
268
|
# 15 secs
|
|
279
|
-
return unless Jamf::JPackage.valid_id packageName: jamf_pkg_name, cnx: jamf_cnx
|
|
280
|
-
|
|
281
269
|
delete_jamf_package
|
|
282
270
|
|
|
283
271
|
# The code below is used when we want real-time progress updates to xadm
|
|
@@ -321,6 +309,8 @@ module Xolo
|
|
|
321
309
|
@jamf_package =
|
|
322
310
|
if id
|
|
323
311
|
log_debug "Jamf: Fetching Jamf::JPackage '#{id}'"
|
|
312
|
+
self.jamf_pkg_id = id # in case we only had the name before, now we have the id, so save it
|
|
313
|
+
save_local_data
|
|
324
314
|
Jamf::JPackage.fetch id: id, cnx: jamf_cnx
|
|
325
315
|
else
|
|
326
316
|
return if deleting?
|
|
@@ -329,10 +319,16 @@ module Xolo
|
|
|
329
319
|
end
|
|
330
320
|
end
|
|
331
321
|
|
|
322
|
+
# @return [Boolean] does the jamf_package exist?
|
|
323
|
+
#########################
|
|
324
|
+
def jamf_package_exist?
|
|
325
|
+
!Jamf::JPackage.valid_id(packageName: jamf_pkg_name, cnx: jamf_cnx).nil?
|
|
326
|
+
end
|
|
327
|
+
|
|
332
328
|
# @return [Jamf::JPackage] Create the Jamf::JPackage object for this version and return it
|
|
333
329
|
#########################
|
|
334
330
|
def create_jamf_package
|
|
335
|
-
progress "Jamf: Creating
|
|
331
|
+
progress "Jamf: Creating Jamf::JPackage '#{jamf_pkg_name}'", log: :info
|
|
336
332
|
|
|
337
333
|
# The filename is temporary, and will be replaced when the file is uploaded
|
|
338
334
|
pkg = Jamf::JPackage.create(
|
|
@@ -406,6 +402,19 @@ module Xolo
|
|
|
406
402
|
jamf_package.save
|
|
407
403
|
end
|
|
408
404
|
|
|
405
|
+
# update the :patch_unknown for the patch policy
|
|
406
|
+
# @return [void]
|
|
407
|
+
##############################
|
|
408
|
+
def update_jamf_patch_policy_patch_unknown
|
|
409
|
+
return unless changes_for_update&.key? :patch_unknown
|
|
410
|
+
|
|
411
|
+
ppol = jamf_patch_policy
|
|
412
|
+
action = changes_for_update[:patch_unknown][:new] ? 'Enabling' : 'Disabling'
|
|
413
|
+
progress "Jamf: #{action} 'patch_unknown' for patch policy #{ppol.name}", log: :debug
|
|
414
|
+
ppol.patch_unknown = changes_for_update[:patch_unknown][:new] ? true : false
|
|
415
|
+
ppol.save
|
|
416
|
+
end
|
|
417
|
+
|
|
409
418
|
# repair the package object only
|
|
410
419
|
#############################
|
|
411
420
|
def repair_jamf_package
|
|
@@ -442,13 +451,13 @@ module Xolo
|
|
|
442
451
|
# @return [void]
|
|
443
452
|
#########################
|
|
444
453
|
def delete_jamf_package
|
|
445
|
-
pkg_id = Jamf::JPackage.valid_id
|
|
454
|
+
pkg_id = jamf_pkg_id || Jamf::JPackage.valid_id(packageName: jamf_pkg_name, cnx: jamf_cnx)
|
|
446
455
|
return unless pkg_id
|
|
447
456
|
|
|
448
457
|
msg = "Jamf: Starting deletion of Package '#{jamf_pkg_name}' id #{jamf_pkg_id} at #{Time.now.strftime '%F %T'}"
|
|
449
458
|
progress msg, log: :info
|
|
450
459
|
|
|
451
|
-
warning = +"IMPORTANT: Package deletion
|
|
460
|
+
warning = +"IMPORTANT: Package deletion can be slow. If you plan to re-add this version, '#{version}', please\n "
|
|
452
461
|
warning <<
|
|
453
462
|
if Xolo::Server.config.alert_tool
|
|
454
463
|
'check your Xolo alerts for completion, which can take up to 5 minutes,'
|
|
@@ -685,8 +694,6 @@ module Xolo
|
|
|
685
694
|
)
|
|
686
695
|
else
|
|
687
696
|
return if deleting?
|
|
688
|
-
# don't create unless there's been a re-upload of the pkg
|
|
689
|
-
return unless reupload_date
|
|
690
697
|
|
|
691
698
|
create_jamf_installed_group
|
|
692
699
|
end
|
|
@@ -736,51 +743,20 @@ module Xolo
|
|
|
736
743
|
# The criteria for the smart group in Jamf that contains all Macs
|
|
737
744
|
# with this version of this title installed
|
|
738
745
|
#
|
|
739
|
-
#
|
|
740
|
-
#
|
|
746
|
+
# We use the "Patch Reporting: #{title_object.display_name}" criterion so that we don't
|
|
747
|
+
# care whether the title uses a version-script or app data.
|
|
741
748
|
#
|
|
742
749
|
# @return [Array<Jamf::Criteriable::Criterion>]
|
|
743
750
|
###################################
|
|
744
751
|
def jamf_installed_group_criteria
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
),
|
|
754
|
-
|
|
755
|
-
Jamf::Criteriable::Criterion.new(
|
|
756
|
-
and_or: :and,
|
|
757
|
-
name: 'Application Bundle ID',
|
|
758
|
-
search_type: 'is',
|
|
759
|
-
value: title_object.app_bundle_id
|
|
760
|
-
),
|
|
761
|
-
|
|
762
|
-
Jamf::Criteriable::Criterion.new(
|
|
763
|
-
and_or: :and,
|
|
764
|
-
name: 'Application Version',
|
|
765
|
-
search_type: 'is',
|
|
766
|
-
value: version
|
|
767
|
-
)
|
|
768
|
-
]
|
|
769
|
-
|
|
770
|
-
# if not, it must have a version script
|
|
771
|
-
elsif title_object.version_script
|
|
772
|
-
[
|
|
773
|
-
Jamf::Criteriable::Criterion.new(
|
|
774
|
-
and_or: :and,
|
|
775
|
-
name: title_object.jamf_normal_ea_name,
|
|
776
|
-
search_type: 'is',
|
|
777
|
-
value: version
|
|
778
|
-
)
|
|
779
|
-
]
|
|
780
|
-
|
|
781
|
-
else
|
|
782
|
-
raise Xolo::Core::Exceptions::InvalidDataError, "Title #{title} has neither a version_script nor a defined app bundle."
|
|
783
|
-
end
|
|
752
|
+
[
|
|
753
|
+
Jamf::Criteriable::Criterion.new(
|
|
754
|
+
and_or: :or,
|
|
755
|
+
name: "Patch Reporting: #{title_object.display_name}",
|
|
756
|
+
search_type: 'is',
|
|
757
|
+
value: version
|
|
758
|
+
)
|
|
759
|
+
]
|
|
784
760
|
end
|
|
785
761
|
|
|
786
762
|
#########################
|
|
@@ -800,7 +776,7 @@ module Xolo
|
|
|
800
776
|
# @return [Boolean] does the jamf_auto_reinstall_policy exist?
|
|
801
777
|
##########################
|
|
802
778
|
def jamf_auto_reinstall_policy_exist?
|
|
803
|
-
Jamf::Policy.all_names(cnx: jamf_cnx).include? jamf_auto_reinstall_policy_name
|
|
779
|
+
Jamf::Policy.all_names(:refresh, cnx: jamf_cnx).include? jamf_auto_reinstall_policy_name
|
|
804
780
|
end
|
|
805
781
|
|
|
806
782
|
# Create or fetch the auto re-install policy for this version
|
|
@@ -814,8 +790,6 @@ module Xolo
|
|
|
814
790
|
Jamf::Policy.fetch(name: jamf_auto_reinstall_policy_name, cnx: jamf_cnx)
|
|
815
791
|
else
|
|
816
792
|
return if deleting?
|
|
817
|
-
# don't create unless there's been a re-upload of the pkg
|
|
818
|
-
return unless reupload_date
|
|
819
793
|
|
|
820
794
|
create_jamf_auto_reinstall_policy
|
|
821
795
|
end
|
|
@@ -845,6 +819,9 @@ module Xolo
|
|
|
845
819
|
# @param pol [Jamf::Policy] the policy to configure
|
|
846
820
|
######################
|
|
847
821
|
def configure_jamf_auto_reinstall_policy(pol)
|
|
822
|
+
# this creates the installed group if it doesn't already exist
|
|
823
|
+
jamf_installed_group
|
|
824
|
+
|
|
848
825
|
pol.category = Xolo::Server::JAMF_XOLO_CATEGORY
|
|
849
826
|
pol.set_trigger_event :checkin, true
|
|
850
827
|
pol.set_trigger_event :custom, Xolo::BLANK
|
|
@@ -852,7 +829,7 @@ module Xolo
|
|
|
852
829
|
pol.recon = false
|
|
853
830
|
pol.retry_event = :checkin
|
|
854
831
|
pol.retry_attempts = 5
|
|
855
|
-
pol.scope.set_targets :computer_groups, [
|
|
832
|
+
pol.scope.set_targets :computer_groups, [jamf_installed_group.name]
|
|
856
833
|
|
|
857
834
|
# exclusions are for always
|
|
858
835
|
set_policy_exclusions pol
|
|
@@ -876,41 +853,6 @@ module Xolo
|
|
|
876
853
|
@jamf_auto_reinstall_policy_url = "#{jamf_gui_url}/policies.html?id=#{pol_id}&o=r"
|
|
877
854
|
end
|
|
878
855
|
|
|
879
|
-
# This will start a thread
|
|
880
|
-
# that will wait some period of time (to allow for pkg uploads
|
|
881
|
-
# to complete) before enabling and flushing the logs for the reinstall policy.
|
|
882
|
-
# This will make all macs with this version installed get it re-installed.
|
|
883
|
-
# @return [void]
|
|
884
|
-
def wait_to_enable_reinstall_policy
|
|
885
|
-
return if @enable_reinstall_policy_thread&.alive?
|
|
886
|
-
return unless reupload_date
|
|
887
|
-
|
|
888
|
-
# TODO: some setting to determine how long to wait?
|
|
889
|
-
# - If uploading via the Jamf API, we need to give it time
|
|
890
|
-
# to then upload the file to the cloud distribution point
|
|
891
|
-
# - If uploading via a custom tool, we need to give that
|
|
892
|
-
# tool time to re-upload to wherever it uploads to
|
|
893
|
-
# - May need to wait for other non-jamf/non-xolo processes
|
|
894
|
-
# to sync the package to other distribution points. This
|
|
895
|
-
# might be very site-specific.
|
|
896
|
-
|
|
897
|
-
# For now, we wait 15 minutes.
|
|
898
|
-
wait_time = JAMF_AUTO_REINSTALL_WAIT_SECS
|
|
899
|
-
|
|
900
|
-
@enable_reinstall_policy_thread = Thread.new do
|
|
901
|
-
log_debug "Jamf: Starting enable_reinstall_policy_thread: waiting #{wait_time} seconds before enabling reinstall policy for version #{version} of title #{title}"
|
|
902
|
-
sleep wait_time
|
|
903
|
-
|
|
904
|
-
log_debug "Jamf: enable_reinstall_policy_thread: enabling and flushing logs for reinstall policy for version #{version} of title #{title}"
|
|
905
|
-
|
|
906
|
-
pol = jamf_auto_reinstall_policy
|
|
907
|
-
pol.enable
|
|
908
|
-
pol.flush_logs
|
|
909
|
-
pol.save
|
|
910
|
-
end
|
|
911
|
-
@enable_reinstall_policy_thread.name = "enable_reinstall_policy_thread-#{title}-#{version}"
|
|
912
|
-
end
|
|
913
|
-
|
|
914
856
|
####### The Jamf Patch Policy
|
|
915
857
|
###########################################
|
|
916
858
|
###########################################
|
|
@@ -941,28 +883,6 @@ module Xolo
|
|
|
941
883
|
def create_jamf_patch_policy
|
|
942
884
|
progress "Jamf: Creating Patch Policy for Version '#{version}' of Title '#{title}'.", log: :info
|
|
943
885
|
|
|
944
|
-
# TODO: decide how many patch policies - see comments at top
|
|
945
|
-
# Probably one: for pilots initially and then rescoped to all for release
|
|
946
|
-
#
|
|
947
|
-
# TODO: How to set these, and should they be settable
|
|
948
|
-
# at the Xolo::Title or Xolo::Version level?
|
|
949
|
-
#
|
|
950
|
-
# allow downgrade? No, to start with.
|
|
951
|
-
# When a version is released, IF we are rolling back, then this will be set.
|
|
952
|
-
# This is to be set only on the current release and only when it was a rollback.
|
|
953
|
-
#
|
|
954
|
-
# patch_unknown_versions... yes?
|
|
955
|
-
#
|
|
956
|
-
# if not in ssvc:
|
|
957
|
-
# - grace period?
|
|
958
|
-
# - update warning Message and Subject
|
|
959
|
-
#
|
|
960
|
-
# if in ssvc:
|
|
961
|
-
# - any way to use existing icon?
|
|
962
|
-
# - use title desc... do we want a version desc??
|
|
963
|
-
# - notifications? Message and Subject? SSvc only, Notif Ctr?
|
|
964
|
-
# - deadline and grace period message and subbject
|
|
965
|
-
|
|
966
886
|
ppol = Jamf::PatchPolicy.create(
|
|
967
887
|
cnx: jamf_cnx,
|
|
968
888
|
name: jamf_patch_policy_name,
|
|
@@ -970,26 +890,12 @@ module Xolo
|
|
|
970
890
|
target_version: version
|
|
971
891
|
)
|
|
972
892
|
|
|
973
|
-
|
|
974
|
-
# 'pilot' so the scope targets are the pilot groups, if any.
|
|
975
|
-
# When the version is released, the patch policy will be
|
|
976
|
-
# rescoped to all targets (limited by eligibility)
|
|
977
|
-
set_policy_pilot_groups ppol
|
|
978
|
-
|
|
979
|
-
# exclusions are for always
|
|
980
|
-
set_policy_exclusions ppol
|
|
893
|
+
configure_jamf_patch_policy(ppol)
|
|
981
894
|
|
|
982
|
-
# This will be set to true as needed if
|
|
895
|
+
# This is always false to start will be set to true as needed if
|
|
983
896
|
# a rollback is being done
|
|
984
897
|
ppol.allow_downgrade = false
|
|
985
898
|
|
|
986
|
-
# This should always be false, so that
|
|
987
|
-
# we don't accidentally downgrade non-xolo test installs,
|
|
988
|
-
# or server-pushed updates (like with commvault or cisco VPN)
|
|
989
|
-
ppol.patch_unknown = false
|
|
990
|
-
|
|
991
|
-
ppol.enable
|
|
992
|
-
|
|
993
899
|
ppol.save
|
|
994
900
|
|
|
995
901
|
# refetch it rather than using the one we just created
|
|
@@ -1003,14 +909,28 @@ module Xolo
|
|
|
1003
909
|
assign_pkg_to_patch_in_jamf
|
|
1004
910
|
|
|
1005
911
|
ppol = jamf_patch_policy
|
|
912
|
+
|
|
913
|
+
configure_jamf_patch_policy(ppol)
|
|
914
|
+
|
|
915
|
+
ppol.save
|
|
916
|
+
end
|
|
917
|
+
|
|
918
|
+
# Configure the patch policy
|
|
919
|
+
# NOTE: This doesn't save the changes!
|
|
920
|
+
##############################
|
|
921
|
+
def configure_jamf_patch_policy(ppol)
|
|
1006
922
|
ppol.name = jamf_patch_policy_name
|
|
1007
923
|
ppol.target_version = version
|
|
1008
924
|
|
|
1009
|
-
# This should
|
|
925
|
+
# This should default to false, so that
|
|
1010
926
|
# we don't accidentally downgrade non-xolo test installs,
|
|
1011
927
|
# or server-pushed updates (like with commvault or cisco VPN)
|
|
1012
|
-
ppol.patch_unknown = false
|
|
928
|
+
ppol.patch_unknown = patch_unknown ? true : false
|
|
1013
929
|
|
|
930
|
+
# when first creating a patch policy, its status is always
|
|
931
|
+
# 'pilot' so the scope targets are the pilot groups, if any.
|
|
932
|
+
# When the version is released, the patch policy will be
|
|
933
|
+
# rescoped to all targets (limited by eligibility)
|
|
1014
934
|
if pilot?
|
|
1015
935
|
set_policy_pilot_groups ppol
|
|
1016
936
|
else
|
|
@@ -1020,13 +940,74 @@ module Xolo
|
|
|
1020
940
|
# exclusions are for always
|
|
1021
941
|
set_policy_exclusions ppol
|
|
1022
942
|
|
|
943
|
+
# only pilot and released versions should have the patch policy enabled
|
|
1023
944
|
if pilot? || released?
|
|
1024
945
|
ppol.enable
|
|
1025
946
|
else
|
|
1026
947
|
ppol.disable
|
|
1027
948
|
end
|
|
1028
949
|
|
|
1029
|
-
ppol
|
|
950
|
+
configure_patch_pol_for_self_service ppol
|
|
951
|
+
end
|
|
952
|
+
|
|
953
|
+
# Configure the patch policy for self service
|
|
954
|
+
# NOTE: Does NOT save the policy changes!
|
|
955
|
+
# @param ppol [Jamf::PatchPolicy] The patch policy to configure
|
|
956
|
+
# @return [void]
|
|
957
|
+
# ###############################
|
|
958
|
+
def configure_patch_pol_for_self_service(ppol = nil)
|
|
959
|
+
ppol ||= jamf_patch_policy
|
|
960
|
+
|
|
961
|
+
# if we're here we're in ssvc
|
|
962
|
+
progress "Jamf: Configuring patch policy for version '#{version}' of title '#{title}' for Self Service'", log: :info
|
|
963
|
+
|
|
964
|
+
# TODO: xadm settings for most of these ssvc values.
|
|
965
|
+
# TODO: deadlines, graceperiod ? needed in ruby-jss
|
|
966
|
+
msg = "#{title_object.display_name} is ready to be updated to version #{version}"
|
|
967
|
+
ppol.add_to_self_service
|
|
968
|
+
ppol.self_service_install_button_text = 'Update'
|
|
969
|
+
ppol.self_service_description = msg
|
|
970
|
+
ppol.self_service_notifications_enabled = true
|
|
971
|
+
ppol.self_service_notification_type = :ssvc_and_nctr
|
|
972
|
+
ppol.self_service_notification_subject = "#{title_object.display_name} update available"
|
|
973
|
+
ppol.self_service_notification_message = msg
|
|
974
|
+
ppol.self_service_reminders_enabled = true
|
|
975
|
+
ppol.self_service_reminder_frequency = 24 # hours
|
|
976
|
+
|
|
977
|
+
return unless title_object.ssvc_icon_id
|
|
978
|
+
|
|
979
|
+
set_patch_policy_ssvc_icon ppol, title_object.ssvc_icon_id
|
|
980
|
+
end
|
|
981
|
+
|
|
982
|
+
# Set an existing ssvc icon for a given patch policy
|
|
983
|
+
#
|
|
984
|
+
# NOTE: Update this if/when ruby-jss and the JPAPI can handle
|
|
985
|
+
# PatchPolicy Icons.
|
|
986
|
+
#
|
|
987
|
+
# This shouldn't interfere with a future #save of a PatchPolicy
|
|
988
|
+
# object, since that xml won't contain self_service_icon data at all.
|
|
989
|
+
#
|
|
990
|
+
# @param ppol [Jamf::PatchPolicy] The Patch Pol. to set the icon for
|
|
991
|
+
# @param icon_id [Integer, String] The id of the existing icon to use.
|
|
992
|
+
# @return [Void]
|
|
993
|
+
##########################
|
|
994
|
+
def set_patch_policy_ssvc_icon(ppol, icon_id)
|
|
995
|
+
# this str can't be frozen for now
|
|
996
|
+
icon_xml = +<<~ENDXML
|
|
997
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
998
|
+
<patch_policy>
|
|
999
|
+
<user_interaction>
|
|
1000
|
+
<self_service_icon>
|
|
1001
|
+
<id>#{icon_id}</id>
|
|
1002
|
+
</self_service_icon>
|
|
1003
|
+
</user_interaction>
|
|
1004
|
+
</patch_policy>
|
|
1005
|
+
ENDXML
|
|
1006
|
+
|
|
1007
|
+
log_debug "Jamf: Adding existing SSvc icon to patch policy for version '#{version}' of title '#{title}'"
|
|
1008
|
+
# TODO: in ruby-jss, update c_put and related methods to
|
|
1009
|
+
# use unfrozen dups of strings for #gsub
|
|
1010
|
+
jamf_cnx.c_put ppol.rest_rsrc, icon_xml
|
|
1030
1011
|
end
|
|
1031
1012
|
|
|
1032
1013
|
# @return [String] the URL for the Jamf Pro Patch Policy that updates to this version
|
|
@@ -1296,7 +1277,14 @@ module Xolo
|
|
|
1296
1277
|
@jamf_patch_version = title_object.jamf_patch_title.versions[version]
|
|
1297
1278
|
return @jamf_patch_version if @jamf_patch_version
|
|
1298
1279
|
|
|
1299
|
-
|
|
1280
|
+
if repairing?
|
|
1281
|
+
# if we're repairing, and the version isn't visible in Jamf, then
|
|
1282
|
+
# jamf polled the title editor in the few moments it was disabled.
|
|
1283
|
+
# and jamf will see it again within 5 minutes.
|
|
1284
|
+
return nil
|
|
1285
|
+
end
|
|
1286
|
+
|
|
1287
|
+
# TODO: wait for it to appear when adding, or re-appear when repairing?
|
|
1300
1288
|
msg = "Jamf: Version '#{version}' of Title '#{title}' is not visible in Jamf. Is the Patch enabled in the Title Editor?"
|
|
1301
1289
|
log_error msg
|
|
1302
1290
|
raise Xolo::NoSuchItemError, msg
|
|
@@ -1310,7 +1298,7 @@ module Xolo
|
|
|
1310
1298
|
#
|
|
1311
1299
|
# @return [void]
|
|
1312
1300
|
#########################
|
|
1313
|
-
def
|
|
1301
|
+
def activate_managed_patch_version_in_jamf
|
|
1314
1302
|
# don't do this if there's already one running for this instance
|
|
1315
1303
|
if @activate_patch_version_thread&.alive?
|
|
1316
1304
|
log_debug "Jamf: activate_patch_version_thread already running. Caller: #{caller_locations.first}"
|
|
@@ -1342,13 +1330,7 @@ module Xolo
|
|
|
1342
1330
|
end
|
|
1343
1331
|
|
|
1344
1332
|
if did_it
|
|
1345
|
-
|
|
1346
|
-
# give jamf a moment to catch up and refresh the patch title
|
|
1347
|
-
# so we see the pkg has been assigned
|
|
1348
|
-
sleep 2
|
|
1349
|
-
title_object.jamf_patch_title(refresh: true)
|
|
1350
|
-
|
|
1351
|
-
create_jamf_patch_policy
|
|
1333
|
+
activate_patch_version_in_jamf
|
|
1352
1334
|
msg = "Jamf: Version '#{version}' of title '#{title}' is now visible in Jamf Pro. Package assigned and Patch policy created."
|
|
1353
1335
|
log_info msg, alert: true
|
|
1354
1336
|
else
|
|
@@ -1359,6 +1341,37 @@ module Xolo
|
|
|
1359
1341
|
@activate_patch_version_thread.name = "activate_patch_version_thread-#{title}-#{version}"
|
|
1360
1342
|
end
|
|
1361
1343
|
|
|
1344
|
+
# Patches for subscribed titles are already visible in Jamf Patch Management
|
|
1345
|
+
# So we just need to assign the pkg to the patch version, and create the patch policy.
|
|
1346
|
+
##########################
|
|
1347
|
+
def activate_subscribed_patch_version_in_jamf
|
|
1348
|
+
msg = "Jamf: Assigning package and creating patch policy for version '#{version}' of subscribed title '#{title}'"
|
|
1349
|
+
log_info msg
|
|
1350
|
+
activate_patch_version_in_jamf
|
|
1351
|
+
end
|
|
1352
|
+
|
|
1353
|
+
# Assign the package for this version to the Jamf::PatchTitle::Version in Jamf
|
|
1354
|
+
# and create the patch policy for this version.
|
|
1355
|
+
#
|
|
1356
|
+
# @return [void]
|
|
1357
|
+
##########################
|
|
1358
|
+
def activate_patch_version_in_jamf
|
|
1359
|
+
log_debug "Jamf: Activating patch version in Jamf for version '#{version}' of title '#{title}'"
|
|
1360
|
+
|
|
1361
|
+
# create the Jamf::JPackage object if needed
|
|
1362
|
+
jamf_package
|
|
1363
|
+
title_object.jamf_patch_title(refresh: true)
|
|
1364
|
+
sleep 3
|
|
1365
|
+
|
|
1366
|
+
assign_pkg_to_patch_in_jamf
|
|
1367
|
+
# give jamf a moment to catch up and refresh the patch title
|
|
1368
|
+
# so we see the pkg has been assigned
|
|
1369
|
+
sleep 2
|
|
1370
|
+
title_object.jamf_patch_title(refresh: true)
|
|
1371
|
+
|
|
1372
|
+
create_jamf_patch_policy
|
|
1373
|
+
end
|
|
1374
|
+
|
|
1362
1375
|
# Assign the Package to the Jamf::PatchTitle::Version for this Xolo version.
|
|
1363
1376
|
# This 'activates' the version in Jamf Patch, and must happen before
|
|
1364
1377
|
# patch policies can be created
|
|
@@ -1374,10 +1387,23 @@ module Xolo
|
|
|
1374
1387
|
# @return [void]
|
|
1375
1388
|
########################################
|
|
1376
1389
|
def assign_pkg_to_patch_in_jamf
|
|
1377
|
-
|
|
1390
|
+
patch_vers_obj = jamf_patch_version
|
|
1391
|
+
|
|
1392
|
+
if patch_vers_obj.nil? && repairing?
|
|
1393
|
+
msg = "Jamf: Cant re-assign package '#{jamf_pkg_name}' to patch version '#{version}' of title '#{title}' at this time. If there are problems with it, try 'repair' again later."
|
|
1394
|
+
progress msg, log: :info
|
|
1395
|
+
return
|
|
1396
|
+
end
|
|
1397
|
+
|
|
1398
|
+
progress "Jamf: Assigning package '#{jamf_pkg_name}' to patch version '#{version}' of title '#{title}'", log: :info
|
|
1399
|
+
|
|
1400
|
+
log_debug "Jamf: jamf_patch_version is: #{patch_vers_obj}"
|
|
1401
|
+
|
|
1402
|
+
patch_vers_obj.package = jamf_pkg_name
|
|
1403
|
+
log_debug "Jamf: jamf_patch_version after assignment is: #{patch_vers_obj}"
|
|
1378
1404
|
|
|
1379
|
-
jamf_patch_version.package = jamf_pkg_name
|
|
1380
1405
|
title_object.jamf_patch_title.save
|
|
1406
|
+
log_debug 'Jamf: Saved jamf_patch_title after assigning package to version.'
|
|
1381
1407
|
end
|
|
1382
1408
|
|
|
1383
1409
|
# Get the patch report for this version
|
|
@@ -48,6 +48,19 @@ module Xolo
|
|
|
48
48
|
# @return [void]
|
|
49
49
|
##########################
|
|
50
50
|
def create_patch_in_ted
|
|
51
|
+
if subscribed?
|
|
52
|
+
log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor patch creation"
|
|
53
|
+
return
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# if the patch exists, remove and recreate it
|
|
57
|
+
if ted_patch
|
|
58
|
+
progress "Title Editor: Patch '#{version}' of SoftwareTitle '#{title}' already exists, removing & readding it..."
|
|
59
|
+
ted_title.patches.delete_patch ted_patch.patchId
|
|
60
|
+
sleep 2
|
|
61
|
+
ted_patch(refresh: true)
|
|
62
|
+
end
|
|
63
|
+
|
|
51
64
|
progress "Title Editor: Creating Patch '#{version}' of SoftwareTitle '#{title}'", log: :info
|
|
52
65
|
ted_title.patches.add_patch(
|
|
53
66
|
version: version,
|
|
@@ -75,6 +88,11 @@ module Xolo
|
|
|
75
88
|
# @return [void]
|
|
76
89
|
##########################
|
|
77
90
|
def update_patch_in_ted
|
|
91
|
+
if subscribed?
|
|
92
|
+
log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor patch update"
|
|
93
|
+
return
|
|
94
|
+
end
|
|
95
|
+
|
|
78
96
|
progress "Title Editor: Updating Patch '#{version}' SoftwareTitle '#{title}'", log: :info
|
|
79
97
|
|
|
80
98
|
Xolo::Server::Version::ATTRIBUTES.each do |attr, deets|
|
|
@@ -340,12 +358,19 @@ module Xolo
|
|
|
340
358
|
# @return [String] the URL for the Title Editor Web App page for this patch
|
|
341
359
|
###################################
|
|
342
360
|
def ted_patch_url
|
|
361
|
+
return unless managed?
|
|
362
|
+
|
|
343
363
|
"https://#{Xolo::Server.config.ted_hostname}/patches/#{ted_id_number}"
|
|
344
364
|
end
|
|
345
365
|
|
|
346
366
|
# Ensure all the TEd items for this version are correct based on the server data.
|
|
347
367
|
#########################
|
|
348
368
|
def repair_ted_patch
|
|
369
|
+
if subscribed?
|
|
370
|
+
log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor patch repair"
|
|
371
|
+
return
|
|
372
|
+
end
|
|
373
|
+
|
|
349
374
|
progress "Title Editor: Repairing Patch '#{version}' of SoftwareTitle '#{title}'", log: :info
|
|
350
375
|
|
|
351
376
|
Xolo::Server::Version::ATTRIBUTES.each do |attr, deets|
|