Skip to content

Commit 4088049

Browse files
committed
feat(xo6): download cluster kubeconfig
1 parent 4f02b10 commit 4088049

10 files changed

Lines changed: 111 additions & 9 deletions

‎@xen-orchestra/web-core/lib/locales/en.json‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"action:disconnect-n-vifs": "Disconnect 1 VIF | Disconnect {n} VIFs",
7474
"action:disconnect-pool": "Disconnect pool",
7575
"action:download-bugtools-archive": "Download bugtools archive",
76+
"action:download-kubeconfig-admin-file": "Download kubeconfig admin file",
7677
"action:duplicate": "Duplicate",
7778
"action:duplicate-n-vms": "Duplicate 1 VM | Duplicate {n} VMs",
7879
"action:edit": "Edit",
@@ -280,6 +281,7 @@
280281
"cluster": "Cluster",
281282
"cluster-class": "Cluster class",
282283
"cluster-delete-warning": "Deleting this Kubernetes cluster is permanent and cannot be undone. All associated resources, workloads, and configurations may become unavailable. Make sure this cluster is no longer in use before confirming. | Deleting these Kubernetes clusters is permanent and cannot be undone. All associated resources, workloads, and configurations may become unavailable. Make sure these clusters are no longer in use before confirming.",
284+
"cluster-missing": "Cluster is missing",
283285
"cluster-name": "Cluster name",
284286
"clusters": "Clusters",
285287
"color-mode:auto": "Automatic mode",
@@ -545,11 +547,13 @@
545547
"job:backup-repository-benchmark:missing-backup-repository": "Missing backup repository",
546548
"job:backup-repository-benchmark:repository-disabled": "Backup repository disabled",
547549
"job:cluster-delete:missing-cluster": "No clusters to delete",
550+
"job:cluster-kubeconfig-download:missing-cluster": "@:cluster-missing",
548551
"job:connect:in-progress": "Connect in progress…",
549552
"job:create:in-progress": "Create in progress…",
550553
"job:delete:in-progress": "Delete in progress…",
551554
"job:disable:in-progress": "Disable in progress…",
552555
"job:disconnect:in-progress": "Disconnect in progress…",
556+
"job:download:in-progress": "Download in progress…",
553557
"job:edit:in-progress": "Edit in progress…",
554558
"job:enable:in-progress": "Enable in progress…",
555559
"job:export:in-progress": "Export in progress…",

‎@xen-orchestra/web-core/lib/locales/fr.json‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"action:disconnect-n-vifs": "Déconnecter 1 VIF | Déconnecter {n} VIFs",
7474
"action:disconnect-pool": "Déconnecter le pool",
7575
"action:download-bugtools-archive": "Télécharger l’archive bugtools",
76+
"action:download-kubeconfig-admin-file": "Télécharger le fichier kubeconfig admin",
7677
"action:duplicate": "Dupliquer",
7778
"action:duplicate-n-vms": "Dupliquer 1 VM | Dupliquer {n} VMs",
7879
"action:edit": "Modifier",
@@ -280,6 +281,7 @@
280281
"cluster": "Cluster",
281282
"cluster-class": "Cluster class",
282283
"cluster-delete-warning": "La suppression de ce cluster Kubernetes est définitive et ne peut pas être annulée. Toutes les ressources, charges de travail et configurations associées pourraient devenir indisponibles. Assurez-vous que le cluster n'est plus en cours d'utilisation avant de confirmer. | La suppression de ces clusters Kubernetes est définitive et ne peut pas être annulée. Toutes les ressources, charges de travail et configurations associées pourraient devenir indisponibles. Assurez-vous que les clusters ne sont plus en cours d'utilisation avant de confirmer.",
284+
"cluster-missing": "Cluster manquant",
283285
"cluster-name": "Nom du cluster",
284286
"clusters": "Clusters",
285287
"color-mode:auto": "Mode automatique",
@@ -545,11 +547,13 @@
545547
"job:backup-repository-benchmark:missing-backup-repository": "Aucun dépôt de sauvegarde",
546548
"job:backup-repository-benchmark:repository-disabled": "Dépôt de sauvegarde désactivé",
547549
"job:cluster-delete:missing-cluster": "Aucun cluster à supprimer",
550+
"job:cluster-kubeconfig-download:missing-cluster": "@:cluster-missing",
548551
"job:connect:in-progress": "Connexion en cours…",
549552
"job:create:in-progress": "Création en cours…",
550553
"job:delete:in-progress": "Suppression en cours…",
551554
"job:disable:in-progress": "Désactivation en cours…",
552555
"job:disconnect:in-progress": "Déconnexion en cours…",
556+
"job:download:in-progress": "Téléchargement en cours…",
553557
"job:edit:in-progress": "Modification en cours…",
554558
"job:enable:in-progress": "Activation en cours…",
555559
"job:export:in-progress": "Export en cours…",

