rancher/dashboard PR 19793 (codyrancher), re-requested after 2504b41ff, reviewed 2026-11-05. Round one is here, though its preview links now show the new code.
Preview: rancherpr19793r.mf-created-dashboard.ui.rancher.space, built from 2504b41ff, backend mf Rancher (v2.16.0-7758e3e-head). PR + no-clear: rancherpr19793-fixr.mf-created-dashboard.ui.rancher.space, built from bdbbd7de2, which is the PR with card 1's change, local only and not pushed. Baseline: the shared dashboard-master preview, rebuilt today from 261b8932f, the current tip.
secrets-ns1, as Cody says.null. On the Secret form the Namespace field disappears, and on chart install it can end up targeting default with a blank field. Normal users reach it by filtering the top nav to a read-only project. Master doesn't do this.allowedNamespaces as deprecated is a fair call.Branch Milestone, and the kubewarden e2e passes this time. Nothing is posted, and suggested text is at the bottom.Click Log in as a local user, then use issue-8544-member. The password is in ~/Projects/pr-reviews/pr19793-fixtures/password.txt on your Mac.
namespaces "default" already exists. It only sends a request, and nothing gets installed for this user.| Your comment | Cody's answer | Checked on the new build |
|---|---|---|
| The namespace the form opens on isn't checked. A read-only namespace that sorts first opens selected and listed, and Create is forbidden. | "when the check returns, a pre-selected namespace that exists but does not allow creating the type moves to the first allowed one, or is cleared if there is none." | The move works. It opens on secrets-ns1 for issue-8544-first and issue-8544-cm, on Secret, Deployment and chart install. Create returned 201. The "or is cleared" half is card 1. |
allowedNamespaces has lost its last real use. Maybe keep it on shell or find a use, mostly pointing it out. | "Kept it because it is a root-store getter extensions can call", marked @deprecated. "Happy to remove it in this PR if you would rather." | Fair. A runtime break for third-party extensions isn't worth it for a few lines. Deprecated is what I'd accept. The unused fixture line in the test and the unread mapGetters entry remain, and neither is worth another round. |
| This file is quite small, and Richard usually pushes against new utils. | "I'm fine to consolidate. Moving it to NamespaceSelect and the tests into NamespaceSelect.test.ts." | Done. The file and its test file are gone. The function now uses the component's own store, so store: any went with it. const namespaces: any[] remains, which isn't worth raising. |
When no namespace in the list allows creating, the commit does namespace.value = null and emits null. Nothing else in the forms expected a null namespace. The select's own empty value is '', and the emit type had to be widened to string | null just for this.
namespaces "default" already exists.(val = '') => val.length, and a default parameter doesn't apply to null, so the select throws Cannot read properties of null (reading 'length') while rendering and Vue leaves nothing in its place. The user has no way to pick a namespace and no message. Create stays disabled.default. The wizard doesn't check the field, so Proceed and Install are enabled. targetNamespace falls back to 'default':
default, createNamespaceIfNeeded tries to create it and fails with namespaces "default" already exists.namespace: null. Rancher's namespace() in helmop/operation.go turns an empty value into "default". So someone with rights in default could install there with a blank field. I read that part in the source and intercepted the request, so no real install ran.typeToCheck doesn't skip that. A throwaway unit test confirmed the value is cleared on a select the user can't change. This one is from the unit test only; I didn't run that form in a browser.Anyone with no creatable namespace in the current list, which is more than users with no rights at all. issue-8544-member can create in another project but gets here just by filtering the top nav to a read-only project, because the list stays inside the filter.
Drop the else branch and put the emit type back to string, so the value stays as it is when nothing is allowed. That matches master: the namespace shows, and Create gives the clear "forbidden" message from the server. All the problems above share this one cause, so they all go away, and it's fewer lines.
Switching null to '' looks tempting but only helps Secret. targetNamespace treats both as empty, so chart install would still target default.
Tested: the 2 touched suites pass (60 tests, with Cody's clears test changed to expect the value kept), lint is clean, and there are no new type errors. In the browser with the same filter, Secret, ConfigMap and chart install all match master, and the chart request goes out with view-only-ns, not null.
--- a/shell/components/form/NamespaceSelect.vue
+++ b/shell/components/form/NamespaceSelect.vue
@@ -51,7 +51,7 @@ interface Props {
createAllowed?: boolean;
/**
* schema id of the resource being created; in create mode only namespaces the user may create it in are listed, and
- * an existing pre-selected namespace the user may not create it in is replaced by the first one listed (or cleared)
+ * an existing pre-selected namespace the user may not create it in is replaced by the first one listed
*/
resourceType?: string | null;
rules?: Validator[];
@@ -84,7 +84,7 @@ const props = withDefaults(defineProps<Props>(), {
required: false,
});
-const emit = defineEmits<{(e: 'update:value', value: string | null): void, (e: 'isNamespaceNew', value: boolean): void}>();
+const emit = defineEmits<{(e: 'update:value', value: string): void, (e: 'isNamespaceNew', value: boolean): void}>();
const store = useStore();
const { t } = useI18n(store);
@@ -262,9 +262,6 @@ function leaveNamespaceNotAllowingCreate(allowed: Set<string>) {
if (firstAllowed) {
emitChange(firstAllowed);
- } else {
- namespace.value = null;
- emit('update:value', null);
}
}
You raised keeping the value in your review. My earlier fix only moved the automatic default, while Cody's moves any existing namespace the user can't create in. So cloning a ConfigMap from a read-only namespace now opens on the first allowed namespace, without saying so. I think that's better: the user couldn't have saved in the source anyway, the new namespace is visible before saving, and a clone from an allowed namespace stays where it was. Nothing to raise unless you feel differently.
| Starting value | master | PR | Right? |
|---|---|---|---|
Automatic default, not allowed (issue-8544-first, issue-8544-cm) | stays, Create forbidden | moves to secrets-ns1 | Yes |
Last-used, allowed (secrets-ns2) | not run | stays on secrets-ns2 | Yes |
Last-used, not allowed (view-only-ns) | not run | moves to secrets-ns1 | Yes |
Clone, source allowed (secrets-ns2) | stays | stays | Yes |
Clone, source read-only (view-only-ns) | stays, listed | moves to secrets-ns1 | Yes, see card 2 |
| New namespace typed on chart install, then Proceed and Back | not run | stays on zz-pr19793-typed | Yes |
| Check fails (forced 500) | no check on master | stays, every namespace listed | Yes |
| Nothing allowed in the list | stays, Create forbidden | cleared to null | No, card 1 |
| Check | Result |
|---|---|
| Lists, master vs PR | 5 users across Secret, ConfigMap, Deployment and chart install. Member lists are unchanged, and issue-8544 and issue-8544-first list the correct two namespaces. |
Does a cleared namespace fall into default on normal creates? | No. Steve rejects a missing namespace, and ConfigMap never sends the request. Only chart install has the fallback. |
| Round one's checks | The permission truth table and top-nav filter tests ran on ee30ed3c4. The check logic only moved in this commit, so I didn't rerun the truth table. The lists above still match. |
| Tests on the PR head | The 2 touched suites pass (60 tests). No new type errors, and lint is clean. |
CI at 2504b41ff | All green except Branch Milestone, which fails on the other 2.17 PRs too. The kubewarden e2e passes this time. |
| Description | The setup script now uses aaa-view-ns, so it shows the case. The Harvester line is still there because the note was cut from the submitted review. Not worth raising alone, and you could mention it if you comment anyway. |
| Side effects of testing | One real Secret was created to check Cody's claim, then removed. No installs, operations or typed namespaces exist, and the fixture users' preferences are reset. |
Your usual shape: an intro, one inline comment, no code and no preview link. If you want the screenshots from card 1 on it, they still need uploading. I'd also resolve the shell/utils thread and answer Cody's question on the allowedNamespaces one.
The move works well, thanks. It opens on an allowed namespace now and keeps a value the user can create in. One more thing on the clear path.
shell/components/form/NamespaceSelect.vue, line 265Could we drop this branch and leave the value as it is when nothing is allowed? A user can get here just by filtering the top nav to a read-only project.
On the Secret form the Namespace field disappears. Its validators use (val = '') => val.length, so null throws while the select renders, and Create stays disabled with no message. On chart install the field is blank but Install stays enabled. It fails with namespaces "default" already exists, or if the user can see default it sends an empty namespace, which Rancher turns into default. It would also clear the locked select on the Fleet AppCo create form.
Without the branch this matches master: the namespace shows and Create gives the clear "forbidden" message. Using '' instead wouldn't be enough, because chart install treats it the same way.
allowedNamespaces threadDeprecated sounds good to me, no need to remove it here.