From d2311a6ec8b2b42212e463f400acca099b738c47 Mon Sep 17 00:00:00 2001 From: Roee Poleg Date: Thu, 17 Mar 2016 16:30:19 +0200 Subject: [PATCH 1/5] all servers list works --- controllers/serverController.js | 48 ++++++++++++++++++++++++++++++--- public/scripts/application.js | 2 +- routes.js | 3 ++- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/controllers/serverController.js b/controllers/serverController.js index 0f173f4..6cf925d 100644 --- a/controllers/serverController.js +++ b/controllers/serverController.js @@ -31,6 +31,17 @@ function checkIfInQueue(user, queue) { return (false); } +function findServerByName(serverName, servers){ + + for (var i = 0; i < servers.length; i++) { + if (servers[i].name.toLowerCase() == serverName.toLowerCase()) { + return (servers[i]); + } + } + + return (null); +} + module.exports = { all: function (req, res) { @@ -286,15 +297,42 @@ module.exports = { }, rest: { + all: function (req, res) { + + try { + + var query = ServerEnv.find({name: req.query.environment}).sort('order'); + + query.exec(function(err, serverEnvs) { + + if (!err) { + + res.json(serverEnvs[0]); + + } else { throw err; } + }); + + } catch (err) { res.send(500); } + }, + take: function (req, res) { try { - module.exports.take(req.body, function(env) { res.json(env); }); + module.exports.take(req.body, function(env) { + + // Extract and return just the requested server! + var srv = findServerByName(req.body.name, env.servers) + res.json(srv); + }); } catch (err) { res.send(500); } }, extend: function (req, res) { try { - module.exports.extend(req.body, function(env) { res.json(env); }); + module.exports.extend(req.body, function(env) { + // Extract and return just the requested server! + var srv = findServerByName(req.body.name, env.servers) + res.json(srv); + }); } catch (err) { res.send(500); } }, @@ -306,7 +344,11 @@ module.exports = { queue: function(req, res) { try { - module.exports.queue(req.body, function(env) { res.json(env); }); + module.exports.queue(req.body, function(env) { + // Extract and return just the requested server! + var srv = findServerByName(req.body.name, env.servers) + res.json(srv); + }); } catch (err) { res.send(500); } }, diff --git a/public/scripts/application.js b/public/scripts/application.js index c9bec77..f674a42 100644 --- a/public/scripts/application.js +++ b/public/scripts/application.js @@ -1,2 +1,2 @@ -var devflowApp=angular.module("devflowApp",["ngRoute","ngDialog","ngAnimate"]);devflowApp.config(["$routeProvider",function($routeProvider){$routeProvider.when("/main",{templateUrl:"views/templates/dashboard.html",controller:"dashboardController"}).when("/servers",{templateUrl:"views/templates/servers.html",controller:"serverController"}).when("/pullrequests",{templateUrl:"views/templates/requests.html",controller:"requestController"}).when("/graylogs",{templateUrl:"views/templates/requests.html",controller:"requestController"}).when("/manage-users",{templateUrl:"views/templates/manageUsers.html",controller:"usersController"}).when("/manage-servers",{templateUrl:"views/templates/manageServers.html",controller:"manageServersController"}).when("/manage-repos",{templateUrl:"views/templates/manageRepos.html",controller:"reposController"}).when("/manage-tags",{templateUrl:"views/templates/manageTags.html",controller:"tagController"}).otherwise({redirectTo:"/main"})}]),devflowApp.factory("socket",function($rootScope){var socket=io.connect();return{on:function(eventName,callback){socket.on(eventName,function(){var args=arguments;$rootScope.$apply(function(){callback.apply(socket,args)})})},emit:function(eventName,data,callback){socket.emit(eventName,data,function(){var args=arguments;$rootScope.$apply(function(){callback&&callback.apply(socket,args)})})}}}),String.prototype.lpad=function(padString,length){for(var str=this;str.length=0&&collection.splice(index,1)})},fetchRepos:function(){repos.length||repoService.getRepos(function(data){repos=data})}};return methods.initSockets(),methods.fetchRepos(),{getRequests:function(type,notTaken,count,onSuccess,onFailure,skipStore){var params={};notTaken&&(params.notTaken=!0),count&&(params.count=count),$http.get("/request/"+type,{params:params}).success(function(data,status,headers,config){"function"==typeof onSuccess&&(skipStore||(requests[type]=data),onSuccess(data))}).error(function(data,status,headers,config){"function"==typeof onFailure&&onFailure(data)})},allowedToReview:function(user){return"reviewer"==user.role||"admin"==user.role},take:function(request,user){request.state="taken",request.sort_order=2,request.reviewer=methods.userData(user),request.taken_date=new Date,socket.emit("takeRequest",request)},getEnv:function(request){if(config.requests[request.type].constantEnv)return config.requests[request.type].constantEnv;if(request.data.title&&request.data.title.indexOf("http")>=0){var arr=request.data.title.split("/"),env=arr[arr.length-3];return env="pull"==env?arr[arr.length-4]:env,env.replace("_"," ")}return"Pull Request"},getNumber:function(request){if(!config.requests[request.type].hasNumber)return"";if(request.data.title&&request.data.title.indexOf("http")>=0){var arr=request.data.title.split("/"),pullNum=arr[arr.length-1];return"#"+("files"==pullNum?arr[arr.length-2]:pullNum)}return"Not Valid"},"new":function(type,defaultType,user){return user=methods.userData(user),{type:type,urgency:"high",state:"posted",data:{title:null,desc:null,sub_type:defaultType},user:user,sort_order:1,reviewer:null,created_date:null,taken_date:null,reviewed_date:null,rejected:!1,tag:null}},complete:function(request,rejected){request.state="reviewed",request.sort_order=3,request.reviewed_date=new Date,request.rejected=rejected?!0:!1,socket.emit("completeRequest",request)},isUserRequest:function(request,user){return request.user.email==user.email},isPosted:function(request){return"posted"==request.state},isTaken:function(request){return"taken"==request.state},isReviewed:function(request){return"reviewed"==request.state},wasRejected:function(request){return request.rejected},canEdit:function(request,user){return this.isUserRequest(request,user)&&"reviewed"!=request.state},canComplete:function(request,user){var selfTakable=config.requests[request.type].selfTakable;return"taken"==request.state&&request.reviewer.email==user.email&&this.allowedToReview(user)&&(request.user.email!=user.email||selfTakable)},canTake:function(request,user){var selfTakable=config.requests[request.type].selfTakable;return"posted"==request.state&&this.allowedToReview(user)&&(request.user.email!=user.email||selfTakable)},release:function(request){request.state="posted",request.reviewer=null,request.taken_date=null,request.sort_order=1,socket.emit("updateRequest",request)},nudge:methods.nudge,"delete":function(request){var collection=methods.getCollection(request);index=collection.indexOf(request),index>=0&&collection.splice(index,1),socket.emit("deleteRequest",request)},createOrUpdate:function(request,user,isNew){if(isNew)request.data.title.length>0&&(request.user=methods.userData(user),request.created_date=new Date,methods.getCollection(request).unshift(request),socket.emit("addRequest",request,function(newRequest){request._id=newRequest._id}));else{var realRequest=methods.find(request);realRequest&&methods.update(realRequest,request,!0)}},loadMore:function(type){this.getRequests(type,!1,requests[type].length+9,function(newRequests){for(var requestsToAdd=newRequests.slice(requests[type].length),i=0;i0?(nextUser=server.queue[0],server.queue.splice(0,1)):env.queue.length>0&&(nextUser=env.queue[0],env.queue.splice(0,1),unqueuEnv=!0),server.user=nextUser,server.taken_since=new Date,server.release_date=new Date,that.setReleaseDate(server,1)),socket.emit("releaseServer",server),unqueuEnv&&socket.emit("unqueueEnv",{env:env,user:methods.userData(nextUser)})},joinQueue:function(server,user,isEnv){user=methods.userData(user),server.queue.push(user),isEnv?socket.emit("queueEnv",{env:server,user:user}):socket.emit("queueServer",{server:server,user:user})},unqueue:function(server,user,isEnv){user=methods.userData(user),this.removeUserFromQueue(server.queue,user),isEnv?socket.emit("unqueueEnv",{env:server,user:user}):socket.emit("unqueueServer",{server:server,user:user})},changeDownState:function(server,isDown){server.is_down=isDown,this.release(server),socket.emit("changeServerDownState",server)},isTaken:function(server){return"undefined"!=typeof server.user&&null!==server.user},isDown:function(server){return server.is_down},isTakenByUser:function(server,user){return server.user&&server.user.email==user.email},allowedToTakeDown:function(server,user){return("admin"==user.role||"devops"==user.role)&&!server.on_demand},canJoin:function(server,user,isEnv){var that=this,env=isEnv?server:methods.findEnvByName(server.environment);if(that.isDown(server)||that.isUserInQueue(env.queue,user)||server.on_demand&&!isEnv)return!1;for(var serverIndex=0;serverIndex=3};$scope.fields=[{key:"image",type:"image",name:"Photo",viewClass:"user-image"},{key:"name",type:"text",name:"Name",placeholder:"New User",unique:!0,validator:nameValidator},{key:"id",type:"readonly",name:"Google ID"},{key:"email",type:"text",name:"Email",unique:!0,validator:emailValidator},{key:"image",type:"text",name:"Image"},{key:"associated",type:"checkbox",name:"Associated?"},{key:"role",type:"text",name:"Role"}]}]),devflowApp.controller("requestController",["$scope","userService","requestService","reviewService",function($scope,userService,requestService,reviewService){$scope.requestType=window.location.hash.replace("#/","").slice(0,-1),userService.getCurrentUser(function(user){$scope.currentUser=user}),requestService.getRequests($scope.requestType,!1,8,function(requests){$scope.requests=requests}),reviewService.getReviews($scope.requestType,6,function(reviews){$scope.reviews=reviews}),$scope.loadMore=function(){requestService.loadMore($scope.requestType)},$scope.isFirstReview=function(review){return 0==$scope.reviews.indexOf(review)}}]),devflowApp.controller("manageServersController",["$scope","serverService",function($scope,serverService){serverService.getServers(!1,function(envs){$scope.envs=envs}),$scope.addServer=function(env){env.servers.unshift(serverService.newServer(env.name))},$scope.deleteServer=function(env,server){env.servers.splice(env.servers.indexOf(server),1)},$scope.saveServers=function(){serverService.updateServers($scope.envs)}}]),devflowApp.controller("reposController",["$scope",function($scope){$scope.service={name:"repoService",fetchAllAction:"getRepos",updateAllAction:"updateRepos",newModel:"newRepo"},$scope.fields=[{key:"name",type:"text",name:"Name",placeholder:"New Repo",unique:!0},{key:"team_name",type:"text",name:"Team Name"},{key:"hipchat_group",type:"text",name:"Hipchat Group"},{key:"slack_group",type:"text",name:"Slack Tag"}]}]),devflowApp.controller("tagController",["$scope",function($scope){$scope.service={name:"tagService",fetchAllAction:"getTags",updateAllAction:"updateTags",newModel:"newTag"},$scope.fields=[{key:"name",type:"text",name:"Name",placeholder:"New Tag",unique:!0},{key:"owner",type:"text",name:"Owner"}]}]),devflowApp.directive("ngSrc",function(){return{link:function(scope,element,attrs){element.bind("error",function(){element.attr("src","../images/noimage.jpg")})}}}),devflowApp.directive("request",["userService","requestService","tagService","config","ngDialog",function(userService,requestService,tagService,config,ngDialog){return{restrict:"E",scope:{request:"=requestObject",currentUser:"=",isNew:"=",type:"="},templateUrl:"scripts/directives/request/view.html",controller:function($scope){var currentUser=$scope.currentUser,requestType=$scope.type||$scope.request.type,requestConfig=config.requests[requestType];$scope.smallLabels=requestConfig.useSmallLabels,$scope.rejectable=requestConfig.rejectable,$scope.showTeam=requestConfig.showTeam,$scope.getEnv=function(request){return requestService.getEnv(request)},$scope.getNumber=function(request){return requestService.getNumber(request)},$scope.getTeam=function(request){return requestService.getTeam(request)},$scope.canEdit=function(request){return requestService.canEdit(request,currentUser)},$scope.openEdit=function(request){var isNew=!1,requestInEdit=null;request?requestInEdit=JSON.parse(JSON.stringify(request)):(requestInEdit=requestService["new"](requestType,requestConfig.types[0],currentUser),isNew=!0),ngDialog.open({template:"/views/templates/popups/editRequest.html",controller:["$scope",function($scope){var typeRegex=new RegExp(requestConfig.linkRegex);$scope.request=requestInEdit,$scope.isNew=isNew,$scope.linkTitle=requestConfig.linkTitle,$scope.typeTitle=requestConfig.typeTitle,$scope.requestTypes=requestConfig.types,$scope.invalidFields={title:!1,desc:!1},$scope.shouldSquash=!1,$scope.mergeable=!0,tagService.getTags(function(tags){$scope.tags=tags});var validateRequest=function(request){return request.data.title&&typeRegex.test(request.data.title)?!request.data.desc||request.data.desc.length>378?($scope.invalidFields.desc=!0,!1):!0:($scope.invalidFields.title=!0,!1)};$scope.saveRequest=function(request){if(validateRequest(request)){if(requestService.createOrUpdate(request,currentUser,isNew),isNew&&$scope.additionalType){var secondRequest=JSON.parse(JSON.stringify(request));secondRequest.data.sub_type=$scope.additionalType,requestService.createOrUpdate(secondRequest,currentUser,!0)}$scope.closeThisDialog()}},$scope.fieldChanged=function(fieldName){$scope.invalidFields[fieldName]=!1},$scope.addAdditionalType=function(){$scope.additionalType||($scope.additionalTypes=$scope.requestTypes.slice(0),$scope.additionalTypes.splice($scope.additionalTypes.indexOf($scope.request.data.sub_type),1),$scope.additionalType=$scope.additionalTypes[0])},$scope.removeAdditionalType=function(){$scope.additionalType=null},$scope.titleBlur=function(url){url&&requestService.preCheck(url,function(response){response&&($scope.request.data.desc=response.description,$scope.shouldSquash=response.shouldSquash,$scope.mergeable=response.mergeable)})}}]})},$scope.isPosted=function(request){return requestService.isPosted(request)},$scope.wasRejected=function(request){return requestService.wasRejected(request)},$scope.nudge=function(request){requestService.nudge(request)},$scope.canComplete=function(request){return requestService.canComplete(request,currentUser)},$scope.release=function(request){requestService.release(request,currentUser)},$scope.getDisplayTitle=function(request){return request.data.title.length>50?request.data.title.substr(0,47)+"...":request.data.title},$scope.getDisplayDate=function(date){return new Date(date).toFormattedDateTimeString()},$scope.canTake=function(request){return requestService.canTake(request,currentUser)},$scope.take=function(request){requestService.take(request,currentUser)},$scope.isWaitingForReviewStart=function(request){return!requestService.canTake(request,currentUser)&&requestService.isPosted(request)},$scope.isWaitingForReviewEnd=function(request){return requestService.isTaken(request)&&!requestService.canComplete(request,currentUser)},$scope["delete"]=function(request){requestService["delete"](request)},$scope.hasReviewer=function(request){return requestService.isTaken(request)||requestService.isReviewed(request)},$scope.complete=function(request){requestService.complete(request)},$scope.reject=function(request){ngDialog.open({template:"/views/templates/popups/rejectionReasons.html",controller:["$scope",function($scope){request.rejection_reasons=[],$scope.request=request,$scope.reasons=requestConfig.rejectionReasons,$scope.reject=function(){requestService.complete(request,!0),$scope.closeThisDialog()},$scope.toggleRejectionReason=function(reason){var reasonIndex=$scope.request.rejection_reasons.indexOf(reason);reasonIndex>-1?$scope.request.rejection_reasons.splice(reasonIndex,1):$scope.request.rejection_reasons.push(reason)},$scope.isSelected=function(reason){return $scope.request.rejection_reasons.indexOf(reason)>-1}}]})},$scope.isReviewed=function(request){return requestService.isReviewed(request)}}}}]),devflowApp.directive("review",[function(){return{restrict:"E",scope:{review:"=reviewObject",isFirst:"=",index:"="},templateUrl:"scripts/directives/review/view.html",controller:function($scope){}}}]),devflowApp.directive("serverEnv",["userService","serverService","ngDialog",function(userService,serverService,ngDialog){return{restrict:"E",scope:{env:"=envObject",currentUser:"="},templateUrl:"scripts/directives/server-env/view.html",controller:function($scope){$scope.canJoinEnvQueue=function(env){return serverService.canJoinEnvQueue(env,currentUser)},$scope.isUserInQueue=function(env){return serverService.isUserInQueue(env.queue,currentUser)},$scope.joinQueue=function(env){serverService.joinQueue(env,currentUser,!0)},$scope.canAddServer=function(env){return env.on_demand&&serverService.canJoin(env,currentUser,!0)},$scope.unqueue=function(env){serverService.unqueue(env,currentUser,!0)},$scope.openCreate=function(env){ngDialog.open({template:"/views/templates/popups/createServer.html",controller:["$scope",function($scope){$scope.env=JSON.parse(JSON.stringify(env));var validateServer=function(env){return env.data.branchName?!0:($scope.invalidFields.branchName=!0,!1)};$scope.saveServer=function(env){validateServer(env)&&serverService.create(env.name,env.data.branchName,currentUser,env.data.customGems,env),$scope.closeThisDialog()}}]})}}}}]),devflowApp.directive("server",["userService","serverService","ngDialog",function(userService,serverService,ngDialog){return{restrict:"E",scope:{server:"=serverObject",currentUser:"="},templateUrl:"scripts/directives/server/view.html",controller:function($scope){$scope.isTaken=function(server){return serverService.isTaken(server)},$scope.canJoin=function(server){return serverService.canJoin(server,currentUser,!1)},$scope.canTakeDown=function(server){return serverService.allowedToTakeDown(server,currentUser)&&!serverService.isDown(server)},$scope.canTakeUp=function(server){return serverService.allowedToTakeDown(server,currentUser)&&serverService.isDown(server)},$scope.changeDownState=function(server,isDown){serverService.changeDownState(server,isDown)},$scope.showExtendForm=function(server){ngDialog.open({template:"/views/templates/popups/serverExtend.html",controller:["$scope",function($scope){$scope.server=server,$scope.time=1,$scope.timeInvalid=!1,$scope.extend=function(server){$scope.time>=1&&$scope.time<=12?(serverService.extend(server,$scope.time),$scope.closeThisDialog()):$scope.timeInvalid=!0},$scope.fieldChanged=function(){$scope.timeInvalid=!1}}]})},$scope.releaseTime=function(server){var releaseDate=new Date(server.release_date);return releaseDate.toFormattedShortDateTimeString()},$scope.isCurrentUser=function(server){return serverService.isTakenByUser(server,currentUser)},$scope.isOnDemand=function(server){return server.on_demand},$scope.take=function(server){serverService.take(server,currentUser),window.open(server.url,"_blank")},$scope.navigateToServer=function(server){window.open(server.server_url,"_blank")},$scope.navigateToDeploy=function(server){window.open(server.url,"_blank")},$scope.kill=function(server){serverService.kill(server,currentUser,!0)},$scope.release=function(server){serverService.release(server)},$scope.joinQueue=function(server){serverService.joinQueue(server,currentUser,!1)},$scope.isUserInQueue=function(server){ +var devflowApp=angular.module("devflowApp",["ngRoute","ngDialog","ngAnimate"]);devflowApp.config(["$routeProvider",function($routeProvider){$routeProvider.when("/main",{templateUrl:"views/templates/dashboard.html",controller:"dashboardController"}).when("/servers",{templateUrl:"views/templates/servers.html",controller:"serverController"}).when("/pullrequests",{templateUrl:"views/templates/requests.html",controller:"requestController"}).when("/graylogs",{templateUrl:"views/templates/requests.html",controller:"requestController"}).when("/manage-users",{templateUrl:"views/templates/manageUsers.html",controller:"usersController"}).when("/manage-servers",{templateUrl:"views/templates/manageServers.html",controller:"manageServersController"}).when("/manage-repos",{templateUrl:"views/templates/manageRepos.html",controller:"reposController"}).when("/manage-tags",{templateUrl:"views/templates/manageTags.html",controller:"tagController"}).otherwise({redirectTo:"/main"})}]),devflowApp.factory("socket",function($rootScope){var socket=io.connect();return{on:function(eventName,callback){socket.on(eventName,function(){var args=arguments;$rootScope.$apply(function(){callback.apply(socket,args)})})},emit:function(eventName,data,callback){socket.emit(eventName,data,function(){var args=arguments;$rootScope.$apply(function(){callback&&callback.apply(socket,args)})})}}}),String.prototype.lpad=function(padString,length){for(var str=this;str.length=0&&collection.splice(index,1)})},fetchRepos:function(){repos.length||repoService.getRepos(function(data){repos=data})}};return methods.initSockets(),methods.fetchRepos(),{getRequests:function(type,notTaken,count,onSuccess,onFailure,skipStore){var params={};notTaken&&(params.notTaken=!0),count&&(params.count=count),$http.get("/request/"+type,{params:params}).success(function(data,status,headers,config){"function"==typeof onSuccess&&(skipStore||(requests[type]=data),onSuccess(data))}).error(function(data,status,headers,config){"function"==typeof onFailure&&onFailure(data)})},allowedToReview:function(user){return"reviewer"==user.role||"admin"==user.role||"devops"==user.role},take:function(request,user){request.state="taken",request.sort_order=2,request.reviewer=methods.userData(user),request.taken_date=new Date,socket.emit("takeRequest",request)},getEnv:function(request){if(config.requests[request.type].constantEnv)return config.requests[request.type].constantEnv;if(request.data.title&&request.data.title.indexOf("http")>=0){var arr=request.data.title.split("/"),env=arr[arr.length-3];return env="pull"==env?arr[arr.length-4]:env,env.replace("_"," ")}return"Pull Request"},getNumber:function(request){if(!config.requests[request.type].hasNumber)return"";if(request.data.title&&request.data.title.indexOf("http")>=0){var arr=request.data.title.split("/"),pullNum=arr[arr.length-1];return"#"+("files"==pullNum?arr[arr.length-2]:pullNum)}return"Not Valid"},"new":function(type,defaultType,user){return user=methods.userData(user),{type:type,urgency:"high",state:"posted",data:{title:null,desc:null,sub_type:defaultType},user:user,sort_order:1,reviewer:null,created_date:null,taken_date:null,reviewed_date:null,rejected:!1,tag:null}},complete:function(request,rejected){request.state="reviewed",request.sort_order=3,request.reviewed_date=new Date,request.rejected=rejected?!0:!1,socket.emit("completeRequest",request)},isUserRequest:function(request,user){return request.user.email==user.email},isPosted:function(request){return"posted"==request.state},isTaken:function(request){return"taken"==request.state},isReviewed:function(request){return"reviewed"==request.state},wasRejected:function(request){return request.rejected},canEdit:function(request,user){return this.isUserRequest(request,user)&&"reviewed"!=request.state},canComplete:function(request,user){var selfTakable=config.requests[request.type].selfTakable;return"taken"==request.state&&request.reviewer.email==user.email&&this.allowedToReview(user)&&(request.user.email!=user.email||selfTakable)},canTake:function(request,user){var selfTakable=config.requests[request.type].selfTakable;return"posted"==request.state&&this.allowedToReview(user)&&(request.user.email!=user.email||selfTakable)},release:function(request){request.state="posted",request.reviewer=null,request.taken_date=null,request.sort_order=1,socket.emit("updateRequest",request)},nudge:methods.nudge,"delete":function(request){var collection=methods.getCollection(request);index=collection.indexOf(request),index>=0&&collection.splice(index,1),socket.emit("deleteRequest",request)},createOrUpdate:function(request,user,isNew){if(isNew)request.data.title.length>0&&(request.user=methods.userData(user),request.created_date=new Date,methods.getCollection(request).unshift(request),socket.emit("addRequest",request,function(newRequest){request._id=newRequest._id}));else{var realRequest=methods.find(request);realRequest&&methods.update(realRequest,request,!0)}},loadMore:function(type){this.getRequests(type,!1,requests[type].length+9,function(newRequests){for(var requestsToAdd=newRequests.slice(requests[type].length),i=0;i0?(nextUser=server.queue[0],server.queue.splice(0,1)):env.queue.length>0&&(nextUser=env.queue[0],env.queue.splice(0,1),unqueuEnv=!0),server.user=nextUser,server.taken_since=new Date,server.release_date=new Date,that.setReleaseDate(server,1)),socket.emit("releaseServer",server),unqueuEnv&&socket.emit("unqueueEnv",{env:env,user:methods.userData(nextUser)})},joinQueue:function(server,user,isEnv){user=methods.userData(user),server.queue.push(user),isEnv?socket.emit("queueEnv",{env:server,user:user}):socket.emit("queueServer",{server:server,user:user})},unqueue:function(server,user,isEnv){user=methods.userData(user),this.removeUserFromQueue(server.queue,user),isEnv?socket.emit("unqueueEnv",{env:server,user:user}):socket.emit("unqueueServer",{server:server,user:user})},changeDownState:function(server,isDown){server.is_down=isDown,this.release(server),socket.emit("changeServerDownState",server)},isTaken:function(server){return"undefined"!=typeof server.user&&null!==server.user},isDown:function(server){return server.is_down},isTakenByUser:function(server,user){return server.user&&server.user.email==user.email},allowedToTakeDown:function(server,user){return("admin"==user.role||"devops"==user.role)&&!server.on_demand},canJoin:function(server,user,isEnv){var that=this,env=isEnv?server:methods.findEnvByName(server.environment);if(that.isDown(server)||that.isUserInQueue(env.queue,user)||server.on_demand&&!isEnv)return!1;for(var serverIndex=0;serverIndex=3};$scope.fields=[{key:"image",type:"image",name:"Photo",viewClass:"user-image"},{key:"name",type:"text",name:"Name",placeholder:"New User",unique:!0,validator:nameValidator},{key:"id",type:"readonly",name:"Google ID"},{key:"email",type:"text",name:"Email",unique:!0,validator:emailValidator},{key:"image",type:"text",name:"Image"},{key:"associated",type:"checkbox",name:"Associated?"},{key:"role",type:"text",name:"Role"}]}]),devflowApp.controller("requestController",["$scope","userService","requestService","reviewService",function($scope,userService,requestService,reviewService){$scope.requestType=window.location.hash.replace("#/","").slice(0,-1),userService.getCurrentUser(function(user){$scope.currentUser=user}),requestService.getRequests($scope.requestType,!1,8,function(requests){$scope.requests=requests}),reviewService.getReviews($scope.requestType,6,function(reviews){$scope.reviews=reviews}),$scope.loadMore=function(){requestService.loadMore($scope.requestType)},$scope.isFirstReview=function(review){return 0==$scope.reviews.indexOf(review)}}]),devflowApp.controller("manageServersController",["$scope","serverService",function($scope,serverService){serverService.getServers(!1,function(envs){$scope.envs=envs}),$scope.addServer=function(env){env.servers.unshift(serverService.newServer(env.name))},$scope.deleteServer=function(env,server){env.servers.splice(env.servers.indexOf(server),1)},$scope.saveServers=function(){serverService.updateServers($scope.envs)}}]),devflowApp.controller("reposController",["$scope",function($scope){$scope.service={name:"repoService",fetchAllAction:"getRepos",updateAllAction:"updateRepos",newModel:"newRepo"},$scope.fields=[{key:"name",type:"text",name:"Name",placeholder:"New Repo",unique:!0},{key:"team_name",type:"text",name:"Team Name"},{key:"hipchat_group",type:"text",name:"Hipchat Group"},{key:"slack_group",type:"text",name:"Slack Tag"}]}]),devflowApp.controller("tagController",["$scope",function($scope){$scope.service={name:"tagService",fetchAllAction:"getTags",updateAllAction:"updateTags",newModel:"newTag"},$scope.fields=[{key:"name",type:"text",name:"Name",placeholder:"New Tag",unique:!0},{key:"owner",type:"text",name:"Owner"}]}]),devflowApp.directive("ngSrc",function(){return{link:function(scope,element,attrs){element.bind("error",function(){element.attr("src","../images/noimage.jpg")})}}}),devflowApp.directive("request",["userService","requestService","tagService","config","ngDialog",function(userService,requestService,tagService,config,ngDialog){return{restrict:"E",scope:{request:"=requestObject",currentUser:"=",isNew:"=",type:"="},templateUrl:"scripts/directives/request/view.html",controller:function($scope){var currentUser=$scope.currentUser,requestType=$scope.type||$scope.request.type,requestConfig=config.requests[requestType];$scope.smallLabels=requestConfig.useSmallLabels,$scope.rejectable=requestConfig.rejectable,$scope.showTeam=requestConfig.showTeam,$scope.getEnv=function(request){return requestService.getEnv(request)},$scope.getNumber=function(request){return requestService.getNumber(request)},$scope.getTeam=function(request){return requestService.getTeam(request)},$scope.canEdit=function(request){return requestService.canEdit(request,currentUser)},$scope.openEdit=function(request){var isNew=!1,requestInEdit=null;request?requestInEdit=JSON.parse(JSON.stringify(request)):(requestInEdit=requestService["new"](requestType,requestConfig.types[0],currentUser),isNew=!0),ngDialog.open({template:"/views/templates/popups/editRequest.html",controller:["$scope",function($scope){var typeRegex=new RegExp(requestConfig.linkRegex);$scope.request=requestInEdit,$scope.isNew=isNew,$scope.linkTitle=requestConfig.linkTitle,$scope.typeTitle=requestConfig.typeTitle,$scope.requestTypes=requestConfig.types,$scope.invalidFields={title:!1,desc:!1},$scope.shouldSquash=!1,$scope.mergeable=!0,tagService.getTags(function(tags){$scope.tags=tags});var validateRequest=function(request){return request.data.title&&typeRegex.test(request.data.title)?!request.data.desc||request.data.desc.length>378?($scope.invalidFields.desc=!0,!1):!0:($scope.invalidFields.title=!0,!1)};$scope.saveRequest=function(request){if(validateRequest(request)){if(requestService.createOrUpdate(request,currentUser,isNew),isNew&&$scope.additionalType){var secondRequest=JSON.parse(JSON.stringify(request));secondRequest.data.sub_type=$scope.additionalType,requestService.createOrUpdate(secondRequest,currentUser,!0)}$scope.closeThisDialog()}},$scope.fieldChanged=function(fieldName){$scope.invalidFields[fieldName]=!1},$scope.addAdditionalType=function(){$scope.additionalType||($scope.additionalTypes=$scope.requestTypes.slice(0),$scope.additionalTypes.splice($scope.additionalTypes.indexOf($scope.request.data.sub_type),1),$scope.additionalType=$scope.additionalTypes[0])},$scope.removeAdditionalType=function(){$scope.additionalType=null},$scope.titleBlur=function(url){url&&requestService.preCheck(url,function(response){response&&($scope.request.data.desc=response.description,$scope.shouldSquash=response.shouldSquash,$scope.mergeable=response.mergeable)})}}]})},$scope.isPosted=function(request){return requestService.isPosted(request)},$scope.wasRejected=function(request){return requestService.wasRejected(request)},$scope.nudge=function(request){requestService.nudge(request)},$scope.canComplete=function(request){return requestService.canComplete(request,currentUser)},$scope.release=function(request){requestService.release(request,currentUser)},$scope.getDisplayTitle=function(request){return request.data.title.length>50?request.data.title.substr(0,47)+"...":request.data.title},$scope.getDisplayDate=function(date){return new Date(date).toFormattedDateTimeString()},$scope.canTake=function(request){return requestService.canTake(request,currentUser)},$scope.take=function(request){requestService.take(request,currentUser)},$scope.isWaitingForReviewStart=function(request){return!requestService.canTake(request,currentUser)&&requestService.isPosted(request)},$scope.isWaitingForReviewEnd=function(request){return requestService.isTaken(request)&&!requestService.canComplete(request,currentUser)},$scope["delete"]=function(request){requestService["delete"](request)},$scope.hasReviewer=function(request){return requestService.isTaken(request)||requestService.isReviewed(request)},$scope.complete=function(request){requestService.complete(request)},$scope.reject=function(request){ngDialog.open({template:"/views/templates/popups/rejectionReasons.html",controller:["$scope",function($scope){request.rejection_reasons=[],$scope.request=request,$scope.reasons=requestConfig.rejectionReasons,$scope.reject=function(){requestService.complete(request,!0),$scope.closeThisDialog()},$scope.toggleRejectionReason=function(reason){var reasonIndex=$scope.request.rejection_reasons.indexOf(reason);reasonIndex>-1?$scope.request.rejection_reasons.splice(reasonIndex,1):$scope.request.rejection_reasons.push(reason)},$scope.isSelected=function(reason){return $scope.request.rejection_reasons.indexOf(reason)>-1}}]})},$scope.isReviewed=function(request){return requestService.isReviewed(request)}}}}]),devflowApp.directive("review",[function(){return{restrict:"E",scope:{review:"=reviewObject",isFirst:"=",index:"="},templateUrl:"scripts/directives/review/view.html",controller:function($scope){}}}]),devflowApp.directive("serverEnv",["userService","serverService","ngDialog",function(userService,serverService,ngDialog){return{restrict:"E",scope:{env:"=envObject",currentUser:"="},templateUrl:"scripts/directives/server-env/view.html",controller:function($scope){$scope.canJoinEnvQueue=function(env){return serverService.canJoinEnvQueue(env,currentUser)},$scope.isUserInQueue=function(env){return serverService.isUserInQueue(env.queue,currentUser)},$scope.joinQueue=function(env){serverService.joinQueue(env,currentUser,!0)},$scope.canAddServer=function(env){return env.on_demand&&serverService.canJoin(env,currentUser,!0)},$scope.unqueue=function(env){serverService.unqueue(env,currentUser,!0)},$scope.openCreate=function(env){ngDialog.open({template:"/views/templates/popups/createServer.html",controller:["$scope",function($scope){$scope.env=JSON.parse(JSON.stringify(env));var validateServer=function(env){return env.data.branchName?!0:($scope.invalidFields.branchName=!0,!1)};$scope.saveServer=function(env){validateServer(env)&&serverService.create(env.name,env.data.branchName,currentUser,env.data.customGems,env),$scope.closeThisDialog()}}]})}}}}]),devflowApp.directive("server",["userService","serverService","ngDialog",function(userService,serverService,ngDialog){return{restrict:"E",scope:{server:"=serverObject",currentUser:"="},templateUrl:"scripts/directives/server/view.html",controller:function($scope){$scope.isTaken=function(server){return serverService.isTaken(server)},$scope.canJoin=function(server){return serverService.canJoin(server,currentUser,!1)},$scope.canTakeDown=function(server){return serverService.allowedToTakeDown(server,currentUser)&&!serverService.isDown(server)},$scope.canTakeUp=function(server){return serverService.allowedToTakeDown(server,currentUser)&&serverService.isDown(server)},$scope.changeDownState=function(server,isDown){serverService.changeDownState(server,isDown)},$scope.showExtendForm=function(server){ngDialog.open({template:"/views/templates/popups/serverExtend.html",controller:["$scope",function($scope){$scope.server=server,$scope.time=1,$scope.timeInvalid=!1,$scope.extend=function(server){$scope.time>=1&&$scope.time<=12?(serverService.extend(server,$scope.time),$scope.closeThisDialog()):$scope.timeInvalid=!0},$scope.fieldChanged=function(){$scope.timeInvalid=!1}}]})},$scope.releaseTime=function(server){var releaseDate=new Date(server.release_date);return releaseDate.toFormattedShortDateTimeString()},$scope.isCurrentUser=function(server){return serverService.isTakenByUser(server,currentUser)},$scope.isOnDemand=function(server){return server.on_demand},$scope.take=function(server){serverService.take(server,currentUser),window.open(server.url,"_blank")},$scope.navigateToServer=function(server){window.open(server.server_url,"_blank")},$scope.navigateToDeploy=function(server){window.open(server.url,"_blank")},$scope.kill=function(server){serverService.kill(server,currentUser,!0)},$scope.release=function(server){serverService.release(server)},$scope.joinQueue=function(server){serverService.joinQueue(server,currentUser,!1)},$scope.isUserInQueue=function(server){ return serverService.isUserInQueue(server.queue,currentUser)},$scope.unqueue=function(server){serverService.unqueue(server,currentUser,!1)},$scope.getState=function(server){return serverService.isDown(server)?"down":serverService.isTaken(server)?"taken":"free"}}}}]),devflowApp.directive("modelManager",["$injector",function($injector){return{restrict:"E",scope:{caption:"=",service:"=",fields:"="},templateUrl:"scripts/directives/model-manager/view.html",controller:function($scope){var service=$injector.get($scope.service.name);service[$scope.service.fetchAllAction](function(models){$scope.models=models}),$scope.invalidFields=[],$scope.saving=!1;var validateModels=function(){for(var fieldCounts={},setInvalid=function(i,fieldName){$scope.invalidFields[i]={},$scope.invalidFields[i][fieldName]=!0},i=0;i<$scope.models.length;i++)for(var model=$scope.models[i],fieldIndex=0;fieldIndex<$scope.fields.length;fieldIndex++){var field=$scope.fields[fieldIndex],fieldValue=model[field.key];if(field.unique&&(fieldCounts[fieldValue]||(fieldCounts[fieldValue]=0),fieldCounts[fieldValue]++,fieldCounts[fieldValue]>1))return setInvalid($scope.models[0][field.key]==fieldValue?0:i,field.key),!1;if(field.validator&&!field.validator(fieldValue))return setInvalid(i,field.key),!1}return!0};$scope.addModel=function(){$scope.models.unshift(service[$scope.service.newModel]())},$scope.deleteModel=function(model){var modelIndex=$scope.models.indexOf(model);$scope.invalidFields.length&&$scope.invalidFields[modelIndex]&&$scope.invalidFields.splice(modelIndex,1),$scope.models.splice(modelIndex,1)},$scope.saveModels=function(){validateModels()&&($scope.saving=!0,service[$scope.service.updateAllAction]($scope.models,function(){$scope.saving=!1}))},$scope.fieldChanged=function(model,fieldName){$scope.invalidFields.length&&$scope.invalidFields[$scope.models.indexOf(model)]&&($scope.invalidFields[$scope.models.indexOf(model)][fieldName]=!1)},$scope.isInvalid=function(model,fieldName){return $scope.invalidFields.length&&$scope.invalidFields[$scope.models.indexOf(model)]?$scope.invalidFields[$scope.models.indexOf(model)][fieldName]:!1}}}}]),devflowApp.directive("inputDropdown",["$timeout",function($timeout){return{restrict:"E",scope:{items:"=",selectedItem:"=",displayProperty:"=",label:"="},templateUrl:"scripts/directives/input-dropdown/view.html",controller:function($scope){$scope.displayItems=[],$scope.inputFocused=!1,$scope.focusedIndex=-1;var setSelectedText=function(){$scope.selectedText=$scope.selectedItem[$scope.displayProperty]};$scope.selectedItem&&setSelectedText(),$scope.selectItem=function(item){$scope.selectedItem=item,setSelectedText(),$scope.displayItems=[],$scope.focusedIndex=-1},$scope.itemTextChanged=function(){if($scope.selectedItem=null,$scope.displayItems=[],$scope.focusedIndex=-1,$scope.selectedText&&""!=$scope.selectedText)for(i=0;i<$scope.items.length;i++)$scope.items[i][$scope.displayProperty].toLowerCase().indexOf($scope.selectedText.toLowerCase())>=0&&$scope.displayItems.push($scope.items[i])},$scope.inputBlur=function(){$timeout(function(){$scope.inputFocused=!1,$scope.focusedIndex=-1},100)},$scope.inputFocus=function(){$scope.inputFocused=!0},$scope.keyDown=function(keyEvent){$scope.displayItems.length>0&&$scope.selectedText.length>0&&$scope.inputFocused&&(40==keyEvent.keyCode&&$scope.focusedIndex<$scope.displayItems.length-1?$scope.focusedIndex++:38==keyEvent.keyCode&&$scope.focusedIndex>0?$scope.focusedIndex--:13==keyEvent.keyCode&&$scope.selectItem($scope.displayItems[$scope.focusedIndex]))},$scope.isFocused=function(item){return $scope.focusedIndex==$scope.displayItems.indexOf(item)}}}}]); \ No newline at end of file diff --git a/routes.js b/routes.js index b1480ac..61aa66f 100644 --- a/routes.js +++ b/routes.js @@ -24,12 +24,13 @@ module.exports = function(app) { app.get('/users/currentUser', user.getCurrentUser); app.post('/users/currentUser', user.updateCurrentUser); + app.get('/server/rest/all', server.rest.all); app.post('/server/rest/take', server.rest.take); app.post('/server/rest/release', server.rest.release); app.post('/server/rest/queue', server.rest.queue); app.post('/server/rest/unqueue', server.rest.unqueue); app.post('/server/rest/extend', server.rest.extend); - + app.get('/repos', repo.getAll); app.post('/repos', repo.saveAll); From 3b961f1883c7a98341cde3fb39a5e70b8abd33fd Mon Sep 17 00:00:00 2001 From: Roee Poleg Date: Thu, 17 Mar 2016 21:14:31 +0200 Subject: [PATCH 2/5] return 500 on error --- controllers/serverController.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/controllers/serverController.js b/controllers/serverController.js index 6cf925d..f6c8c62 100644 --- a/controllers/serverController.js +++ b/controllers/serverController.js @@ -309,7 +309,11 @@ module.exports = { res.json(serverEnvs[0]); - } else { throw err; } + } else { + + res.send(500); + + } }); } catch (err) { res.send(500); } From c28b81b2aef734e97556892d5a4c30b9ab3f6593 Mon Sep 17 00:00:00 2001 From: Roee Poleg Date: Tue, 29 Mar 2016 22:44:20 +0300 Subject: [PATCH 3/5] Adding guard code to prevent server crashes --- controllers/serverController.js | 188 ++++++++++++++++++++++++-------- models/serverEnvironment.js | 7 +- 2 files changed, 149 insertions(+), 46 deletions(-) diff --git a/controllers/serverController.js b/controllers/serverController.js index f6c8c62..cc8aad4 100644 --- a/controllers/serverController.js +++ b/controllers/serverController.js @@ -149,11 +149,18 @@ module.exports = { ServerEnv.findOne({name: data.environment}, function(err, env) { if (err) { throw err; } - env.take(data.name, data.user, data.release_date); - saveServerEnv(env); - notifier.sendMessage('server', data.user.name, getNotifierMsg(data, 'took'), 'red'); + try { + + env.take(data.name, data.user, data.release_date); + saveServerEnv(env); + notifier.sendMessage('server', data.user.name, getNotifierMsg(data, 'took'), 'red'); + + if (callback) { callback(env); } + + } catch (exp) { + if (callback) { callback(null, exp); } + } - if (callback) { callback(env); } }); }, @@ -161,10 +168,17 @@ module.exports = { ServerEnv.findOne({name: data.environment}, function(err, env) { if (err) { throw err; } - env.setReleaseDate(data.name, new Date(data.release_date)); - saveServerEnv(env); + try { + + env.setReleaseDate(data.name, new Date(data.release_date)); + saveServerEnv(env); + + if (callback) { callback(env); } + + } catch (exp) { + if (callback) { callback(null, exp); } + } - if (callback) { callback(env); } }); }, @@ -172,23 +186,30 @@ module.exports = { ServerEnv.findOne({name: data.environment}, function(err, env) { if (err) { throw err; } - var server = env.release(data.name).toObject(); - saveServerEnv(env); + try { + + var server = env.release(data.name).toObject(); + saveServerEnv(env); - notifier.sendMessage('server', "Devflow", server.name + " released", "green"); + notifier.sendMessage('server', "Devflow", server.name + " released", "green"); - if (server.user) { - mailer.sendMail(server.user.email, - server.name + ' is finally free for you', - 'Hi ' + server.user.name + ',


' + - 'Finally,

' + - '' + server.name + ' is FREE, and you are next in line...



' + - 'The server has been marked as taken by you automatically :)'); + if (server.user) { + mailer.sendMail(server.user.email, + server.name + ' is finally free for you', + 'Hi ' + server.user.name + ',


' + + 'Finally,

' + + '' + server.name + ' is FREE, and you are next in line...



' + + 'The server has been marked as taken by you automatically :)'); + + notifier.sendMessage('server', server.user.name, getNotifierMsg(server, 'took by queue'), 'red'); + } - notifier.sendMessage('server', server.user.name, getNotifierMsg(server, 'took by queue'), 'red'); + if (callback) { callback({env: env, server: server}); } + + } catch (exp) { + if (callback) { callback(null, exp); } } - if (callback) { callback({env: env, server: server}); } }); }, @@ -196,12 +217,19 @@ module.exports = { ServerEnv.findOne({name: data.server.environment}, function(err, env) { if (err) { throw err; } - env.queueServer(data.server.name, data.user); - saveServerEnv(env); + try { - notifier.sendMessage('server', data.user.name, getNotifierMsg(data.server, 'queued in'), 'yellow'); + env.queueServer(data.server.name, data.user); + saveServerEnv(env); + + notifier.sendMessage('server', data.user.name, getNotifierMsg(data.server, 'queued in'), 'yellow'); + + if (callback) { callback(env); } + + } catch (exp) { + if (callback) { callback(null, exp); } + } - if (callback) { callback(env); } }); }, @@ -209,12 +237,19 @@ module.exports = { ServerEnv.findOne({name: data.server.environment}, function(err, env) { if (err) { throw err; } - env.unqueueServer(data.server.name, data.user); - saveServerEnv(env); + try { - notifier.sendMessage('server', data.user.name, getNotifierMsg(data.server, 'unqueued in'), 'green'); + env.unqueueServer(data.server.name, data.user); + saveServerEnv(env); + + notifier.sendMessage('server', data.user.name, getNotifierMsg(data.server, 'unqueued in'), 'green'); + + if (callback) { callback(env); } + + } catch (exp) { + if (callback) { callback(null, exp); } + } - if (callback) { callback(env); } }); }, @@ -222,12 +257,19 @@ module.exports = { ServerEnv.findOne({_id: data.env._id}, function(err, env) { if (err) { throw err; } - env.queueEnv(data.user); - saveServerEnv(env); + try { - notifier.sendMessage('server', data.user.name, getNotifierMsg(data.env, 'queued in ENV: '), 'red'); + env.queueEnv(data.user); + saveServerEnv(env); + + notifier.sendMessage('server', data.user.name, getNotifierMsg(data.env, 'queued in ENV: '), 'red'); + + if (callback) { callback(env); } + + } catch (exp) { + if (callback) { callback(null, exp); } + } - if (callback) { callback(env); } }); }, @@ -235,12 +277,19 @@ module.exports = { ServerEnv.findOne({_id: data.env._id}, function(err, env) { if (err) { throw err; } - env.unqueueEnv(data.user); - saveServerEnv(env); + try { - notifier.sendMessage('server', data.user.name, getNotifierMsg(data.env, 'unqueued in ENV: '), 'green'); + env.unqueueEnv(data.user); + saveServerEnv(env); + + notifier.sendMessage('server', data.user.name, getNotifierMsg(data.env, 'unqueued in ENV: '), 'green'); + + if (callback) { callback(env); } + + } catch (exp) { + if (callback) { callback(null, exp); } + } - if (callback) { callback(env); } }); }, @@ -321,45 +370,94 @@ module.exports = { take: function (req, res) { try { - module.exports.take(req.body, function(env) { + module.exports.take(req.body, function(env, err) { + + if (err) { + res.send(500, {error: err.toString()}); + return; + } + + if (!env) { + res.send(500, { error: "Environment not found!" }); + return; + } // Extract and return just the requested server! var srv = findServerByName(req.body.name, env.servers) res.json(srv); }); - } catch (err) { res.send(500); } + } catch (err) { res.send(500, {error: err.toString()}); } }, extend: function (req, res) { try { - module.exports.extend(req.body, function(env) { + module.exports.extend(req.body, function(env, err) { + + if (err) { + res.send(500, {error: err.toString()}); + return; + } + + if (!env) { + res.send(500, { error: "Environment not found!" }); + return; + } + // Extract and return just the requested server! var srv = findServerByName(req.body.name, env.servers) res.json(srv); }); - } catch (err) { res.send(500); } + } catch (err) { res.send(500, {error: err.toString()}); } }, release: function(req, res) { try { - module.exports.release(req.body, function(env) { res.json(env); }); - } catch (err) { res.send(500); } + module.exports.release(req.body, function(env, err) { + + if (err) { + res.send(500, {error: err.toString()}); + return; + } + + res.json(env); + + }); + } catch (err) { res.send(500, {error: err.toString()}); } }, queue: function(req, res) { try { - module.exports.queue(req.body, function(env) { + module.exports.queue(req.body, function(env, err) { + + if (err) { + res.send(500, {error: err.toString()}); + return; + } + + if (!env) { + res.send(500, { error: "Environment not found!" }); + return; + } + // Extract and return just the requested server! var srv = findServerByName(req.body.name, env.servers) res.json(srv); }); - } catch (err) { res.send(500); } + } catch (err) { res.send(500, {error: err.toString()}); } }, unqueue: function(req, res) { try { - module.exports.unqueue(req.body, function(env) { res.json(env); }); - } catch (err) { res.send(500); } + module.exports.unqueue(req.body, function(env) { + + if (err) { + res.send(500, {error: err.toString()}); + return; + } + + res.json(env); + }); + } catch (err) { res.send(500, {error: err.toString()}); } } } } diff --git a/models/serverEnvironment.js b/models/serverEnvironment.js index dae9c57..9a27154 100644 --- a/models/serverEnvironment.js +++ b/models/serverEnvironment.js @@ -91,7 +91,12 @@ var environmentSchema = new mongoose.Schema({ }); environmentSchema.methods.take = function(serverName, user, releaseDate) { - findServerbyName(this, serverName).take(getUserDetails(user), releaseDate); + var srv = findServerbyName(this, serverName); + if (srv == null){ + return (null); + } + + srv.take(getUserDetails(user), releaseDate); } environmentSchema.methods.setReleaseDate = function(serverName, date) { From eeae31bd76561f6946bbaa26abf64e83dc2d9077 Mon Sep 17 00:00:00 2001 From: Roee Poleg Date: Wed, 30 Mar 2016 16:02:09 +0300 Subject: [PATCH 4/5] refine error handling --- app.js | 8 +- controllers/serverController.js | 245 ++++++++++++++++++-------------- 2 files changed, 139 insertions(+), 114 deletions(-) diff --git a/app.js b/app.js index 018eaa6..119063b 100644 --- a/app.js +++ b/app.js @@ -49,14 +49,12 @@ app.use( app.use(express.static(path.join(__dirname, 'public'))); -// development only error handling -if (env == 'development') { - app.use(express.errorHandler()); -} - // setup routes require('./routes')(app); +// Must be after all the routes to catch errors. +app.use(express.errorHandler); + // Init server var nodeServer = http.createServer(app); diff --git a/controllers/serverController.js b/controllers/serverController.js index cc8aad4..f51d028 100644 --- a/controllers/serverController.js +++ b/controllers/serverController.js @@ -146,11 +146,13 @@ module.exports = { }, take: function (data, callback) { + ServerEnv.findOne({name: data.environment}, function(err, env) { - if (err) { throw err; } try { + if (err) { throw err; } + env.take(data.name, data.user, data.release_date); saveServerEnv(env); notifier.sendMessage('server', data.user.name, getNotifierMsg(data, 'took'), 'red'); @@ -158,7 +160,9 @@ module.exports = { if (callback) { callback(env); } } catch (exp) { - if (callback) { callback(null, exp); } + + if (callback) { callback(null, exp); } + } }); @@ -166,17 +170,19 @@ module.exports = { extend : function(data, callback) { ServerEnv.findOne({name: data.environment}, function(err, env) { - if (err) { throw err; } - try { + if (err) { throw err; } + env.setReleaseDate(data.name, new Date(data.release_date)); saveServerEnv(env); if (callback) { callback(env); } } catch (exp) { + if (callback) { callback(null, exp); } + } }); @@ -184,10 +190,10 @@ module.exports = { release: function (data, callback) { ServerEnv.findOne({name: data.environment}, function(err, env) { - if (err) { throw err; } - try { + if (err) { throw err; } + var server = env.release(data.name).toObject(); saveServerEnv(env); @@ -207,7 +213,9 @@ module.exports = { if (callback) { callback({env: env, server: server}); } } catch (exp) { + if (callback) { callback(null, exp); } + } }); @@ -215,10 +223,10 @@ module.exports = { queue: function (data, callback) { ServerEnv.findOne({name: data.server.environment}, function(err, env) { - if (err) { throw err; } - try { + if (err) { throw err; } + env.queueServer(data.server.name, data.user); saveServerEnv(env); @@ -227,7 +235,9 @@ module.exports = { if (callback) { callback(env); } } catch (exp) { + if (callback) { callback(null, exp); } + } }); @@ -235,10 +245,10 @@ module.exports = { unqueue: function(data, callback) { ServerEnv.findOne({name: data.server.environment}, function(err, env) { - if (err) { throw err; } - try { + if (err) { throw err; } + env.unqueueServer(data.server.name, data.user); saveServerEnv(env); @@ -247,7 +257,9 @@ module.exports = { if (callback) { callback(env); } } catch (exp) { + if (callback) { callback(null, exp); } + } }); @@ -255,10 +267,10 @@ module.exports = { queueEnv: function(data, callback) { ServerEnv.findOne({_id: data.env._id}, function(err, env) { - if (err) { throw err; } - try { + if (err) { throw err; } + env.queueEnv(data.user); saveServerEnv(env); @@ -267,7 +279,9 @@ module.exports = { if (callback) { callback(env); } } catch (exp) { + if (callback) { callback(null, exp); } + } }); @@ -275,10 +289,10 @@ module.exports = { unqueueEnv: function(data, callback) { ServerEnv.findOne({_id: data.env._id}, function(err, env) { - if (err) { throw err; } - try { + if (err) { throw err; } + env.unqueueEnv(data.user); saveServerEnv(env); @@ -287,7 +301,9 @@ module.exports = { if (callback) { callback(env); } } catch (exp) { + if (callback) { callback(null, exp); } + } }); @@ -310,154 +326,165 @@ module.exports = { // On-demand create: function (data, callback) { ServerEnv.findOne({name: data.environment}, function(err, env) { - if (err) { throw err; } + try { - var options = { - uri: config.pod.url, - method: 'POST', - json: { "branch_name": data.branch_name } - }; + if (err) { throw err; } - request(options, function (error, response, body) { + var options = { + uri: config.pod.url, + method: 'POST', + json: { "branch_name": data.branch_name } + }; - if (error) { throw error; } + request(options, function (error, response, body) { - var srv = env.create(body.instance_id, data.user, data.release_date, body.deploy_url, body.server_url, data.custom_gemset); - saveServerEnv(env); + if (error) { throw error; } - if (callback) { callback(srv); } - }); + var srv = env.create(body.instance_id, data.user, data.release_date, body.deploy_url, body.server_url, data.custom_gemset); + saveServerEnv(env); + + if (callback) { callback(srv); } + }); + + } catch (exp) { + + if (callback) { callback(null, exp); } + + } }); }, kill: function (data, callback) { - ServerEnv.findOne({name: data.environment}, function(err, env) { - if (err) { throw err; } - request.del(config.pod.url + '/' + data.name, function (error, response, body) { - if (error) { throw error; } + try { + + ServerEnv.findOne({name: data.environment}, function(err, env) { + if (err) { throw err; } + + request.del(config.pod.url + '/' + data.name, function (error, response, body) { + if (error) { throw error; } + }); + + var srv = env.kill(data.name); + saveServerEnv(env); + + if (callback) { callback(srv); } }); + } catch (exp) { - var srv = env.kill(data.name); - saveServerEnv(env); + if (callback) { callback(null, exp); } - if (callback) { callback(srv); } - }); + } }, rest: { all: function (req, res) { +throw new Error(); + var query = ServerEnv.find({name: req.query.environment}).sort('order'); - try { - - var query = ServerEnv.find({name: req.query.environment}).sort('order'); - - query.exec(function(err, serverEnvs) { + query.exec(function(err, serverEnvs) { - if (!err) { + try { - res.json(serverEnvs[0]); + res.json(serverEnvs[0]); - } else { + } catch (exp) { - res.send(500); + res.send(500, {error: exp.toString()}); - } - }); + } + }); - } catch (err) { res.send(500); } }, take: function (req, res) { - try { - module.exports.take(req.body, function(env, err) { - if (err) { - res.send(500, {error: err.toString()}); - return; - } + module.exports.take(req.body, function(env, err) { - if (!env) { - res.send(500, { error: "Environment not found!" }); - return; - } + if (err) { + res.send(500, {error: err.toString()}); + return; + } - // Extract and return just the requested server! - var srv = findServerByName(req.body.name, env.servers) - res.json(srv); - }); - } catch (err) { res.send(500, {error: err.toString()}); } + if (!env) { + res.send(500, { error: "Environment not found!" }); + return; + } + + // Extract and return just the requested server! + var srv = findServerByName(req.body.name, env.servers) + res.json(srv); + }); }, extend: function (req, res) { - try { - module.exports.extend(req.body, function(env, err) { - if (err) { - res.send(500, {error: err.toString()}); - return; - } + module.exports.extend(req.body, function(env, err) { - if (!env) { - res.send(500, { error: "Environment not found!" }); - return; - } + if (err) { + res.send(500, {error: err.toString()}); + return; + } - // Extract and return just the requested server! - var srv = findServerByName(req.body.name, env.servers) - res.json(srv); - }); - } catch (err) { res.send(500, {error: err.toString()}); } + if (!env) { + res.send(500, { error: "Environment not found!" }); + return; + } + + // Extract and return just the requested server! + var srv = findServerByName(req.body.name, env.servers) + res.json(srv); + }); }, release: function(req, res) { - try { - module.exports.release(req.body, function(env, err) { - if (err) { - res.send(500, {error: err.toString()}); - return; - } + module.exports.release(req.body, function(env, err) { - res.json(env); + if (err) { + res.send(500, {error: err.toString()}); + return; + } + + res.json(env); + + }); - }); - } catch (err) { res.send(500, {error: err.toString()}); } }, queue: function(req, res) { - try { - module.exports.queue(req.body, function(env, err) { - if (err) { - res.send(500, {error: err.toString()}); - return; - } + module.exports.queue(req.body, function(env, err) { - if (!env) { - res.send(500, { error: "Environment not found!" }); - return; - } + if (err) { + res.send(500, {error: err.toString()}); + return; + } + + if (!env) { + res.send(500, { error: "Environment not found!" }); + return; + } + + // Extract and return just the requested server! + var srv = findServerByName(req.body.name, env.servers) + res.json(srv); + }); - // Extract and return just the requested server! - var srv = findServerByName(req.body.name, env.servers) - res.json(srv); - }); - } catch (err) { res.send(500, {error: err.toString()}); } }, unqueue: function(req, res) { - try { - module.exports.unqueue(req.body, function(env) { - if (err) { - res.send(500, {error: err.toString()}); - return; - } + module.exports.unqueue(req.body, function(env) { + + if (err) { + res.send(500, {error: err.toString()}); + return; + } + + res.json(env); + }); - res.json(env); - }); - } catch (err) { res.send(500, {error: err.toString()}); } } } } From ee5daf5deb3065914a42779ec34682fc4c62a4a3 Mon Sep 17 00:00:00 2001 From: Roee Poleg Date: Wed, 30 Mar 2016 16:54:49 +0300 Subject: [PATCH 5/5] remove debug code --- controllers/serverController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/serverController.js b/controllers/serverController.js index f51d028..3ab8279 100644 --- a/controllers/serverController.js +++ b/controllers/serverController.js @@ -379,7 +379,7 @@ module.exports = { rest: { all: function (req, res) { -throw new Error(); + var query = ServerEnv.find({name: req.query.environment}).sort('order'); query.exec(function(err, serverEnvs) {