配置一个https读取svn服务器配置的jenkins插件
2019-07-26 本文已影响0人
独孤流
项目结构如下
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── io
│ │ └── jenkins
│ │ └── plugins
│ │ └── flow
│ │ ├── HttpsRequest.java
│ │ ├── ReadSVNProperty.java
│ │ └── ReadSVNPropertyValue.java
│ └── resources
│ ├── index.jelly
│ └── io
│ └── jenkins
│ └── plugins
│ └── flow
│ ├── Messages.properties
│ ├── Messages_de.properties
│ ├── Messages_es.properties
│ ├── Messages_fr.properties
│ ├── Messages_it.properties
│ ├── Messages_sv.properties
│ ├── Messages_tr.properties
│ ├── ReadSVNProperty
│ │ ├── config.jelly
│ │ ├── help.html
│ │ └── index.jelly
│ └── ReadSVNPropertyValue
│ └── value.jelly
└── test
└── java
└── io
└── jenkins
└── plugins
└── flow
pom.xml文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>3.4</version>
<relativePath />
</parent>
<groupId>io.jenkins.plugins</groupId>
<artifactId>ReadSVNProperty</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>hpi</packaging>
<properties>
<!-- Baseline Jenkins version you use to build the plugin. Users must have this version or newer to run. -->
<jenkins.version>2.7.3</jenkins.version>
<java.level>7</java.level>
<!-- Other properties you may want to use:
~ jenkins-test-harness.version: Jenkins Test Harness version you use to test the plugin. For Jenkins version >= 1.580.1 use JTH 2.0 or higher.
~ hpi-plugin.version: The HPI Maven Plugin version used by the plugin..
~ stapler-plugin.version: The Stapler Maven plugin version required by the plugin.
-->
</properties>
<name>解析远程SVN配置</name>
<description>根据配置阅读</description>
<!-- The default licence for Jenkins OSS Plugins is MIT. Substitute for the applicable one if needed. -->
<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jquery</artifactId>
<version>1.11.2-1</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>2.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>2.39</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>2.11.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-basic-steps</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-durable-task-step</artifactId>
<version>2.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-api</artifactId>
<version>2.20</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>2.14</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- If you want this to appear on the wiki page:
<developers>
<developer>
<id>bhacker</id>
<name>Bob Q. Hacker</name>
<email>bhacker@nowhere.net</email>
</developer>
</developers> -->
<!-- Assuming you want to host on @jenkinsci:
<url>https://wiki.jenkins.io/display/JENKINS/TODO+Plugin</url>
<scm>
<connection>scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git</connection>
<developerConnection>scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>
</scm>
-->
<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
</project>
ReadSVNProperty.java
package io.jenkins.plugins.flow;
import hudson.Extension;
import hudson.model.*;
import hudson.util.ListBoxModel;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import javax.annotation.CheckForNull;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
public class ReadSVNProperty extends ParameterDefinition {
private static final Logger LOG = Logger.getLogger(ReadSVNProperty.class.getName());
static final long serialVersionUID = 4;
public String svnUrl;
public String svnName;
public String svnPwd;
public String svnFolder;
public ArrayList<String> configList = new ArrayList<>();
@DataBoundConstructor
public ReadSVNProperty(String name, String description,
String svnUrl,String svnName,String svnPwd,String svnFolder) {
super(name, description);
this.svnUrl = svnUrl;
this.svnName = svnName;
this.svnPwd = svnPwd;
this.svnFolder = svnFolder;
}
@Extension
public static final class DescriptorImpl extends ParameterDescriptor {
@Override
public String getDisplayName() {
return "解析远程SVN配置";
}
private ReadSVNProperty getHelloMyParameter(String param) {
String containsJobName = getCurrentDescriptorByNameUrl();
//LOG.warning(">>>>>>>>>>>>getHelloMyParameter--xxxx>>>>>>>>: "+containsJobName);
String jobName = null;
try {
jobName = java.net.URLDecoder.decode(containsJobName.substring(containsJobName.lastIndexOf("/") + 1), "UTF-8");
} catch (UnsupportedEncodingException e) {
LOG.warning("Could not find parameter definition instance for parameter " + param + " due to encoding error in job name: " + e.getMessage());
return null;
}
Job<?, ?> j = Hudson.getInstance().getItemByFullName(jobName, hudson.model.Job.class);
if (j != null) {
ParametersDefinitionProperty pdp = j.getProperty(hudson.model.ParametersDefinitionProperty.class);
List<ParameterDefinition> pds = pdp.getParameterDefinitions();
for (ParameterDefinition pd : pds) {
if (this.isInstance(pd) && ((ReadSVNProperty) pd).getName().equalsIgnoreCase(param)) {
return (ReadSVNProperty) pd;
}
}
}
LOG.warning("Could not find parameter definition instance for parameter " + param);
return null;
}
public ListBoxModel doFillValueItems(@QueryParameter String name, @QueryParameter String value) {
ListBoxModel m = new ListBoxModel();
ReadSVNProperty dp = this.getHelloMyParameter(name);
dp.configList.clear();
if(dp.configList.size()<=0){
String findKey = "."+dp.svnFolder;
// LOG.warning(">>>>>>>>>>>>svn--request<<<<<<<<<<<<");
try {
HttpsRequest t = new HttpsRequest();
ArrayList<String> resultList = t.requestSVN(dp.svnUrl,dp.svnName,dp.svnPwd);
for(String str : resultList){
String txt = str.replaceAll(" ","");
if(!txt.isEmpty() && !txt.startsWith("#")){
String[] keyVals = txt.split("=");
if(keyVals.length==2){
String configKey = keyVals[0];
String configVal = keyVals[1];
// LOG.warning(">>>>>>>>>>>>configKey:"+configKey+"--configVal: "+configVal);
if(configKey.endsWith(findKey)){
String groupConfigKey = configKey.substring(0,configKey.length()-findKey.length());
dp.configList.add(configVal+"#"+groupConfigKey);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
for(String item : dp.configList){
m.add(item);
}
return m;
}
public ListBoxModel doFillFilterItems(@QueryParameter String name, @QueryParameter String value) {
ListBoxModel m = new ListBoxModel();
LOG.warning(name+"---"+value);
m.add("1234");
return m;
}
}
@CheckForNull
@Override
public ParameterValue createValue(StaplerRequest req, JSONObject jo) {
// LOG.warning(">>>>>>>>>>>>createValue--111>>>>>>>>jo:"+jo);
ReadSVNPropertyValue value = req.bindJSON(ReadSVNPropertyValue.class, jo);
// LOG.warning(">>>>>>>>>>>>createValue--111>>>>>>>>value:"+value);
return value;
}
@CheckForNull
@Override
public ParameterValue createValue(StaplerRequest req) {
// LOG.warning(">>>>>>>>>>>>createValue--222>>>>>>>>");
String[] value = req.getParameterValues(getName());
// LOG.warning(getName() + ": " + value[0] + "\n");
return new ReadSVNPropertyValue(getName(), value[0], this.svnUrl, this.svnName,this.svnPwd);
}
}
ReadSVNPropertyValue.java
package io.jenkins.plugins.flow;
import hudson.EnvVars;
import hudson.model.Run;
import hudson.model.StringParameterValue;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.export.Exported;
import java.util.logging.Logger;
import java.util.Locale;
public class ReadSVNPropertyValue extends StringParameterValue {
private static final Logger LOG = Logger.getLogger(ReadSVNProperty.class.getName());
private static final long serialVersionUID = 1L;
@Exported(visibility=4)
public final String svnUrl;
public final String svnName;
public final String svnPwd;
@DataBoundConstructor
public ReadSVNPropertyValue(String name, String value, String svnUrl, String svnName,String svnPwd) {
this(name, value, svnUrl, svnName, svnPwd,null);
}
public ReadSVNPropertyValue(String name, String value, String svnUrl, String svnName,String svnPwd, String description) {
super(name, value, description);
this.svnUrl = svnUrl;
this.svnName = svnName;
this.svnPwd = svnPwd;
}
/**
* Exposes the name/value as an environment variable.
*/
@Override
public void buildEnvironment(Run<?,?> build, EnvVars env) {
// LOG.warning(">>>>>>>>>>>>buildEnvironment--5555>>>>>>>>");
env.put(name,value);
env.put(name.toUpperCase(Locale.ENGLISH),value); // backward compatibility pre 1.345
//env.put(dynamicName, dynamicValue);
}
}
执行https请求svn配置文件的工具类
HttpsRequest.java
package io.jenkins.plugins.flow;
import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
public class HttpsRequest {
public ArrayList<String> requestSVN(String svnUrl,String svnName,String svnPwd) throws Exception {
// 设置账号密码
if(svnName != null && svnPwd != null){
final PasswordAuthentication auth = new PasswordAuthentication (svnName, svnPwd.toCharArray());
Authenticator.setDefault (new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return auth;
}
});
}
// 设置忽略https证书校验
HttpsURLConnection.setDefaultHostnameVerifier(new HttpsRequest().new NullHostNameVerifier());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
URL url = new URL(svnUrl);
// 打开restful链接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");// POST GET PUT DELETE
// 设置访问提交模式,表单提交
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
conn.setConnectTimeout(130000);// 连接超时 单位毫秒
conn.setReadTimeout(130000);// 读取超时 单位毫秒
conn.setInstanceFollowRedirects(false);
// 解析返回数据
InputStream inStream = conn.getInputStream();
StringBuilder sb = new StringBuilder();
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(inStream));
ArrayList<String> resultList = new ArrayList<>();
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append("\\r\\n");
resultList.add(line);
}
String res = sb.toString();
return resultList;
}
static TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
}
};
public class NullHostNameVerifier implements HostnameVerifier {
/*
* (non-Javadoc)
*
* @see javax.net.ssl.HostnameVerifier#verify(java.lang.String,
* javax.net.ssl.SSLSession)
*/
@Override
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return true;
}
}
}
资源文件:
config.jelly
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<!--
This jelly script is used for per-project configuration.
See global.jelly for a general discussion about jelly script.
-->
<!--
Creates a text field that shows the value of the "name" property.
When submitted, it will be passed to the corresponding constructor parameter.
-->
<f:entry title="Name" field="name" description="The name of the parameter set by the first select box">
<f:textbox />
</f:entry>
<f:entry title="svnUrl" field="svnUrl" description="svn url">
<f:textbox />
</f:entry>
<f:entry title="svnName" field="svnName" description="svn name">
<f:textbox />
</f:entry>
<f:entry title="svnPwd" field="svnPwd" description="svn password">
<f:textbox />
</f:entry>
<f:entry title="svnFolder" field="svnFolder" description="svn folder">
<f:textbox />
</f:entry>
<f:entry title="Description" field="description" description="Description of this parameter's use">
<f:textbox />
</f:entry>
</j:jelly>
index.jelly
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define"
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"
xmlns:i="jelly:fmt" xmlns:p="/lib/hudson/project">
<st:adjunct includes="org.kohsuke.stapler.jquery"/>
<!-- <st:adjunct includes="io.jenkins.plugins.sample.script"/>-->
<!-- <st:adjunct includes="io.jenkins.plugins.sample.gitParameterSelect"/>-->
<f:entry description="${it.description}">
<div name="parameter" id="io.jenkins.plugins.sample">
<j:set var="instance" value="${it}" />
<j:set var="descriptor" value="${it.descriptor}" />
<input type="hidden" name="name" value="${it.name}" />
${it.name}<br/>
<f:select field="value" default="" title="${it.name}" size="1" id="brand" />
<!-- <input id="brand_search" placeholder="筛选"/>-->
<!-- <script type="text/javascript">-->
<!-- //<![CDATA[-->
<!-- jQuery(function () {-->
<!-- var opts = jQuery('#brand option').map(function () {-->
<!-- return [[this.value, jQuery(this).text()]];-->
<!-- });-->
<!-- jQuery('#brand_search').keyup(function () {-->
<!-- filterBrand();-->
<!-- });-->
<!-- // 监听值的变化-->
<!-- jQuery("#brand").change(function(){-->
<!-- console.log(jQuery('#brand').val());-->
<!-- filterBrand();-->
<!-- });-->
<!-- function filterBrand(){-->
<!-- var rxp = new RegExp(jQuery('#brand_search').val(), 'i');-->
<!-- if(opts.length == 1 && opts[0].length==2 && opts[0][0] == ""){-->
<!-- var list = opts[0];-->
<!-- var listVar1 = list[0];-->
<!-- var listVar2 = list[1];-->
<!-- opts = jQuery('#brand option').map(function () {-->
<!-- return [[this.value, jQuery(this).text()]];-->
<!-- });-->
<!-- }-->
<!-- var optlist = jQuery('#brand').empty();-->
<!-- console.log("=====》》》=======");-->
<!-- console.log(opts);-->
<!-- console.log(jQuery('#brand_search').val());-->
<!-- opts.each(function () {-->
<!-- if (rxp.test(this[1])) {-->
<!-- optlist.append(jQuery('<option/>').attr('value', this[0]).text(this[1]));-->
<!-- }-->
<!-- });-->
<!-- }-->
<!-- });-->
<!-- //]]>-->
<!-- </script>-->
</div>
</f:entry>
</j:jelly>
help.html
A dynamic parameter allows you to specify two variable names and two sets of data that Jenkins will use to generate a list of values a user can select for the parameters.
value.jelly
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define"
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"
xmlns:i="jelly:fmt" xmlns:p="/lib/hudson/project">
<f:entry title="${it.name}">
<f:textbox name="value" value="${it.value}" readonly="true" />
</f:entry>
</j:jelly>