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 user-defined compliance messages #280

Conversation

JustinKuli
Copy link
Member

Policy authors can now define go templates to be used for compliance messages, with .DefaultMessage and .Policy fields available for getting useful information. If an error occurs with the template, those details will be appended to the default message. See the CRD description for more details.

This also updates the default compliance message function to use a template, which provides an example of what is possible. The new tests also provide examples.

Refs:

@JustinKuli
Copy link
Member Author

One thing potentially missing here is access to sprig functions like the other template fields provide. It might be helpful to export some of the information in https://github.com/stolostron/go-template-utils/blob/main/pkg/templates/sprig_wrapper.go for usage here.

Copy link
Member

@mprahl mprahl left a comment

Choose a reason for hiding this comment

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

This looks great! I just left a few minor comments.

@mprahl
Copy link
Member

mprahl commented Jul 31, 2024

One thing potentially missing here is access to sprig functions like the other template fields provide. It might be helpful to export some of the information in https://github.com/stolostron/go-template-utils/blob/main/pkg/templates/sprig_wrapper.go for usage here.

I don't think it's necessary but it'd be nice to have the same sprig template functions.

@JustinKuli JustinKuli force-pushed the 12423-custom-compliance-messages branch from ed3c245 to c251d00 Compare July 31, 2024 20:29
mprahl
mprahl previously approved these changes Jul 31, 2024
Copy link
Member

@mprahl mprahl left a comment

Choose a reason for hiding this comment

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

/hold for @dhaiducek

Copy link
Member

@dhaiducek dhaiducek left a comment

Choose a reason for hiding this comment

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

Still reviewing the code logic, but I have some minor comments around the wording to consider.

api/v1/configurationpolicy_types.go Outdated Show resolved Hide resolved
api/v1/configurationpolicy_types.go Outdated Show resolved Hide resolved
controllers/configurationpolicy_controller.go Outdated Show resolved Hide resolved
// Paranoid checks to ensure that the policy has a status of the right format
plcStatus, ok := plcMap["status"].(map[string]any)
if !ok {
goto messageTemplating
Copy link
Member

Choose a reason for hiding this comment

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

Oh goodness. What is this, BASIC programming??? 😆 I had no idea this existed in Go.

Copy link
Contributor

Choose a reason for hiding this comment

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

"any"?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not Go without goto 😆

I'm surprised @mprahl didn't comment on this, I think I've tried to sneak in a goto before... here it's just playing the role of a break statement for the if currentlyUsingWatch section. Maybe I set the whole thing up poorly, but when I try to re-write it without goto, it seems worse to me...

	// Only add the full related object information when it can be pulled from the cache
	if currentlyUsingWatch(plc) {
		skip := false

		// Paranoid checks to ensure that the policy has a status of the right format
		plcStatus, ok := plcMap["status"].(map[string]any)
		if !ok {
			skip = true
		}

		var relObjs []any

		if !skip {
			relObjs, ok = plcStatus["relatedObjects"].([]any)
			if !ok {
				skip = true
			}
		}

		if !skip {
			for i, relObj := range plc.Status.RelatedObjects {
				objNS := relObj.Object.Metadata.Namespace
				objName := relObj.Object.Metadata.Name
				objGVK := schema.FromAPIVersionAndKind(relObj.Object.APIVersion, relObj.Object.Kind)

				fullObj, err := r.getObjectFromCache(plc, objNS, objName, objGVK)
				if err == nil && fullObj != nil {
					if _, ok := relObjs[i].(map[string]any); ok {
						relObjs[i].(map[string]any)["object"] = fullObj.Object
					}
				}
			}
		}
	}

Copy link
Member Author

Choose a reason for hiding this comment

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

@yiraeChristineKim , any is a recent keyword added to go, which just means interface{}, the empty interface. So any is "any" type. It's just shorter to write, which makes some of these type assertions nicer on unstructured things.

Copy link
Member Author

Choose a reason for hiding this comment

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

These assertions really are just paranoia... since it's coming from a properly typed ConfigurationPolicy, I don't think it's possible they could ever fail. But, if they do fail unchecked, it's a panic, so that would be pretty bad.

Copy link
Member

Choose a reason for hiding this comment

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

@JustinKuli I decided to let the "goto" slide even though I don't like them in general. It's prevalent in the Go standard library so I let it be an artistic decision. 😆

Copy link
Contributor

Choose a reason for hiding this comment

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

I like using goto. Great first step @JustinKuli

@JustinKuli
Copy link
Member Author

KinD tests (latest) Flake?
  [FAIL] Test Object deletion Test status fields being set for object deletion [It] should update status fields properly for created objects
  /home/runner/work/config-policy-controller/config-policy-controller/test/e2e/case20_delete_objects_test.go:65
• [FAILED] [62.343 seconds]
Test Object deletion Test status fields being set for object deletion [It] should update status fields properly for created objects
/home/runner/work/config-policy-controller/config-policy-controller/test/e2e/case20_delete_objects_test.go:46

  Timeline >>
  STEP: Creating policy-pod-create-c20 on managed @ 07/31/24 20:34:29.462
  [FAILED] in [It] - /home/runner/work/config-policy-controller/config-policy-controller/test/e2e/case20_delete_objects_test.go:65 @ 07/31/24 20:35:30.822
  << Timeline

  [FAILED] Timed out after 60.001s.
  Expected
      <bool>: false
  to equal
      <bool>: true
  In [It] at: /home/runner/work/config-policy-controller/config-policy-controller/test/e2e/case20_delete_objects_test.go:65 @ 07/31/24 20:35:30.822

`[{"op": "replace", "path": "/spec/remediationAction", "value": "enforce"}]`)

