diff --git a/.travis.yml b/.travis.yml
index 9799fe7e8..7621a18e1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,16 +37,16 @@ jobs:
script:
- sshpass -p $PROD_MACHINE_PASSWORD ssh -o StrictHostKeyChecking=no $PROD_MACHINE_USERNAME@$PROD_MACHINE_IP "cd /Controller; NODE_ENV=production node src/main.js stop; git pull; npm i; NODE_ENV=production node src/main.js start"
- stage: release
- before_install:
- - git clone "https://github.com/$TRAVIS_REPO_SLUG.git" "$TRAVIS_REPO_SLUG";
- - cd "$TRAVIS_REPO_SLUG";
- - git checkout -qf "$TRAVIS_COMMIT";
- - git checkout master
- before_deploy:
- - git config --global user.name "${GH_USERNAME}";
- - git config credential.helper "store --file=.git/credentials";
- - echo "https://${GH_TOKEN}:@github.com" > .git/credentials;
- - npm run automatic-release
+ #before_install:
+ #- git clone "https://github.com/$TRAVIS_REPO_SLUG.git" "$TRAVIS_REPO_SLUG";
+ #- cd "$TRAVIS_REPO_SLUG";
+ #- git checkout -qf "$TRAVIS_COMMIT";
+ #- git checkout master
+ #before_deploy:
+ #- git config --global user.name "${GH_USERNAME}";
+ #- git config credential.helper "store --file=.git/credentials";
+ #- echo "https://${GH_TOKEN}:@github.com" > .git/credentials;
+ #- npm run automatic-release
deploy:
skip_cleanup: true
provider: npm
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9155fd6a5..1117207fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,13 +4,7 @@ Also see the **[release page](https://github.com/ioFog/Controller/releases)**.
-## [1.0.31](https://github.com/ioFog/Controller/releases/tag/1.0.31) (2018-12-14)
-
-
-
-
-## [1.1.0](https://github.com/ioFog/Controller/releases/tag/1.1.0) (2018-12-14)
-
+## [1.0.28](https://github.com/ioFog/Controller/releases/tag/1.0.28) (2018-12-14)
diff --git a/scripts/postinstall.js b/scripts/postinstall.js
index a5bf6e22e..263e111d1 100644
--- a/scripts/postinstall.js
+++ b/scripts/postinstall.js
@@ -17,57 +17,49 @@ const fs = require('fs');
const semver = require('semver');
const currentVersion = require('../package').version;
-const rootDir = `${__dirname}/../`;
+const rootDir = `${__dirname}/..`;
let installationVariablesFileName = 'iofogcontroller_install_variables';
-let installationVariablesFile;
-let tempDir;
-
-if (os.type() === 'Linux') {
- tempDir = '/tmp/';
-} else if (os.type() === 'Darwin') {
- tempDir = '/tmp/';
-} else if (os.type() === 'Windows_NT') {
- tempDir = `${process.env.APPDATA}/`;
-} else {
- throw new Error("Unsupported OS found: " + os.type());
-}
-
-installationVariablesFile = tempDir + installationVariablesFileName;
+let tempDir = getTempDirLocation();
+const installationVariablesFile = tempDir + '/' + installationVariablesFileName;
-const devDbBackup = `${tempDir}dev_database.sqlite`;
+//restore all files
+const devDbBackup = `${tempDir}/dev_database.sqlite`;
const devDb = `${rootDir}/src/sequelize/dev_database.sqlite`;
-if (fs.existsSync(devDbBackup)) {
- fs.renameSync(devDbBackup, devDb);
-}
+moveFileIfExists(devDbBackup, devDb);
-const prodDbBackup = `${tempDir}prod_database.sqlite`;
+const prodDbBackup = `${tempDir}/prod_database.sqlite`;
const prodDb = `${rootDir}/src/sequelize/prod_database.sqlite`;
-if (fs.existsSync(prodDbBackup)) {
- fs.renameSync(prodDbBackup, prodDb);
-}
+moveFileIfExists(prodDbBackup, prodDb);
+
+const defConfigBackup = `${tempDir}/default_iofog_backup.json`;
+const defConfig = `${rootDir}/src/config/default.json`;
+moveFileIfExists(defConfigBackup, defConfig);
+const prodConfigBackup = `${tempDir}/production_iofog_backup.json`;
+const prodConfig = `${rootDir}/src/config/production.json`;
+moveFileIfExists(prodConfigBackup, prodConfig);
+
+const devConfigBackup = `${tempDir}/development_iofog_backup.json`;
+const devConfig = `${rootDir}/src/config/development.json`;
+moveFileIfExists(devConfigBackup, devConfig);
+
+//process migrations
try {
- const instalationVarsStr = fs.readFileSync(installationVariablesFile);
- const instalationVars = JSON.parse(instalationVarsStr);
- const prevVersion = instalationVars.prevVer;
+ const installationVarsStr = fs.readFileSync(installationVariablesFile);
+ const installationVars = JSON.parse(installationVarsStr);
+ const prevVersion = installationVars.prevVer;
console.log(`previous version - ${prevVersion}`);
console.log(`new version - ${currentVersion}`);
if (semver.satisfies(prevVersion, '<=1.0.0')) {
- console.log('upgrading from version <=1.0.0 :');
- console.log(' inserting seeds meta info in db');
- const options = {
- env: {
- "PATH": process.env.PATH
- },
- stdio: [process.stdin, process.stdout, process.stderr]
- };
-
- execSync(`sqlite3 ${prodDb} "insert into SequelizeMeta (name) values ('20180928110125-insert-registry.js');"`, options);
- execSync(`sqlite3 ${prodDb} "insert into SequelizeMeta (name) values ('20180928111532-insert-catalog-item.js');"`, options);
- execSync(`sqlite3 ${prodDb} "insert into SequelizeMeta (name) values ('20180928112152-insert-iofog-type.js');"`, options);
- execSync(`sqlite3 ${prodDb} "insert into SequelizeMeta (name) values ('20180928121334-insert-catalog-item-image.js');"`, options);
+ console.log('upgrading from version <= 1.0.0 :');
+ insertSeeds();
+ }
+
+ if (semver.satisfies(prevVersion, '<=1.0.30')) {
+ console.log('upgrading from version <= 1.0.30 :');
+ updateEncryptionMethod();
}
fs.unlinkSync(installationVariablesFile);
@@ -84,4 +76,122 @@ const options = {
stdio: [process.stdin, process.stdout, process.stderr]
};
-execSync('node ./src/main.js init', options);
\ No newline at end of file
+execSync('node ./src/main.js init', options);
+
+//other functions definitions
+
+function getTempDirLocation() {
+ let tempDir;
+ if (os.type() === 'Linux') {
+ tempDir = '/tmp';
+ } else if (os.type() === 'Darwin') {
+ tempDir = '/tmp';
+ } else if (os.type() === 'Windows_NT') {
+ tempDir = `${process.env.APPDATA}`;
+ } else {
+ throw new Error("Unsupported OS found: " + os.type());
+ }
+ return tempDir;
+}
+
+function moveFileIfExists(from, to) {
+ if (fs.existsSync(from)) {
+ fs.renameSync(from, to);
+ }
+}
+
+function insertSeeds() {
+ console.log(' inserting seeds meta info in db');
+ const options = {
+ env: {
+ "PATH": process.env.PATH
+ },
+ stdio: [process.stdin, process.stdout, process.stderr]
+ };
+
+ execSync(`sqlite3 ${prodDb} "insert into SequelizeMeta (name) values ('20180928110125-insert-registry.js');"`, options);
+ execSync(`sqlite3 ${prodDb} "insert into SequelizeMeta (name) values ('20180928111532-insert-catalog-item.js');"`, options);
+ execSync(`sqlite3 ${prodDb} "insert into SequelizeMeta (name) values ('20180928112152-insert-iofog-type.js');"`, options);
+ execSync(`sqlite3 ${prodDb} "insert into SequelizeMeta (name) values ('20180928121334-insert-catalog-item-image.js');"`, options);
+}
+
+function updateEncryptionMethodForUsersPassword(decryptionFunc) {
+ const options = {
+ env: {
+ "PATH": process.env.PATH
+ }
+ };
+
+ const usersOutput = execSync(`sqlite3 ${prodDb} "select id, email, password from Users;"`, options).toString();
+ const usersLines = usersOutput.match(/[^\r\n]+/g);
+ for (let line of usersLines) {
+ let id, email, oldEncryptedPassword;
+ try {
+ const vals = line.split('|');
+ id = vals[0];
+ email = vals[1];
+ oldEncryptedPassword = vals[2];
+
+ const decryptedPassword = decryptionFunc(oldEncryptedPassword, email);
+
+ const AppHelper = require('../src/helpers/app-helper');
+ const newEncryptedPassword = AppHelper.encryptText(decryptedPassword, email);
+
+ const options = {
+ env: {
+ "PATH": process.env.PATH
+ },
+ stdio: [process.stdin, process.stdout, process.stderr]
+ };
+ execSync(`sqlite3 ${prodDb} "update Users set password='${newEncryptedPassword}' where id=${id};"`, options);
+ } catch (e) {
+ console.log('db problem');
+ }
+ }
+}
+
+function updateEncryptionMethodForEmailService(configFile, decryptionFunc) {
+ console.log(configFile);
+ if (!configFile) {
+ return
+ }
+ const configObj = JSON.parse(fs.readFileSync(configFile, 'utf8'));
+ console.log(configObj);
+ if (!configObj || !configObj.Email || !configObj.Email.Address || !configObj.Email.Password) {
+ return
+ }
+
+ const email = configObj.Email.Address;
+ const oldEncryptedPassword = configObj.Email.Password;
+
+ const decryptedPassword = decryptionFunc(oldEncryptedPassword, email);
+
+ const AppHelper = require('../src/helpers/app-helper');
+ configObj.Email.Password = AppHelper.encryptText(decryptedPassword, email);
+
+ console.log(configObj);
+ try {
+ fs.writeFileSync(configFile, JSON.stringify(configObj, null, 2));
+ } catch (e) {
+ console.log(e)
+ }
+}
+
+function updateEncryptionMethod() {
+ console.log(' updating encryption method for old users');
+
+ function decryptTextVer30(text, salt) {
+ const crypto = require('crypto');
+ const ALGORITHM = 'aes-256-ctr';
+
+ const decipher = crypto.createDecipher(ALGORITHM, salt);
+ let dec = decipher.update(text, 'hex', 'utf8');
+ dec += decipher.final('utf8');
+ return dec
+ }
+
+ updateEncryptionMethodForUsersPassword(decryptTextVer30);
+ updateEncryptionMethodForEmailService(defConfig, decryptTextVer30);
+ updateEncryptionMethodForEmailService(devConfig, decryptTextVer30);
+ updateEncryptionMethodForEmailService(prodConfig, decryptTextVer30);
+}
\ No newline at end of file
diff --git a/scripts/preuninstall.js b/scripts/preuninstall.js
index da1fbcea5..1c8ed5106 100644
--- a/scripts/preuninstall.js
+++ b/scripts/preuninstall.js
@@ -16,22 +16,22 @@ const execSync = require('child_process').execSync;
const fs = require('fs');
const version = require('../package').version;
-const rootDir = `${__dirname}/../`;
+const rootDir = `${__dirname}/..`;
let installationVariablesFileName = 'iofogcontroller_install_variables';
let installationVariablesFile;
let tempDir;
if (os.type() === 'Linux') {
- tempDir = '/tmp/';
+ tempDir = '/tmp';
} else if (os.type() === 'Darwin') {
- tempDir = '/tmp/';
+ tempDir = '/tmp';
} else if (os.type() === 'Windows_NT') {
- tempDir = `${process.env.APPDATA}/`;
+ tempDir = `${process.env.APPDATA}`;
} else {
throw new Error("Unsupported OS found: " + os.type());
}
-installationVariablesFile = tempDir + installationVariablesFileName;
+installationVariablesFile = tempDir + '/' + installationVariablesFileName;
const instalationVars = {
prevVer: version
@@ -41,11 +41,26 @@ fs.writeFileSync(installationVariablesFile, JSON.stringify(instalationVars));
const devDb = `${rootDir}/src/sequelize/dev_database.sqlite`;
if (fs.existsSync(devDb)) {
- fs.renameSync(devDb, `${tempDir}dev_database.sqlite`)
+ fs.renameSync(devDb, `${tempDir}/dev_database.sqlite`)
}
const prodDb = `${rootDir}/src/sequelize/prod_database.sqlite`;
if (fs.existsSync(prodDb)) {
- fs.renameSync(prodDb, `${tempDir}prod_database.sqlite`)
+ fs.renameSync(prodDb, `${tempDir}/prod_database.sqlite`)
+}
+
+const defConfig = `${rootDir}/src/config/default.json`;
+if (fs.existsSync(defConfig)) {
+ fs.renameSync(defConfig, `${tempDir}/default_iofog_backup.json`)
+}
+
+const devConfig = `${rootDir}/src/config/development.json`;
+if (fs.existsSync(devConfig)) {
+ fs.renameSync(devConfig, `${tempDir}/development_iofog_backup.json`)
+}
+
+const prodConfig = `${rootDir}/src/config/production.json`;
+if (fs.existsSync(prodConfig)) {
+ fs.renameSync(prodConfig, `${tempDir}/production_iofog_backup.json`)
}
diff --git a/src/cli/diagnostics.js b/src/cli/diagnostics.js
index dd5e096d0..1a0445f3d 100644
--- a/src/cli/diagnostics.js
+++ b/src/cli/diagnostics.js
@@ -131,7 +131,6 @@ const _changeMicroserviceStraceState = async function (obj) {
const isEnable = AppHelper.validateBooleanCliOptions(obj.enable, obj.disable);
await DiagnosticService.changeMicroserviceStraceState(obj.microserviceUuid, {enable: isEnable}, {}, true);
const msg = isEnable ? 'Microservice strace has been enabled' : 'Microservice strace has been disabled';
-
logger.info(msg);
};
@@ -139,7 +138,9 @@ const _getMicroserviceStraceData = async function (obj) {
logger.info(JSON.stringify(obj));
const result = await DiagnosticService.getMicroserviceStraceData(obj.microserviceUuid, {format: obj.format}, {}, true);
- logger.info(JSON.stringify(result, null, 2));
+ logger.info('Strace data:');
+ logger.info('=============================');
+ logger.info(result.data);
logger.info('Microservice strace data has been retrieved successfully.');
};
diff --git a/src/cli/user.js b/src/cli/user.js
index 71f3f6d70..bf61143e3 100644
--- a/src/cli/user.js
+++ b/src/cli/user.js
@@ -51,6 +51,11 @@ class User extends BaseCLIHandler {
name: 'password', alias: 'p', type: String,
description: 'User\'s password',
group: [constants.CMD_ADD, constants.CMD_UPDATE],
+ },
+ {
+ name: 'force', alias: 'F', type: Boolean,
+ description: 'User\'s force delete',
+ group: [constants.CMD_REMOVE],
}
];
this.commands = {
@@ -136,10 +141,10 @@ const _updateUserDetails = async function (userDetails, user) {
logger.info('User updated successfully.');
};
-const _deleteUser = async function (emailObj, user) {
- logger.info(JSON.stringify(emailObj));
+const _deleteUser = async function (obj, user) {
+ logger.info(JSON.stringify(obj));
- await UserService.deleteUser(user, true);
+ await UserService.deleteUser(obj.force, user, true);
logger.info('User removed successfully.');
};
diff --git a/src/controllers/user-controller.js b/src/controllers/user-controller.js
index 43badf767..c86fa65ab 100644
--- a/src/controllers/user-controller.js
+++ b/src/controllers/user-controller.js
@@ -42,14 +42,11 @@ const userLoginEndPoint = async function (req) {
await Validator.validate(user, Validator.schemas.login);
- const encryptedPassword = AppHelper.encryptText(user.password, user.email);
const credentials = {
email: user.email,
- password: encryptedPassword
+ password: user.password
};
- logger.info("Parameters:" + JSON.stringify(credentials));
-
return await UserService.login(credentials, false);
};
@@ -88,7 +85,7 @@ const updateUserProfileEndPoint = async function (req, user) {
};
const deleteUserProfileEndPoint = async function (req, user) {
- return await UserService.deleteUser(user, false);
+ return await UserService.deleteUser(req.body.force, user, false);
};
const updateUserPasswordEndPoint = async function (req, user) {
@@ -96,17 +93,7 @@ const updateUserPasswordEndPoint = async function (req, user) {
await Validator.validate(passwordUpdates, Validator.schemas.updatePassword);
- const encryptedOldPassword = AppHelper.encryptText(passwordUpdates.oldPassword, user.email);
- const encryptedNewPassword = AppHelper.encryptText(passwordUpdates.newPassword, user.email);
-
- const encryptedPasswordUpdates = {
- oldPassword: encryptedOldPassword,
- newPassword: encryptedNewPassword
- };
-
- logger.info("Parameters:" + JSON.stringify(encryptedPasswordUpdates));
-
- return await UserService.updateUserPassword(encryptedPasswordUpdates, user, false);
+ return await UserService.updateUserPassword(passwordUpdates, user, false);
};
const resetUserPasswordEndPoint = async function (req) {
diff --git a/src/helpers/app-helper.js b/src/helpers/app-helper.js
index ff7056322..5f9d2cde7 100644
--- a/src/helpers/app-helper.js
+++ b/src/helpers/app-helper.js
@@ -21,19 +21,30 @@ const portscanner = require('portscanner');
const format = require('string-format');
const ALGORITHM = 'aes-256-ctr';
+const IV_LENGTH = 16;
+
const Transaction = require('sequelize/lib/transaction');
function encryptText(text, salt) {
- const cipher = crypto.createCipher(ALGORITHM, salt);
+ const iv = crypto.randomBytes(IV_LENGTH);
+ const processedSalt = crypto.createHash('md5').update(salt).digest("hex");
+
+ const cipher = crypto.createCipheriv(ALGORITHM, processedSalt, iv);
let crypted = cipher.update(text, 'utf8', 'hex');
crypted += cipher.final('hex');
- return crypted
+ return iv.toString('hex') + ':' + crypted.toString('hex');
}
function decryptText(text, salt) {
- const decipher = crypto.createDecipher(ALGORITHM, salt);
- let dec = decipher.update(text, 'hex', 'utf8');
+ const processedSalt = crypto.createHash('md5').update(salt).digest("hex");
+
+ const textParts = text.split(':');
+ const iv = new Buffer(textParts.shift(), 'hex');
+ let encryptedText = new Buffer(textParts.join(':'), 'hex');
+
+ const decipher = crypto.createDecipheriv(ALGORITHM, processedSalt, iv);
+ let dec = decipher.update(encryptedText, 'hex', 'utf8');
dec += decipher.final('utf8');
return dec
}
diff --git a/src/helpers/error-messages.js b/src/helpers/error-messages.js
index 6ab703477..0625d2952 100644
--- a/src/helpers/error-messages.js
+++ b/src/helpers/error-messages.js
@@ -27,6 +27,7 @@ module.exports = {
INVALID_VOLUME_MAPPING_UUID: "Invalid volume mapping id '{}'",
ACTIVATION_CODE_NOT_FOUND: 'Activation code not found',
INVALID_OLD_PASSWORD: 'Old password is incorrect',
+ NEEDED_FORCE_DELETE_USER: "There are running iofog-agents, stop them before removal or pass 'force' parameter",
ACCOUNT_NOT_FOUND: 'Account not found',
USER_NOT_UPDATED: 'User not updated',
EMAIL_NOT_ACTIVATED: 'Email is not activated. Please activate your account first.',
diff --git a/src/routes/agent.js b/src/routes/agent.js
index f2610e1e1..2ab7f255d 100644
--- a/src/routes/agent.js
+++ b/src/routes/agent.js
@@ -278,7 +278,7 @@ module.exports = [
method: 'put',
path: '/api/v3/agent/strace',
middleware: async (req, res) => {
- const successCode = constants.HTTP_CODE_SUCCESS;
+ const successCode = constants.HTTP_CODE_NO_CONTENT;
const errorCodes = [
{
code: constants.HTTP_CODE_NOT_FOUND,
diff --git a/src/schemas/agent.js b/src/schemas/agent.js
index 5dd990aa4..e1bfbb44a 100644
--- a/src/schemas/agent.js
+++ b/src/schemas/agent.js
@@ -46,15 +46,6 @@ const updateAgentConfig = {
"additionalProperties": false
};
-const agentConfigChanges = {
- "id": "/agentConfigChanges",
- "type": "object",
- "properties": {
- "timestamp": {"type": "integer"}
- },
- "additionalProperties": false
-};
-
const updateAgentStatus = {
"id": "/updateAgentStatus",
"type": "object",
@@ -148,7 +139,7 @@ const updateUsbInfo = {
};
module.exports = {
- mainSchemas: [agentProvision, updateAgentConfig, agentConfigChanges, updateAgentStatus, updateAgentStrace,
+ mainSchemas: [agentProvision, updateAgentConfig, updateAgentStatus, updateAgentStrace,
updateHardwareInfo, updateUsbInfo],
innerSchemas: [straceData, microserviceStatus]
};
\ No newline at end of file
diff --git a/src/schemas/index.js b/src/schemas/index.js
index 158302d73..7f524724b 100644
--- a/src/schemas/index.js
+++ b/src/schemas/index.js
@@ -19,8 +19,6 @@ const basename = path.basename(__filename);
const Errors = require('../helpers/errors');
-const Logger = require('../logger');
-
const v = new Validator();
const schemas = {};
diff --git a/src/sequelize/managers/iofog-manager.js b/src/sequelize/managers/iofog-manager.js
index 4289ef7b5..0ac555f4e 100644
--- a/src/sequelize/managers/iofog-manager.js
+++ b/src/sequelize/managers/iofog-manager.js
@@ -54,11 +54,11 @@ class FogManager extends BaseManager {
{
model: Microservice,
as: 'microservice',
- required: false,
+ required: true,
include: [{
model: Strace,
as: 'strace',
- required: false
+ required: true
}]
}],
where: where
diff --git a/src/sequelize/managers/microservice-manager.js b/src/sequelize/managers/microservice-manager.js
index 2e6729cae..ca103f664 100644
--- a/src/sequelize/managers/microservice-manager.js
+++ b/src/sequelize/managers/microservice-manager.js
@@ -153,7 +153,8 @@ class MicroserviceManager extends BaseManager {
'$flow.is_activated$': true
},
{
- '$catalogItem.category$': {[Op.eq]: 'SYSTEM'}
+ '$catalogItem.category$': {[Op.eq]: 'SYSTEM'},
+ '$catalogItem.id$': {[Op.ne]: 1}
}
]
diff --git a/src/services/agent-service.js b/src/services/agent-service.js
index ab71dd9b9..1fdcd258e 100644
--- a/src/services/agent-service.js
+++ b/src/services/agent-service.js
@@ -14,7 +14,6 @@
const TransactionDecorator = require('../decorators/transaction-decorator');
const FogProvisionKeyManager = require('../sequelize/managers/iofog-provision-key-manager');
-const FogTypeManager = require('../sequelize/managers/iofog-type-manager');
const FogManager = require('../sequelize/managers/iofog-manager');
const FogAccessTokenService = require('../services/iofog-access-token-service');
const ChangeTrackingService = require('./change-tracking-service');
@@ -34,7 +33,6 @@ const MicroserviceService = require('../services/microservices-service');
const path = require('path');
const fs = require('fs');
const formidable = require('formidable');
-const logger = require('../logger');
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
@@ -221,7 +219,7 @@ const getAgentMicroservices = async function (fog, transaction) {
const image = images.find(image => image.fogTypeId === fogTypeId);
const imageId = image ? image.containerImage : '';
- const routes = await MicroserviceService.getPhysicalConections(microservice, transaction);
+ const routes = await MicroserviceService.getPhysicalConnections(microservice, transaction);
const responseMicroservice = {
uuid: microservice.uuid,
@@ -300,7 +298,7 @@ const getAgentTunnel = async function (fog, transaction) {
};
const getAgentStrace = async function (fog, transaction) {
- const fogWithStrace = FogManager.findFogStraces({
+ const fogWithStrace = await FogManager.findFogStraces({
uuid: fog.uuid
}, transaction);
@@ -308,7 +306,17 @@ const getAgentStrace = async function (fog, transaction) {
throw new Errors.NotFoundError(ErrorMessages.STRACE_NOT_FOUND);
}
- return fogWithStrace.strace;
+ const straceArr = [];
+ for (const msData of fogWithStrace.microservice) {
+ straceArr.push({
+ microserviceUuid: msData.strace.microserviceUuid,
+ straceRun: msData.strace.straceRun
+ })
+ }
+
+ return {
+ straceValues: straceArr
+ }
};
const updateAgentStrace = async function (straceData, fog, transaction) {
@@ -330,13 +338,13 @@ const getAgentChangeVersionCommand = async function (fog, transaction) {
throw new Errors.NotFoundError(ErrorMessages.VERSION_COMMAND_NOT_FOUND);
}
- const provision = FogProvisionKeyManager.findOne({
+ const provision = await FogProvisionKeyManager.findOne({
iofogUuid: fog.uuid
}, transaction);
return {
versionCommand: versionCommand.versionCommand,
- provisionKey: provision.key,
+ provisionKey: provision.provisionKey,
expirationTime: provision.expirationTime
}
};
diff --git a/src/services/connector-service.js b/src/services/connector-service.js
index dd10c8a04..2f1ceab98 100644
--- a/src/services/connector-service.js
+++ b/src/services/connector-service.js
@@ -168,7 +168,7 @@ async function openPortsOnConnector(connector, isPublicAccess, transaction) {
};
if (!connector.devMode && connector.cert && connector.isSelfSignedCert === true) {
const ca = fs.readFileSync(connector.cert);
- options.ca = new Buffer(ca);
+ options.ca = new Buffer.from(ca);
}
const ports = await _makeRequest(connector, options, data);
@@ -205,7 +205,7 @@ async function closePortOnConnector(connector, ports, transaction) {
};
if (!connector.devMode && connector.cert && connector.isSelfSignedCert === true) {
const ca = fs.readFileSync(connector.cert);
- options.ca = new Buffer(ca);
+ options.ca = new Buffer.from(ca);
}
diff --git a/src/services/diagnostic-service.js b/src/services/diagnostic-service.js
index 474db7797..fcd46e37b 100644
--- a/src/services/diagnostic-service.js
+++ b/src/services/diagnostic-service.js
@@ -28,40 +28,40 @@ const path = require('path');
const mime = require('mime');
-const changeMicroserviceStraceState = async function (id, data, user, isCLI, transaction) {
+const changeMicroserviceStraceState = async function (uuid, data, user, isCLI, transaction) {
await Validator.validate(data, Validator.schemas.straceStateUpdate);
- const microservice = await MicroserviceService.getMicroservice(id, user, isCLI, transaction);
+ const microservice = await MicroserviceService.getMicroservice(uuid, user, isCLI, transaction);
if (microservice.iofogUuid === null) {
throw new Errors.ValidationError(ErrorMessages.STRACE_WITHOUT_FOG);
}
const straceObj = {
straceRun: data.enable,
- microserviceUuid: id
+ microserviceUuid: uuid
};
- await StraceDiagnosticManager.updateOrCreate({microserviceUuid: id}, straceObj, transaction);
+ await StraceDiagnosticManager.updateOrCreate({microserviceUuid: uuid}, straceObj, transaction);
await ChangeTrackingService.update(microservice.iofogUuid, ChangeTrackingService.events.diagnostics, transaction)
};
-const getMicroserviceStraceData = async function (id, data, user, isCLI, transaction) {
+const getMicroserviceStraceData = async function (uuid, data, user, isCLI, transaction) {
await Validator.validate(data, Validator.schemas.straceGetData);
const microserviceWhere = isCLI
- ? {uuid: id}
- : {uuid: id, userId: user.id};
+ ? {uuid: uuid}
+ : {uuid: uuid, userId: user.id};
const microservice = await MicroserviceManager.findOne(microserviceWhere, transaction);
if (!microservice) {
- throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_UUID, id))
+ throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_UUID, uuid))
}
- const straceData = await StraceDiagnosticManager.findOne({microserviceUuid: id}, transaction);
+ const straceData = await StraceDiagnosticManager.findOne({microserviceUuid: uuid}, transaction);
if (!straceData) {
- throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_STRACE, id))
+ throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_STRACE, uuid))
}
const dir = config.get('Diagnostics:DiagnosticDir') || 'diagnostics';
- const filePath = dir + '/' + id;
+ const filePath = dir + '/' + uuid;
let result = straceData.buffer;
@@ -77,16 +77,24 @@ const getMicroserviceStraceData = async function (id, data, user, isCLI, transac
};
};
-const postMicroserviceStraceDatatoFtp = async function (id, data, user, isCLI, transaction) {
+const postMicroserviceStraceDatatoFtp = async function (uuid, data, user, isCLI, transaction) {
await Validator.validate(data, Validator.schemas.stracePostToFtp);
- const straceData = await StraceDiagnosticManager.findOne({microserviceUuid: id}, transaction);
+
+ const microserviceWhere = isCLI
+ ? {uuid: uuid}
+ : {uuid: uuid, userId: user.id};
+ const microservice = await MicroserviceManager.findOne(microserviceWhere, transaction);
+ if (!microservice) {
+ throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_UUID, uuid))
+ }
+ const straceData = await StraceDiagnosticManager.findOne({microserviceUuid: uuid}, transaction);
if (!straceData) {
- throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_STRACE, id))
+ throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_STRACE, uuid))
}
const dir = config.get('Diagnostics:DiagnosticDir');
- const filePath = dir + '/' + id;
+ const filePath = dir + '/' + uuid;
_createDirectoryIfNotExists(dir);
_writeBufferToFile(filePath, straceData.buffer);
diff --git a/src/services/microservices-service.js b/src/services/microservices-service.js
index f0e0b7dd1..2207b4d04 100644
--- a/src/services/microservices-service.js
+++ b/src/services/microservices-service.js
@@ -243,6 +243,8 @@ async function _deleteMicroservice(microserviceUuid, microserviceData, user, isC
throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_UUID, microserviceUuid));
}
+ await _deletePortMappings(microservice, user, transaction);
+
if (microservice.microserviceStatus.status === MicroserviceStates.NOT_RUNNING) {
await _deleteMicroserviceWithRoutes(microserviceUuid, transaction);
} else {
@@ -258,6 +260,20 @@ async function _deleteMicroservice(microserviceUuid, microserviceData, user, isC
await _updateChangeTracking(false, microservice.iofogUuid, transaction)
}
+async function _deletePortMappings(microservice, user, transaction) {
+ const msPortMappings = await MicroservicePortManager.findAll({
+ microserviceUuid: microservice.uuid
+ }, transaction);
+
+ for (const msPorts of msPortMappings) {
+ if (msPorts.isPublic) {
+ await _deletePortMappingOverConnector(microservice, msPorts, user, transaction)
+ } else {
+ await _deleteSimplePortMapping(microservice, msPorts, user, transaction)
+ }
+ }
+}
+
async function _deleteNotRunningMicroservices(transaction) {
const microservices = await MicroserviceManager.findAllWithStatuses(transaction);
microservices
@@ -709,12 +725,13 @@ async function _deletePortMapping(microserviceUuid, internalPort, user, isCLI, t
}
async function _deleteSimplePortMapping(microservice, msPorts, user, transaction) {
- await MicroservicePortManager.delete({id: msPorts.id}, transaction)
+ await MicroservicePortManager.delete({id: msPorts.id}, transaction);
const updateRebuildMs = {
rebuild: true
- }
- await MicroserviceManager.update({uuid: microservice.uuid}, updateRebuildMs, transaction)
+ };
+ await MicroserviceManager.update({uuid: microservice.uuid}, updateRebuildMs, transaction);
+ await ChangeTrackingService.update(microservice.iofogUuid, ChangeTrackingService.events.microserviceCommon, transaction);
}
async function _deletePortMappingOverConnector(microservice, msPorts, user, transaction) {
@@ -956,6 +973,6 @@ module.exports = {
createVolumeMapping: TransactionDecorator.generateTransaction(_createVolumeMapping),
deleteVolumeMapping: TransactionDecorator.generateTransaction(_deleteVolumeMapping),
listVolumeMappings: TransactionDecorator.generateTransaction(_listVolumeMappings),
- getPhysicalConections: getPhysicalConections,
+ getPhysicalConnections: getPhysicalConections,
deleteNotRunningMicroservices: _deleteNotRunningMicroservices
};
diff --git a/src/services/user-service.js b/src/services/user-service.js
index 85e30c08e..881670c15 100644
--- a/src/services/user-service.js
+++ b/src/services/user-service.js
@@ -18,6 +18,7 @@ const AppHelper = require('../helpers/app-helper');
const Errors = require('../helpers/errors');
const ErrorMessages = require('../helpers/error-messages');
const Config = require('../config');
+const ioFogManager = require('../sequelize/managers/iofog-manager');
const emailActivationTemplate = require('../views/email-activation-temp');
const emailRecoveryTemplate = require('../views/email-temp');
@@ -66,7 +67,12 @@ const login = async function (credentials, isCLI, transaction) {
throw new Errors.InvalidCredentialsError();
}
- const validPassword = credentials.password === user.password || credentials.password === user.tempPassword;
+ const pass = AppHelper.decryptText(user.password, user.email);
+ if (isCLI) {
+ credentials.password = AppHelper.decryptText(credentials.password, credentials.email);
+ }
+
+ const validPassword = credentials.password === pass || credentials.password === user.tempPassword;
if (!validPassword) {
throw new Errors.InvalidCredentialsError();
}
@@ -167,21 +173,40 @@ const updateDetails = async function (user, profileData, isCLI, transaction) {
}
};
-const deleteUser = async function (user, isCLI, transaction) {
+const deleteUser = async function (force, user, isCLI, transaction) {
+
+ if (!force) {
+ const ioFogArray = await ioFogManager.findAll({
+ userId: user.id
+ }, transaction);
+
+ if (!!ioFogArray) {
+ for (const ioFog of ioFogArray) {
+ if (ioFog.daemonStatus === 'RUNNING') {
+ throw new Errors.ValidationError(ErrorMessages.NEEDED_FORCE_DELETE_USER);
+ }
+ }
+ }
+ }
+
await UserManager.delete({
id: user.id
}, transaction);
};
const updateUserPassword = async function (passwordUpdates, user, isCLI, transaction) {
- if (user.password !== passwordUpdates.oldPassword && user.tempPassword !== passwordUpdates.oldPassword) {
+ const pass = AppHelper.decryptText(user.password, user.email);
+
+ if (pass !== passwordUpdates.oldPassword && user.tempPassword !== passwordUpdates.oldPassword) {
throw new Errors.ValidationError(ErrorMessages.INVALID_OLD_PASSWORD);
}
const emailData = await _getEmailData();
const transporter = await _userEmailSender(emailData);
- await UserManager.updatePassword(user.id, passwordUpdates.newPassword, transaction);
+ const newPass = AppHelper.encryptText(passwordUpdates.newPassword, user.email);
+
+ await UserManager.updatePassword(user.id, newPass, transaction);
await _notifyUserAboutPasswordChange(user, emailData, transporter);
};
@@ -356,7 +381,7 @@ async function _getEmailData() {
service: service
}
- } catch(errMsg) {
+ } catch (errMsg) {
throw new Errors.EmailActivationSetupError();
}
diff --git a/test/src/controllers/user-controller.test.js b/test/src/controllers/user-controller.test.js
index 815a45b0a..617ff8537 100644
--- a/test/src/controllers/user-controller.test.js
+++ b/test/src/controllers/user-controller.test.js
@@ -113,14 +113,11 @@ describe('User Controller', () => {
}
}));
def('response', () => Promise.resolve());
- def('encryptedPassword', () => 'encryptedPassword');
def('validatorResponse', () => Promise.resolve(true));
- def('encryptTextResponse', () => $encryptedPassword);
def('subject', () => $subject.userLoginEndPoint($req));
beforeEach(() => {
$sandbox.stub(Validator, 'validate').returns($validatorResponse);
- $sandbox.stub(AppHelper, 'encryptText').returns($encryptTextResponse);
$sandbox.stub(UserService, 'login').returns($response);
});
@@ -141,43 +138,30 @@ describe('User Controller', () => {
});
context('when Validator#validate() succeeds', () => {
- it('calls AppHelper#encryptText() with correct args', async () => {
+ it('calls UserService.login with correct args', async () => {
await $subject;
- expect(AppHelper.encryptText).to.have.been.calledWith($password, $email);
+ expect(UserService.login).to.have.been.calledWith({
+ email: $email,
+ password: $password
+ }, false)
});
- context('when AppHelper#encryptText() fails', () => {
- it('fails', () => {
- return expect($subject).to.eventually.equal(undefined);
- });
- });
-
- context('when AppHelper#encryptText() succeeds', () => {
- it('calls UserService.login with correct args', async () => {
- await $subject;
- expect(UserService.login).to.have.been.calledWith({
- email: $email,
- password: $encryptedPassword
- }, false)
- });
-
- context('when UserService#login fails', () => {
- const error = 'Error!';
+ context('when UserService#login fails', () => {
+ const error = 'Error!';
- def('response', () => Promise.reject(error));
+ def('response', () => Promise.reject(error));
- it(`fails with "${error}"`, () => {
- return expect($subject).to.be.rejectedWith(error)
- })
- });
-
- context('when UserService#login succeeds', () => {
- it(`succeeds`, () => {
- return expect($subject).to.eventually.equal(undefined)
- })
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
})
});
+ context('when UserService#login succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.equal(undefined)
+ })
+ })
+
});
});
@@ -354,7 +338,9 @@ describe('User Controller', () => {
def('user', () => 'user!');
def('req', () => ({
- body: {}
+ body: {
+ force: true
+ }
}));
def('response', () => Promise.resolve());
def('subject', () => $subject.deleteUserProfileEndPoint($req, $user));
@@ -365,7 +351,7 @@ describe('User Controller', () => {
it('calls UserService.deleteUser with correct args', async () => {
await $subject;
- expect(UserService.deleteUser).to.have.been.calledWith($user, false);
+ expect(UserService.deleteUser).to.have.been.calledWith(true, $user, false);
});
context('when UserService#deleteUser fails', () => {
@@ -399,13 +385,10 @@ describe('User Controller', () => {
}));
def('response', () => Promise.resolve());
def('validatorResponse', () => Promise.resolve(true));
- def('encryptedPassword', () => 'encryptedPassword');
- def('encryptTextResponse', () => $encryptedPassword);
def('subject', () => $subject.updateUserPasswordEndPoint($req, $user));
beforeEach(() => {
$sandbox.stub(Validator, 'validate').returns($validatorResponse);
- $sandbox.stub(AppHelper, 'encryptText').returns($encryptTextResponse);
$sandbox.stub(UserService, 'updateUserPassword').returns($response);
});
@@ -426,56 +409,29 @@ describe('User Controller', () => {
});
context('when Validator#validate() succeeds', () => {
- it('calls AppHelper#encryptText() for old password with correct args', async () => {
+ it('calls UserService.updateUserPassword with correct args', async () => {
await $subject;
- expect(AppHelper.encryptText).to.have.been.calledWith($oldPassword, $user.email);
- });
-
- context('when AppHelper#encryptText() for old password fails', () => {
- it('fails', () => {
- return expect($subject).to.eventually.equal(undefined);
- });
+ expect(UserService.updateUserPassword).to.have.been.calledWith({
+ oldPassword: $oldPassword,
+ newPassword: $newPassword
+ }, $user, false);
});
- context('when AppHelper#encryptText() for old password succeeds', () => {
- it('calls AppHelper#encryptText() for new password with correct args', async () => {
- await $subject;
- expect(AppHelper.encryptText).to.have.been.calledWith($newPassword, $user.email);
- });
+ context('when UserService#updateUserPassword fails', () => {
+ const error = 'Error!';
- context('when AppHelper#encryptText() for new password fails', () => {
- it('fails', () => {
- return expect($subject).to.eventually.equal(undefined);
- });
- });
-
- context('when AppHelper#encryptText() for new password succeeds', () => {
- it('calls UserService.updateUserPassword with correct args', async () => {
- await $subject;
- expect(UserService.updateUserPassword).to.have.been.calledWith({
- oldPassword: $encryptedPassword,
- newPassword: $encryptedPassword
- }, $user, false);
- });
-
- context('when UserService#updateUserPassword fails', () => {
- const error = 'Error!';
-
- def('response', () => Promise.reject(error));
-
- it(`fails with "${error}"`, () => {
- return expect($subject).to.be.rejectedWith(error)
- })
- });
-
- context('when UserService#updateUserPassword succeeds', () => {
- it(`succeeds`, () => {
- return expect($subject).to.eventually.equal(undefined)
- })
- })
- });
+ def('response', () => Promise.reject(error));
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
});
+
+ context('when UserService#updateUserPassword succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.equal(undefined)
+ })
+ })
});
});
diff --git a/test/src/helpers/app-helpers.test.js b/test/src/helpers/app-helpers.test.js
index 69935d8d2..f832ef517 100644
--- a/test/src/helpers/app-helpers.test.js
+++ b/test/src/helpers/app-helpers.test.js
@@ -1,93 +1,88 @@
-const crypto = require('crypto')
-const { expect } = require('chai')
-const fs = require('fs')
-const path = require('path')
-const portscanner = require('portscanner')
-const sinon = require('sinon')
+const crypto = require('crypto');
+const { expect } = require('chai');
+const fs = require('fs');
+const path = require('path');
+const portscanner = require('portscanner');
+const sinon = require('sinon');
-const AppHelpers = require('../../../src/helpers/app-helper')
-const Config = require('../../../src/config')
+const AppHelpers = require('../../../src/helpers/app-helper');
+const Config = require('../../../src/config');
describe('App Helpers', () => {
- const text = 'some-text'
- const salt = 'kosher-salt'
- const encrypted = '17f4faa5c532708c8f'
-
- def('subject', () => AppHelpers)
- def('sandbox', () => sinon.createSandbox())
+ const text = 'some-text';
+ const salt = 'kosher-salt';
+ const encrypted = '18f4faa5c532708c8f';
+ const processedSalt = 'c2cd22c1a8133704f09fc8a218088b1b';
+ const encryptedPasswordLine = '17f4faa5c532708c8f:18f4faa5c532708c8f';
+
+ def('subject', () => AppHelpers);
+ def('sandbox', () => sinon.createSandbox());
def('cipher', () => ({
update: $sandbox.stub().returns(''),
final: $sandbox.stub().returns(encrypted)
- }))
+ }));
def('decipher', () => ({
update: $sandbox.stub().returns(''),
final: $sandbox.stub().returns(text)
- }))
+ }));
- afterEach(() => $sandbox.restore())
+ afterEach(() => $sandbox.restore());
describe('.encryptText()', () => {
- def('subject', () => $subject.encryptText(text, salt))
+ def('subject', () => $subject.encryptText(text, salt));
+ def('iv', () => '17f4faa5c532708c8f');
beforeEach(() => {
- $sandbox.stub(crypto, 'createCipher').returns($cipher)
- })
+ $sandbox.stub(crypto, 'randomBytes').returns($iv);
+ $sandbox.stub(crypto, 'createCipheriv').returns($cipher);
+ });
- it('calls crypto#createCipher() with correct args', () => {
+ it('calls crypto#createCipheriv() with correct args', () => {
$subject
- expect(crypto.createCipher).to.have.been.calledWith('aes-256-ctr', salt)
- })
+ expect(crypto.createCipheriv).to.have.been.calledWith('aes-256-ctr', processedSalt, $iv)
+ });
it('calls crypto.cipher#update() with correct args', () => {
$subject
expect($cipher.update).to.have.been.calledWith(text, 'utf8', 'hex')
- })
+ });
it('calls crypto.cipher#final() with correct args', () => {
$subject
expect($cipher.final).to.have.been.calledWith('hex')
- })
+ });
it('returns the encrypted text', () => {
- expect($subject).to.equal(encrypted)
+ expect($subject).to.equal(encryptedPasswordLine)
})
- })
+ });
describe('.decryptText()', () => {
- def('subject', () => $subject.decryptText(encrypted, salt))
+ def('iv', () => '17f4faa5c532708c8f');
+ def('subject', () => $subject.decryptText(encryptedPasswordLine, salt));
beforeEach(() => {
- $sandbox.stub(crypto, 'createDecipher').returns($decipher)
- })
-
- it('calls crypto#createDecipher() with correct args', () => {
- $subject
- expect(crypto.createDecipher).to.have.been.calledWith('aes-256-ctr', salt)
- })
-
- it('calls crypto.decipher#update() with correct args', () => {
- $subject
- expect($decipher.update).to.have.been.calledWith(encrypted, 'hex', 'utf8')
- })
+ $sandbox.stub(crypto, 'createDecipheriv').returns($decipher);
+ });
it('calls crypto.decipher#final() with correct args', () => {
$subject
expect($decipher.final).to.have.been.calledWith('utf8')
- })
+ });
it('returns the decrypted text', () => {
expect($subject).to.equal(text)
})
- })
+ });
describe('.generateRandomString()', () => {
- def('size', () => 12)
+ def('size', () => 12);
context('when size is greater than zero', () => {
it('returns a random string with length of size', () => {
expect(AppHelpers.generateRandomString($size)).to.have.lengthOf($size)
})
- })
+ });
context('when size is zero', () => {
def('size', () => 0)
diff --git a/test/src/services/access-token-service.test.js b/test/src/services/access-token-service.test.js
new file mode 100644
index 000000000..ba058e0af
--- /dev/null
+++ b/test/src/services/access-token-service.test.js
@@ -0,0 +1,83 @@
+const { expect } = require('chai');
+const sinon = require('sinon');
+
+const AccessTokenManager = require('../../../src/sequelize/managers/access-token-manager');
+const AccessTokenService = require('../../../src/services/access-token-service');
+
+describe('AccessToken Service', () => {
+ def('subject', () => AccessTokenService);
+ def('sandbox', () => sinon.createSandbox());
+
+ afterEach(() => $sandbox.restore());
+
+ describe('.createAccessToken()', () => {
+ const accessToken = "accessToken";
+ const transaction = {};
+ const error = 'Error!';
+
+ def('accessTokenObj', () => 'accessTokenResponse');
+
+ def('subject', () => $subject.createAccessToken(accessToken, transaction));
+ def('accessTokenResponse', () => Promise.resolve($accessTokenObj));
+
+ beforeEach(() => {
+ $sandbox.stub(AccessTokenManager, 'create').returns($accessTokenResponse);
+ });
+
+ it('calls AccessTokenManager#create() with correct args', async () => {
+ await $subject;
+ expect(AccessTokenManager.create).to.have.been.calledWith(accessToken, transaction);
+ });
+
+ context('when AccessTokenManager#create() fails', () => {
+ def('accessTokenResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when AccessTokenManager#create() succeeds', () => {
+ it('fulfills the promise', () => {
+ return expect($subject).to.eventually.equal($accessTokenObj)
+ })
+ })
+ });
+
+ describe('.removeAccessTokenByUserId()', () => {
+ const userId = 15;
+ const transaction = {};
+ const error = 'Error!';
+
+ def('removeTokenObj', () => 'removeToken');
+
+ def('subject', () => $subject.removeAccessTokenByUserId(userId, transaction));
+ def('removeTokenResponse', () => Promise.resolve($removeTokenObj));
+
+ beforeEach(() => {
+ $sandbox.stub(AccessTokenManager, 'delete').returns($removeTokenResponse);
+ });
+
+ it('calls AccessTokenManager#delete() with correct args', async () => {
+ await $subject;
+ expect(AccessTokenManager.delete).to.have.been.calledWith({
+ userId: userId
+ }, transaction);
+ });
+
+ context('when AccessTokenManager#delete() fails', () => {
+ def('removeTokenResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when AccessTokenManager#delete() succeeds', () => {
+ it('fulfills the promise', () => {
+ return expect($subject).to.eventually.equal($removeTokenObj)
+ })
+ })
+ })
+
+});
\ No newline at end of file
diff --git a/test/src/services/agent-service.test.js b/test/src/services/agent-service.test.js
new file mode 100644
index 000000000..198d25d56
--- /dev/null
+++ b/test/src/services/agent-service.test.js
@@ -0,0 +1,1051 @@
+const {expect} = require('chai');
+const sinon = require('sinon');
+
+const AgentService = require('../../../src/services/agent-service');
+const Validator = require('../../../src/schemas');
+const FogProvisionKeyManager = require('../../../src/sequelize/managers/iofog-provision-key-manager');
+const MicroserviceManager = require('../../../src/sequelize/managers/microservice-manager');
+const ioFogManager = require('../../../src/sequelize/managers/iofog-manager');
+const FogAccessTokenService = require('../../../src/services/iofog-access-token-service');
+const AppHelper = require('../../../src/helpers/app-helper');
+const ChangeTrackingService = require('../../../src/services/change-tracking-service');
+const MicroserviceStatusManager = require('../../../src/sequelize/managers/microservice-status-manager');
+const MicroserviceService = require('../../../src/services/microservices-service');
+const RegistryManager = require('../../../src/sequelize/managers/registry-manager');
+const TunnelManager = require('../../../src/sequelize/managers/tunnel-manager');
+const StraceManager = require('../../../src/sequelize/managers/strace-manager');
+const ioFogVersionCommandManager = require('../../../src/sequelize/managers/iofog-version-command-manager');
+const ioFogProvisionKeyManager = require('../../../src/sequelize/managers/iofog-provision-key-manager');
+const BaseManager = require('../../../src/sequelize/managers/base-manager');
+const Sequelize = require('sequelize');
+const Op = Sequelize.Op;
+
+
+describe('Agent Service', () => {
+ def('subject', () => AgentService);
+ def('sandbox', () => sinon.createSandbox());
+
+ afterEach(() => $sandbox.restore());
+
+ describe('.agentProvision()', () => {
+ const provisionData = {
+ type: 1,
+ key: 'dpodkqwdpj'
+ };
+
+ const transaction = {};
+ const error = 'Error!';
+
+ def('uuid', () => 'testUuid');
+ def('token', () => 'testToken');
+
+ def('provisionResponse', () => 'provisionResponse');
+
+ def('subject', () => $subject.agentProvision(provisionData, transaction));
+ def('accessTokenResponse', () => Promise.resolve($accessTokenObj));
+
+ def('validatorResponse', () => Promise.resolve(true));
+ def('fogProvisionKeyManagerResponse', () => Promise.resolve({
+ uuid: $uuid
+ }));
+ def('microserviceManagerResponse', () => Promise.resolve());
+ def('iofogManagerResponse', () => Promise.resolve({
+ uuid: $uuid
+ }));
+ def('fogAccessTokenServiceGenerateResponse', () => Promise.resolve({
+ token: $token
+ }));
+ def('fogAccessTokenServiceUpdateResponse', () => Promise.resolve());
+ def('iofogManagerUpdateResponse', () => Promise.resolve());
+ def('fogProvisionKeyManagerDeleteResponse', () => Promise.resolve());
+
+ beforeEach(() => {
+ $sandbox.stub(Validator, 'validate').returns($validatorResponse);
+ $sandbox.stub(FogProvisionKeyManager, 'findOne').returns($fogProvisionKeyManagerResponse);
+ $sandbox.stub(MicroserviceManager, 'findAllWithDependencies').returns($microserviceManagerResponse);
+ $sandbox.stub(ioFogManager, 'findOne').returns($iofogManagerResponse);
+ $sandbox.stub(FogAccessTokenService, 'generateAccessToken').returns($fogAccessTokenServiceGenerateResponse);
+ $sandbox.stub(FogAccessTokenService, 'updateAccessToken').returns($fogAccessTokenServiceUpdateResponse);
+ $sandbox.stub(ioFogManager, 'update').returns($iofogManagerUpdateResponse);
+ $sandbox.stub(FogProvisionKeyManager, 'delete').returns($fogProvisionKeyManagerDeleteResponse);
+ });
+
+ it('calls Validator#validate() with correct args', async () => {
+ await $subject;
+ expect(Validator.validate).to.have.been.calledWith(provisionData, Validator.schemas.agentProvision);
+ });
+
+ context('when Validator#validate() fails', () => {
+ def('validatorResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when Validator#validate() succeeds', () => {
+ it('calls FogProvisionKeyManager.findOne with correct args', async () => {
+ await $subject;
+ expect(FogProvisionKeyManager.findOne).to.have.been.calledWith({
+ provisionKey: provisionData.key
+ }, transaction);
+ });
+
+ context('when FogProvisionKeyManager#findOne fails', () => {
+ const error = 'Error!';
+
+ def('fogProvisionKeyManagerResponse', () => Promise.reject(error));
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when ioFogManager#findOne succeeds', () => {
+ it('calls ioFogManager.findOne with correct args', async () => {
+ await $subject;
+ expect(ioFogManager.findOne).to.have.been.calledWith({
+ uuid: $fogProvisionKeyManagerResponse.uuid
+ }, transaction);
+ });
+
+ context('when ioFogManager#findOne fails', () => {
+ const error = 'Error!';
+
+ def('iofogManagerResponse', () => Promise.reject(error));
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when ioFogManager#findOne succeeds', () => {
+ it('calls MicroserviceManager.findAllWithDependencies with correct args', async () => {
+ await $subject;
+ expect(MicroserviceManager.findAllWithDependencies).to.have.been.calledWith({
+ iofogUuid: $uuid
+ }, {}, transaction);
+ });
+
+ context('when MicroserviceManager#findAllWithDependencies fails', () => {
+ const error = 'Error!';
+
+ def('microserviceManagerResponse', () => Promise.reject(error));
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when MicroserviceManager#findAllWithDependencies succeeds', () => {
+ it('calls FogAccessTokenService.generateAccessToken with correct args', async () => {
+ await $subject;
+ expect(FogAccessTokenService.generateAccessToken).to.have.been.calledWith(transaction);
+ });
+
+ context('when FogAccessTokenService#generateAccessToken fails', () => {
+ const error = 'Error!';
+
+ def('fogAccessTokenServiceGenerateResponse', () => Promise.reject(error));
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when FogAccessTokenService#generateAccessToken succeeds', () => {
+ it('calls FogAccessTokenService.updateAccessToken with correct args', async () => {
+ await $subject;
+ expect(FogAccessTokenService.updateAccessToken).to.have.been.calledWith($uuid, {
+ token: $token
+ }, transaction);
+ });
+
+ context('when FogAccessTokenService#updateAccessToken fails', () => {
+ const error = 'Error!';
+
+ def('fogAccessTokenServiceUpdateResponse', () => Promise.reject(error));
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when FogAccessTokenService#updateAccessToken succeeds', () => {
+ it('calls ioFogManager.update with correct args', async () => {
+ await $subject;
+ expect(ioFogManager.update).to.have.been.calledWith({
+ uuid: $uuid
+ }, {
+ fogTypeId: provisionData.type
+ }, transaction);
+ });
+
+ context('when ioFogManager#update fails', () => {
+ const error = 'Error!';
+
+ def('iofogManagerUpdateResponse', () => Promise.reject(error));
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when ioFogManager#update succeeds', () => {
+ it('calls FogProvisionKeyManager.delete with correct args', async () => {
+ await $subject;
+ expect(FogProvisionKeyManager.delete).to.have.been.calledWith({
+ provisionKey: provisionData.key
+ }, transaction);
+ });
+
+ context('when FogProvisionKeyManager#delete fails', () => {
+ const error = 'Error!';
+
+ def('fogProvisionKeyManagerDeleteResponse', () => Promise.reject(error));
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when FogProvisionKeyManager#delete succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.have.property('uuid') &&
+ expect($subject).to.eventually.have.property('token');
+ })
+ })
+ })
+ })
+ })
+ })
+ })
+ })
+ });
+ });
+
+ describe('.updateAgentConfig()', () => {
+ const agentConfig = {
+ networkInterface: "testNetworkInterface",
+ dockerUrl: "testDockerUrl",
+ diskLimit: 5,
+ diskDirectory: "testDiskDirectory",
+ memoryLimit: 15,
+ cpuLimit: 25,
+ logLimit: 35,
+ logDirectory: 'testLogDirectory',
+ logFileCount: 15,
+ statusFrequency: 40,
+ changeFrequency: 45,
+ deviceScanFrequency: 50,
+ watchdogEnabled: false,
+ latitude: 35,
+ longitude: 36,
+ gpsMode: 'testGpsMode'
+ };
+
+ const transaction = {};
+ const error = 'Error!';
+
+ def('uuid', () => 'testUuid');
+
+ def('fog', () => ({
+ uuid: $uuid
+ }));
+
+ def('token', () => 'testToken');
+
+ def('updateAgentResponse', () => 'updateAgentResponse');
+
+ def('subject', () => $subject.updateAgentConfig(agentConfig, $fog, transaction));
+
+ def('validatorResponse', () => Promise.resolve(true));
+ def('deleteUndefinedFieldsResponse', () => agentConfig);
+ def('iofogManagerUpdateResponse', () => Promise.resolve());
+
+ beforeEach(() => {
+ $sandbox.stub(Validator, 'validate').returns($validatorResponse);
+ $sandbox.stub(AppHelper, 'deleteUndefinedFields').returns($deleteUndefinedFieldsResponse);
+ $sandbox.stub(ioFogManager, 'update').returns($iofogManagerUpdateResponse);
+ });
+
+ it('calls Validator#validate() with correct args', async () => {
+ await $subject;
+ expect(Validator.validate).to.have.been.calledWith(agentConfig, Validator.schemas.updateAgentConfig);
+ });
+
+ context('when Validator#validate() fails', () => {
+ def('validatorResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when Validator#validate() succeeds', () => {
+ it('calls AppHelper.deleteUndefinedFields with correct args', async () => {
+ await $subject;
+ expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(agentConfig);
+ });
+
+ context('when AppHelper#deleteUndefinedFields fails', () => {
+ const error = 'Error!';
+
+ def('deleteUndefinedFieldsResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when AppHelper#deleteUndefinedFields succeeds', () => {
+ it('calls ioFogManager.update with correct args', async () => {
+ await $subject;
+ expect(ioFogManager.update).to.have.been.calledWith({
+ uuid: $uuid
+ }, agentConfig, transaction);
+ });
+
+ context('when ioFogManager#update fails', () => {
+ const error = 'Error!';
+
+ def('iofogManagerUpdateResponse', () => Promise.reject(error));
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith(error)
+ })
+ });
+
+ context('when ioFogManager#update succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.equal(undefined);
+ })
+ })
+
+ })
+ });
+ });
+
+ describe('.getAgentConfigChanges()', () => {
+ const configChanges = {
+ config: undefined,
+ version: undefined,
+ reboot: undefined,
+ deleteNode: undefined,
+ microserviceList: undefined,
+ microserviceConfig: undefined,
+ routing: undefined,
+ registries: undefined,
+ tunnel: undefined,
+ diagnostics: undefined,
+ isImageSnapshot: undefined
+ };
+
+ const transaction = {};
+ const error = 'Error!';
+
+ def('uuid', () => 'testUuid');
+
+ def('fog', () => ({
+ uuid: $uuid
+ }));
+
+ def('token', () => 'testToken');
+
+ def('subject', () => $subject.getAgentConfigChanges($fog, transaction));
+
+ def('getByFogIdResponse', () => 'getByFogIdResponse');
+ def('updateIfChangedResponse', () => Promise.resolve());
+
+ beforeEach(() => {
+ $sandbox.stub(ChangeTrackingService, 'getByFogId').returns($getByFogIdResponse);
+ $sandbox.stub(ChangeTrackingService, 'updateIfChanged').returns($updateIfChangedResponse);
+ });
+
+ it('calls ChangeTrackingService#getByFogId() with correct args', async () => {
+ await $subject;
+ expect(ChangeTrackingService.getByFogId).to.have.been.calledWith($uuid, transaction);
+ });
+
+ context('when ChangeTrackingService#getByFogId() fails', () => {
+ def('getByFogIdResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when ChangeTrackingService#getByFogId() succeeds', () => {
+ it('calls ChangeTrackingService.updateIfChanged with correct args', async () => {
+ await $subject;
+ expect(ChangeTrackingService.updateIfChanged).to.have.been.calledWith($uuid,
+ ChangeTrackingService.events.clean, transaction);
+ });
+
+ context('when ChangeTrackingService#updateIfChanged fails', () => {
+ const error = 'Error!';
+
+ def('deleteUndefinedFieldsResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when ChangeTrackingService#updateIfChanged succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.deep.equal(configChanges);
+ })
+ })
+ });
+ });
+
+ describe('.updateAgentStatus()', () => {
+ const microservicesStatus = "[{\"containerId\":\"testContainerId\", \"status\":\"RUNNING\"" +
+ ",\"startTime\":5325543453454,\"operatingDuration\":534535435435,\"cpuUsage\":35,\"memoryUsage\":45}]";
+
+ const microserviceStatus = {
+ "containerId": "testContainerId",
+ "status": "RUNNING",
+ "startTime": 5325543453454,
+ "operatingDuration": 534535435435,
+ "cpuUsage": 35,
+ "memoryUsage": 45
+ };
+
+ const microserviceStatusArray = [microserviceStatus];
+
+ const fogStatus = {
+ daemonStatus: 'RUNNING',
+ daemonOperatingDuration: 25,
+ daemonLastStart: 15325235253,
+ memoryUsage: 15,
+ diskUsage: 16,
+ cpuUsage: 17,
+ memoryViolation: false,
+ diskViolation: false,
+ cpuViolation: false,
+ repositoryCount: 5,
+ repositoryStatus: 'testStatus',
+ systemTime: 15325235253,
+ lastStatusTime: 15325235253,
+ ipAddress: 'testIpAddress',
+ processedMessages: 155,
+ microserviceMessageCounts: 'testMessageCounts',
+ messageSpeed: 255,
+ lastCommandTime: 15325235253,
+ tunnelStatus: 'testTunnelStatus',
+ version: '1.0.0',
+ isReadyToUpgrade: false,
+ isReadyToRollback: false,
+ microserviceStatus: microservicesStatus
+ };
+
+ const agentStatus = {
+ daemonStatus: 'RUNNING',
+ daemonOperatingDuration: 25,
+ daemonLastStart: 15325235253,
+ memoryUsage: 15,
+ diskUsage: 16,
+ cpuUsage: 17,
+ memoryViolation: false,
+ diskViolation: false,
+ cpuViolation: false,
+ repositoryCount: 5,
+ repositoryStatus: 'testStatus',
+ systemTime: 15325235253,
+ lastStatusTime: 15325235253,
+ ipAddress: 'testIpAddress',
+ processedMessages: 155,
+ microserviceMessageCounts: 'testMessageCounts',
+ messageSpeed: 255,
+ lastCommandTime: 15325235253,
+ tunnelStatus: 'testTunnelStatus',
+ version: '1.0.0',
+ isReadyToUpgrade: false,
+ isReadyToRollback: false
+ };
+
+ const transaction = {};
+ const error = 'Error!';
+
+ def('uuid', () => 'testUuid');
+
+ def('fog', () => ({
+ uuid: $uuid
+ }));
+
+ def('token', () => 'testToken');
+
+ def('subject', () => $subject.updateAgentStatus(fogStatus, $fog, transaction));
+
+ def('validatorResponse', () => Promise.resolve(true));
+ def('deleteUndefinedFieldsResponse', () => agentStatus);
+ def('deleteUndefinedFieldsResponse2', () => microserviceStatus);
+ def('updateResponse', () => Promise.resolve());
+ def('jsonParseResponse', () => microserviceStatusArray);
+ def('updateMicroserviceStatusesResponse', () => Promise.resolve());
+ def('deleteNotRunningResponse', () => Promise.resolve());
+
+ beforeEach(() => {
+ $sandbox.stub(Validator, 'validate').returns($validatorResponse);
+ $sandbox.stub(AppHelper, 'deleteUndefinedFields')
+ .onFirstCall().returns($deleteUndefinedFieldsResponse)
+ .onSecondCall().returns($deleteUndefinedFieldsResponse2);
+ $sandbox.stub(ioFogManager, 'update').returns($updateResponse);
+ $sandbox.stub(JSON, 'parse').returns($jsonParseResponse);
+ $sandbox.stub(MicroserviceStatusManager, 'update').returns($updateMicroserviceStatusesResponse);
+ $sandbox.stub(MicroserviceService, 'deleteNotRunningMicroservices').returns($deleteNotRunningResponse);
+ });
+
+ it('calls Validator#validate() with correct args', async () => {
+ await $subject;
+ expect(Validator.validate).to.have.been.calledWith(fogStatus, Validator.schemas.updateAgentStatus);
+ });
+
+ context('when Validator#validate() fails', () => {
+ def('validatorResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when Validator#validate() succeeds', () => {
+ it('calls AppHelper.deleteUndefinedFields with correct args', async () => {
+ await $subject;
+ expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(agentStatus);
+ });
+
+ context('when AppHelper#deleteUndefinedFields fails', () => {
+ const error = 'Error!';
+
+ def('$deleteUndefinedFieldsResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when AppHelper#deleteUndefinedFields succeeds', () => {
+ it('calls ioFogManager.update with correct args', async () => {
+ await $subject;
+ expect(ioFogManager.update).to.have.been.calledWith({
+ uuid: $uuid
+ }, agentStatus, transaction);
+ });
+
+ context('when ioFogManager#update fails', () => {
+ const error = 'Error!';
+
+ def('updateResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when ioFogManager#update succeeds', () => {
+ it('calls JSON.parse with correct args', async () => {
+ await $subject;
+ expect(JSON.parse).to.have.been.calledWith(fogStatus.microserviceStatus);
+ });
+
+ context('when JSON#parse fails', () => {
+ const error = 'Error!';
+
+ def('jsonParseResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when JSON#parse succeeds', () => {
+ it('calls AppHelper.deleteUndefinedFields with correct args', async () => {
+ await $subject;
+ expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(microserviceStatus);
+ });
+
+ context('when AppHelper#deleteUndefinedFields fails', () => {
+ const error = 'Error!';
+
+ def('$deleteUndefinedFieldsResponse2', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when AppHelper#deleteUndefinedFields succeeds', () => {
+ it('calls MicroserviceStatusManager.update with correct args', async () => {
+ await $subject;
+ expect(MicroserviceStatusManager.update).to.have.been.calledWith({
+ microserviceUuid: microserviceStatus.id
+ }, microserviceStatus, transaction);
+ });
+
+ context('when MicroserviceStatusManager#update fails', () => {
+ const error = 'Error!';
+
+ def('updateMicroserviceStatusesResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when MicroserviceStatusManager#update succeeds', () => {
+ it('calls MicroserviceService.deleteNotRunningMicroservices with correct args', async () => {
+ await $subject;
+ expect(MicroserviceService.deleteNotRunningMicroservices).to.have.been.calledWith(transaction);
+ });
+
+ context('when MicroserviceService#deleteNotRunningMicroservices fails', () => {
+ const error = 'Error!';
+
+ def('deleteNotRunningResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when MicroserviceService#deleteNotRunningMicroservices succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.equal(undefined);
+ })
+ })
+ })
+ })
+ })
+ })
+ })
+ });
+ });
+
+
+ describe('.getAgentMicroservices()', () => {
+ const transaction = {};
+ const error = 'Error!';
+
+ const routes = [];
+
+ const microservice = {
+ uuid: 'testMicroserviceUuid',
+ imageId: '',
+ config: '{}',
+ rebuild: false,
+ rootHostAccess: false,
+ logSize: 15,
+ ports: 'testPorts',
+ volumeMappings: 'testVolumeMappings',
+ imageSnapshot: 'testImageSnapshot',
+ delete: false,
+ deleteWithCleanup: false,
+ catalogItem: {
+ images: [{
+ fogTypeId: 1,
+ containerImage: 'testContainerImage'
+ }
+ ],
+ registry: {
+ url: 'testUrl'
+ }
+ },
+ routes: routes
+ };
+
+ const microserviceResponse = {
+ microservices: [{
+ uuid: 'testMicroserviceUuid',
+ imageId: 'testContainerImage',
+ config: '{}',
+ rebuild: false,
+ rootHostAccess: false,
+ logSize: 15,
+ portMappings: 'testPorts',
+ volumeMappings: 'testVolumeMappings',
+ imageSnapshot: 'testImageSnapshot',
+ delete: false,
+ deleteWithCleanup: false,
+ routes: routes,
+ registryUrl: 'testUrl'
+ }]
+ };
+
+ def('uuid', () => 'testUuid');
+ def('fogTypeId', () => 1);
+
+ def('fog', () => ({
+ uuid: $uuid,
+ fogTypeId: $fogTypeId
+ }));
+
+ def('token', () => 'testToken');
+
+ def('subject', () => $subject.getAgentMicroservices($fog, transaction));
+
+ def('findAllMicroservicesResponse', () => Promise.resolve([microservice]));
+ def('getPhysicalConnectionsResponse', () => Promise.resolve(routes));
+ def('updateResponse', () => Promise.resolve(microserviceResponse));
+
+ beforeEach(() => {
+ $sandbox.stub(MicroserviceManager, 'findAllActiveFlowMicroservices').returns($findAllMicroservicesResponse);
+ $sandbox.stub(MicroserviceService, 'getPhysicalConnections').returns($getPhysicalConnectionsResponse);
+ $sandbox.stub(MicroserviceManager, 'update').returns($updateResponse);
+ });
+
+ it('calls MicroserviceManager#findAllActiveFlowMicroservices() with correct args', async () => {
+ await $subject;
+ expect(MicroserviceManager.findAllActiveFlowMicroservices).to.have.been.calledWith($uuid, transaction);
+ });
+
+ context('when MicroserviceManager#findAllActiveFlowMicroservices() fails', () => {
+ def('findAllMicroservicesResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when MicroserviceManager#findAllActiveFlowMicroservices() succeeds', () => {
+ it('calls MicroserviceService.getPhysicalConnections with correct args', async () => {
+ await $subject;
+ expect(MicroserviceService.getPhysicalConnections).to.have.been.calledWith(microservice, transaction);
+ });
+
+ context('when MicroserviceService#getPhysicalConnections fails', () => {
+ const error = 'Error!';
+
+ def('getPhysicalConnectionsResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when MicroserviceService#getPhysicalConnections succeeds', () => {
+ it('calls MicroserviceManager.update with correct args', async () => {
+ await $subject;
+ expect(MicroserviceManager.update).to.have.been.calledWith({
+ uuid: microservice.uuid
+ }, {
+ rebuild: false
+ }, transaction);
+ });
+
+ context('when MicroserviceManager#update fails', () => {
+ const error = 'Error!';
+
+ def('updateResponse', () => error);
+
+ it(`fails with "${error}"`, () => {
+ return expect($subject).to.be.rejectedWith = (error)
+ })
+ });
+
+ context('when MicroserviceManager#update succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.deep.equal(microserviceResponse);
+ })
+ })
+ })
+ });
+ });
+
+ describe('.getAgentMicroservice()', () => {
+ const transaction = {};
+ const error = 'Error!';
+
+ const routes = [];
+
+ const microservice = {
+ uuid: 'testMicroserviceUuid',
+ imageId: 'testContainerImage',
+ config: '{}',
+ rebuild: false,
+ rootHostAccess: false,
+ logSize: 15,
+ portMappings: 'testPorts',
+ volumeMappings: 'testVolumeMappings',
+ imageSnapshot: 'testImageSnapshot',
+ delete: false,
+ deleteWithCleanup: false,
+ routes: routes,
+ registryUrl: 'testUrl'
+ };
+
+ const microserviceResponse = {
+ microservice: microservice
+ };
+
+ def('uuid', () => 'testUuid');
+ def('microserviceUuid', () => 'testMicroserviceUuid');
+
+ def('fog', () => ({
+ uuid: $uuid
+ }));
+
+ def('token', () => 'testToken');
+
+ def('subject', () => $subject.getAgentMicroservice($microserviceUuid, $fog, transaction));
+
+ def('findMicroserviceResponse', () => Promise.resolve(microservice));
+
+ beforeEach(() => {
+ $sandbox.stub(MicroserviceManager, 'findOneWithDependencies').returns($findMicroserviceResponse);
+ });
+
+ it('calls MicroserviceManager#findOneWithDependencies() with correct args', async () => {
+ await $subject;
+ expect(MicroserviceManager.findOneWithDependencies).to.have.been.calledWith({
+ uuid: $microserviceUuid,
+ iofogUuid: $uuid
+ }, {}, transaction);
+ });
+
+ context('when MicroserviceManager#findOneWithDependencies() fails', () => {
+ def('findMicroserviceResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when MicroserviceManager#findOneWithDependencies() succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.deep.equal(microserviceResponse);
+ })
+ });
+ });
+
+ describe('.getAgentRegistries()', () => {
+ const transaction = {};
+ const error = 'Error!';
+
+ def('uuid', () => 'testUuid');
+ def('userId', () => 15);
+
+ def('fog', () => ({
+ uuid: $uuid,
+ userId: $userId
+ }));
+
+ def('token', () => 'testToken');
+
+ def('subject', () => $subject.getAgentRegistries($fog, transaction));
+
+ def('getAgentRegistriesResponse', () => Promise.resolve());
+
+ beforeEach(() => {
+ $sandbox.stub(RegistryManager, 'findAll').returns($getAgentRegistriesResponse);
+ });
+
+ it('calls RegistryManager#findAll() with correct args', async () => {
+ await $subject;
+ expect(RegistryManager.findAll).to.have.been.calledWith({
+ [Op.or]:
+ [
+ {
+ userId: $userId
+ },
+ {
+ isPublic: true
+ }
+ ]
+ }, transaction);
+ });
+
+ context('when RegistryManager#findAll() fails', () => {
+ def('getAgentRegistriesResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when RegistryManager#findAll() succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.have.property('registries');
+ })
+ });
+ });
+
+ describe('.getAgentTunnel()', () => {
+ const transaction = {};
+ const error = 'Error!';
+
+ def('uuid', () => 'testUuid');
+
+ def('fog', () => ({
+ uuid: $uuid
+ }));
+
+ def('token', () => 'testToken');
+
+ def('subject', () => $subject.getAgentTunnel($fog, transaction));
+
+ def('getTunnelResponse', () => Promise.resolve({}));
+
+ beforeEach(() => {
+ $sandbox.stub(TunnelManager, 'findOne').returns($getTunnelResponse);
+ });
+
+ it('calls TunnelManager#findOne() with correct args', async () => {
+ await $subject;
+ expect(TunnelManager.findOne).to.have.been.calledWith({
+ iofogUuid: $uuid
+ }, transaction);
+ });
+
+ context('when TunnelManager#findOne() fails', () => {
+ def('getTunnelResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when TunnelManager#findOne() succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.have.property('tunnel');
+ })
+ });
+ });
+
+ describe('.getAgentStrace()', () => {
+ const transaction = {};
+ const error = 'Error!';
+
+ def('uuid', () => 'testUuid');
+
+ def('fog', () => ({
+ uuid: $uuid
+ }));
+
+ def('microserviceUuid', () => 'testMicroserviceUuid');
+ def('straceRun', () => 'testStraceRun');
+
+ def('strace', () => ({
+ microserviceUuid: $microserviceUuid,
+ straceRun: $straceRun
+ }));
+
+ def('getStracesData', () => ({
+ microservice: [{
+ strace: $strace
+ }]
+ }));
+
+ def('straceResponse', () => ({
+ straceValues: [$strace]
+ }));
+
+ def('subject', () => $subject.getAgentStrace($fog, transaction));
+
+ def('getStracesResponse', () => Promise.resolve($getStracesData));
+
+ beforeEach(() => {
+ $sandbox.stub(ioFogManager, 'findFogStraces').returns($getStracesResponse);
+ });
+
+ it('calls ioFogManager#findFogStraces() with correct args', async () => {
+ await $subject;
+ expect(ioFogManager.findFogStraces).to.have.been.calledWith({
+ uuid: $uuid
+ }, transaction);
+ });
+
+ context('when ioFogManager#findFogStraces() fails', () => {
+ def('getStracesResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when ioFogManager#findFogStraces() succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.deep.equal($straceResponse);
+ })
+ });
+ });
+
+ describe('.updateAgentStrace()', () => {
+
+ const transaction = {};
+ const error = 'Error!';
+
+ def('uuid', () => 'testUuid');
+
+ def('fog', () => ({
+ uuid: $uuid
+ }));
+
+ def('microserviceUuid', () => 'testMicroserviceUuid');
+ def('buffer', () => 'testBuffer');
+
+ def('strace', () => ({
+ microserviceUuid: $microserviceUuid,
+ buffer: $buffer
+ }));
+
+ def('straceData', () => ({
+ straceData: [$strace]
+ }));
+
+ def('straceResponse', () => ({
+ straceValues: [$strace]
+ }));
+
+ def('subject', () => $subject.updateAgentStrace($straceData, $fog, transaction));
+
+ def('validatorResponse', () => Promise.resolve(true));
+ def('pushBufferResponse', () => Promise.resolve());
+
+
+ beforeEach(() => {
+ $sandbox.stub(Validator, 'validate').returns($validatorResponse);
+ $sandbox.stub(StraceManager, 'pushBufferByMicroserviceUuid').returns($pushBufferResponse);
+ });
+
+ it('calls Validator#validate() with correct args', async () => {
+ await $subject;
+ expect(Validator.validate).to.have.been.calledWith($straceData, Validator.schemas.updateAgentStrace);
+ });
+
+ context('when Validator#validate() fails', () => {
+ def('validatorResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when Validator#validate() succeeds', () => {
+ it('calls StraceManager#pushBufferByMicroserviceUuid() with correct args', async () => {
+ await $subject;
+ expect(StraceManager.pushBufferByMicroserviceUuid).to.have.been.calledWith($microserviceUuid, $buffer,
+ transaction);
+ });
+
+ context('when StraceManager#pushBufferByMicroserviceUuid() fails', () => {
+ def('pushBufferResponse', () => Promise.reject(error));
+
+ it(`fails with ${error}`, () => {
+ return expect($subject).to.be.rejectedWith(error);
+ })
+ });
+
+ context('when StraceManager#pushBufferByMicroserviceUuid() succeeds', () => {
+ it(`succeeds`, () => {
+ return expect($subject).to.eventually.equal(undefined);
+ })
+ });
+ });
+ });
+
+
+
+});
\ No newline at end of file