package org.jfrog.hudson.pipeline;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.*;
import hudson.plugins.git.util.BuildData;
import hudson.remoting.Callable;
import hudson.util.ArgumentListBuilder;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import org.apache.commons.io.IOUtils;
import org.jfrog.build.api.BuildInfoFields;
import org.jfrog.build.api.Vcs;
import org.jfrog.build.extractor.clientConfiguration.IncludeExcludePatterns;
import org.jfrog.hudson.CredentialsConfig;
import org.jfrog.hudson.pipeline.docker.proxy.CertManager;
import org.jfrog.hudson.pipeline.types.ArtifactoryServer;
import org.jfrog.hudson.pipeline.types.PromotionConfig;
import org.jfrog.hudson.pipeline.types.buildInfo.BuildInfo;
import org.jfrog.hudson.util.IncludesExcludes;
import org.jfrog.hudson.util.RepositoriesUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.*;
/**
* Created by romang on 4/24/16.
*/
public class Utils {
public static final String BUILD_INFO_DELIMITER = ".";
public static final String CONAN_USER_HOME = "CONAN_USER_HOME";
/**
* Prepares Artifactory server either from serverID or from ArtifactoryServer.
*
* @param artifactoryServerID
* @param pipelineServer
* @return
*/
public static org.jfrog.hudson.ArtifactoryServer prepareArtifactoryServer(String artifactoryServerID,
ArtifactoryServer pipelineServer) {
if (artifactoryServerID == null && pipelineServer == null) {
return null;
}
if (artifactoryServerID != null && pipelineServer != null) {
return null;
}
if (pipelineServer != null) {
CredentialsConfig credentials = pipelineServer.createCredentialsConfig();
return new org.jfrog.hudson.ArtifactoryServer(null, pipelineServer.getUrl(), credentials,
credentials, pipelineServer.getConnection().getTimeout(), pipelineServer.isBypassProxy(), pipelineServer.getConnection().getRetry());
}
org.jfrog.hudson.ArtifactoryServer server = RepositoriesUtils.getArtifactoryServer(artifactoryServerID, RepositoriesUtils.getArtifactoryServers());
if (server == null) {
return null;
}
return server;
}
public static ListBoxModel getServerListBox() {
ListBoxModel r = new ListBoxModel();
List<org.jfrog.hudson.ArtifactoryServer> servers = RepositoriesUtils.getArtifactoryServers();
r.add("", "");
for (org.jfrog.hudson.ArtifactoryServer server : servers) {
r.add(server.getName() + Utils.BUILD_INFO_DELIMITER + server.getUrl(), server.getName());
}
return r;
}
public static BuildInfo prepareBuildinfo(Run build, BuildInfo buildinfo) {
if (buildinfo == null) {
return new BuildInfo(build);
}
return buildinfo;
}
public static ObjectMapper mapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
public static EnvVars extractBuildParameters(Run build, TaskListener listener) {
EnvVars buildVariables = new EnvVars();
try {
ParametersAction parameters = build.getAction(ParametersAction.class);
if (parameters != null) {
for (ParameterValue p : parameters) {
if (p.isSensitive()) {
continue;
}
String v = p.createVariableResolver(null).resolve(p.getName());
if (v != null) {
buildVariables.put(p.getName(), v);
}
}
}
} catch (Exception e) {
listener.getLogger().println("Can't get build variables");
return null;
}
return buildVariables;
}
public static List<Vcs> extractVcsBuildData(Run build) {
List<Vcs> result = new ArrayList<Vcs>();
List<BuildData> buildData = build.getActions(BuildData.class);
if (buildData != null) {
for (BuildData data : buildData) {
String sha1 = data.getLastBuiltRevision().getSha1String();
Iterator<String> iterator = data.getRemoteUrls().iterator();
if (iterator.hasNext()) {
result.add(new Vcs(iterator.next(), sha1));
}
}
}
return result;
}
public static Node getNode(Launcher launcher) {
Node node = null;
Jenkins j = Jenkins.getInstance();
for (Computer c : j.getComputers()) {
if (c.getChannel() == launcher.getChannel()) {
node = c.getNode();
break;
}
}
return node;
}
public static Computer getCurrentComputer(Launcher launcher) {
Jenkins j = Jenkins.getInstance();
for (Computer c : j.getComputers()) {
if (c.getChannel() == launcher.getChannel()) {
return c;
}
}
return null;
}
public static IncludesExcludes getArtifactsIncludeExcludeForDeyployment(IncludeExcludePatterns patternFilter) {
if (patternFilter == null) {
return new IncludesExcludes("", "");
}
String[] excludePatterns = patternFilter.getExcludePatterns();
String[] includePatterns = patternFilter.getIncludePatterns();
StringBuilder include = new StringBuilder();
StringBuilder exclude = new StringBuilder();
for (int i = 0; i < includePatterns.length; i++) {
if (i < includePatterns.length - 1 && include.length() > 0) {
include.append(", ");
}
include.append(includePatterns[i]);
}
for (int i = 0; i < excludePatterns.length; i++) {
if (i < excludePatterns.length - 1 && exclude.length() > 0) {
exclude.append(", ");
}
exclude.append(excludePatterns[i]);
}
IncludesExcludes result = new IncludesExcludes(include.toString(), exclude.toString());
return result;
}
public static org.jfrog.build.api.Build getGeneratedBuildInfo(Run build, TaskListener listener, Launcher launcher, String jsonBuildPath) {
ObjectMapper mapper = new ObjectMapper();
FilePath generatedBuildInfoFilePath = null;
InputStream inputStream = null;
try {
StringWriter writer = new StringWriter();
generatedBuildInfoFilePath = new FilePath(launcher.getChannel(), jsonBuildPath);
inputStream = generatedBuildInfoFilePath.read();
IOUtils.copy(inputStream, writer, "UTF-8");
String theString = writer.toString();
return mapper.readValue(theString, org.jfrog.build.api.Build.class);
} catch (Exception e) {
listener.error("Couldn't read generated build info at : " + jsonBuildPath);
build.setResult(Result.FAILURE);
throw new Run.RunnerAbortedException();
} finally {
if (inputStream != null) {
IOUtils.closeQuietly(inputStream);
}
deleteFilePathQuietly(generatedBuildInfoFilePath);
}
}
private static void deleteFilePathQuietly(FilePath filePath) {
try {
if (filePath != null && filePath.exists()) {
filePath.delete();
}
} catch (Exception e) {
// Ignore exceptions
}
}
public static void copyCertsToAgent(Computer c) throws IOException, InterruptedException {
if (!(c instanceof Jenkins.MasterComputer)) {
String certPath = CertManager.DEFAULT_RELATIVE_CERT_PATH;
FilePath remotePublicKey = new FilePath(c.getChannel(), c.getNode().getRootPath() + "/" + certPath);
FilePath localPublicKey = new FilePath(Jenkins.getInstance().getRootPath(), certPath);
localPublicKey.copyTo(remotePublicKey);
String keyPath = CertManager.DEFAULT_RELATIVE_KEY_PATH;
FilePath remotePrivateKey = new FilePath(c.getChannel(), c.getNode().getRootPath() + "/" + keyPath);
FilePath localPrivateKey = new FilePath(Jenkins.getInstance().getRootPath(), keyPath);
localPrivateKey.copyTo(remotePrivateKey);
}
}
public static String createTempBuildInfoFile(Launcher launcher) throws Exception {
return launcher.getChannel().call(new Callable<String, Exception>() {
public String call() throws IOException {
File tempFile = File.createTempFile(BuildInfoFields.GENERATED_BUILD_INFO, ".json");
tempFile.deleteOnExit();
return tempFile.getAbsolutePath();
}
});
}
public static void exeConan(ArgumentListBuilder args, String pwd, Launcher launcher, TaskListener listener, Run build, EnvVars env) {
boolean failed;
try {
int exitValue = launcher.launch().cmds(args).envs(env).stdout(listener).pwd(pwd).join();
failed = (exitValue != 0);
} catch (Exception e) {
listener.error("Couldn't execute the conan client executable. " + e.getMessage());
build.setResult(Result.FAILURE);
throw new Run.RunnerAbortedException();
}
if (failed) {
build.setResult(Result.FAILURE);
throw new Run.RunnerAbortedException();
}
}
public static PromotionConfig createPromotionConfig(Map<String, Object> promotionParams, boolean isTargetRepositoryMandatory) {
final String targetRepository = "targetRepo";
List<String> mandatoryParams = new ArrayList<String>(Arrays.asList(ArtifactoryServer.BUILD_NAME, ArtifactoryServer.BUILD_NUMBER));
List<String> allowedParams = Arrays.asList(ArtifactoryServer.BUILD_NAME, ArtifactoryServer.BUILD_NUMBER, targetRepository, "sourceRepo", "status", "comment", "includeDependencies", "copy", "failFast");
if (isTargetRepositoryMandatory) {
mandatoryParams.add(targetRepository);
}
if (!promotionParams.keySet().containsAll(mandatoryParams)) {
throw new IllegalArgumentException(mandatoryParams.toString() + " are mandatory arguments");
}
if (!allowedParams.containsAll(promotionParams.keySet())) {
throw new IllegalArgumentException("Only the following arguments are allowed: " + allowedParams.toString());
}
final ObjectMapper mapper = new ObjectMapper();
PromotionConfig config = mapper.convertValue(promotionParams, PromotionConfig.class);
return config;
}
public static org.jfrog.hudson.release.promotion.PromotionConfig convertPromotionConfig(PromotionConfig pipelinePromotionConfig) {
org.jfrog.hudson.release.promotion.PromotionConfig promotionConfig = new org.jfrog.hudson.release.promotion.PromotionConfig();
promotionConfig.setBuildName(pipelinePromotionConfig.getBuildName());
promotionConfig.setBuildNumber(pipelinePromotionConfig.getBuildNumber());
promotionConfig.setTargetRepo(pipelinePromotionConfig.getTargetRepo());
promotionConfig.setSourceRepo(pipelinePromotionConfig.getSourceRepo());
promotionConfig.setStatus(pipelinePromotionConfig.getStatus());
promotionConfig.setComment(pipelinePromotionConfig.getComment());
promotionConfig.setIncludeDependencies(pipelinePromotionConfig.isIncludeDependencies());
promotionConfig.setCopy(pipelinePromotionConfig.isCopy());
promotionConfig.setFailFast(pipelinePromotionConfig.isFailFast());
return promotionConfig;
}
}