Skip to content
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
26 changes: 25 additions & 1 deletion src/main/groovy/com/rundeck/plugin/GitCloneWorkflowStep.groovy
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.rundeck.plugin

import com.dtolabs.rundeck.core.execution.ExecutionListener
import com.dtolabs.rundeck.core.execution.ExecutionContext
import com.dtolabs.rundeck.core.execution.proxy.ProxyRunnerPlugin
import com.dtolabs.rundeck.core.execution.proxy.ProxySecretBundleCreator
import com.dtolabs.rundeck.core.execution.proxy.SecretBundle
import com.dtolabs.rundeck.core.execution.workflow.steps.StepException
import com.dtolabs.rundeck.core.plugins.Plugin
import com.dtolabs.rundeck.core.plugins.configuration.Describable
Expand All @@ -21,7 +25,7 @@ import groovy.json.JsonOutput

@Plugin(name = GitCloneWorkflowStep.PROVIDER_NAME, service = ServiceNameConstants.WorkflowStep)
@PluginDescription(title = GitCloneWorkflowStep.PROVIDER_TITLE, description = GitCloneWorkflowStep.PROVIDER_DESCRIPTION)
class GitCloneWorkflowStep implements StepPlugin, Describable{
class GitCloneWorkflowStep implements StepPlugin, Describable, ProxyRunnerPlugin, ProxySecretBundleCreator{
public static final String PROVIDER_NAME = "git-clone-step"
public static final String PROVIDER_TITLE = "Git / Clone"
public static final String PROVIDER_DESCRIPTION ="Clone a Git repository on Rundeck server"
Expand All @@ -34,6 +38,7 @@ class GitCloneWorkflowStep implements StepPlugin, Describable{
public final static String GIT_KEY_STORAGE="gitKeyPath"
public final static String GIT_PASSWORD_STORAGE="gitPasswordPath"
public final static String GIT_PROJECT_BASED_SUBDIRECTORY="gitUseProjectBasedSubdirectory"
public final static String GIT_REPO_NAME_SUBDIRECTORY="gitUseRepoNameSubdirectory"


final static Map<String, Object> renderingOptionsAuthentication = GitPluginUtil.getRenderOpt("Authentication", false)
Expand Down Expand Up @@ -74,6 +79,8 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil
null,null,null, renderingOptionsAuthenticationKey))
.property(PropertyUtil.bool(GIT_PROJECT_BASED_SUBDIRECTORY, "Use per-project subdirectories", "Check repositories out in project-based subdirectories of the Rundeck home directory.",
false, "false", PropertyScope.Project, renderingOptionsConfig))
.property(PropertyUtil.bool(GIT_REPO_NAME_SUBDIRECTORY, "Clone into repo name subdirectory", "Clone into a subdirectory named after the Git repository under the base directory.",
false, "false", null, renderingOptionsConfig))
.build()

GitCloneWorkflowStep() {
Expand Down Expand Up @@ -104,6 +111,13 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil
localPath = configuration.get(GIT_BASE_DIRECTORY)
}

if (Boolean.parseBoolean((String) configuration.get(GIT_REPO_NAME_SUBDIRECTORY))) {
String repoName = GitPluginUtil.extractRepoName((String) configuration.get(GIT_URL))
if (repoName) {
localPath = new File(localPath, repoName).getPath()
}
}

if(configuration.get(GIT_PASSWORD_STORAGE)){
def password = GitPluginUtil.getFromKeyStorage(configuration.get(GIT_PASSWORD_STORAGE), context)
gitManager.setGitPassword(password)
Expand Down Expand Up @@ -146,4 +160,14 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil


}

@Override
List<String> listSecretsPathWorkflowStep(ExecutionContext context, Map<String, Object> configuration) {
return GitPluginUtil.listSecretsPathForStep(context, configuration, GIT_PASSWORD_STORAGE, GIT_KEY_STORAGE)
}

@Override
SecretBundle prepareSecretBundleWorkflowStep(ExecutionContext context, Map<String, Object> configuration) {
return GitPluginUtil.prepareSecretBundleForStep(context, configuration, GIT_PASSWORD_STORAGE, GIT_KEY_STORAGE)
}
}
26 changes: 25 additions & 1 deletion src/main/groovy/com/rundeck/plugin/GitCommitWorkflowStep.groovy
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.rundeck.plugin

