Created by Katie Ross on Dec 30, 2019
This article might help you if you need to send language files for translation and get them back using the Devon service, NodeJS and Jenkins.
You need to have a service user to be used by Jenkins and the Devon's secret needs to go to Vault under your team's app area as described below:
- Request Devon's team for an authorization that consists of an UUID and a secret.
- Request DevOps for a service user and your team`s secret area in Vault. It should be something like "secrect/apps/[YOUR_TEAM]/*".
- When you have both, log into Vault and add the Devon's secret into the apps/team area. You can try "vault write secret/apps/[YOUR_TEAM]/[YOUR_SECRET_KEY] uuid=[THE_UUID] secret=[THE_SECRET]".
Devon needs the authorization in the header for its API calls:
- Get Devon's secret based on the steps shown at Accessing a Vault secret with NodeJS and Jenkins.
- With the secret you can set the "Authorization" to the header to access the API's
// This file is an example from "Accessing a Vault secret with NodeJS and Jenkins" how-to-article
var secret = require('secret.js');
secret.read().then(function done (data) {
var headers = {
Authorization: ['FD ', data.uuid, ':', data.secret].join('')
};
// Whatever comes next
}, function fail () {
// Handle failed situations
});
Calling Devon's APIs
- Check Devon's documentation for the requirements and workflow.
- Check the code below if you are using it as an example. It doesn't have examples how to get the translation file and make the call, but that should come from your knowledge in Grunt, Gulp or any other build framework.
- Make sure keys don't have trailing and leading spaces, are empty, longer than 50 characters, containing apostrophe, double or single quote and tilde.
Full implementatino for "info", "input", "build" and "output":
var http = require('http'),
_ = require('lodash'),
secret = require('secret.js');
var devonOptions = {
hostname: 'api.disney.network',
path: '/devon/default/v2',
port: 80,
headers: {
'Accept': 'application/json'
}
},
uploadDevonOptions = _.merge({
headers: {
'Content-Type': 'json',
'Content-transfer-encoding': 'BINARY'
}
}, devonOptions);
// Make calls for any types (GET, PUT, ...)
var requestDevon = function (requestOptions, body) {
return new Promise(function (resolve, reject) {
secret.read().then(function done (auth) {
var options = _.merge({}, requestOptions.method === 'PUT' ? uploadDevonOptions : devonOptions, requestOptions);
options.path = options.path + requestOptions.pathArea;
options.headers.Authorization = ['FD ', auth.uuid, ':', auth.secret].join('');
var url = [options.hostname, options.path].join(''),
req = http.request(options, (res) => {
var chunkedData = [];
res.setEncoding('utf8');
res.on('data', (chunk) => {
chunkedData.push(chunk);
});
res.on('end', () => {
resolve(JSON.parse(chunkedData.join('')));
});
});
if (body !== undefined)
req.write(body);
req.on('error', (e) => {
throw new Error(url + ' returned ' + e.message);
});
req.end();
}, reject);
});
};
module.exports = {
/**
* Gets information regarding the API, and optionally, a specific project. This endpoint could be used as a
* "ping" method if necessary.
*
* REFERENCE: https://docs.wdig.com/display/DEVON/REST+API+Specification+V2#RESTAPISpecificationV2-/info
*
* @method info
* @param {String} projectName An optional project name.
*/
info (projectName) {
var path = projectName ? ['/info', projectName].join('/') : '/info';
return requestDevon({
pathArea: path,
method: 'GET'
});
},
/**
* Builds a DEVON project.
*
* REFERENCE: https://docs.wdig.com/display/DEVON/REST+API+Specification+V2#RESTAPISpecificationV2-/build
*
* @method build
* @param {String} projectName A required project name.
*/
build (projectName) {
if (!projectName)
throw new Error('"projectName" is required.');
return requestDevon({
pathArea: ['/build', projectName].join('/'),
method: 'GET'
});
},
/**
* Upload a new or updated input file into DEVON and import the data as per the project settings.
*
* REFERENCE: https://docs.wdig.com/display/DEVON/REST+API+Specification+V2#RESTAPISpecificationV2-/input
*
* @method sendFile
* @param {String} projectName A required project name.
* @param {String} fileName A required file name.
*/
sendFile (projectName, fileName, body) {
if (!projectName)
throw new Error('"projectName" is required.');
if (!fileName)
throw new Error('"fileName" is required.');
if (!body)
throw new Error('"body" is required.');
return requestDevon({
pathArea: ['/input', projectName, fileName].join('/'),
method: 'PUT'
}, body);
},
/**
* Returns a list of existing DEVON input files for the given project.
*
* REFERENCE: https://docs.wdig.com/display/DEVON/REST+API+Specification+V2#RESTAPISpecificationV2-/output
*
* @method fetchFile
* @param {String} projectName A required project name.
* @param {String} fileName A required file name.
*/
fetchFile (projectName, fileName) {
if (!projectName)
throw new Error('"projectName" is required.');
if (!fileName)
throw new Error('"fileName" is required.');
return requestDevon({
pathArea: ['/output', projectName, fileName].join('/'),
method: 'GET'
});
},
/**
* Gets DEVON output files list for a given project.
*
* REFERENCE: https://docs.wdig.com/display/DEVON/REST+API+Specification+V2#RESTAPISpecificationV2-/output
*
* @method filesList
* @param {String} projectName A required project name.
*/
filesList (projectName) {
if (!projectName)
throw new Error('"projectName" is required.');
return requestDevon({
pathArea: ['/output', projectName].join('/'),
method: 'GET'
});
}
};
Related articles
Error rendering macro 'contentbylabel'
parameters should not be empty