diff --git a/README.md b/README.md
index 2193cbb..ed20f97 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ Java Plugins:
* Notification
* WorkflowStep
* WorkflowNodeStep
+* LogFilter
Script Plugins:
* ResourceModelSource
diff --git a/src/main/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGenerator.groovy b/src/main/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGenerator.groovy
index e9f3cb2..e672886 100644
--- a/src/main/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGenerator.groovy
+++ b/src/main/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGenerator.groovy
@@ -24,7 +24,7 @@ class JavaPluginTemplateGenerator extends AbstractTemplateGenerator {
private static final String TEMPLATE_BASE = "templates/java-plugin/"
private static final String JAVA_STRUCTURE = "java-plugin.structure"
- private static final List ALLOWED_TEMPLATES = ["ResourceModelSource","Notification","WorkflowStep","WorkflowNodeStep"]
+ private static final List ALLOWED_TEMPLATES = ["ResourceModelSource","Notification","WorkflowStep","WorkflowNodeStep","LogFilter"]
@Override
Map makeTemplateProperties(final String pluginName, final String providedService) {
diff --git a/src/main/resources/templates/java-plugin/logfilter/Plugin.java.template b/src/main/resources/templates/java-plugin/logfilter/Plugin.java.template
new file mode 100644
index 0000000..3fbb49f
--- /dev/null
+++ b/src/main/resources/templates/java-plugin/logfilter/Plugin.java.template
@@ -0,0 +1,83 @@
+package com.plugin.${javaPluginClass.toLowerCase()};
+
+import com.dtolabs.rundeck.core.logging.LogEventControl;
+import com.dtolabs.rundeck.core.logging.LogLevel;
+import com.dtolabs.rundeck.core.logging.PluginLoggingContext;
+import com.dtolabs.rundeck.core.plugins.Plugin;
+import com.dtolabs.rundeck.plugins.descriptions.PluginDescription;
+import com.dtolabs.rundeck.plugins.descriptions.PluginProperty;
+import com.dtolabs.rundeck.plugins.descriptions.SelectLabels;
+import com.dtolabs.rundeck.plugins.descriptions.SelectValues;
+import com.dtolabs.rundeck.plugins.logging.LogFilterPlugin;
+import java.util.HashMap;
+import java.util.Map;
+
+@Plugin(service="LogFilter",name="${sanitizedPluginName}")
+@PluginDescription(title="${pluginName}", description="My plugin description")
+public class ${javaPluginClass} implements LogFilterPlugin{
+
+ @PluginProperty(name = "example header",title = "Example String",description = "Example description")
+ private String header;
+
+ @PluginProperty(
+ title = "Data type",
+ description = "Select datatype output",
+ required = false
+ )
+ @SelectValues(
+ values = {"text/plain", "text/html"},
+ freeSelect = true
+ )
+ @SelectLabels(values = {"TEXT", "HTML"})
+ String datatype = null;
+
+
+ private boolean started = false;
+ private StringBuilder buffer;
+
+ @Override
+ public void init(final PluginLoggingContext context) {
+ started = true;
+ buffer = new StringBuilder();
+
+ if(datatype.equals("text/html")){
+ buffer.append("
");
+ buffer.append("Log Output |
");
+ }
+ }
+
+ @Override
+ public void handleEvent(final PluginLoggingContext context, final LogEventControl event) {
+ if(event.getEventType().equals("log") && event.getLoglevel().equals(LogLevel.NORMAL) ){
+
+ if(datatype.equals("text/html")){
+ buffer.append("").append("[").append(header).append("] ").append(event.getMessage()).append(" |
");
+ }else{
+ buffer.append("[").append(header).append("] ").append(event.getMessage()).append("\\n");
+ }
+
+ event.setLoglevel(LogLevel.DEBUG);
+ }
+ }
+
+ @Override
+ public void complete(final PluginLoggingContext context) {
+ if (started && datatype!=null && buffer.length()>0) {
+
+ if(datatype.equals("text/html")){
+ buffer.append("
");
+ }
+
+ Map type = new HashMap<>();
+ type.put("content-data-type", datatype);
+
+
+ context.log(
+ 2,
+ buffer.toString(),
+ type
+ );
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/templates/java-plugin/logfilter/PluginSpec.groovy.template b/src/main/resources/templates/java-plugin/logfilter/PluginSpec.groovy.template
new file mode 100644
index 0000000..cb2e5f5
--- /dev/null
+++ b/src/main/resources/templates/java-plugin/logfilter/PluginSpec.groovy.template
@@ -0,0 +1,45 @@
+package com.plugin.${javaPluginClass.toLowerCase()}
+
+import com.dtolabs.rundeck.core.dispatcher.ContextView
+import com.dtolabs.rundeck.core.execution.workflow.DataOutput
+import com.dtolabs.rundeck.core.logging.LogEventControl
+import com.dtolabs.rundeck.core.logging.LogLevel
+import com.dtolabs.rundeck.core.logging.PluginLoggingContext
+import spock.lang.Specification
+
+class ${javaPluginClass}Spec extends Specification {
+
+ def "test preset type "() {
+ given:
+ def plugin = new ${javaPluginClass}()
+ plugin.datatype = datatype
+ plugin.header = "test"
+ def sharedoutput = new DataOutput(ContextView.global())
+ def context = Mock(PluginLoggingContext) {
+ getOutputContext() >> sharedoutput
+ }
+ def events = []
+ lines.each { line ->
+ events << Mock(LogEventControl) {
+ getMessage() >> line
+ getEventType() >> 'log'
+ getLoglevel() >> LogLevel.NORMAL
+ }
+ }
+ when:
+ plugin.init(context)
+ events.each {
+ plugin.handleEvent(context, it)
+ }
+ plugin.complete(context)
+
+ then:
+ 1 * context.log(2, output, meta)
+
+ where:
+ datatype | lines | output | meta
+ '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']
+ 'text/html' | ['1,2,3', '---', 'a,b,c'] | "Log Output |
---|
[test] 1,2,3 |
[test] --- |
[test] a,b,c |
" | ['content-data-type': 'text/html']
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/resources/templates/java-plugin/logfilter/README.md.template b/src/main/resources/templates/java-plugin/logfilter/README.md.template
new file mode 100644
index 0000000..a03f19d
--- /dev/null
+++ b/src/main/resources/templates/java-plugin/logfilter/README.md.template
@@ -0,0 +1,4 @@
+# ${pluginName} Rundeck Plugin
+
+This is a log filter plugin.
+
diff --git a/src/main/resources/templates/java-plugin/logfilter/build.gradle.template b/src/main/resources/templates/java-plugin/logfilter/build.gradle.template
new file mode 100644
index 0000000..b304aa9
--- /dev/null
+++ b/src/main/resources/templates/java-plugin/logfilter/build.gradle.template
@@ -0,0 +1,42 @@
+version = '0.1.0'
+defaultTasks 'clean','build'
+apply plugin: 'java'
+apply plugin: 'groovy'
+apply plugin: 'idea'
+sourceCompatibility = 1.8
+ext.rundeckPluginVersion= '2.0'
+ext.rundeckVersion= '${rundeckVersion}'
+
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
+
+dependencies {
+ compile 'org.rundeck:rundeck-core:3.0.1+'
+
+ testCompile 'junit:junit:4.12'
+ testCompile "org.codehaus.groovy:groovy-all:2.4.15"
+ testCompile "org.spockframework:spock-core:1.0-groovy-2.4"
+}
+
+ext.pluginClassNames='com.plugin.${sanitizedPluginName}.${javaPluginClass}'
+jar {
+ manifest {
+ attributes 'Rundeck-Plugin-Classnames': pluginClassNames
+ attributes 'Rundeck-Plugin-File-Version': version
+ attributes 'Rundeck-Plugin-Name': '${pluginName}'
+ attributes 'Rundeck-Plugin-Description': 'Provide a short description of your plugin here.'
+ attributes 'Rundeck-Plugin-Rundeck-Compatibility-Version': '3.x'
+ attributes 'Rundeck-Plugin-Tags': 'java,notification'
+ attributes 'Rundeck-Plugin-Version': rundeckPluginVersion, 'Rundeck-Plugin-Archive': 'true'
+ }
+ from("rundeck-verb-artifact.yaml") {
+ into("")
+ }
+}
+
+task wrapper(type: Wrapper) {
+ gradleVersion = '4.4.1'
+}
diff --git a/src/main/resources/templates/java-plugin/logfilter/icon.png b/src/main/resources/templates/java-plugin/logfilter/icon.png
new file mode 100644
index 0000000..7aaf7e8
Binary files /dev/null and b/src/main/resources/templates/java-plugin/logfilter/icon.png differ
diff --git a/src/main/resources/templates/java-plugin/logfilter/java-plugin.structure b/src/main/resources/templates/java-plugin/logfilter/java-plugin.structure
new file mode 100644
index 0000000..d0ce03e
--- /dev/null
+++ b/src/main/resources/templates/java-plugin/logfilter/java-plugin.structure
@@ -0,0 +1,6 @@
+build.gradle.template->build.gradle
+README.md.template->README.md
+icon.png->src/main/resources/resources/icon.png
+Plugin.java.template->src/main/java/com/plugin/${javaPluginClass.toLowerCase()}/${javaPluginClass}.java
+PluginSpec.groovy.template->src/test/groovy/com/plugin/${javaPluginClass.toLowerCase()}/${javaPluginClass}Spec.groovy
+
diff --git a/src/main/resources/templates/script-plugin/filecopier/plugin.yaml.template b/src/main/resources/templates/script-plugin/filecopier/plugin.yaml.template
index 58e31ac..86d3cb1 100644
--- a/src/main/resources/templates/script-plugin/filecopier/plugin.yaml.template
+++ b/src/main/resources/templates/script-plugin/filecopier/plugin.yaml.template
@@ -40,4 +40,22 @@ providers:
description: 'Just echo what would be done'
default: true
renderingOptions:
- groupName: 'Config'
\ No newline at end of file
+ groupName: 'Config'
+ - type: String
+ name: storageprivatekey
+ title: Storage Private Key
+ description: Access to storage private key example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-key-type=private"
+ - type: String
+ name: storagepassword
+ title: Storage Password
+ description: Access to storage password example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-data-type=password"
\ No newline at end of file
diff --git a/src/main/resources/templates/script-plugin/nodeexecutor-filecopier/plugin.yaml.template b/src/main/resources/templates/script-plugin/nodeexecutor-filecopier/plugin.yaml.template
index 82e8b18..92ecd48 100644
--- a/src/main/resources/templates/script-plugin/nodeexecutor-filecopier/plugin.yaml.template
+++ b/src/main/resources/templates/script-plugin/nodeexecutor-filecopier/plugin.yaml.template
@@ -41,6 +41,24 @@ providers:
default: true
renderingOptions:
groupName: 'Config'
+ - type: String
+ name: storageprivatekey
+ title: Storage Private Key
+ description: Access to storage private key example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-key-type=private"
+ - type: String
+ name: storagepassword
+ title: Storage Password
+ description: Access to storage password example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-data-type=password"
- name: ${sanitizedPluginName}-FileCopier
service: FileCopier
title: ${pluginName}
@@ -70,4 +88,22 @@ providers:
description: 'Just echo what would be done'
default: true
renderingOptions:
- groupName: 'Config'
\ No newline at end of file
+ groupName: 'Config'
+ - type: String
+ name: storageprivatekey
+ title: Storage Private Key
+ description: Access to storage private key example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-key-type=private"
+ - type: String
+ name: storagepassword
+ title: Storage Password
+ description: Access to storage password example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-data-type=password"
\ No newline at end of file
diff --git a/src/main/resources/templates/script-plugin/nodeexecutor/plugin.yaml.template b/src/main/resources/templates/script-plugin/nodeexecutor/plugin.yaml.template
index b383b93..7e85361 100644
--- a/src/main/resources/templates/script-plugin/nodeexecutor/plugin.yaml.template
+++ b/src/main/resources/templates/script-plugin/nodeexecutor/plugin.yaml.template
@@ -40,4 +40,22 @@ providers:
description: 'Just echo what would be done'
default: true
renderingOptions:
- groupName: 'Config'
\ No newline at end of file
+ groupName: 'Config'
+ - type: String
+ name: storageprivatekey
+ title: Storage Private Key
+ description: Access to storage private key example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-key-type=private"
+ - type: String
+ name: storagepassword
+ title: Storage Password
+ description: Access to storage password example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-data-type=password"
\ No newline at end of file
diff --git a/src/main/resources/templates/script-plugin/workflow/plugin.yaml.template b/src/main/resources/templates/script-plugin/workflow/plugin.yaml.template
index a24545e..462c299 100644
--- a/src/main/resources/templates/script-plugin/workflow/plugin.yaml.template
+++ b/src/main/resources/templates/script-plugin/workflow/plugin.yaml.template
@@ -44,4 +44,22 @@ providers:
title: Debug?
description: 'Write debug messages to stderr'
renderingOptions:
- groupName: 'Config'
\ No newline at end of file
+ groupName: 'Config'
+ - type: String
+ name: storageprivatekey
+ title: Storage Private Key
+ description: Access to storage private key example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-key-type=private"
+ - type: String
+ name: storagepassword
+ title: Storage Password
+ description: Access to storage password example
+ renderingOptions:
+ selectionAccessor: "STORAGE_PATH"
+ valueConversion: "STORAGE_PATH_AUTOMATIC_READ"
+ storage-path-root: "keys"
+ storage-file-meta-filter: "Rundeck-data-type=password"
\ No newline at end of file
diff --git a/src/test/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGeneratorTest.groovy b/src/test/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGeneratorTest.groovy
index fcaa77a..f169c6d 100644
--- a/src/test/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGeneratorTest.groovy
+++ b/src/test/groovy/com/rundeck/plugin/generator/JavaPluginTemplateGeneratorTest.groovy
@@ -85,4 +85,20 @@ class JavaPluginTemplateGeneratorTest extends Specification {
new File(tmpDir,"/my-workflownodestep-plugin/src/test/groovy/com/plugin/myworkflownodestepplugin/MyWorkflownodestepPluginSpec.groovy").exists()
}
+ def "Create Logfilter Template"() {
+ when:
+ File tmpDir = File.createTempDir()
+ JavaPluginTemplateGenerator generator = new JavaPluginTemplateGenerator()
+ generator.createTemplate("My LogFilter Plugin","LogFilter",tmpDir.absolutePath)
+ int compileResult = TestUtils.buildGradle(new File(tmpDir,"my-logfilter-plugin"))
+
+ then:
+ compileResult == 0
+ new File(tmpDir,"/my-logfilter-plugin/build.gradle").exists()
+ new File(tmpDir,"/my-logfilter-plugin/src/main/resources/resources/icon.png").exists()
+ new File(tmpDir,"/my-logfilter-plugin/README.md").exists()
+ new File(tmpDir,"/my-logfilter-plugin/src/main/java/com/plugin/mylogfilterplugin/MyLogfilterPlugin.java").exists()
+ new File(tmpDir,"/my-logfilter-plugin/src/test/groovy/com/plugin/mylogfilterplugin/MyLogfilterPluginSpec.groovy").exists()
+ }
+
}