Skip to content

Commit

Permalink
Merge pull request rundeck#1825 from gschueler/issue/1508
Browse files Browse the repository at this point in the history
fix rundeck#1508 retry failed nodes with dynamic filter and spaces in node name
  • Loading branch information
gschueler committed Apr 25, 2016
2 parents e687b43 + dd5355d commit 426c8b1
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.dtolabs.rundeck.core.authorization.UserAndRolesAuthContext
import com.dtolabs.rundeck.core.common.Framework
import com.dtolabs.rundeck.core.common.INodeEntry
import com.dtolabs.rundeck.core.utils.NodeSet
import com.dtolabs.rundeck.core.utils.OptsUtil
import com.dtolabs.rundeck.server.authorization.AuthConstants
import grails.converters.JSON
import groovy.xml.MarkupBuilder
Expand Down Expand Up @@ -2291,8 +2292,9 @@ class ScheduledExecutionController extends ControllerBase{
if (e && e.scheduledExecution?.id == scheduledExecution.id) {
model.failedNodes = e.failedNodeList
if(varfound){
nset = ExecutionService.filtersAsNodeSet([filter: "name: " + e.failedNodeList])
nset = ExecutionService.filtersAsNodeSet([filter: OptsUtil.join("name:", e.failedNodeList)])
}
model.nodesetvariables = false
}
}
def nodes = frameworkService.filterAuthorizedNodes(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package rundeck.controllers

import com.dtolabs.rundeck.core.authorization.UserAndRolesAuthContext
import com.dtolabs.rundeck.core.common.Framework
import com.dtolabs.rundeck.core.common.NodeEntryImpl
import com.dtolabs.rundeck.core.common.NodeSetImpl
import com.dtolabs.rundeck.core.common.NodesSelector
import grails.test.mixin.Mock
import grails.test.mixin.TestFor
import org.codehaus.groovy.grails.web.servlet.mvc.SynchronizerTokensHolder
import rundeck.CommandExec
import rundeck.Execution
import rundeck.ScheduledExecution
import rundeck.Workflow
import rundeck.services.ApiService
import rundeck.services.FrameworkService
import rundeck.services.NotificationService
import rundeck.services.OrchestratorPluginService
import rundeck.services.ScheduledExecutionService
import spock.lang.Specification
import spock.lang.Unroll
Expand All @@ -19,7 +26,7 @@ import javax.security.auth.Subject
* Created by greg on 7/14/15.
*/
@TestFor(ScheduledExecutionController)
@Mock([ScheduledExecution,Workflow,CommandExec])
@Mock([ScheduledExecution,Workflow,CommandExec,Execution])
class ScheduledExecutionControllerSpec extends Specification {


Expand Down Expand Up @@ -192,4 +199,91 @@ class ScheduledExecutionControllerSpec extends Specification {
params[SynchronizerTokensHolder.TOKEN_KEY] = token.generateToken('/test')
params[SynchronizerTokensHolder.TOKEN_URI] = '/test'
}

def "show job retry failed exec id filter nodes"(){
given:

def se = new ScheduledExecution(
uuid: 'testUUID',
jobName: 'test1',
project: 'project1',
groupPath: 'testgroup',
doNodedispatch: true,
filter:'name: ${option.nodes}',
workflow: new Workflow(
keepgoing: true,
commands: [
new CommandExec([
adhocRemoteString: 'test buddy',
argString: '-delay 12 -monkey cheese -particle'
])
]
)
).save()
def exec = new Execution(
user: "testuser",
project: "project1",
loglevel: 'WARN',
status: 'FAILED',
doNodedispatch: true,
filter:'name: nodea',
succeededNodeList:'fwnode',
failedNodeList: 'nodec xyz,nodea',
workflow: new Workflow(commands: [new CommandExec(adhocExecution: true, adhocRemoteString: 'a remote string')]).save(),
scheduledExecution: se
).save()



NodeSetImpl testNodeSet = new NodeSetImpl()
testNodeSet.putNode(new NodeEntryImpl("nodea"))
testNodeSet.putNode(new NodeEntryImpl("nodeb"))
testNodeSet.putNode(new NodeEntryImpl("nodec xyz"))
NodeSetImpl testNodeSetB = new NodeSetImpl()
testNodeSetB.putNode(new NodeEntryImpl("nodea"))
testNodeSetB.putNode(new NodeEntryImpl("nodec xyz"))

controller.frameworkService=Mock(FrameworkService){
authorizeProjectJobAll(_,_,_,_)>>true
filterAuthorizedNodes(_,_,_,_)>>{args-> args[2]}
filterNodeSet({ NodesSelector selector->
selector.acceptNode(new NodeEntryImpl("nodea")) &&
selector.acceptNode(new NodeEntryImpl("nodec xyz")) &&
!selector.acceptNode(new NodeEntryImpl("nodeb"))

},_)>>testNodeSetB
getRundeckFramework()>>Mock(Framework){
getFrameworkNodeName()>>'fwnode'
}
}
controller.scheduledExecutionService=Mock(ScheduledExecutionService){
getByIDorUUID(_)>>se
}
controller.notificationService=Mock(NotificationService)
controller.orchestratorPluginService=Mock(OrchestratorPluginService)

when:
request.parameters = [id: se.id.toString(),project:'project1',retryFailedExecId:exec.id.toString()]

def model = controller.show()
then:
response.redirectedUrl==null
model != null
model.scheduledExecution != null
'fwnode' == model.localNodeName
'name: ${option.nodes}' == model.nodefilter
false == model.nodesetvariables
'nodec xyz,nodea' == model.failedNodes
null == model.nodesetempty
testNodeSetB.nodes == model.nodes
null == model.selectedNodes
[:] == model.grouptags
null == model.selectedoptsmap
true == model.nodesSelectedByDefault
[:] == model.dependentoptions
[:] == model.optiondependencies
null == model.optionordering
[:] == model.remoteOptionData

}
}

0 comments on commit 426c8b1

Please sign in to comment.