feat(xo-web/new/metadata): ability to set the backup report when property (#4149)

This commit is contained in:
badrAZ
2019-05-15 16:47:59 +02:00
committed by Pierre Donias
parent 36a5f52068
commit 0b0f235252
5 changed files with 156 additions and 82 deletions

View File

@@ -3,6 +3,7 @@
### Enhancements
- [VM/general] Display 'Started... ago' instead of 'Halted... ago' for paused state [#3750](https://github.com/vatesfr/xen-orchestra/issues/3750) (PR [#4170](https://github.com/vatesfr/xen-orchestra/pull/4170))
- [Metadata backup] Ability to define when the backup report will be sent (PR [#4149](https://github.com/vatesfr/xen-orchestra/pull/4149))
### Bug fixes

View File

@@ -7,6 +7,7 @@ const DEFAULTS = {
concurrency: 0,
fullInterval: 0,
offlineSnapshot: false,
reportWhen: 'failure',
timeout: 0,
}

View File

@@ -0,0 +1,70 @@
import _ from 'intl'
import decorate from 'apply-decorators'
import Icon from 'icon'
import Link from 'link'
import PropTypes from 'prop-types'
import React from 'react'
import Select from 'form/select'
import Tooltip from 'tooltip'
import { generateId } from 'reaclette-utils'
import { injectState, provideState } from 'reaclette'
import { FormGroup } from './../utils'
const REPORT_WHEN_FILTER_OPTIONS = [
{
label: 'reportWhenAlways',
value: 'always',
},
{
label: 'reportWhenFailure',
value: 'failure',
},
{
label: 'reportWhenNever',
value: 'never',
},
]
const getOptionRenderer = ({ label }) => <span>{_(label)}</span>
const ReportWhen = decorate([
provideState({
computed: {
idInput: generateId,
},
}),
injectState,
({ state, onChange, value, ...props }) => (
<FormGroup>
<label htmlFor={state.idInput}>
<strong>{_('reportWhen')}</strong>
</label>{' '}
<Tooltip content={_('pluginsWarning')}>
<Link
className='btn btn-primary btn-sm'
target='_blank'
to='/settings/plugins'
>
<Icon icon='menu-settings-plugins' />{' '}
<strong>{_('pluginsSettings')}</strong>
</Link>
</Tooltip>
<Select
id={state.idInput}
onChange={onChange}
optionRenderer={getOptionRenderer}
options={REPORT_WHEN_FILTER_OPTIONS}
value={value}
{...props}
/>
</FormGroup>
),
])
ReportWhen.propTypes = {
onChange: PropTypes.func.isRequired,
value: PropTypes.string,
}
export { ReportWhen as default }

View File

@@ -7,7 +7,6 @@ import Icon from 'icon'
import Link from 'link'
import moment from 'moment-timezone'
import React from 'react'
import Select from 'form/select'
import Tooltip from 'tooltip'
import Upgrade from 'xoa-upgrade'
import UserError from 'user-error'
@@ -42,6 +41,7 @@ import {
} from 'xo'
import NewSchedule from './new-schedule'
import ReportWhen from './_reportWhen'
import Schedules from './schedules'
import SmartBackup from './smart-backup'
import getSettingsWithNonDefaultValue from '../_getSettingsWithNonDefaultValue'
@@ -115,23 +115,6 @@ const destructVmsPattern = pattern =>
vms: destructPattern(pattern),
}
const REPORT_WHEN_FILTER_OPTIONS = [
{
label: 'reportWhenAlways',
value: 'always',
},
{
label: 'reportWhenFailure',
value: 'failure',
},
{
label: 'reportWhenNever',
value: 'never',
},
]
const getOptionRenderer = ({ label }) => <span>{_(label)}</span>
const createDoesRetentionExist = name => {
const predicate = setting => setting[name] > 0
return ({ propSettings, settings = propSettings }) => settings.some(predicate)
@@ -541,7 +524,6 @@ export default decorate([
formId: generateId,
inputConcurrencyId: generateId,
inputFullIntervalId: generateId,
inputReportWhenId: generateId,
inputTimeoutId: generateId,
vmsPattern: ({ _vmsPattern }, { job }) =>
@@ -884,33 +866,13 @@ export default decorate([
</ActionButton>
</CardHeader>
<CardBlock>
<FormGroup>
<label htmlFor={state.inputReportWhenId}>
<strong>{_('reportWhen')}</strong>
</label>{' '}
<Tooltip content={_('pluginsWarning')}>
<Link
className='btn btn-primary btn-sm'
target='_blank'
to='/settings/plugins'
>
<Icon icon='menu-settings-plugins' />{' '}
<strong>{_('pluginsSettings')}</strong>
</Link>
</Tooltip>
<Select
id={state.inputReportWhenId}
labelKey='label'
onChange={effects.setReportWhen}
optionRenderer={getOptionRenderer}
options={REPORT_WHEN_FILTER_OPTIONS}
required
// Handle improper value introduced by:
// https://github.com/vatesfr/xen-orchestra/commit/753ee994f2948bbaca9d3161eaab82329a682773#diff-9c044ab8a42ed6576ea927a64c1ec3ebR105
value={reportWhen === 'Never' ? 'never' : reportWhen}
valueKey='value'
/>
</FormGroup>
<ReportWhen
onChange={effects.setReportWhen}
required
// Handle improper value introduced by:
// https://github.com/vatesfr/xen-orchestra/commit/753ee994f2948bbaca9d3161eaab82329a682773#diff-9c044ab8a42ed6576ea927a64c1ec3ebR105
value={reportWhen === 'Never' ? 'never' : reportWhen}
/>
{state.displayAdvancedSettings && (
<div>
<FormGroup>

View File

@@ -33,6 +33,7 @@ import {
Ul,
} from '../../utils'
import ReportWhen from '../_reportWhen'
import Schedules from '../_schedules'
// A retention can be:
@@ -51,6 +52,25 @@ const RETENTION_XO_METADATA = {
valuePath: 'retentionXoMetadata',
}
const GLOBAL_SETTING_KEY = ''
const setSettingsDefaultRetentions = (
settings,
{ modePoolMetadata, modeXoMetadata }
) =>
mapValues(settings, (setting, key) =>
key !== GLOBAL_SETTING_KEY
? {
retentionPoolMetadata: modePoolMetadata
? defined(setting.retentionPoolMetadata, DEFAULT_RETENTION)
: undefined,
retentionXoMetadata: modeXoMetadata
? defined(setting.retentionXoMetadata, DEFAULT_RETENTION)
: undefined,
}
: setting
)
const getInitialState = () => ({
_modePoolMetadata: undefined,
_modeXoMetadata: undefined,
@@ -79,28 +99,25 @@ export default decorate([
return { showErrors: true }
}
const {
modePoolMetadata,
modeXoMetadata,
name,
pools,
remotes,
schedules,
settings,
} = state
await createMetadataBackupJob({
name: state.name,
pools: state.modePoolMetadata
? constructPattern(state.pools)
: undefined,
remotes: constructPattern(state.remotes),
xoMetadata: state.modeXoMetadata,
schedules: mapValues(
state.schedules,
({ id, ...schedule }) => schedule
),
settings: mapValues(
state.settings,
({ retentionPoolMetadata, retentionXoMetadata }) => ({
retentionPoolMetadata: state.modePoolMetadata
? defined(retentionPoolMetadata, DEFAULT_RETENTION)
: undefined,
retentionXoMetadata: state.modeXoMetadata
? defined(retentionXoMetadata, DEFAULT_RETENTION)
: undefined,
})
),
name,
pools: modePoolMetadata ? constructPattern(pools) : undefined,
remotes: constructPattern(remotes),
schedules: mapValues(schedules, ({ id, ...schedule }) => schedule),
settings: setSettingsDefaultRetentions(settings, {
modePoolMetadata,
modeXoMetadata,
}),
xoMetadata: modeXoMetadata,
})
},
editJob: () => async (state, props) => {
@@ -138,23 +155,17 @@ export default decorate([
}),
])
const { modePoolMetadata, modeXoMetadata, name, pools, remotes } = state
await editMetadataBackupJob({
id: props.job.id,
name: state.name,
pools: state.modePoolMetadata ? constructPattern(state.pools) : null,
remotes: constructPattern(state.remotes),
xoMetadata: state.modeXoMetadata,
settings: mapValues(
settings,
({ retentionPoolMetadata, retentionXoMetadata }) => ({
retentionPoolMetadata: state.modePoolMetadata
? defined(retentionPoolMetadata, DEFAULT_RETENTION)
: undefined,
retentionXoMetadata: state.modeXoMetadata
? defined(retentionXoMetadata, DEFAULT_RETENTION)
: undefined,
})
),
name,
pools: modePoolMetadata ? constructPattern(pools) : null,
remotes: constructPattern(remotes),
settings: setSettingsDefaultRetentions(settings, {
modePoolMetadata,
modeXoMetadata,
}),
xoMetadata: modeXoMetadata,
})
},
@@ -169,6 +180,20 @@ export default decorate([
setSettings: (_, _settings) => () => ({
_settings,
}),
setGlobalSettings: ({ setSettings }, name, value) => ({
settings = {},
}) => {
setSettings({
...settings,
[GLOBAL_SETTING_KEY]: {
...settings[GLOBAL_SETTING_KEY],
[name]: value,
},
})
},
setReportWhen({ setGlobalSettings }, { value }) {
setGlobalSettings('reportWhen', value)
},
toggleMode: (_, { mode }) => state => ({
[`_${mode}`]: !state[mode],
}),
@@ -265,6 +290,11 @@ export default decorate([
missingSchedules,
} = state.showErrors ? state : {}
const { reportWhen = 'failure' } = defined(
() => state.settings[GLOBAL_SETTING_KEY],
{}
)
return (
<form id={state.idForm}>
<Container>
@@ -357,6 +387,16 @@ export default decorate([
)}
</CardBlock>
</Card>
<Card>
<CardHeader>{_('newBackupSettings')}</CardHeader>
<CardBlock>
<ReportWhen
onChange={effects.setReportWhen}
required
value={reportWhen}
/>
</CardBlock>
</Card>
</Col>
<Col mediumSize={6}>
{state.modePoolMetadata && (