import com.dtolabs.rundeck.core.execution.ExecutionListener
import com.dtolabs.rundeck.core.execution.ExecutionContext
import com.dtolabs.rundeck.core.execution.proxy.ProxyRunnerPlugin
import com.dtolabs.rundeck.core.execution.proxy.ProxySecretBundleCreator
import com.dtolabs.rundeck.core.execution.proxy.SecretBundle
import com.dtolabs.rundeck.core.execution.workflow.steps.StepException
import com.dtolabs.rundeck.core.plugins.Plugin
import com.dtolabs.rundeck.core.plugins.configuration.Describable
Expand All @@ -21,7 +25,7 @@ import groovy.json.JsonOutput

@Plugin(name = GitCommitWorkflowStep.PROVIDER_NAME, service = ServiceNameConstants.WorkflowStep)
@PluginDescription(title = GitCommitWorkflowStep.PROVIDER_TITLE, description = GitCommitWorkflowStep.PROVIDER_DESCRIPTION)
class GitCommitWorkflowStep implements StepPlugin, Describable{
class GitCommitWorkflowStep implements StepPlugin, Describable, ProxyRunnerPlugin, ProxySecretBundleCreator{
public static final String PROVIDER_NAME = "git-commit-step"
public static final String PROVIDER_TITLE = "Git / Commit"
public static final String PROVIDER_DESCRIPTION ="Commit a Git repository on Rundeck server"
Expand All @@ -36,6 +40,7 @@ class GitCommitWorkflowStep implements StepPlugin, Describable{
public final static String GIT_KEY_STORAGE="gitKeyPath"
public final static String GIT_PASSWORD_STORAGE="gitPasswordPath"
public final static String GIT_PROJECT_BASED_SUBDIRECTORY="gitUseProjectBasedSubdirectory"
public final static String GIT_REPO_NAME_SUBDIRECTORY="gitUseRepoNameSubdirectory"


final static Map<String, Object> renderingOptionsAuthentication = GitPluginUtil.getRenderOpt("Authentication", false)
Expand Down Expand Up @@ -80,6 +85,8 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil
null,null,null, renderingOptionsAuthenticationKey))
.property(PropertyUtil.bool(GIT_PROJECT_BASED_SUBDIRECTORY, "Use per-project subdirectories", "Check repositories out in project-based subdirectories of the Rundeck home directory.",
false, "false", PropertyScope.Project, renderingOptionsConfig))
.property(PropertyUtil.bool(GIT_REPO_NAME_SUBDIRECTORY, "Clone into repo name subdirectory", "Use a subdirectory named after the Git repository under the base directory.",
false, "false", null, renderingOptionsConfig))
.build()

GitCommitWorkflowStep() {
Expand Down Expand Up @@ -110,6 +117,13 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil
localPath = configuration.get(GIT_BASE_DIRECTORY)
}

if (Boolean.parseBoolean((String) configuration.get(GIT_REPO_NAME_SUBDIRECTORY))) {
String repoName = GitPluginUtil.extractRepoName((String) configuration.get(GIT_URL))
if (repoName) {
localPath = new File(localPath, repoName).getPath()
}
}

if(configuration.get(GIT_PASSWORD_STORAGE)){
def password = GitPluginUtil.getFromKeyStorage(configuration.get(GIT_PASSWORD_STORAGE), context)
gitManager.setGitPassword(password)
Expand Down Expand Up @@ -156,4 +170,14 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil


}

@Override
List<String> listSecretsPathWorkflowStep(ExecutionContext context, Map<String, Object> configuration) {
return GitPluginUtil.listSecretsPathForStep(context, configuration, GIT_PASSWORD_STORAGE, GIT_KEY_STORAGE)
}

@Override
SecretBundle prepareSecretBundleWorkflowStep(ExecutionContext context, Map<String, Object> configuration) {
return GitPluginUtil.prepareSecretBundleForStep(context, configuration, GIT_PASSWORD_STORAGE, GIT_KEY_STORAGE)
}
}
35 changes: 27 additions & 8 deletions src/main/groovy/com/rundeck/plugin/GitManager.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.rundeck.plugin
import com.rundeck.plugin.util.PluginSshSessionFactory
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.api.PullResult
import org.eclipse.jgit.api.ResetCommand
import org.eclipse.jgit.transport.PushResult
import org.eclipse.jgit.api.TransportCommand
import org.eclipse.jgit.lib.Repository
Expand Down Expand Up @@ -115,6 +116,8 @@ class GitManager {
logger.debug("branch differs, re-cloning")
needsClone = true
} else {
agit.reset().setMode(ResetCommand.ResetType.HARD).call()
agit.clean().setCleanDirectories(true).setForce(true).call()
performPull(agit)
}

