feat(xo-server/xo.exportConfig): new compress=true param

This commit is contained in:
Julien Fontanet 2023-04-21 17:03:12 +02:00
parent 76a91cc5e9
commit a956cb2ac9
3 changed files with 20 additions and 6 deletions

View File

@ -25,7 +25,7 @@
"xo-server-recover-account": "dist/recover-account-cli.mjs" "xo-server-recover-account": "dist/recover-account-cli.mjs"
}, },
"engines": { "engines": {
"node": ">=14.17" "node": ">=14.18"
}, },
"dependencies": { "dependencies": {
"@iarna/toml": "^2.2.1", "@iarna/toml": "^2.2.1",

View File

@ -15,8 +15,11 @@ clean.permission = 'admin'
// ------------------------------------------------------------------- // -------------------------------------------------------------------
export async function exportConfig({ entries, passphrase }) { export async function exportConfig({ compress, entries, passphrase }) {
let suffix = '/config.json' let suffix = '/config.json'
if (compress) {
suffix += '.gz'
}
if (passphrase !== undefined) { if (passphrase !== undefined) {
suffix += '.enc' suffix += '.enc'
} }
@ -26,10 +29,9 @@ export async function exportConfig({ entries, passphrase }) {
(req, res) => { (req, res) => {
res.set({ res.set({
'content-disposition': 'attachment', 'content-disposition': 'attachment',
'content-type': 'application/json',
}) })
return this.exportConfig({ entries, passphrase }) return this.exportConfig({ compress, entries, passphrase })
}, },
undefined, undefined,
{ suffix } { suffix }
@ -40,6 +42,7 @@ export async function exportConfig({ entries, passphrase }) {
exportConfig.permission = 'admin' exportConfig.permission = 'admin'
exportConfig.params = { exportConfig.params = {
compress: { type: 'boolean', default: true },
entries: { type: 'array', items: { type: 'string' }, optional: true }, entries: { type: 'array', items: { type: 'string' }, optional: true },
passphrase: { type: 'string', optional: true }, passphrase: { type: 'string', optional: true },
} }

View File

@ -1,6 +1,8 @@
import * as openpgp from 'openpgp' import * as openpgp from 'openpgp'
import DepTree from 'deptree' import DepTree from 'deptree'
import fromCallback from 'promise-toolbox/fromCallback'
import { createLogger } from '@xen-orchestra/log' import { createLogger } from '@xen-orchestra/log'
import { gunzip, gzip } from 'node:zlib'
import { asyncMapValues } from '../_asyncMapValues.mjs' import { asyncMapValues } from '../_asyncMapValues.mjs'
@ -23,7 +25,7 @@ export default class ConfigManagement {
this._managers[id] = { dependencies, exporter, importer } this._managers[id] = { dependencies, exporter, importer }
} }
async exportConfig({ entries, passphrase } = {}) { async exportConfig({ compress = false, entries, passphrase } = {}) {
let managers = this._managers let managers = this._managers
if (entries !== undefined) { if (entries !== undefined) {
const subset = { __proto__: null } const subset = { __proto__: null }
@ -39,11 +41,15 @@ export default class ConfigManagement {
let config = JSON.stringify(await asyncMapValues(managers, ({ exporter }) => exporter())) let config = JSON.stringify(await asyncMapValues(managers, ({ exporter }) => exporter()))
if (compress) {
config = await fromCallback(gzip, config)
}
if (passphrase !== undefined) { if (passphrase !== undefined) {
config = Buffer.from( config = Buffer.from(
await openpgp.encrypt({ await openpgp.encrypt({
format: 'binary', format: 'binary',
message: await openpgp.createMessage({ text: config }), message: await openpgp.createMessage(typeof config === 'string' ? { text: config } : { binary: config }),
passwords: passphrase, passwords: passphrase,
}) })
) )
@ -56,12 +62,17 @@ export default class ConfigManagement {
if (passphrase !== undefined) { if (passphrase !== undefined) {
config = ( config = (
await openpgp.decrypt({ await openpgp.decrypt({
format: 'binary',
message: await openpgp.readMessage({ binaryMessage: config }), message: await openpgp.readMessage({ binaryMessage: config }),
passwords: passphrase, passwords: passphrase,
}) })
).data ).data
} }
if (typeof config !== 'string' && config[0] === 0x1f && config[1] === 0x8b) {
config = await fromCallback(gunzip, config)
}
config = JSON.parse(config) config = JSON.parse(config)
const managers = this._managers const managers = this._managers