diff --git a/backend/cmd/headlamp.go b/backend/cmd/headlamp.go index 88da814178..d271c874dd 100644 --- a/backend/cmd/headlamp.go +++ b/backend/cmd/headlamp.go @@ -1475,6 +1475,8 @@ func (c *HeadlampConfig) renameCluster(w http.ResponseWriter, r *http.Request) { if reqBody.Stateless { // For stateless clusters we just need to remove cluster from cache c.handleStatelessClusterRename(w, r, clusterName) + + return } // Get path of kubeconfig from source diff --git a/frontend/src/components/cluster/KubeConfigLoader.tsx b/frontend/src/components/cluster/KubeConfigLoader.tsx index fd2440c286..a2def7b703 100644 --- a/frontend/src/components/cluster/KubeConfigLoader.tsx +++ b/frontend/src/components/cluster/KubeConfigLoader.tsx @@ -10,6 +10,7 @@ import { useDropzone } from 'react-dropzone'; import { useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; +import { useClustersConf } from '../../lib/k8s'; import { setCluster } from '../../lib/k8s/apiProxy'; import { setStatelessConfig } from '../../redux/configSlice'; import { DialogTitle } from '../common/Dialog'; @@ -105,6 +106,7 @@ const WideButton = styled(Button)({ const enum Step { LoadKubeConfig, SelectClusters, + ValidateKubeConfig, ConfigureClusters, Success, } @@ -120,6 +122,7 @@ function KubeConfigLoader() { currentContext: '', }); const [selectedClusters, setSelectedClusters] = useState([]); + const configuredClusters = useClustersConf(); // Get already configured clusters useEffect(() => { if (fileContent.contexts.length > 0) { @@ -130,9 +133,27 @@ function KubeConfigLoader() { }, [fileContent]); useEffect(() => { + if (state === Step.ValidateKubeConfig) { + const alreadyConfiguredClusters = selectedClusters.filter( + clusterName => configuredClusters && configuredClusters[clusterName] + ); + + if (alreadyConfiguredClusters.length > 0) { + setError( + t( + 'translation|Duplicate cluster: {{ clusterNames }} in the list. Please edit the context name.', + { + clusterNames: alreadyConfiguredClusters.join(', '), + } + ) + ); + setState(Step.SelectClusters); + } else { + setState(Step.ConfigureClusters); + } + } if (state === Step.ConfigureClusters) { function loadClusters() { - //@todo: We need to check if the cluster is already configured. const selectedClusterConfig = configWithSelectedClusters(fileContent, selectedClusters); setCluster({ kubeconfig: btoa(yaml.dump(selectedClusterConfig)) }) .then(res => { @@ -295,7 +316,7 @@ function KubeConfigLoader() { variant="contained" color="primary" onClick={() => { - setState(Step.ConfigureClusters); + setState(Step.ValidateKubeConfig); }} disabled={selectedClusters.length === 0} > @@ -318,6 +339,13 @@ function KubeConfigLoader() { ) : null} ); + case Step.ValidateKubeConfig: + return ( + + {t('translation|Validating selected clusters')} + + + ); case Step.ConfigureClusters: return ( diff --git a/frontend/src/i18n/locales/de/translation.json b/frontend/src/i18n/locales/de/translation.json index 558f436ed1..c77f36bb64 100644 --- a/frontend/src/i18n/locales/de/translation.json +++ b/frontend/src/i18n/locales/de/translation.json @@ -110,6 +110,7 @@ "Current//context:cluster": "Aktuell", "Choose cluster": "Cluster auswählen", "Add Cluster": "Cluster hinzufügen", + "Duplicate cluster: {{ clusterNames }} in the list. Please edit the context name.": "", "Error setting up clusters, please load a valid kubeconfig file": "Fehler beim Einrichten der Cluster. Bitte laden Sie eine korrekte kubeconfig-Datei", "Couldn't read kubeconfig file": "Konnte die kubeconfig-Datei nicht lesen", "No clusters found!": "", @@ -119,6 +120,7 @@ "Choose file": "Datei auswählen", "Select clusters": "Cluster auswählen", "Next": "Weiter", + "Validating selected clusters": "", "Setting up clusters": "Einrichten der Cluster", "Clusters successfully set up!": "Cluster erfolgreich eingerichtet!", "Finish": "Beenden", diff --git a/frontend/src/i18n/locales/en/translation.json b/frontend/src/i18n/locales/en/translation.json index 0d8a529ef6..721b0b6b99 100644 --- a/frontend/src/i18n/locales/en/translation.json +++ b/frontend/src/i18n/locales/en/translation.json @@ -110,6 +110,7 @@ "Current//context:cluster": "Current", "Choose cluster": "Choose cluster", "Add Cluster": "Add Cluster", + "Duplicate cluster: {{ clusterNames }} in the list. Please edit the context name.": "Duplicate cluster: {{ clusterNames }} in the list. Please edit the context name.", "Error setting up clusters, please load a valid kubeconfig file": "Error setting up clusters, please load a valid kubeconfig file", "Couldn't read kubeconfig file": "Couldn't read kubeconfig file", "No clusters found!": "No clusters found!", @@ -119,6 +120,7 @@ "Choose file": "Choose file", "Select clusters": "Select clusters", "Next": "Next", + "Validating selected clusters": "Validating selected clusters", "Setting up clusters": "Setting up clusters", "Clusters successfully set up!": "Clusters successfully set up!", "Finish": "Finish", diff --git a/frontend/src/i18n/locales/es/translation.json b/frontend/src/i18n/locales/es/translation.json index 6cde511210..bd2ecfd616 100644 --- a/frontend/src/i18n/locales/es/translation.json +++ b/frontend/src/i18n/locales/es/translation.json @@ -110,6 +110,7 @@ "Current//context:cluster": "Actuales", "Choose cluster": "Elegir cluster", "Add Cluster": "Añadir cluster", + "Duplicate cluster: {{ clusterNames }} in the list. Please edit the context name.": "", "Error setting up clusters, please load a valid kubeconfig file": "Error al configurar los clusters, por favor cargue un archivo kubeconfig válido", "Couldn't read kubeconfig file": "No se pudo leer el archivo kubeconfig", "No clusters found!": "", @@ -119,6 +120,7 @@ "Choose file": "Elija el archivo", "Select clusters": "Seleccione los clusters", "Next": "Siguiente", + "Validating selected clusters": "", "Setting up clusters": "Configurando los clusters", "Clusters successfully set up!": "¡Clusters configurados con éxito!", "Finish": "Finalizar", diff --git a/frontend/src/i18n/locales/fr/translation.json b/frontend/src/i18n/locales/fr/translation.json index 2f0a2405ea..742b59b9bb 100644 --- a/frontend/src/i18n/locales/fr/translation.json +++ b/frontend/src/i18n/locales/fr/translation.json @@ -110,6 +110,7 @@ "Current//context:cluster": "Actuel", "Choose cluster": "Choisir un cluster", "Add Cluster": "Ajouter un cluster", + "Duplicate cluster: {{ clusterNames }} in the list. Please edit the context name.": "", "Error setting up clusters, please load a valid kubeconfig file": "Erreur lors de la configuration des clusters, veuillez charger un fichier kubeconfig valide", "Couldn't read kubeconfig file": "Impossible de lire le fichier kubeconfig", "No clusters found!": "", @@ -119,6 +120,7 @@ "Choose file": "Choisir un fichier", "Select clusters": "Sélectionner des clusters", "Next": "Suivant", + "Validating selected clusters": "", "Setting up clusters": "Configuration des clusters", "Clusters successfully set up!": "Clusters configurés avec succès !", "Finish": "Terminer", diff --git a/frontend/src/i18n/locales/pt/translation.json b/frontend/src/i18n/locales/pt/translation.json index 3b8f801a61..441781b762 100644 --- a/frontend/src/i18n/locales/pt/translation.json +++ b/frontend/src/i18n/locales/pt/translation.json @@ -110,6 +110,7 @@ "Current//context:cluster": "Actual", "Choose cluster": "Escolha o cluster", "Add Cluster": "Adicionar Cluster", + "Duplicate cluster: {{ clusterNames }} in the list. Please edit the context name.": "", "Error setting up clusters, please load a valid kubeconfig file": "Erro ao configurar clusters, por favor carregue um ficheiro kubeconfig válido", "Couldn't read kubeconfig file": "Não foi possível ler o ficheiro kubeconfig", "No clusters found!": "", @@ -119,6 +120,7 @@ "Choose file": "Escolha o ficheiro", "Select clusters": "Selecione os clusters", "Next": "Seguinte", + "Validating selected clusters": "", "Setting up clusters": "A configurar clusters", "Clusters successfully set up!": "Clusters configurados com sucesso!", "Finish": "Terminar", diff --git a/frontend/src/stateless/index.ts b/frontend/src/stateless/index.ts index d27978de8c..dcae5569ec 100644 --- a/frontend/src/stateless/index.ts +++ b/frontend/src/stateless/index.ts @@ -247,8 +247,8 @@ export function findKubeconfigByClusterName(clusterName: string): Promise cluster.name === clusterName + const matchingKubeconfig = parsedKubeconfig.contexts.find( + context => context.name === clusterName ); if (matchingKubeconfig || matchingContext) { @@ -437,9 +437,12 @@ export async function deleteClusterKubeconfig(clusterName: string): Promise cluster.name === clusterName + // Find the context with the matching cluster name or custom name in headlamp_info + const matchingKubeconfig = parsedKubeconfig.contexts.find( + context => + context.name === clusterName || + context.context.extensions?.find(extension => extension.name === 'headlamp_info') + ?.extension.customName === clusterName ); if (matchingKubeconfig) { @@ -489,11 +492,10 @@ export function updateStatelessClusterKubeconfig( const request = indexedDB.open('kubeconfigs', 1) as any; // Parse the kubeconfig from base64 const parsedKubeconfig = jsyaml.load(atob(kubeconfig)) as KubeconfigObject; - // Find the context with the matching cluster name or custom name in headlamp_info const matchingContext = parsedKubeconfig.contexts.find( context => - context.context.cluster === clusterName || + context.name === clusterName || context.context.extensions?.find(extension => extension.name === 'headlamp_info') ?.extension.customName === clusterName ); @@ -502,7 +504,7 @@ export function updateStatelessClusterKubeconfig( const extensions = matchingContext.context.extensions || []; const headlampExtension = extensions.find(extension => extension.name === 'headlamp_info'); - if (matchingContext.context.cluster === clusterName) { + if (matchingContext.name === clusterName) { // Push the new extension if the cluster name matches extensions.push({ extension: {