@@ -148,7 +148,6 @@ g, admin, role:admin`
148148 },
149149 },
150150 },
151-
152151 Controller : argooperator.ArgoCDApplicationControllerSpec {
153152 Resources : & v1.ResourceRequirements {
154153 Limits : v1.ResourceList {
@@ -247,6 +246,94 @@ g, admin, role:admin`
247246 kinds:
248247 - TaskRun
249248 - PipelineRun` ,
249+ // We can drop this custom Subscription healthcheck once https://www.github.com/argoproj/argo-cd/issues/25921 is fixed
250+ ResourceHealthChecks : []argooperator.ResourceHealthCheck {
251+ {
252+ Group : "operators.coreos.com" ,
253+ Kind : "Subscription" ,
254+ Check : `local health_status = {}
255+ if obj.status ~= nil then
256+ if obj.status.conditions ~= nil then
257+ local numDegraded = 0
258+ local numPending = 0
259+ local msg = ""
260+
261+ -- Check if this is a manual approval scenario where InstallPlanPending is expected
262+ -- and the operator is already installed (upgrade pending, not initial install)
263+ local isManualApprovalPending = false
264+ if obj.spec ~= nil and obj.spec.installPlanApproval == "Manual" then
265+ for _, condition in pairs(obj.status.conditions) do
266+ if condition.type == "InstallPlanPending" and condition.status == "True" and condition.reason == "RequiresApproval" then
267+ -- Only treat as expected healthy state if the operator is already installed
268+ -- (installedCSV is present), meaning this is an upgrade pending approval
269+ if obj.status.installedCSV ~= nil then
270+ isManualApprovalPending = true
271+ end
272+ break
273+ end
274+ end
275+ end
276+
277+ for i, condition in pairs(obj.status.conditions) do
278+ -- Skip InstallPlanPending condition when manual approval is pending (expected behavior)
279+ if isManualApprovalPending and condition.type == "InstallPlanPending" then
280+ -- Do not include in message or count as pending
281+ else
282+ msg = msg .. i .. ": " .. condition.type .. " | " .. condition.status .. "\n"
283+ if condition.type == "InstallPlanPending" and condition.status == "True" then
284+ numPending = numPending + 1
285+ elseif (condition.type == "InstallPlanMissing" and condition.reason ~= "ReferencedInstallPlanNotFound") then
286+ numDegraded = numDegraded + 1
287+ elseif (condition.type == "CatalogSourcesUnhealthy" or condition.type == "InstallPlanFailed" or condition.type == "ResolutionFailed") and condition.status == "True" then
288+ numDegraded = numDegraded + 1
289+ end
290+ end
291+ end
292+
293+ -- Available states: undef/nil, UpgradeAvailable, UpgradePending, UpgradeFailed, AtLatestKnown
294+ -- Source: https://github.com/openshift/operator-framework-olm/blob/5e2c73b7663d0122c9dc3e59ea39e515a31e2719/staging/api/pkg/operators/v1alpha1/subscription_types.go#L17-L23
295+ if obj.status.state == nil then
296+ numPending = numPending + 1
297+ msg = msg .. ".status.state not yet known\n"
298+ elseif obj.status.state == "" or obj.status.state == "UpgradeAvailable" then
299+ numPending = numPending + 1
300+ msg = msg .. ".status.state is '" .. obj.status.state .. "'\n"
301+ elseif obj.status.state == "UpgradePending" then
302+ -- UpgradePending with manual approval is expected behavior, treat as healthy
303+ if isManualApprovalPending then
304+ msg = msg .. ".status.state is 'AtLatestKnown'\n"
305+ else
306+ numPending = numPending + 1
307+ msg = msg .. ".status.state is '" .. obj.status.state .. "'\n"
308+ end
309+ elseif obj.status.state == "UpgradeFailed" then
310+ numDegraded = numDegraded + 1
311+ msg = msg .. ".status.state is '" .. obj.status.state .. "'\n"
312+ else
313+ -- Last possiblity of .status.state: AtLatestKnown
314+ msg = msg .. ".status.state is '" .. obj.status.state .. "'\n"
315+ end
316+
317+ if numDegraded == 0 and numPending == 0 then
318+ health_status.status = "Healthy"
319+ health_status.message = msg
320+ return health_status
321+ elseif numPending > 0 and numDegraded == 0 then
322+ health_status.status = "Progressing"
323+ health_status.message = msg
324+ return health_status
325+ else
326+ health_status.status = "Degraded"
327+ health_status.message = msg
328+ return health_status
329+ end
330+ end
331+ end
332+ health_status.status = "Progressing"
333+ health_status.message = "An install plan for a subscription is pending installation"
334+ return health_status` ,
335+ },
336+ },
250337 Server : argooperator.ArgoCDServerSpec {
251338 Autoscale : argooperator.ArgoCDServerAutoscaleSpec {
252339 Enabled : false ,
0 commit comments