rancher/dashboard PR 19793 (codyrancher), "List the namespaces a user can create the resource in on create forms". Head ee30ed3c4, reviewed 2026-11-05. You are the only requested reviewer, and nobody has reviewed it yet.
Preview: rancherpr19793r.mf-created-dashboard.ui.rancher.space, built from ee30ed3c4, backend mf Rancher (v2.16.0-7758e3e-head). PR + fix: rancherpr19793-fixr.mf-created-dashboard.ui.rancher.space, built from c644df7f0, which is the PR plus card 1's fix, local only and not pushed. Baseline: the shared dashboard-master preview, rebuilt today from 261b8932f, the current tip.
local, plus a restricted user on a downstream cluster, and found 0 mismatches. The customer's case from the issue goes from one namespace to the correct two, on Secrets and on chart install.allowedNamespaces is now dead code, and the PR adds a file under shell/utils.The login page defaults to OpenLDAP, so click Log in as a local user first. The password for every issue-8544* user is in ~/Projects/pr-reviews/pr19793-fixtures/password.txt on your Mac. It's not on this page because the page is public.
issue-8544 and pick Opaque. Namespace lists secrets-ns1 and secrets-ns2, as the description says. On master it lists only secrets-ns1.issue-8544-first. It opens on aaa-view-ns, which is also in the list. Type a name and click Create to get the forbidden error.secrets-ns1 and aaa-view-ns is gone. Don't click Create here: a save remembers secrets-ns1 as that user's last namespace, and then the PR preview opens there too and hides the bug. If that happens, issue-8544-cm shows the same thing on default.rancher-alerting-drivers, then Install. It behaves the same way as Secrets.defaultNamespace picks the last-used namespace, then default, then the first one. It never looks at permissions, and it runs before the check comes back. namespaceSelectOptions then adds the current value back to the list so the select can display it, so the namespace the PR filtered out reappears at the top.
aaa-view-ns, and it is the only option. This is the issue.aaa-view-ns and lists it.secrets-ns1, and Create worked when I submitted it.Anyone whose default isn't creatable. I reproduced two of these, and the third is the same code path:
issue-8544-first).default (issue-8544-cm). For that role the check says default isn't creatable, but it's preselected and listed.The setup script in the description can't show it, because view-only-ns sorts after secrets-ns1. Rename it aaa-view-ns and it appears.
When the check comes back, if the current value is still the default and isn't allowed, select the first allowed namespace. Any other value stays, so a clone or a namespace being typed isn't touched. If nothing is allowed, nothing moves, which matches master. A disabled select now skips the check, so a locked value (the Fleet AppCo create form) can't move. That also saves a request and a spinner on a select nobody can change.
Tested: 4 new unit test cases, and the "moves the default" test fails without the fix. The 3 touched suites pass (65 tests), lint is clean and there are no new type errors. In the browser, it clears the case for issue-8544-first and issue-8544-cm on Secret and chart install, and issue-8544-cm on Deployment. issue-8544, member, read-only and admin behave as before.
--- a/shell/components/form/NamespaceSelect.vue
+++ b/shell/components/form/NamespaceSelect.vue
@@ -95,7 +95,7 @@ const inStore = computed(() => store.getters['currentStore']());
const nsSchema = computed(() => store.getters[`${ inStore.value }/schemaFor`](NAMESPACE));
const typeToCheck = computed(() => {
- if (!isCreate.value || props.override || props.options || props.forceNamespace || !props.resourceType) {
+ if (!isCreate.value || props.override || props.options || props.forceNamespace || props.disabled || !props.resourceType) {
return null;
}
@@ -118,6 +118,15 @@ watch(typeToCheck, async(type) => {
if (type === typeToCheck.value) {
namespacesAllowingCreate.value = allowed;
loadingNamespacesAllowingCreate.value = false;
+
+ // defaultNamespace does not know about permissions, so it can be a namespace the user cannot create in
+ if (allowed && namespace.value === store.getters['defaultNamespace'] && !allowed.has(namespace.value as string)) {
+ const firstAllowed = realNamespaceOptions.value[0]?.value;
+
+ if (firstAllowed) {
+ emitChange(firstAllowed as string);
+ }
+ }
}
}, { immediate: true });
allowedNamespaces has no callers leftThis PR removes the last real use. What's left is the getter, getReadOnlyActiveNamespaces, the readonly param on getActiveNamespaces, a mapGetters entry nobody reads, and a fixture line in the PR's own new test. Removing them stops the old links.update rule from being reused by accident. GitHub search finds no other use in the rancher org or in harvester-ui-extension, but I can't see third-party extensions. A follow-up would be fine too.
shell/utilsOur checklist says no new files there, and this function has one caller, so it could live in NamespaceSelect.vue. That also drops the store: any. A fair answer from Cody would be that it mirrors shell/utils/project-permissions.ts, which came from your PR 18840, so skip this one if you don't feel strongly.
checkPermissionsThe description says a Steve without the feature, "e.g. Harvester's", falls back to every namespace. Both our Harvesters, v1.8.0-rc5 and v1.9.0-rc4, return resourcePermissions, so the check will really run there.
create in every namespace, and virtual names such as harvesterhci.io.secret have no schema, so the form skips the check rather than showing an empty list.e2e-test (admin, @navigation, @extensions): kubewarden.spec.ts fails in its before-all hook, waiting for the extension repo to go Active, on both attempts. The same spec fails with the same assertion on master at 261b8932f. The other 12 specs in that job pass.Branch Milestone: branches-metadata.json still maps master to v2.16.0 while this PR is on v2.17.0. PRs 19794, 19795 and 19796 are red on the same check.QA/dev-automation label and the PR has unit tests only, with no e2e for a restricted user. I don't know if the team expects one here.Opens on, then lists, on Create Secret (chart install gave the same answer wherever I ran it). "Create a new Namespace" is left out.
| User | master | PR | PR + fix |
|---|---|---|---|
issue-8544the description's setup: custom role on one project, read-only on another | opens secrets-ns1lists only that | opens secrets-ns1lists ns1, ns2 | same as PR |
issue-8544-firstsame, but the read-only namespace sorts first | opens aaa-view-nslists only that | opens aaa-view-nslists it, ns1, ns2Create: forbidden | opens secrets-ns1lists ns1, ns2Create: saved |
issue-8544-cmCluster Member, View All Projects, member of one project | opens defaultlists it, ns1, ns2 | same as master | opens secrets-ns1lists ns1, ns2 |
issue-8544-baseUser-Base, same bindings as issue-8544 | opens secrets-ns1lists only that | opens secrets-ns1lists ns1, ns2 | not rerun |
issue-8544-memberProject Member on one, read-only on another. Also ConfigMap and Deployment. | opens secrets-ns1lists ns1, ns2 | same as master | same as master (ConfigMap not rerun) |
issue-8544-roread-only everywhere, can't create anywhere | opens view-only-nslists only that | same as master | same as master |
admin | opens defaultevery namespace | same as master | same as master (identical list, 109 on all 3 builds) |
| Step | Result |
|---|---|
Secrets, Create, Opaque lists secrets-ns1 and secrets-ns2, not view-only-ns | True with this fixture. Card 1 is the exception. |
| On master it lists only the pre-selected default | True |
| Chart install shows the same two namespaces | True, with rancher-alerting-drivers |
| As admin, create forms still list every namespace | True, same list as master |
| Edit is unchanged | True. Editing a ConfigMap as a member: select locked, no check sent. |
| If the check fails, every namespace is listed | True. With the check forced to 500, view-only-ns is back. |
A Steve without checkPermissions (e.g. Harvester's) falls back | The fallback is unit tested, but v1.8 and v1.9 Harvester aren't that case. See card 4. |
| Check | Result |
|---|---|
| Is the backend answer true? | 6 users and 3 types on local, each namespace compared with a real dry-run create: 0 mismatches. A restricted user on created-dashboard-2: 47 namespaces and 2 types, check says none, all really 403. As admin, all 6 active clusters I tried return resourcePermissions. |
Does include=metadata.name drop the permissions? | No. Steve writes resourcePermissions after applying include, confirmed in its source and live. |
| Could a namespace with no rights trigger the "unsupported" fallback? | No. Steve sends an empty {}, not a missing key. No namespace came back without it. |
| Top-nav filter, issue 6094 | Project, single namespace and Only User Namespaces, with the filter confirmed applied each time: master, PR and PR + fix give the same answers. |
Does value.type suit every form? | Scripted sweep of the namespace props on every NameNsDescription call in shell and pkg, and in the 33 Harvester extension files. I found no form that passes something other than a resource, sets namespaced=false or gives its own options, apart from chart install, which the PR handles. In the browser I confirmed Secret, ConfigMap, Deployment and chart install. |
| Loading state | About 130 to 350 ms on mf, longest with 165 namespaces. Select disabled, spinner, Create stays disabled. The spinner overlaps the placeholder text, which is cosmetic and not worth raising. |
| A check that never answers | The select stays locked with a spinner (seen at 8 s, forced). Not worth raising, since it takes a request that never returns. |
| Conventions | Tests use shallowMount and toStrictEqual. No new strings, v-html or ticket references in code. Commit message is fine, and the issue is linked with a milestone. |
Your usual shape: this intro as the body, the rest as inline comments, no code and no preview link. If you want the screenshots from card 1 on comment 1, they still need uploading. Comments 2 and 3 are optional.
This works well. I tried it with several roles on local and on a downstream cluster, and the list matched what the server allows every time. One thing left on the preselected namespace, plus two small cleanups. Also, Harvester v1.8 and v1.9 do answer checkPermissions, so the note about Harvester falling back could be updated.
shell/components/form/NamespaceSelect.vue, line 119The list is right now, but the namespace the form opens on still isn't checked. defaultNamespace doesn't know about permissions, and namespaceSelectOptions adds the current value back to the list. So a user whose first namespace is read-only opens the form on it, sees it listed, and gets "secrets is forbidden" on Create. A Cluster Member with View All Projects gets the same with default. The setup script doesn't show it because view-only-ns sorts after secrets-ns1; naming it aaa-view-ns does.
Could we move the selection to the first allowed namespace here when the current value is still the default? Other values can stay as they are, so a clone or a typed new namespace isn't touched. A disabled select (Fleet AppCo create) could skip the check too, so its value never moves.
shell/components/form/__tests__/NamespaceSelect.test.ts, line 230 (optional)This was the last real use of allowedNamespaces. The getter, getReadOnlyActiveNamespaces and the readonly param in shell/store/index.js are unused now, as are the mapGetters entry in HarvesterServiceAddOnConfig.vue and this fixture line. Can we remove them here so the old links.update rule doesn't stay around?
shell/utils/namespace-permissions.ts, line 16 (optional)We try not to add new files under shell/utils. This has one caller, so could it live in NamespaceSelect.vue?