1+ package com.plugin.${javaPluginClass.toLowerCase()};
2+
3+ import com.dtolabs.rundeck.core.common.INodeEntry
4+ import com.dtolabs.rundeck.core.execution.ExecutionContext
5+ import com.dtolabs.rundeck.core.execution.ExecutionLogger
6+ import com.dtolabs.rundeck.core.execution.service.NodeExecutor
7+ import com.dtolabs.rundeck.core.execution.service.NodeExecutorResult
8+ import com.dtolabs.rundeck.core.execution.service.NodeExecutorResultImpl
9+ import com.dtolabs.rundeck.core.execution.utils.ResolverUtil
10+ import com.dtolabs.rundeck.core.plugins.Plugin
11+ import com.dtolabs.rundeck.core.plugins.configuration.Describable
12+ import com.dtolabs.rundeck.core.plugins.configuration.Description;
13+ import com.dtolabs.rundeck.core.plugins.configuration.StringRenderingConstants;
14+ import com.dtolabs.rundeck.plugins.ServiceNameConstants;
15+ import com.dtolabs.rundeck.plugins.descriptions.PluginDescription;
16+ import com.dtolabs.rundeck.plugins.util.DescriptionBuilder
17+ import com.dtolabs.rundeck.plugins.util.PropertyBuilder;
18+
19+ @Plugin(name = "${sanitizedPluginName}", service = ServiceNameConstants.NodeExecutor)
20+ @PluginDescription(title = "${pluginName}", description = "A node executor plugin that can execute commands on remote nodes")
21+ public class ${javaPluginClass} implements NodeExecutor, Describable {
22+
23+ public static final String SERVICE_PROVIDER_NAME = "${sanitizedPluginName}"
24+
25+ public static final String PROJ_PROP_PREFIX = "project."
26+ public static final String FRAMEWORK_PROP_PREFIX = "framework."
27+
28+ public static final String MOCK_FAILURE = "mockFailure"
29+ public static final String USERNAME = "username"
30+ public static final String PASSWORD = "password"
31+
32+ @Override
33+ Description getDescription() {
34+ DescriptionBuilder builder = DescriptionBuilder.builder()
35+ .name(SERVICE_PROVIDER_NAME)
36+ .title("${pluginName}")
37+ .description("A node executor plugin that can execute commands on remote nodes")
38+ .property(PropertyBuilder.builder()
39+ .title("Username")
40+ .string(USERNAME)
41+ .description("The username to use for the connection")
42+ .required(true)
43+ .renderingOption(StringRenderingConstants.INSTANCE_SCOPE_NODE_ATTRIBUTE_KEY, "username-key-path")
44+ .build()
45+ )
46+ .property(
47+ PropertyBuilder.builder()
48+ .title("Password")
49+ .string(PASSWORD)
50+ .description("The password to use for the connection")
51+ .required(true)
52+ .renderingOption(StringRenderingConstants.SELECTION_ACCESSOR_KEY, StringRenderingConstants.SelectionAccessor.STORAGE_PATH)
53+ .renderingOption(StringRenderingConstants.STORAGE_PATH_ROOT_KEY, "keys")
54+ .renderingOption(StringRenderingConstants.STORAGE_FILE_META_FILTER_KEY, "Rundeck-data-type=password")
55+ .build()
56+ )
57+ .property(
58+ PropertyBuilder.builder()
59+ .title("Mock Failure")
60+ .booleanType(MOCK_FAILURE)
61+ .description("Optionally select to mock a failure")
62+ .required(false)
63+ .defaultValue("false")
64+ .build()
65+ )
66+
67+ builder.mapping(USERNAME, PROJ_PROP_PREFIX + USERNAME)
68+ builder.frameworkMapping(USERNAME, FRAMEWORK_PROP_PREFIX + USERNAME)
69+ builder.mapping(PASSWORD, PROJ_PROP_PREFIX + PASSWORD)
70+ builder.frameworkMapping(PASSWORD, FRAMEWORK_PROP_PREFIX + PASSWORD)
71+ builder.mapping(MOCK_FAILURE, PROJ_PROP_PREFIX + MOCK_FAILURE)
72+ builder.frameworkMapping(MOCK_FAILURE, FRAMEWORK_PROP_PREFIX + MOCK_FAILURE)
73+
74+ return builder.build()
75+ }
76+
77+ @Override
78+ public NodeExecutorResult executeCommand(ExecutionContext context, String[] command, INodeEntry node) {
79+
80+ String username = ResolverUtil.resolveProperty(USERNAME, null, node,
81+ context.getIFramework().getFrameworkProjectMgr().getFrameworkProject(context.getFrameworkProject()),
82+ context.framework)
83+ String passwordKeyPath = ResolverUtil.resolveProperty(PASSWORD, null, node,
84+ context.getIFramework().getFrameworkProjectMgr().getFrameworkProject(context.getFrameworkProject()),
85+ context.framework)
86+ boolean mockFailure = Boolean.parseBoolean(ResolverUtil.resolveProperty(MOCK_FAILURE, "false", node,
87+ context.getIFramework().getFrameworkProjectMgr().getFrameworkProject(context.getFrameworkProject()),
88+ context.framework))
89+
90+ ExecutionLogger logger= context.getExecutionLogger()
91+
92+ //Here we can retrieve the password from key storage and use it to authenticate with the target node.
93+ String password = Util.getPasswordFromPath(passwordKeyPath, context)
94+
95+ logger.log(2, "Executing command: " + Arrays.asList(command) + " on node: " + node.getNodename() + " with username: " + username)
96+
97+ if(mockFailure) {
98+ return NodeExecutorResultImpl.createFailure(Util.PluginFailureReason.ConnectionError, "Failure due to mock failure", node)
99+ } else {
100+ return NodeExecutorResultImpl.createSuccess(node)
101+ }
102+ }
103+ }
0 commit comments