Skip to content

Commit 443a7b5

Browse files
authored
Merge pull request #11 from rundeck/java-orchestrator
Adding orchestrator java plugin
2 parents c844507 + 8e2e2ac commit 443a7b5

9 files changed

Lines changed: 202 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Existing service plugins enabled on boostrap-plugin
5555
* WorkflowNodeStep
5656
* LogFilter
5757
* NodeExecutor
58+
* Orchestrator
5859

5960
#### for Script Plugins:
6061
* ResourceModelSource

src/main/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGenerator.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class JavaPluginTemplateGenerator extends AbstractTemplateGenerator {
2424
private static final String TEMPLATE_BASE = "templates/java-plugin/"
2525
private static final String JAVA_STRUCTURE = "java-plugin.structure"
2626

27-
private static final List ALLOWED_TEMPLATES = ["ResourceModelSource","Notification","WorkflowStep","WorkflowNodeStep","LogFilter","NodeExecutor"]
27+
private static final List ALLOWED_TEMPLATES = ["ResourceModelSource","Notification","WorkflowStep","WorkflowNodeStep","LogFilter","NodeExecutor","Orchestrator"]
2828

2929
@Override
3030
Map makeTemplateProperties(final String pluginName, final String providedService) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.plugin.${javaPluginClass.toLowerCase()};
2+
3+
import com.dtolabs.rundeck.core.common.INodeEntry;
4+
import com.dtolabs.rundeck.core.execution.workflow.StepExecutionContext;
5+
import com.dtolabs.rundeck.core.plugins.Plugin;
6+
import com.dtolabs.rundeck.plugins.ServiceNameConstants;
7+
import com.dtolabs.rundeck.plugins.descriptions.PluginDescription;
8+
import com.dtolabs.rundeck.plugins.descriptions.PluginProperty;
9+
import com.dtolabs.rundeck.plugins.orchestrator.Orchestrator;
10+
import com.dtolabs.rundeck.plugins.orchestrator.OrchestratorPlugin;
11+
12+
import java.io.UnsupportedEncodingException;
13+
import java.nio.ByteBuffer;
14+
import java.security.MessageDigest;
15+
import java.security.NoSuchAlgorithmException;
16+
import java.util.Collection;
17+
import java.util.List;
18+
import java.util.stream.Collectors;
19+
20+
import java.util.ArrayList;
21+
import java.util.Collection;
22+
import java.util.List;
23+
import java.util.Random;
24+
25+
@Plugin(service=ServiceNameConstants.Orchestrator,name="${sanitizedPluginName}")
26+
@PluginDescription(title="${pluginName}", description="My Orchestrator plugin description")
27+
public class ${javaPluginClass} implements OrchestratorPlugin{
28+
29+
@PluginProperty(title = "Count", description = "Number of nodes to select from the pool", defaultValue = "1")
30+
protected int count;
31+
32+
@Override
33+
public Orchestrator createOrchestrator(StepExecutionContext context, Collection<INodeEntry> nodes) {
34+
return new ${javaPluginClass}Orchestrator(count, context, nodes);
35+
}
36+
37+
38+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.plugin.${javaPluginClass.toLowerCase()};
2+
3+
import com.dtolabs.rundeck.core.common.INodeEntry;
4+
import com.dtolabs.rundeck.core.execution.workflow.StepExecutionContext;
5+
import com.dtolabs.rundeck.core.execution.workflow.steps.node.NodeStepResult;
6+
import com.dtolabs.rundeck.plugins.orchestrator.Orchestrator;
7+
8+
import java.util.ArrayList;
9+
import java.util.Collection;
10+
import java.util.List;
11+
import java.util.Random;
12+
13+
/**
14+
* Selects a random subset of the nodes
15+
*/
16+
public class ${javaPluginClass}Orchestrator implements Orchestrator {
17+
18+
Random random;
19+
final int count;
20+
List<INodeEntry> nodes;
21+
22+
public ${javaPluginClass}Orchestrator(
23+
int count,
24+
StepExecutionContext context,
25+
Collection<INodeEntry> nodes
26+
)
27+
{
28+
this.random = new Random();
29+
this.count = count;
30+
this.nodes = select(count, nodes);
31+
}
32+
33+
/**
34+
* Select count random items from the input nodes, or if nodes is smaller than count, reorders them
35+
* @param count number of nodes
36+
* @param nodes input nodes
37+
* @return list of count nodes
38+
*/
39+
private List<INodeEntry> select(final int count, final Collection<INodeEntry> nodes) {
40+
List<INodeEntry> source = new ArrayList<>(nodes);
41+
List<INodeEntry> selected = new ArrayList<>();
42+
int total = Math.min(count, nodes.size());
43+
for (int i = 0; i < total; i++) {
44+
selected.add(source.remove(random.nextInt(source.size())));
45+
}
46+
return selected;
47+
}
48+
49+
50+
@Override
51+
public INodeEntry nextNode() {
52+
if (nodes.size() > 0) {
53+
return nodes.remove(0);
54+
} else {
55+
return null;
56+
}
57+
}
58+
59+
@Override
60+
public void returnNode( final INodeEntry node, final boolean success, final NodeStepResult result)
61+
{
62+
63+
}
64+
65+
@Override
66+
public boolean isComplete() {
67+
return nodes.size() == 0;
68+
}
69+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.plugin.${javaPluginClass.toLowerCase()}
2+
3+
import com.dtolabs.rundeck.core.common.INodeEntry
4+
import com.dtolabs.rundeck.core.common.NodeEntryImpl
5+
import com.dtolabs.rundeck.core.execution.workflow.StepExecutionContext
6+
import spock.lang.Specification
7+
8+
class ${javaPluginClass}Spec extends Specification {
9+
10+
private INodeEntry create(String hostname, String rankAttr=null, String rankValue=null){
11+
INodeEntry iNodeEntry = NodeEntryImpl.create(hostname, hostname);
12+
13+
if(null!=rankAttr) {
14+
iNodeEntry.getAttributes().put(rankAttr, rankValue);
15+
}
16+
return iNodeEntry;
17+
}
18+
19+
def "simple test"() {
20+
21+
given:
22+
INodeEntry node1 = create("Centos6", "memory", "1048");
23+
INodeEntry node2 = create("Centos7", "memory", "2048");
24+
INodeEntry node3 = create("Windows2016", "memory", "10240");
25+
INodeEntry node4 = create("Windows10", "memory", "4096");
26+
27+
List<INodeEntry> nodes = Arrays.asList(node1, node2, node3, node4);
28+
29+
def count=1
30+
31+
StepExecutionContext context=Mock(StepExecutionContext)
32+
33+
when:
34+
def orchestrator=new ${javaPluginClass}Orchestrator(count,context,nodes)
35+
36+
then:
37+
orchestrator.nextNode()?.hostname!=null
38+
orchestrator.nextNode()?.hostname==null
39+
40+
}
41+
42+
43+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# ${pluginName} Rundeck Plugin
2+
3+
This is a orchestrator plugin.
4+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
version = '0.1.0'
2+
defaultTasks 'clean','build'
3+
apply plugin: 'java'
4+
apply plugin: 'groovy'
5+
apply plugin: 'idea'
6+
sourceCompatibility = 1.8
7+
ext.rundeckPluginVersion= '2.0'
8+
ext.rundeckVersion= '${rundeckVersion}'
9+
10+
11+
repositories {
12+
mavenLocal()
13+
mavenCentral()
14+
}
15+
16+
dependencies {
17+
compile 'org.rundeck:rundeck-core:3.0.1+'
18+
19+
testCompile 'junit:junit:4.12'
20+
testCompile "org.codehaus.groovy:groovy-all:2.4.15"
21+
testCompile "org.spockframework:spock-core:1.0-groovy-2.4"
22+
}
23+
24+
ext.pluginClassNames='com.plugin.${sanitizedPluginName}.${javaPluginClass}'
25+
jar {
26+
manifest {
27+
attributes 'Rundeck-Plugin-Classnames': pluginClassNames
28+
attributes 'Rundeck-Plugin-File-Version': version
29+
attributes 'Rundeck-Plugin-Name': '${pluginName}'
30+
attributes 'Rundeck-Plugin-Description': 'Provide a short description of your plugin here.'
31+
attributes 'Rundeck-Plugin-Rundeck-Compatibility-Version': '3.x'
32+
attributes 'Rundeck-Plugin-Tags': 'java,orchestrator'
33+
attributes 'Rundeck-Plugin-Version': rundeckPluginVersion, 'Rundeck-Plugin-Archive': 'true'
34+
}
35+
}
36+
37+
wrapper {
38+
gradleVersion = '4.4.1'
39+
}
1.66 KB
Loading
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
build.gradle.template->build.gradle
2+
README.md.template->README.md
3+
icon.png->src/main/resources/resources/icon.png
4+
Plugin.java.template->src/main/java/com/plugin/${javaPluginClass.toLowerCase()}/${javaPluginClass}.java
5+
PluginOrchestrator.java.template->src/main/java/com/plugin/${javaPluginClass.toLowerCase()}/${javaPluginClass}Orchestrator.java
6+
PluginSpec.groovy.template->src/test/groovy/com/plugin/${javaPluginClass.toLowerCase()}/${javaPluginClass}Spec.groovy
7+

0 commit comments

Comments
 (0)