-
Notifications
You must be signed in to change notification settings - Fork 175
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
fix(frontend): prevent unintended deletion of shared ConfigMaps and Secrets during notebook deletion #3539
fix(frontend): prevent unintended deletion of shared ConfigMaps and Secrets during notebook deletion #3539
Conversation
…ionality in tests
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #3539 +/- ##
========================================
Coverage 85.56% 85.57%
========================================
Files 1342 1371 +29
Lines 31016 31201 +185
Branches 8675 8733 +58
========================================
+ Hits 26538 26699 +161
- Misses 4478 4502 +24
... and 65 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
.filter((envName): envName is ConfigMapRef => !!envName.configMapRef) | ||
.filter( | ||
(envName): envName is ConfigMapRef => | ||
!!envName.configMapRef && envName.configMapRef.name.startsWith(CONFIGMAP_PREFIX), |
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 would not filter by a newly-created configmap or secret name prefix.
Instead, I would suggest by the odh-universal label kex opendatahub.io/managed
(DATA_CONNECTION_AWS) which I think you call
https://github.com/opendatahub-io/odh-dashboard/blob/main/frontend/src/const.ts#L5 DATA_CONNECTION_AWS, but it is in fact just indicating that the secret or configmap are managed by opendatahub.
That label would be the ideal one to go for in filtering. Because we only have the name in envFrom sections, i.e. secretRef.name, we'd need a helper .ts function to get the details of that secret and configmap, if possible.
That function could be used later on in the filtering / selection configmap UI as well when selecting configmaps and secrets from the namespace not already assigned to envFrom that have label opendatahub.io/dashboard
.
Later on, that helper function could also be used to add a property to ConfigmapKind and SecretKind instances setting "manyNotebooks": true if truly referenced in multiple workbenches / notebooks, determining of which of course would require another function ...
Regarding api call volume / frequency: configmaps and secrets per namespace, not created by dashboard, are not changing frequently. Corporate CICD, ArgoCD apply, and so on.
So, any kind of functions / determination could possibly happen at dashboard startup only, similar to the storageClasses info determination at cluster-level.
My main argument against prefix-based filtering remains: how can we assume non-dashboard, CICD type external processes do not create secrets that have configmap or secret not as a postfix, but as a prefix, then, they would still be deleted, would they not?
If we stay the way it is proposed here currently, it would need to be documented in arhcitecture decision records https://github.com/opendatahub-io/architecture-decision-records/tree/main/documentation
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.
My main argument against prefix-based filtering remains: how can we assume non-dashboard, CICD type external processes do not create secrets that have configmap or secret not as a postfix, but as a prefix, then, they would still be deleted, would they not?
yep and that is the biggest issue here.
for api call volume we would be fetching for every resource in env from which may be small yes, but could be huge.
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 could be two-pronged possibly: slow-changing, non-ODH created secrets and configmaps and their info like labels only fetched on first start of dashboard ... and dashboard secrets only fetched by name live, in terms of call volume ...
But then again, that might not be optimal either. Plus, then the logic in dashboard would be more complex, too. I see what you mean by call volume to the API of openshift ...
.filter((envName): envName is SecretRef => !!envName.secretRef) | ||
.filter( | ||
(envName): envName is SecretRef => | ||
!!envName.secretRef && envName.secretRef.name.startsWith(SECRET_PREFIX), |
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.
Lets make sure we also filter for the fixed length of characters (which defaults to 6 today)
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.
sure can do that too
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, good idea. Anyways, I am fine with this intermediate solution. Anything further would need to go into design docs and decision records architecture.
… and secrets in DeleteNotebookModal
frontend/src/api/k8s/configMaps.ts
Outdated
@@ -18,7 +20,7 @@ export const assembleConfigMap = ( | |||
apiVersion: 'v1', | |||
kind: 'ConfigMap', | |||
metadata: { | |||
name: configMapName || `configmap-${genRandomChars()}`, | |||
name: configMapName || `${CONFIGMAP_PREFIX}${genRandomChars()}`, |
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.
Can we tidy this a bit up...
getGeneratedConfigMapName()
isGeneratedConfigMapName(name)
Do the same for the secret as well.
.filter( | ||
(envName): envName is ConfigMapRef => | ||
!!envName.configMapRef && | ||
Boolean(envName.configMapRef.name.match(new RegExp(`^${CONFIGMAP_PREFIX}.{6}$`))), |
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.
.{6}
in regexp can be any 6 characters... they can be all dashes but the last character and still be valid k8s name but not what we are looking for.
The DSPA secret looks for [a-z0-9]{6}
-- I think that is more accurate of a check.
fixes must-parts (not nice-to-have) parts of fixes #3521 thanks for all your work. @andrewballantyne do we went to create a follow-up ticket to https://issues.redhat.com/browse/RHOAIENG-16192 or will we just keep it open longer for tracking purposes? |
@shalberd, @Gkrumbach07 will be logging another ticket momentarily... we discussed it yesterday. |
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.
/hold
Fix the secret name, it's getting kinda bonkers how the code is written and we should try to clean that up imo. But otherwise tested and looks good to me.
follow up jira: https://issues.redhat.com/browse/RHOAIENG-16608 |
… clarity and maintainability
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.
left one small comment, it lgtm overall.
/lgtm
frontend/src/api/k8s/configMaps.ts
Outdated
|
||
export const getGeneratedConfigMapName = (): string => `${CONFIGMAP_PREFIX}${genRandomChars()}`; | ||
export const isGeneratedConfigMapName = (name: string): boolean => | ||
Boolean(name.match(new RegExp(`^${CONFIGMAP_PREFIX}[a-z0-9]{6}$`))); |
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.
Though that might be the same result, just curious, would it be better to use new RegExp(`^${CONFIGMAP_PREFIX}[a-z0-9]{6}$`).test(name)
instead of forcing to cast the type to boolean here? Same question to the other 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.
yeah its cleaner to use test. i made the switch can you readd the lgtm
/lgtm |
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.
/unhold
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: andrewballantyne, DaoDaoNoCode 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:
Approvers can indicate their approval by writing |
https://issues.redhat.com/browse/RHOAIENG-16192
fixes #3521 (we will follow up with more flexibility in the future)
Description
This PR addresses an issue where deleting a notebook would unintentionally delete ConfigMaps and Secrets that might be shared between multiple workbenches. The fix introduces prefix-based filtering to ensure only dashboard-generated resources are deleted.
How Has This Been Tested?
Test Impact
updated delete test
Expected Results
Request review criteria:
Self checklist (all need to be checked):
If you have UI changes:
After the PR is posted & before it merges:
main