-
Notifications
You must be signed in to change notification settings - Fork 98
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
feat: Introduce the Features Factory #412
Conversation
b1344e5
to
da281a5
Compare
Codecov Report
@@ Coverage Diff @@
## main #412 +/- ##
=======================================
Coverage 60.60% 60.60%
=======================================
Files 3 3
Lines 132 132
=======================================
Hits 80 80
Misses 40 40
Partials 12 12
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report at Codecov.
|
524c60f
to
d2579c9
Compare
bb39d31
to
fbc5410
Compare
type Feature interface { | ||
// Configure use to configure the internal of a Feature | ||
// It should return `true` if the feature is enabled, else `false`. | ||
Configure(dda *v2alpha1.DatadogAgent) bool |
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 function both altering the DatadogAgent spec and checking if the feature is enabled?
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.
From the ksmcore example it seems only the latter, in which case maybe we can call it IsConfigured
or IsEnabled
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.
yes the idea it to extra the information needed from the DatadogAgent
. like this we don't need to access again the resource after when processing the feature
e68a192
to
bb4ee42
Compare
// OperatorStoreLabelKey used to identified which resource is managed by the store. | ||
OperatorStoreLabelKey = "operator.datadoghq.com/managed-by-store" | ||
// OperatorGenHashAnnotationKey annotation key used on a Resource in order to compare 2 resources without know the spec struct. | ||
OperatorGenHashAnnotationKey = "operator.datadoghq.com/gen-hash" |
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.
Not used, could be easily implemented in the store, no?
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.
it already the case and used here:
- https://github.com/DataDog/datadog-operator/pull/412/files#diff-48d116016241a7d62a8614e21fc9b23f37962ca9d1bb54fa2ee5abd447709ed3R74
- https://github.com/DataDog/datadog-operator/pull/412/files#diff-48d116016241a7d62a8614e21fc9b23f37962ca9d1bb54fa2ee5abd447709ed3R146
I can move it to private
return false | ||
} | ||
|
||
func (f *dummyFeature) ConfigureV1(dda *v1alpha1.DatadogAgent) bool { |
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.
Should not be necessary with conversion in place
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.
Agree, But for now. I use it to validate the PR in #430
we can easily remove it later
// ManageDependencies allows a feature to manage its dependencies. | ||
// Feature's dependencies should be added in the store. | ||
func (f *dummyFeature) ManageDependencies(store feature.DependenciesStoreClient) error { | ||
return nil |
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.
With the store API, it means each deps need to do:
Get -> Check if nil -> Not nil: Update
-> Nil: Create
I think we should think about how to improve this experience before implementing features?
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.
IMO dependencies are not so often shared between features.
I was thinking to create a function GetOrCreate
that return the instance or create a new instance automatically.
then the Store
have a fuction AddOrUpdate
so it doesn't need to know if the resource already exist in the API server.
I'm open to other idea
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 thinking about Roles
for instance (or ConfigMap
if we decide to move all configs to datadog.yaml
). Having a GetOrCreate
may not be useful as you will still need to check if the object is newly created or not to fill some fieds.
I think we way want to have Managers
on top of the store. Like the RBACManager
, offering a high level API like AddPermissions(serviceAccount, roleName, permissions)
and when Apply
is called on the store, it lazily generates the necessary objects.
About the comment below, your intention looks like a PodTemplateManager
to me, with its helper functions to manage each piece.
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.
@vboulineau
I have added a new commit with a RBACManager
b0722e2
} | ||
|
||
// PodFeatureConfiguration use to store a Pod Feature Configuration. | ||
type PodFeatureConfiguration struct { |
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'm not sure to understand how this will be used, wasn't able to find any reference?
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 a tentative to implement your proposition about not exposing the PodTemplate
to feature function but only a subset of what can be configured.
But I haven't found a good implementation. It made me think that it was more clear to share the PodTemplate. and provide helper fonction to add|update|remove
envvar, volume, volumemount.
3e6a95e
to
42c1ff4
Compare
42c1ff4
to
06ed743
Compare
39f3a0e
to
523c55f
Compare
89b4697
to
67e92b7
Compare
9814ca2
to
4751c1b
Compare
c4db9a3
to
f0e8997
Compare
// Manage dependencies | ||
// ----------------------- | ||
depsStore := dependencies.NewStore(&dependencies.StoreOptions{SupportCilium: r.options.SupportCilium}) | ||
rbacManager := feature.NewResourcesManagers(depsStore) |
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.
should this be generalized to resourceManager
instead of rbacManager
?
f0e8997
to
c6adf6e
Compare
What does this PR do?
This draft PR is here to illustrate how the Feature Factory can improve the generically of the DatadogAgent controller logic.
Motivation
Additional Notes
Some code entry point:
Then the new Reconcile function is define here: https://github.com/DataDog/datadog-operator/blob/clamoriniere/generic-reconciler/controllers/datadogagent/reconcilerv2.go
Describe your test plan
Write there any instructions and details you may have to test your PR.