xolo-server 2.1.0 → 2.2.2
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 +16 -4
- data/data/com.pixar.xoloserver.plist +9 -2
- data/lib/xolo/core/base_classes/title.rb +113 -13
- data/lib/xolo/core/base_classes/version.rb +5 -6
- data/lib/xolo/core/exceptions.rb +3 -1
- data/lib/xolo/core/version.rb +1 -1
- data/lib/xolo/server/app.rb +1 -1
- data/lib/xolo/server/configuration.rb +4 -4
- data/lib/xolo/server/helpers/auth.rb +3 -3
- data/lib/xolo/server/helpers/maintenance.rb +194 -90
- data/lib/xolo/server/helpers/progress_streaming.rb +43 -10
- data/lib/xolo/server/mixins/title_jamf_access.rb +269 -51
- data/lib/xolo/server/mixins/version_jamf_access.rb +83 -34
- data/lib/xolo/server/routes/maint.rb +16 -15
- data/lib/xolo/server/routes/titles.rb +3 -0
- data/lib/xolo/server/routes.rb +1 -1
- data/lib/xolo/server/title.rb +28 -5
- data/lib/xolo/server/version.rb +71 -28
- metadata +2 -2
|
@@ -56,7 +56,7 @@ module Xolo
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# Create title-level things in jamf when creating a title.
|
|
59
|
-
#
|
|
59
|
+
# No need to deal with versions here, there are none yet.
|
|
60
60
|
# @return [void]
|
|
61
61
|
################################
|
|
62
62
|
def create_title_in_jamf
|
|
@@ -85,6 +85,10 @@ module Xolo
|
|
|
85
85
|
# Just calling this will create it if it doesn't exist.
|
|
86
86
|
jamf_frozen_group
|
|
87
87
|
|
|
88
|
+
# If we have target-groups, create the jamf_target_groups_exclusion_group
|
|
89
|
+
# to use as an exclusion
|
|
90
|
+
jamf_target_groups_exclusion_group if target_groups && !target_groups.pix_empty?
|
|
91
|
+
|
|
88
92
|
# This either notifies, or does it
|
|
89
93
|
# TODO: EAs for subscribed titles can change at any time and need
|
|
90
94
|
# re-accepted - Notifications must happen.
|
|
@@ -100,9 +104,31 @@ module Xolo
|
|
|
100
104
|
def update_title_in_jamf
|
|
101
105
|
# ORDER MATTERS
|
|
102
106
|
|
|
107
|
+
# target group changes are tricky cuz the related group is in scopes
|
|
108
|
+
# all over the place.
|
|
109
|
+
need_to_delete_jamf_target_groups_exclusion_group = false
|
|
110
|
+
|
|
111
|
+
# TODO: Move this to a sep. method
|
|
112
|
+
if changes_for_update[:target_groups]
|
|
113
|
+
# if some->none, update the scopes later, then delete the group at the end
|
|
114
|
+
if changes_for_update[:target_groups][:new].empty?
|
|
115
|
+
need_to_delete_jamf_target_groups_exclusion_group = true
|
|
116
|
+
|
|
117
|
+
# if from none->some, create the group - add to scopes later
|
|
118
|
+
elsif changes_for_update[:target_groups][:old].empty?
|
|
119
|
+
# create the group
|
|
120
|
+
jamf_target_groups_exclusion_group
|
|
121
|
+
|
|
122
|
+
# if tgt grps changed, just update the smartgroup, don't change any scopes
|
|
123
|
+
else
|
|
124
|
+
configure_jamf_target_groups_exclusion_group changes_for_update[:target_groups][:new]
|
|
125
|
+
progress "Jamf: Done updating smart group '#{jamf_target_groups_exclusion_group_name}'", log: :debug
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
103
129
|
# if the exclusions have changed update the manual install released policy
|
|
104
|
-
if changes_for_update[:excluded_groups]
|
|
105
|
-
progress "Jamf: Updating
|
|
130
|
+
if changes_for_update[:target_groups] || changes_for_update[:excluded_groups]
|
|
131
|
+
progress "Jamf: Updating scope for Manual Released Policy '#{jamf_manual_install_released_policy_name}'."
|
|
106
132
|
configure_jamf_manual_install_released_policy(jamf_manual_install_released_policy)
|
|
107
133
|
end
|
|
108
134
|
|
|
@@ -132,39 +158,32 @@ module Xolo
|
|
|
132
158
|
update_ssvc
|
|
133
159
|
# TODO: deal with icon changes: if changes_for_update&.key? :self_service_icon
|
|
134
160
|
|
|
161
|
+
# are there any versions yet? if no, not active
|
|
135
162
|
if jamf_title_active?
|
|
136
163
|
update_versions_for_title_changes_in_jamf
|
|
137
164
|
else
|
|
138
165
|
log_debug "Jamf: Title '#{display_name}' (#{title}) is not yet active to Jamf, nothing to update in versions."
|
|
139
166
|
end
|
|
167
|
+
|
|
168
|
+
# version scopes should have been updated, now do the title
|
|
169
|
+
configure_jamf_manual_install_released_policy
|
|
170
|
+
delete_jamf_target_groups_exclusion_group if need_to_delete_jamf_target_groups_exclusion_group
|
|
140
171
|
end
|
|
141
172
|
|
|
142
173
|
# Repair this title in Jamf Pro
|
|
143
|
-
# - TODO: activate title in patch mgmt
|
|
144
|
-
# - TODO: Accept Patch EA
|
|
145
|
-
# - title-installed smart group 'xolo-<title>-installed'
|
|
146
|
-
# - frozen static group 'xolo-<title>-frozen'
|
|
147
|
-
# - manual/SSvc install-current-release policy 'xolo-<title>-install'
|
|
148
|
-
# - trigger 'xolo-<title>-install'
|
|
149
|
-
# - ssvc icon
|
|
150
|
-
# - ssvc category
|
|
151
|
-
# - description
|
|
152
|
-
# - if uninstallable
|
|
153
|
-
# - uninstall script 'xolo-<title>-uninstall'
|
|
154
|
-
# - uninstall policy 'xolo-<title>-uninstall'
|
|
155
|
-
# - if expirable
|
|
156
|
-
# - expire policy 'xolo-<title>-expire'
|
|
157
|
-
# - trigger 'xolo-<title>-expire'
|
|
174
|
+
# - TODO: activate title in patch mgmt if needed
|
|
175
|
+
# - TODO: Accept Patch EA if needed
|
|
158
176
|
#
|
|
159
177
|
###############################################
|
|
160
178
|
def repair_jamf_title_objects
|
|
161
179
|
progress "Jamf: Repairing Jamf objects for title '#{title}'", log: :info
|
|
162
180
|
|
|
163
|
-
|
|
181
|
+
repair_jamf_installed_group
|
|
164
182
|
repair_jamf_uninstall_policy
|
|
165
183
|
repair_jamf_uninstall_script
|
|
166
184
|
repair_jamf_expire_policy
|
|
167
185
|
repair_frozen_group
|
|
186
|
+
repair_jamf_target_groups_exclusion_group
|
|
168
187
|
repair_jamf_manual_install_released_policy
|
|
169
188
|
end
|
|
170
189
|
|
|
@@ -186,9 +205,11 @@ module Xolo
|
|
|
186
205
|
|
|
187
206
|
delete_jamf_patch_title
|
|
188
207
|
|
|
189
|
-
#
|
|
208
|
+
# excl groups deleted last,
|
|
190
209
|
# was used in scopes for patch and normal policies
|
|
191
210
|
delete_jamf_frozen_group
|
|
211
|
+
|
|
212
|
+
delete_jamf_target_groups_exclusion_group
|
|
192
213
|
end
|
|
193
214
|
|
|
194
215
|
# If any title changes require updates to existing versions in
|
|
@@ -206,9 +227,13 @@ module Xolo
|
|
|
206
227
|
############################
|
|
207
228
|
def update_versions_for_title_changes_in_jamf
|
|
208
229
|
version_objects.each do |vers_obj|
|
|
230
|
+
progress "Jamf: Applying changes to version '#{vers_obj.version}' of title '#{title}' (#{self.class})", log: :info
|
|
209
231
|
vers_obj.update_release_groups(ttl_obj: self) if changes_for_update&.key? :release_groups
|
|
210
|
-
|
|
232
|
+
|
|
233
|
+
vers_obj.update_excluded_groups(ttl_obj: self) if changes_for_update&.key?(:excluded_groups) || changes_for_update&.key?(:target_groups)
|
|
234
|
+
|
|
211
235
|
vers_obj.update_jamf_package_notes(ttl_obj: self) if need_to_update_description?
|
|
236
|
+
vers_obj.update_patch_policy_deployment(ttl_obj: self) if changes_for_update&.key? :self_service_updates
|
|
212
237
|
end
|
|
213
238
|
end
|
|
214
239
|
|
|
@@ -792,8 +817,13 @@ module Xolo
|
|
|
792
817
|
|
|
793
818
|
jamf_installed_group.criteria = Jamf::Criteriable::Criteria.new(jamf_installed_group_criteria)
|
|
794
819
|
jamf_installed_group.save
|
|
795
|
-
log_debug 'Jamf: Sleeping
|
|
796
|
-
sleep
|
|
820
|
+
log_debug 'Jamf: Sleeping 15 secs to let Jamf server see changes to Installed smart group.'
|
|
821
|
+
sleep 15
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
############################
|
|
825
|
+
def repair_jamf_installed_group
|
|
826
|
+
configure_jamf_installed_group
|
|
797
827
|
end
|
|
798
828
|
|
|
799
829
|
# The criteria for the smart group in Jamf that contains all Macs
|
|
@@ -846,6 +876,141 @@ module Xolo
|
|
|
846
876
|
@jamf_installed_group_url = "#{jamf_gui_url}/smartComputerGroups.html?id=#{gr_id}&o=r"
|
|
847
877
|
end
|
|
848
878
|
|
|
879
|
+
####### The TargetGroups Exclusion Group
|
|
880
|
+
###########################################
|
|
881
|
+
###########################################
|
|
882
|
+
|
|
883
|
+
############################
|
|
884
|
+
def jamf_target_groups_exclusion_group
|
|
885
|
+
return @jamf_target_groups_exclusion_group if @jamf_target_groups_exclusion_group
|
|
886
|
+
return if target_groups_to_use.pix_empty?
|
|
887
|
+
|
|
888
|
+
if jamf_target_groups_exclusion_group_exist?
|
|
889
|
+
@jamf_target_groups_exclusion_group = Jamf::ComputerGroup.fetch(
|
|
890
|
+
name: jamf_target_groups_exclusion_group_name,
|
|
891
|
+
cnx: jamf_cnx
|
|
892
|
+
)
|
|
893
|
+
else
|
|
894
|
+
return if deleting?
|
|
895
|
+
|
|
896
|
+
progress "Jamf: Creating smart group '#{jamf_target_groups_exclusion_group_name}'", log: :info
|
|
897
|
+
|
|
898
|
+
@jamf_target_groups_exclusion_group = Jamf::ComputerGroup.create(
|
|
899
|
+
name: jamf_target_groups_exclusion_group_name,
|
|
900
|
+
type: :smart,
|
|
901
|
+
cnx: jamf_cnx
|
|
902
|
+
)
|
|
903
|
+
@jamf_target_groups_exclusion_group.save
|
|
904
|
+
configure_jamf_target_groups_exclusion_group
|
|
905
|
+
progress "Jamf: Done creating smart group '#{jamf_target_groups_exclusion_group_name}'", log: :debug
|
|
906
|
+
|
|
907
|
+
end
|
|
908
|
+
|
|
909
|
+
@jamf_target_groups_exclusion_group
|
|
910
|
+
end
|
|
911
|
+
|
|
912
|
+
############################
|
|
913
|
+
def jamf_target_groups_exclusion_group_exist?
|
|
914
|
+
Jamf::ComputerGroup.all_names(:refresh, cnx: jamf_cnx).include? jamf_target_groups_exclusion_group_name
|
|
915
|
+
end
|
|
916
|
+
|
|
917
|
+
############################
|
|
918
|
+
def jamf_target_groups_exclusion_group_criteria(tgt_grps = nil)
|
|
919
|
+
# for some reason this can be really slow
|
|
920
|
+
jamf_cnx.timeout = 1800
|
|
921
|
+
tgt_grps ||= target_groups_to_use
|
|
922
|
+
criteria = []
|
|
923
|
+
tgt_grps.each do |tgrp|
|
|
924
|
+
progress "Jamf: Adding criterion for target group '#{tgrp}' (can be slow)", log: :info
|
|
925
|
+
criteria << Jamf::Criteriable::Criterion.new(
|
|
926
|
+
and_or: :and,
|
|
927
|
+
name: 'Computer Group',
|
|
928
|
+
search_type: 'not member of',
|
|
929
|
+
value: tgrp
|
|
930
|
+
)
|
|
931
|
+
end
|
|
932
|
+
criteria
|
|
933
|
+
end
|
|
934
|
+
|
|
935
|
+
############################
|
|
936
|
+
def configure_jamf_target_groups_exclusion_group(tgt_grps = nil)
|
|
937
|
+
return if target_groups_to_use.pix_empty?
|
|
938
|
+
|
|
939
|
+
tgt_grps ||= target_groups_to_use
|
|
940
|
+
progress "Jamf: Configuring smart group '#{jamf_target_groups_exclusion_group_name}'", log: :info
|
|
941
|
+
|
|
942
|
+
jamf_target_groups_exclusion_group.criteria =
|
|
943
|
+
Jamf::Criteriable::Criteria.new jamf_target_groups_exclusion_group_criteria(tgt_grps)
|
|
944
|
+
|
|
945
|
+
jamf_target_groups_exclusion_group.save
|
|
946
|
+
|
|
947
|
+
progress "Jamf: Sleeping 10 secs to let Jamf server see changes to smart group '#{jamf_target_groups_exclusion_group_name}'", log: :debug
|
|
948
|
+
sleep 10
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
############################
|
|
952
|
+
def repair_jamf_target_groups_exclusion_group
|
|
953
|
+
progress "Jamf: Repairing smart group '#{jamf_target_groups_exclusion_group_name}'", log: :info
|
|
954
|
+
|
|
955
|
+
if target_groups_to_use.pix_empty?
|
|
956
|
+
delete_jamf_target_groups_exclusion_group
|
|
957
|
+
else
|
|
958
|
+
configure_jamf_target_groups_exclusion_group
|
|
959
|
+
progress "Jamf: Done repairing smart group '#{jamf_target_groups_exclusion_group_name}'", log: :debug
|
|
960
|
+
|
|
961
|
+
end
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
############################
|
|
965
|
+
def delete_jamf_target_groups_exclusion_group
|
|
966
|
+
return unless jamf_target_groups_exclusion_group_exist?
|
|
967
|
+
|
|
968
|
+
progress "Jamf: Deleting smart group '#{jamf_target_groups_exclusion_group_name}'", log: :info
|
|
969
|
+
grp = Jamf::ComputerGroup.fetch(
|
|
970
|
+
name: jamf_target_groups_exclusion_group_name,
|
|
971
|
+
cnx: jamf_cnx
|
|
972
|
+
)
|
|
973
|
+
grp.delete
|
|
974
|
+
|
|
975
|
+
# give the server time to see the deletion
|
|
976
|
+
log_debug "Jamf: Sleeping 10 secs to let server see deletion of smart group '#{jamf_target_groups_exclusion_group_name}'"
|
|
977
|
+
sleep 10
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
############################
|
|
981
|
+
def jamf_target_groups_exclusion_group_url
|
|
982
|
+
return @jamf_target_groups_exclusion_group_url if @jamf_target_groups_exclusion_group_url
|
|
983
|
+
|
|
984
|
+
gr_id = Jamf::ComputerGroup.valid_id jamf_target_groups_exclusion_group_name, cnx: jamf_cnx
|
|
985
|
+
return unless gr_id
|
|
986
|
+
|
|
987
|
+
@jamf_target_groups_exclusion_group_url = "#{jamf_gui_url}/smartComputerGroups.html?id=#{gr_id}&o=r"
|
|
988
|
+
end
|
|
989
|
+
|
|
990
|
+
# should we use the jamf_target_groups_exclusion_group in our exclusions?
|
|
991
|
+
# If yes, it must have been created before now.
|
|
992
|
+
# If no, it can't have been deleted yet.
|
|
993
|
+
#
|
|
994
|
+
# @return [Boolean] should we use the jamf_target_groups_exclusion_group in our exclusions?
|
|
995
|
+
#########
|
|
996
|
+
def use_jamf_target_groups_exclusion_group?
|
|
997
|
+
if changes_for_update[:target_groups]
|
|
998
|
+
## if some-to-none, no
|
|
999
|
+
if changes_for_update[:target_groups][:new].empty?
|
|
1000
|
+
false
|
|
1001
|
+
# if from none-to-some, yes
|
|
1002
|
+
elsif changes_for_update[:target_groups][:old].empty?
|
|
1003
|
+
true
|
|
1004
|
+
# if tgt grps changed, just update the smartgroup, don't change any scopes
|
|
1005
|
+
else
|
|
1006
|
+
true
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
else
|
|
1010
|
+
!target_groups.empty?
|
|
1011
|
+
end
|
|
1012
|
+
end
|
|
1013
|
+
|
|
849
1014
|
####### The Frozen Group
|
|
850
1015
|
###########################################
|
|
851
1016
|
###########################################
|
|
@@ -1260,14 +1425,14 @@ module Xolo
|
|
|
1260
1425
|
self.title_id = title
|
|
1261
1426
|
log_debug "Jamf: Display Name in managed? after setting patch_source and title_id: #{display_name}"
|
|
1262
1427
|
|
|
1263
|
-
# display name
|
|
1264
|
-
# so for subbed, we look
|
|
1428
|
+
# display name & publisher are required for managed titles, but will be empty for subbed
|
|
1429
|
+
# so for subbed, we look them up from the patch source in set_subscribed_display_name_and_publisher
|
|
1265
1430
|
else
|
|
1266
|
-
log_debug "Jamf: Title '#{title}' is subscribed, so looking up patch source and title_id
|
|
1431
|
+
log_debug "Jamf: Title '#{title}' is subscribed, so looking up patch source and title_id"
|
|
1267
1432
|
log_debug "Jamf: Display Name in NOT managed?: #{display_name}"
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1433
|
+
|
|
1434
|
+
set_subscribed_display_name_and_publisher
|
|
1435
|
+
|
|
1271
1436
|
end # if managed
|
|
1272
1437
|
|
|
1273
1438
|
log_debug "Jamf: class: #{self.class}, display_name: #{display_name}, patch_source: #{patch_source}, title_id: #{title_id}"
|
|
@@ -1284,11 +1449,48 @@ module Xolo
|
|
|
1284
1449
|
)
|
|
1285
1450
|
jamf_patch_title.category = Xolo::Server::JAMF_XOLO_CATEGORY
|
|
1286
1451
|
self.jamf_patch_title_id = jamf_patch_title.save
|
|
1287
|
-
|
|
1452
|
+
|
|
1453
|
+
log_debug "Jamf: Activated Jamf Patch Title '#{display_name}' (#{title}) with id #{jamf_patch_title_id}"
|
|
1288
1454
|
|
|
1289
1455
|
jamf_patch_title
|
|
1290
1456
|
end
|
|
1291
1457
|
|
|
1458
|
+
# set the display name and publisher from the patch title data
|
|
1459
|
+
########################
|
|
1460
|
+
def set_subscribed_display_name_and_publisher
|
|
1461
|
+
return unless subscribed?
|
|
1462
|
+
|
|
1463
|
+
# if we already have a patch title id, the title won't be available from the patch source,
|
|
1464
|
+
# so use the JPAPI endpoint to look up the data from the already active title.
|
|
1465
|
+
# TODO: update this when ruby-jss uses the JPAPI for patch title stuff
|
|
1466
|
+
if jamf_patch_title_id
|
|
1467
|
+
log_debug 'Jamf: Getting display name and publisher from already-active title.'
|
|
1468
|
+
patch_title_data = jamf_cnx.jp_get "v2/patch-software-title-configurations/#{jamf_patch_title_id}"
|
|
1469
|
+
|
|
1470
|
+
dname = patch_title_data[:displayName]
|
|
1471
|
+
publ = patch_title_data[:softwareTitlePublisher]
|
|
1472
|
+
|
|
1473
|
+
# we don't yet have the patch title id, so the title is still 'available' from the patch source
|
|
1474
|
+
# so get the data there
|
|
1475
|
+
else
|
|
1476
|
+
log_debug 'Jamf: Getting display name and publisher from avilable/not-yet-active title.'
|
|
1477
|
+
patch_title_data = Jamf::PatchSource.available_titles(patch_source, cnx: jamf_cnx).select { |t| t[:name_id] == title_id }.first
|
|
1478
|
+
|
|
1479
|
+
dname = patch_title_data&.dig :app_name
|
|
1480
|
+
publ = patch_title_data&.dig :publisher
|
|
1481
|
+
end # if jamf_patch_title_id
|
|
1482
|
+
|
|
1483
|
+
if dname
|
|
1484
|
+
progress "Jamf: Setting display name for subscribed title: #{dname}", log: :debug
|
|
1485
|
+
self.display_name = dname
|
|
1486
|
+
end
|
|
1487
|
+
|
|
1488
|
+
return unless publ
|
|
1489
|
+
|
|
1490
|
+
progress "Jamf: Setting publisher for subscribed title: #{publ}", log: :debug
|
|
1491
|
+
self.publisher = publ
|
|
1492
|
+
end
|
|
1493
|
+
|
|
1292
1494
|
# wait up to 60secs for a managed title to become available to be activated
|
|
1293
1495
|
# subscribed titles are already available
|
|
1294
1496
|
####################
|
|
@@ -1408,7 +1610,11 @@ module Xolo
|
|
|
1408
1610
|
# @param pol [Jamf::Policy] the policy we are configuring
|
|
1409
1611
|
# @return [void]
|
|
1410
1612
|
###################
|
|
1411
|
-
def configure_jamf_manual_install_released_policy(pol)
|
|
1613
|
+
def configure_jamf_manual_install_released_policy(pol = nil)
|
|
1614
|
+
progress "Jamf: Configuring manual install-released policy '#{jamf_manual_install_released_policy_name}'", log: :info
|
|
1615
|
+
|
|
1616
|
+
pol ||= jamf_manual_install_released_policy
|
|
1617
|
+
|
|
1412
1618
|
pol.category = Xolo::Server::JAMF_XOLO_CATEGORY
|
|
1413
1619
|
pol.set_trigger_event :checkin, false
|
|
1414
1620
|
pol.set_trigger_event :custom, jamf_manual_install_released_policy_name
|
|
@@ -1421,19 +1627,9 @@ module Xolo
|
|
|
1421
1627
|
|
|
1422
1628
|
toggle_jamf_manual_install_released_policy pol
|
|
1423
1629
|
|
|
1424
|
-
|
|
1425
|
-
#
|
|
1426
|
-
# explicit exlusions for the title
|
|
1427
|
-
excls = changes_for_update&.key?(:excluded_groups) ? changes_for_update[:excluded_groups][:new].dup : excluded_groups.dup
|
|
1428
|
-
excls ||= []
|
|
1429
|
-
# plus the frozen group
|
|
1430
|
-
excls << jamf_frozen_group_name
|
|
1431
|
-
# plus any forced group from the server config
|
|
1432
|
-
excls << valid_forced_exclusion_group_name if valid_forced_exclusion_group_name
|
|
1433
|
-
# NOTE: we do not exclude existing installs, so that manual re-installs can be a thing.
|
|
1434
|
-
log_debug "Setting exclusions for manual install policy for current release: #{excls}"
|
|
1630
|
+
log_debug "Setting exclusions for manual install policy for current release: #{excluded_groups_to_use}"
|
|
1435
1631
|
|
|
1436
|
-
pol.scope.set_exclusions :computer_groups,
|
|
1632
|
+
pol.scope.set_exclusions :computer_groups, excluded_groups_to_use
|
|
1437
1633
|
|
|
1438
1634
|
if self_service?
|
|
1439
1635
|
add_title_to_self_service(pol)
|
|
@@ -1442,6 +1638,30 @@ module Xolo
|
|
|
1442
1638
|
end
|
|
1443
1639
|
end
|
|
1444
1640
|
|
|
1641
|
+
# what exclusions should we use now on all title-level scopable things?
|
|
1642
|
+
#######################
|
|
1643
|
+
def excluded_groups_to_use
|
|
1644
|
+
# always the frozen group
|
|
1645
|
+
excls = [jamf_frozen_group_name]
|
|
1646
|
+
|
|
1647
|
+
# plus any explicit exclusions for the title
|
|
1648
|
+
excls += changes_for_update&.key?(:excluded_groups) ? changes_for_update[:excluded_groups][:new] : excluded_groups
|
|
1649
|
+
|
|
1650
|
+
# plus the target_groups_exclusion_group if needed
|
|
1651
|
+
excls << jamf_target_groups_exclusion_group_name if use_jamf_target_groups_exclusion_group?
|
|
1652
|
+
|
|
1653
|
+
# plus any forced group from the server config
|
|
1654
|
+
excls << valid_forced_exclusion_group_name if valid_forced_exclusion_group_name
|
|
1655
|
+
|
|
1656
|
+
excls
|
|
1657
|
+
end
|
|
1658
|
+
|
|
1659
|
+
# what target groups should we use now on all title-level scopable things?
|
|
1660
|
+
#######################
|
|
1661
|
+
def target_groups_to_use
|
|
1662
|
+
changes_for_update&.key?(:target_groups) ? changes_for_update[:target_groups][:new] : target_groups
|
|
1663
|
+
end
|
|
1664
|
+
|
|
1445
1665
|
# enable or disable the manual install policy for the current release, depending on
|
|
1446
1666
|
# whether or not we have a released version
|
|
1447
1667
|
# @param pol [Jamf::Policy] the manual install policy for the current release, which may or may not be saved yet.
|
|
@@ -1504,13 +1724,6 @@ module Xolo
|
|
|
1504
1724
|
|
|
1505
1725
|
configure_pol_for_self_service(pol)
|
|
1506
1726
|
pol.save
|
|
1507
|
-
|
|
1508
|
-
# loop thru versions to make any SSvc changes
|
|
1509
|
-
version_objects.each do |vobj|
|
|
1510
|
-
ppol = vobj.jamf_patch_policy
|
|
1511
|
-
vobj.configure_patch_pol_for_self_service ppol
|
|
1512
|
-
ppol.save
|
|
1513
|
-
end
|
|
1514
1727
|
end
|
|
1515
1728
|
|
|
1516
1729
|
# Add the jamf_manual_install_released_policy to self service if needed
|
|
@@ -1593,12 +1806,17 @@ module Xolo
|
|
|
1593
1806
|
pol.self_service_description = new_desc
|
|
1594
1807
|
|
|
1595
1808
|
pol.self_service_install_button_text = Xolo::Server::Title::SELF_SERVICE_INSTALL_BTN_TEXT
|
|
1809
|
+
# icon already uploaded to jamf
|
|
1810
|
+
return if ssvc_icon_id
|
|
1811
|
+
|
|
1812
|
+
# icon never uploaded to xolo
|
|
1596
1813
|
return unless ssvc_icon_file
|
|
1597
1814
|
|
|
1598
|
-
#
|
|
1815
|
+
# Upload the icon from xolo to jamd
|
|
1599
1816
|
progress 'Jamf: Uploading Self Service icon', log: :debug
|
|
1600
1817
|
pol.save # won't do anything unless needed, but has to exist before we can upload icons
|
|
1601
1818
|
pol.upload :icon, ssvc_icon_file
|
|
1819
|
+
|
|
1602
1820
|
# re-fetch the pol to get the icon id
|
|
1603
1821
|
self.ssvc_icon_id = Jamf::Policy.fetch(id: pol.id, cnx: jamf_cnx).icon.id
|
|
1604
1822
|
end
|
|
@@ -45,6 +45,14 @@ module Xolo
|
|
|
45
45
|
# changes
|
|
46
46
|
JAMF_POLICY_NAME_AUTO_REINSTALL_SFX = 'auto-reinstall'
|
|
47
47
|
|
|
48
|
+
PATCH_POL_SSVC_NOTIFICATION_TYPE = :ssvc_and_nctr
|
|
49
|
+
PATCH_POL_SSVC_INSTALL_BTN_TXT = 'Update'
|
|
50
|
+
PATCH_POL_SSVC_REMINDER_FREQ_HRS = 24
|
|
51
|
+
PATCH_POL_SSVC_DEADLINE_DAYS = 7
|
|
52
|
+
|
|
53
|
+
PATCH_POL_GRACE_PERIOD_MINUTES = 15
|
|
54
|
+
PATCH_POL_GRACE_PERIOD_SUBJ = 'Important'
|
|
55
|
+
PATCH_POL_GRACE_PERIOD_MSG = '$APP_NAMES will quit in $DELAY_MINUTES minutes so that $SOFTWARE_TITLE can be updated. Please save anything you are working on and quit the app(s).'
|
|
48
56
|
# POLICIES, PATCH POLICIES, SCOPING
|
|
49
57
|
#############################
|
|
50
58
|
#
|
|
@@ -402,19 +410,6 @@ module Xolo
|
|
|
402
410
|
jamf_package.save
|
|
403
411
|
end
|
|
404
412
|
|
|
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
|
-
|
|
418
413
|
# repair the package object only
|
|
419
414
|
#############################
|
|
420
415
|
def repair_jamf_package
|
|
@@ -915,16 +910,33 @@ module Xolo
|
|
|
915
910
|
ppol.save
|
|
916
911
|
end
|
|
917
912
|
|
|
913
|
+
# update the :patch_unknown for the patch policy
|
|
914
|
+
# @return [void]
|
|
915
|
+
##############################
|
|
916
|
+
def update_jamf_patch_policy_patch_unknown
|
|
917
|
+
return unless changes_for_update&.key? :patch_unknown
|
|
918
|
+
|
|
919
|
+
ppol = jamf_patch_policy
|
|
920
|
+
action = changes_for_update[:patch_unknown][:new] ? 'Enabling' : 'Disabling'
|
|
921
|
+
progress "Jamf: #{action} 'patch_unknown' for patch policy #{ppol.name}", log: :debug
|
|
922
|
+
ppol.patch_unknown = changes_for_update[:patch_unknown][:new] ? true : false
|
|
923
|
+
ppol.save
|
|
924
|
+
end
|
|
925
|
+
|
|
918
926
|
# Configure the patch policy
|
|
919
927
|
# NOTE: This doesn't save the changes!
|
|
920
928
|
##############################
|
|
921
929
|
def configure_jamf_patch_policy(ppol)
|
|
930
|
+
progress "Jamf: Configuring Patch Policy for Version '#{version}' of Title '#{title}'.", log: :info
|
|
931
|
+
|
|
922
932
|
ppol.name = jamf_patch_policy_name
|
|
923
933
|
ppol.target_version = version
|
|
924
934
|
|
|
925
935
|
# This should default to false, so that
|
|
926
936
|
# we don't accidentally downgrade non-xolo test installs,
|
|
927
937
|
# or server-pushed updates (like with commvault or cisco VPN)
|
|
938
|
+
# The ternary operator is used here so that nils become
|
|
939
|
+
# explicit false
|
|
928
940
|
ppol.patch_unknown = patch_unknown ? true : false
|
|
929
941
|
|
|
930
942
|
# when first creating a patch policy, its status is always
|
|
@@ -940,43 +952,79 @@ module Xolo
|
|
|
940
952
|
# exclusions are for always
|
|
941
953
|
set_policy_exclusions ppol
|
|
942
954
|
|
|
955
|
+
# deployment method
|
|
956
|
+
configure_patch_pol_deployment ppol: ppol
|
|
957
|
+
|
|
943
958
|
# only pilot and released versions should have the patch policy enabled
|
|
944
|
-
if pilot? || released?
|
|
959
|
+
if pilot? || released? || creating? || releasing?
|
|
945
960
|
ppol.enable
|
|
946
961
|
else
|
|
947
962
|
ppol.disable
|
|
948
963
|
end
|
|
964
|
+
end
|
|
965
|
+
|
|
966
|
+
# Update the patch policy deployment settings if
|
|
967
|
+
# they were changed in the title.
|
|
968
|
+
#
|
|
969
|
+
# @param ttl_obj [Xolo::Server::Title] the title object that is being changed.
|
|
970
|
+
###############################
|
|
971
|
+
def update_patch_policy_deployment(ttl_obj:)
|
|
972
|
+
return unless ttl_obj.changes_for_update[:self_service_updates]
|
|
949
973
|
|
|
950
|
-
|
|
974
|
+
ppol = jamf_patch_policy
|
|
975
|
+
configure_patch_pol_deployment ttl_obj: ttl_obj, ppol: ppol
|
|
976
|
+
ppol.save
|
|
951
977
|
end
|
|
952
978
|
|
|
953
|
-
# Configure the patch policy for self service
|
|
979
|
+
# Configure the patch policy for self service or automatic deployment
|
|
954
980
|
# NOTE: Does NOT save the policy changes!
|
|
955
981
|
# @param ppol [Jamf::PatchPolicy] The patch policy to configure
|
|
956
982
|
# @return [void]
|
|
957
983
|
# ###############################
|
|
958
|
-
def
|
|
984
|
+
def configure_patch_pol_deployment(ppol: nil, ttl_obj: nil)
|
|
959
985
|
ppol ||= jamf_patch_policy
|
|
986
|
+
ttl_obj ||= title_object
|
|
987
|
+
|
|
988
|
+
use_ssvc_updates =
|
|
989
|
+
if ttl_obj.changes_for_update&.dig :self_service_updates
|
|
990
|
+
ttl_obj.changes_for_update[:self_service_updates][:new]
|
|
991
|
+
else
|
|
992
|
+
ttl_obj.self_service_updates
|
|
993
|
+
end
|
|
994
|
+
|
|
995
|
+
# always set the grace period regardless of deployment type
|
|
996
|
+
progress "Jamf: Configuring Patch Policy grace period for version '#{version}' of title '#{title}' ", log: :info
|
|
997
|
+
ppol.grace_period = PATCH_POL_GRACE_PERIOD_MINUTES
|
|
998
|
+
ppol.grace_period_subject = PATCH_POL_GRACE_PERIOD_SUBJ
|
|
999
|
+
ppol.grace_period_message = PATCH_POL_GRACE_PERIOD_MSG
|
|
1000
|
+
|
|
1001
|
+
# Self Service deployment
|
|
1002
|
+
if use_ssvc_updates
|
|
1003
|
+
progress "Jamf: Configuring Patch Policy for version '#{version}' of title '#{title}' for Self Service", log: :info
|
|
960
1004
|
|
|
961
|
-
|
|
962
|
-
progress "Jamf: Configuring patch policy for version '#{version}' of title '#{title}' for Self Service'", log: :info
|
|
1005
|
+
ppol.add_to_self_service
|
|
963
1006
|
|
|
964
|
-
|
|
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
|
|
1007
|
+
msg = "#{title_object.display_name} is ready to be updated to version #{version}"
|
|
976
1008
|
|
|
977
|
-
|
|
1009
|
+
ppol.self_service_install_button_text = PATCH_POL_SSVC_INSTALL_BTN_TXT
|
|
1010
|
+
ppol.self_service_description = msg
|
|
1011
|
+
ppol.self_service_notifications_enabled = true
|
|
1012
|
+
ppol.self_service_notification_type = PATCH_POL_SSVC_NOTIFICATION_TYPE
|
|
1013
|
+
ppol.self_service_notification_subject = "#{title_object.display_name} update available"
|
|
1014
|
+
ppol.self_service_notification_message = msg
|
|
1015
|
+
ppol.self_service_reminders_enabled = true
|
|
1016
|
+
ppol.self_service_reminder_frequency = PATCH_POL_SSVC_REMINDER_FREQ_HRS
|
|
1017
|
+
ppol.deadline = PATCH_POL_SSVC_DEADLINE_DAYS
|
|
978
1018
|
|
|
979
|
-
|
|
1019
|
+
return unless title_object.ssvc_icon_id
|
|
1020
|
+
|
|
1021
|
+
set_patch_policy_ssvc_icon ppol, title_object.ssvc_icon_id
|
|
1022
|
+
|
|
1023
|
+
# Automatic deployment
|
|
1024
|
+
else
|
|
1025
|
+
progress "Jamf: Configuring Patch Policy for version '#{version}' of title '#{title}' for automatic deployment", log: :info
|
|
1026
|
+
ppol.remove_from_self_service
|
|
1027
|
+
end
|
|
980
1028
|
end
|
|
981
1029
|
|
|
982
1030
|
# Set an existing ssvc icon for a given patch policy
|
|
@@ -1086,6 +1134,7 @@ module Xolo
|
|
|
1086
1134
|
############################
|
|
1087
1135
|
def set_policy_exclusions(pol, ttl_obj: nil)
|
|
1088
1136
|
ttl_obj ||= title_object
|
|
1137
|
+
|
|
1089
1138
|
# dup, so when we add the installed group below, we don't
|
|
1090
1139
|
# keep that for future calls to this method.
|
|
1091
1140
|
exclusions = excluded_groups_to_use(ttl_obj: ttl_obj).dup
|
|
@@ -1254,7 +1303,7 @@ module Xolo
|
|
|
1254
1303
|
pol = jamf_patch_policy
|
|
1255
1304
|
return unless pol
|
|
1256
1305
|
|
|
1257
|
-
progress "Jamf: Updating
|
|
1306
|
+
progress "Jamf: Updating excluded groups for Patch Policy '#{jamf_patch_policy_name}'."
|
|
1258
1307
|
set_policy_exclusions(pol, ttl_obj: ttl_obj)
|
|
1259
1308
|
pol.save
|
|
1260
1309
|
end
|