-
Notifications
You must be signed in to change notification settings - Fork 206
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 Design for Dynamic export of ConfigMap/Secret values #4148
Conversation
116952d
to
961e24b
Compare
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Outdated
Show resolved
Hide resolved
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Show resolved
Hide resolved
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Outdated
Show resolved
Hide resolved
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Show resolved
Hide resolved
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Outdated
Show resolved
Hide resolved
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Outdated
Show resolved
Hide resolved
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Show resolved
Hide resolved
Getting access to data to export to ConfigMaps is pretty easy, we'll just pass the whole `resource` to | ||
the expression. As shown elsewhere fields will be accessible in expressions like `resource.status.id`. |
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 think it may be better to pass in spec
and status
as the two available variables, since everyone will need to index into one or the other first. This would allow us to also add secrets
as a third variable, which is only included if secrets.
exists as a substring in the expression.
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's also metadata though so I think just passing the whole top level object might be cleaner?
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 think the tension here is between making things possible and making common things easy.
Passing just the top level object makes things possible but it forces every usage to incur a little bit of overhead. Passing multiple objects is more complex to implement, but has the benefit of making most usage simpler.
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.
Still not sure I agree. resource.spec.whatever
isn't much more complicated than spec.whatever
.
The advantages to us using top level names we choose are:
- It disambiguates between the resource and its secrets, since for secret usage we'll support
secrets.myKey
. If we control the top-level name of all the inputs (the main 2 right now beingresource
andsecrets
), then we can ensure there are no collisions because we own the top of the path for each input. If we instead snip that part out (for just resource? or for secrets too?) then we run the risk (though it's small) that a top level field such assecrets
collides. - It puts us in a better position to grow in the future by adding other top-level types going forward, such as
operator
(holding operator configuration?) orcluster
(holding cluster details?). I don't know if we're ever going to want to add these but if we did, disambiguating between them at the top level helps with clarity. - It means we're consistent between
resource.x
andsecrets.y
in terms of the pattern, as opposed to doingx
andsecrets.y
. I think includingsecrets
as a prefix for secret values which are not on the resource is very useful from a security/safety point of view because we're making it really obvious the value you're about to output is a secret. Obviously we only support this in the context of saving to secrets so it's not like there's risk of exposing a secret value as plaintext but still the clarity seems a win for something sensitive like secrets.
I'll update the document to discuss this and leave it as an option question at the end of the document.
This interface must be implemented manually alongside the manual implementation of the | ||
`KubernetesExporter` resource. |
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.
If it must be implemented alongside - that is, if it's mandatory - why not extend the existing KubernetesExporter
interface with a second method, to force 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.
Not every KubernetesExporter produces secrets. If all it produces is configmaps we don't need to have the secret specific one
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've clarified this wording some and pointed out we could add the method to the existing interface, but I think a separate interface will ultimately be cleaner. Not married to making a decision here though we can also discuss during implementation.
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Outdated
Show resolved
Hide resolved
value: "'%s:%s'.format([secret.hostName, secret.sslPort])" # Value (format) of the secret | ||
``` | ||
|
||
**ConfigMaps** |
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.
Would we be able to export collections? Most preferably Maps
since we don't support exporting slices yet.
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, though the user might need to write a CEL expression to explain what exactly they want to gather from the map
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 will update the documentation here to be explicit about how this might look in an actual CEL expression, but it is doable for both maps and arrays
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.
Updated the FAQ documentation. It now says:
Q: Can this be used to export a particular item from an arbitrary array or map?
A: Yes! The syntax for maps is:
request.myMap['hello']
, and for arraysrequest.myArray[0]
. CEL has a concept of
macros and there are some useful ones such asfilter
,exists
, andall
built in, so you can craft more complex
expressions likerequest.slice.exists_one(i, i.name=='foo') ? request.slice.filter(i, i.name == 'foo')[0].value : 0
which checks if the slice contains exactly one element whose name isfoo
and if so, gets that elements value,
otherwise returns 0. A similar construct can be done for maps using the sameexists_one
andfilter
macros.
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.
Ah, but what about if you want the whole collection..., let me think on 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.
Ok we can support whole collections too. Here's how:
Q: Can this be used to export entire collections of secret or configmap values?
A: Yes. We will support two flavors of entry into the
dynamicSecrets
anddynamicConfigMaps
collections. One
flavor is the one we've seen above, wherevalue
is a CEL expression that returns astring
and thename
andkey
fields specify which configMap or secret and what key within that to export.The other kind of entry is:
operatorSpec: dynamicConfigMaps: - name: account-data # Name of the destination configMap valueMap: "{"key1": "foo", "key2": "bar"}" # CEL expression that returns a map[string]string
The
valueMap
fields result can be directly saved as keys + values in the resulting configmap or secret, so the author
of the CEL expression has direct control over what values go into their secret/configMap.
Great question @super-harsh.
docs/hugo/content/design/ADR-2024-07-Dynamic-Export-To-Secret-Or-ConfigMap.md
Show resolved
Hide resolved
cfcc024
to
ba97db2
Compare
/ok-to-test sha=ba97db2 |
ba97db2
to
f201536
Compare
/ok-to-test sha=f201536 |
Related to #2555.
If applicable: