Skip to content

Commit b9e0e76

Browse files
authored
Merge pull request #3896 from vyncent-t/dynamic-cluster-stale-names-fix
Fix renaming dynamic cluster spawning stale names
2 parents ae7cea9 + 0487e0c commit b9e0e76

File tree

4 files changed

+415
-115
lines changed

4 files changed

+415
-115
lines changed

frontend/src/components/App/Settings/SettingsCluster.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ import { isElectron } from '../../../helpers/isElectron';
3434
import { useCluster, useClustersConf } from '../../../lib/k8s';
3535
import { deleteCluster, parseKubeConfig, renameCluster } from '../../../lib/k8s/api/v1/clusterApi';
3636
import { setConfig, setStatelessConfig } from '../../../redux/configSlice';
37-
import { updateStatelessClusterKubeconfig } from '../../../stateless';
3837
import { findKubeconfigByClusterName } from '../../../stateless/findKubeconfigByClusterName';
38+
import { updateStatelessClusterKubeconfig } from '../../../stateless/updateStatelessClusterKubeconfig';
3939
import ConfirmButton from '../../common/ConfirmButton';
4040
import ConfirmDialog from '../../common/ConfirmDialog';
4141
import Empty from '../../common/EmptyContent';

frontend/src/stateless/index.ts

Lines changed: 2 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
import * as jsyaml from 'js-yaml';
1817
import _ from 'lodash';
1918
import { addBackstageAuthHeaders } from '../helpers/addBackstageAuthHeaders';
2019
import { request } from '../lib/k8s/api/v1/clusterRequests';
@@ -26,6 +25,7 @@ import store from '../redux/stores/store';
2625
import { deleteClusterKubeconfig } from './deleteClusterKubeconfig';
2726
import { findKubeconfigByClusterName } from './findKubeconfigByClusterName';
2827
import { getUserIdFromLocalStorage } from './getUserIdFromLocalStorage';
28+
import { updateStatelessClusterKubeconfig } from './updateStatelessClusterKubeconfig';
2929

3030
/**
3131
* ParsedConfig is the object that is fetched from the backend.
@@ -63,7 +63,7 @@ export interface DatabaseEvent extends Event {
6363
* @see getStatelessClusterKubeConfigs
6464
* @see findKubeconfigByClusterName
6565
*/
66-
interface DatabaseErrorEvent extends Event {
66+
export interface DatabaseErrorEvent extends Event {
6767
// target is the request that generated the event.
6868
target: IDBOpenDBRequest & {
6969
// error is the error of the request.
@@ -414,118 +414,6 @@ export async function fetchStatelessClusterKubeConfigs(dispatch: any) {
414414
});
415415
}
416416

417-
/**
418-
* Update the kubeconfig context extensions in IndexedDB.
419-
* @param kubeconfig - The kubeconfig to store.
420-
* @param customName - The custom name for the context extension.
421-
* @param clusterName - The name of the cluster to update the kubeconfig context for.
422-
* @returns promise that resolves when the kubeconfig is successfully updated and stored.
423-
* @throws Error if IndexedDB is not supported.
424-
* @throws Error if the kubeconfig is invalid.
425-
*/
426-
export function updateStatelessClusterKubeconfig(
427-
kubeconfig: string,
428-
customName: string,
429-
clusterName: string
430-
): Promise<void> {
431-
return new Promise<void>(async (resolve, reject) => {
432-
try {
433-
const request = indexedDB.open('kubeconfigs', 1) as any;
434-
// Parse the kubeconfig from base64
435-
const parsedKubeconfig = jsyaml.load(atob(kubeconfig)) as KubeconfigObject;
436-
// Find the context with the matching cluster name or custom name in headlamp_info
437-
const matchingContext = parsedKubeconfig.contexts.find(
438-
context =>
439-
context.name === clusterName ||
440-
context.context.extensions?.find(extension => extension.name === 'headlamp_info')
441-
?.extension.customName === clusterName
442-
);
443-
444-
if (matchingContext) {
445-
const extensions = matchingContext.context.extensions || [];
446-
const headlampExtension = extensions.find(extension => extension.name === 'headlamp_info');
447-
448-
if (matchingContext.name === clusterName) {
449-
// Push the new extension if the cluster name matches
450-
extensions.push({
451-
extension: {
452-
customName: customName,
453-
},
454-
name: 'headlamp_info',
455-
});
456-
} else if (headlampExtension) {
457-
// Update the existing extension if found
458-
headlampExtension.extension.customName = customName;
459-
}
460-
461-
// Ensure the extensions property is updated
462-
matchingContext.context.extensions = extensions;
463-
} else {
464-
console.error('No context found matching the cluster name:', clusterName);
465-
reject('No context found matching the cluster name');
466-
return;
467-
}
468-
469-
// Convert the updated kubeconfig back to base64
470-
const updatedKubeconfig = btoa(jsyaml.dump(parsedKubeconfig));
471-
472-
// The onupgradeneeded event is fired when the database is created for the first time.
473-
request.onupgradeneeded = handleDatabaseUpgrade;
474-
// The onsuccess event is fired when the database is opened.
475-
// This event is where you specify the actions to take when the database is opened.
476-
request.onsuccess = function handleDatabaseSuccess(event: DatabaseEvent) {
477-
const db = event.target.result;
478-
if (db) {
479-
const transaction = db.transaction(['kubeconfigStore'], 'readwrite');
480-
const store = transaction.objectStore('kubeconfigStore');
481-
482-
// Get the existing kubeconfig entry by clusterName
483-
store.openCursor().onsuccess = function getSuccess(event: Event) {
484-
const successEvent = event as CursorSuccessEvent;
485-
const cursor = successEvent.target?.result;
486-
if (cursor) {
487-
// Update the kubeconfig entry with the new kubeconfig
488-
cursor.value.kubeconfig = updatedKubeconfig;
489-
// Put the updated kubeconfig entry back into IndexedDB
490-
const putRequest = store.put(cursor.value);
491-
// The onsuccess event is fired when the request has succeeded.
492-
putRequest.onsuccess = function putSuccess() {
493-
console.log('Updated kubeconfig with custom name and stored in IndexedDB');
494-
resolve(); // Resolve the promise when the kubeconfig is successfully updated and stored
495-
};
496-
497-
// The onerror event is fired when the request has failed.
498-
putRequest.onerror = function putError(event: Event) {
499-
const errorEvent = event as DatabaseErrorEvent;
500-
console.error(errorEvent.target ? errorEvent.target.error : 'An error occurred');
501-
reject(errorEvent.target ? errorEvent.target.error : 'An error occurred');
502-
};
503-
} else {
504-
console.error('No kubeconfig entry found for cluster name:', clusterName);
505-
reject('No kubeconfig entry found for cluster name');
506-
}
507-
};
508-
509-
store.openCursor().onerror = function getError(event: Event) {
510-
const errorEvent = event as DatabaseErrorEvent;
511-
console.error(errorEvent.target ? errorEvent.target.error : 'An error occurred');
512-
reject(errorEvent.target ? errorEvent.target.error : 'An error occurred');
513-
};
514-
} else {
515-
console.error('Failed to open IndexedDB');
516-
reject('Failed to open IndexedDB');
517-
}
518-
};
519-
520-
// The onerror event is fired when the database is opened.
521-
// This is where you handle errors
522-
request.onerror = handleDataBaseError;
523-
} catch (error) {
524-
reject(error);
525-
}
526-
});
527-
}
528-
529417
const exportFunctions = {
530418
storeStatelessClusterKubeconfig,
531419
getStatelessClusterKubeConfigs,

0 commit comments

Comments
 (0)