Git/Gerrit/svn/Shell/UI标注/团队协作

配置一个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>
上一篇 下一篇

猜你喜欢

热点阅读