github.com/argoproj/argo-cd/v3@v3.2.1/resource_customizations/promoter.argoproj.io/PromotionStrategy/health.lua (about) 1 local hs = {} 2 hs.status = "Progressing" 3 hs.message = "Initializing promotion strategy" 4 5 -- Check for deletion timestamp 6 if obj.metadata.deletionTimestamp then 7 hs.status = "Progressing" 8 hs.message = "Promotion strategy is being deleted" 9 return hs 10 end 11 12 -- Check if status exists 13 if not obj.status then 14 return hs 15 end 16 17 -- Check for reconciliation conditions 18 local hasReadyCondition = false 19 if obj.status.conditions then 20 for _, condition in ipairs(obj.status.conditions) do 21 if condition.type == "Ready" then 22 hasReadyCondition = true 23 -- Check observedGeneration vs metadata.generation within the reconciliation condition 24 if condition.observedGeneration and obj.metadata.generation and condition.observedGeneration ~= obj.metadata.generation then 25 hs.status = "Progressing" 26 hs.message = "Waiting for promotion strategy spec update to be observed" 27 return hs 28 end 29 -- Check for any False condition status 30 if condition.status == "False" then 31 hs.status = "Degraded" 32 local msg = condition.message or "Unknown error" 33 local reason = condition.reason or "Unknown" 34 -- Don't include ReconciliationError in the message since it's redundant 35 if reason == "ReconciliationError" then 36 hs.message = "Promotion strategy reconciliation failed: " .. msg 37 else 38 hs.message = "Promotion strategy reconciliation failed (" .. reason .. "): " .. msg 39 end 40 return hs 41 end 42 end 43 end 44 end 45 46 -- If no Ready condition is found, return Progressing status 47 if not hasReadyCondition then 48 hs.status = "Progressing" 49 hs.message = "Promotion strategy is not ready yet" 50 return hs 51 end 52 53 if not obj.status.environments or #obj.status.environments == 0 then 54 hs.status = "Degraded" 55 hs.message = "Promotion strategy has no environments configured" 56 return hs 57 end 58 59 -- Make sure there's a fully-populated status for both active and proposed commits in all environments. If anything is 60 -- missing or empty, return a Progressing status. 61 for _, env in ipairs(obj.status.environments) do 62 if not env.active or not env.active.dry or not env.active.dry.sha or env.active.dry.sha == "" then 63 hs.status = "Progressing" 64 hs.message = "The active commit DRY SHA is missing or empty in environment '" .. env.branch .. "'." 65 return hs 66 end 67 if not env.proposed or not env.proposed.dry or not env.proposed.dry.sha or env.proposed.dry.sha == "" then 68 hs.status = "Progressing" 69 hs.message = "The proposed commit DRY SHA is missing or empty in environment '" .. env.branch .. "'." 70 return hs 71 end 72 end 73 74 -- Check if all the proposed environments have the same proposed commit dry sha. If not, return a Progressing status. 75 local proposedSha = obj.status.environments[1].proposed.dry.sha -- Don't panic, Lua is 1-indexed. 76 for _, env in ipairs(obj.status.environments) do 77 if env.proposed.dry.sha ~= proposedSha then 78 hs.status = "Progressing" 79 hs.message = "Not all environments have the same proposed commit SHA. This likely means the hydrator has not run for all environments yet." 80 return hs 81 end 82 end 83 84 -- Helper function to get short SHA 85 local function getShortSha(sha) 86 if not sha or sha == "" then 87 return "" 88 end 89 if string.len(sha) > 7 then 90 return string.sub(sha, 1, 7) 91 end 92 return sha 93 end 94 95 -- Find the first environment with a proposed commit dry sha that doesn't match the active one. Loop over its commit 96 -- statuses and build a summary about how many are pending, successful, or failed. Return a Progressing status for this 97 -- in-progress environment. 98 for _, env in ipairs(obj.status.environments) do 99 if env.proposed.dry.sha ~= env.active.dry.sha then 100 local pendingCount = 0 101 local successCount = 0 102 local failureCount = 0 103 local pendingKeys = {} 104 local failedKeys = {} 105 106 -- pending, success, and failure are the only possible values 107 -- https://github.com/argoproj-labs/gitops-promoter/blob/c58d55ef52f86ff84e4f8fa35d2edba520886e3b/api/v1alpha1/commitstatus_types.go#L44 108 for _, status in ipairs(env.proposed.commitStatuses or {}) do 109 if status.phase == "pending" then 110 pendingCount = pendingCount + 1 111 table.insert(pendingKeys, status.key) 112 elseif status.phase == "success" then 113 successCount = successCount + 1 114 elseif status.phase == "failure" then 115 failureCount = failureCount + 1 116 table.insert(failedKeys, status.key) 117 end 118 end 119 120 hs.status = "Progressing" 121 hs.message = 122 "Promotion in progress for environment '" .. env.branch .. 123 "' from '" .. getShortSha(env.active.dry.sha) .. 124 "' to '" .. getShortSha(env.proposed.dry.sha) .. "': " .. 125 pendingCount .. " pending, " .. successCount .. " successful, " .. failureCount .. " failed. " 126 127 if pendingCount > 0 then 128 hs.message = hs.message .. "Pending commit statuses: " .. table.concat(pendingKeys, ", ") .. ". " 129 end 130 if failureCount > 0 then 131 hs.message = hs.message .. "Failed commit statuses: " .. table.concat(failedKeys, ", ") .. ". " 132 end 133 return hs 134 end 135 end 136 137 -- Check all environments for active commit statuses that aren't successful. For each environment with a non-successful 138 -- commit status, get a count of how many aren't successful. Write a summary of non-successful environments. 139 local nonSuccessfulEnvironments = {} 140 for _, env in ipairs(obj.status.environments) do 141 local pendingCount = 0 142 local failureCount = 0 143 144 for _, status in ipairs(env.active.commitStatuses or {}) do 145 if status.phase == "pending" then 146 pendingCount = pendingCount + 1 147 elseif status.phase == "failure" then 148 failureCount = failureCount + 1 149 end 150 end 151 152 if pendingCount > 0 or failureCount > 0 then 153 nonSuccessfulEnvironments[env.branch] = { 154 pending = pendingCount, 155 failure = failureCount, 156 } 157 end 158 end 159 160 if next(nonSuccessfulEnvironments) then 161 local envMessages = {} 162 for branch, counts in pairs(nonSuccessfulEnvironments) do 163 local msg = branch .. " (" .. counts.failure .. " failed, " .. counts.pending .. " pending)" 164 table.insert(envMessages, msg) 165 end 166 hs.status = "Healthy" 167 hs.message = "Environments are up-to-date, but some environments have non-successful commit statuses: " .. table.concat(envMessages, ", ") .. "." 168 return hs 169 end 170 171 172 -- If all environments have the same proposed commit dry sha as the active one, we can consider the promotion strategy 173 -- healthy. This means all environments are in sync and no further action is needed. 174 hs.status = "Healthy" 175 hs.message = "All environments are up-to-date on commit '" .. getShortSha(obj.status.environments[1].proposed.dry.sha) .. "'." 176 return hs