-
Notifications
You must be signed in to change notification settings - Fork 56
Description
Description
When accessing Busola with a permalink that includes both a resource path and kubeconfigID query parameter (e.g., https://busola.example.com/cluster/my-cluster/namespaces/default/pods?kubeconfigID=abc123), the user ends up at the cluster overview instead of the intended resource path on the first attempt.
The second click on the same link works correctly because the cluster configuration is already stored in session/local storage.
Expected Behavior
Accessing a permalink with kubeconfigID should:
- Load the kubeconfig from the kubeconfigID
- Authenticate the user (including OIDC flow if needed)
- Navigate to the intended resource path
Actual Behavior
User ends up at /cluster/{context-name}/overview instead of the intended path.
Root Cause Analysis
After analyzing the codebase, I identified three interconnected problems:
Problem 1: Context Name in URL Path is Unpredictable
The current URL structure requires the context name in the path:
/cluster/{contextName}/namespaces/default/pods?kubeconfigID=abc123
However, when using kubeconfigID:
- The context name is not known until the kubeconfig is fetched and parsed
- With multiple contexts in the kubeconfig, the user might select a different context than the one in the URL
- The context name might change between kubeconfig versions
This makes it impossible to construct a reliable permalink that includes both kubeconfigID and a context-dependent path.
Problem 2: Race Condition in Cluster Configuration
Location: src/components/App/ClusterRoutes.jsx (lines 60-77)
useEffect(() => {
if (cluster?.name === currentClusterName) return;
const currentCluster = clusters?.[currentClusterName];
const kubeconfigId = search.get('kubeconfigID');
if (!currentCluster && !kubeconfigId) {
removePreviousPath();
alert("Such cluster doesn't exist");
navigate('/clusters');
return;
}
// ...
}, [currentClusterName, cluster, clusters, navigate, setCluster, setAuth, search]);When the permalink is first accessed:
- The URL contains
/cluster/my-cluster/namespaces/default/pods?kubeconfigID=abc123 ClusterRoutestries to findmy-clusterinclustersstate- The cluster doesn't exist yet because
useLoginWithKubeconfigIDhasn't finished loading it - The routing fails silently or redirects to overview
Problem 3: OIDC Redirect Loses the Resource Path
Location: src/state/authDataAtom.ts (lines 52-65)
export function createUserManager(
oidcParams: { /* ... */ },
redirectPath = '', // <-- Always empty string!
) {
return new UserManager({
redirect_uri: window.location.origin + redirectPath, // <-- Only origin, no path!
// ...
});
}The OIDC redirect URI is set to window.location.origin only. When the OIDC provider redirects back:
- User is redirected to
https://busola.example.com(just the origin) - The
kubeconfigIDquery parameter is lost - The resource path is lost
- The
savePreviousPath()mechanism doesn't help because it was called before the OIDC redirect
Proposed Solution
New URL Format for Permalinks
Instead of embedding the context name in the path, use a context-independent permalink format with a separate path query parameter:
https://busola.example.com/?kubeconfigID=abc123&path=/namespaces/default/pods
Or for cluster-scoped resources:
https://busola.example.com/?kubeconfigID=abc123&path=/nodes
Why This Approach is Better
- Context-independent: The path doesn't include the context name, so it works regardless of which context the user selects
- Predictable: The URL can be constructed without knowing the kubeconfig contents
- Survives OIDC: The path is stored in sessionStorage before any redirects
- Simple to implement: Minimal changes to existing code
- Backward compatible: Existing URLs without
pathparameter continue to work