Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the ability to pull the Git password and ssh key from Key Stor… #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,26 @@ configurations {


dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.11'
compile 'org.codehaus.groovy:groovy-all:3.0.0'
testCompile group: 'junit', name: 'junit', version: '4.12'

compile group: 'org.rundeck', name: 'rundeck-core', version: '2.10.1'
compile 'org.slf4j:slf4j-api:1.7.30'
compile group: 'org.rundeck', name: 'rundeck-core', version: '4.14.0-20230615'
compile group: 'org.rundeck', name: 'rundeck-storage-api', version: '4.14.0-20230615'
compile 'org.slf4j:slf4j-api:2.0.7'

pluginLibs( 'org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r') {
pluginLibs( 'org.eclipse.jgit:org.eclipse.jgit:6.6.0.202305301015-r') {
exclude module: 'slf4j-api'
exclude module: 'jsch'
exclude module: 'commons-logging'
}

testCompile "org.codehaus.groovy:groovy-all:2.3.7"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
pluginLibs( 'org.eclipse.jgit:org.eclipse.jgit.ssh.jsch:6.6.0.202305301015-r') {
exclude module: 'slf4j-api'
exclude module: 'commons-logging'
}

testCompile "org.codehaus.groovy:groovy-all:3.0.0"
testCompile "org.spockframework:spock-core:2.4-M1-groovy-3.0"
testCompile "cglib:cglib-nodep:2.2.2"
testCompile 'org.objenesis:objenesis:1.4'
}
Expand All @@ -85,7 +91,7 @@ jar {


task wrapper(type: Wrapper) {
gradleVersion = '3.3'
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
gradleVersion = '3.3'
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}

9 changes: 9 additions & 0 deletions src/main/groovy/com/rundeck/plugin/GitFailureReason.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.rundeck.plugin

import com.dtolabs.rundeck.core.execution.workflow.steps.FailureReason

enum GitFailureReason implements FailureReason{

KeyStorage

}
23 changes: 21 additions & 2 deletions src/main/groovy/com/rundeck/plugin/GitManager.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import org.eclipse.jgit.transport.RemoteRefUpdate
import org.eclipse.jgit.transport.URIish
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider
import org.eclipse.jgit.util.FileUtils
import org.rundeck.app.spi.Services
import com.dtolabs.rundeck.core.storage.keys.KeyStorageTree
import com.rundeck.plugin.util.GitPluginUtil

import java.nio.file.Files
import java.nio.file.Path
Expand All @@ -34,15 +37,20 @@ class GitManager {
String sshPrivateKeyPath
String gitPassword
String gitURL
String gitPasswordKeyStoragePath
String gitSshKeyKeyStoragePath
Services services

GitManager(Properties configuration) {
GitManager(Properties configuration, Services services) {
this.gitURL=configuration.getProperty(GitResourceModelFactory.GIT_URL)
this.branch = configuration.getProperty(GitResourceModelFactory.GIT_BRANCH)
this.fileName=configuration.getProperty(GitResourceModelFactory.GIT_FILE)
this.strictHostKeyChecking=configuration.getProperty(GitResourceModelFactory.GIT_HOSTKEY_CHECKING)
sshPrivateKeyPath=configuration.getProperty(GitResourceModelFactory.GIT_KEY_STORAGE)
gitPassword=configuration.getProperty(GitResourceModelFactory.GIT_PASSWORD_STORAGE)

this.gitPasswordKeyStoragePath=configuration.getProperty(GitResourceModelFactory.GIT_PASSWORD_KEY_STORAGE_PATH)
this.gitSshKeyKeyStoragePath=configuration.getProperty(GitResourceModelFactory.GIT_SSH_KEY_KEY_STORAGE_PATH)
this.services = services
}

Map<String, String> getSshConfig() {
Expand Down Expand Up @@ -130,6 +138,17 @@ class GitManager {
def factory = new PluginSshSessionFactory(keyData)
factory.sshConfig = sshConfig
command.setTransportConfigCallback(factory)
} else if ((u.scheme == null || u.scheme == 'ssh') && u.user && gitSshKeyKeyStoragePath) {
KeyStorageTree keyStorage = services.getService(KeyStorageTree.class)
String key = GitPluginUtil.getPasswordFromKeyStorage(gitSshKeyKeyStoragePath, keyStorage)
byte[] keyData = key.getBytes();
def factory = new PluginSshSessionFactory(keyData)
factory.sshConfig = sshConfig
command.setTransportConfigCallback(factory)
} else if (u.user && gitPasswordKeyStoragePath) {
KeyStorageTree keyStorage = services.getService(KeyStorageTree.class)
String key = GitPluginUtil.getPasswordFromKeyStorage(gitPasswordKeyStoragePath, keyStorage)
command.setCredentialsProvider(new UsernamePasswordCredentialsProvider(u.user, key))
} else if (u.user && gitPassword) {
logger.debug("using password")

Expand Down
9 changes: 5 additions & 4 deletions src/main/groovy/com/rundeck/plugin/GitResourceModel.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.dtolabs.rundeck.core.resources.format.ResourceFormatParser
import com.dtolabs.rundeck.core.resources.format.ResourceFormatParserException
import com.dtolabs.rundeck.core.resources.format.UnsupportedFormatException
import com.dtolabs.utils.Streams
import org.rundeck.app.spi.Services


/**
Expand All @@ -19,6 +20,7 @@ class GitResourceModel implements ResourceModelSource , WriteableModelSource{

private Properties configuration;
private Framework framework;
Services services
private boolean writable=false;

String extension
Expand All @@ -31,20 +33,19 @@ class GitResourceModel implements ResourceModelSource , WriteableModelSource{
this.writable=true;
}


GitResourceModel(Properties configuration, Framework framework) {
GitResourceModel(Properties configuration, Framework framework, Services services) {
this.configuration = configuration
this.framework = framework
this.services = services

this.extension=configuration.getProperty(GitResourceModelFactory.GIT_FORMAT_FILE)
this.writable=Boolean.valueOf(configuration.getProperty(GitResourceModelFactory.WRITABLE))
this.fileName=configuration.getProperty(GitResourceModelFactory.GIT_FILE)
this.localPath=configuration.getProperty(GitResourceModelFactory.GIT_BASE_DIRECTORY)

if(gitManager==null){
gitManager = new GitManager(configuration)
gitManager = new GitManager(configuration, services)
}

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.dtolabs.rundeck.plugins.ServiceNameConstants
import com.dtolabs.rundeck.plugins.descriptions.PluginDescription
import com.dtolabs.rundeck.plugins.util.DescriptionBuilder
import com.rundeck.plugin.util.GitPluginUtil
import org.rundeck.app.spi.Services


/**
* Created by luistoledo on 12/18/17.
Expand All @@ -38,11 +40,15 @@ class GitResourceModelFactory implements ResourceModelSourceFactory,Describable
public final static String GIT_KEY_STORAGE="gitKeyPath"
public final static String GIT_PASSWORD_STORAGE="gitPasswordPath"
public static final String WRITABLE="writable";
public static final String GIT_PASSWORD_KEY_STORAGE_PATH = "gitPasswordKeyStoragePath"
public static final String GIT_SSH_KEY_KEY_STORAGE_PATH = "gitSshKeyKeyStoragePath"



final static Map<String, Object> renderingOptionsAuthentication = GitPluginUtil.getRenderOpt("Authentication",false)
final static Map<String, Object> renderingOptionsAuthenticationPassword = GitPluginUtil.getRenderOpt("Authentication",false, true)
final static Map<String, Object> renderingOptionsConfig = GitPluginUtil.getRenderOpt("Configuration",false)
final static Map<String, Object> renderingOptionsAuthenticationStorage = GitPluginUtil.getRenderOpt("Authentication",false, false, true)

GitResourceModelFactory(Framework framework) {
this.framework = framework
Expand Down Expand Up @@ -79,7 +85,11 @@ Some examples:
If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` file, otherwise do not verify.''', false,
"yes",GitResourceModelFactory.LIST_HOSTKEY_CHECKING,null, renderingOptionsAuthentication))
.property(PropertyUtil.string(GIT_KEY_STORAGE, "SSH Key Path", 'SSH Key Path', false,
null,null,null, renderingOptionsAuthentication))
null,null,null, renderingOptionsAuthentication))
.property(PropertyUtil.string(GIT_PASSWORD_KEY_STORAGE_PATH, "Password Key Storage Path", "Access password from Rundeck key storage path", false,
null,null,null, renderingOptionsAuthenticationStorage))
.property(PropertyUtil.string(GIT_SSH_KEY_KEY_STORAGE_PATH, "SSH Key Storage Path", "Access SSH key from Rundeck key storage path", false,
null,null,null, renderingOptionsAuthenticationStorage))
.build()


Expand All @@ -95,4 +105,13 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil

return resource
}

@Override
ResourceModelSource createResourceModelSource(Services services, Properties configuration) throws ConfigurationException {
final GitResourceModel resource = new GitResourceModel(configuration,framework,services)

return resource
}


}
31 changes: 30 additions & 1 deletion src/main/groovy/com/rundeck/plugin/util/GitPluginUtil.groovy
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.rundeck.plugin.util

import com.dtolabs.rundeck.core.execution.workflow.steps.StepException
import com.dtolabs.rundeck.core.plugins.configuration.StringRenderingConstants
import com.dtolabs.rundeck.core.storage.ResourceMeta
import com.dtolabs.rundeck.plugins.step.PluginStepContext
import com.dtolabs.rundeck.core.storage.StorageTree
import com.rundeck.plugin.GitFailureReason


/**
* Created by luistoledo on 12/18/17.
Expand All @@ -26,4 +29,30 @@ class GitPluginUtil {
return ret;
}

static String getPasswordFromKeyStorage(String path, StorageTree storage) {
try{
ResourceMeta contents = storage.getResource(path).getContents()
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()
contents.writeContent(byteArrayOutputStream)
String password = new String(byteArrayOutputStream.toByteArray())

return password
}catch(Exception e){
throw new StepException("error accessing ${path}: ${e.message}", GitFailureReason.KeyStorage)
}

}

static String getSshKeyFromKeyStorage(String path, StorageTree storage) {
try{
ResourceMeta contents = storage.getResource(path).getContents()
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()
contents.writeContent(byteArrayOutputStream)
return byteArrayOutputStream.toByteArray()
}catch(Exception e){
throw new StepException("error accessing ${path}: ${e.message}", GitFailureReason.KeyStorage)
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import com.jcraft.jsch.JSch
import com.jcraft.jsch.JSchException
import com.jcraft.jsch.Session
import org.eclipse.jgit.api.TransportConfigCallback
import org.eclipse.jgit.transport.JschConfigSessionFactory
import org.eclipse.jgit.transport.OpenSshConfig
import org.eclipse.jgit.transport.ssh.jsch.JschConfigSessionFactory
import org.eclipse.jgit.transport.ssh.jsch.OpenSshConfig
import org.eclipse.jgit.transport.SshTransport
import org.eclipse.jgit.transport.Transport
import org.eclipse.jgit.util.FS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.dtolabs.rundeck.core.common.INodeSet
import com.dtolabs.rundeck.core.resources.format.ResourceFormatParser
import com.dtolabs.rundeck.core.resources.format.ResourceFormatParserService
import spock.lang.Specification
import org.apache.log4j.Logger

/**
* Created by luistoledo on 12/22/17.
Expand Down