Latest changes from Harvester master - a537c1ae38eb7030542ac371f24ae3336cd9d422

Signed-off-by: Francesco Torchia <francesco.torchia@suse.com>
This commit is contained in:
Francesco Torchia
2024-10-23 17:01:40 +02:00
parent 2ca86930ad
commit 118aaf16b7
35 changed files with 1484 additions and 93 deletions
@@ -660,7 +660,7 @@ export default {
:name="t('harvester.dashboard.hardwareResourceGauge.storage')"
:used="storageUsed"
:reserved="storageAllocated"
:reserved-title="t('harvester.formatters.hardwareResourceGauge.allocated')"
:reserved-title="t('harvester.dashboard.hardwareResourceGauge.allocated')"
/>
</div>
</template>
@@ -0,0 +1,123 @@
<script>
import Loading from '@shell/components/Loading';
import Masthead from '@shell/components/ResourceList/Masthead';
import ResourceTable from '@shell/components/ResourceTable';
import { HCI } from '../types';
import { allSettled } from '../utils/promise';
import { STATE, AGE, NAME, NAMESPACE } from '@shell/config/table-headers';
import { VM_SCHEDULE_CRON, VM_SCHEDULE_RETAIN, VM_SCHEDULE_TYPE, VM_SCHEDULE_MAX_FAILURE } from '../config/table-headers';
import { BACKUP_TYPE } from '../config/types';
export default {
name: 'HarvesterListSchedule',
components: {
ResourceTable, Loading, Masthead,
},
props: {
schema: {
type: Object,
required: true,
}
},
async fetch() {
const inStore = this.$store.getters['currentProduct'].inStore;
const hash = await allSettled({
vms: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.VM }),
rows: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.SCHEDULE_VM_BACKUP }),
});
this.rows = hash.rows;
},
data() {
const params = { ...this.$route.params };
const resource = params.resource;
return {
rows: [],
settings: [],
resource,
to: `${ HCI.SETTING }/backup-target?mode=edit`,
};
},
computed: {
headers() {
const cols = [
STATE,
NAME,
NAMESPACE,
{
name: 'sourceVm',
labelKey: 'harvester.tableHeaders.sourceVm',
value: 'spec.vmbackup.source.name',
sort: 'sourceVm',
align: 'center',
formatter: 'AttachVMWithName'
},
VM_SCHEDULE_TYPE,
VM_SCHEDULE_CRON,
VM_SCHEDULE_RETAIN,
VM_SCHEDULE_MAX_FAILURE,
AGE,
];
return cols;
},
filteredRows() {
return this.rows.filter(R => R.spec?.type !== BACKUP_TYPE.SNAPSHOT);
},
typeDisplay() {
return this.t('harvester.schedule.label');
}
},
methods: {
getRow(row) {
return row.spec?.vmbackup?.source?.name;
}
},
};
</script>
<template>
<Loading v-if="$fetchState.pending" />
<div v-else>
<Masthead
:schema="schema"
:resource="resource"
:type-display="typeDisplay"
:parentNameOverride="'Virtual Machine schedule'"
:create-button-label="t('harvester.schedule.createButtonText')"
/>
<ResourceTable
v-bind="$attrs"
:headers="headers"
:groupable="true"
:rows="filteredRows"
:schema="schema"
key-field="_key"
default-sort-by="age"
>
<template #col:name="{row}">
<td>
<span>
<router-link
v-if="getRow(row)"
:to="row.detailLocation"
>
{{ row.nameDisplay }}
</router-link>
<span v-else>
{{ row.nameDisplay }}
</span>
</span>
</td>
</template>
</ResourceTable>
</div>
</template>
@@ -6,34 +6,37 @@ import Masthead from '@shell/components/ResourceList/Masthead';
import ResourceTable from '@shell/components/ResourceTable';
import { STATE, AGE, NAME, NAMESPACE } from '@shell/config/table-headers';
import FilterVMSchedule from '../components/FilterVMSchedule';
import { HCI } from '../types';
import { allSettled } from '../utils/promise';
import { BACKUP_TYPE } from '../config/types';
import { defaultTableSortGenerationFn } from '@shell/components/ResourceTable.vue';
export default {
name: 'HarvesterListBackup',
components: {
ResourceTable, Banner, Loading, Masthead, MessageLink
ResourceTable, Banner, Loading, Masthead, MessageLink, FilterVMSchedule
},
props: {
schema: {
type: Object,
required: true,
}
},
},
async fetch() {
const inStore = this.$store.getters['currentProduct'].inStore;
const hash = await allSettled({
vms: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.VM }),
settings: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.SETTING }),
rows: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.BACKUP }),
vms: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.VM }),
settings: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.SETTING }),
backups: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.BACKUP }),
scheduleList: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.SCHEDULE_VM_BACKUP }),
});
this.rows = hash.rows;
this.backups = hash.backups;
this.rows = hash.backups;
this.settings = hash.settings;
if (this.$store.getters[`${ inStore }/schemaFor`](HCI.SETTING)) {
const backupTargetResource = hash.settings.find( O => O.id === 'backup-target');
const isEmpty = this.getBackupTargetValueIsEmpty(backupTargetResource);
@@ -50,10 +53,12 @@ export default {
const resource = params.resource;
return {
rows: [],
settings: [],
rows: [],
backups: [],
settings: [],
resource,
to: `${ HCI.SETTING }/backup-target?mode=edit`,
to: `${ HCI.SETTING }/backup-target?mode=edit`,
searchSchedule: ''
};
},
@@ -85,7 +90,25 @@ export default {
}
return out;
}
},
getRow(row) {
return row.status && row.status.source;
},
changeRows(filteredRows, searchSchedule) {
this[searchSchedule] = searchSchedule;
this[backups] = filteredRows;
},
sortGenerationFn() {
let base = defaultTableSortGenerationFn(this.schema, this.$store);
base += this.searchSchedule;
return base;
},
},
computed: {
@@ -101,6 +124,12 @@ export default {
align: 'left',
formatter: 'AttachVMWithName'
},
{
name: 'backupCreatedFrom',
labelKey: 'harvester.tableHeaders.vmSchedule',
value: 'sourceSchedule',
formatter: 'BackupCreatedFrom',
},
{
name: 'backupTarget',
labelKey: 'tableHeaders.backupTarget',
@@ -112,7 +141,7 @@ export default {
name: 'readyToUse',
labelKey: 'tableHeaders.readyToUse',
value: 'status.readyToUse',
align: 'left',
align: 'center',
formatter: 'Checked',
},
];
@@ -124,25 +153,24 @@ export default {
value: 'backupProgress',
align: 'left',
formatter: 'HarvesterBackupProgressBar',
width: 200,
});
}
cols.push(AGE);
return cols;
},
hasBackupProgresses() {
return !!this.rows.find(R => R.status?.progress !== undefined);
return !!this.backups.find(r => r.status?.progress !== undefined);
},
filteredRows() {
return this.rows.filter(R => R.spec?.type !== BACKUP_TYPE.SNAPSHOT);
return this.backups.filter(r => r.spec?.type !== BACKUP_TYPE.SNAPSHOT);
},
getRawRows() {
return this.rows.filter(r => r.spec?.type === BACKUP_TYPE.BACKUP);
},
backupTargetResource() {
return this.settings.find( O => O.id === 'backup-target');
return this.settings.find(O => O.id === 'backup-target');
},
isEmptyValue() {
@@ -211,16 +239,22 @@ export default {
:headers="headers"
:groupable="true"
:rows="filteredRows"
:sort-generation-fn="sortGenerationFn"
:schema="schema"
key-field="_key"
default-sort-by="age"
>
<template #more-header-middle>
<FilterVMSchedule
:rows="getRawRows"
@change-rows="changeRows"
/>
</template>
<template #col:name="{row}">
<td>
<span>
<router-link
v-if="row.status && row.status.source"
v-if="getRow(row)"
:to="row.detailLocation"
>
{{ row.nameDisplay }}
@@ -2,14 +2,15 @@
import Loading from '@shell/components/Loading';
import Masthead from '@shell/components/ResourceList/Masthead';
import ResourceTable from '@shell/components/ResourceTable';
import { SCHEMA } from '@shell/config/types';
import { allHash } from '@shell/utils/promise';
import FilterVMSchedule from '../components/FilterVMSchedule';
import { STATE, AGE, NAME, NAMESPACE } from '@shell/config/table-headers';
import { HCI } from '../types';
import { BACKUP_TYPE } from '../config/types';
import { defaultTableSortGenerationFn } from '@shell/components/ResourceTable.vue';
const schema = {
export const schema = {
id: HCI.VM_SNAPSHOT,
type: SCHEMA,
attributes: {
@@ -22,7 +23,7 @@ const schema = {
export default {
name: 'HarvesterListVMSnapshot',
components: {
ResourceTable, Loading, Masthead
ResourceTable, Loading, Masthead, FilterVMSchedule
},
async fetch() {
@@ -39,6 +40,7 @@ export default {
}
this.rows = hash.rows;
this.snapshots = hash.rows;
},
data() {
@@ -47,7 +49,9 @@ export default {
const resource = params.resource;
return {
rows: [],
rows: [],
snapshots: [],
searchSchedule: '',
resource,
};
},
@@ -63,19 +67,32 @@ export default {
labelKey: 'tableHeaders.targetVm',
value: 'attachVM',
align: 'left',
sort: 'attachVM',
formatter: 'AttachVMWithName'
},
{
name: 'backupCreatedFrom',
labelKey: 'harvester.tableHeaders.vmSchedule',
value: 'sourceSchedule',
sort: 'sourceSchedule',
formatter: 'BackupCreatedFrom',
},
{
name: 'readyToUse',
labelKey: 'tableHeaders.readyToUse',
value: 'status.readyToUse',
align: 'left',
align: 'center',
sort: 'status.readyToUse',
formatter: 'Checked',
},
AGE
];
},
getRawRows() {
return this.rows.filter(r => r.spec?.type === BACKUP_TYPE.SNAPSHOT);
},
schema() {
return schema;
},
@@ -85,9 +102,24 @@ export default {
},
filteredRows() {
return this.rows.filter(R => R.spec?.type !== BACKUP_TYPE.BACKUP);
return this.snapshots.filter(r => r.spec?.type !== BACKUP_TYPE.BACKUP);
},
},
methods: {
changeRows(filteredRows, searchSchedule) {
this['searchSchedule'] = searchSchedule;
this['snapshots'] = filteredRows;
},
sortGenerationFn() {
let base = defaultTableSortGenerationFn(this.schema, this.$store);
base += this.searchSchedule;
return base;
},
}
};
</script>
@@ -100,17 +132,23 @@ export default {
:type-display="typeDisplay"
:create-button-label="t('harvester.vmSnapshot.createText')"
/>
<ResourceTable
v-bind="$attrs"
:headers="headers"
:groupable="true"
:rows="filteredRows"
:schema="schema"
:sort-generation-fn="sortGenerationFn"
key-field="_key"
default-sort-by="age"
>
<template #more-header-middle>
<FilterVMSchedule
:rows="getRawRows"
@change-rows="changeRows"
/>
</template>
<template #col:name="{row}">
<td>
<span>
@@ -126,6 +164,6 @@ export default {
</span>
</td>
</template>
</resourcetable>
</ResourceTable>
</div>
</template>