mirror of https://github.com/rancher/dashboard.git
Single + bulk download kubeconfig
This commit is contained in:
parent
8f15575514
commit
ecfed78021
|
|
@ -75,9 +75,10 @@ nav:
|
|||
title: Dashboard
|
||||
backToRancher: Cluster Manager
|
||||
clusterTools: Cluster Tools
|
||||
shell: Kubectl Shell
|
||||
kubeconfig: Download KubeConfig
|
||||
import: Import YAML
|
||||
home: Home
|
||||
shell: Kubectl Shell
|
||||
support: Get Support
|
||||
group:
|
||||
cluster: Cluster
|
||||
|
|
|
|||
|
|
@ -47,11 +47,15 @@ export default {
|
|||
return this.$store.getters['rancher/byId'](NORMAN.PRINCIPAL, this.$store.getters['auth/principalId']) || {};
|
||||
},
|
||||
|
||||
showShell() {
|
||||
kubeConfigEnabled() {
|
||||
return true;
|
||||
},
|
||||
|
||||
shellEnabled() {
|
||||
return !!this.currentCluster?.links?.shell;
|
||||
},
|
||||
|
||||
showImport() {
|
||||
importEnabled() {
|
||||
return !!this.currentCluster?.actions?.apply;
|
||||
},
|
||||
|
||||
|
|
@ -147,36 +151,46 @@ export default {
|
|||
</div>
|
||||
|
||||
<div v-if="!simple" class="header-buttons">
|
||||
<button
|
||||
v-if="currentProduct && currentProduct.showClusterSwitcher"
|
||||
v-tooltip="t('nav.import')"
|
||||
:disabled="!showImport"
|
||||
type="button"
|
||||
class="btn header-btn role-tertiary"
|
||||
@click="openImport()"
|
||||
>
|
||||
<i class="icon icon-upload icon-lg" />
|
||||
</button>
|
||||
<modal
|
||||
class="import-modal"
|
||||
name="importModal"
|
||||
width="75%"
|
||||
height="auto"
|
||||
styles="max-height: 90vh;"
|
||||
>
|
||||
<Import :cluster="currentCluster" @close="closeImport" />
|
||||
</modal>
|
||||
<template v-if="currentProduct && currentProduct.showClusterSwitcher">
|
||||
<button
|
||||
v-tooltip="t('nav.import')"
|
||||
:disabled="!importEnabled"
|
||||
type="button"
|
||||
class="btn header-btn role-tertiary"
|
||||
@click="openImport()"
|
||||
>
|
||||
<i class="icon icon-upload icon-lg" />
|
||||
</button>
|
||||
<modal
|
||||
class="import-modal"
|
||||
name="importModal"
|
||||
width="75%"
|
||||
height="auto"
|
||||
styles="max-height: 90vh;"
|
||||
>
|
||||
<Import :cluster="currentCluster" @close="closeImport" />
|
||||
</modal>
|
||||
|
||||
<button
|
||||
v-if="currentProduct && currentProduct.showClusterSwitcher"
|
||||
v-tooltip="t('nav.shell')"
|
||||
:disabled="!showShell"
|
||||
type="button"
|
||||
class="btn header-btn role-tertiary"
|
||||
@click="currentCluster.openShell()"
|
||||
>
|
||||
<i class="icon icon-terminal icon-lg" />
|
||||
</button>
|
||||
<button
|
||||
v-tooltip="t('nav.shell')"
|
||||
:disabled="!shellEnabled"
|
||||
type="button"
|
||||
class="btn header-btn role-tertiary"
|
||||
@click="currentCluster.openShell()"
|
||||
>
|
||||
<i class="icon icon-terminal icon-lg" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-tooltip="t('nav.kubeconfig')"
|
||||
:disabled="!kubeConfigEnabled"
|
||||
type="button"
|
||||
class="btn header-btn role-tertiary"
|
||||
@click="currentCluster.downloadKubeConfig()"
|
||||
>
|
||||
<i class="icon icon-file icon-lg" />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<button
|
||||
v-if="showSearch"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import { CATALOG } from '@/config/labels-annotations';
|
||||
import { FLEET, MANAGEMENT } from '@/config/types';
|
||||
import { insertAt } from '@/utils/array';
|
||||
import { downloadFile } from '@/utils/download';
|
||||
import { parseSi } from '@/utils/units';
|
||||
import jsyaml from 'js-yaml';
|
||||
import { eachLimit } from '@/utils/promise';
|
||||
|
||||
// See translation file cluster.providers for list of providers
|
||||
// If the logo is not named with the provider name, add an override here
|
||||
|
|
@ -37,6 +40,15 @@ export default {
|
|||
enabled: !!this.links.shell,
|
||||
});
|
||||
|
||||
insertAt(out, 1, {
|
||||
action: 'downloadKubeConfig',
|
||||
bulkAction: 'downloadKubeConfigBulk',
|
||||
label: 'Download KubeConfig',
|
||||
icon: 'icon icon-download',
|
||||
bulkable: true,
|
||||
enabled: this.$rootGetters['isRancher'],
|
||||
});
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
|
|
@ -102,21 +114,6 @@ export default {
|
|||
return '';
|
||||
},
|
||||
|
||||
openShell() {
|
||||
return () => {
|
||||
this.$dispatch('wm/open', {
|
||||
id: `kubectl-${ this.id }`,
|
||||
label: this.$rootGetters['i18n/t']('wm.kubectlShell.title', { name: this.nameDisplay }),
|
||||
icon: 'terminal',
|
||||
component: 'KubectlShell',
|
||||
attrs: {
|
||||
cluster: this,
|
||||
pod: {}
|
||||
}
|
||||
}, { root: true });
|
||||
};
|
||||
},
|
||||
|
||||
providerOs() {
|
||||
if ( this.status?.provider === 'rke.windows' ) {
|
||||
return 'windows';
|
||||
|
|
@ -189,5 +186,67 @@ export default {
|
|||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
openShell() {
|
||||
return () => {
|
||||
this.$dispatch('wm/open', {
|
||||
id: `kubectl-${ this.id }`,
|
||||
label: this.$rootGetters['i18n/t']('wm.kubectlShell.title', { name: this.nameDisplay }),
|
||||
icon: 'terminal',
|
||||
component: 'KubectlShell',
|
||||
attrs: {
|
||||
cluster: this,
|
||||
pod: {}
|
||||
}
|
||||
}, { root: true });
|
||||
};
|
||||
},
|
||||
|
||||
generateKubeConfig() {
|
||||
return async() => {
|
||||
const res = await this.$dispatch('request', {
|
||||
method: 'post',
|
||||
url: `/v3/clusters/${ this.id }?action=generateKubeconfig`
|
||||
});
|
||||
|
||||
return res.config;
|
||||
};
|
||||
},
|
||||
|
||||
downloadKubeConfig() {
|
||||
return async() => {
|
||||
const config = await this.generateKubeConfig();
|
||||
|
||||
downloadFile(`${ this.nameDisplay }.yaml`, config, 'application/yaml');
|
||||
};
|
||||
},
|
||||
|
||||
downloadKubeConfigBulk() {
|
||||
return async(items) => {
|
||||
let obj = {};
|
||||
let first = true;
|
||||
|
||||
await eachLimit(items, 10, (item, idx) => {
|
||||
return item.generateKubeConfig().then((config) => {
|
||||
const entry = jsyaml.safeLoad(config);
|
||||
|
||||
if ( first ) {
|
||||
obj = entry;
|
||||
first = false;
|
||||
} else {
|
||||
obj.clusters.push(...entry.clusters);
|
||||
obj.users.push(...entry.users);
|
||||
obj.contexts.push(...entry.contexts);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
delete obj['current-context'];
|
||||
|
||||
const out = jsyaml.safeDump(obj);
|
||||
|
||||
downloadFile('kubeconfig.yaml', out, 'application/yaml');
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { CAPI, MANAGEMENT, NORMAN } from '@/config/types';
|
||||
import { findBy } from '@/utils/array';
|
||||
import { findBy, insertAt } from '@/utils/array';
|
||||
import { sortBy } from '@/utils/sort';
|
||||
import { ucFirst } from '@/utils/string';
|
||||
|
||||
|
|
@ -25,6 +25,28 @@ export default {
|
|||
return out;
|
||||
},
|
||||
|
||||
_availableActions() {
|
||||
const out = this._standardActions;
|
||||
|
||||
insertAt(out, 0, {
|
||||
action: 'openShell',
|
||||
label: 'Kubectl Shell',
|
||||
icon: 'icon icon-terminal',
|
||||
enabled: !!this.mgmt?.links.shell,
|
||||
});
|
||||
|
||||
insertAt(out, 1, {
|
||||
action: 'downloadKubeConfig',
|
||||
bulkAction: 'downloadKubeConfigBulk',
|
||||
label: 'Download KubeConfig',
|
||||
icon: 'icon icon-download',
|
||||
bulkable: true,
|
||||
enabled: this.$rootGetters['isRancher'],
|
||||
});
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
isImported() {
|
||||
return this.provisioner === 'imported';
|
||||
},
|
||||
|
|
@ -208,5 +230,29 @@ export default {
|
|||
|
||||
return token.save();
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
openShell() {
|
||||
return () => {
|
||||
return this.mgmt?.openShell();
|
||||
};
|
||||
},
|
||||
|
||||
generateKubeConfig() {
|
||||
return () => {
|
||||
return this.mgmt?.generateKubeConfig();
|
||||
};
|
||||
},
|
||||
|
||||
downloadKubeConfig() {
|
||||
return () => {
|
||||
return this.mgmt?.downloadKubeConfig();
|
||||
};
|
||||
},
|
||||
|
||||
downloadKubeConfigBulk() {
|
||||
return (items) => {
|
||||
return this.mgmt?.downloadKubeConfigBulk(items);
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue