Compare commits
19 Commits
developmen
...
w/8.2/bugf
Author | SHA1 | Date |
---|---|---|
Salim | 60dab39ace | |
bert-e | dc5efbafdc | |
naren-scality | de3ff7507e | |
naren-scality | 42fba9e2bb | |
naren-scality | 14d3bc8b2d | |
naren-scality | f2b5eb3ec7 | |
bert-e | 1f201b8b3a | |
bert-e | bd8f92ee6f | |
Salim | 6322e527af | |
bert-e | 9c0ef12b10 | |
vrancurel | 2aab4be5d4 | |
bert-e | f04608a0ce | |
bert-e | 19415e36d5 | |
bert-e | 589a465c57 | |
bert-e | 957631cea0 | |
bert-e | 0faa470247 | |
bert-e | aa874cf6fd | |
bert-e | 3ab5d23dab | |
Salim | 6ea92cf9ce |
|
@ -39,6 +39,10 @@
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 8900
|
"port": 8900
|
||||||
},
|
},
|
||||||
|
"workflowEngineOperator": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 3001
|
||||||
|
},
|
||||||
"cdmi": {
|
"cdmi": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 81,
|
"port": 81,
|
||||||
|
|
|
@ -147,6 +147,14 @@ if [[ "$CRR_METRICS_PORT" ]]; then
|
||||||
JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .backbeat.port=$CRR_METRICS_PORT"
|
JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .backbeat.port=$CRR_METRICS_PORT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$WE_OPERATOR_HOST" ]]; then
|
||||||
|
JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .workflowEngineOperator.host=\"$WE_OPERATOR_HOST\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$WE_OPERATOR_PORT" ]]; then
|
||||||
|
JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .workflowEngineOperator.port=$WE_OPERATOR_PORT"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ "$HEALTHCHECKS_ALLOWFROM" ]]; then
|
if [[ "$HEALTHCHECKS_ALLOWFROM" ]]; then
|
||||||
JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .healthChecks.allowFrom=[\"$HEALTHCHECKS_ALLOWFROM\"]"
|
JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .healthChecks.allowFrom=[\"$HEALTHCHECKS_ALLOWFROM\"]"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -586,6 +586,16 @@ class Config extends EventEmitter {
|
||||||
this.backbeat = backbeat;
|
this.backbeat = backbeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.workflowEngineOperator) {
|
||||||
|
const { workflowEngineOperator } = config;
|
||||||
|
assert.strictEqual(typeof workflowEngineOperator.host, 'string',
|
||||||
|
'bad config: workflowEngineOperator host must be a string');
|
||||||
|
assert(Number.isInteger(workflowEngineOperator.port) &&
|
||||||
|
workflowEngineOperator.port > 0,
|
||||||
|
'bad config: workflowEngineOperator port not a positive integer');
|
||||||
|
this.workflowEngineOperator = workflowEngineOperator;
|
||||||
|
}
|
||||||
|
|
||||||
// legacy
|
// legacy
|
||||||
if (config.regions !== undefined) {
|
if (config.regions !== undefined) {
|
||||||
throw new Error('bad config: regions key is deprecated. ' +
|
throw new Error('bad config: regions key is deprecated. ' +
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
const url = require('url');
|
||||||
|
const httpProxy = require('http-proxy');
|
||||||
|
|
||||||
|
const workflowEngineOperatorProxy = httpProxy.createProxyServer({
|
||||||
|
ignorePath: true,
|
||||||
|
});
|
||||||
|
const { auth, errors, s3routes } =
|
||||||
|
require('arsenal');
|
||||||
|
const { responseJSONBody } = s3routes.routesUtils;
|
||||||
|
const vault = require('../auth/vault');
|
||||||
|
const prepareRequestContexts = require(
|
||||||
|
'../api/apiUtils/authorization/prepareRequestContexts');
|
||||||
|
const { config } = require('../Config');
|
||||||
|
const constants = require('../../constants');
|
||||||
|
|
||||||
|
auth.setHandler(vault);
|
||||||
|
|
||||||
|
function _decodeURI(uri) {
|
||||||
|
// do the same decoding than in S3 server
|
||||||
|
return decodeURIComponent(uri.replace(/\+/g, ' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
function _normalizeRequest(req) {
|
||||||
|
/* eslint-disable no-param-reassign */
|
||||||
|
const parsedUrl = url.parse(req.url, true);
|
||||||
|
req.path = _decodeURI(parsedUrl.pathname);
|
||||||
|
const pathArr = req.path.split('/');
|
||||||
|
req.query = parsedUrl.query;
|
||||||
|
req.resourceType = pathArr[3];
|
||||||
|
req.bucketName = pathArr[4];
|
||||||
|
req.objectKey = pathArr.slice(5).join('/');
|
||||||
|
/* eslint-enable no-param-reassign */
|
||||||
|
}
|
||||||
|
|
||||||
|
function routeWorkflowEngineOperator(clientIP, request, response, log) {
|
||||||
|
log.debug('routing request', {
|
||||||
|
method: 'routeWorkflowEngineOperator',
|
||||||
|
url: request.url,
|
||||||
|
});
|
||||||
|
_normalizeRequest(request);
|
||||||
|
const requestContexts = prepareRequestContexts('objectReplicate', request);
|
||||||
|
|
||||||
|
// proxy api requests to Workflow Engine Operator API server
|
||||||
|
if (request.resourceType === 'api') {
|
||||||
|
if (!config.workflowEngineOperator) {
|
||||||
|
log.debug('unable to proxy workflow engine operator request', {
|
||||||
|
workflowEngineConfig: config.workflowEngineOperator,
|
||||||
|
});
|
||||||
|
return responseJSONBody(errors.MethodNotAllowed, null, response,
|
||||||
|
log);
|
||||||
|
}
|
||||||
|
const path = request.url.replace('/_/workflow-engine-operator/api', '/_/');
|
||||||
|
const { host, port } = config.workflowEngineOperator;
|
||||||
|
const target = `http://${host}:${port}${path}`;
|
||||||
|
return auth.server.doAuth(request, log, (err, userInfo) => {
|
||||||
|
if (err) {
|
||||||
|
log.debug('authentication error', {
|
||||||
|
error: err,
|
||||||
|
method: request.method,
|
||||||
|
bucketName: request.bucketName,
|
||||||
|
objectKey: request.objectKey,
|
||||||
|
});
|
||||||
|
return responseJSONBody(err, null, response, log);
|
||||||
|
}
|
||||||
|
// FIXME for now, any authenticated user can access API
|
||||||
|
// routes. We should introduce admin accounts or accounts
|
||||||
|
// with admin privileges, and restrict access to those
|
||||||
|
// only.
|
||||||
|
if (userInfo.getCanonicalID() === constants.publicId) {
|
||||||
|
log.debug('unauthenticated access to API routes', {
|
||||||
|
method: request.method,
|
||||||
|
bucketName: request.bucketName,
|
||||||
|
objectKey: request.objectKey,
|
||||||
|
});
|
||||||
|
return responseJSONBody(
|
||||||
|
errors.AccessDenied, null, response, log);
|
||||||
|
}
|
||||||
|
return workflowEngineOperatorProxy.web(
|
||||||
|
request, response, { target }, err => {
|
||||||
|
log.error('error proxying request to api server',
|
||||||
|
{ error: err.message });
|
||||||
|
return responseJSONBody(errors.ServiceUnavailable, null,
|
||||||
|
response, log);
|
||||||
|
});
|
||||||
|
}, 's3', requestContexts);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = routeWorkflowEngineOperator;
|
|
@ -1,6 +1,8 @@
|
||||||
const { healthcheckHandler } = require('./healthcheckHandler');
|
const { healthcheckHandler } = require('./healthcheckHandler');
|
||||||
const routeBackbeat = require('../routes/routeBackbeat');
|
const routeBackbeat = require('../routes/routeBackbeat');
|
||||||
const routeMetadata = require('../routes/routeMetadata');
|
const routeMetadata = require('../routes/routeMetadata');
|
||||||
|
const routeWorkflowEngineOperator =
|
||||||
|
require('../routes/routeWorkflowEngineOperator');
|
||||||
const { reportHandler } = require('./reportHandler');
|
const { reportHandler } = require('./reportHandler');
|
||||||
const { monitoringHandler } = require('./monitoringHandler');
|
const { monitoringHandler } = require('./monitoringHandler');
|
||||||
|
|
||||||
|
@ -10,6 +12,7 @@ const internalHandlers = {
|
||||||
report: reportHandler,
|
report: reportHandler,
|
||||||
monitoring: monitoringHandler,
|
monitoring: monitoringHandler,
|
||||||
metadata: routeMetadata,
|
metadata: routeMetadata,
|
||||||
|
'workflow-engine-operator': routeWorkflowEngineOperator,
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -46,6 +46,8 @@ function getCapabilities() {
|
||||||
secureChannelOptimizedPath: hasWSOptionalDependencies(),
|
secureChannelOptimizedPath: hasWSOptionalDependencies(),
|
||||||
s3cIngestLocation: true,
|
s3cIngestLocation: true,
|
||||||
nfsIngestLocation: true,
|
nfsIngestLocation: true,
|
||||||
|
cephIngestLocation: true,
|
||||||
|
awsIngestLocation: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/scality/S3#readme",
|
"homepage": "https://github.com/scality/S3#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"arsenal": "github:scality/Arsenal#2bb0e17",
|
"arsenal": "github:scality/Arsenal#635d2fe",
|
||||||
"async": "~2.5.0",
|
"async": "~2.5.0",
|
||||||
"aws-sdk": "2.28.0",
|
"aws-sdk": "2.28.0",
|
||||||
"azure-storage": "^2.1.0",
|
"azure-storage": "^2.1.0",
|
||||||
|
|
|
@ -231,9 +231,9 @@ arraybuffer.slice@~0.0.7:
|
||||||
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
|
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
|
||||||
integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
|
integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
|
||||||
|
|
||||||
"arsenal@github:scality/Arsenal#2bb0e17":
|
"arsenal@github:scality/Arsenal#635d2fe":
|
||||||
version "8.1.4"
|
version "8.1.4"
|
||||||
resolved "https://codeload.github.com/scality/Arsenal/tar.gz/2bb0e171d8bada09e40491680b82ab33a882e7eb"
|
resolved "https://codeload.github.com/scality/Arsenal/tar.gz/635d2fe6d9421e2a59c4fa213594ef2785b17709"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@hapi/joi" "^15.1.0"
|
"@hapi/joi" "^15.1.0"
|
||||||
JSONStream "^1.0.0"
|
JSONStream "^1.0.0"
|
||||||
|
|
Loading…
Reference in New Issue