Expand Down Expand Up @@ -175,14 +178,16 @@ class GitManager {
setURI(this.gitURL).
setCloneSubmodules(true)


PluginSshSessionFactory sshFactory = null
try {
setupTransportAuthentication(sshConfig, cloneCommand, this.gitURL)
sshFactory = setupTransportAuthentication(sshConfig, cloneCommand, this.gitURL)
git = withPluginClassLoader { cloneCommand.call() }
} catch (Exception e) {
e.printStackTrace()
logger.debug("Failed cloning the repository from ${this.gitURL}: ${e.message}", e)
throw new Exception("Failed cloning the repository from ${this.gitURL}: ${e.message}", e)
} finally {
sshFactory?.close()
}
repo = git.getRepository()
}
Expand All @@ -193,8 +198,9 @@ class GitManager {
def pullCommand = git.pull()
.setRebase(true)

PluginSshSessionFactory sshFactory = null
try {
setupTransportAuthentication(sshConfig, pullCommand, this.gitURL)
sshFactory = setupTransportAuthentication(sshConfig, pullCommand, this.gitURL)
PullResult result = withPluginClassLoader { pullCommand.call() }
if (!result.isSuccessful()) {
logger.info("Pull is not successful.")
Expand All @@ -205,6 +211,8 @@ class GitManager {
e.printStackTrace()
logger.debug("Failed pulling the repository from ${this.gitURL}: ${e.message}", e)
throw new Exception("Failed pulling the repository from ${this.gitURL}: ${e.message}", e)
} finally {
sshFactory?.close()
}
repo = git.getRepository()
}
Expand All @@ -213,14 +221,17 @@ class GitManager {
def pushCommand = git.push()
.setPushAll()

PluginSshSessionFactory sshFactory = null
try {
setupTransportAuthentication(sshConfig, pushCommand, this.gitURL)
sshFactory = setupTransportAuthentication(sshConfig, pushCommand, this.gitURL)
withPluginClassLoader { pushCommand.call() }
logger.info("Push is not successful.")
} catch (Exception e) {
e.printStackTrace()
logger.debug("Failed pushing the repository to ${this.gitURL}: ${e.message}", e)
throw new Exception("Failed pushing the repository to ${this.gitURL}: ${e.message}", e)
} finally {
sshFactory?.close()
}
}

Expand Down Expand Up @@ -254,7 +265,7 @@ class GitManager {
}
}

void setupTransportAuthentication(
PluginSshSessionFactory setupTransportAuthentication(
Map<String, String> sshConfig,
TransportCommand command,
String url = null) throws Exception {
Expand Down Expand Up @@ -283,19 +294,25 @@ class GitManager {
def factory = new PluginSshSessionFactory(keyData)
factory.sshConfig = sshConfig
command.setTransportConfigCallback(factory)
return factory
} else if (u.user && gitPassword) {
logger.debug("using password")

if (null != gitPassword && gitPassword.length() > 0) {
command.setCredentialsProvider(new UsernamePasswordCredentialsProvider(u.user, gitPassword))
}
}
return null
}

PullResult gitPull(Git git1 = null) {
def pullCommand = (git1 ?: git).pull().setRemote(REMOTE_NAME).setRemoteBranchName(branch)
setupTransportAuthentication(sshConfig, pullCommand)
withPluginClassLoader { pullCommand.call() }
PluginSshSessionFactory sshFactory = setupTransportAuthentication(sshConfig, pullCommand)
try {
return withPluginClassLoader { pullCommand.call() }
} finally {
sshFactory?.close()
}
}

def gitCommitAndPush() {
Expand All @@ -317,14 +334,16 @@ class GitManager {
def pushb = git.push()
pushb.setRemote(REMOTE_NAME)
pushb.add(branch)
setupTransportAuthentication(sshConfig, pushb)
PluginSshSessionFactory sshFactory = setupTransportAuthentication(sshConfig, pushb)

def push
try {
push = withPluginClassLoader { pushb.call() }
} catch (Exception e) {
logger.debug("Failed push to remote: ${e.message}", e)
throw new Exception("Failed push to remote: ${e.message}", e)
} finally {
sshFactory?.close()
}
def sb = new StringBuilder()
def updates = (push*.remoteUpdates).flatten()
Expand Down
26 changes: 25 additions & 1 deletion src/main/groovy/com/rundeck/plugin/GitPushWorkflowStep.groovy
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.rundeck.plugin

import com.dtolabs.rundeck.core.execution.ExecutionListener
import com.dtolabs.rundeck.core.execution.ExecutionContext
import com.dtolabs.rundeck.core.execution.proxy.ProxyRunnerPlugin
import com.dtolabs.rundeck.core.execution.proxy.ProxySecretBundleCreator
import com.dtolabs.rundeck.core.execution.proxy.SecretBundle
import com.dtolabs.rundeck.core.execution.workflow.steps.StepException
import com.dtolabs.rundeck.core.plugins.Plugin
import com.dtolabs.rundeck.core.plugins.configuration.Describable
Expand All @@ -21,7 +25,7 @@ import groovy.json.JsonOutput

@Plugin(name = GitPushWorkflowStep.PROVIDER_NAME, service = ServiceNameConstants.WorkflowStep)
@PluginDescription(title = GitPushWorkflowStep.PROVIDER_TITLE, description = GitPushWorkflowStep.PROVIDER_DESCRIPTION)
class GitPushWorkflowStep implements StepPlugin, Describable{
class GitPushWorkflowStep implements StepPlugin, Describable, ProxyRunnerPlugin, ProxySecretBundleCreator{
public static final String PROVIDER_NAME = "git-push-step"
public static final String PROVIDER_TITLE = "Git / Push"
public static final String PROVIDER_DESCRIPTION ="Push a Git repository on Rundeck server"
Expand All @@ -33,6 +37,7 @@ class GitPushWorkflowStep implements StepPlugin, Describable{
public final static String GIT_KEY_STORAGE="gitKeyPath"
public final static String GIT_PASSWORD_STORAGE="gitPasswordPath"
public final static String GIT_PROJECT_BASED_SUBDIRECTORY="gitUseProjectBasedSubdirectory"
public final static String GIT_REPO_NAME_SUBDIRECTORY="gitUseRepoNameSubdirectory"


final static Map<String, Object> renderingOptionsAuthentication = GitPluginUtil.getRenderOpt("Authentication", false)
Expand Down Expand Up @@ -71,6 +76,8 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil
null,null,null, renderingOptionsAuthenticationKey))
.property(PropertyUtil.bool(GIT_PROJECT_BASED_SUBDIRECTORY, "Use per-project subdirectories", "Check repositories out in project-based subdirectories of the Rundeck home directory.",
false, "false", PropertyScope.Project, renderingOptionsConfig))
.property(PropertyUtil.bool(GIT_REPO_NAME_SUBDIRECTORY, "Clone into repo name subdirectory", "Use a subdirectory named after the Git repository under the base directory.",
false, "false", null, renderingOptionsConfig))
.build()

GitPushWorkflowStep() {
Expand Down Expand Up @@ -101,6 +108,13 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil
localPath = configuration.get(GIT_BASE_DIRECTORY)
}

if (Boolean.parseBoolean((String) configuration.get(GIT_REPO_NAME_SUBDIRECTORY))) {
String repoName = GitPluginUtil.extractRepoName((String) configuration.get(GIT_URL))
if (repoName) {
localPath = new File(localPath, repoName).getPath()
}
}

if(configuration.get(GIT_PASSWORD_STORAGE)){
def password = GitPluginUtil.getFromKeyStorage(configuration.get(GIT_PASSWORD_STORAGE), context)
gitManager.setGitPassword(password)
Expand Down Expand Up @@ -139,4 +153,14 @@ If `yes`, require remote host SSH key is defined in the `~/.ssh/known_hosts` fil


}

@Override
List<String> listSecretsPathWorkflowStep(ExecutionContext context, Map<String, Object> configuration) {
return GitPluginUtil.listSecretsPathForStep(context, configuration, GIT_PASSWORD_STORAGE, GIT_KEY_STORAGE)
}

@Override
SecretBundle prepareSecretBundleWorkflowStep(ExecutionContext context, Map<String, Object> configuration) {
return GitPluginUtil.prepareSecretBundleForStep(context, configuration, GIT_PASSWORD_STORAGE, GIT_KEY_STORAGE)
}
}
Loading