|
1 | 1 | const url = require('url'); |
2 | | -const xml2js = require('xml2js'); |
3 | 2 | const { errors, errorInstances } = require('arsenal'); |
4 | 3 | const querystring = require('querystring'); |
5 | | -const metadata = require('../../metadata/wrapper'); |
6 | 4 | const { responseXMLBody } = require('arsenal/build/lib/s3routes/routesUtils'); |
7 | | -const { respondWithData, getResponseHeader, buildHeadXML, validPath } = require('./utils'); |
| 5 | +const { respondWithData, getResponseHeader, buildXML, validPath, fetchCapacityMetrics, getBucket } = require('./utils'); |
8 | 6 | const { processVersions, processMasterVersions } = require('../../api/bucketGet'); |
9 | 7 |
|
10 | | - |
11 | 8 | /** |
12 | 9 | * Utility function to build a standard response for the LIST route. |
13 | 10 | * It adds the supported path by default as a static and default file. |
@@ -83,51 +80,67 @@ function buildXMLResponse(request, arrayOfFiles, versioned = false) { |
83 | 80 | * @param {object} log - logger object |
84 | 81 | * @returns {undefined} - |
85 | 82 | */ |
86 | | -function listVeeamFiles(request, response, bucketMd, log) { |
| 83 | +async function listVeeamFiles(request, response, bucketMd, log) { |
87 | 84 | if (!bucketMd) { |
88 | 85 | return responseXMLBody(errors.NoSuchBucket, null, response, log); |
89 | 86 | } |
| 87 | + |
90 | 88 | // Only accept list-type query parameter |
91 | 89 | if (!('list-type' in request.query) && !('versions' in request.query)) { |
92 | 90 | return responseXMLBody(errorInstances.InvalidRequest |
93 | 91 | .customizeDescription('The Veeam folder does not support this action.'), null, response, log); |
94 | 92 | } |
95 | | - return metadata.getBucket(request.bucketName, log, (err, data) => { |
96 | | - if (err) { |
| 93 | + |
| 94 | + let data; |
| 95 | + try { |
| 96 | + data = await getBucket(request.bucketName, log); |
| 97 | + } catch { |
| 98 | + return responseXMLBody(errors.InternalError, null, response, log); |
| 99 | + } |
| 100 | + |
| 101 | + let bucketMetrics; |
| 102 | + if (data._capabilities?.VeeamSOSApi?.CapacityInfo) { |
| 103 | + try { |
| 104 | + bucketMetrics = await fetchCapacityMetrics(bucketMd, request, log); |
| 105 | + } catch { |
97 | 106 | return responseXMLBody(errors.InternalError, null, response, log); |
98 | 107 | } |
99 | | - const filesToBuild = []; |
100 | | - const fieldsToGenerate = []; |
101 | | - if (data._capabilities?.VeeamSOSApi?.SystemInfo) { |
102 | | - fieldsToGenerate.push({ |
103 | | - ...data._capabilities?.VeeamSOSApi?.SystemInfo, |
104 | | - name: `${validPath}system.xml`, |
105 | | - }); |
106 | | - } |
107 | | - if (data._capabilities?.VeeamSOSApi?.CapacityInfo) { |
108 | | - fieldsToGenerate.push({ |
109 | | - ...data._capabilities?.VeeamSOSApi?.CapacityInfo, |
110 | | - name: `${validPath}capacity.xml`, |
111 | | - }); |
112 | | - } |
113 | | - fieldsToGenerate.forEach(file => { |
114 | | - const lastModified = file.LastModified; |
115 | | - // eslint-disable-next-line no-param-reassign |
116 | | - delete file.LastModified; |
117 | | - const builder = new xml2js.Builder({ |
118 | | - headless: true, |
119 | | - }); |
120 | | - const dataBuffer = Buffer.from(buildHeadXML(builder.buildObject(file))); |
121 | | - filesToBuild.push({ |
122 | | - ...getResponseHeader(request, data, |
123 | | - dataBuffer, lastModified, log), |
124 | | - name: file.name, |
125 | | - }); |
| 108 | + } else { |
| 109 | + bucketMetrics = { date: new Date() }; |
| 110 | + } |
| 111 | + |
| 112 | + const filesToBuild = []; |
| 113 | + const fieldsToGenerate = []; |
| 114 | + if (data._capabilities?.VeeamSOSApi?.SystemInfo) { |
| 115 | + fieldsToGenerate.push({ |
| 116 | + ...data._capabilities?.VeeamSOSApi?.SystemInfo, |
| 117 | + name: `${validPath}system.xml`, |
| 118 | + }); |
| 119 | + } |
| 120 | + if (data._capabilities?.VeeamSOSApi?.CapacityInfo) { |
| 121 | + fieldsToGenerate.push({ |
| 122 | + ...data._capabilities?.VeeamSOSApi?.CapacityInfo, |
| 123 | + name: `${validPath}capacity.xml`, |
| 124 | + }); |
| 125 | + } |
| 126 | + fieldsToGenerate.forEach(file => { |
| 127 | + const isCapacity = file.name.endsWith('capacity.xml'); |
| 128 | + const lastModified = isCapacity |
| 129 | + ? bucketMetrics.date |
| 130 | + : file.LastModified; |
| 131 | + // eslint-disable-next-line no-param-reassign |
| 132 | + delete file.LastModified; |
| 133 | + const dataBuffer = Buffer.from(buildXML(file)); |
| 134 | + filesToBuild.push({ |
| 135 | + ...getResponseHeader(request, data, |
| 136 | + dataBuffer, lastModified, log), |
| 137 | + name: file.name, |
126 | 138 | }); |
127 | | - // When `versions` is present, listing should return a versioned list |
128 | | - return respondWithData(request, response, log, data, |
129 | | - buildXMLResponse(request, filesToBuild, 'versions' in request.query)); |
130 | 139 | }); |
| 140 | + |
| 141 | + // When `versions` is present, listing should return a versioned list |
| 142 | + return await respondWithData(request, response, log, data, |
| 143 | + buildXMLResponse(request, filesToBuild, 'versions' in request.query)); |
131 | 144 | } |
132 | 145 |
|
133 | 146 | module.exports = listVeeamFiles; |
0 commit comments