Skip to content

Commit bb8aacb

Browse files
committed
First Commit
0 parents  commit bb8aacb

14 files changed

+1101
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.gradle
2+
.idea
3+
build
4+
gradle

README.md

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Git Plugin
2+
3+
This is a git plugin (based on [Jgit](https://www.eclipse.org/jgit/)) which contain a Resource model and worflow steps
4+
5+
For authentication, it can be used a private key or a password.
6+
If the private key is not defined, then the password will be used.
7+
8+
* The primary key will work with SSH protocol on the Git URL.
9+
* The password will work with http/https protocol on the Git URL (the most of the case, the username is needed on the URI, eg: `http[s]://[email protected][:port]/path/to/repo.git/` when you use password authentication)
10+
11+
12+
## Build
13+
14+
Run the following command to built the jar file:
15+
16+
```
17+
./gradlew clean build
18+
```
19+
20+
## Install
21+
22+
Copy the `git-plugin-x.y.x.jar` file to the `$RDECK_BASE/libext/` directory inside your Rundeck installation.
23+
24+
25+
## GIT Resource Model
26+
27+
This is a resource model plugin that uses Git to store resources model file.
28+
29+
### Configuration
30+
31+
You need to set up the following options to use the plugin:
32+
33+
![](images/resource_model.png)
34+
35+
### Repo Settings
36+
37+
* **Base Directory**: Directory for checkout
38+
* **Git URL**: Checkout URL.
39+
See [git-clone](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html)
40+
specifically the [GIT URLS](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS) section.
41+
Some examples:
42+
* `ssh://[user@]host.xz[:port]/path/to/repo.git/`
43+
* `git://host.xz[:port]/path/to/repo.git/`
44+
* `http[s]://host.xz[:port]/path/to/repo.git/`
45+
* `ftp[s]://host.xz[:port]/path/to/repo.git/`
46+
* `rsync://host.xz/path/to/repo.git/`
47+
48+
* **Branch**: Checkout branch
49+
* **Resource model File**: Resource model file inside the github repo. This is the file that will be added to Rundeck resource model.
50+
* **File Format**: File format of the resource model, it could be xml, yaml, json
51+
* **Writable**: Allow to write the remote file
52+
53+
### Authentication
54+
55+
* **Git Password**: Password to authenticate remotely
56+
* **SSH: Strict Host Key Checking**: Use strict host key checking.
57+
If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` file, otherwise do not verify.
58+
* **SSH Key Path**: SSH Key Path to authenticate
59+
60+
### Limitations
61+
62+
* The plugin needs to clone the full repo on the local directory path (Base Directory option) to get the file that will be added to the resource model.
63+
* Any time that you edit the nodes on the GUI, the commit will be perfomed with the message `Edit node from GUI` (it is not editable)
64+
65+
## GIT Clone Workflow Step
66+
67+
This plugin clone a git repo into a rundeck server folder
68+
69+
### Configuration
70+
71+
You need to set up the following options to use the plugin:
72+
73+
![](images/clone-workflow-step.png)
74+
75+
### Repo Settings
76+
77+
* **Base Directory**: Directory for checkout
78+
* **Git URL**: Checkout URL.
79+
See [git-clone](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html)
80+
specifically the [GIT URLS](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS) section.
81+
Some examples:
82+
* `ssh://[user@]host.xz[:port]/path/to/repo.git/`
83+
* `git://host.xz[:port]/path/to/repo.git/`
84+
* `http[s]://host.xz[:port]/path/to/repo.git/`
85+
* `ftp[s]://host.xz[:port]/path/to/repo.git/`
86+
* `rsync://host.xz/path/to/repo.git/`
87+
88+
* **Branch**: Checkout branch
89+
90+
### Authentication
91+
92+
* **Password Storage Path**: Password storage path to authenticate remotely
93+
* **SSH: Strict Host Key Checking**: Use strict host key checking.
94+
If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` file, otherwise do not verify.
95+
* **SSH Key Storage Path**: SSH Key storage path to authenticate
96+

build.gradle

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
plugins {
2+
id 'pl.allegro.tech.build.axion-release' version '1.3.2'
3+
}
4+
5+
group 'com.rundeck'
6+
7+
ext.rundeckPluginVersion = '1.2'
8+
ext.pluginClassNames='com.rundeck.plugin.GitResourceModelFactory,com.rundeck.plugin.GitCloneWorkflowStep'
9+
ext.pluginName = 'Git Plugin'
10+
ext.pluginDescription = 'Git Plugin'
11+
12+
scmVersion {
13+
tag {
14+
prefix = ''
15+
versionSeparator = ''
16+
def origDeserialize=deserialize
17+
//apend .0 to satisfy semver if the tag version is only X.Y
18+
deserialize = { config, position, tagName ->
19+
def orig = origDeserialize(config, position, tagName)
20+
if (orig.split('\\.').length < 3) {
21+
orig += ".0"
22+
}
23+
orig
24+
}
25+
}
26+
}
27+
project.version = scmVersion.version
28+
29+
apply plugin: 'groovy'
30+
apply plugin: 'java'
31+
32+
repositories {
33+
mavenCentral()
34+
}
35+
36+
configurations {
37+
pluginLibs
38+
39+
compile {
40+
extendsFrom pluginLibs
41+
}
42+
}
43+
44+
45+
dependencies {
46+
compile 'org.codehaus.groovy:groovy-all:2.3.11'
47+
testCompile group: 'junit', name: 'junit', version: '4.12'
48+
49+
compile group: 'org.rundeck', name: 'rundeck-core', version: '2.11.4'
50+
51+
pluginLibs( 'org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r') {
52+
exclude module: 'slf4j-api'
53+
exclude module: 'jsch'
54+
exclude module: 'commons-logging'
55+
}
56+
57+
testCompile "org.codehaus.groovy:groovy-all:2.3.7"
58+
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
59+
testCompile "cglib:cglib-nodep:2.2.2"
60+
testCompile 'org.objenesis:objenesis:1.4'
61+
}
62+
63+
64+
task copyToLib(type: Copy) {
65+
into "$buildDir/output/lib"
66+
from configurations.pluginLibs
67+
}
68+
69+
jar {
70+
from "$buildDir/output"
71+
manifest {
72+
def libList = configurations.pluginLibs.collect{'lib/' + it.name}.join(' ')
73+
attributes 'Rundeck-Plugin-Classnames': pluginClassNames
74+
attributes 'Rundeck-Plugin-File-Version': project.version
75+
attributes 'Rundeck-Plugin-Version': rundeckPluginVersion
76+
attributes 'Rundeck-Plugin-Archive': 'true'
77+
attributes 'Rundeck-Plugin-Libs': "${libList}"
78+
}
79+
dependsOn(copyToLib)
80+
}

images/clone-workflow-step.png

191 KB
Loading

images/resource_model.png

222 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package com.rundeck.plugin
2+
3+
import com.dtolabs.rundeck.core.execution.workflow.steps.StepException
4+
import com.dtolabs.rundeck.core.plugins.Plugin
5+
import com.dtolabs.rundeck.core.plugins.configuration.Describable
6+
import com.dtolabs.rundeck.core.plugins.configuration.Description
7+
import com.dtolabs.rundeck.core.plugins.configuration.PropertyUtil
8+
import com.dtolabs.rundeck.plugins.PluginLogger
9+
import com.dtolabs.rundeck.plugins.ServiceNameConstants
10+
import com.dtolabs.rundeck.plugins.descriptions.PluginDescription
11+
import com.dtolabs.rundeck.plugins.step.PluginStepContext
12+
import com.dtolabs.rundeck.plugins.step.StepPlugin
13+
import com.dtolabs.rundeck.plugins.util.DescriptionBuilder
14+
import com.rundeck.plugin.util.GitPluginUtil
15+
import groovy.json.JsonOutput
16+
17+
18+
@Plugin(name = GitCloneWorkflowStep.PROVIDER_NAME, service = ServiceNameConstants.WorkflowStep)
19+
@PluginDescription(title = GitCloneWorkflowStep.PROVIDER_TITLE, description = GitCloneWorkflowStep.PROVIDER_DESCRIPTION)
20+
class GitCloneWorkflowStep implements StepPlugin, Describable{
21+
public static final String PROVIDER_NAME = "git-clone-step";
22+
public static final String PROVIDER_TITLE = "Git / Clone"
23+
public static final String PROVIDER_DESCRIPTION ="Clone a Git repository on Rundeck server"
24+
25+
public final static String GIT_URL="gitUrl"
26+
public final static String GIT_BASE_DIRECTORY="gitBaseDirectory"
27+
public final static String GIT_BRANCH="gitBranch"
28+
public final static String GIT_HOSTKEY_CHECKING="strictHostKeyChecking"
29+
public final static String GIT_KEY_STORAGE="gitKeyPath"
30+
public final static String GIT_PASSWORD_STORAGE="gitPasswordPath"
31+
32+
33+
final static Map<String, Object> renderingOptionsAuthentication = GitPluginUtil.getRenderOpt("Authentication", false)
34+
final static Map<String, Object> renderingOptionsAuthenticationPassword = GitPluginUtil.getRenderOpt("Authentication",false, false, true)
35+
final static Map<String, Object> renderingOptionsAuthenticationKey = GitPluginUtil.getRenderOpt("Authentication",false, false, false, true)
36+
37+
final static Map<String, Object> renderingOptionsConfig = GitPluginUtil.getRenderOpt("Configuration",false)
38+
39+
GitManager gitManager
40+
41+
static Description DESCRIPTION = DescriptionBuilder.builder()
42+
.name(PROVIDER_NAME)
43+
.title(PROVIDER_TITLE)
44+
.description(PROVIDER_DESCRIPTION)
45+
.property(
46+
PropertyUtil.string(GIT_BASE_DIRECTORY, "Base Directory", "Directory for checkout.", true,
47+
null, null, null, renderingOptionsConfig))
48+
.property(PropertyUtil.string(GIT_URL, "Git URL", '''Checkout url.
49+
See [git-clone](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html)
50+
specifically the [GIT URLS](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS) section.
51+
Some examples:
52+
* `ssh://[user@]host.xz[:port]/path/to/repo.git/`
53+
* `git://host.xz[:port]/path/to/repo.git/`
54+
* `http[s]://host.xz[:port]/path/to/repo.git/`
55+
* `ftp[s]://host.xz[:port]/path/to/repo.git/`
56+
* `rsync://host.xz/path/to/repo.git/`''', true,
57+
null,null,null, renderingOptionsConfig))
58+
.property(PropertyUtil.string(GIT_BRANCH, "Branch", "Checkout branch.", true,
59+
"master",null,null, renderingOptionsConfig))
60+
.property(PropertyUtil.string(GIT_PASSWORD_STORAGE, "Git Password", 'Password to authenticate remotely', false,
61+
null,null,null, renderingOptionsAuthenticationPassword))
62+
.property(PropertyUtil.select(GIT_HOSTKEY_CHECKING, "SSH: Strict Host Key Checking", '''Use strict host key checking.
63+
If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` file, otherwise do not verify.''', false,
64+
"yes",GitResourceModelFactory.LIST_HOSTKEY_CHECKING,null, renderingOptionsAuthentication))
65+
.property(PropertyUtil.string(GIT_KEY_STORAGE, "SSH Key Path", 'SSH Key Path', false,
66+
null,null,null, renderingOptionsAuthenticationKey))
67+
.build()
68+
69+
GitCloneWorkflowStep() {
70+
}
71+
72+
@Override
73+
Description getDescription() {
74+
return DESCRIPTION
75+
}
76+
77+
@Override
78+
void executeStep(final PluginStepContext context, final Map<String, Object> configuration) throws StepException {
79+
Properties proConfiguration = new Properties()
80+
proConfiguration.putAll(configuration)
81+
82+
if(gitManager==null){
83+
gitManager = new GitManager(proConfiguration)
84+
}
85+
86+
def localPath=configuration.get(GIT_BASE_DIRECTORY)
87+
88+
if(configuration.get(GIT_PASSWORD_STORAGE)){
89+
def password = GitPluginUtil.getFromKeyStorage(configuration.get(GIT_PASSWORD_STORAGE), context)
90+
gitManager.setGitPassword(password)
91+
}
92+
93+
if(configuration.get(GIT_KEY_STORAGE)){
94+
def key = GitPluginUtil.getFromKeyStorage(configuration.get(GIT_KEY_STORAGE), context)
95+
gitManager.setSshPrivateKey(key)
96+
}
97+
98+
PluginLogger logger = context.getLogger()
99+
logger.log(3, "Cloning Repo ${gitManager.gitURL} to local path ${localPath}")
100+
101+
File base = new File(localPath)
102+
103+
if(!base){
104+
base.mkdir()
105+
}
106+
107+
try{
108+
gitManager.cloneOrCreate(base)
109+
110+
def jsonMap = base.listFiles().collect {file ->
111+
return [name: file.name, directory: file.directory, file: file.file, path: file.absolutePath]
112+
}
113+
def json = JsonOutput.toJson(jsonMap)
114+
logger.log(2, json)
115+
116+
}catch(Exception e){
117+
logger.log(0, e.getMessage())
118+
throw new StepException("Error ${op} VM.", GitFailureReason.AuthenticationError)
119+
120+
}
121+
122+
123+
124+
}
125+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.rundeck.plugin
2+
3+
import com.dtolabs.rundeck.core.execution.workflow.steps.FailureReason
4+
5+
enum GitFailureReason implements FailureReason {
6+
7+
/**
8+
* Authentication Error
9+
*/
10+
AuthenticationError,
11+
12+
}

0 commit comments

Comments
 (0)