Skip to content

Commit

Permalink
app: home: Add delete button for clusters
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent T <[email protected]>
  • Loading branch information
vyncent-t committed Nov 15, 2024
1 parent d24fc9f commit 7fd77f4
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 31 deletions.
16 changes: 16 additions & 0 deletions backend/cmd/headlamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,22 @@ func (c *HeadlampConfig) deleteCluster(w http.ResponseWriter, r *http.Request) {
return
}

removeKubeConfig := r.URL.Query().Get("removeKubeConfig") == "true"
// removeKubeConfig := true

Check failure on line 1388 in backend/cmd/headlamp.go

View workflow job for this annotation

GitHub Actions / build

File is not `gofmt`-ed with `-s` (gofmt)


if removeKubeConfig {
// delete context from actual deafult kubecofig file

Check failure on line 1392 in backend/cmd/headlamp.go

View workflow job for this annotation

GitHub Actions / build

`deafult` is a misspelling of `default` (misspell)
// to do : replace the hard coding of this line with an actual path
err = kubeconfig.RemoveContextFromFile(name, filepath.Join("/home/vynty/.kube/config"))

Check failure on line 1394 in backend/cmd/headlamp.go

View workflow job for this annotation

GitHub Actions / build

badCall: suspicious Join on 1 argument (gocritic)
if err != nil {
logger.Log(logger.LevelError, map[string]string{"cluster": name},
err, "my cool error")
http.Error(w, "removing cluster from kubeconfig", http.StatusInternalServerError)
return

Check failure on line 1399 in backend/cmd/headlamp.go

View workflow job for this annotation

GitHub Actions / build

return statements should not be cuddled if block has more than two lines (wsl)
}
}

kubeConfigPersistenceFile, err := defaultKubeConfigPersistenceFile()
if err != nil {
logger.Log(logger.LevelError, map[string]string{"cluster": name},
Expand Down
52 changes: 29 additions & 23 deletions frontend/src/components/App/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ import { ConfirmDialog } from '../../common';
import ResourceTable from '../../common/Resource/ResourceTable';
import RecentClusters from './RecentClusters';

/**
* Gets the origin of a cluster.
*
* @param cluster
* @returns A description of where the cluster is picked up from: dynamic, in-cluster, or from a kubeconfig file.
*/
function getOrigin(cluster: Cluster): string {
if (cluster.meta_data?.source === 'kubeconfig') {
const kubeconfigPath = process.env.KUBECONFIG ?? '~/.kube/config';
return `Kubeconfig: ${kubeconfigPath}`;
} else if (cluster.meta_data?.source === 'dynamic_cluster') {
return t('translation|Plugin');
} else if (cluster.meta_data?.source === 'in_cluster') {
return t('translation|In-cluster');
}
return 'Unknown';
}

function ContextMenu({ cluster }: { cluster: Cluster }) {
const { t } = useTranslation(['translation']);
const history = useHistory();
Expand All @@ -33,8 +51,8 @@ function ContextMenu({ cluster }: { cluster: Cluster }) {
const menuId = useId('context-menu');
const [openConfirmDialog, setOpenConfirmDialog] = React.useState(false);

function removeCluster(cluster: Cluster) {
deleteCluster(cluster.name || '')
function removeCluster(cluster: Cluster, removeKubeconfig?: boolean) {
deleteCluster(cluster.name || '', removeKubeconfig)
.then(config => {
dispatch(setConfig(config));
})
Expand Down Expand Up @@ -92,7 +110,8 @@ function ContextMenu({ cluster }: { cluster: Cluster }) {
>
<ListItemText>{t('translation|Settings')}</ListItemText>
</MenuItem>
{helpers.isElectron() && cluster.meta_data?.source === 'dynamic_cluster' && (

{helpers.isElectron() && (
<MenuItem
onClick={() => {
setOpenConfirmDialog(true);
Expand All @@ -109,13 +128,18 @@ function ContextMenu({ cluster }: { cluster: Cluster }) {
handleClose={() => setOpenConfirmDialog(false)}
onConfirm={() => {
setOpenConfirmDialog(false);
removeCluster(cluster);
if (cluster.meta_data?.source !== 'dynamic_cluster') {
removeCluster(cluster, true);
} else {
removeCluster(cluster);
}
}}
title={t('translation|Delete Cluster')}
description={t(
'translation|Are you sure you want to remove the cluster "{{ clusterName }}"?',
'translation|This action will delete cluster "{{ clusterName }}" from {{ source }}.',
{
clusterName: cluster.name,
source: getOrigin(cluster),
}
)}
/>
Expand Down Expand Up @@ -239,24 +263,6 @@ function HomeComponent(props: HomeComponentProps) {
.sort();
}

/**
* Gets the origin of a cluster.
*
* @param cluster
* @returns A description of where the cluster is picked up from: dynamic, in-cluster, or from a kubeconfig file.
*/
function getOrigin(cluster: Cluster): string {
if (cluster.meta_data?.source === 'kubeconfig') {
const kubeconfigPath = process.env.KUBECONFIG ?? '~/.kube/config';
return `Kubeconfig: ${kubeconfigPath}`;
} else if (cluster.meta_data?.source === 'dynamic_cluster') {
return t('translation|Plugin');
} else if (cluster.meta_data?.source === 'in_cluster') {
return t('translation|In-cluster');
}
return 'Unknown';
}

const memoizedComponent = React.useMemo(
() => (
<PageGrid>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/common/ConfirmDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { DialogTitle } from './Dialog';

export interface ConfirmDialogProps extends MuiDialogProps {
title: string;
description: string;
description: string | JSX.Element;
onConfirm: () => void;
handleClose: () => void;
}
Expand Down
13 changes: 6 additions & 7 deletions frontend/src/lib/k8s/api/v1/clusterApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ export async function setCluster(clusterReq: ClusterRequest) {
// @todo: needs documenting.

export async function deleteCluster(
cluster: string
cluster: string,
removeKubeConfig?: boolean
): Promise<{ clusters: ConfigState['clusters'] }> {
if (cluster) {
const kubeconfig = await findKubeconfigByClusterName(cluster);
Expand All @@ -89,12 +90,10 @@ export async function deleteCluster(
}
}

return request(
`/cluster/${cluster}`,
{ method: 'DELETE', headers: { ...getHeadlampAPIHeaders() } },
false,
false
);
const url = `/cluster/${cluster}?removeKubeConfig=${removeKubeConfig}`;

// need a way to add a param that passes 'removeKubeConfig' to go backend
return request(url, { method: 'DELETE', headers: { ...getHeadlampAPIHeaders() } }, false, false);
}

/**
Expand Down

0 comments on commit 7fd77f4

Please sign in to comment.