Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 47 additions & 57 deletions lib/management/poll.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,65 @@
const _config = require('../Config').config;
const logger = require('../utilities/logger');
const metadata = require('../metadata/wrapper');
const {
loadCachedOverlay,
patchConfiguration,
saveConfigurationVersion,
} = require('./configuration');
const { loadCachedOverlay, patchConfiguration, saveConfigurationVersion } = require('./configuration');
const { reshapeExceptionError } = arsenal.errorUtils;

const pushReportDelay = 30000;
const pullConfigurationOverlayDelay = 60000;

function loadRemoteOverlay(
managementEndpoint, instanceId, remoteToken, cachedOverlay, log, cb) {
function loadRemoteOverlay(managementEndpoint, instanceId, remoteToken, cachedOverlay, log, cb) {
log.debug('loading remote overlay');
const opts = {
headers: {
'x-instance-authentication-token': remoteToken,
'x-scal-request-id': log.getSerializedUids(),
'x-scal-request-uids': log.getSerializedUids(),
},
json: true,
};
request.get(`${managementEndpoint}/${instanceId}/config/overlay`, opts,
(error, response, body) => {
if (error) {
return cb(error);
}
if (response.statusCode === 200) {
return cb(null, cachedOverlay, body);
}
if (response.statusCode === 404) {
return cb(null, cachedOverlay, {});
}
return cb(arsenal.errors.AccessForbidden, cachedOverlay, {});
});
}

// TODO save only after successful patch
function applyConfigurationOverlay(
managementEndpoint, instanceId, remoteToken, log) {
async.waterfall([
wcb => loadCachedOverlay(log, wcb),
(cachedOverlay, wcb) => patchConfiguration(cachedOverlay,
log, wcb),
(cachedOverlay, wcb) =>
loadRemoteOverlay(managementEndpoint, instanceId, remoteToken,
cachedOverlay, log, wcb),
(cachedOverlay, remoteOverlay, wcb) =>
saveConfigurationVersion(cachedOverlay, remoteOverlay, log, wcb),
(remoteOverlay, wcb) => patchConfiguration(remoteOverlay,
log, wcb),
], error => {
request.get(`${managementEndpoint}/${instanceId}/config/overlay`, opts, (error, response, body) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the poll hits GET /instance/{uuid}/config/overlay on pensieve-api, and AFAIK that specific endpoint does not declare X-Scal-Request-Uids in its swagger parameters while most other pensieve endpoints do. upon checking I found https://scality.atlassian.net/browse/PSVAPI-131 might be useful to put it in the summary to avoid confusion

if (error) {
log.error('could not apply managed configuration',
{ error: reshapeExceptionError(error),
method: 'applyConfigurationOverlay' });
return cb(error);
}
if (response.statusCode === 200) {
return cb(null, cachedOverlay, body);
}
setTimeout(applyConfigurationOverlay, pullConfigurationOverlayDelay,
managementEndpoint, instanceId, remoteToken,
logger.newRequestLogger());
if (response.statusCode === 404) {
return cb(null, cachedOverlay, {});
}
return cb(arsenal.errors.AccessForbidden, cachedOverlay, {});
});
}

Check notice

Code scanning / CodeQL

Callback-style function (async migration) Note

This function uses a callback parameter ('cb'). Refactor to async/await.

// TODO save only after successful patch
function applyConfigurationOverlay(managementEndpoint, instanceId, remoteToken, log) {
async.waterfall(
[
wcb => loadCachedOverlay(log, wcb),
(cachedOverlay, wcb) => patchConfiguration(cachedOverlay, log, wcb),
(cachedOverlay, wcb) =>
loadRemoteOverlay(managementEndpoint, instanceId, remoteToken, cachedOverlay, log, wcb),
(cachedOverlay, remoteOverlay, wcb) => saveConfigurationVersion(cachedOverlay, remoteOverlay, log, wcb),
(remoteOverlay, wcb) => patchConfiguration(remoteOverlay, log, wcb),
],
error => {
if (error) {
log.error('could not apply managed configuration', {
error: reshapeExceptionError(error),
method: 'applyConfigurationOverlay',
});
}
setTimeout(
applyConfigurationOverlay,
pullConfigurationOverlayDelay,
managementEndpoint,
instanceId,
remoteToken,
logger.newRequestLogger(),
);
},
);
}

function postStats(managementEndpoint, instanceId, remoteToken, report, next) {
const toURL = `${managementEndpoint}/${instanceId}/stats`;
const toOptions = {
Expand Down Expand Up @@ -115,18 +113,11 @@
}

logger.debug('report', { report });
postStats(
managementEndpoint,
instanceId,
remoteToken,
report,
next
);
postStats(managementEndpoint, instanceId, remoteToken, report, next);
return;
});

setTimeout(pushStats, pushReportDelay,
managementEndpoint, instanceId, remoteToken);
setTimeout(pushStats, pushReportDelay, managementEndpoint, instanceId, remoteToken);
}

/**
Expand All @@ -141,17 +132,16 @@
*
* @returns {undefined}
*/
function startPollingManagementClient(
managementEndpoint, instanceId, remoteToken) {
function startPollingManagementClient(managementEndpoint, instanceId, remoteToken) {
metadata.notifyBucketChange(() => {
pushStats(managementEndpoint, instanceId, remoteToken);
});

pushStats(managementEndpoint, instanceId, remoteToken);
applyConfigurationOverlay(managementEndpoint, instanceId, remoteToken,
logger.newRequestLogger());
applyConfigurationOverlay(managementEndpoint, instanceId, remoteToken, logger.newRequestLogger());
}

module.exports = {
startPollingManagementClient,
loadRemoteOverlay,
};
30 changes: 30 additions & 0 deletions tests/unit/management/poll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const assert = require('assert');
const sinon = require('sinon');

const request = require('../../../lib/utilities/request');
const { loadRemoteOverlay } = require('../../../lib/management/poll');
const { DummyRequestLogger } = require('../helpers');

describe('management poll loadRemoteOverlay', () => {
const managementEndpoint = 'https://management.example.com';
const instanceId = 'instance-id';
const remoteToken = 'remote-token';
const log = new DummyRequestLogger();

afterEach(() => {
sinon.restore();
});

it('should forward the werelogs request uids under the ' + 'x-scal-request-uids header', done => {
const getStub = sinon.stub(request, 'get').callsFake((url, opts, cb) => cb(null, { statusCode: 200 }, {}));

loadRemoteOverlay(managementEndpoint, instanceId, remoteToken, {}, log, err => {
assert.ifError(err);
assert(getStub.calledOnce);
const opts = getStub.firstCall.args[1];
assert.strictEqual(opts.headers['x-scal-request-uids'], log.getSerializedUids());
assert.strictEqual(opts.headers['x-scal-request-id'], undefined);
done();
});
});
});
Loading