diff --git a/app/core/applications/relationsApplication.js b/app/core/applications/relationsApplication.js new file mode 100644 index 00000000..b4089272 --- /dev/null +++ b/app/core/applications/relationsApplication.js @@ -0,0 +1,23 @@ +'use strict'; + +const _ = require('lodash'); + +const DRelationsSyncerService = require('core/services/RelationsSyncerService'); + + +const RelationsApp = (Entity, REntity, RelationsSyncerService = DRelationsSyncerService) => { + + return { + syncer: (req, res, next) => { + const source = 'params.id'; + + RelationsSyncerService(Entity)(REntity) + .syncer(req, source) + .then(e => res.json(e)) + .catch(next); + } + + }; +}; + +module.exports = _.curry(RelationsApp); diff --git a/app/core/applications/transforms/strIDtoObjectID.js b/app/core/applications/transforms/strIDtoObjectID.js index 50ecf449..9121bfda 100644 --- a/app/core/applications/transforms/strIDtoObjectID.js +++ b/app/core/applications/transforms/strIDtoObjectID.js @@ -6,7 +6,8 @@ const {ObjectId} = require('mongorito'); const transfID = (data, key) => { if(_.has(data, key)) { - data[key] = ObjectId(_.get(data, key)); + const id = ObjectId(_.get(data, key)); + _.set(data, key, id); } return data; diff --git a/app/core/hooks/relationInc.js b/app/core/hooks/relationInc.js index a7c8925e..de1c2d0d 100644 --- a/app/core/hooks/relationInc.js +++ b/app/core/hooks/relationInc.js @@ -5,10 +5,9 @@ const DFactoryDBRepository = require('core/repositories/DBRepository'); const {transfID} = require('core/applications/transforms/strIDtoObjectID'); - const relationInc = (configs) => (data) => { - const {Entity, field, source} = configs; - + const {Entity, field} = configs; + const source = _.get(configs, 'source', `${Entity.name}._id`); if(_.has(data, source)) { const inc = _.get(configs, 'inc', 1); @@ -22,6 +21,8 @@ const relationInc = (configs) => (data) => { DBRepository .increment({_id}, post) .catch(console.log); + + return post; } } diff --git a/app/core/repositories/DBRepository.js b/app/core/repositories/DBRepository.js index 99b0cbdc..c9a3ee08 100644 --- a/app/core/repositories/DBRepository.js +++ b/app/core/repositories/DBRepository.js @@ -61,6 +61,7 @@ const DBRepository = (Entity, options={}) => { count (filters = {}, fill = Entity.singleFilled) { return new Promise((resolve, reject) => { const filter = findFilledFormat(filters, fill); + return DB.count(filter) .then(resolve) .catch(reject); diff --git a/app/core/services/PersistenceServices.js b/app/core/services/PersistenceServices.js index 8eea5c7e..f3a2196c 100644 --- a/app/core/services/PersistenceServices.js +++ b/app/core/services/PersistenceServices.js @@ -35,6 +35,21 @@ const Persistence = (Entity, FactoryDBRepository = DFactoryDBRepository) => { }); }, + count (query, owner, access = Access.ROLE_READ) { + return new Promise((resolve, reject) => { + + const prepared = _.assign({}, + query, + accessMergeTransform(owner, Entity.access, query, access), + ...regexFilterQuery(_.get(query, 'query')) + ); + + DBRepository.count(prepared) + .then(resolve) + .catch(reject); + }); + }, + findOne (_id, owner, access = Access.ROLE_READ) { return new Promise((resolve, reject) => { diff --git a/app/core/services/RelationsSyncerService.js b/app/core/services/RelationsSyncerService.js new file mode 100644 index 00000000..add10cac --- /dev/null +++ b/app/core/services/RelationsSyncerService.js @@ -0,0 +1,35 @@ +'use strict'; + +const _ = require('lodash'); +const DBRepository = require('core/repositories/DBRepository'); +const {transfID} = require('core/applications/transforms/strIDtoObjectID'); + + +const RelationsSyncerService = (Entity) => (REntity) => { + + return { + syncer: (data, source = '_id') => { + + return new Promise((resolve, reject) => { + + const _id = _.get(transfID(data, source), source); + const path = `${Entity.name}._id`; + + const fielder = `${REntity.name}_count`; + + DBRepository(REntity) + .count({[path]:_id}, [path]) + .then(total => { + return DBRepository(Entity) + .update({_id}, {[fielder]: total}) + .catch(console.log); + }) + .then(resolve) + .catch(reject); + }); + } + + }; +}; + +module.exports = RelationsSyncerService; diff --git a/app/inventory/applications/persistenceServers.js b/app/inventory/applications/persistenceServers.js index b4a1f3de..b3573221 100644 --- a/app/inventory/applications/persistenceServers.js +++ b/app/inventory/applications/persistenceServers.js @@ -19,7 +19,7 @@ const ApplicationServers = (Entity, PersistenceServices = DPersistenceServices) query = filterHooks(query, field, [ {dest: 'id', source: '_id', module: 'swap'}, - {dest: 'dc.name', source: 'dc', module: 'swap'}, + {dest: 'datacenters.name', source: 'datacenters', module: 'swap'}, {dest: 'os.base', source: 'os', module: 'swap'}, {dest: 'environment', source: 'environment', module: 'swap'}, {dest: 'role', source: 'role', module: 'swap'}, diff --git a/app/inventory/entities/Servers.js b/app/inventory/entities/Servers.js index 3913cc92..9b549ed4 100644 --- a/app/inventory/entities/Servers.js +++ b/app/inventory/entities/Servers.js @@ -5,9 +5,9 @@ const _ = require('lodash'); const Servers = require('../repositories/dao/servers'); const servers = () => { - const resFilled = ['_id', 'updated_at', 'created_at', 'hostname', 'ipv4_private', 'ipv4_public', 'os.base', 'os.dist', 'dc.name', 'dc.region', 'dc.zone', 'role', 'environment', 'auth.name', 'auth.username', 'auth.type', 'tags']; + const resFilled = ['_id', 'updated_at', 'created_at', 'hostname', 'ipv4_private', 'ipv4_public', 'os.base', 'os.dist', 'datacenters.name', 'datacenters.region', 'datacenters.zone', 'role', 'environment', 'auth.name', 'auth.username', 'auth.type', 'tags']; - const singleFilled = [...resFilled, 'cpu', 'memory', 'storage', 'services', 'dc', 'os', 'auth', 'role', 'environment', + const singleFilled = [...resFilled, 'cpu', 'memory', 'storage', 'services', 'datacenters', 'os', 'auth', 'role', 'environment', 'roles', 'owner', 'active', 'status']; const filled = [..._.slice(singleFilled, 3)]; // delete id @@ -23,14 +23,14 @@ const servers = () => { defaults: {}, - mapRelations: [], + mapRelations: ['datacenters'], hooks: { after_create: { relationInc: { Entity: require('inventory/entities/Datacenter'), field: 'servers_count', - source: 'dc._id' + source: 'datacenters._id' } } }, diff --git a/app/inventory/routers/datacenters/datacenters.js b/app/inventory/routers/datacenters/datacenters.js index 82b13f25..f49540d9 100644 --- a/app/inventory/routers/datacenters/datacenters.js +++ b/app/inventory/routers/datacenters/datacenters.js @@ -2,7 +2,11 @@ const authenticate = require('identity/profile/middlewares/authenticate'); const Datacenter = require('../../entities/Datacenter'); +const Servers = require('../../entities/Servers'); + const PersistenceApp = require('core/applications/persistenceApplication')(Datacenter); +const SyncerApp = require('core/applications/relationsApplication')(Datacenter)(Servers); + const AccessApp = require('core/applications/accessApplication')(Datacenter); module.exports = function (router) { @@ -25,5 +29,10 @@ module.exports = function (router) { .put('/:id/roles/:idu', authenticate(), AccessApp.update) - .delete('/:id/roles/:idu', authenticate(), AccessApp.remove); + .delete('/:id/roles/:idu', authenticate(), AccessApp.remove) + + /* + Actions + */ + .patch('/:id/sync_count_servers/', authenticate(), SyncerApp.syncer); }; diff --git a/app/inventory/routers/datacenters/index.js b/app/inventory/routers/datacenters/index.js index e89d682b..3895926e 100644 --- a/app/inventory/routers/datacenters/index.js +++ b/app/inventory/routers/datacenters/index.js @@ -67,4 +67,6 @@ module.exports = function (router) { */ .delete('/teams/:id/datacenters/:idu/roles/:ida', authenticate(), WrapperAccessApp.remove); + + }; diff --git a/app/inventory/validators/datacenters.js b/app/inventory/validators/datacenters.js index 10a060f2..bf346c4c 100644 --- a/app/inventory/validators/datacenters.js +++ b/app/inventory/validators/datacenters.js @@ -10,8 +10,12 @@ const roles = Joi.object().keys({ email: Joi.string().max(250) }); +const create = { + name: Joi.string().min(3).max(30).required() +}; + const scheme = { - name: Joi.string().min(3).max(30).required(), + name: Joi.string().min(3).max(30), role: Joi.any(), zones: Joi.array(), regions: Joi.array(), @@ -29,8 +33,8 @@ const scheme = { }; module.exports = { - create: scheme, - update: scheme, + create: Joi.object().keys(Object.assign({}, scheme, create)), + update: Joi.object().keys(Object.assign({}, scheme)), delete: {}, list: {} }; diff --git a/app/inventory/validators/servers.js b/app/inventory/validators/servers.js index 36119691..03575de3 100644 --- a/app/inventory/validators/servers.js +++ b/app/inventory/validators/servers.js @@ -47,7 +47,7 @@ const schema = Joi.object().keys({ memory: Joi.number().positive().max(1024), storage: Joi.array().items(storage).unique('name'), services: Joi.array().items(services).unique('name'), - dc: Joi.object(), + datacenters: Joi.object(), role: Joi.string().valid('Application', 'Cache', 'Container', 'Database', 'File', 'Loadbalance', 'Monitoring', 'NAT', 'Proxy', 'SMTP', 'VPN', 'Standard').required(), environment: Joi.string().valid('Production', 'Staging', 'Development', 'UTA', 'Training', 'SandBox').required(), auth: Joi.array().items(auth),