Skip to content

Commit ebcbe3a

Browse files
authored
Merge pull request #3 from rundeck/add-logfilter-template
logfilter example
2 parents 8ebc909 + 82d80e7 commit ebcbe3a

13 files changed

Lines changed: 292 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Java Plugins:
1919
* Notification
2020
* WorkflowStep
2121
* WorkflowNodeStep
22+
* LogFilter
2223

2324
Script Plugins:
2425
* 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"]
27+
private static final List ALLOWED_TEMPLATES = ["ResourceModelSource","Notification","WorkflowStep","WorkflowNodeStep","LogFilter"]
2828

2929
@Override
3030
Map makeTemplateProperties(final String pluginName, final String providedService) {
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.plugin.${javaPluginClass.toLowerCase()};
2+
3+
import com.dtolabs.rundeck.core.logging.LogEventControl;
4+
import com.dtolabs.rundeck.core.logging.LogLevel;
5+
import com.dtolabs.rundeck.core.logging.PluginLoggingContext;
6+
import com.dtolabs.rundeck.core.plugins.Plugin;
7+
import com.dtolabs.rundeck.plugins.descriptions.PluginDescription;
8+
import com.dtolabs.rundeck.plugins.descriptions.PluginProperty;
9+
import com.dtolabs.rundeck.plugins.descriptions.SelectLabels;
10+
import com.dtolabs.rundeck.plugins.descriptions.SelectValues;
11+
import com.dtolabs.rundeck.plugins.logging.LogFilterPlugin;
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
15+
@Plugin(service="LogFilter",name="${sanitizedPluginName}")
16+
@PluginDescription(title="${pluginName}", description="My plugin description")
17+
public class ${javaPluginClass} implements LogFilterPlugin{
18+
19+
@PluginProperty(name = "example header",title = "Example String",description = "Example description")
20+
private String header;
21+
22+
@PluginProperty(
23+
title = "Data type",
24+
description = "Select datatype output",
25+
required = false
26+
)
27+
@SelectValues(
28+
values = {"text/plain", "text/html"},
29+
freeSelect = true
30+
)
31+
@SelectLabels(values = {"TEXT", "HTML"})
32+
String datatype = null;
33+
34+
35+
private boolean started = false;
36+
private StringBuilder buffer;
37+
38+
@Override
39+
public void init(final PluginLoggingContext context) {
40+
started = true;
41+
buffer = new StringBuilder();
42+
43+
if(datatype.equals("text/html")){
44+
buffer.append("<table class='table table-striped'>");
45+
buffer.append("<tr><th>Log Output</th></tr>");
46+
}
47+
}
48+
49+
@Override
50+
public void handleEvent(final PluginLoggingContext context, final LogEventControl event) {
51+
if(event.getEventType().equals("log") && event.getLoglevel().equals(LogLevel.NORMAL) ){
52+
53+
if(datatype.equals("text/html")){
54+
buffer.append("<tr><td>").append("<b>[").append(header).append("]</b> ").append(event.getMessage()).append("</td></tr>");
55+
}else{
56+
buffer.append("[").append(header).append("] ").append(event.getMessage()).append("\\n");
57+
}
58+
59+
event.setLoglevel(LogLevel.DEBUG);
60+
}
61+
}
62+
63+
@Override
64+
public void complete(final PluginLoggingContext context) {
65+
if (started && datatype!=null && buffer.length()>0) {
66+
67+
if(datatype.equals("text/html")){
68+
buffer.append("</table>");
69+
}
70+
71+
Map<String,String> type = new HashMap<>();
72+
type.put("content-data-type", datatype);
73+
74+
75+
context.log(
76+
2,
77+
buffer.toString(),
78+
type
79+
);
80+
81+
}
82+
}
83+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.plugin.${javaPluginClass.toLowerCase()}
2+
3+
import com.dtolabs.rundeck.core.dispatcher.ContextView
4+
import com.dtolabs.rundeck.core.execution.workflow.DataOutput
5+
import com.dtolabs.rundeck.core.logging.LogEventControl
6+
import com.dtolabs.rundeck.core.logging.LogLevel
7+
import com.dtolabs.rundeck.core.logging.PluginLoggingContext
8+
import spock.lang.Specification
9+
10+
class ${javaPluginClass}Spec extends Specification {
11+
12+
def "test preset type "() {
13+
given:
14+
def plugin = new ${javaPluginClass}()
15+
plugin.datatype = datatype
16+
plugin.header = "test"
17+
def sharedoutput = new DataOutput(ContextView.global())
18+
def context = Mock(PluginLoggingContext) {
19+
getOutputContext() >> sharedoutput
20+
}
21+
def events = []
22+
lines.each { line ->
23+
events << Mock(LogEventControl) {
24+
getMessage() >> line
25+
getEventType() >> 'log'
26+
getLoglevel() >> LogLevel.NORMAL
27+
}
28+
}
29+
when:
30+
plugin.init(context)
31+
events.each {
32+
plugin.handleEvent(context, it)
33+
}
34+
plugin.complete(context)
35+
36+
then:
37+
1 * context.log(2, output, meta)
38+
39+
where:
40+
datatype | lines | output | meta
41+
'text/plain' | ['1,2,3', '---', 'a,b,c'] | '[test] 1,2,3\\n[test] ---\\n[test] a,b,c\\n' | ['content-data-type': 'text/plain']
42+
'text/html' | ['1,2,3', '---', 'a,b,c'] | "<table class='table table-striped'><tr><th>Log Output</th></tr><tr><td><b>[test]</b> 1,2,3</td></tr><tr><td><b>[test]</b> ---</td></tr><tr><td><b>[test]</b> a,b,c</td></tr></table>" | ['content-data-type': 'text/html']
43+
}
44+
45+
}
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 log filter plugin.
4+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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,notification'
33+
attributes 'Rundeck-Plugin-Version': rundeckPluginVersion, 'Rundeck-Plugin-Archive': 'true'
34+
}
35+
from("rundeck-verb-artifact.yaml") {
36+
into("")
37+
}
38+
}
39+
40+
task wrapper(type: Wrapper) {
41+
gradleVersion = '4.4.1'
42+
}
1.66 KB
Loading
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
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+
PluginSpec.groovy.template->src/test/groovy/com/plugin/${javaPluginClass.toLowerCase()}/${javaPluginClass}Spec.groovy
6+