‎@xen-orchestra/web/src/modules/kubernetes/components/actions/ClusterActions.vue‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
<template>
2+
<ClusterKubeconfigDownloadButton :cluster />
23
<ClusterDeleteButton :cluster />
34
</template>
45

56
<script lang="ts" setup>
67
import ClusterDeleteButton from '@/modules/kubernetes/components/actions/delete-cluster/ClusterDeleteButton.vue'
8+
import ClusterKubeconfigDownloadButton from '@/modules/kubernetes/components/actions/download-kubeconfig/ClusterKubeconfigDownloadButton.vue'
79
import type { XoKubernetesCluster } from '@/modules/kubernetes/types/xo-kubernetes.type.ts'
810
911
defineProps<{
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<template>
2+
<MenuItem
3+
icon="action:download"
4+
accent="neutral"
5+
:disabled="!canDownloadKubeconfig"
6+
:busy="isDownloadingKubeconfig"
7+
@click="downloadKubeconfig()"
8+
>
9+
{{ t('action:download-kubeconfig-admin-file') }}
10+
</MenuItem>
11+
</template>
12+
13+
<script lang="ts" setup>
14+
import { useKubernetesClusterKubeconfigDownload } from '@/modules/kubernetes/composables/use-kubernetes-cluster-kubeconfig-download.composable.ts'
15+
import type { XoKubernetesCluster } from '@/modules/kubernetes/types/xo-kubernetes.type.ts'
16+
import MenuItem from '@core/components/menu/MenuItem.vue'
17+
import { useI18n } from 'vue-i18n'
18+
19+
const { cluster } = defineProps<{
20+
cluster: XoKubernetesCluster
21+
}>()
22+
23+
const { t } = useI18n()
24+
25+
const { downloadKubeconfig, canDownloadKubeconfig, isDownloadingKubeconfig } = useKubernetesClusterKubeconfigDownload(
26+
() => cluster
27+
)
28+
</script>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useXoKubernetesClusterKubeconfigDownloadJob } from '@/modules/kubernetes/jobs/xo-kubernetes-cluster-kubeconfig-download.job.ts'
2+
import type { XoKubernetesCluster } from '@/modules/kubernetes/types/xo-kubernetes.type.ts'
3+
import { isClusterPhaseReady } from '@/modules/kubernetes/utils/kubernetes-cluster.util.ts'
4+
import { toComputed } from '@core/utils/to-computed.util.ts'
5+
import { computed, type MaybeRefOrGetter } from 'vue'
6+
7+
export function useKubernetesClusterKubeconfigDownload(rawCluster: MaybeRefOrGetter<XoKubernetesCluster>) {
8+
const cluster = toComputed(rawCluster)
9+
10+
const { run, canRun, isRunning: isDownloadingKubeconfig } = useXoKubernetesClusterKubeconfigDownloadJob(cluster)
11+
12+
const canDownloadKubeconfig = computed(() => canRun.value && isClusterPhaseReady(cluster.value.phase))
13+
14+
async function downloadKubeconfig() {
15+
try {
16+
await run()
17+
} catch (error) {
18+
console.error('Error when downloading cluster kubeconfig:', error)
19+
}
20+
}
21+
22+
return { downloadKubeconfig, canDownloadKubeconfig, isDownloadingKubeconfig }
23+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { XoKubernetesCluster } from '@/modules/kubernetes/types/xo-kubernetes.type.ts'
2+
import { defineJobArg } from '@core/packages/job'
3+
4+
export const xoKubernetesClustersArg = defineJobArg({
5+
identify: (cluster: XoKubernetesCluster) => cluster.id,
6+
toArray: true,
7+
})
8+
9+
export const xoKubernetesClusterArg = defineJobArg({
10+
identify: (cluster: XoKubernetesCluster) => cluster.id,
11+
toArray: false,
12+
})

‎@xen-orchestra/web/src/modules/kubernetes/jobs/xo-kubernetes-cluster-delete-args.ts‎

Lines changed: 0 additions & 7 deletions
This file was deleted.

‎@xen-orchestra/web/src/modules/kubernetes/jobs/xo-kubernetes-cluster-delete.job.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { clustersArg } from '@/modules/kubernetes/jobs/xo-kubernetes-cluster-delete-args.ts'
1+
import { xoKubernetesClustersArg } from '@/modules/kubernetes/jobs/xo-kubernetes-cluster-args.ts'
22
import type { XoKubernetesCluster } from '@/modules/kubernetes/types/xo-kubernetes.type.ts'
33
import { fetchDelete } from '@/shared/utils/fetch.util.ts'
44
import { defineJob, JobError, JobRunningError } from '@core/packages/job'
55
import { useI18n } from 'vue-i18n'
66

7-
export const useXoKubernetesClusterDeleteJob = defineJob('kubernetes-cluster.delete', [clustersArg], () => {
7+
export const useXoKubernetesClusterDeleteJob = defineJob('kubernetes-cluster.delete', [xoKubernetesClustersArg], () => {
88
const { t } = useI18n()
99

1010
return {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { xoKubernetesClusterArg } from '@/modules/kubernetes/jobs/xo-kubernetes-cluster-args.ts'
2+
import type { XoKubernetesCluster } from '@/modules/kubernetes/types/xo-kubernetes.type.ts'
3+
import { fetchRequest } from '@/shared/utils/fetch.util.ts'
4+
import { defineJob, JobError, JobRunningError } from '@core/packages/job'
5+
import { downloadFile } from '@core/utils/download-file.utils.ts'
6+
import { useI18n } from 'vue-i18n'
7+
8+
export const useXoKubernetesClusterKubeconfigDownloadJob = defineJob(
9+
'kubernetes-cluster.kubeconfig-download',
10+
[xoKubernetesClusterArg],
11+
() => {
12+
const { t } = useI18n()
13+
14+
return {
15+
async run(cluster: XoKubernetesCluster) {
16+
const { kubeconfig } = await fetchRequest<{ kubeconfig: string }>(`kubernetes/clusters/${cluster.id}/config`)
17+
18+
const url = URL.createObjectURL(new Blob([kubeconfig], { type: 'application/yaml' }))
19+
20+
downloadFile(url, `${cluster.name}-kubeconfig.yaml`, false)
21+
URL.revokeObjectURL(url)
22+
},
23+
24+
validate(isRunning, cluster: XoKubernetesCluster | undefined) {
25+
if (!cluster) {
26+
throw new JobError(t('job:cluster-kubeconfig-download:missing-cluster'))
27+
}
28+
29+
if (isRunning) {
30+
throw new JobRunningError(t('job:download:in-progress'))
31+
}
32+
},
33+
}
34+
}
35+
)

‎CHANGELOG.unreleased.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- [XO6/Kubernetes] Add Kubernetes in the treeview, Kubernetes page with clusters table and side-panel (PR [#10459](https://github.com/vatesfr/xen-orchestra/pull/10459))
1515
- [XO6/Kubernetes] Kubernetes clusters can now be created from the UI (PR [#10524](https://github.com/vatesfr/xen-orchestra/pull/10524))
1616
- [XO6/Kubernetes] Kubernetes clusters can now be deleted from the UI (PR [#10526](https://github.com/vatesfr/xen-orchestra/pull/10526))
17+
- [XO6/Kubernetes] Kubernetes clusters kubeconfig admin file can now be downloaded from the UI (PR [#10535](https://github.com/vatesfr/xen-orchestra/pull/10535))
1718

1819
### Bug fixes
1920

0 commit comments

Comments
 (0)