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
|
title: Dashboard
|
||||||
backToRancher: Cluster Manager
|
backToRancher: Cluster Manager
|
||||||
clusterTools: Cluster Tools
|
clusterTools: Cluster Tools
|
||||||
shell: Kubectl Shell
|
kubeconfig: Download KubeConfig
|
||||||
import: Import YAML
|
import: Import YAML
|
||||||
home: Home
|
home: Home
|
||||||
|
shell: Kubectl Shell
|
||||||
support: Get Support
|
support: Get Support
|
||||||
group:
|
group:
|
||||||
cluster: Cluster
|
cluster: Cluster
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,15 @@ export default {
|
||||||
return this.$store.getters['rancher/byId'](NORMAN.PRINCIPAL, this.$store.getters['auth/principalId']) || {};
|
return this.$store.getters['rancher/byId'](NORMAN.PRINCIPAL, this.$store.getters['auth/principalId']) || {};
|
||||||
},
|
},
|
||||||
|
|
||||||
showShell() {
|
kubeConfigEnabled() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
shellEnabled() {
|
||||||
return !!this.currentCluster?.links?.shell;
|
return !!this.currentCluster?.links?.shell;
|
||||||
},
|
},
|
||||||
|
|
||||||
showImport() {
|
importEnabled() {
|
||||||
return !!this.currentCluster?.actions?.apply;
|
return !!this.currentCluster?.actions?.apply;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -147,36 +151,46 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!simple" class="header-buttons">
|
<div v-if="!simple" class="header-buttons">
|
||||||
<button
|
<template v-if="currentProduct && currentProduct.showClusterSwitcher">
|
||||||
v-if="currentProduct && currentProduct.showClusterSwitcher"
|
<button
|
||||||
v-tooltip="t('nav.import')"
|
v-tooltip="t('nav.import')"
|
||||||
:disabled="!showImport"
|
:disabled="!importEnabled"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn header-btn role-tertiary"
|
class="btn header-btn role-tertiary"
|
||||||
@click="openImport()"
|
@click="openImport()"
|
||||||
>
|
>
|
||||||
<i class="icon icon-upload icon-lg" />
|
<i class="icon icon-upload icon-lg" />
|
||||||
</button>
|
</button>
|
||||||
<modal
|
<modal
|
||||||
class="import-modal"
|
class="import-modal"
|
||||||
name="importModal"
|
name="importModal"
|
||||||
width="75%"
|
width="75%"
|
||||||
height="auto"
|
height="auto"
|
||||||
styles="max-height: 90vh;"
|
styles="max-height: 90vh;"
|
||||||
>
|
>
|
||||||
<Import :cluster="currentCluster" @close="closeImport" />
|
<Import :cluster="currentCluster" @close="closeImport" />
|
||||||
</modal>
|
</modal>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="currentProduct && currentProduct.showClusterSwitcher"
|
v-tooltip="t('nav.shell')"
|
||||||
v-tooltip="t('nav.shell')"
|
:disabled="!shellEnabled"
|
||||||
:disabled="!showShell"
|
type="button"
|
||||||
type="button"
|
class="btn header-btn role-tertiary"
|
||||||
class="btn header-btn role-tertiary"
|
@click="currentCluster.openShell()"
|
||||||
@click="currentCluster.openShell()"
|
>
|
||||||
>
|
<i class="icon icon-terminal icon-lg" />
|
||||||
<i class="icon icon-terminal icon-lg" />
|
</button>
|
||||||
</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
|
<button
|
||||||
v-if="showSearch"
|
v-if="showSearch"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import { CATALOG } from '@/config/labels-annotations';
|
import { CATALOG } from '@/config/labels-annotations';
|
||||||
import { FLEET, MANAGEMENT } from '@/config/types';
|
import { FLEET, MANAGEMENT } from '@/config/types';
|
||||||
import { insertAt } from '@/utils/array';
|
import { insertAt } from '@/utils/array';
|
||||||
|
import { downloadFile } from '@/utils/download';
|
||||||
import { parseSi } from '@/utils/units';
|
import { parseSi } from '@/utils/units';
|
||||||
|
import jsyaml from 'js-yaml';
|
||||||
|
import { eachLimit } from '@/utils/promise';
|
||||||
|
|
||||||
// See translation file cluster.providers for list of providers
|
// See translation file cluster.providers for list of providers
|
||||||
// If the logo is not named with the provider name, add an override here
|
// If the logo is not named with the provider name, add an override here
|
||||||
|
|
@ -37,6 +40,15 @@ export default {
|
||||||
enabled: !!this.links.shell,
|
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;
|
return out;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -102,21 +114,6 @@ export default {
|
||||||
return '';
|
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() {
|
providerOs() {
|
||||||
if ( this.status?.provider === 'rke.windows' ) {
|
if ( this.status?.provider === 'rke.windows' ) {
|
||||||
return 'windows';
|
return 'windows';
|
||||||
|
|
@ -189,5 +186,67 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
return null;
|
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 { CAPI, MANAGEMENT, NORMAN } from '@/config/types';
|
||||||
import { findBy } from '@/utils/array';
|
import { findBy, insertAt } from '@/utils/array';
|
||||||
import { sortBy } from '@/utils/sort';
|
import { sortBy } from '@/utils/sort';
|
||||||
import { ucFirst } from '@/utils/string';
|
import { ucFirst } from '@/utils/string';
|
||||||
|
|
||||||
|
|
@ -25,6 +25,28 @@ export default {
|
||||||
return out;
|
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() {
|
isImported() {
|
||||||
return this.provisioner === 'imported';
|
return this.provisioner === 'imported';
|
||||||
},
|
},
|
||||||
|
|
@ -208,5 +230,29 @@ export default {
|
||||||
|
|
||||||
return token.save();
|
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