src/main/resources/templates/script-plugin/filecopier/plugin.yaml.template

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,22 @@ providers:
4040
description: 'Just echo what would be done'
4141
default: true
4242
renderingOptions:
43-
groupName: 'Config'
43+
groupName: 'Config'
44+
- type: String
45+
name: storageprivatekey
46+
title: Storage Private Key
47+
description: Access to storage private key example
48+
renderingOptions:
49+
selectionAccessor: "STORAGE_PATH"
50+
valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
51+
storage-path-root: "keys"
52+
storage-file-meta-filter: "Rundeck-key-type=private"
53+
- type: String
54+
name: storagepassword
55+
title: Storage Password
56+
description: Access to storage password example
57+
renderingOptions:
58+
selectionAccessor: "STORAGE_PATH"
59+
valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
60+
storage-path-root: "keys"
61+
storage-file-meta-filter: "Rundeck-data-type=password"

src/main/resources/templates/script-plugin/nodeexecutor-filecopier/plugin.yaml.template

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,24 @@ providers:
4141
default: true
4242
renderingOptions:
4343
groupName: 'Config'
44+
- type: String
45+
name: storageprivatekey
46+
title: Storage Private Key
47+
description: Access to storage private key example
48+
renderingOptions:
49+
selectionAccessor: "STORAGE_PATH"
50+
valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
51+
storage-path-root: "keys"
52+
storage-file-meta-filter: "Rundeck-key-type=private"
53+
- type: String
54+
name: storagepassword
55+
title: Storage Password
56+
description: Access to storage password example
57+
renderingOptions:
58+
selectionAccessor: "STORAGE_PATH"
59+
valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
60+
storage-path-root: "keys"
61+
storage-file-meta-filter: "Rundeck-data-type=password"
4462
- name: ${sanitizedPluginName}-FileCopier
4563
service: FileCopier
4664
title: ${pluginName}
@@ -70,4 +88,22 @@ providers:
7088
description: 'Just echo what would be done'
7189
default: true
7290
renderingOptions:
73-
groupName: 'Config'
91+
groupName: 'Config'
92+
- type: String
93+
name: storageprivatekey
94+
title: Storage Private Key
95+
description: Access to storage private key example
96+
renderingOptions:
97+
selectionAccessor: "STORAGE_PATH"
98+
valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
99+
storage-path-root: "keys"
100+
storage-file-meta-filter: "Rundeck-key-type=private"
101+
- type: String
102+
name: storagepassword
103+
title: Storage Password
104+
description: Access to storage password example
105+
renderingOptions:
106+
selectionAccessor: "STORAGE_PATH"
107+
valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
108+
storage-path-root: "keys"
109+
storage-file-meta-filter: "Rundeck-data-type=password"

0 commit comments

Comments
 (0)