mirror of https://github.com/rancher/dashboard.git
RKE2 backup & restore
This commit is contained in:
parent
e7f1fbc9dd
commit
f95f4e802a
|
|
@ -6,6 +6,8 @@ import Banner from '@/components/Banner';
|
|||
import Date from '@/components/formatter/Date.vue';
|
||||
import RadioGroup from '@/components/form/RadioGroup.vue';
|
||||
import { exceptionToErrorsArray } from '@/utils/error';
|
||||
import { CAPI } from '@/config/types';
|
||||
import { set } from '@/utils/object';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -20,7 +22,7 @@ export default {
|
|||
return {
|
||||
errors: [],
|
||||
labels: {},
|
||||
restoreMode: 'etcd',
|
||||
restoreMode: 'all',
|
||||
moveTo: this.workspace,
|
||||
loaded: false,
|
||||
allWorkspaces: [],
|
||||
|
|
@ -62,14 +64,22 @@ export default {
|
|||
|
||||
async apply(buttonDone) {
|
||||
try {
|
||||
await this.$store.dispatch('rancher/request', {
|
||||
url: `/v3/clusters/${ escape(this.snapshot.clusterId) }?action=restoreFromEtcdBackup`,
|
||||
method: 'post',
|
||||
data: {
|
||||
etcdBackupId: this.snapshot.id,
|
||||
restoreRkeConfig: this.restoreMode,
|
||||
},
|
||||
});
|
||||
if ( this.isRke2 ) {
|
||||
const cluster = this.$store.getters['management/byId'](CAPI.RANCHER_CLUSTER, this.snapshot.clusterId);
|
||||
|
||||
set(cluster, 'spec.rkeConfig.etcdSnapshotRestore', { name: this.snapshot.name });
|
||||
|
||||
await cluster.save();
|
||||
} else {
|
||||
await this.$store.dispatch('rancher/request', {
|
||||
url: `/v3/clusters/${ escape(this.snapshot.clusterId) }?action=restoreFromEtcdBackup`,
|
||||
method: 'post',
|
||||
data: {
|
||||
etcdBackupId: this.snapshot.id,
|
||||
restoreRkeConfig: this.restoreMode,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
buttonDone(true);
|
||||
this.close();
|
||||
|
|
@ -103,15 +113,17 @@ export default {
|
|||
<h3>Snapshot Date</h3>
|
||||
<div><Date :value="snapshot.createdAt || snapshot.created" /></div>
|
||||
|
||||
<div class="spacer" />
|
||||
<template v-if="!isRke2">
|
||||
<div class="spacer" />
|
||||
|
||||
<RadioGroup
|
||||
v-model="restoreMode"
|
||||
name="restoreMode"
|
||||
label="Restore Type"
|
||||
:labels="['Only etcd', 'Kubernetes version and etcd', 'Cluster config, Kubernetes version and etcd']"
|
||||
:options="['etcd', 'kubernetesVersion', 'all']"
|
||||
/>
|
||||
<RadioGroup
|
||||
v-model="restoreMode"
|
||||
name="restoreMode"
|
||||
label="Restore Type"
|
||||
:labels="['Only etcd', 'Kubernetes version and etcd', 'Cluster config, Kubernetes version and etcd']"
|
||||
:options="['etcd', 'kubernetesVersion', 'all']"
|
||||
/>
|
||||
</template>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
|
@ -122,12 +134,9 @@ export default {
|
|||
|
||||
<AsyncButton
|
||||
mode="restore"
|
||||
:disabled="isRke2"
|
||||
@click="apply"
|
||||
/>
|
||||
|
||||
<Banner v-if="isRke2" color="warning" label="@TODO The actual rke2 restore action..." />
|
||||
|
||||
<Banner v-for="(err, i) in errors" :key="i" color="error" :label="err" />
|
||||
</div>
|
||||
</Card>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
} from '@/config/table-headers';
|
||||
import CustomCommand from '@/edit/provisioning.cattle.io.cluster/CustomCommand';
|
||||
import AsyncButton from '@/components/AsyncButton.vue';
|
||||
import { set } from '@/utils/object';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -191,8 +192,9 @@ export default {
|
|||
btnCb(true);
|
||||
}, 1000);
|
||||
} else {
|
||||
btnCb(false);
|
||||
this.$store.dispatch('growl/fromError', { title: '@TODO Actual RKE2 snapshot create API call' });
|
||||
set(this.value.spec.rkeConfig, 'etcdSnapshotCreate', {});
|
||||
await this.value.save();
|
||||
btnCb(true);
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.dispatch('growl/fromError', { title: 'Error creating snapshot', err });
|
||||
|
|
|
|||
|
|
@ -313,9 +313,9 @@ export default {
|
|||
v-model="provisioner"
|
||||
class="rke-switch"
|
||||
off-value="rke1"
|
||||
off-label="RKE"
|
||||
off-label="RKE1"
|
||||
on-value="rke2"
|
||||
on-label="RKE2"
|
||||
on-label="RKE2/K3s"
|
||||
/>
|
||||
</div>
|
||||
{{ obj.label }}
|
||||
|
|
|
|||
|
|
@ -42,14 +42,21 @@ export default async function({
|
|||
}
|
||||
// Initial ?setup=admin-password can technically be on any route
|
||||
const initialPass = route.query[SETUP];
|
||||
const firstLogin = await store.dispatch('rancher/find', {
|
||||
type: 'setting',
|
||||
id: 'first-login',
|
||||
opt: { url: `/v3/settings/first-login` }
|
||||
});
|
||||
let firstLogin = false;
|
||||
|
||||
try {
|
||||
const res = await store.dispatch('rancher/find', {
|
||||
type: 'setting',
|
||||
id: 'first-login',
|
||||
opt: { url: `/v3/settings/first-login` }
|
||||
});
|
||||
|
||||
firstLogin = res?.value === 'true';
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
// TODO show error if firstLogin and default pass doesn't work
|
||||
if (firstLogin && firstLogin.value === 'true' ) {
|
||||
if ( firstLogin ) {
|
||||
const ok = await tryInitialSetup(store, initialPass);
|
||||
|
||||
if (ok) {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ export default {
|
|||
function responseObject(res) {
|
||||
let out = res.data;
|
||||
|
||||
if ( res.status === 201 ) {
|
||||
if ( res.status === 204 || out === null ) {
|
||||
out = {};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue