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