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

[DevEx] controller/rbac: edge based events for applies #4307

Merged

Conversation

sttts
Copy link
Contributor

@sttts sttts commented Jul 10, 2023

Description of your changes

The Applied RBAC roles event is repeated again and again:

default          9m59s (x450 over 3d4h)   Normal    ApplyRoles               Namespace/upbound-system                                         Applied RBAC Roles
default          9m59s (x455 over 3d4h)   Normal    ApplyRoles               Namespace/default                                                Applied RBAC Roles
default          9m59s (x440 over 3d4h)   Normal    ApplyRoles               Namespace/kube-system                                            Applied RBAC Roles
default          9m59s (x437 over 3d4h)   Normal    ApplyRoles               Namespace/kube-public                                            Applied RBAC Roles
default          9m59s (x484 over 3d4h)   Normal    ApplyRoles               Namespace/kube-node-lease                                        Applied RBAC Roles

Similar for

default          2m39s (x13 over 69m)     Normal   BindClusterRole          ProviderRevision/upbound-provider-aws-s3-dbc7f981d81f       Bound system ClusterRole to provider ServiceAccount(s)
default          2m39s (x13 over 69m)     Normal   BindClusterRole          ProviderRevision/upbound-provider-family-aws-d095ac1e13dd   Bound system ClusterRole to provider ServiceAccount(s)

This PR supresses the events if nothing happens, and it prints up to the first 3 role names in case it's not an noop. With that the event is actually useful.

I have:

  • Read and followed Crossplane's contribution process.
  • Added or updated unit and E2E tests for my change.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR if necessary.

@sttts sttts requested review from a team and negz as code owners July 10, 2023 14:27
@sttts sttts requested a review from MisterMX July 10, 2023 14:27
Copy link
Member

@jbw976 jbw976 left a comment

Choose a reason for hiding this comment

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

Seems reasonable to only create an event when we do something - do you have an example from your testing of what events in this style look like now?

@@ -210,9 +213,15 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco
}

log.Debug("Applied RBAC Role")
Copy link
Member

Choose a reason for hiding this comment

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

would it be useful in this debug log statement to include the name of the RBAC role that was just applied?

Copy link
Contributor Author

@sttts sttts Jul 10, 2023

Choose a reason for hiding this comment

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

it actually is, look the log.WithValues above :) Had the same thought.

}

r.record.Event(ns, event.Normal(reasonApplyRoles, "Applied RBAC Roles"))
sort.Strings(applied)
if len(applied) > 3 {
Copy link
Member

Choose a reason for hiding this comment

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

is this > 3 pattern pretty common in upstream k8s? i feel like i may have seen this before - not 💯 on it though, as I have hazy memories of thinking to myself "well why didn't you just tell me the rest of them too then?" 😂

more curious than anything - not blocking from me 😁

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we use something like that in OpenShift. No strong opinions. I thought 3 is a good number :) 10 might be too.

@sttts sttts force-pushed the sttts-namespace-reconciler-rbac-event branch 2 times, most recently from 7dce9bd to c72cfaf Compare July 10, 2023 15:11
@sttts sttts changed the title controller/rbac/namespace: edge based events for role updates controller/rbac/{provider,namespace}: edge based events for applies Jul 10, 2023
@sttts sttts force-pushed the sttts-namespace-reconciler-rbac-event branch from c72cfaf to 6ec954e Compare July 10, 2023 15:22
@sttts sttts changed the title controller/rbac/{provider,namespace}: edge based events for applies controller/rbac: edge based events for applies Jul 10, 2023
Copy link
Member

@negz negz 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, thank you. FWIW there's a similar event WRT selecting a Composition in the XR controller that I've been meaning to fix if you're feeling motivated to do so.

Few style nits, but nothing blocking.

internal/controller/rbac/provider/binding/reconciler.go Outdated Show resolved Hide resolved
Comment on lines 203 to 206
if len(applied) > 3 {
r.record.Event(d, event.Normal(reasonApplyRoles, fmt.Sprintf("Applied RBAC ClusterRoles: %s, %s, %s, and %d more", applied[0], applied[1], applied[2], len(applied)-3)))
} else if len(applied) > 0 {
r.record.Event(d, event.Normal(reasonApplyRoles, fmt.Sprintf("Applied RBAC ClusterRoles: %s", strings.Join(applied, ", "))))
Copy link
Member

Choose a reason for hiding this comment

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

Given this pattern is repeated a few times I wonder whether a little utility could help? I'm on the fence. Normally I prefer to avoid such little utilities for things like this, until they're almost everywhere, but I must admit I'm a little (unreasonably?) allergic to if then else statements.

I'm thinking something like:

r.record.Event(d, event.Normal(reasonApplyRoles, maybeTruncate("Applied RBAC ClusterRoles", applied)))

// maybeTruncate needs a better name :)
func maybeTruncate(prefix string, names []string) string {
	if len(names) > 3 {
		return fmt.Sprintf("%s: %s, and %d more", prefix, strings.Join(names[:3], ", "), len(names)-3)
	}
	return fmt.Sprintf("%s: %s", prefix, strings.Join(names, ", "))
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added. Any good place to put it? Have 3 copies now.

Copy link
Member

Choose a reason for hiding this comment

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

I could imagine this being added as a utility in crossplane-runtime somewhere (not sure which package). I'm fine leaving a few copies scattered around for now though - we can figure out a better home if and when it becomes more widely used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack. Leaving it. We can deduplicate later.

@negz
Copy link
Member

negz commented Jul 10, 2023

PS the PR / checklist-completed check is failing because it wants you to explicitly ~strikethrough~ any checklist items that you don't intend to do for this PR.

@sttts sttts requested a review from muvaf as a code owner July 11, 2023 12:25
@@ -528,8 +529,12 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco
return reconcile.Result{Requeue: true}, errors.Wrap(r.client.Status().Update(ctx, cm), errUpdateClaimStatus)
}

log.Debug("Successfully applied composite resource")
record.Event(cm, event.Normal(reasonCompositeConfigure, "Successfully applied composite resource"))
if oldRV != cp.GetResourceVersion() {
Copy link
Contributor Author

@sttts sttts Jul 11, 2023

Choose a reason for hiding this comment

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

@negz not sure I am a fan of this construct. Am open for better patterns.

See my comments about the available applicators in Slack.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps something like:

err := r.client.Apply(ctx, cp, resource.AllowUpdateIf(func(current, desired) bool { !cmp.Equal(current, desired) }))
switch {
case resource.IsNotAllowed(err):
	log.Debug("Skipped no-op composite resource apply")
case err != nil:
	// Current error handling block
default:
	log.Debug("Successfully applied composite resource")
	record.Event(cm, event.Normal(reasonCompositeConfigure, "Successfully applied composite resource"))
}

I believe this would disallow the apply (i.e. patch) entirely if this reconcile didn't actually change cp. Using cmp.Equal on the entire *Unstructured feels inelegant but this approach at least seems syntactically more pleasant to me.

https://pkg.go.dev/github.com/crossplane/crossplane-runtime@v0.19.2/pkg/resource#AllowUpdateIf

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was wondering whether this can still lead to multiple events when the informers are lagging behind. Just because an update is attempted does not mean an actual update happened.

Copy link
Member

Choose a reason for hiding this comment

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

Was wondering whether this can still lead to multiple events when the informers are lagging behind.

FWIW I think the controller-runtime machinery automatically dedupes multiple events in the queue to result in one reconcile call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

and in any case this will eventually settle. If two or more, but few events are creating on rare races, that's fine. Just cosmetics (different to the RV topic in the applicator which is about consistency).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

@sttts sttts changed the title controller/rbac: edge based events for applies [DevEx] controller/rbac: edge based events for applies Jul 11, 2023
@sttts sttts force-pushed the sttts-namespace-reconciler-rbac-event branch 5 times, most recently from f26326f to cb730d8 Compare July 11, 2023 13:32
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
…nding apply

Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
@sttts sttts force-pushed the sttts-namespace-reconciler-rbac-event branch from cb730d8 to fd64e44 Compare July 11, 2023 15:01
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
@sttts sttts force-pushed the sttts-namespace-reconciler-rbac-event branch from fd64e44 to 4a0bb29 Compare July 14, 2023 10:10
@turkenh turkenh merged commit 91a1e06 into crossplane:master Jul 31, 2023
16 checks passed
@jbw976 jbw976 added this to the v1.14 milestone Aug 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

4 participants