-
Notifications
You must be signed in to change notification settings - Fork 33
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
Reconcile Sub Component Limitador CR #350
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #350 +/- ##
==========================================
+ Coverage 65.69% 66.03% +0.33%
==========================================
Files 37 38 +1
Lines 3842 3901 +59
==========================================
+ Hits 2524 2576 +52
- Misses 1127 1135 +8
+ Partials 191 190 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
918f2a9
to
76290da
Compare
76290da
to
5b43903
Compare
5b43903
to
94bb3f3
Compare
3a887fc
to
6c45659
Compare
@@ -29,6 +31,26 @@ import ( | |||
|
|||
// KuadrantSpec defines the desired state of Kuadrant | |||
type KuadrantSpec struct { | |||
// +optional | |||
Limitador *LimitadorSpec `json:"limitador,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose we don't want the entire limitadorv1alpha1.LimitadorSpec
type here, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. Some spec may be forced by the operator and not user editable. While others are classified as dev/test and should not be easily set in the kuadrant operator.
@Boomatang Can you rebase with main? Running The Istio "istiocontrolplane" is invalid: spec.namespace: Required value
make[4]: *** [sail-install] Error 1
make[3]: *** [istio-install] Error 2
make[2]: *** [local-cluster-setup] Error 2
make[1]: *** [local-env-setup] Error 2
make: *** [local-setup] Error 2 |
6c45659
to
c1ca4ec
Compare
controllers/kuadrant_controller.go
Outdated
if limitador.OwnerReferences != nil && !reflect.DeepEqual(tmp.OwnerReferences, limitador.OwnerReferences) { | ||
return nil | ||
} | ||
|
||
err := r.SetOwnerReference(kObj, limitador) | ||
err = r.SetOwnerReference(kObj, limitador) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this so that if there is an owner reference set on limitador (e.g. not created / managed by kuadrant), then the limitador spec in Kuadrant CR will not be reconciled to the Limitador CR ? 🤔
So, in the case of ownerReference
is nil
(e.g. I just create the Limitador CR manually), the spec defined, if set, in Kuadrant CR will be reconciled to the Limitador CR. Is this the expected behaviour ? 🤔
One weird thing from this setup, unless I'm missing something, is that I expect the ownerRefence to be set to the Limitador
CR in this case, but it isn't on my setup, everything else is reconciled correctly 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a bug here in my mutate function, working on the fix now, but should explain what is going on here.
Firstly the Kuadrant operator expects the limitador CR to be called limitador
and in the same namespace as the Kuadrant CR. The code will not reconcile any limitador resources of a different name or in different namespace.
The reflect.DeepEqual
on line 527 is me being extra safe. I would only expect that to true if the user has its own custom controller that is managing the limitador CR. I could see this being a thing if the user was to use limitador as standalone product before using kuadrant.
So the bug is in the setting of the owner reference if the user manually creates the limitador CR in the same namespace as the kuadrant CR when the kuadrant operator is scaled down for example. Or the real world use case would be if the user was using the limitador as a standalone product and then starts to use kuadrant. In this case you would expect kuadrant to take ownership of the limitador CR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is an edge case. I guess to me, if I were to use limitador standalone first (using the limitador
name) in the kuadrant namespace, having kuadrant take ownership of the CR afterwards may not necessary be expected, as this limitador could be used by other services 🤔 Deleting the kuadrant CR, will then delete this limitador instance, potentially affecting other services using this limitador instance 🤔
Anyhow, just a thought, I don't mind as long as this is expected flow, though maybe best documented somewhere that this will happen at least.
In the case where the limitador CR is managed by another custom controller (due to different owner references), I think a log or a even better a status on the kuadrant CR noting this would be nice, since it is not obvious to the user that the limitador spec defined in the Kuadrant CR will not be reconciled due to this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Kevin here, and to add a bit more, it could be a common scenario to have a limitador instance in the cluster with its default name limitador
, thus Kuadrant should not take ownership if not explicitly declared in the Kuadrant CR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it could be common to have any existing limitador CRs called limitador
on the cluster. But let me ask this question. If you have a limitador instance that you do not want kuadrant to manage, why would you create the kuadrant CR in the same namespace as the existing limitador CR? Next question I would ask, can limitador work with two limitador CRs in the same namespace?
ed429c6
to
c029047
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good generally 👍 Have 2 comments 🧑💻
controllers/kuadrant_controller.go
Outdated
tmp := &limitadorv1alpha1.Limitador{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: common.LimitadorName, | ||
Name: "temp", | ||
Namespace: kObj.Namespace, | ||
}, | ||
Spec: limitadorv1alpha1.LimitadorSpec{ | ||
RateLimitHeaders: &[]limitadorv1alpha1.RateLimitHeadersType{limitadorv1alpha1.RateLimitHeadersTypeDraft03}[0], | ||
Telemetry: &[]limitadorv1alpha1.Telemetry{limitadorv1alpha1.TelemetryExhaustive}[0], | ||
}, | ||
} | ||
err = r.SetOwnerReference(kObj, tmp) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if limitador.OwnerReferences != nil && !reflect.DeepEqual(tmp.OwnerReferences, limitador.OwnerReferences) { | ||
logger.Error(fmt.Errorf("limitador CR owned by different controller: %v", limitador.OwnerReferences[0].Name), "check limitador CR ownerReference") | ||
return nil | ||
} | ||
|
||
err := r.SetOwnerReference(kObj, limitador) | ||
err = r.SetOwnerReference(kObj, limitador) | ||
if err != nil { | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking at controllerutil SetControllerReference
method, it seems to return an AlreadyOwnedError
in the case where the obj is already owned by another controller.
So I wonder can this be simplified to this without needing to have a tmp obj here:
err = r.SetOwnerReference(kObj, limitador)
if err != nil {
var alreadyOwnedError *controllerutil.AlreadyOwnedError
if errors.As(err, &alreadyOwnedError) {
logger.Error(alreadyOwnedError, "check limitador CR ownerReference")
return nil
}
return err
}
Also, can you add a unit test here to test this behaviour ?
controllers/kuadrant_status.go
Outdated
@@ -94,7 +95,7 @@ func (r *KuadrantReconciler) readyCondition(ctx context.Context, kObj *kuadrantv | |||
return cond, nil | |||
} | |||
|
|||
reason, err := r.checkLimitadorReady(ctx, kObj) | |||
reason, err := r.checkLimitador(ctx, kObj) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of differing owner ref, condition will be set to LimitadorNotReady
with message Unable to reconcile limitador CR, Own Reference belongs to different controller
.
Do we view Kuadrant
is ready or not in this state ? All components could be up and Limitador is technically ready in the "unmanaged state" but since the resource is owned by another controller, there is really nothing we can do 🤔 Though i realise this this a nitpick on an edge case 🤷
c029047
to
f428dc4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verified and code looks good to me as we've decided to have a follow up ticket instead on if the edge case of the limitador used is owned by another custom controller 👍
There's failing integration tests, but not sure it related to this PR 🤷
The failing integration tests where cause by the edge case that was found during this time. Where a second kuadrant CR was trying to take ownership of the limitador CR, which was owned by the first kuadrant CR. In this case the integration tests required a small refactor. |
I'm getting the following error when running error: no objects passed to apply
make[4]: *** [sail-install] Error 1
make[3]: *** [istio-install] Error 2
make[2]: *** [local-cluster-setup] Error 2
make[1]: *** [local-env-setup] Error 2
make: *** [local-setup] Error 2 |
@didierofrivia The istio-operator removed the manifests on Friday. Its an error on related to these changes. You can try |
This error is from sail (again) #400, addressed partially in #395. For now you can run with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
works as expected! noted regarding the edge case, and probably we might want to address limitador instance naming too in that following issue (?)
Good job! 🎖️
Part of: #307
Closes: #163
RFC: https://github.com/Kuadrant/architecture/blob/main/rfcs/0006-kuadrant_sub_components_configurations.md
The changes here allow a user to configure the setting in the Limitador CR from the kuadrant CR.
Verification
make local-setup
.kubectl apply -f https://raw.githubusercontent.com/Boomatang/k8s_configs/kuadrant-operator-PR350/manifest/kuadrant_spec_limitador.yaml
Use Case:
Existing Limitador Users
It is possible that a user can be using limitador as a standalone product before using kuadrant. In the case where the user named the limitador CR
limitador
and places the kuadrant CR in the same namespace, the kuadrant operator will take ownership of the limitador CR. This will be done by setting the ownerReference in the limitador CR.Validating this use case.
ownerReference
block from the metadata.spec
switches to that defined in the kuadrant CRownerReference
is set to the kuadrant operator