Compare commits

...

3 Commits

Author SHA1 Message Date
badrAZ
888ae03d2d update implementation 2021-04-16 15:56:12 +02:00
badrAZ
125b74d873 Merge branch 'master' into compactReport 2021-04-16 15:36:49 +02:00
badrAZ
5258dad51a feat(xo-server-backup-reports): send compact report to slack/mattermost
Fixes #3195

This PR removes subtasks from markdown
2021-01-29 12:05:56 +01:00
2 changed files with 61 additions and 23 deletions

View File

@@ -320,6 +320,7 @@ You can learn more about XenServer [resource management on the Citrix Website](h
:::tip :::tip
XCP-ng doesn't limit VMs to 32 vCPU XCP-ng doesn't limit VMs to 32 vCPU
::: :::
### VDI live migration ### VDI live migration
Thanks to Xen Storage Motion, it's easy to move a VM disk from one storage location to another, while the VM is running! This feature can help you migrate from your local storage to a SAN, or just upgrade your SAN without any downtime. Thanks to Xen Storage Motion, it's easy to move a VM disk from one storage location to another, while the VM is running! This feature can help you migrate from your local storage to a SAN, or just upgrade your SAN without any downtime.
@@ -492,9 +493,11 @@ If you are behind a proxy, please update your `xo-server` configuration to add a
As specified in the [documentation](https://xcp-ng.org/docs/requirements.html#pool-requirements) your pool shouldn't consist of hosts from different CPU vendors. As specified in the [documentation](https://xcp-ng.org/docs/requirements.html#pool-requirements) your pool shouldn't consist of hosts from different CPU vendors.
::: :::
::: warning ::: warning
- Even with matching CPU vendors, in the case of different CPU models XCP-ng will scale the pool CPU ability to the CPU having the least instructions. - Even with matching CPU vendors, in the case of different CPU models XCP-ng will scale the pool CPU ability to the CPU having the least instructions.
- All the hosts in a pool must run the same XCP-ng version. - All the hosts in a pool must run the same XCP-ng version.
::: :::
### Creating a pool ### Creating a pool
First you should add your new host to XOA by going to New > Server as described in [the relevant chapter](manage_infrastructure.md#add-a-host). First you should add your new host to XOA by going to New > Server as described in [the relevant chapter](manage_infrastructure.md#add-a-host).

View File

@@ -375,10 +375,22 @@ class BackupReportsXoPlugin {
}) })
} }
const failedTasksText = [] const failedVmsText = {
const skippedVmsText = [] default: [],
const successfulVmsText = [] compact: [],
const interruptedVmsText = [] }
const skippedVmsText = {
default: [],
compact: [],
}
const successfulVmsText = {
default: [],
compact: [],
}
const interruptedVmsText = {
default: [],
compact: [],
}
const nagiosText = [] const nagiosText = []
let globalMergeSize = 0 let globalMergeSize = 0
@@ -393,8 +405,10 @@ class BackupReportsXoPlugin {
const { type, id } = taskLog.data ?? {} const { type, id } = taskLog.data ?? {}
if (taskLog.message === 'get SR record' || taskLog.message === 'get remote adapter') { if (taskLog.message === 'get SR record' || taskLog.message === 'get remote adapter') {
const text = []
++nFailures ++nFailures
failedTasksText.push( text.push(
// It will ensure that it will never be in a nested list // It will ensure that it will never be in a nested list
'' ''
) )
@@ -402,25 +416,29 @@ class BackupReportsXoPlugin {
try { try {
if (type === 'SR') { if (type === 'SR') {
const { name_label: name, uuid } = xo.getObject(id) const { name_label: name, uuid } = xo.getObject(id)
failedTasksText.push(`### ${name}`, '', `- **UUID**: ${uuid}`) text.push(`### ${name}`, '', `- **UUID**: ${uuid}`)
nagiosText.push(`[(${type} failed) ${name} : ${taskLog.result.message} ]`) nagiosText.push(`[(${type} failed) ${name} : ${taskLog.result.message} ]`)
} else { } else {
const { name } = await xo.getRemote(id) const { name } = await xo.getRemote(id)
failedTasksText.push(`### ${name}`, '', `- **UUID**: ${id}`) text.push(`### ${name}`, '', `- **UUID**: ${id}`)
nagiosText.push(`[(${type} failed) ${name} : ${taskLog.result.message} ]`) nagiosText.push(`[(${type} failed) ${name} : ${taskLog.result.message} ]`)
} }
} catch (error) { } catch (error) {
logger.warn(error) logger.warn(error)
failedTasksText.push(`### ${UNKNOWN_ITEM}`, '', `- **UUID**: ${id}`) text.push(`### ${UNKNOWN_ITEM}`, '', `- **UUID**: ${id}`)
nagiosText.push(`[(${type} failed) ${id} : ${taskLog.result.message} ]`) nagiosText.push(`[(${type} failed) ${id} : ${taskLog.result.message} ]`)
} }
failedTasksText.push( text.push(
`- **Type**: ${type}`, `- **Type**: ${type}`,
...getTemporalDataMarkdown(taskLog.end, taskLog.start, formatDate), ...getTemporalDataMarkdown(taskLog.end, taskLog.start, formatDate),
...getWarningsMarkdown(taskLog.warnings), ...getWarningsMarkdown(taskLog.warnings),
`- **Error**: ${taskLog.result.message}` `- **Error**: ${taskLog.result.message}`
) )
failedVmsText.default.push(...text)
failedVmsText.compact.push(...text)
continue continue
} }
@@ -537,32 +555,39 @@ class BackupReportsXoPlugin {
if (taskLog.result !== undefined) { if (taskLog.result !== undefined) {
if (taskLog.status === 'skipped') { if (taskLog.status === 'skipped') {
++nSkipped ++nSkipped
skippedVmsText.push( const common = [
...text, ...text,
`- **Reason**: ${ `- **Reason**: ${
taskLog.result.message === UNHEALTHY_VDI_CHAIN_ERROR taskLog.result.message === UNHEALTHY_VDI_CHAIN_ERROR
? UNHEALTHY_VDI_CHAIN_MESSAGE ? UNHEALTHY_VDI_CHAIN_MESSAGE
: taskLog.result.message : taskLog.result.message
}` }`,
) ]
skippedVmsText.default.push(...common)
skippedVmsText.compact.push(...common)
nagiosText.push(`[(Skipped) ${vm !== undefined ? vm.name_label : 'undefined'} : ${taskLog.result.message} ]`) nagiosText.push(`[(Skipped) ${vm !== undefined ? vm.name_label : 'undefined'} : ${taskLog.result.message} ]`)
} else { } else {
++nFailures ++nFailures
failedTasksText.push(...text, `- **Error**: ${taskLog.result.message}`) const common = [...text, `- **Error**: ${taskLog.result.message}`]
failedVmsText.default.push(...common)
failedVmsText.compact.push(...common)
nagiosText.push(`[(Failed) ${vm !== undefined ? vm.name_label : 'undefined'} : ${taskLog.result.message} ]`) nagiosText.push(`[(Failed) ${vm !== undefined ? vm.name_label : 'undefined'} : ${taskLog.result.message} ]`)
} }
} else { } else {
if (taskLog.status === 'failure') { if (taskLog.status === 'failure') {
++nFailures ++nFailures
failedTasksText.push(...text, ...subText) failedVmsText.default.push(...text, ...subText)
failedVmsText.compact.push(...text)
nagiosText.push(`[${vm !== undefined ? vm.name_label : 'undefined'}: (failed)[${failedSubTasks.toString()}]]`) nagiosText.push(`[${vm !== undefined ? vm.name_label : 'undefined'}: (failed)[${failedSubTasks.toString()}]]`)
} else if (taskLog.status === 'interrupted') { } else if (taskLog.status === 'interrupted') {
++nInterrupted ++nInterrupted
interruptedVmsText.push(...text, ...subText) interruptedVmsText.default.push(...text, ...subText)
interruptedVmsText.compact.push(...text)
nagiosText.push(`[(Interrupted) ${vm !== undefined ? vm.name_label : 'undefined'}]`) nagiosText.push(`[(Interrupted) ${vm !== undefined ? vm.name_label : 'undefined'}]`)
} else { } else {
successfulVmsText.push(...text, ...subText) successfulVmsText.default.push(...text, ...subText)
successfulVmsText.compact.push(...text)
} }
} }
} }
@@ -582,27 +607,37 @@ class BackupReportsXoPlugin {
...getWarningsMarkdown(log.warnings), ...getWarningsMarkdown(log.warnings),
'', '',
] ]
const slackMarkdown = [...markdown]
if (nFailures !== 0) { if (nFailures !== 0) {
markdown.push('---', '', `## ${nFailures} Failure${nFailures === 1 ? '' : 's'}`, '', ...failedTasksText) const common = ['---', '', `## ${nFailures} Failure${nFailures === 1 ? '' : 's'}`, '']
markdown.push(...common, ...failedVmsText.default)
slackMarkdown.push(...common, ...failedVmsText.compact)
} }
if (nSkipped !== 0) { if (nSkipped !== 0) {
markdown.push('---', '', `## ${nSkipped} Skipped`, '', ...skippedVmsText) const common = ['---', '', `## ${nSkipped} Skipped`, '']
markdown.push(...common, ...skippedVmsText.default)
slackMarkdown.push(...common, ...skippedVmsText.compact)
} }
if (nInterrupted !== 0) { if (nInterrupted !== 0) {
markdown.push('---', '', `## ${nInterrupted} Interrupted`, '', ...interruptedVmsText) const common = ['---', '', `## ${nInterrupted} Interrupted`, '']
markdown.push(...common, ...interruptedVmsText.default)
slackMarkdown.push(...common, ...interruptedVmsText.compact)
} }
if (nSuccesses !== 0 && (force || reportWhen !== 'failure')) { if (nSuccesses !== 0 && (force || reportWhen !== 'failure')) {
markdown.push('---', '', `## ${nSuccesses} Success${nSuccesses === 1 ? '' : 'es'}`, '', ...successfulVmsText) const common = ['---', '', `## ${nSuccesses} Success${nSuccesses === 1 ? '' : 'es'}`, '']
markdown.push(...common, ...successfulVmsText.default)
slackMarkdown.push(...common, ...successfulVmsText.compact)
} }
markdown.push('---', '', `*${pkg.name} v${pkg.version}*`) markdown.push('---', '', `*${pkg.name} v${pkg.version}*`)
return this._sendReport({ return this._sendReport({
mailReceivers, mailReceivers,
markdown: toMarkdown(markdown), markdown: toMarkdown(markdown),
slackMarkdown: toMarkdown(slackMarkdown),
subject: `[Xen Orchestra] ${log.status} Backup report for ${jobName} ${STATUS_ICON[log.status]}`, subject: `[Xen Orchestra] ${log.status} Backup report for ${jobName} ${STATUS_ICON[log.status]}`,
success: log.status === 'success', success: log.status === 'success',
nagiosMarkdown: nagiosMarkdown:
@@ -614,7 +649,7 @@ class BackupReportsXoPlugin {
}) })
} }
_sendReport({ mailReceivers, markdown, nagiosMarkdown, subject, success }) { _sendReport({ mailReceivers, markdown, slackMarkdown = markdown, nagiosMarkdown, subject, success }) {
if (mailReceivers === undefined || mailReceivers.length === 0) { if (mailReceivers === undefined || mailReceivers.length === 0) {
mailReceivers = this._mailsReceivers mailReceivers = this._mailsReceivers
} }
@@ -634,7 +669,7 @@ class BackupReportsXoPlugin {
}), }),
xo.sendSlackMessage !== undefined && xo.sendSlackMessage !== undefined &&
xo.sendSlackMessage({ xo.sendSlackMessage({
message: markdown, message: slackMarkdown,
}), }),
xo.sendPassiveCheck !== undefined && xo.sendPassiveCheck !== undefined &&
xo.sendPassiveCheck({ xo.sendPassiveCheck({