By("Verifying the ConfigurationPolicy becomes Compliant")
Eventually(func() interface{} {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not important maybe string is better for consistency?

@JustinKuli JustinKuli force-pushed the 12423-custom-compliance-messages branch from 9bc5756 to 8e3eab3 Compare August 1, 2024 14:43
@yiraeChristineKim
Copy link
Contributor

/lgtm /hold I like it! test cases are very detailed Thanks, Justin! I added hold for others

customMessage:
description: |-
CustomMessage configures the compliance messages emitted by the configuration policy, to use one
of the specified Go templates based on the current compliance. The data passed to the templates
Copy link
Contributor

Choose a reason for hiding this comment

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

the templates
Maybe is only to me...When I read this, I was confused with policy-template.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not just you, policy templates, object templates, and now message templates get easily confused. I'm not sure what to do about it.

Policy authors can now define go templates to be used for compliance
messages, with .DefaultMessage and .Policy fields available for getting
useful information. If an error occurs with the template, those details
will be appended to the default message. See the CRD description for
more details.

This also updates the default compliance message function to use a
template, which provides an example of what is possible. The new tests
also provide examples.

Refs:
 - https://issues.redhat.com/browse/ACM-12423

Signed-off-by: Justin Kulikauskas <[email protected]>
@JustinKuli JustinKuli force-pushed the 12423-custom-compliance-messages branch from 8e3eab3 to 089c603 Compare August 1, 2024 17:17
@JustinKuli
Copy link
Member Author

KinD tests (minimum) Another (different) flake?
  [FAIL] Test results of namespace selection Checking results of different namespaceSelectors [It] No namespaceSelector specified
  /home/runner/work/config-policy-controller/config-policy-controller/test/e2e/case19_ns_selector_test.go:61
• [FAILED] [67.971 seconds]
Test results of namespace selection Checking results of different namespaceSelectors [It] No namespaceSelector specified
/home/runner/work/config-policy-controller/config-policy-controller/test/e2e/case19_ns_selector_test.go:63

  Timeline >>
  STEP: Applying prerequisites @ 08/01/24 17:23:57.141
  STEP: patching policy with the test selector @ 08/01/24 17:23:59.332
  [FAILED] in [It] - /home/runner/work/config-policy-controller/config-policy-controller/test/e2e/case19_ns_selector_test.go:61 @ 08/01/24 17:24:59.543
  << Timeline

  [FAILED] Timed out after 60.001s.
  Expected
      <string>: configmaps [configmap-selector-e2e] not found in namespaces: case19a-2-e2e, case19a-3-e2e, case19a-4-e2e, case19a-5-e2e, case19b-1-e2e, case19b-2-e2e, case19b-3-e2e, case19b-4-e2e, case9-test, default, innovafertanimvsmvtatasdicereformascorporinnovafertanimvsmvt10, innovafertanimvsmvtatasdicereformascorporinnovafertanimvsmvt11, innovafertanimvsmvtatasdicereformascorporinnovafertanimvsmvt12, innovafertanimvsmvtatasdicereformascorporinnovafertanimvsmvt13, innovafertanimvsmvtatasdicereformascorporinnovafertanimvsmvt14, innovafertanimvsmvtatasdicereformascorporinnovafertanimvsmvt15, kube-case19b-e2e, kube-node-lease, kube-public, kube-system, local-path-storage, managed, olm, open-cluster-management-agent-addon, operator-policy-testns, operators, range1, range2
  to equal
      <string>: namespaced object configmap-selector-e2e of kind ConfigMap has no namespace specified from the policy namespaceSelector nor the object metadata
  In [It] at: /home/runner/work/config-policy-controller/config-policy-controller/test/e2e/case19_ns_selector_test.go:61 @ 08/01/24 17:24:59.543

@JustinKuli
Copy link
Member Author

@mprahl @dhaiducek any more comments for this PR?

Copy link
Member

@mprahl mprahl left a comment

Choose a reason for hiding this comment

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

/unhold

Copy link

openshift-ci bot commented Aug 1, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: JustinKuli, mprahl, yiraeChristineKim

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [JustinKuli,mprahl,yiraeChristineKim]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit 8979505 into open-cluster-management-io:main Aug 1, 2024
9 checks passed
@JustinKuli JustinKuli deleted the 12423-custom-compliance-messages branch August 2, 2024 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants