Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add policy for ArgoCD healthcheck configuration #500

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stable/CM-Configuration-Management/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ Policy | Description | Prerequisites
[policy-pod](../CM-Configuration-Management/policy-pod.yaml) | Ensures that a pod exists as specified. |
[policy-zts-cmc](../CM-Configuration-Management/policy-zts-cmc.yaml) | This example deploys a replica of \`zts-cmc-deployment\`. | See the [Zettaset README.stable(https://github.com/zettaset/zettaset-public/) to learn more about Zettaset CMC Deployment.
[Scan your cluster with the OpenShift CIS security profile](../CM-Configuration-Management/policy-compliance-operator-cis-scan.yaml) | This example creates a ScanSettingBinding that the ComplianceOperator uses to scan the cluster for compliance with the OpenShift CIS benchmark. | See the [Compliance Operator repository](https://github.com/openshift/compliance-operator) to learn more about the operator. **Note**: The Compliance Operator must be installed to use this policy. See the [Compliance operator policy](../CA-Security-Assessment-and-Authorization/policy-compliance-operator-install.yaml) to install the Compliance Operator with a policy.
[Configure ArgoCD instances with Policy healthchecks](../CM-Configuration-Management/argocd-policy-healthchecks.yaml) | This policy configures healthchecks for open-cluster-management-io Policy kinds on any ArgoCD instances found on the cluster. | See the [Red Hat OpenShift GitOps documentation](https://docs.openshift.com/gitops/) for more information about this operator. |

You can contribute more policies that map to the Configuration Management catalog. See [Contibuting policies](https://github.com/open-cluster-management-io/policy-collection/blob/main/docs/CONTRIBUTING.md) for more details.
162 changes: 162 additions & 0 deletions stable/CM-Configuration-Management/argocd-policy-healthchecks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
apiVersion: policy.open-cluster-management.io/v1
kind: Policy
metadata:
name: argocd-policy-healthchecks
annotations:
policy.open-cluster-management.io/standards: NIST SP 800-53
policy.open-cluster-management.io/categories: CM Configuration Management
policy.open-cluster-management.io/controls: CM-2 Baseline Configuration
policy.open-cluster-management.io/description: >-
This policy configures healthchecks for open-cluster-management-io Policy kinds on any ArgoCD
instances found on the cluster.
spec:
remediationAction: inform
disabled: false
policy-templates:
- objectDefinition:
apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
name: config-argocd-policy-healthchecks
spec:
severity: medium
# Apply the healthcheck configuration to all ArgoCD instances that are
# found - this helps it to work on different environments, and ensures
# that the configuration is not applied before the GitOps operator
# creates the initial instance.
object-templates-raw: |
{{- range (lookup "argoproj.io/v1beta1" "ArgoCD" "" "").items }}
- complianceType: musthave
objectDefinition:
apiVersion: argoproj.io/v1beta1
kind: ArgoCD
metadata:
name: {{ .metadata.name }}
namespace: {{ .metadata.namespace }}
spec:
resourceHealthChecks:
- group: policy.open-cluster-management.io
kind: CertificatePolicy
check: |
hs = {}
if obj.status == nil or obj.status.compliant == nil then
hs.status = "Progressing"
hs.message = "Waiting for the status to be reported"
return hs
end
if obj.status.compliant == "Compliant" then
hs.status = "Healthy"
hs.message = "All certificates found comply with the policy"
return hs
else
hs.status = "Degraded"
hs.message = "At least once certificate does not comply with the policy"
return hs
end
- group: policy.open-cluster-management.io
kind: ConfigurationPolicy
check: |
hs = {}
if obj.status == nil or obj.status.compliant == nil then
hs.status = "Progressing"
hs.message = "Waiting for the status to be reported"
return hs
end
if obj.status.lastEvaluatedGeneration ~= obj.metadata.generation then
hs.status = "Progressing"
hs.message = "Waiting for the status to be updated"
return hs
end
if obj.status.compliant == "Compliant" then
hs.status = "Healthy"
else
hs.status = "Degraded"
end
if obj.status.compliancyDetails ~= nil then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it guaranteed that the flow will reach this point and return, regardless of whether obj.status.compliant == "Compliant" or not? I’m asking because hs.status = "Progressing" is being overridden further down.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. It would have been more clear if I had written it as:

if obj.status.compliancyDetails == nil then
  hs.status = "Progressing"
  hs.message = "Waiting for compliance"
  return hs
end

and I could have put that above the if obj.status.compliant == "Compliant" part.

These checks are already present in the argocd repo, and I'd like to keep them in sync. Since this change would be logically equivalent, I'd rather just keep it as is for now, what do you think?

messages = {}
for i, compliancy in ipairs(obj.status.compliancyDetails) do
if compliancy.conditions ~= nil then
for i, condition in ipairs(compliancy.conditions) do
if condition.message ~= nil and condition.type ~= nil then
table.insert(messages, condition.type .. " - " .. condition.message)
end
end
end
end
hs.message = table.concat(messages, "; ")
return hs
end
hs.status = "Progressing"
hs.message = "Waiting for compliance"
return hs
- group: policy.open-cluster-management.io
kind: OperatorPolicy
check: |
hs = {}
if obj.status == nil or obj.status.conditions == nil then
hs.status = "Progressing"
hs.message = "Waiting for the status to be reported"
return hs
end
if obj.status.observedGeneration ~= nil and obj.status.observedGeneration ~= obj.metadata.generation then
hs.status = "Progressing"
hs.message = "Waiting for the status to be updated"
return hs
end
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Compliant" then
hs.message = condition.message
if condition.status == "True" then
hs.status = "Healthy"
return hs
else
hs.status = "Degraded"
return hs
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for the compliance condition"
return hs
- group: policy.open-cluster-management.io
kind: Policy
check: |
hs = {}
if obj.status == nil or obj.status.compliant == nil then
hs.status = "Progressing"
hs.message = "Waiting for the status to be reported"
return hs
end
if obj.status.compliant == "Compliant" then
hs.status = "Healthy"
else
hs.status = "Degraded"
end
noncompliants = {}
if obj.status.status ~= nil then
-- "root" policy
for i, entry in ipairs(obj.status.status) do
if entry.compliant ~= "Compliant" then
noncompliants[i] = entry.clustername
end
end
if table.getn(noncompliants) == 0 then
hs.message = "All clusters are compliant"
else
hs.message = "NonCompliant clusters: " .. table.concat(noncompliants, ", ")
end
elseif obj.status.details ~= nil then
-- "replicated" policy
for i, entry in ipairs(obj.status.details) do
if entry.compliant ~= "Compliant" then
noncompliants[i] = entry.templateMeta.name
end
end
if table.getn(noncompliants) == 0 then
hs.message = "All templates are compliant"
else
hs.message = "NonCompliant templates: " .. table.concat(noncompliants, ", ")
end
end
return hs
{{- end }}
1 change: 1 addition & 0 deletions stable/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Policy | Description | Prerequisites
[policy-pod](./CM-Configuration-Management/policy-pod.yaml) | Ensures that a pod exists as specified. |
[policy-zts-cmc](./CM-Configuration-Management/policy-zts-cmc.yaml) | This example deploys a replica of \`zts-cmc-deployment\`. | See the [Zettaset README.stable](https://github.com/zettaset/zettaset-public/) to learn more about Zettaset CMC Deployment.
[Scan your cluster with the OpenShift CIS security profile](./CM-Configuration-Management/policy-compliance-operator-cis-scan.yaml) | This example creates a ScanSettingBinding that the ComplianceOperator uses to scan the cluster for compliance with the OpenShift CIS benchmark. | See the [Compliance Operator repository](https://github.com/openshift/compliance-operator) to learn more about the operator. **Note**: The Compliance Operator must be installed to use this policy. See the [Compliance operator policy](./CA-Security-Assessment-and-Authorization/policy-compliance-operator-install.yaml) to install the Compliance Operator with a policy.
[Configure ArgoCD instances with Policy healthchecks](./CM-Configuration-Management/argocd-policy-healthchecks.yaml) | This policy configures healthchecks for open-cluster-management-io Policy kinds on any ArgoCD instances found on the cluster. | See the [Red Hat OpenShift GitOps documentation](https://docs.openshift.com/gitops/) for more information about this operator. |

### Contingency Planning

Expand Down